12

One of the major innovations of the Apple 1 when it was released in April 1976 was that instead of using a serial interface requiring an expensive external terminal it had a built-in 40×24 text video display that could be hooked up to an external monitor. (It may not have been the very first to do this, but it was certainly one of the first.)

This was not, however, a memory-mapped display typical of later microcomputers. Rather than writing a character code to a byte of memory that would then be displayed in a corresponding position on the screen, this was a "glass TTY" circuit: you'd write an ASCII byte to the output port and that would be displayed in the next position on the display, with the display automatically scrolling when writing a CR on the last line or writing the last position on the last line. There appears to have been little or no cursor control beyond this, I'm not even sure if backspace was available.

I understand the computer side of this: the video circuit received data from port 2 of a a Motorola 6820 PIA (data register at addresss $D012); one would wait until bit 7 of the port (set to input) went high, indicating that it was ready to recieve data, and then write the desired character to the output bits 0-6.

What I'm interested in is how the circuit after this, on the second-last page of the Apple 1 manual, worked. What control characters could it handle, and how did it do that? How did it store the characters for the screen and generate the video? As well as a general theory of operation, links to data sheets would also be appreciated since some of the parts seem to be quite rare (e.g., the Signetics 2519 hex 40-bit shift register).

  • 1
    "of the major innovations" - minor nitpick, this was not an innovation of the Apple I. The VDM-1 had been in the market for a while at this point (less than a year, but not a lot less), and there were already several competitors like the VB-1. – Maury Markowitz Jan 21 at 12:36
  • @Maury You're right that text video displays themselves preceeded the Apple 1, but the Apple 1 was the first microcomputer (that I'm aware of) where this was built-in as the primary and sole interface, rather than an add-on option to replace a built-in serial port (or front panel). – cjs Jan 21 at 15:24
  • 1
    That's why this sub exists :-) Sphere-1, MCM/70, a Cromemco machine I can't recall, Compucolor 8080 and several others. Some used a built-in display, others had external video. Sol-20 as well, but I'm not sure who predates whom in that case. – Maury Markowitz Jan 21 at 15:50
  • Classic example of Apple rewriting history. :-) I adore the Apple 1. But I don't know of one thing it did that was "the first". MAYBE it was the first SBC that had video...but I really don't know that one. – cbmeeks Jan 21 at 20:20
  • @cbmeeks That's really more me rewriting history; I don't know that Apple themselves ever claimed they were the first to do this. Anyway, I've edited the post to make it clear that, though Apple may not have been the very first, they were certainly one of the first. (The other examples given all seem to have been close enough in time that Woz may not have known about them when he started designing the Apple I.) – cjs Jan 22 at 5:43
11

Preface: The whole circuit isn't complicated, but quite involved. I will try to use 'normal' language to make it less hard to read, as mentioning all the signals and interaction would end in an unreadable conglomeration of words.

you'd write an ASCII byte to the output port and that would be displayed in the next position on the display,

On the circuit side it waited until the 'cursor bit' in the 7th shift register (C11B) marking the cursor position, came along,. Then the character was inserted and the cursor position delayed by one, so it marked the next character position.

with the display automatically scrolling when writing a CR on the last line or writing the last position on the last line.

CR was a function, not a character written into the display. A CR waited like any other character for the cursor position to come around. But instead of getting inserted, it simply waited for the end of the line (*1) and inserted the cursor into the beginning of the next - which may include a scroll.

Scrolling also wasn't exactly like one imagines from memory-mapped screens. The shift registers held 1024 bits each, thus 1024 character positions. The screen was made up as 24x40=960 characters, leaving 64 'invisible' ones. These positions were shifted through during retrace - and cleared. Thus there were always 64 spaces after the last visible line. Scrolling was now done by advancing the start of the screen by one line (40 characters), effectively moving the top line into the 'invisible area' and pulling an already empty one from there. During the next retrace the 'old' line was eliminated, ready for the next up-scroll operation :)

There appears to have been little or no cursor control beyond this, I'm not even sure if backspace was available.

No, it wasn't. The display understood only one control character, CR. The only other manipulation was by pulling CLR to clear the display.

How did it store the characters for the screen

The six 2504 type 1024x1 shift registers build the screen memory. So each shift moves one character ahead.

and generate the video?

During the first scan line of a character row, the screen memory is shifted 40 times and its content is moved into the 2519 type 40x6 shift register. It will output its content to the 2513 character ROM. Once during loading and 7 times thereafter, for each can further scan line. One of the 74161 (D8) addresses them. From the ROM it gets loaded into the 74166 shift register and shifted out to be displayed.

As well as a general theory of operation,

If the above isn't sufficient, please ask in comment. It's just too broad to describe everything here (I guess it'll take 3-5 A4 pages to do so in full detail).

links to data sheets would also be appreciated

Most chips are standard TTL. The shift registers are:

  • 2504 - 1024x1 shift register. Six are used in parallel to store the characters and a 7th holds the cursor position. They are a bit odd as they need voltages of -12V for clock low and +5V for clock high, as well as two alternating clocks, but essentially they are simple shift registers with 1024 bits, advancing one position per clock. The output is rerouted to input, unless a character is written or cleared.

  • 2519 - 40x6 shift register holding one character line during display. As a special feature, they have a 'recirculate' function. This can be seen as kind of a load. As long as pin 4 is high, each clock just moves the content one position ahead and outputs it. If low, the data at the input pins get loaded and at the same time outputted. As described above, during the first scan line of a text row (detected by gate B2 from the scan line counter) 40 characters get loaded from the 2504s holding the screen data.

Everything else is, AFAICT, basic TTL devices.


*1 - This is a little oddity which is complicated to understand (or at least I can't). For one, when a CR occurs, there can't be any character after that position on the line, so CR does not need to delete anything. Still, the CR detection circuit does pull CLR until the end of the line.

The "can't be any character" results from the fact that the only function that can set the cursor up again is clearing the screen. But when doing so, all lines are cleared, so CR does not need to clear to the end of the line. Similarly, any new line scrolled up is also cleared before (during retrace), so again there is no need to clear the line when CR comes along.

The only way to screw that up is by pulling CLR for less than a whole frame (16.7 ms). But even then the cursor would still be positioned after the last text, with all empty lines below.

  • If the Apple I had omitted the timing control circuitry but could force the state of a few bits of the circulating circuitry under CPU control, a load from a certain address would report some bits of the scan-line counter, and a store to a certain address would inject that character into the shift chain, I wonder how much code would be needed to perform screen output, and how much circuitry could be saved. – supercat Jan 1 at 22:57
  • If a row counter was readable and code started with cmp $xxxx / bne .. to wait for the proper row, that would establish timing with a margin of 7 cycles. Then one could probably run a some number of repetitions of a loop which did an "inc" every 12 cycles so as to get lined up precisely with the DRAM refresh, load A with the column number and use a five cycle "SBC #xx / bcs" loop to delay the right number of columns within 5, five ADC/bcc to delay 20-25 extra cycles, and then a store to drop the character in place. More code than needed with the hardware in the machine... – supercat Jan 2 at 17:53
  • ...but code would be able to output characters at arbitrary X/Y positions. With a little extra work, code could output multiple bytes, or perhaps even an entire line of text stored in zero-page, in one frame (get lined up with the beam, then use the seven middles scan lines of a text row to do 5-6 "lda zp/sta abs" pairs). – supercat Jan 2 at 17:56

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.