14

The original Apple I didn't use RAM to hold the contents of the display, but instead used a group of six 1024-bit shift registers to hold the display contents and a seventh 1024-bit shift register to keep track of the cursor position. The normal means of outputting data to the display was to somehow activate a signal that would cause the display to store a byte into the display shifters at the spot where the "cursor" shifter had a 1, and then bump the cursor shifter by a space. This approach was limited to outputting one character per frame.

On the other hand, there are some other approaches which seem able to write more data on a frame. For example, when scrolling the screen, the system seems to be able to clear all 40 of the "new" characters on a single frame, and when clearing the screen it appears to be able to write all 960 characters and then set the single bit in the cursor shift register associated with the upper-left corner of the screen.

Did the Apple I provide any means, or could it be readily modified to provide any means, by which the CPU could manipulate the cursor shifter or force a character into the shift register at whatever part in the cycle it happened to be, allowing suitably-written code to produce faster screen output? If one could e.g. cause 1 bits to be stored into every ninth bit of the cursor shifter, it would seem like it should be possible to write any number of lines of text in nine frames by waiting for display scanning to reach the first line to be written, outputting one useful byte of data every nine cycles, waiting for the next line, outputting one useful byte of data every nine cycles, etc. and then cancel the "write-character" operation once all lines of interest had been written? Do any emulators or recreations of the Apple I support such things?

While being able to simply store screen contents in RAM as was done on the Apple ][ was better than anything that could have been done using shift registers, I would think that the shift-register-based design of the Apple I could have been used much more effectively than it was had it not been so quickly obsoleted.

1 Answer 1

7

Video output runs via a 6821 PIA and the interface exposed to the CPU is fairly simple: peripheral register B is configured so that the highest bit is an input and the low seven bits are an output. Checking its published source code, the echo character operation is in the monitor at address FFEF:

ECHO    BIT DSP
        BMI ECHO
        STA DSP
        RTS

i.e. busy wait while the top bit of register B is set. As soon as it is clear, transmit the new character. No positioning, no direct interaction with the shifters, just a push next.

Looking elsewhere, note the implementation of GETLINE at A98D:

GETLINE    LDA #$8D     ; CR
           JSR ECHO

           LDY #$01     ; Initialize text index
BACKSPACE  DEY
           BMI GETLINE  ; Beyond start of line, reinitialize.

NEXTCHAR   ... stuff of getting keyboard input,
           checking it for special characters and echoing it ...

Which suggests two things:

  • special characters, such as carriage return are handled in hardware; but
  • the only meaningful response to trying to backspace to before the start of a line in progress is to start a new line.

Combine those hints with the diagram below that describes DA, the video data available line that is a signal from the 6821 to the video subsystem, as "(UART style)" and I feel confident answering that: there is no means by which the CPU can usurp the normal serialised store-and-wait procedure. Full-line clears and scrolling appear to be a hardware feature, and I'm sure that screen clearing is implemented in terms of those.

Addendum, from the word of God (a sneaky deep link from here; scroll down to 'Don Lancaster's TV Typewriter' and see text billed as "Here is Steve [Wozniak]'s reply to my inquiry"):

The major cost component of my TV Terminal was the video RAM. ... 1024-bit dynamic shift registers were the most cost-effective solution I could find for the screen memory ... These RAM's had to shift once for each character on the screen ... This also led to only being able to add one character every 60th of a second, which is much lower than microprocessor speeds. [...]

When I turned it into the Apple I by adding my own local processor and RAM, the low character refresh rate was a real slow-down. But I was only modifying a terminal to get something built quickly.

4
  • Thanks for that information. That does leave open the question of how difficult it would be to change the hardware to allow things to be done more efficiently, and whether any of the recreations that are out there could be hacked in similar fashion. I would guess that if compatibility wasn't required, a few cuts and jumps would be sufficient without requiring any additional components aside from a bit more ROM space for fancier I/O routines (the cost of which could be offset by eliminating some bypassed components).
    – supercat
    Jan 17, 2019 at 22:30
  • BTW, I wonder what the effect would be of storing a carriage return but changing the stored value before processing is complete. The documentation may not specify such things, but I would think that if software does stores with consistent times, the effects could be made likewise consistent.
    – supercat
    Jan 18, 2019 at 15:59
  • "[T]he only meaningful response to trying to backspace to before the start of a line in progress is to start a new line." No, it's also just as reasonable to continue printing rubout indicators (_). Remember that there's no BS control character, so typing the "delete the last character I typed" character (_) actually leaves the character to be deleted on the screen and the following _ on the screen; you're expected to read this as neither character being in the buffer. Thus, foa_oxa__bar on the screen represents foobar in the buffer.
    – cjs
    Jul 26, 2022 at 1:32
  • The most important reason by far for why the input system starts a new line if you try to backspace before the start of the buffer is because that uses less code than any other obvious way of handling this. The ROM, being only 256 bytes, is very cramped and when studied carefully it becomes clear that many of the UI design decisions were about saving code space. A new line and prompt on making the buffer empty via _ does, however, also happen to be a bit easier to read and nicer to use.
    – cjs
    Jul 26, 2022 at 1:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .