Does PuTTy work correctly with ANSI/VT100 escape sequences? - putty

I'm writing a program for a class in HC12 Assembly for the Freescale MC9S12C32 processor. I'm using PuTTy as the terminal attached to the device via serial(-over-USB). For this assignment, we are supposed to use VT100/ANSI escape sequences to move the cursor to an arbitrary location and write the current time and then return it so the user can type and have their input echo'd back.
I'm using the below sequence to save the cursor, move it, and return it. Yet for some reason PuTTy just places the cursor in the upper-left and fails to return it.
ESC EQU $1B ; ASCII ESC
SAVECUR EQU $37 ; ASCII 7
RESTCUR EQU $38 ; ASCII 8
SaveCursor PSHA
LDAA #ESC ; Use Escape Sequence
JSR putchar
LDAA #'['
JSR putchar
LDAA #SAVECUR ; To save cursor location
JSR putchar
PULA
RTS
GotoClkPos PSHA
LDAA #ESC ; Move Cursor
JSR putchar
LDAA #'['
JSR putchar
LDAA #$05 ; To Row 5
JSR putchar
LDAA #';'
JSR putchar
LDAA #$05 ; Column 5
JSR putchar
LDAA #'H'
JSR putchar
PULA
RTS
RestCursor PSHA
LDAA #ESC ; Use Escape Sequence
JSR putchar
LDAA #'['
JSR putchar
LDAA #RESTCUR ; To Restore Cursor
JSR putchar
PULA
RTS
Am I coding the escape sequences wrong or does PuTTy not handle them as I expect?

Your escape sequences are wrong. You should remove the '[' from SaveCursor and RestCursor (save cursor=ESC+'7', restore=ESC+'8').
GotoClkPos seems OK though.
PuTTY handles VT100-commands just fine. Although I'm having trouble getting some commands to work, like hide cursor.

Putty does not handle all of VT100 right. It sends garbage for all function keys other than F1/F2/F3 and does not handle a variety of the other interfacing correctly. I have yet to find a good program that actually does, so I'm happy that I have a few dumb terminals kicking around (but how silly is that?)

Related

Where does the extra 'D' come from in dup1.go?

I'm new to golang and learning it now. I'm reading "The Go Programming Language" book and trying to run the dup1 example on my Mac. But I noticed a very weird issue. The output of the count contains an extra "D". Anyone has any idea why?
> go run dup1New.go test
test
test
hello
hello
world
3D test
2 hello
> cat dup1New.go
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
counts := make(map[string]int)
input := bufio.NewScanner(os.Stdin)
for input.Scan() {
counts[input.Text()]++
}
// NOTE: ignoring potential errors from input.Err()
for line, n := range counts {
if n > 1 {
fmt.Printf("%d\t%s\n", n, line)
}
}
}
go version go1.13.5 darwin/amd64
You're getting that D character from Ctrl+D is because of echoctl option in your terminal device interface. You could easily remove that off by running this command in your shell/terminal:
stty -echoctl
Ref: man stty
As wlisrausr answered, this is in part from your MacOS Terminal stty settings. (You probably should not turn off echoctl, though.)
To be more complete: when you type the CTRL+D sequence to signal EOF,1 the tty driver2 "displays" the character as the two-character sequence ^D, but then prints two backspace or CTRL+H characters. More precisely, it does so as long as the ECHOCTL flag is set in the lflags control field in the underlying tty settings.
The window that is displaying the interactive Terminal session is treating output as directives to draw particular characters, move (position) the cursor, and have other interesting effects. Some character codes, particularly those in the range 0x20 (32 decimal) through 0x7e (126 decimal), are displayable ASCII characters. Others are controlling characters—ANSI escape codes—or Unicode characters that have been encoded in UTF-8. Go itself uses UTF-8 extensively, to encode runes, so Go's use of UTF-8 dovetails nicely with Terminal's use of UTF-8.3
The CTRL+H, ASCII code 8—which they call BACKSPACE or BS—has the effect of moving the cursor back one display-column. That is, it is a cursor-positioning control code. (There are many of these; see the ANSI escape codes page. This stuff has a very long history, going back to just after the first glass tty.)
So, the CTRL+D has been displayed as ^D, but the cursor is positioned over the ^ (hat or caret or circumflex) character. Now you, in your Go program, send to the Terminal display-handling code, a sequence of ASCII codes: 3, which is 0x33 or 51 decimal; then TAB or CTRL+I or ASCII Horizontal Tab (HT), which is code 9; then the ASCII codes for the letters test (0x74, 0x65, 0x73, 0x74), then a newline or CTRL+J or ASCII NL, which is code 10.
Like backspace, a horizontal tab is a cursor positioning operation. It directs the terminal (or window emulation of terminal) to move the cursor to the next tab-stop, without changing anything else on the display. So you first overwrite the ^ with 3, leaving 3D visible, and the cursor positioned over the letter D. Then you have Terminal move the cursor to column 9 (columns are numbered from 1 and the default tab stop is at every eighth column) and display the word test, and then move the cursor to column 1 of a new line. The result is that the line shows:
3D test
(with exactly six blank positions between D and the first t). On the newly exposed or created line, which is currently all-blank, you print the character 2, move to column 9, and print the letters hello (and another newline directive).
1In fact, control-D simply pushes the accumulating line through the "input canonization" queue as is. If the line is empty, this sends a zero-length record up the tty's read side. Reading zero bytes from a file or device-file is interpreted as EOF by many systems, including Go's os.File reader. If you type a partial line, without a terminating newline, and then use control-D to send it, you can no longer edit that partial line, and a reader that is reading and is not concerned with newlines will have obtained the data and be using it at this point. A second control-D is then required to signal the EOF: the reader simply got the non-newline terminated input from the first control-D.
2This link describes Linux tty drivers, but Linux tty drivers are derived from the same common ancestor behind MacOS tty drivers.
3This is not an accident, even though the Go folks are not the Darwin folks: again, all this stuff goes back (via different paths) to some common ancestors.

