14

Many commonplace cassette recorders in the 1970s and 1980s were capable of reading or writing two tracks at once (stereo). While that wasn't universal (portable cassette recorders were often monaural, and probably used a single-coil record/playback head) stereo recorders were hardly rare. Further, at least one computer company (Atari) supplied a cassette recorder which used a stereo playback head. Additionally, one of the primary limiting factors for cassette data rates is that the tape only moves at 1.875"/second but the motor speed on many cassette drives could easily be increased merely by changing a resistor or other such component.

It would seem, then, that cassette drives that were customized for, and sold by, computer manufacturers should easily have been capable of handling data much faster than would be possible recording a single track at 1.875"/second, merely by adding some extra record/play electronics and by changing the value of a speed-control component. I know the Coleco Adam used a rather fancy and sophisticated tape drive, but from what I understand that didn't use standard cassettes. Were there any 1970s-1980s computers that used tape drives to record more than one data track, or record data at a speed faster than 1.875"/second?

  • even those computers that used proprietry compact casette(tm) drives used consumer tape transports running at normal speed, only customising the case and audio circuitry. – Jasen May 14 '16 at 20:22
  • I deleted my answer as I realized that despite being an interesting examination of how data cassettes were implemented it didn't address your actual question. – mnem May 14 '16 at 21:07
  • 1
    The ZX microdrive, of course, wasn't a compact cassette (it's design was apparently based on a miniaturized 8-track tape) but it did run the tape somewhat faster than a standard compact cassette did -- 76cm/s, allowing for a complete memory dump/load of the 48K spectrum in around 3 seconds. It was about as reliable as you'd expect from trying to make a cassette tape both smaller and over 10 times faster at the same time. :) – Jules May 16 '16 at 20:07
17

The Sprint cassette player/recorder, specially designed for the ZX Spectrum, allowed 4X load and save speeds.

enter image description here

It works by speeding up the tape four times the standard playing speed. It is meant to load programs originally recorded at the Spectrum ROM standard speed (1500 bps). It provides a shadow ROM that pages in when the CPU starts executing a SAVE or LOAD routine. The shadow ROM mimics the behaviour of a LOAD or SAVE, but using their own routines. Many units had an after-market modification, that allowed the Sprint to be disconnected from the bus in order to improve compatibility with other peripherals, like the Interface 1.

It doesn't use the audio connectors (EAR/MIC), but it talks directly to the CPU through the expansion port. Therefore, the Sprint has to have electronics to clean and digitize the signal, making a volume control not neccesary.

Here you have the disassembly of the 512 byte Sprint ROM.

http://www.zxprojects.com/images/stories/sprint/rom_sprint.html

To ease the disassembly process, I have assumed that the 512 byte block is present at address 0400h to 05FFh. This is because the starting points of the original SAVE and LOAD routines are at 04C2h and 0556h respectively, so they fall entirely into this 512-byte block (as expected).

There's a JP 4 instruction right at the beginning of the ROM (after an EI instruction). As this block is also at 0000h, the JP 4 instruction merely jumps to the next instruction, which outputs a 0 into port BFh. I think this unpages the Sprint ROM, and the next instruction executed, already from the main ROM, begins at 0008h, the ERROR restart.

By the way: this ROM (and thus, the device) uses these ports:

  • BFh. Write-only. The ROM only writes 00h here. I think it's for disabling the Sprint ROM
  • 7Fh. Write-only. The ROM writes 00h or 80h here. It's the new "MIC" port, bit 7.
  • FFh. Read-only. "EAR" port, bit 7. Decoded bit value, bit 0

enter image description here

The internals of the Sprint seem to work according to patent number GB2164527A or "High speed cassette tape player"

The device actually decodes FSK, so the value at bit 7 of port FFh is not the current state of the "EAR" input, as in normal loaders, but the actual bit of the current loading byte.

So, as the patent states, there no need for tight loops, as the time measuring is performed by a monostable, which is reset to 0 on each positive edge of the incoming signal. The computer has to keep reading the monostable value while it waits until the next positive edge. A polarity correction circuit ensures that the edges are right regardless of the polarity the tape were recorded with.

The monostable is configured so it turns to '1' after a specific period of time. Time that is roughly 3/4 times the period of a '1' bit in FSK (remember that the '1' bit lasts double the time than a '0' bit). So if a '1' is currently playing, the monostable will switch to '1' and that will be the value read by the computer, but if a '0' is playing, the next positive edge will happen long before the monostable switchs to '1', hence a '0' will be read.

