Super sweet!

I didn't read the whole manual I linked above, but I think the way the original VT52 handled scrolling was that it incremented a register which it used for the index of the starting line. The microprogram was responsible for poking each new character into the character generator at the right moment 80 times for each of 240 scan lines, so it looked at this register each time it started drawing the screen to see where to start this process.

(Incidentally, if you remember BSD talk/otalk/ntalk/ytalk, you might remember that it divides the screen into two windows and avoids ever scrolling them by wrapping the conversation around from the top to the bottom of the window in a sort of similar way; I suspect that this is because some terminals, like the ADM3A, didn't support scrolling part of the screen, and redrawing half the screen at 2400 baud would have been slow.)

Your timing is a little more challenging to meet: although your horizontal resolution is almost the same, instead of 240 scan lines 60 times a second (a new scan line every 69 microseconds and a new character every 870 ns), you have 384 scan lines 70 times a second (a new scan line every 37 us and a new character every 470 ns, which I guess means 58 ns per pixel). But you're running on an FPGA where a lot of circuits can be clocked at 50 MHz, right? 20 ns.

I wonder if your design would have been simpler with a processor; you say half of the 2000 LUTs (iCE40 4-LUTs I guess?) were occupied with USB, but that still leaves 1000 LUTs for the terminal logic, roughly equivalent to 1000 7400-series TTL chips, which is a lot bigger than the historical VT52. I'm thinking the VT52 used its "microprogram" approach in order to reduce that complexity; now that we have faster hardware we could probably go further in that direction if we wanted.

Also 1000 4-LUTs is five times the size of SeRV, though I'm guessing SeRV itself probably isn't fast enough to do the character-feeding job the VT52 microprogram did. A bit-serial 7-bit processor might be the ticket.

— ⁂ —

I was chatting with a friend today about a project of his and wondering whether an FPGA-implemented terminal might be useful for a certain weird project, though not specifically a VT52. It's a super low power portable computer, and right now he's using a Raspberry Pi for prototyping.

You can maintain a display on an e-ink screen without any power, and Sharp's memory-in-pixel LCDs need about 0.05 milliwatts per 0.1 megapixels to maintain the display (and are several orders of magnitude lower-power to actually update). But a Raspberry Pi Zero takes more like 650 milliwatts to run, normally takes about 40 seconds to boot, and has no real sleep mode. With buildroot evidently you can get the boot time down to a few seconds https://www.furkantokac.com/rpi3-fast-boot-less-than-2-secon... but that's still a long time to wait for a response to a keystroke. The Pi 3 and Pi 4 evidently do have a working sleep mode, but it uses a lot of power (like, 50 milliwatts or something) and imposes a latency of 100 ms or so.

So I was thinking that one way to design the system would be as the moral equivalent of a web-browser + webserver, where some kind of tiny, low-power front-end processor handles most of the moment-to-moment interaction, then powers up a Raspberry Pi to boot Linux whenever it has a "webserver request" to handle. (Even while Linux is booting the UI doesn't need to become unresponsive! My browser doesn't hang until the web server responds!) For the front-end processor I suggested an ATTiny, because that's what he has on hand, but that may be a little too tiny, and anyway Ambiq's chips use less power and can handle faster compute. However, an FPGA opens up a lot of other possible alternatives.

Probably HTML and JS are not the right way to script the front-end processor, but clearly something as functional as an IBM 3270 is achievable. With the benefit of 50 years of hindsight, though, not to mention 8000-LUT FPGAs running at 50 MHz with tens of kilobytes of RAM, I think we can do a lot better. Like, you can have fragment shaders, though they probably have to be more limited than GLSL shaders because you don't have space for a framebuffer.