That's to match impedance with the display drawing and input handling code, which is written in reverse polish notation stack based PostScript, which is going back the forward side.

psterm.ps: https://donhopkins.com/home/archive/NeWS/news-tape/applicati...

tcap.cps: https://donhopkins.com/home/archive/NeWS/news-tape/applicati...

sampl.user.ps: https://donhopkins.com/home/archive/NeWS/news-tape/applicati...

UsingPSTerm: https://donhopkins.com/home/archive/NeWS/news-tape/applicati...

It's still a much better more flexible approach than xterm, since it can emulate any terminal type, and even if the termcap entry is incorrect and not faithful to the actual terminal, it still works.

In fact you can even make up a termcap entry with your own custom sets of fictional/virtual (but efficient) terminal escape sequences, or mix and match different terminals (like adding reverse and bold text, or line/char insert/delete, to a terminal type that doesn't support it), and it still works perfectly.

https://donhopkins.com/home/archive/NeWS/news-tape/applicati...

# This is a faster termcap for psterm, Warning: if you use this termcap
# some control characters you type will do strange things to the screen
# on systems that echo typed control characters to the users terminal.
psterm-fast,
am, km, hs,
cols#80, lines#34,
bel=^G, cr=\r, csr=^E%p1%d;%p2%d;,
clear=\f, el=^C, ed=^B,
cup=^D%p1%d;%p2%d;, cud1=^P, home=^R,
cub1=^T, cuf1=^V, ll=^U,
cuu1=^Y, dch1=^F, dl1=^K,
blink=^Ob, bold=^Od, smcup=^Ot,
smir=^Oi, rev=^Or, smso=^Oo,
smul=^Ou, sgr0=^N*, rmcup=^Nt,
rmir=^Ni, rmso=^No, rmul=^Nu,
flash=^Z, fsl=^Nl, is1=^N*,
il1=^A, kbs=\b, kcud1=\E[B,
kcub1=\E[D, kcuf1=\E[C, kcuu1=\E[A,
nel=\r\n, rs1=^N*, rc=^\,
sc=^], ind=^W, ri=^X,
ht=\t, tsl=^Ol,

I don't understand why it's better to emulate only one fixed terminal type (especially the verbose anathema that's vt100), since you might encounter programs or operating systems that don't support vt100 or whatever you chose to emulate, don't respect termcap, and might use any other fixed set of escape sequences, which psterm can easily handle.

Even if you encounter a program that requires a totally new terminal you've never seen, you can easily write a termcap entry for it, and psterm will emulate it without any changes.

Why rewrite a bunch of other programs, or a bunch of other terminal emulators, when one terminal emulator can easily adapt to them all?

In 1988 when psterm was written there were many different programs and operating systems and terminals like that, especially since terminals can talk to other operating systems than unix that don't support termcap, via telnet or serial ports and modems. It wasn't anything like the stagnant linux/xterm/vt100 monoculture we have today. And if you're going to standardize on one terminal, the vt100's one of the worst you could possibly chose!

That's kind of the whole point of a terminal emulator: to emulate terminals, so the more the merrier!

The idea of virtualizing terminal protocols has been around for a long time, like Marc Crispin's SUPDUP Display Protocol for ITS and Lisp Machines (RFC734 from 1977), and ITS's CRTSTY virtual terminal emulator (kind of like "screen" for translating virtual to actual terminal sequences for many terminal types, adapting dumb terminals without line/char insert/delete, supporting redisplay for low baud rates or congested ARPA connections, and keeping your session and jobs alive if you disconnect, so you can continue after you reconnect, even with a different terminal type, if you got kicked off a nice AAA and forced to use a shitty VT52).

http://junk.nocrew.org/pipermail/its/1988-September/002005.h...

https://github.com/PDP-10/its/blob/master/doc/sysdoc/itstty....

>This file describes just about all there is to know about using and
programming TTYs (abbreviation for "Teletypes", for which read "consoles")
on the ITS operating system.

https://datatracker.ietf.org/doc/rfc734/

>NWG/RFC# 734 MRC 07-OCT-77 08:46 41953
SUPDUP Display Protocol Page 1
Network Working Group Mark Crispin
Request for Comments 734 SU-AI
NIC 41953 7 October 1977

>SUPDUP Protocol

>This document describes the SUPDUP protocol, a highly efficient display
telnet protocol. It originally started as a private protocol between the
ITS systems at MIT to allow a user at any one of these systems to use one
of the others as a display. At the current writing, SUPDUP user programs
also exist for Data Disc and Datamedia displays at SU-AI and for
Datamedias at SRI-KL. The author is not aware of any SUPDUP servers other
than at the four MIT ITS sites.

>The advantage of the SUPDUP protocol over an individual terminal's
protocol is that SUPDUP defines a "virtual" or "software" display terminal
that implements relevant cursor motion operations. The protocol is not
built on any particular display terminal but rather on the set of
functions common to all display terminals; hence it is completely device-
independent. In addition, the protocol also provides for terminals which
cannot handle certain operations, such as line or character insert/delete.
In fact, it is more than this. It provides for terminals which are
missing any set of features, all the way down to model 33 Teletypes.

>The advantage over the TELNET protocol is that SUPDUP takes advantage of
the full capabilities of display terminals, although it also has the
ability to run printing terminals.

https://its.victor.se/wiki/_media/ai_wp_235.pdf

>The SUPDUP protocol [Crispin 77] is a highly efficient display telnet protocol. The advantage over
the TELNET protocol is that SUPDUP takes advantage of the full capabilities of display terminals,
although it also has the ability to run printing terminals. When you use the SUPDUP protocol, you do
not need to tell the remote host which you are connecting to what type of terminal you have or what
the terminal's capabilities are. The host you are SUPDUPing from handles the actual display support
for your terminal.

>Additionally, SUPDUP defines a network graphics protpcol [Stallman 78] which makes it easy for
network hosts to draw pictures along in addition to text.

I even wrote a SUPDUP emulator in FORTH and RPN 6502 assembly, which is about as backwards and upside-down as it gets -- this code also supports the SUPDUP line saving extensions that RMS hacked into ITS Emacs, so it can stash lines on the screen in local memory before overpainting them, then almost instantly pop them back on the screen later, so you can scroll back and forth through text really fast at 300 baud (plus Devon McCullough made ZipMod with Huffman encoding to make it even faster on top of that):

https://donhopkins.com/home/archive/forth/supdup.f

HEX CREATE SETUP-LINE ASSEMBLER
BOT LDA, N STA, BOT 1+ LDA, N 1+ STA,
BOT 2+ LDY, SCR-LBASES ,Y LDA,
N 2+ STA, SCR-HBASES ,Y LDA,
N 3 + STA, SCR-WIDTH 1- # LDY, RTS,

At 300 baud over a congested ARPA connection, we had a lot of time to think about how to optimize terminal emulation while waiting for the screen to repaint...

And just what's wrong with backwards and upside-down algorithms that solve problems in ways that forward and rightside-up algorithms can't?

That's how Emacs's infamous screen redisplay algorithm (and many other common algorithms like pathfinding in games and route planning in cars) work: recursively flood filling forward then navigating backwards from the goal to the current position at the minimal cost, through a matrix or maze of different possible alternative escape sequences and drawing operations or roads with different costs, to find the optimal shortest possible route.

At 300 baud or even 1200 baud, and even on a busy Vax 11/750, there's a lot of time between each character for Emacs to think about what text and escape sequences to send next.

And of course Emacs's screen update algorithm would automatically take into account and use the short optimized custom control codes defined in the psterm-fast termcap entry, to be much more efficient that the verbose inefficient vt100 codes.

Read the paper and display.c code I linked to, and see the wikipedia page on dynamic programming:

>James Gosling's Emacs screen redisplay algorithm also used similar "dynamic programming techniques" to compute the minimal cost path through a cost matrix of string edit operations (the costs depended i.e. on the number of characters to draw, length of the escape codes to insert/delete lines/characters, padding for slow terminals, etc).

https://en.wikipedia.org/wiki/Gosling_Emacs

>Gosling Emacs was especially noteworthy because of the effective redisplay code, which used a dynamic programming technique to solve the classical string-to-string correction problem. The algorithm was quite sophisticated; that section of the source was headed by a skull-and-crossbones in ASCII art, warning any would-be improver that even if they thought they understood how the display code worked, they probably did not.

https://donhopkins.com/home/archive/emacs/skull-and-crossbon...

>Trivia: That "Skull and Crossbones" ASCII art is originally from Brian Reid's Scribe program, and is not copyrighted.

https://donhopkins.com/home/archive/emacs/mw/display.c

/* 1 2 3 4 .... Each Mij represents the minumum cost of
+---+---+---+---+----- rearranging the first i lines to map onto
1 | | | | | the first j lines (the j direction
+---+---+---+---+----- represents the desired contents of a line,
2 | | \| ^ | | i the current contents). The algorithm
+---+---\-|-+---+----- used is a dynamic programming one, where
3 | | <-+Mij| | M[i,j] = min( M[i-1,j],
+---+---+---+---+----- M[i,j-1]+redraw cost for j,2
4 | | | | | M[i-1,j-1]+the cost of
+---+---+---+---+----- converting line i to line j);
. | | | | | Line i can be converted to line j by either
. just drawing j, or if they match, by moving
. line i to line j (with insert/delete line)
*/

https://donhopkins.com/home/documents/EmacsRedisplayAlgorith...

https://dl.acm.org/doi/10.1145/1159890.806463

>A redisplay algorithm, by James Gosling.

>Abstract

>This paper presents an algorithm for updating the image displayed on a conventional video terminal. It assumes that the terminal is capable of doing the usual insert/delete line and insert/delete character operations. It takes as input a description of the image currently on the screen and a description of the new image desired and produces a series of operations to do the desired transformation in a near-optimal manner. The algorithm is interesting because it applies results from the theoretical string-to-string correction problem (a generalization of the problem of finding a longest common subsequence), to a problem that is usually approached with crude ad-hoc techniques.

[...]

>6. Conclusion

>The redisplay algorithm described in this paper is used in an Emacs-like editor for Unix and a structure editor. It's performance has been quite good: to redraw everything on the screen (when everything has changed) takes about 0.12 seconds CPU time on a VAX 11/780 running Unix. Using the standard file typing program, about 0.025 seconds of CPU time are needed to type one screenful of text. Emacs averages about 0.004 CPU seconds per keystroke (with one call on the redisplay per keystroke).

>Although in the interests of efficency we have stripped down algorithm 5 to algorithm 6 the result is still an algorithm which has a firm theoretical basis and which is superior to the usual ad-hoc approach.

https://en.wikipedia.org/wiki/Dynamic_programming

>Dynamic programming

>Figure 1. Finding the shortest path in a graph using optimal substructure; a straight line indicates a single edge; a wavy line indicates a shortest path between the two vertices it connects (among other paths, not shown, sharing the same two vertices); the bold line is the overall shortest path from start to goal.

>Dynamic programming is both a mathematical optimization method and an algorithmic paradigm. The method was developed by Richard Bellman in the 1950s and has found applications in numerous fields, from aerospace engineering to economics.

>In both contexts it refers to simplifying a complicated problem by breaking it down into simpler sub-problems in a recursive manner. While some decision problems cannot be taken apart this way, decisions that span several points in time do often break apart recursively. Likewise, in computer science, if a problem can be solved optimally by breaking it into sub-problems and then recursively finding the optimal solutions to the sub-problems, then it is said to have optimal substructure.

>If sub-problems can be nested recursively inside larger problems, so that dynamic programming methods are applicable, then there is a relation between the value of the larger problem and the values of the sub-problems.[1] In the optimization literature this relationship is called the Bellman equation.