By analysing the source code, it is likely that port FFh offers two things: the current state of the incoming signal, at bit 7, needed to track the pilot tone at the first part of the loading routine, and to detect edges in the second part. The current value of the monostable, that is, the bit after the FSK decoding process, seems to be at bit 0. The routine reads port FFh, stores bit 0 into the carry with a RRA instruction, some instructions after that, the routine retrieves the bit again into H using the instruction RL H.

ROM:0492 loc_492:
ROM:0492                 dec     l
ROM:0493                 jr      z, loc_4A8
ROM:0495                 in      a, (c)
ROM:0497                 jp      m, loc_492  
;loops while the pulse is high, so it exits 
;just after a positive to negative edge has ocurred

ROM:049A
ROM:049A loc_49A:
ROM:049A                 dec     l
ROM:049B                 jr      z, loc_4A8
ROM:049D                 rra
ROM:049E                 in      a, (c)
ROM:04A0                 jp      p, loc_49A  
;loops while the pulse is low, so it exists just after 
;a negative to positive edge has ocurred. The carry
;bit holds the value of bit 0 read in the previous IN
;operation, as at the precise moment a falling edge
;happens, the monostable is reset to 0.

ROM:04A3                 rl      h  ;load the bit into the H register.
ROM:04A5                 jr      nc, loc_482

This explains why I have seen no tight loops, but some NOP's inside the saving and loading loop. The computer uses timming loops to detect the pilot tone, but the monostable for actual byte loading.

(the following parragraphs were written after a more careful read of the new LOAD routine was made)

Finally, I'd like to give some details of what I think it's the very heart of the loading routine, and the code that shows all the magic that the SPRINT cassette offers:

What this tape player implements is no more and no less than a converter from an asynchronous FSK coded signal to a synchronous 1-bit serial line. The DATA bit is the monostable bit (bit 0 of port FFh) and the CLOCK bit is what we have previously called the "signal" bit (bit 7 of port FFh, which gives us the actual pulses present into the tape). As we stated, the conversion is performed in hardware, and DATA is valid just before a negative to positive transition at CLOCK happens. The byte loading routine that follows, just have to wait for this situation, taking into account that the signal flow might be interrupted at any time, so timeouts have to be provided to not to hang the computer into an endless loop because of an interrupted operation.

;Registers used:
;C = 0FFh (for the IN instruction)
;BC' = 1601h. C is xored with B at each loop. The result is 
;outputted to FEh, so these two values provides visual
;and audio feedback of the loading process to the user.
;H = holds the byte that is being read from tape. First bit
;read is MSb.
;L = timeout value for waiting an edge.

;On "normal" exit: H = byte loaded from tape. Carry set.

ROM:0480 LoadOneByte:
ROM:0480                 ld      h, 1  ;Mark bit 0 with 1. When H is filled
                                       ;this '1' goes to the carry bit,
                                       ;signaling that the byte is completed.
ROM:0482 NextBit:
;--------------------------------------------------------------
; BREAK CHECKING
ROM:0482                 ld      a, 7Fh
ROM:0484                 in      a, (0FEh)  ;read SPACE.
ROM:0486                 rra
ROM:0487                 jr      nc, TotalExit  ;if pressed, early exit.
;--------------------------------------------------------------
; BORDER AND SPEAKER HANDLING
ROM:0489                 exx
ROM:048A                 ld      a, c
ROM:048B                 xor     b
ROM:048C                 ld      c, a
ROM:048D                 out     (0FEh), a
ROM:048F                 exx

ROM:0490                 ld      l, 1Eh  ;timeout for waiting for an edge.
;--------------------------------------------------------------
; LOOP FOR WAITING A POSITIVE TO NEGATIVE EDGE.
ROM:0492 WaitFor0:
ROM:0492                 dec     l  ;update timeout value
ROM:0493                 jr      z, TotalExit  ;if timeout, early exit.
ROM:0495                 in      a, (c)  ;reads clock and monostable
ROM:0497                 jp      m, WaitFor0  ;loops while clock is '1'
;--------------------------------------------------------------
; LOOP FOR WAITING A NEGATIVE TO POSITIVE EDGE.
ROM:049A WaitFor1:
ROM:049A                 dec     l   
ROM:049B                 jr      z, TotalExit
ROM:049D                 rra   ;stores last monostable value read into carry.
ROM:049E                 in      a, (c)  ;reads clock and monostable
ROM:04A0                 jp      p, WaitFor1  ;loops while clock is '0'
;--------------------------------------------------------------

