Emulating the DMD 5620 Terminal
Back in the early 1980s, before GUIs were commonplace, Rob Pike and Bart Locanthi Jr. at AT&T Bell Labs created a bitmapped windowing system for use with UNIX. Originally, they called the system “jerq”, a play on the name of the Three Rivers PERQ computer. When the technology started to get showed around outside of the lab, however, they changed its name to “Blit”, from the name of the “bit blit” operation.
Here’s a small demo of the system in action, circa 1982.
The windowing system was a combination of hardware and software. The hardware was a terminal built around a Motorola 68000, with an 800 by 1024 pixel 1-bit bitmapped display in portrait mode, a keyboard, and a mouse. The software was hosted on a UNIX computer and would be uploaded to the terminal’s memory on demand, where it executed on the terminal’s CPU itself.
Later still, AT&T and the Teletype Corporation teamed up to commercialize the system. They reimplemented the hardware and based it on a Western Electric WE32100 CPU. They named it the DMD 5620 (DMD for “Dot-Mapped Display”).
Because I’m such a fan of emulation, and because I worked so long and hard on the AT&T 3B2/400 Emulator, and because 3B2s often ran DMD 5620 terminals in commercial environments, I knew I had to remedy the situation.
Unlike the 3B2/400, the DMD 5620 is extraordinarily well documented. Not only that, but the source code for the ROM is available, as is the source code for the driver and application software on the UNIX side. Many thanks go to Eric Smith for his DMD 5620 FAQ and Software archive, without which this project wouldn’t have been possible. It made writing the emulator a weeks-long project instead of a years-long project.
The Back End
Naturally, I worked on the Rust back end first, starting with the very tedious work of porting my WE32100 CPU core from the 3B2/400 emulator to the new DMD 5620 emulator. It gave me a chance to rethink some things, and also add unit tests where I didn’t have them before (SIMH does not support any unit testing framework, which I thik is a shame). After the CPU core was implemented, I added the other peripherals one by one, emulating them as I went, until I could boot the ROM successfully.
Lucky for me, the DMD 5620 as a system is pretty simple. There’s a ROM, a RAM, a DUART, some non-volatile memory, a couple of status registers, and an optional parallel I/O interface that I’ve chosen not to implement. Fairly easy-peasy. The biggest pain is the 2681 DUART, which is very complex. I was able to crib most of the architecture for this from the 3B2/400 emulator, though, since the 3B2/400 uses the same model of DUART for its console I/O.
The Front End
Finally, it was time to stick a front end on it so I could see whether it was trying to talk to me after it booted.
The first front end I built was just an experiment, written in Rust, and not meant to be cross platform. It uses the Piston rust library to draw to an OpenGL window, but otherwise has no interesting features.
Actually drawing the bit-mapped display is pretty easy. The DMD 5620 exposes a 100KB window of its RAM as video memory, so really all I had to do was iterate over this block of memory, reading it bit by bit, and draw a green pixel if the bit was set, or a black pixel if the bit was not set. Still, it took me a few tries to get it right, because I’m a doofus. In the end, though, I could see the DMD 5620 booting, echoing some status messages to the screen, presenting a cursor, and then waiting for input.
events. These are fed into the back end as either keyboard UART
receive events, mouse button UART events, or memory updates (the DMD
5620 writes the current mouse X and Y position to a pair of registers
Finally, there has to be a way to communicate with a host. My first implementation is Telnet, which can be used to connect the terminal emulator to a 3B2/400 emulator on the same host, or on a different host. It may be a little counter-intuitive, but the front end is actually responsible for handling the Telnet protocol. The back end is totally agnostic about where characters come from, it doesn’t care. This means I can plug in different character sources, say direct serial interface.
With all the elements put together, it’s a fairly usable system!
Odds and Ends
I’m happy with how this project progressed. The bulk of the time spent on it was porting the CPU core, which was tedious and error prone (thank goodness for unit tests). The rest of the time seems to have breezed by, thanks to good documentation and a simple system.