The ASR33, like most teletypes of the era, works at a fixed rate. It does 10 characters per second. It is 110 Baud, using 1 start, 8 data (inc parity), and 2 stop, so 10cps Tx and 10cps Rx; 10cps printing; 10cps punching tape; 10cps reading tape; 10cps maximum typing speed. Everything happens based on one motor that does this 10cps working, engaging clutches to start an operation which completes in one turn. So everything has to happen within 100ms, well, sort of.
There is one exception: carriage return [CR]. The carriage is released within the 100ms time, but the carriage is on a spring, and does not get back to the left within 100ms if it is too far over to the right. The usual fix is to send another non printing character, such as a line feed [LF], as the next character, where CR and LF are used for each new line. The paper advances whilst the carriage is returning so giving the carriage a whole 200ms to complete the return. This allows enough time to get to the left, but can leave the carriage still bouncing and mean the first printable character is not well aligned. The fact that 200ms is enough is usually fine, unless you are particularly fussy. The fix to this is to send another non printing character, such as a NULL, another CR, or even a rub out [RO]. The standard HEREIS drum coding even specifies CR, LF and RO at the start.
If you do send characters immediately following a CR, you get them printed in the fly-back of the carriage, like this...
The whole “new line = CR+LF” thing has plagued computing for the last 6 decades, with some systems and file formats using CR as new line, some LF, and some CR+LF. Even today I can find I have a file in DOS format using CR+LF that needs converting.
The software I have written in the controller allows for this when printing text itself, doing CR, LF for new line, and adding a NULL if beyond 40 columns at the time. This works, and is used for prompts and even the Colossal Cave game that is built in.
However, this presents a few issues :-
- This works when generating text, but if in some sort of raw mode it mean the sending device needs to know to do this. Some systems know, some do not.
- If this is done automatically, so extra characters are inserted that is not a problem for printing, but for punching paper tape it records those extra characters. That said, a NULL or RO on paper tape should not normally be an issue when read in. But it is not ideal, and assumes it is not binary data on the paper tape for some reason. So you sort of need a raw or processed mode for handling such tape, which is messy.
- Paper tape is sometimes used for raw / binary data, but can also be used for “large text” or patterns (which is gibberish as printed). Whilst fun, this also has a practical use to label reels of paper tape at the start in a human readable format. If automatic extra characters for CR handling are added, they mess this up.
A new solution to an old problem...
My solution works because we are now using a soft UART. I am doing this, working the individual data bits on a timer interrupt, to allow the extra low Baud rates used by some teletypes, which are not supported by hardware UARTs. Some work as low as 45.45 Baud even.
The soft UART has now been coded so that the bytes, as actually sent to the teletype (i.e. not when buffered/queued, but in real time), are tracked to know carriage position, and operate a timer between sending a CR and the next printable character. A non printable character like a NL, NULL, RO, are allowed within this timeout, but the timeout has to finish before the first printable character after a CR. This allows the CR to complete and avoids printing a character during the fly-back of the carriage.
This means :-
- Where the sending device is sending the extra characters, even just a CR, LF, to allow for CR, then the operation is totally unchanged. This makes it 100% backwards compatible with existing working of teletypes and means no special raw or processed modes needed.
- Where the CR needs this extra time it can be done in sub character, even sub bit, periods, not wasting the time for a whole extra character such as a NULL.
- The delay can be adjusted for the position of the carriage, and hence allow just the time it will take to complete the return.
- This works even when CR is immediately followed by a printable character (causing a pause you can just hear on longer lines).
- No extra characters are actually inserted, so characters as punched on paper tape are perfect, no gaps or ROs, etc.
This works well, even with a printable character immediately following the CR, like this...
Today I learned...
What is funny (well, for me) is that there will be people who have worked in computing and IT for decades and encountered the whole craziness that is CR and LF, but have no idea why it was ever a thing. I hope this, in some way, explains some of the background.
You're welcome :-)
P.S. I cannot say for sure that the way teletypes work is why CR and LF are separate. They were around at the time ASCII was being developed - heck my teletype does not even have lower case as it is 1963 first ASCII version. So the way they work is quite likely to be a factor. That said, CR and LF as characters dates back even further than ASCII. It is true that CR being separate has been used for things like over printing underscores, even over printing hyphens many types to make a perforation, and other tricks, but I suspect those tricks are all a consequence of CR being separate and not the reason for it. Even the older manual typewriters would have a manual carriage return level that would typically do the line feed at the same time - so it seems odd they would be made separate characters if not for this reason. It is odd how, what may have seemed trivial at the time, such a decision still impacts computing today. At the very least, you can see why it is CR then LF, and not LF then CR, in files.