Space characters inside the ESC[ (0x1b/0x5b) sequence invalidate the sequence?

I can not find information about what should be done to spaces within ESC sequence. Example: position cursor
ESC[10;20H
is a valid ESC sequence, but is the one including spaces like
ESC[ 10; 20H
valid too? The point is that while ESC character is a control character with code 0x1b, text following it is human and machine readable text, and in general spaces should not harm the meaning of ESC sequence, thus I would just remove all the spaces found within ESC sequence.
Lots of article on the internet talking what ESC sequence is and what they may consist of (however there're only just few good and really informative ones), but none of them clarify this matter.
I found this one, and it says
Since ASCII control functions do not follow a structured syntax, the notation used to describe function sequences and parameters is important to avoid confusion. Escape sequences are shown with a space between each character to make them easier to read. These spaces are not part of the Escape sequence.
While it says that space char separates characters for readability, they do not say if keeping space invalidates the ESC sequence.
Is there any related RFC for it? I hope it unambiguously defines this case.
Update: thanks Thomas to pointing to space char being one of the ESC sequence operators. So now it is clear that [ should follow ESC character, and space is not allowed between them.
But what is about following arguments? As in the example above, spaces in row and column coordinates ESC[SP10;SP20H makes sequence invalid and I must stop processing it starting displaying space character instead?
Update1: I did small test using Windows telnet application. Logged into the remote server, and that server responds with ESC sequence. The result is:
ESC[2;5H positions properly row 2 column 5
ESC[ 2; 5H displays "2; 5H" in current cursor position
ESC[2 ; 5H displays "; 5H" in current cursor position
So basing on the empirical findings I suspect spaces are NOT allowed, and space char invalidates/cancels the sequence.
ECMA-48's the place to look (if you want an RFC). Look for mention of 02/00 (the way it represents the hexadecimal 0x20 for space).
For what it's worth, there are DEC control sequences (VT220 and up) with an embedded space, e.g., the ones marked with SP:
Controls beginning with ESC
This excludes controls where ESC is part of a 7-bit equivalent to 8-bit
C1 controls, ordered by the final character(s).
ESC SP F 7-bit controls (S7C1T), VT220.
ESC SP G 8-bit controls (S8C1T), VT220.
ESC SP L Set ANSI conformance level 1 (dpANS X3.134.1).
ESC SP M Set ANSI conformance level 2 (dpANS X3.134.1).
ESC SP N Set ANSI conformance level 3 (dpANS X3.134.1).
In your examples, the whitespace is just for readability, and non-printing characters such as ASCII escape (decimal 27, hexadecimal 01xb) are shown by a name such as ESC.

Where can I find a list of terminal ANSI codes sent by Ctrl-key sequences?

I am writing some behavioural tests for code that interacts with a terminal and I need to assert behaviour on the sequence C-p C-q (ctrl-p ctrl-q). In order to do this, I need to write the raw characters to the PTY. I have a small mapping at the moment for things like C-d => 0x04, C-h => 0x08.
Is there somewhere I can get a basic mapping of human readable control sequences, mapped to raw byte sequences for xterm?
Take the ASCII value of the character (e.g., for ^H, take 72), and subtract 64. Thus, ^H is 8.
This works for any control character. Using it, you can discover that, for example, ^# is the NUL character and ^[ is ESC.

ANSI questions: "\x1B[?25h" and "\x1BE"

What does "\x1B[?25h" do?
How is "\x1BE" different from "\n"? According to http://ascii-table.com/ansi-escape-sequences-vt-100.php it "moves to next line"? Seems like that's what "\n" does?
I tried echo "xxx\nxxx\n" and echo "xxx\x1BExxx\n" in PHP and they both output the same thing.
Any ideas?
Thanks!
These are ANSI escape sequences (also known as VT100 codes) are an early standardisation of control codes pre-dating ASCII.
The escape sequence \x1BE, or Esc+E, is NEL or "Next line", and is used on older terminals and mainframes to denote CR+LF, or \r\n.
The escape sequence \x1B[ (Esc+[) is an example of a Control Sequence Introducer. (\x9B is another single-character CSI.) The control sequence ?25h following it is used to show the cursor.
Most terminals will support these control codes; to enter escape sequences you can type Ctrl+V, Ctrl+[ which should render as ^[ (the C0 code for ESC), followed by the escape code.
References:
ANSI escape code
C0 and C1 control codes

PuTTY Cntrl Characters

Using PuTTY to talk with my PIC chip over a Serial connection. I want to recognize <CR> <Backspace> <Cursor Up> <Cursor Dwn> <Cursor left> <Cursor Right> and do the correct thing in the LCD display.
I figured this should be easy enough. Just go look at an Ascii table and use the Hex values being sent. Problem is I guess PuTTY sends more than one value for each of the cntrl char values.
Is there a list I can refer to for these values that I can modify my code with or is the answer starring me in the face?
I don't know the specifics of PuTTY's protocols, but ASCII does define escape characters - Control+key. To be more specific, ASCII 0 is Control-#, 1 through 26 (0x1 through 0x1a) are Control+the corresponding letter of the alphabet.

Resources