I started the project without any clearly defined goals for the terminal functionality other than it had to scroll. I wanted a terminal to connect to a nebulously defined future computer project but was stuck with testing with modern computer...which still speak to command line environments with ANSI escape sequences. Why not emulate the classic computer terminal progenitors then? I started with the VT100 but soon found I liked the additional features that DEC added with the VT102 such as the ability to support printers and more efficient editing capabilities. This meant a lot of escape sequence decoding. I ended up wading through a lot of websites describing various ANSI escape sequences but finally found http://vt100.net as the best source. Obviously I couldn't deal with commands to change the font or font-size so I ignored those but I tried to deal with everything else and I added a couple of escape sequences from more advanced terminals that supported some function (like cursor blink) that my display could also support. I tested my code using both a Raspberry Pi running Raspian and my Mac OS X laptop. Interestingly the OS X system wanted a much more modern set of ANSI escape sequences even when I thought I told it to limit to the old VT102 set. I ended up adding code to ignore entire classes of escape sequences such as "Operating System" types. My main test was bash shell interactivity and the vi text editor. I used a diagnostic mode in my code to dump the incoming stream to the USB serial port so I could see what the terminal had seen when the display didn't match what I expected (which, at least at first, was a lot). It was entertaining if nothing else. A lot of modern code thinks nothing of sending the same escape sequence multiple times in a row.
Ultimately for my first go-around I ended up with the following control character and escape sequence "command set" for the terminal. I made the conscious decision not to support all the control characters in the same way DEC terminals did to match some more "stupid" terminals that I had run across over the years.
Control Characters Implemented
CTRL-C EOT - Break command for Tiny Basic (ignored in Terminal mode)
CTRL-G BELL - sends BELL to keyboard (rings keyboard bell)
CTRL-H BS - backspace cursor
CTRL-I TAB - forwardspace cursor to next tab position (default values: 1, 2, 4
or 8 positions, configurable)
CTRL-J LF - Linefeed character (moves cursor down one row; may also
be configured to include a CR)
CTRL-K VT - Vertical tab (moves cursor up one position) (**)
CTRL-L FF - Formfeed (clear screen) (**)
CTRL-M CR - Carriage return (moves cursor to start of line; may also
be configured to include a LF)
ESC (*) Escape - starts escape sequence
DEL Delete - backspace cursor, deleting character first (**)
Notes:
* The EOT key on the keyboard is treated as an Escape in terminal mode and a CTRL-C
(break) in Tiny Basic mode.
** These control characters are not VT100/ANSI compliant. They exist for compatibility with
other, more primitive, terminals.
ANSI Sequences Implemented (numeric arguments in decimal ASCII notation are contained with <>)
ESC[;H Cursor Position
ESC[;f Horizontal and Vertical Position (same as Cursor Position)
ESC[A Cursor Up
ESC[B Cursor Down
ESC[C Cursor Forward
ESC[D Cursor Backward
ESC[s Save Cursor Position
ESC[u Restore Cursor Position
ESC7 Save Cursor Position, origin mode and cursor attributes (*)
ESC8 Restore Cursor Position, origin mode and cursor attributes (*)
ESC[J Erase Down
ESC[1J Erase Up
ESC[2J Erase Display
ESC[K Erase End of Line
ESC[1K Erase Start of Line
ESC[2K Erase Line
ESC[L Insert Line
ESC[M Delete Line
ESC[P Delete Character
ESC[c / ESC[0c / ESCZ Query Device Attributes (responds with VT102 ESC[?6c)
ESC[5n Query Device Status (responds with Report Read, no malfunctions ESC[0n)
ESC[6n Query Cursor Position (responds with Report Cursor Position ESC[;R)
ESC[?15n Query Printer Status (responds with
ESC[?13n if printer is offline
ESC[?11n if printer is out of paper
ESC[?10n if printer is ready to print
ESCc Reset Device
ESCD Scroll Down One Line
ESCE Next Line
ESCM Scroll Up One Line
ESCH Set Tab
ESC[0g / ESC[g Clear Tab at position
ESC[3g Clear all tabs
ESC[;r Set scrolling region
ESC[r Reset scrolling region
ESC[4h Enable Character Insertion
ESC[4l Disable Character Insertion
ESC[7h Enable Line Wrap
ESC[7l Disable Line Wrap
ESC[12h Disable Local Echo
ESC[12l Enable Local Echo
ESC[20h Set New Line Mode (new line also includes CR, CR sends CR+LF)
ESC[20l Reset New Line Mode
ESC[?6h Set Origin Mode
ESC[?6l Reset Origin Mode
ESC[?25h Make Cursor visible
ESC[?25l Make Cursor invisible
ESC[0q / ESC[1q Cursor Blink (**)
ESC[2q Cursor Solid (**)
ESC[i / ESC[0i Print Screen or scrolling region (based on Printer Extend Mode)
ESC[?1i Print Line with cursor (followed by CR/LF)
ESC[4i Disable Print log
ESC[5i Start Print log (send incoming data to printer instead of screen)
ESC[?4i Turn off Auto Print
ESC[?5i Turn on Auto Print (print line after cursor moved off line w/ LF, FF, VT)
ESC[?18h Set FF as print screen terminator
ESC[?18l Set nothing as print screen terminator
ESC[?19h Set full screen to print during print screen
ESC[?19l Set scrolling region to print during print screen
ESC# Line Attributes (IGNORED)
ESC( Select Character Set (IGNORED)
ESC) Select Character Set (IGNORED)
ESC];BEL Operating System Command (IGNORED)
Notes:
* This isn't ANSI compliant, instead of storing character attribute, we are storing cursor attributes
** These are VT520 commands
Dan Julio
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.