ROM:04A3                 rl      h  ;load monostable value into H
ROM:04A5                 jr      nc, NextBit  ;if H is not full, go 
                                              ;for the next bit.
ROM:04A7                 ret

ROM:0535 TotalExit:
ROM:0535                 pop     hl  ;discard return value for this routine
ROM:0536                 xor     h  ;clears carry?
ROM:0537                 ret  ;return to the caller of the main load routine.

Here you have a live demonstration of the Sprint, loading a copy of Jet Pac, previously recorded in a standard cassette at the ROM speed:

http://www.youtube.com/watch?v=ofBmvjuuIBg

(FINAL NOTE: this answer is a copy of an answer I gave at the WOS forums about 5 years ago. The pictures are from my own Sprint cassette. I've copied it for the sake of preservation, in case the forum vanishes or something. The link to my answer, along with comments from other fellow WOSers, is here: http://www.worldofspectrum.org/forums/discussion/comment/554708/#Comment_554708 )

  • 2
    @mnem: Compatibility with what? When the C64 was introduced, there were two computers that used that style of port (the C64 and the VIC-20), and there only existing drive that used that style of port (the 1540) wasn't compatible with the C64. The C1541 was a tragically-bad rush job; it kinda sorta worked, but should have been way better. – supercat May 14 '16 at 22:46
  • 1
    I recall having read an article which explains why the 1541 was so slow, and it seems like there was a mistake in the design of the CIA, and an operation that was meant to be handled by hardware had to be emulated by the CPU using bit banging, and hence, slower – mcleod_ideafix May 15 '16 at 0:06
  • 1
    @supercat It should be noted that cassettes were an inherently unreliable media (especially for digital/data) and most of that unreliability (in the short term) came from tape stretch. Engaging the read/write heads while it was in FF/REV speeds would naturally exacerbate that problem. The only obvious way to compensate for this problem would be to use shorter tapes (both because shorter means less stretch and because shorter tapes could have thicker mylar) which would mean less data storage. Then there's the long-term problem of dropouts from coating wear, made much worse by hi-speed R/W. – RBarryYoung May 16 '16 at 15:47
  • 1
    @RBarryYoung: Abuse of tapes could obviously cause trouble, but tapes were considered suitable media for music where a momentary 1% speed deviation would be quite noticeable. The only case I would think higher speed would make things worse would be when hitting the start/end of a tape, and if a tape had a suitable leader on the ends I wouldn't think the leader could take the brunt of that rather than the reset of the tape [indeed, I my understanding is that part of the purpose of the leader is to protect the rest of the tape]. – supercat May 16 '16 at 15:54
  • 2
    @mnem: Many encodings allow synchronization on each bit, which should allow them to tolerate 5% stretching without any problem whatsoever (RS-232 communication only synchronizes once every ten bits and can tolerate up to 5% speed mismatch between sender/receiver). For many encodings, even arbitrarily lengthening or shrinking individual bits by up to 25% would have no effect. Why should data be more readily corruptible than music, where a transient pitch change of even 1% would be noticeable and 5% would be obvious? Did some playback routines count pulses without synchronizing on them? – supercat May 16 '16 at 18:47
4

Not really a cassette improvement, but audio anyway: the CD Games Collection from Codemasters came with an adapter that meant to be connected to the joystick port of the computer and the headphones out of a CD Player. The games were recorded with a custom loading scheme, much faster than standard loaders, thanks to the absence of background noise, wow and flutter.

enter image description here

Theorically, the game would be recorded using both left and right tracks, as the audio plug is a stereo 3.5'' jack and the joystick connector seem to have two pins wired. A simple audio analysis shows that it isn't true, and both tracks carried the same signal. Besides, and according to Jose Leandro's research, the loader routine listened to only one pin from the joystick connector. He inferred how the inside circuit would look like:

enter image description here

So it seems that the recording and the loader routine were made after the cable was designed, and they were in a hurry to release this collection, so they couldn't debug it enough and decided to go with a mono signal version and a more reliable, although slower loader.

More about this in Jose Leandro's hardware page: http://trastero.speccy.org/cosas/JL/CableCD/CableCD.html

And speaking of loading through the joystick port. Long time ago I tried to do something similar (although I didn't hear about the CD Games Pack until years after). My approach is to use 5 pins from the joystick port to carry a parallel 4-bit digital signal (using the direction pins), and a clock (using the trigger pin). I could even make it DDR, i.e. accepting data on both the rising and the falling edge of the clock signal. With this approach, I achieved about 155kbps.

Details about this experiment can be found on my website: http://www.zxprojects.com/index.php/external-ultra-high-loader-for-the-zx-spectrum/14-proof-of-concept-alchemist

This is a demonstration of such technique. I use a microcontroller to store the program I want to load, along with the bit banging code that converts it into a series of nibbles to be sent over the joystick cable. The routine at the computer end merely needs to wait until a clock edge happens and then, read the data present in direction pins, store it and when the second half is read, assemble a byte and store in memory. I think the technique can be extrapolated to any computer that has a digital joystick port, and the microcontroller part can be changed for a PC with a FTDI chip with assist from software to do the bit-banging part, loading a program from USB.

https://www.youtube.com/watch?v=i8Sv9riKVwg

  • I wrote a boot loader in 1994 to fetch Atari 2600 code from a PC serial port plugged into the joystick port (via adapter) after I bought Harry Dodgson's monitor cartridge. His monitor included such functionality in 7800 mode, but I think he only used 2400 baud. I forget what I used, but was probably at least 19200. Even 57600 baud should be achievable without difficulty if code is doing nothing but waiting for incoming bits. – supercat May 15 '16 at 20:02
3

The Philips P2000's mini-cassette drives were 10x speed. Do mini-cassettes count?

Otherwise, there were tape recorder mods like the RamBIT for higher speeds. And on various computers you could POKE values or use special software to load and save at higher baud rates, usually up to 2400 baud (600 baud was standard), depending on the quality of the tape and what speed you've set your recorder to.

And here is software that allows a Spectrum to load from the cassette port at up to 27,428 baud.

  • Do you know anything about how the Philips worked? My primary interest was in whether any machines used simple means to increase the fastest speed the hardware could support (I know some software pushed speeds well beyond what the built-in loaders could handle, but I would think simple hardware mods would allow speeds to be pushed higher still. – supercat May 14 '16 at 20:21
  • Of course, pushing hardware speeds would only be relevant for manufacturers that tried to push software toward the upper limits of hardware, which many manufacturers--from what I can tell--didn't. – supercat May 14 '16 at 20:23
3

You could consider the Coleco ADAM as one of the machines that did such tricks.

Though it has been 25+ years since I owned one of these machines, I do remember a few things about them. For starters, it used custom cassettes rather than normal consumer bought audio tapes despite being the same form factor; I do seem to recall that there was an extra hole in the cassette to prevent you from using consumer audio tapes, though you could defeat that with some power tools. I believe it was more than just being a CrO2 or Metal cassette in that they were more durable given the high speeds the drive would push: 20 ips (inches per second) for read/write, 80 ips for cue/rewind.

I believe the ADAM tapes were single-sided only, though I don't recall if the tape head was 2 or 4 tracks (I'll assume the latter because of the ease of getting parts). What was interesting about these tapes is that not only were they fast, but they had full seeking capabilities. In other words, just like how a floppy disk head will jump and sweep from track to track, the cassette would speed up to 80 ips to seek the tape and then drop down to 20 ips for read/write. Yes, the seek would go in either direction, though I think read/write ONLY went forwards. Assuming the 4-track configuration, I'd guess that one track was always position and the other three probably weren't that much different than typical disk sector data patterns.

I don't remember much else about the drives, but they weren't as fast as an IBM / Apple II disk but certainly faster than normal cassettes.

2

Digital Group offered a 5x-speed (as I recall) tape drive called Phi-Deck. This was around 1978. It was a poor man's floppy disk, because it supported a file system, and a primitive operating system, PhiMon.

Some details are here: http://bytecollector.com/dg_phideck.htm

1

The Commodore 64 had many different tape loaders. Game publishers often included them, especially in Europe, as the C64 had on average more memory to fill and the standard tape routines weren't very fast. The exact same tape routines exist in the PET, VIC20, C64, and C128 because when Chuck Peddle wrote them and he left Commodore, the secrets of the logic of the routines left with him.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.