Browse Source

start of step 41 now ...

Eric Streit 1 day ago
parent
commit
d2e45c7c60
74 changed files with 5970 additions and 45 deletions
  1. 0 0
      Done/step36/Makefile
  2. 0 0
      Done/step36/SplitV1.def
  3. 0 0
      Done/step36/SplitV1.mod
  4. 0 0
      Done/step36/SplitV1.o
  5. 0 0
      Done/step36/VT100.def
  6. 0 0
      Done/step36/VT100.mod
  7. 0 0
      Done/step36/VT100.o
  8. 0 0
      Done/step36/Winsize.txt
  9. 0 0
      Done/step36/editor
  10. 0 0
      Done/step36/editor.mod
  11. 0 0
      Done/step36/kilo
  12. 0 0
      Done/step36/kilo.c
  13. 0 0
      Done/step37/Makefile
  14. 0 0
      Done/step37/SplitV1.def
  15. 0 0
      Done/step37/SplitV1.mod
  16. 0 0
      Done/step37/SplitV1.o
  17. 0 0
      Done/step37/VT100.def
  18. 0 0
      Done/step37/VT100.mod
  19. 0 0
      Done/step37/VT100.o
  20. 0 0
      Done/step37/Winsize.txt
  21. 0 0
      Done/step37/editor
  22. 0 0
      Done/step37/editor.mod
  23. 0 0
      Done/step37/kilo
  24. 0 0
      Done/step37/kilo.c
  25. 0 0
      Done/step38/Makefile
  26. 0 0
      Done/step38/SplitV1.def
  27. 0 0
      Done/step38/SplitV1.mod
  28. 0 0
      Done/step38/SplitV1.o
  29. 0 0
      Done/step38/VT100.def
  30. 0 0
      Done/step38/VT100.mod
  31. 0 0
      Done/step38/VT100.o
  32. 0 0
      Done/step38/Winsize.txt
  33. 0 0
      Done/step38/editor
  34. 0 0
      Done/step38/editor.mod
  35. 0 0
      Done/step38/kilo
  36. 0 0
      Done/step38/kilo.c
  37. 0 0
      Done/step39/Makefile
  38. 0 0
      Done/step39/SplitV1.def
  39. 0 0
      Done/step39/SplitV1.mod
  40. 0 0
      Done/step39/SplitV1.o
  41. 0 0
      Done/step39/VT100.def
  42. 0 0
      Done/step39/VT100.mod
  43. 0 0
      Done/step39/VT100.o
  44. 0 0
      Done/step39/Winsize.txt
  45. BIN
      Done/step39/editor
  46. 32 40
      Done/step39/editor.mod
  47. BIN
      Done/step39/kilo
  48. 3 1
      Done/step39/kilo.c
  49. BIN
      Tests/T20
  50. 5 2
      Tests/T20.mod
  51. 8 2
      step40/Makefile
  52. 28 0
      step40/SplitV1.def
  53. 157 0
      step40/SplitV1.mod
  54. BIN
      step40/SplitV1.o
  55. 544 0
      step40/VT100.def
  56. 1594 0
      step40/VT100.mod
  57. BIN
      step40/VT100.o
  58. 150 0
      step40/Winsize.txt
  59. BIN
      step40/editor
  60. 342 0
      step40/editor.mod
  61. BIN
      step40/kilo
  62. 134 0
      step40/kilo.c
  63. 15 0
      step41/Makefile
  64. 28 0
      step41/SplitV1.def
  65. 157 0
      step41/SplitV1.mod
  66. BIN
      step41/SplitV1.o
  67. 544 0
      step41/VT100.def
  68. 1594 0
      step41/VT100.mod
  69. BIN
      step41/VT100.o
  70. 150 0
      step41/Winsize.txt
  71. BIN
      step41/editor
  72. 342 0
      step41/editor.mod
  73. BIN
      step41/kilo
  74. 143 0
      step41/kilo.c

+ 0 - 0
step36/Makefile → Done/step36/Makefile


+ 0 - 0
step36/SplitV1.def → Done/step36/SplitV1.def


+ 0 - 0
step36/SplitV1.mod → Done/step36/SplitV1.mod


+ 0 - 0
step36/SplitV1.o → Done/step36/SplitV1.o


+ 0 - 0
step36/VT100.def → Done/step36/VT100.def


+ 0 - 0
step36/VT100.mod → Done/step36/VT100.mod


+ 0 - 0
step36/VT100.o → Done/step36/VT100.o


+ 0 - 0
step36/Winsize.txt → Done/step36/Winsize.txt


+ 0 - 0
step36/editor → Done/step36/editor


+ 0 - 0
step36/editor.mod → Done/step36/editor.mod


+ 0 - 0
step36/kilo → Done/step36/kilo


+ 0 - 0
step36/kilo.c → Done/step36/kilo.c


+ 0 - 0
step37/Makefile → Done/step37/Makefile


+ 0 - 0
step37/SplitV1.def → Done/step37/SplitV1.def


+ 0 - 0
step37/SplitV1.mod → Done/step37/SplitV1.mod


+ 0 - 0
step37/SplitV1.o → Done/step37/SplitV1.o


+ 0 - 0
step37/VT100.def → Done/step37/VT100.def


+ 0 - 0
step37/VT100.mod → Done/step37/VT100.mod


+ 0 - 0
step37/VT100.o → Done/step37/VT100.o


+ 0 - 0
step37/Winsize.txt → Done/step37/Winsize.txt


+ 0 - 0
step37/editor → Done/step37/editor


+ 0 - 0
step37/editor.mod → Done/step37/editor.mod


+ 0 - 0
step37/kilo → Done/step37/kilo


+ 0 - 0
step37/kilo.c → Done/step37/kilo.c


+ 0 - 0
step38/Makefile → Done/step38/Makefile


+ 0 - 0
step38/SplitV1.def → Done/step38/SplitV1.def


+ 0 - 0
step38/SplitV1.mod → Done/step38/SplitV1.mod


+ 0 - 0
step38/SplitV1.o → Done/step38/SplitV1.o


+ 0 - 0
step38/VT100.def → Done/step38/VT100.def


+ 0 - 0
step38/VT100.mod → Done/step38/VT100.mod


+ 0 - 0
step38/VT100.o → Done/step38/VT100.o


+ 0 - 0
step38/Winsize.txt → Done/step38/Winsize.txt


+ 0 - 0
step38/editor → Done/step38/editor


+ 0 - 0
step38/editor.mod → Done/step38/editor.mod


+ 0 - 0
step38/kilo → Done/step38/kilo


+ 0 - 0
step38/kilo.c → Done/step38/kilo.c


+ 0 - 0
step39/Makefile → Done/step39/Makefile


+ 0 - 0
step39/SplitV1.def → Done/step39/SplitV1.def


+ 0 - 0
step39/SplitV1.mod → Done/step39/SplitV1.mod


+ 0 - 0
step39/SplitV1.o → Done/step39/SplitV1.o


+ 0 - 0
step39/VT100.def → Done/step39/VT100.def


+ 0 - 0
step39/VT100.mod → Done/step39/VT100.mod


+ 0 - 0
step39/VT100.o → Done/step39/VT100.o


+ 0 - 0
step39/Winsize.txt → Done/step39/Winsize.txt


BIN
Done/step39/editor


+ 32 - 40
step39/editor.mod → Done/step39/editor.mod

@@ -2,7 +2,7 @@ MODULE editor1;
 
 (* based on the kilo editor building course*)
 
-(* Step 28 *)
+(* Step 39 *)
 
 (******************** INCLUDES ******************)
 
@@ -33,6 +33,9 @@ VAR
     clearScreenStr      : ARRAY[0..6] OF CHAR;
     cursorHomeStr       : ARRAY[0..2] OF CHAR;
     requestCursorPosStr : ARRAY[0..15] OF CHAR;
+    cursorOnStr          : ARRAY[0..6] OF CHAR;
+    cursorOffStr         : ARRAY[0..6] OF CHAR;
+    tildeStr             : ARRAY[0..3] OF CHAR;
 
     resultStr           : ARRAY [0..15] OF CHAR;
     tmpString           : ARRAY[0..15] OF CHAR;
@@ -131,17 +134,10 @@ VAR
         VAR
             llen : CARDINAL;
     BEGIN
-        (*  REALLOCATE - attempts to reallocate storage. The address,
-            a, should either be NIL in which case ALLOCATE
-            is called, or alternatively it should have already
-            been initialized by ALLOCATE. The allocated storage
-            is resized accordingly. *)
-        (* PROCEDURE REALLOCATE (VAR a: ADDRESS; Size: CARDINAL) ; *)
-        (* PROCEDURE MemCopy (from: ADDRESS; length: CARDINAL; to: ADDRESS) ; *)
         llen := Strings.Length(str);
         IF ptr <> NIL THEN
             IF ptr^.b = NIL THEN
-                Storage.ALLOCATE(ptr^.b,llen)
+                Storage.ALLOCATE(ptr^.b,llen);
             ELSE
                 Storage.REALLOCATE( ptr^.b,ptr^.len + llen);
             END;
@@ -153,8 +149,6 @@ VAR
     PROCEDURE abFree (VAR ptr : abufTypePtr);
 
     BEGIN
-        (* PROCEDURE DEALLOCATE (VAR a: ADDRESS ; Size: CARDINAL) ; *)
-        (* PROCEDURE DISPOSE (VAR p:<any pointer type>) ; *)
         Storage.DEALLOCATE(ptr^.b, ptr^.len);
         Storage.DEALLOCATE(ptr,SYSTEM.TSIZE(abufType));
     END abFree;
@@ -165,27 +159,14 @@ VAR
 
         VAR
             y : CARDINAL;
-            str : ARRAY [0..15] OF CHAR;
+            str : ARRAY [0..3] OF CHAR;
 
     BEGIN
-        abufInit(ptr);
-        IF ptr = NIL THEN
-            die("not enough memory")
-        END;
-        str[0] := "~";
-        str[1] := CHR(13);
-        str[2] := CHR(10);
-        str[3] := CHR(0);
-        (* FOR y := 1 TO editorConfig.screenrows -1 DO
-            libc.write(FIO.StdOut,SYSTEM.ADR(str),3);
-        END;*)
         FOR y := 1 TO editorConfig.screenrows -1 DO
-            abAppend(ptr,str)
+            abAppend(ptr,tildeStr)
         END;
-        (* IO.Write("~"); *)
         abAppend(ptr,"~");
-        libc.write(FIO.StdOut,ptr^.b,ptr^.len);
-        abFree(ptr);
+        (* libc.write(FIO.StdOut,ptr^.b,ptr^.len); *)
     END editorDrawRows;
 
    PROCEDURE editorRefreshScreen;
@@ -193,16 +174,15 @@ VAR
         VAR
             ptr : abufTypePtr;
     BEGIN
-        (* modif  using libc write procedure *)
-        libc.write(FIO.StdOut,SYSTEM.ADR(clearScreenStr),4);
-        libc.write(FIO.StdOut,SYSTEM.ADR(cursorHomeStr),3);
-        (* abAppend(ptr,clearScreenStr);
-        abAppend(ptr,cursorHomeStr); *)
+        abufInit(ptr);
+        abAppend(ptr,cursorOffStr);
+        abAppend(ptr,clearScreenStr);
+        abAppend(ptr,cursorHomeStr);
         editorDrawRows(ptr);
-        libc.write(FIO.StdOut,SYSTEM.ADR(cursorHomeStr),3);
-        (* abAppend(ptr,cursorHomeStr);
+        abAppend(ptr,cursorHomeStr);
+        abAppend(ptr,cursorOnStr);
         libc.write(FIO.StdOut,ptr^.b,ptr^.len);
-        abFree(ptr); *)
+        abFree(ptr);
     END editorRefreshScreen;
 
     PROCEDURE requestCursorPosition(VAR x,y : CARDINAL);
@@ -215,10 +195,6 @@ VAR
         SplitV1.InitStructure(theStructure);
         Strings.Concat(str,ASCII.esc,str);
         Strings.Concat(str,"[6n", str);
-        (* sending request *)
-        (* FOR i := 0 TO 3 DO
-            IO.Write(str[i])
-        END; *)
         libc.write(FIO.StdOut,SYSTEM.ADR(str),4);
         (* getting answer *)
         str := "";
@@ -227,13 +203,14 @@ VAR
             cc[0] := c;
             Strings.Concat(str,cc,str);
         UNTIL c = "R";
-
+        (* DEBUG*)
         (* displaying the retour , changing the escape to ? *)
         (* str[0] := "?"; *)
         (* FOR i := 0 TO Strings.Length(str) DO
             IO.Write(str[i])
         END; *)
         (* libc.write(FIO.StdOut,SYSTEM.ADR(str),Length(str)); *)
+        (* END DEBUG*)
         (* extracting the coordinates *)
         Strings.Delete(str,0,2);
         Strings.Delete(str,Strings.Length(str) -1 ,1);
@@ -309,6 +286,21 @@ VAR
         requestCursorPosStr := "";
         Strings.Concat(requestCursorPosStr,ASCII.esc,requestCursorPosStr);
         Strings.Concat(requestCursorPosStr,"[6n",requestCursorPosStr);
+    
+        cursorOnStr := "";
+        Strings.Concat(cursorOnStr,ASCII.esc,cursorOnStr);
+        Strings.Concat(cursorOnStr,"[?25h",cursorOnStr);
+        
+        cursorOffStr := "";
+        Strings.Concat(cursorOffStr,ASCII.esc,cursorOffStr);
+        Strings.Concat(cursorOffStr,"[?25l",cursorOffStr);
+        
+        tildeStr := "~";
+        cc[0] := CHR(13);
+        Strings.Concat(tildeStr,cc,tildeStr);
+        cc[0] := CHR(10);
+        Strings.Concat(tildeStr,cc,tildeStr);
+
     END InitScreenEscapes;
 
     PROCEDURE InitEditor;

BIN
step39/kilo → Done/step39/kilo


+ 3 - 1
step39/kilo.c → Done/step39/kilo.c

@@ -92,6 +92,7 @@ void editorDrawRows(struct abuf *ab) {
   int y;
   for (y = 0; y < E.screenrows; y++) {
     abAppend(ab, "~", 1);
+    abAppend(ab, "\x1b[K", 3);
     if (y < E.screenrows - 1) {
       abAppend(ab, "\r\n", 2);
     }
@@ -99,10 +100,11 @@ void editorDrawRows(struct abuf *ab) {
 }
 void editorRefreshScreen() {
   struct abuf ab = ABUF_INIT;
-  abAppend(&ab, "\x1b[2J", 4);
+  abAppend(&ab, "\x1b[?25l", 6);
   abAppend(&ab, "\x1b[H", 3);
   editorDrawRows(&ab);
   abAppend(&ab, "\x1b[H", 3);
+  abAppend(&ab, "\x1b[?25h", 6);
   write(STDOUT_FILENO, ab.b, ab.len);
   abFree(&ab);
 }

BIN
Tests/T20


+ 5 - 2
Tests/T20.mod

@@ -37,7 +37,7 @@ PROCEDURE abAppend (VAR ptr : abufTypePtr; str: ARRAY OF CHAR );
         llen := Strings.Length(str);
         IF ptr <> NIL THEN
             IF ptr^.b = NIL THEN
-                Storage.ALLOCATE(ptr^.b,llen)
+                Storage.ALLOCATE(ptr^.b,llen);
             ELSE
                 Storage.REALLOCATE( ptr^.b,ptr^.len + llen);
             END;
@@ -52,7 +52,10 @@ BEGIN
     str := " Bonjour les petits amis!";
     abAppend(abufPtr, str);
 
-    str := " coucou";
+    str := " coucou! ";
+    abAppend(abufPtr, str);
+
+    str := "    et encore une chaîne :D  ";
     abAppend(abufPtr, str);
 
     (* writing the string in the terminal *)

+ 8 - 2
step40/Makefile

@@ -4,6 +4,12 @@ kilo: kilo.c
 #	echo "building the C version"
 	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
 
-editor: editor.mod
+editor: editor.mod VT100.o SplitV1.o
 #	echo "building the Modula-2 version"
-	gm2 -fiso -o editor editor.mod
+	gm2 -fiso -o editor SplitV1.o VT100.o editor.mod
+
+SplitV1.o:
+	gm2 -fiso -c SplitV1.mod
+
+VT100.o:
+	gm2 -fiso -c VT100.mod

+ 28 - 0
step40/SplitV1.def

@@ -0,0 +1,28 @@
+DEFINITION MODULE SplitV1;
+
+TYPE
+  Element = RECORD
+              pos : CARDINAL;
+              element : ARRAY[0..255] OF CHAR;
+            END;  
+  Structure = ARRAY[0..20] OF Element;    
+ 
+VAR 
+  trimMode    : BOOLEAN;
+  allTrimMode : BOOLEAN;
+  noDupMode   : BOOLEAN;
+  rtrim       : BOOLEAN;
+  ltrim       : BOOLEAN;
+  
+                  
+PROCEDURE Ltrim ( VAR src : ARRAY OF CHAR; separator : CHAR  );
+  
+PROCEDURE Rtrim ( VAR src : ARRAY OF CHAR ; separator : CHAR );
+    
+PROCEDURE removeDuplicate ( VAR src : ARRAY OF CHAR ; separator : CHAR );             
+                  
+PROCEDURE SplitStr(s : ARRAY OF CHAR; separator : CHAR; VAR out : Structure); 
+
+PROCEDURE InitStructure ( VAR out : Structure);
+
+END SplitV1.

+ 157 - 0
step40/SplitV1.mod

@@ -0,0 +1,157 @@
+IMPLEMENTATION MODULE SplitV1;
+
+IMPORT Strings;
+FROM InOut IMPORT Write, WriteString, WriteCard, WriteLn;
+
+VAR
+  j : CARDINAL;
+  
+PROCEDURE Ltrim (VAR src : ARRAY OF CHAR; separator : CHAR  );
+
+VAR
+  longueur : CARDINAL;
+  
+  BEGIN
+    REPEAT
+      longueur := LENGTH(src);
+      IF src[0] = separator THEN
+      	(*PROCEDURE Delete (VAR stringVar: ARRAY OF CHAR; startIndex, numberToDelete:CARDINAL);*)
+        (* Deletes at most numberToDelete characters from stringVar, starting at position startIndex.*)
+        Strings.Delete(src,0,1);
+      END;  
+    UNTIL (src[0] # separator) OR (longueur = 0)
+  END Ltrim;     
+  
+PROCEDURE Rtrim ( VAR src : ARRAY OF CHAR ; separator : CHAR );
+
+VAR
+  longueur : CARDINAL;
+  
+  BEGIN
+    longueur := LENGTH(src);
+    REPEAT
+      longueur := LENGTH(src);
+      IF src[longueur - 1] = separator THEN
+      	(*PROCEDURE Delete (VAR stringVar: ARRAY OF CHAR; startIndex, numberToDelete:CARDINAL);*)
+        (* Deletes at most numberToDelete characters from stringVar, starting at position startIndex.*)
+        Strings.Delete(src,longueur - 1,1);
+      END;  
+      longueur := LENGTH(src);
+    UNTIL (src[longueur - 1] # separator) OR (longueur =0 ) 
+   END Rtrim;  
+  
+PROCEDURE removeDuplicate ( VAR src : ARRAY OF CHAR ; separator : CHAR );             
+
+VAR
+  longueur : CARDINAL;
+  pos      : CARDINAL;
+  
+  BEGIN
+    pos := 0;
+    longueur := LENGTH(src);
+    LOOP
+      IF (longueur = 0 ) OR (pos = longueur ) THEN
+        RETURN
+      END;
+      (*Write(src[pos]);Write(" ");*)
+      IF src[pos] = separator THEN 
+        pos := pos + 1;
+        WHILE src[pos] = separator DO 
+          Strings.Delete(src,pos,1);
+        END; 
+      ELSE 
+        INC(pos) 
+      END;  
+      longueur := LENGTH(src);
+    END; (* end loop*)
+  END removeDuplicate;   
+  
+PROCEDURE SplitStr(s : ARRAY OF CHAR; separator : CHAR; VAR out : Structure) ;
+
+(*
+  There are several cases to take account for :
+  - standard case : s begin with an element and end with an element
+  - s begins with a separator and end with an element
+  - s begins with a separator and ends with a separators
+  - there are consecutive separators inside s
+  - there are consecutive separators at the beginning
+  - there are consecutive separators at the end
+*)
+
+VAR 
+  i : CARDINAL;
+  indice : CARDINAL;
+  longueur : CARDINAL;
+  resultat : ARRAY[0..255] OF CHAR;
+  deja : BOOLEAN;
+  c : CHAR;
+  
+  BEGIN
+    indice := 0; 
+    (* modes de fonctionnement *)
+    (*  trimMode    : BOOLEAN;
+        allTrimMode : BOOLEAN;
+        noDupMode   : BOOLEAN;
+        rtrim       : BOOLEAN;
+        ltrim       : BOOLEAN;*)
+    IF trimMode THEN
+      Rtrim ( s, separator);
+      Ltrim ( s, separator);
+    END;
+    
+    IF ltrim THEN
+      Ltrim ( s, separator);
+    END;
+    
+    IF rtrim THEN
+      Rtrim ( s, separator);
+    END;    
+    
+    IF noDupMode THEN
+      removeDuplicate ( s, separator);
+    END;
+    
+    IF allTrimMode THEN
+      Rtrim ( s, separator);
+      Ltrim ( s, separator);
+      removeDuplicate ( s, separator);
+    END;  
+    
+    longueur := LENGTH(s);
+    resultat := "";
+    deja := FALSE;
+    FOR i := 0 TO longueur -1 DO
+      c := s[i]; 						(* the first character of the string s *)
+      IF c # separator THEN 					(* the character belongs to an element *)
+         Strings.Append(Strings.String1(c),resultat);
+      ELSE
+        out[indice].element := resultat;
+        resultat := ""; 
+        INC(indice);
+      END;
+      out[indice].element := resultat;
+    END;
+    FOR i := indice + 1 TO HIGH(out) DO 
+      out[i].pos := MAX(CARDINAL);
+    END;
+  END SplitStr;
+
+PROCEDURE InitStructure ( VAR out : Structure);
+
+VAR 
+  i : CARDINAL;
+  
+BEGIN 
+  FOR i := 0 TO HIGH(out)   DO
+    out[i].pos := i;
+    out[i].element := "";
+  END;
+END InitStructure;
+
+BEGIN 
+  trimMode    := FALSE;
+  allTrimMode := FALSE;
+  noDupMode   := FALSE;
+  ltrim       := FALSE;
+  rtrim       := FALSE; 
+END SplitV1. 

BIN
step40/SplitV1.o


+ 544 - 0
step40/VT100.def

@@ -0,0 +1,544 @@
+DEFINITION MODULE VT100;
+
+(*
+ The POSIX function cfmakeraw() sets the canonical
+ combination. Applications typically use tcgetattr()
+ to save the current settings, call cfmakeraw() 
+ to switch to raw mode, and call tcsetattr() with 
+ the saved settings on exit to restore the terminal.
+*)
+
+TYPE 
+    screenModes = (M40x25BW,M40x25C,M80x25BW,M80x25C,M320x200C4,M320x200BW,M640x200BW,
+                   M320x200C256,M640x200C,M640x350BW,M640x350C,M640x480BW,M640x480C,M320x200C);
+    Attribut    = (boldAt,dimAt,italicAt,underlineAt,blinkingAt,inverseAt,hiddenAt,
+                   strikethroughAt,doubleunderlineAt);
+
+    Colors      = (Black, Red, Green, Yellow, Blue, Magenta, Cyan, White, Default,
+                    BrightBlack, BrightRed, BrightGreen, BrightYellow, 
+                    BrightBlue, BrighMagenta, BrightCyan, BrightWhite);
+(*
+PROCEDURE setnl;
+(* LMN             Set new line mode                      ^[[20h *)
+
+PROCEDURE setappl;
+(* DECCKM        Set cursor key to application          ^[[?1h *)
+
+PROCEDURE setansi;
+(* DECANM        Set ANSI (versus VT52)                 none *)
+
+PROCEDURE setcol;
+(* DECCOLM        Set number of columns to 132           ^[[?3h *)
+
+PROCEDURE setsmooth;
+(* DECSCLM     Set smooth scrolling                   ^[[?4h *)
+
+PROCEDURE setrevscrn;
+(* DECSCNM    Set reverse video on screen            ^[[?5h *)
+
+PROCEDURE setorgrel;
+(* DECOM       Set origin to relative                 ^[[?6h *)
+
+PROCEDURE setwrap;
+(* DECAWM        Set auto-wrap mode                     ^[[?7h *)
+
+PROCEDURE setrep;
+(* DECARM         Set auto-repeat mode                   ^[[?8h *)
+
+PROCEDURE setinter;
+(* DECINLM      Set interlacing mode                   ^[[?9h *)
+
+PROCEDURE setlf;
+(* LMN             Set line feed mode                     ^[[20l *)
+
+PROCEDURE setcursor;
+(* DECCKM      Set cursor key to cursor               ^[[?1l *)
+
+PROCEDURE setvt52;
+(* DECANM        Set VT52 (versus ANSI)                 ^[[?2l *)
+
+PROCEDURE resetcol;
+(* DECCOLM      Set number of columns to 80            ^[[?3l *)
+
+PROCEDURE setjump;
+(* DECSCLM       Set jump scrolling                     ^[[?4l *)
+
+PROCEDURE setnormscrn;
+(* DECSCNM   Set normal video on screen             ^[[?5l *)
+
+PROCEDURE setorgabs;
+(* DECOM       Set origin to absolute                 ^[[?6l *)
+
+PROCEDURE resetwrap;
+(* DECAWM      Reset auto-wrap mode                   ^[[?7l *)
+
+PROCEDURE resetrep;
+(* DECARM       Reset auto-repeat mode                 ^[[?8l *)
+
+PROCEDURE resetinter;
+(* DECINLM    Reset interlacing mode                 ^[[?9l *)
+
+PROCEDURE altkeypad;
+(* DECKPAM     Set alternate keypad mode              ^[= *)
+
+PROCEDURE numkeypad;
+(* DECKPNM     Set numeric keypad mode                ^[> *)
+
+PROCEDURE setukg0;
+    (* Set United Kingdom G0 character set    ^[(A *)
+
+PROCEDURE setukg1;
+    (* Set United Kingdom G1 character set    ^[)A *)
+
+PROCEDURE setusg0;
+(* Set United States G0 character set     ^[(B *)
+
+PROCEDURE setusg1;
+(* Set United States G1 character set     ^[)B *)
+
+PROCEDURE setspecg0;
+(* Set G0 special chars. & line set       ^[(0 *)
+
+PROCEDURE setspecg1;
+(* Set G1 special chars. & line set       ^[)0 *)
+
+PROCEDURE setaltg0;
+(* Set G0 alternate character ROM         ^[(1 *)
+
+PROCEDURE setaltg1;
+(* Set G1 alternate character ROM         ^[)1 *)
+
+PROCEDURE setaltspecg0;
+(* Set G0 alt char ROM and spec. graphics ^[(2 *)
+
+PROCEDURE setaltspecg1;
+(* Set G1 alt char ROM and spec. graphics ^[)2 *)
+
+PROCEDURE setss2 ;
+(* SS2 Set single shift 2                 ^[N *)
+
+PROCEDURE setss3;
+(* SS3 Set single shift 3                  ^[O *)
+*)
+
+(*
+ESC Code Sequence 	Reset Sequence 	Description
+ESC[1;34;{...}m 		Set graphics modes for cell, separated by semicolon (;).
+ESC[1m 	ESC[22m 	set bold mode.
+ESC[2m 	ESC[22m 	set dim/faint mode.
+ESC[3m 	ESC[23m 	set italic mode.
+ESC[4m 	ESC[24m 	set underline mode.
+ESC[5m 	ESC[25m 	set blinking mode
+ESC[7m 	ESC[27m 	set inverse/reverse mode
+ESC[8m 	ESC[28m 	set hidden/invisible mode
+ESC[9m 	ESC[29m 	set strikethrough mode.
+ESC[21m ESC[24m    set double underline
+*)
+
+PROCEDURE modesoff; (*OK*)
+(* SGR0 Turn off character attributes          ^[[m *)
+
+PROCEDURE modesoff1; (*OK*)
+(* SGR0 Turn off character attributes          ^[[0m *)
+
+PROCEDURE bold; (*OK*)
+(* SGR1 Turn bold mode on                      ^[[1m *)
+
+PROCEDURE lowint; (*OK*)
+(* SGR2 Turn low intensity mode on             ^[[2m *)
+
+PROCEDURE italic; (*OK*)
+(* set italic mode                              ESC[3m *)
+
+PROCEDURE underline; (*OK*)
+(* SGR4 Turn underline mode on                 ^[[4m *)
+
+PROCEDURE blink; (*OK*)
+(* SGR5 Turn blinking mode on                  ^[[5m *)
+
+PROCEDURE reverse; (*OK*)
+(* SGR7 Turn reverse video on                  ^[[7m *)
+
+PROCEDURE invisible; (*OK*)
+(* SGR8 Turn invisible text mode on            ^[[8m *)
+
+PROCEDURE strikethrough; (*OK*)
+(* ESC[9m 	ESC[29m 	set strikethrough mode. *)
+
+PROCEDURE doubleUnderline;
+(* ESC[21m *)
+
+PROCEDURE resetbold; (*OK*)
+(* SGR1 Turn bold mode on                      ^[[1m *)
+
+PROCEDURE resetlowint; (*OK*)
+(* SGR2 Turn low intensity mode on             ^[[2m *)
+
+PROCEDURE resetitalic; (*OK*)
+(* set italic mode                              ESC[3m *)
+
+PROCEDURE resetunderline; (*OK*)
+(* SGR4 Turn underline mode on                 ^[[4m *)
+
+PROCEDURE resetblink; (*OK*)
+(* SGR5 Turn blinking mode on                  ^[[5m *)
+
+PROCEDURE resetreverse; (*OK*)
+(* SGR7 Turn reverse video on                  ^[[7m *)
+
+PROCEDURE resetinvisible; (*OK*)
+(* SGR8 Turn invisible text mode on            ^[[8m *)
+
+PROCEDURE resetstrikethrough; (*OK*)
+(* ESC[9m 	ESC[29m 	set strikethrough mode. *)
+
+PROCEDURE resetDoubleUnderline;
+(* ESC[24m. *)
+
+(*
+PROCEDURE setwin;
+(* DECSTBM Set top and bottom line#s of a window  ^[[<v>;<v>r *)
+*)
+
+(*
+ESC Code Sequence 	Description
+ESC[H 	moves cursor to home position (0, 0)
+ESC[{line};{column}H
+ESC[{line};{column}f 	moves cursor to line #, column #
+ESC[#A 	moves cursor up # lines
+ESC[#B 	moves cursor down # lines
+ESC[#C 	moves cursor right # columns
+ESC[#D 	moves cursor left # columns
+ESC[#E 	moves cursor to beginning of next line, # lines down
+ESC[#F 	moves cursor to beginning of previous line, # lines up
+ESC[#G 	moves cursor to column #
+
+ESC[6n 	request cursor position (reports as ESC[#;#R)
+ESC M 	moves cursor one line up, scrolling if needed
+ESC 7 	save cursor position (DEC)
+ESC 8 	restores the cursor to the last saved position (DEC)
+ESC[s 	save cursor position (SCO)
+ESC[u 	restores the cursor to the last saved position (SCO)
+*)
+
+PROCEDURE cursorup(n : CARDINAL); (*OK*)
+(* CUU Move cursor up n lines                 ^[[<n>A *)
+
+PROCEDURE cursordn(n : CARDINAL); (*OK*)
+(* CUD Move cursor down n lines               ^[[<n>B *)
+
+PROCEDURE cursorrt(n : CARDINAL); (*OK*)
+(* CUF Move cursor right n lines              ^[[<n>C *)
+
+PROCEDURE cursor1lf(n : CARDINAL); (*OK*)
+(* CUB Move cursor left n lines               ^[[<n>D *)
+
+PROCEDURE cursorbnl(n : CARDINAL);
+(* ESC[#E 	moves cursor to beginning of next line, # lines down *)
+
+PROCEDURE cursorblpl(n : CARDINAL);
+(* ESC[#F 	moves cursor to beginning of previous line, # lines up *)
+
+PROCEDURE cursottocol(n : CARDINAL);
+(* ESC[#G 	moves cursor to column # *)
+
+PROCEDURE requestCursorPosition(VAR x,y : CARDINAL);
+(* ESC[6n 	request cursor position (reports as ESC[#;#R) *)
+
+PROCEDURE cursorhome; (*OK*)
+(* Move cursor to upper left corner       ^[[H *)
+
+PROCEDURE cursorhome1; (*OK*)
+(* Move cursor to upper left corner       ^[[;H *)
+
+PROCEDURE cursorpos(x,y: CARDINAL); (*OK*)
+(* CUP Move cursor to screen location v,h     ^[[<v>;<h>H *)
+(*
+PROCEDURE hvhome;
+(* Move cursor to upper left corner       ^[[f *)
+
+PROCEDURE hvhome;
+(* Move cursor to upper left corner       ^[[;f *)
+
+PROCEDURE hvpos(v,h);
+(* CUP Move cursor to screen location v,h     ^[[<v>;<h>f *)
+
+PROCEDURE index;
+(* IND Move/scroll window up one line         ^[D *)
+
+PROCEDURE revindex;
+(* RI Move/scroll window down one line       ^[M *)
+
+PROCEDURE nextline;
+(* NEL Move to next line                      ^[E *)
+
+PROCEDURE savecursor;
+(* DECSC Save cursor position and attributes    ^[7 *)
+
+PROCEDURE restorecursor;
+(* DECSC Restore cursor position and attributes ^[8 *)
+
+PROCEDURE tabset;
+(* HTS Set a tab at the current column        ^[H *)
+
+PROCEDURE tabclr;
+(* TBC Clear a tab at the current column      ^[[g *)
+
+PROCEDURE tabclr;
+(* TBC Clear a tab at the current column      ^[[0g *)
+
+PROCEDURE tabclrall;
+(* TBC Clear all tabs                         ^[[3g *)
+
+PROCEDURE dhtop;
+(* DECDHL Double-height letters, top half        ^[#3 *)
+
+PROCEDURE dhbot;
+(* DECDHL Double-height letters, bottom half     ^[#4 *)
+
+PROCEDURE swsh;
+(* DECSWL Single width, single height letters    ^[#5 *)
+
+PROCEDURE dwsh;
+(* DECDWL Double width, single height letters    ^[#6 *)
+
+PROCEDURE cleareol;
+(* EL0 Clear line from cursor right           ^[[K *)
+
+PROCEDURE cleareol;
+(* EL0 Clear line from cursor right           ^[[0K *)
+
+PROCEDURE clearbol;
+(* EL1 Clear line from cursor left            ^[[1K *)
+
+PROCEDURE clearline;
+(* EL2 Clear entire line                      ^[[2K *)
+
+PROCEDURE cleareos;
+(* ED0 Clear screen from cursor down          ^[[J *)
+
+PROCEDURE cleareos;
+(* ED0 Clear screen from cursor down          ^[[0J *)
+
+PROCEDURE clearbos;
+(* ED1 Clear screen from cursor up            ^[[1J *)
+*)
+PROCEDURE clearscreen; (* OK *)
+(* ED2 Clear entire screen                    ^[[2J *)
+(*
+PROCEDURE devstat;
+(* DSR Device status report                   ^[5n *)
+
+PROCEDURE termok;
+(* DSR Response: terminal is OK            ^[0n *)
+
+PROCEDURE termnok;
+(* DSR Response: terminal is not OK        ^[3n *)
+
+PROCEDURE getcursor;
+(* DSR Get cursor position                    ^[6n *)
+
+PROCEDURE cursorpos;
+(* CPR Response: cursor is at v,h          ^[<v>;<h>R *)
+
+PROCEDURE ident;
+(* DA Identify what terminal type            ^[[c *)
+
+PROCEDURE ident;
+(* DA Identify what terminal type (another)  ^[[0c *)
+
+PROCEDURE gettype;
+(* DA Response: terminal type code n      ^[[?1;<n>0c *)
+
+PROCEDURE reset;
+(* RIS Reset terminal to initial state        ^[c *)
+
+PROCEDURE align;
+(* DECALN Screen alignment display               ^[#8 *)
+
+PROCEDURE testpu;
+(* DECTST Confidence power up test               ^[[2;1y *)
+
+PROCEDURE testlb;
+(* DECTST Confidence loopback test               ^[[2;2y *)
+
+PROCEDURE testpurep;
+(* DECTST Repeat power up test                   ^[[2;9y *)
+
+PROCEDURE testlbrep;
+(* DECTST Repeat loopback test                   ^[[2;10y *)
+
+PROCEDURE ledsoff;
+(* DECLL0 Turn off all four leds                 ^[[0q *)
+
+PROCEDURE led1;
+(* DECLL1 Turn on LED #1                         ^[[1q *)
+
+PROCEDURE led2;
+(* DECLL2 Turn on LED #2                         ^[[2q *)
+
+PROCEDURE led3;
+(* DECLL3 Turn on LED #3                         ^[[3q *)
+
+PROCEDURE led4;
+(* DECLL4 Turn on LED #4                         ^[[4q *)
+*)
+
+(*
+Screen Modes
+Set Mode
+ESC Code Sequence 	Description
+ESC[={value}h 	Changes the screen width or type to the mode specified by value.
+ESC[=0h 	40 x 25 monochrome (text)
+ESC[=1h 	40 x 25 color (text)
+ESC[=2h 	80 x 25 monochrome (text)
+ESC[=3h 	80 x 25 color (text)
+ESC[=4h 	320 x 200 4-color (graphics)
+ESC[=5h 	320 x 200 monochrome (graphics)
+ESC[=6h 	640 x 200 monochrome (graphics)
+ESC[=7h 	Enables line wrapping
+ESC[=13h 	320 x 200 color (graphics)
+ESC[=14h 	640 x 200 color (16-color graphics)
+ESC[=15h 	640 x 350 monochrome (2-color graphics)
+ESC[=16h 	640 x 350 color (16-color graphics)
+ESC[=17h 	640 x 480 monochrome (2-color graphics)
+ESC[=18h 	640 x 480 color (16-color graphics)
+ESC[=19h 	320 x 200 color (256-color graphics)
+ESC[={value}l 	Resets the mode by using the same values that Set Mode uses, except for 7, which disables line wrapping. The last character in this escape sequence is a lowercase L.
+Common Private Modes
+*)
+PROCEDURE screenMode(mode : screenModes);
+
+PROCEDURE resetScreenMode(mode : screenModes);
+
+PROCEDURE lineWrapping;
+
+PROCEDURE resetLineWrapping;
+
+(*
+These are some examples of private modes, which are not defined by the specification, but are implemented in most terminals.
+ESC Code Sequence 	Description
+ESC[?25l 	make cursor invisible
+ESC[?25h 	make cursor visible
+ESC[?47l 	restore screen
+ESC[?47h 	save screen
+ESC[?1049h 	enables the alternative buffer
+ESC[?1049l 	disables the alternative buffer
+*)
+
+PROCEDURE makeCursorInvisible;
+
+PROCEDURE makeCursorVisible;
+
+PROCEDURE restoreScreen;
+
+PROCEDURE saveScreen;
+
+PROCEDURE enableAlternativeBuffer;
+
+PROCEDURE disableAlternativeBuffer;
+
+(*
+Color codes
+
+Most terminals support 8 and 16 colors, as well as 256 (8-bit) colors. These colors are set by the user, but have commonly defined meanings.
+8-16 Colors
+Color Name 	Foreground Color Code 	Background Color Code
+Black 	30 	40
+Red 	31 	41
+Green 	32 	42
+Yellow 	33 	43
+Blue 	34 	44
+Magenta 	35 	45
+Cyan 	36 	46
+White 	37 	47
+Default 	39 	49
+Reset 	0 	0
+
+    Note: the Reset color is the reset code that resets all colors and text effects, Use Default color to reset colors only.
+
+Most terminals, apart from the basic set of 8 colors, also support the "bright" or "bold" colors. These have their own set of codes, mirroring the normal colors, but with an additional ;1 in their codes:
+
+# Set style to bold, red foreground.
+\x1b[1;31mHello
+# Set style to dimmed white foreground with red background.
+\x1b[2;37;41mWorld
+
+Terminals that support the aixterm specification provides bright versions of the ISO colors, without the need to use the bold modifier:
+Color Name 	Foreground Color Code 	Background Color Code
+Bright Black 	90 	100
+Bright Red 	91 	101
+Bright Green 	92 	102
+Bright Yellow 	93 	103
+Bright Blue 	94 	104
+Bright Magenta 	95 	105
+Bright Cyan 	96 	106
+Bright White 	97 	107
+256 Colors
+
+*)
+
+PROCEDURE setAttribut ( attribut: Attribut; front, back : Colors);
+
+(* 
+#
+#  All codes below are for use in VT52 compatibility mode.
+# 
+*)
+
+PROCEDURE VT52setansi; (*OK*)
+               (* Enter/exit ANSI mode (VT52)            ^[< *)
+
+PROCEDURE VT52altkeypad;
+             (* Enter alternate keypad mode            ^[= *)
+
+PROCEDURE VT52numkeypad;
+             (* Exit alternate keypad mode             ^[> *)
+
+PROCEDURE VT52setgr; (* NOT OK*)
+                 (* Use special graphics character set     ^[F *)
+
+PROCEDURE VT52resetgr; (* NOT OK*)
+               (* Use normal US/UK character set         ^[G *)
+
+PROCEDURE VT52cursorup; (*OK*)
+              (* Move cursor up one line                ^[A *)
+
+PROCEDURE VT52cursordn; (*OK*)
+              (* Move cursor down one line              ^[B *)
+
+PROCEDURE VT52cursorrt; (*OK*)
+              (* Move cursor right one char             ^[C *)
+
+PROCEDURE VT52cursorlf; (*OK*)
+              (* Move cursor left one char              ^[D *)
+
+PROCEDURE VT52cursorhome; (*OK*)
+            (* Move cursor to upper left corner       ^[H *)
+
+PROCEDURE VT52cursorpos(x, y : CARDINAL); (* NOT OK*)
+        (* Move cursor to v,h location            ^[<v><h> *)
+
+PROCEDURE VT52revindex;
+              (* Generate a reverse line-feed           ^[I *)
+
+PROCEDURE VT52cleareol; (*OK*)
+              (* Erase to end of current line           ^[K *)
+
+PROCEDURE VT52cleareos; (*OK*)
+              (* Erase to end of screen                 ^[J *)
+
+PROCEDURE VT52ident;
+                 (* Identify what the terminal is          ^[Z *)
+
+PROCEDURE VT52identresp;
+             (*Correct response to ident             ^[/Z   *) 
+
+PROCEDURE CloseTerminal;
+    (* PROCEDURE tcsetattr (fd: INTEGER; option: INTEGER; t: TERMIOS) : INTEGER ; *)
+
+PROCEDURE InitTerminal;
+(* PROCEDURE tcgetattr (fd: INTEGER; t: TERMIOS) : INTEGER ; *)
+
+
+END VT100.

+ 1594 - 0
step40/VT100.mod

@@ -0,0 +1,1594 @@
+IMPLEMENTATION MODULE VT100;
+
+IMPORT ASCII;
+FROM STextIO IMPORT WriteString, WriteChar, WriteLn, ReadString;
+FROM NumberIO IMPORT WriteCard, CardToStr,StrToCard;
+FROM Strings IMPORT Concat, Length, String1, Assign, Delete;
+FROM NumberIO IMPORT WriteHex;
+FROM Delay IMPORT Delay;
+IMPORT SplitV1;
+IMPORT termios;
+
+(*
+Name                  DASCII.escription                            ASCII.esc Code
+
+setnl LMN             Set new line mode                      ^[[20h
+setappl DECCKM        Set cursor key to application          ^[[?1h
+setansi DECANM        Set ANSI (versus VT52)                 none
+setcol DECCOLM        Set number of columns to 132           ^[[?3h
+setsmooth DECSCLM     Set smooth scrolling                   ^[[?4h
+setrevscrn DECSCNM    Set reverse video on screen            ^[[?5h
+setorgrel DECOM       Set origin to relative                 ^[[?6h
+setwrap DECAWM        Set auto-wrap mode                     ^[[?7h
+setrep DECARM         Set auto-repeat mode                   ^[[?8h
+setinter DECINLM      Set interlacing mode                   ^[[?9h
+
+setlf LMN             Set line feed mode                     ^[[20l
+setcursor DECCKM      Set cursor key to cursor               ^[[?1l
+setvt52 DECANM        Set VT52 (versus ANSI)                 ^[[?2l
+resetcol DECCOLM      Set number of columns to 80            ^[[?3l
+setjump DECSCLM       Set jump scrolling                     ^[[?4l
+setnormscrn DECSCNM   Set normal video on screen             ^[[?5l
+setorgabs DECOM       Set origin to absolute                 ^[[?6l
+resetwrap DECAWM      Reset auto-wrap mode                   ^[[?7l
+resetrep DECARM       Reset auto-repeat mode                 ^[[?8l
+resetinter DECINLM    Reset interlacing mode                 ^[[?9l
+
+altkeypad DECKPAM     Set alternate keypad mode              ^[=
+numkeypad DECKPNM     Set numeric keypad mode                ^[>
+
+setukg0               Set United Kingdom G0 character set    ^[(A
+setukg1               Set United Kingdom G1 character set    ^[)A
+setusg0               Set United States G0 character set     ^[(B
+setusg1               Set United States G1 character set     ^[)B
+setspecg0             Set G0 special chars. & line set       ^[(0
+setspecg1             Set G1 special chars. & line set       ^[)0
+setaltg0              Set G0 alternate character ROM         ^[(1
+setaltg1              Set G1 alternate character ROM         ^[)1
+setaltspecg0          Set G0 alt char ROM and spec. graphics ^[(2
+setaltspecg1          Set G1 alt char ROM and spec. graphics ^[)2
+
+setss2 SS2            Set single shift 2                     ^[N
+setss3 SS3            Set single shift 3                     ^[O
+
+modesoff SGR0         Turn off character attributes          ^[[m
+modesoff SGR0         Turn off character attributes          ^[[0m
+bold SGR1             Turn bold mode on                      ^[[1m
+lowint SGR2           Turn low intensity mode on             ^[[2m
+underline SGR4        Turn underline mode on                 ^[[4m
+blink SGR5            Turn blinking mode on                  ^[[5m
+reverse SGR7          Turn reverse video on                  ^[[7m
+invisible SGR8        Turn invisible text mode on            ^[[8m
+
+setwin DECSTBM        Set top and bottom line#s of a window  ^[[<v>;<v>r
+
+cursorup(n) CUU       Move cursor up n lines                 ^[[<n>A
+cursordn(n) CUD       Move cursor down n lines               ^[[<n>B
+cursorrt(n) CUF       Move cursor right n lines              ^[[<n>C
+cursorlf(n) CUB       Move cursor left n lines               ^[[<n>D
+cursorhome            Move cursor to upper left corner       ^[[H
+cursorhome            Move cursor to upper left corner       ^[[;H
+cursorpos(v,h) CUP    Move cursor to screen location v,h     ^[[<v>;<h>H
+hvhome                Move cursor to upper left corner       ^[[f
+hvhome                Move cursor to upper left corner       ^[[;f
+hvpos(v,h) CUP        Move cursor to screen location v,h     ^[[<v>;<h>f
+index IND             Move/scroll window up one line         ^[D
+revindex RI           Move/scroll window down one line       ^[M
+nextline NEL          Move to next line                      ^[E
+savecursor DECSC      Save cursor position and attributes    ^[7
+restorecursor DECSC   Restore cursor position and attributes ^[8
+
+tabset HTS            Set a tab at the current column        ^[H
+tabclr TBC            Clear a tab at the current column      ^[[g
+tabclr TBC            Clear a tab at the current column      ^[[0g
+tabclrall TBC         Clear all tabs                         ^[[3g
+
+dhtop DECDHL          Double-height letters, top half        ^[#3
+dhbot DECDHL          Double-height letters, bottom half     ^[#4
+swsh DECSWL           Single width, single height letters    ^[#5
+dwsh DECDWL           Double width, single height letters    ^[#6
+
+cleareol EL0          Clear line from cursor right           ^[[K
+cleareol EL0          Clear line from cursor right           ^[[0K
+clearbol EL1          Clear line from cursor left            ^[[1K
+clearline EL2         Clear entire line                      ^[[2K
+
+cleareos ED0          Clear screen from cursor down          ^[[J
+cleareos ED0          Clear screen from cursor down          ^[[0J
+clearbos ED1          Clear screen from cursor up            ^[[1J
+clearscreen ED2       Clear entire screen                    ^[[2J
+
+devstat DSR           Device status report                   ^[5n
+termok DSR               Response: terminal is OK            ^[0n
+termnok DSR              Response: terminal is not OK        ^[3n
+
+getcursor DSR         Get cursor position                    ^[6n
+cursorpos CPR            Response: cursor is at v,h          ^[<v>;<h>R
+
+ident DA              Identify what terminal type            ^[[c
+ident DA              Identify what terminal type (another)  ^[[0c
+gettype DA               Response: terminal type code n      ^[[?1;<n>0c
+
+reset RIS             Reset terminal to initial state        ^[c
+
+align DECALN          Screen alignment display               ^[#8
+testpu DECTST         Confidence power up test               ^[[2;1y
+testlb DECTST         Confidence loopback test               ^[[2;2y
+testpurep DECTST      Repeat power up test                   ^[[2;9y
+testlbrep DECTST      Repeat loopback test                   ^[[2;10y
+
+ledsoff DECLL0        Turn off all four leds                 ^[[0q
+led1 DECLL1           Turn on LED #1                         ^[[1q
+led2 DECLL2           Turn on LED #2                         ^[[2q
+led3 DECLL3           Turn on LED #3                         ^[[3q
+led4 DECLL4           Turn on LED #4                         ^[[4q
+
+#
+#  All codes below are for use in VT52 compatibility mode.
+#
+
+setansi               Enter/exit ANSI mode (VT52)            ^[<
+
+altkeypad             Enter alternate keypad mode            ^[=
+numkeypad             Exit alternate keypad mode             ^[>
+
+setgr                 Use special graphics character set     ^[F
+resetgr               Use normal US/UK character set         ^[G
+
+cursorup              Move cursor up one line                ^[A
+cursordn              Move cursor down one line              ^[B
+cursorrt              Move cursor right one char             ^[C
+cursorlf              Move cursor left one char              ^[D
+cursorhome            Move cursor to upper left corner       ^[H
+cursorpos(v,h)        Move cursor to v,h location            ^[<v><h>
+revindex              Generate a reverse line-feed           ^[I
+
+cleareol              Erase to end of current line           ^[K
+cleareos              Erase to end of screen                 ^[J
+
+ident                 Identify what the terminal is          ^[Z
+identresp             Correct response to ident              ^[/Z
+
+*)
+
+(*                    VT52 compatibility mode                 *)
+
+TYPE 
+    Array2  = ARRAY[0..1] OF CHAR;  
+    Array3  = ARRAY[0..2] OF CHAR;
+    Array4  = ARRAY[0..3] OF CHAR;
+    Array5  = ARRAY[0..4] OF CHAR;
+    Array6  = ARRAY[0..5] OF CHAR;
+    Array8  = ARRAY[0..7] OF CHAR;
+    Array10 = ARRAY[0..9] OF CHAR;
+
+
+VAR 
+    theterminal : termios.TERMIOS;
+    savedFd     : INTEGER;
+
+VAR                 (* cursor *)
+    cursorupStr     : Array3;
+    cursordnStr     : Array3;             
+    cursorrtStr     : Array3;            
+    cursorlfStr     : Array3;            
+    cursorhomeStr   : Array3;       
+    cursorposStr    : ARRAY [0..10] OF CHAR;
+    revindexStr     : Array3;        
+
+    cleareolStr     : Array3;         
+    cleareosStr     : Array3; 
+    
+VAR                 (* ident *)
+    identStr        : Array3; 
+    identrespStr    : ARRAY [0..3] OF CHAR;
+
+VAR                 (* graphic *)
+    setgrStr        : Array3;
+    resetgrStr      : Array3; 
+
+VAR                 (* VT52 mode *)
+    setansiStr      : Array3; 
+
+VAR                 (* keypad switch *)
+    altkeypadStr    : Array3;
+    numkeypadStr    :   Array3; 
+
+(*                                    VT100                                      *)
+VAR
+    setnlStr        : Array3;
+    setapplStr      : Array3;
+    setansi1Str     : Array3;
+    setcolStr       : Array3;
+    setsmoothStr    : Array3;
+    setrevscrnStr   : Array3;
+    setorgrelStr    : Array3;
+    setwrapStr      : Array3;
+    setrepStr       : Array3;
+    setinterStr     : Array3;
+
+    setlfStr        : Array3;
+    setcursorStr    : Array3;
+    setvt52Str      : Array3;
+    resetcolStr     : Array3;
+    setjumpStr      : Array3;
+    setnormscrnStr  : Array3;
+    setorgabsStr    : Array3;
+    resetwrapStr    : Array3;
+    resetrepStr     : Array3;
+    resetinterStr   : Array3;
+
+    altkeypad1Str   : Array3;
+    numkeypad1Str   : Array3;
+
+    setukg0Str      : Array3;
+    setukg1Str      : Array3;
+    setusg0Str      : Array3;
+    setusg1Str      : Array3;
+    setspecg0Str    : Array3;
+    setspecg1Str    : Array3;
+    setaltg0Str     : Array3;
+    setaltg1Str     : Array3;
+    setaltspecg0Str : Array3;
+    setaltspecg1Str : Array3;
+
+    setss2Str       : Array3;
+    setss3Str       : Array3;
+
+    modesoff0Str    : Array3;
+    modesoff1Str    : Array4;
+    boldStr         : Array4;
+    lowintStr       : Array4;
+    underlineStr    : Array4;
+    blinkStr        : Array4;
+    reverseStr      : Array4;
+    invisibleStr    : Array4;
+    italicStr       : Array4;
+    strikethroughStr: Array4; 
+
+    resetboldStr         : Array5;
+    resetlowintStr       : Array5;
+    resetunderlineStr    : Array5;
+    resetblinkStr        : Array5;
+    resetreverseStr      : Array5;
+    resetinvisibleStr    : Array5;
+    resetitalicStr       : Array5;
+    resetstrikethroughStr: Array5;
+
+    setwinStr       : Array3;
+
+    cursorup1Str    : Array3;
+    cursordn1Str    : Array3;
+    cursorrt1Str    : Array3;
+    cursorlf1Str    : Array3;
+    cursorhome0Str  : Array3;
+    cursorhome1Str  : Array4;
+    cursorpos1Str   : Array3;
+    hvhome0Str      : Array3;
+    hvhome1Str      : Array3;
+    hvposStr        : Array3;
+    indexStr        : Array3;
+    revindex1Str    : Array3;
+    nextlineStr     : Array3;
+    savecursStr     : Array3;
+    restorecursorStr: Array3;
+    requestCursorPositionStr: Array6;
+    tabsetStr       : Array3;
+    tabclr0Str      : Array3;
+    tabclr1Str      : Array3;
+    tabclrallStr    : Array3;
+
+    dhtopStr        : Array3;
+    dhbotStr        : Array3;
+    swshStr         : Array3;
+    dwshStr         : Array3;
+
+    cleareol0Str    : Array3;
+    cleareol1Str    : Array3;
+    clearbol2Str    : Array3;
+    clearlineStr    : Array3;
+
+    cleareos0Str    : Array3;
+    cleareos1Str    : Array3;
+    clearbos2Str    : Array3;
+    clearscreenStr  : Array4;
+
+    devstatStr      : Array3;
+    termokStr       : Array3;
+    termnokStr      : Array3;
+
+    getcursorStr    : Array3;
+    cursorpos2Str   : Array3;
+    cursorbnlStr    : Array3;
+    cursorblplStr   : Array3;
+    cursottocolStr  : Array3;
+    ident1Str       : Array3;
+    ident2Str       : Array3;
+    gettypeStr      : Array3;
+
+    resetStr        : Array3;
+
+    alignStr        : Array3;
+    testpuStr       : Array3;
+    testlbStr       : Array3;
+    testpurepStr    : Array3;
+    testlbrepStr    : Array3;
+    (* screen modes *)
+    resetScreenModeStr : Array6;
+    ledsoffStr      : Array3;
+    led1Str         : Array3;
+    led2Str         : Array3;
+    led3Str         : Array3;
+    led4Str         : Array3;
+    M40x25BWStr      : Array4;
+    M40x25CStr       : Array5;
+    M80x25BWStr      : Array5;
+    M80x25CStr       : Array5;
+    M320x200C4Str     : Array6;
+    M320x200BWStr    : Array6;
+    M640x200BWStr    : Array6;
+    M320x200C256Str     : Array6;
+    M640x200CStr     : Array6;
+    M640x350BWStr    : Array6;
+    M640x350CStr     : Array6;
+    M640x480BWStr    : Array6;
+    M640x480CStr     : Array6;
+    M320x200CStr     : Array6;
+    lineWrappingStr  : Array6;
+    resetLineWrappingStr : Array6;
+
+    (* some proprietary extensions *)
+    makeCursorInvisibleStr      : Array6;
+    makeCursorVisibleStr        : Array6;
+    restoreScreenStr            : Array6;
+    saveScreenStr               : Array6;
+    enableAlternativeBufferStr  : Array10;
+    disableAlternativeBufferStr : Array10;
+
+    doubleUnderlineStr           : Array6;
+    resetDoubleUnderlineStr     : Array6;
+    
+    (* colors *)
+    setAttributStr  : Array2;
+
+VAR
+    i : CARDINAL;
+
+PROCEDURE Card2Str ( x : CARDINAL; VAR str : ARRAY OF CHAR);
+
+BEGIN
+IF x < 10 THEN
+        CardToStr(x,1,str);
+    ELSIF x < 100 THEN
+        CardToStr(x,2,str);
+    ELSE
+        CardToStr(x,3,str);
+    END;
+END Card2Str;
+
+PROCEDURE affiche ( m : ARRAY OF CHAR; s : ARRAY OF CHAR);
+
+BEGIN
+    WriteString(m);WriteLn;
+    FOR i := 0 TO Length(s) DO
+        WriteHex(ORD(s[i]),2);
+        WriteChar(" ")
+    END; 
+    WriteLn;
+END affiche;
+
+(*
+PROCEDURE setnl;
+(* LMN             Set new line mode                      ^[[20h *)
+BEGIN
+END ;
+
+PROCEDURE setappl;
+(* DECCKM        Set cursor key to application          ^[[?1h *)
+BEGIN
+END ;
+
+PROCEDURE setansi;
+(* DECANM        Set ANSI (versus VT52)                 none *)
+BEGIN
+END ;
+
+PROCEDURE setcol;
+(* DECCOLM        Set number of columns to 132           ^[[?3h *)
+BEGIN
+END ;
+
+PROCEDURE setsmooth;
+(* DECSCLM     Set smooth scrolling                   ^[[?4h *)
+BEGIN
+END ;
+
+PROCEDURE setrevscrn;
+(* DECSCNM    Set reverse video on screen            ^[[?5h *)
+BEGIN
+END ;
+
+PROCEDURE setorgrel;
+(* DECOM       Set origin to relative                 ^[[?6h *)
+BEGIN
+END ;
+
+PROCEDURE setwrap;
+(* DECAWM        Set auto-wrap mode                     ^[[?7h *)
+BEGIN
+END ;
+
+PROCEDURE setrep;
+(* DECARM         Set auto-repeat mode                   ^[[?8h *)
+BEGIN
+END ;
+
+PROCEDURE setinter;
+(* DECINLM      Set interlacing mode                   ^[[?9h *)
+BEGIN
+END ;
+
+PROCEDURE setlf;
+(* LMN             Set line feed mode                     ^[[20l *)
+BEGIN
+END ;
+
+PROCEDURE setcursor;
+(* DECCKM      Set cursor key to cursor               ^[[?1l *)
+BEGIN
+END ;
+
+PROCEDURE setvt52;
+(* DECANM        Set VT52 (versus ANSI)                 ^[[?2l *)
+BEGIN
+END ;
+
+PROCEDURE resetcol;
+(* DECCOLM      Set number of columns to 80            ^[[?3l *)
+BEGIN
+END ;
+
+PROCEDURE setjump;
+(* DECSCLM       Set jump scrolling                     ^[[?4l *)
+BEGIN
+END ;
+
+PROCEDURE setnormscrn;
+(* DECSCNM   Set normal video on screen             ^[[?5l *)
+BEGIN
+END ;
+
+PROCEDURE setorgabs;
+(* DECOM       Set origin to absolute                 ^[[?6l *)
+BEGIN
+END ;
+
+PROCEDURE resetwrap;
+(* DECAWM      Reset auto-wrap mode                   ^[[?7l *)
+BEGIN
+END ;
+
+PROCEDURE resetrep;
+(* DECARM       Reset auto-repeat mode                 ^[[?8l *)
+BEGIN
+END ;
+
+PROCEDURE resetinter;
+(* DECINLM    Reset interlacing mode                 ^[[?9l *)
+BEGIN
+END ;
+
+PROCEDURE altkeypad;
+(* DECKPAM     Set alternate keypad mode              ^[= *)
+BEGIN
+END ;
+
+PROCEDURE numkeypad;
+(* DECKPNM     Set numeric keypad mode                ^[> *)
+BEGIN
+END ;
+
+PROCEDURE setukg0;
+    (* Set United Kingdom G0 character set    ^[(A *)
+BEGIN
+END ;
+
+PROCEDURE setukg1;
+    (* Set United Kingdom G1 character set    ^[)A *)
+BEGIN
+END ;
+
+PROCEDURE setusg0;
+(* Set United States G0 character set     ^[(B *)
+BEGIN
+END ;
+
+PROCEDURE setusg1;
+(* Set United States G1 character set     ^[)B *)
+BEGIN
+END ;
+
+PROCEDURE setspecg0;
+(* Set G0 special chars. & line set       ^[(0 *)
+BEGIN
+END ;
+
+PROCEDURE setspecg1;
+(* Set G1 special chars. & line set       ^[)0 *)
+BEGIN
+END ;
+
+PROCEDURE setaltg0;
+(* Set G0 alternate character ROM         ^[(1 *)
+BEGIN
+END ;
+
+PROCEDURE setaltg1;
+(* Set G1 alternate character ROM         ^[)1 *)
+BEGIN
+END ;
+
+PROCEDURE setaltspecg0;
+(* Set G0 alt char ROM and spec. graphics ^[(2 *)
+BEGIN
+END ;
+
+PROCEDURE setaltspecg1;
+(* Set G1 alt char ROM and spec. graphics ^[)2 *)
+BEGIN
+END ;
+
+PROCEDURE setss2 ;
+(* SS2 Set single shift 2                 ^[N *)
+BEGIN
+END ;
+
+PROCEDURE setss3;
+(* SS3 Set single shift 3                  ^[O *)
+BEGIN
+END ;
+*)
+PROCEDURE modesoff;
+(* SGR0 Turn off character attributes          ^[[m *)
+BEGIN
+    WriteString(modesoff0Str)
+END modesoff;
+
+PROCEDURE modesoff1;
+(* SGR0 Turn off character attributes          ^[[0m *)
+BEGIN
+    WriteString(modesoff1Str)
+END modesoff1;
+
+PROCEDURE bold;
+(* SGR1 Turn bold mode on                      ^[[1m *)
+BEGIN
+    WriteString(boldStr);
+END bold;
+
+PROCEDURE lowint;
+(* SGR2 Turn low intensity mode on             ^[[2m *)
+BEGIN
+    WriteString(lowintStr)
+END lowint;
+
+PROCEDURE italic;
+(* set italic mode                           ESC[3m *)
+BEGIN
+    WriteString(italicStr)
+END italic;
+
+PROCEDURE underline;
+(* SGR4 Turn underline mode on                 ^[[4m *)
+BEGIN
+    WriteString(underlineStr)
+END underline;
+
+PROCEDURE blink;
+(* SGR5 Turn blinking mode on                  ^[[5m *)
+BEGIN
+    WriteString(blinkStr)
+END blink;
+
+PROCEDURE reverse;
+(* SGR7 Turn reverse video on                  ^[[7m *)
+BEGIN
+    WriteString(reverseStr)
+END reverse;
+
+PROCEDURE invisible;
+(* SGR8 Turn invisible text mode on            ^[[8m *)
+BEGIN
+    WriteString(invisibleStr)
+END invisible;
+
+PROCEDURE strikethrough;
+BEGIN
+    WriteString(strikethroughStr)
+END strikethrough;
+
+PROCEDURE doubleUnderline;
+(* ESC[21m *)
+BEGIN
+    WriteString(doubleUnderlineStr)
+END doubleUnderline;
+
+PROCEDURE resetbold;
+(* SGR1 Turn bold mode on                      ^[[21m *)
+
+BEGIN
+    WriteString(resetboldStr)
+END resetbold;
+
+PROCEDURE resetlowint;
+(* SGR2 Turn low intensity mode on             ^[[22m *)
+BEGIN
+    WriteString(resetlowintStr)
+END resetlowint;
+
+
+PROCEDURE resetitalic;
+(* set italic mode                              ESC[23m *)
+BEGIN
+    WriteString(resetitalicStr)
+END resetitalic;
+
+
+PROCEDURE resetunderline;
+(* SGR4 Turn underline mode on                 ^[[24m *)
+BEGIN
+    WriteString(resetunderlineStr)
+END resetunderline;
+
+
+PROCEDURE resetblink;
+(* SGR5 Turn blinking mode on                  ^[[25m *)
+BEGIN
+    WriteString(resetblinkStr)
+END resetblink;
+
+
+PROCEDURE resetreverse;
+(* SGR7 Turn reverse video on                  ^[[27m *)
+BEGIN
+    WriteString(resetreverseStr)
+END resetreverse;
+
+
+PROCEDURE resetinvisible;
+(* SGR8 Turn invisible text mode on            ^[[28m *)
+BEGIN
+    WriteString(resetinvisibleStr)
+END resetinvisible;
+
+
+PROCEDURE resetstrikethrough;
+(* ESC[9m 	ESC[29m 	set strikethrough mode. *)
+BEGIN
+    WriteString(resetstrikethroughStr)
+END resetstrikethrough;
+
+PROCEDURE resetDoubleUnderline;
+(* ESC[24m. *)
+BEGIN
+    WriteString(resetDoubleUnderlineStr)
+END resetDoubleUnderline;
+
+
+(*
+PROCEDURE setwin;
+(* DECSTBM Set top and bottom line#s of a window  ^[[<v>;<v>r *)
+BEGIN
+END ;
+*)
+PROCEDURE cursorup(n : CARDINAL);
+(* CUU Move cursor up n lines                 ^[[<n>A *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+
+BEGIN
+    tmpString := "";
+    Card2Str(n,tmpString1);
+    tmpString2[0] := "A";
+
+    Concat(tmpString,cursorup1Str, tmpString);
+    Concat(tmpString, tmpString1,tmpString);
+    Concat(tmpString, tmpString2,tmpString);
+    WriteString(tmpString)
+END cursorup;
+
+PROCEDURE cursordn(n : CARDINAL);
+(* CUD Move cursor down n lines               ^[[<n>B *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+
+BEGIN
+    tmpString := "";
+    Card2Str(n,tmpString1);
+    tmpString2[0] := "B";
+
+    Concat(tmpString,cursordn1Str, tmpString);
+    Concat(tmpString, tmpString1,tmpString);
+    Concat(tmpString, tmpString2,tmpString);
+    WriteString(tmpString) 
+END cursordn;
+
+PROCEDURE cursorrt(n : CARDINAL);
+(* CUF Move cursor right n lines              ^[[<n>C *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+
+BEGIN
+    tmpString := "";
+    Card2Str(n,tmpString1);
+    tmpString2[0] := "C";
+
+    Concat(tmpString,cursorrt1Str, tmpString);
+    Concat(tmpString, tmpString1,tmpString);
+    Concat(tmpString, tmpString2,tmpString);
+    WriteString(tmpString)
+END cursorrt;
+
+PROCEDURE cursor1lf(n : CARDINAL);
+(* CUB Move cursor left n lines               ^[[<n>D *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+
+BEGIN
+    tmpString := "";
+    Card2Str(n,tmpString1);
+    tmpString2[0] := "D";
+
+    Concat(tmpString,cursorlf1Str, tmpString);
+    Concat(tmpString, tmpString1,tmpString);
+    Concat(tmpString, tmpString2,tmpString);
+    WriteString(tmpString)
+END cursor1lf;
+
+PROCEDURE cursorbnl(n : CARDINAL);
+(* ESC[#E 	moves cursor to beginning of next line, # lines down *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+    
+BEGIN
+    tmpString     := "";
+    tmpString2[0] := "E";
+    Card2Str(n,tmpString1);
+    Concat(tmpString,tmpString1,tmpString);
+    Concat(tmpString,tmpString2,tmpString);
+    WriteString(tmpString)
+END cursorbnl;
+
+PROCEDURE cursorblpl(n : CARDINAL);
+(* ESC[#F 	moves cursor to beginning of previous line, # lines up *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+    
+BEGIN
+    tmpString := "";
+    tmpString2[0] := "F";
+    Card2Str(n,tmpString1);
+    Concat(tmpString,tmpString1,tmpString);
+    Concat(tmpString,tmpString2,tmpString);
+    WriteString(tmpString)
+END cursorblpl;
+
+PROCEDURE cursottocol(n : CARDINAL);
+(* ESC[#G 	moves cursor to column # *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+    
+BEGIN
+    tmpString := "";
+    tmpString2[0] := "G";
+    Card2Str(n,tmpString1);
+    Concat(tmpString,tmpString1,tmpString);
+    Concat(tmpString,tmpString2,tmpString);
+    WriteString(tmpString)
+END cursottocol;
+
+PROCEDURE requestCursorPosition(VAR x,y : CARDINAL);
+(* ESC[6n 	request cursor position (reports as ESC[#;#R) *)
+
+VAR
+    str          : ARRAY [0..15] OF CHAR;
+    theStructure : SplitV1.Structure;
+
+BEGIN
+    SplitV1.InitStructure(theStructure);
+    (* sending the request *)
+    WriteString(requestCursorPositionStr);
+    (* quering the answer *)
+    ReadString(str);
+    (* extracting coodinates from the answer *)
+    (*PROCEDURE Delete (VAR stringVar: ARRAY OF CHAR; startIndex, numberToDelete: CARDINAL);
+D   eletes at most numberToDelete characters from stringVar, starting at position startIndex.
+    *)
+    Delete(str,0,2);
+    Delete(str,Length(str) -1 ,1);
+    SplitV1.SplitStr(str, ";", theStructure);
+    StrToCard(theStructure[0].element,x);
+    StrToCard(theStructure[1].element,y);
+
+END requestCursorPosition;
+
+PROCEDURE cursorhome;
+(* Move cursor to upper left corner       ^[[H *)
+BEGIN
+    WriteString(cursorhomeStr)
+END cursorhome;
+
+PROCEDURE cursorhome1;
+(* Move cursor to upper left corner       ^[[;H *)
+BEGIN
+    WriteString(cursorhome1Str)
+END cursorhome1;
+
+PROCEDURE cursorpos(x,y : CARDINAL);
+(* CUP Move cursor to screen location v,h     ^[[<v>;<h>H *)
+
+VAR
+    tmpString : ARRAY[0..10] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+
+BEGIN
+    tmpString := "";
+    (* the preamble *)
+    Concat(tmpString,cursorpos1Str, tmpString);
+
+    (* the first coordinate *)
+    tmpString1 := "";
+    Card2Str(y,tmpString1);
+    Concat(tmpString,tmpString1, tmpString);
+
+    (* the separator *)
+    tmpString2[0] := ";";
+    Concat(tmpString, tmpString2,tmpString);
+
+    (* the second coordinate *)
+    tmpString1 := "";
+    Card2Str(x,tmpString1);
+    Concat(tmpString,tmpString1, tmpString);
+
+    (* the final *)
+    tmpString2[0] := "H";
+    Concat(tmpString, tmpString2,tmpString);
+
+    (*End Debug*)
+    WriteString(tmpString)
+
+END cursorpos;
+(*
+PROCEDURE hvhome;
+(* Move cursor to upper left corner       ^[[f *)
+BEGIN
+END ;
+
+PROCEDURE hvhome;
+(* Move cursor to upper left corner       ^[[;f *)
+BEGIN
+END ;
+
+PROCEDURE hvpos(v,h);
+(* CUP Move cursor to screen location v,h     ^[[<v>;<h>f *)
+BEGIN
+END ;
+
+PROCEDURE index;
+(* IND Move/scroll window up one line         ^[D *)
+
+PROCEDURE revindex;
+(* RI Move/scroll window down one line       ^[M *)
+BEGIN
+END ;
+
+PROCEDURE nextline;
+(* NEL Move to next line                      ^[E *)
+BEGIN
+END ;
+
+PROCEDURE savecursor;
+(* DECSC Save cursor position and attributes    ^[7 *)
+BEGIN
+END ;
+
+PROCEDURE restorecursor;
+(* DECSC Restore cursor position and attributes ^[8 *)
+BEGIN
+END ;
+
+PROCEDURE tabset;
+(* HTS Set a tab at the current column        ^[H *)
+BEGIN
+END ;
+
+PROCEDURE tabclr;
+(* TBC Clear a tab at the current column      ^[[g *)
+BEGIN
+END ;
+
+PROCEDURE tabclr;
+(* TBC Clear a tab at the current column      ^[[0g *)
+BEGIN
+END ;
+
+PROCEDURE tabclrall;
+(* TBC Clear all tabs                         ^[[3g *)
+BEGIN
+END ;
+
+PROCEDURE dhtop;
+(* DECDHL Double-height letters, top half        ^[#3 *)
+BEGIN
+END ;
+
+PROCEDURE dhbot;
+(* DECDHL Double-height letters, bottom half     ^[#4 *)
+BEGIN
+END ;
+
+PROCEDURE swsh;
+(* DECSWL Single width, single height letters    ^[#5 *)
+BEGIN
+END ;
+
+PROCEDURE dwsh;
+(* DECDWL Double width, single height letters    ^[#6 *)
+BEGIN
+END ;
+
+PROCEDURE cleareol;
+(* EL0 Clear line from cursor right           ^[[K *)
+BEGIN
+END ;
+
+PROCEDURE cleareol;
+(* EL0 Clear line from cursor right           ^[[0K *)
+BEGIN
+END ;
+
+PROCEDURE clearbol;
+(* EL1 Clear line from cursor left            ^[[1K *)
+BEGIN
+END ;
+
+PROCEDURE clearline;
+(* EL2 Clear entire line                      ^[[2K *)
+BEGIN
+END ;
+
+PROCEDURE cleareos;
+(* ED0 Clear screen from cursor down          ^[[J *)
+BEGIN
+END ;
+
+PROCEDURE cleareos;
+(* ED0 Clear screen from cursor down          ^[[0J *)
+BEGIN
+END ;
+
+PROCEDURE clearbos;
+(* ED1 Clear screen from cursor up            ^[[1J *)
+BEGIN
+END ;
+*)
+PROCEDURE clearscreen;
+(* ED2 Clear entire screen                    ^[[2J *)
+BEGIN
+    WriteString(clearscreenStr)
+END clearscreen;
+(*
+PROCEDURE devstat;
+(* DSR Device status report                   ^[5n *)
+BEGIN
+END ;
+
+PROCEDURE termok;
+(* DSR Response: terminal is OK            ^[0n *)
+BEGIN
+END ;
+
+PROCEDURE termnok;
+(* DSR Response: terminal is not OK        ^[3n *)
+BEGIN
+END ;
+
+PROCEDURE getcursor;
+(* DSR Get cursor position                    ^[6n *)
+BEGIN
+END ;
+
+PROCEDURE cursorpos;
+(* CPR Response: cursor is at v,h          ^[<v>;<h>R *)
+BEGIN
+END ;
+
+PROCEDURE ident;
+(* DA Identify what terminal type            ^[[c *)
+BEGIN
+END ;
+
+PROCEDURE ident;
+(* DA Identify what terminal type (another)  ^[[0c *)
+BEGIN
+END ;
+
+PROCEDURE gettype;
+(* DA Response: terminal type code n      ^[[?1;<n>0c *)
+BEGIN
+END ;
+
+PROCEDURE reset;
+(* RIS Reset terminal to initial state        ^[c *)
+BEGIN
+END ;
+
+PROCEDURE align;
+(* DECALN Screen alignment display               ^[#8 *)
+BEGIN
+END ;
+
+PROCEDURE testpu;
+(* DECTST Confidence power up test               ^[[2;1y *)
+BEGIN
+END ;
+
+PROCEDURE testlb;
+(* DECTST Confidence loopback test               ^[[2;2y *)
+BEGIN
+END ;
+
+PROCEDURE testpurep;
+(* DECTST Repeat power up test                   ^[[2;9y *)
+BEGIN
+END ;
+
+PROCEDURE testlbrep;
+(* DECTST Repeat loopback test                   ^[[2;10y *)
+BEGIN
+END ;
+
+PROCEDURE ledsoff;
+(* DECLL0 Turn off all four leds                 ^[[0q *)
+BEGIN
+END ;
+
+PROCEDURE led1;
+(* DECLL1 Turn on LED #1                         ^[[1q *)
+BEGIN
+END ;
+
+PROCEDURE led2;
+(* DECLL2 Turn on LED #2                         ^[[2q *)
+BEGIN
+END ;
+
+PROCEDURE led3;
+(* DECLL3 Turn on LED #3                         ^[[3q *)
+BEGIN
+END ;
+
+PROCEDURE led4;
+(* DECLL4 Turn on LED #4                         ^[[4q *)
+BEGIN
+END ;
+*)
+
+
+PROCEDURE screenMode(mode : screenModes);
+VAR
+    tmpString   : Array4;
+    scrMode     : screenModes;
+BEGIN
+    tmpString := "";
+    CASE scrMode OF
+        M40x25BW:       Assign(M40x25BWStr, tmpString);       |
+        M40x25C:        Assign(M80x25BWStr, tmpString);       |
+        M80x25BW:       Assign(M80x25BWStr, tmpString);       |
+        M80x25C:        Assign(M80x25CStr, tmpString);        |
+        M320x200C4:     Assign(M320x200C4Str, tmpString);     |
+        M320x200BW:     Assign(M320x200BWStr, tmpString);     |
+        M640x200BW:     Assign(M640x200BWStr, tmpString);     |
+        M320x200C256:   Assign(M320x200C256Str, tmpString);   |
+        M640x200C:      Assign(M640x200CStr, tmpString);      |
+        M640x350BW:     Assign(M640x350BWStr, tmpString);     |
+        M640x350C:      Assign(M640x350CStr, tmpString);      |
+        M640x480BW:     Assign(M640x480BWStr, tmpString);     |
+        M640x480C:      Assign(M640x480CStr, tmpString);      |
+        M320x200C:      Assign(M320x200CStr, tmpString);
+    END;
+    WriteString(tmpString)
+END screenMode;
+
+PROCEDURE resetScreenMode(mode : screenModes);
+BEGIN
+   WriteString(resetScreenModeStr)
+END resetScreenMode;
+
+PROCEDURE lineWrapping;
+BEGIN
+   WriteString(lineWrappingStr)
+END lineWrapping;
+
+PROCEDURE resetLineWrapping;
+BEGIN
+   WriteString(resetLineWrappingStr)
+END resetLineWrapping;
+
+PROCEDURE makeCursorInvisible;
+BEGIN
+   WriteString(makeCursorInvisibleStr)
+END makeCursorInvisible;
+
+PROCEDURE makeCursorVisible;
+BEGIN
+   WriteString(makeCursorVisibleStr)
+END makeCursorVisible;
+
+PROCEDURE restoreScreen;
+BEGIN
+   WriteString(restoreScreenStr)
+END restoreScreen;
+
+PROCEDURE saveScreen;
+BEGIN
+   WriteString(saveScreenStr)
+END saveScreen;
+
+PROCEDURE enableAlternativeBuffer;
+BEGIN
+   WriteString(enableAlternativeBufferStr)
+END enableAlternativeBuffer;
+
+PROCEDURE disableAlternativeBuffer;
+BEGIN
+   WriteString(disableAlternativeBufferStr)
+END disableAlternativeBuffer;
+
+PROCEDURE setAttribut ( attribut : Attribut; front, back : Colors );
+VAR
+    tmpString  : ARRAY [0..15] OF CHAR;
+    tmpString1 : ARRAY [0..1]  OF CHAR;
+    tmpString2 : ARRAY [0..2]  OF CHAR;
+    tmpString3 : String1;
+    tmpString4 : String1;
+    tmpString5 : String1;
+
+    (* esc + [ + attribut + ; + front + ; back + m *)
+BEGIN
+    tmpString1 := "";
+    tmpString2 := "";
+    tmpString3[0] := ";";
+    tmpString4[0] := "m";
+    (* esc [ *)
+    Concat(tmpString,setAttributStr,tmpString);
+    (* attribute *)
+    CASE attribut OF
+      boldAt:           tmpString5[0] := "1";   |
+      dimAt:            tmpString5[0] := "2";   |
+      italicAt:         tmpString5[0] := "3";   |
+      underlineAt:      tmpString5[0] := "4";   |
+      blinkingAt:       tmpString5[0] := "5";   |
+      inverseAt:        tmpString5[0] := "7";   |
+      hiddenAt:         tmpString5[0] := "8";   |
+      strikethroughAt:  tmpString5[0] := "9";   
+      (* doubleunderlineAt:tmpString2 := "21"; *)
+    END;
+    Concat(tmpString,tmpString5,tmpString);
+    (* special case with double underline *)
+    IF attribut = doubleunderlineAt THEN
+        Concat(tmpString,"21",tmpString);
+    END;
+    (* ; *)
+    Concat(tmpString,tmpString3,tmpString);
+    (* front *)
+    CASE front OF
+        Black:          tmpString1 := "30"; |
+        Red:            tmpString1 := "31"; |
+        Green:          tmpString1 := "32"; |
+        Yellow:         tmpString1 := "33"; |
+        Blue:           tmpString1 := "34"; |
+        Magenta:        tmpString1 := "35"; |
+        Cyan:           tmpString1 := "36"; |
+        White:          tmpString1 := "37"; |
+        Default:        tmpString1 := "39"; |
+        BrightBlack:    tmpString1 := "90"; |
+        BrightRed:      tmpString1 := "91"; |
+        BrightGreen:    tmpString1 := "92"; |
+        BrightYellow:   tmpString1 := "93"; |
+        BrightBlue:     tmpString1 := "94"; |
+        BrighMagenta:   tmpString1 := "95"; |
+        BrightCyan:     tmpString1 := "96"; |
+        BrightWhite:    tmpString1 := "97"; 
+    END;
+    Concat(tmpString,tmpString1,tmpString);
+    Concat(tmpString,tmpString3,tmpString);
+    (* back *)
+    CASE back OF
+        Black:          tmpString2 := "40";  |
+        Red:            tmpString2 := "41";  |
+        Green:          tmpString2 := "42";  |
+        Yellow:         tmpString2 := "43";  |
+        Blue:           tmpString2 := "44";  |
+        Magenta:        tmpString2 := "45";  |
+        Cyan:           tmpString2:= "46";   |
+        White:          tmpString2 := "47";  |
+        Default:        tmpString2 := "49";  |
+        BrightBlack:    tmpString2 := "100"; |
+        BrightRed:      tmpString2 := "101"; |
+        BrightGreen:    tmpString2 := "102"; |
+        BrightYellow:   tmpString2 := "103"; |
+        BrightBlue:     tmpString2 := "104"; |
+        BrighMagenta:   tmpString2 := "105"; |
+        BrightCyan:     tmpString2 := "106"; |
+        BrightWhite:    tmpString2 := "107"; 
+    END;
+    Concat(tmpString,tmpString2,tmpString);
+    (* m *)
+    Concat(tmpString,tmpString4,tmpString);
+    WriteString(tmpString)
+
+END setAttribut;
+
+(* 
+#
+#  All codes below are for use in VT52 compatibility mode.
+# 
+*)
+
+PROCEDURE VT52setansi;
+               (* Enter/exit ANSI mode (VT52)            ^[< *)
+BEGIN
+    WriteString(setansiStr)
+END VT52setansi ;
+
+PROCEDURE VT52altkeypad;
+             (* Enter alternate keypad mode            ^[= *)
+BEGIN
+    WriteString(altkeypadStr)
+END VT52altkeypad;
+
+PROCEDURE VT52numkeypad ;
+            (* Exit alternate keypad mode             ^[> *)
+BEGIN
+    WriteString(numkeypadStr)
+END VT52numkeypad;
+
+PROCEDURE VT52setgr ;
+                (* Use special graphics character set     ^[F *)
+BEGIN
+    WriteString(setgrStr)
+END VT52setgr;
+
+PROCEDURE VT52resetgr;
+               (* Use normal US/UK character set         ^[G *)
+BEGIN
+    WriteString(resetgrStr)
+END VT52resetgr;
+
+PROCEDURE VT52cursorup;
+              (* Move cursor up one line                ^[A *)
+BEGIN
+    WriteString(cursorupStr)
+END VT52cursorup;
+
+PROCEDURE VT52cursordn;
+              (* Move cursor down one line              ^[B *)
+BEGIN
+    WriteString(cursordnStr)
+END VT52cursordn;
+
+PROCEDURE VT52cursorrt;
+              (* Move cursor right one char             ^[C *)
+BEGIN
+    WriteString(cursorrtStr)
+END VT52cursorrt;
+
+PROCEDURE VT52cursorlf;
+              (* Move cursor left one char              ^[D *)
+BEGIN
+    WriteString(cursorlfStr)
+END VT52cursorlf;
+
+PROCEDURE VT52cursorhome;
+            (* Move cursor to upper left corner       ^[H *)
+BEGIN
+    WriteString(cursorhomeStr)
+END VT52cursorhome;
+
+PROCEDURE VT52cursorpos(y ,x : CARDINAL);
+        (* Move cursor to v,h location            ^[<v><h> *)
+    VAR
+        tmpString       : ARRAY [0..10] OF CHAR;
+        tmpString1,
+        tmpString2,
+        tmpString3      : String1;
+        xPos, yPos      : CARDINAL;
+
+BEGIN
+    Concat(tmpString,cursorposStr,tmpString);
+    xPos := x  + 31;  
+    yPos := y + 31;  
+    (* don't forget to flip x and y *)
+    tmpString1[0] :=  CHR(yPos);
+    tmpString2[0] :=  CHR(xPos);
+    (* tmpString3[0] :=  "H"; *)
+    Concat(tmpString,tmpString1, tmpString);
+    Concat(tmpString,tmpString2, tmpString);  
+    (* Concat(tmpString,tmpString3, tmpString); *)
+    WriteString(tmpString)
+END VT52cursorpos;
+
+PROCEDURE VT52revindex;
+              (* Generate a reverse line-feed           ^[I *)
+BEGIN
+    WriteString(revindexStr)
+END VT52revindex;
+
+PROCEDURE VT52cleareol;
+              (* Erase to end of current line           ^[K *)
+BEGIN
+    WriteString(cleareolStr)
+END VT52cleareol;
+
+PROCEDURE VT52cleareos;
+              (* Erase to end of screen                 ^[J *)
+BEGIN
+    WriteString(cleareosStr)
+END VT52cleareos;
+
+PROCEDURE VT52ident;
+                 (* Identify what the terminal is          ^[Z *)
+BEGIN
+    WriteString(identStr)
+END VT52ident;
+
+PROCEDURE VT52identresp;
+             (* Correct response to ident              ^[/Z *)
+BEGIN
+    WriteString(identrespStr)
+END VT52identresp; 
+
+PROCEDURE CloseTerminal;
+    (* PROCEDURE tcsetattr (fd: INTEGER; option: INTEGER; t: TERMIOS) : INTEGER ; *)
+
+   VAR
+        theResult : INTEGER;
+BEGIN
+    theResult  := termios.tcsetattr(savedFd,termios.lflusho,theterminal);
+    IF theResult <> 0 THEN
+        WriteString(" Terminal state properly restored !")
+    ELSE
+        WriteString("Terminal not properly restored !")
+    END;
+END CloseTerminal;
+
+
+PROCEDURE InitTerminal;
+(* PROCEDURE tcgetattr (fd: INTEGER; t: TERMIOS) : INTEGER ; *)
+
+    VAR
+        theResult : INTEGER;
+BEGIN
+    theterminal := termios.InitTermios();
+    theResult  := termios.tcgetattr(savedFd, theterminal);
+    IF theResult <> -1 THEN
+        WriteString(" Terminal state properly saved !")
+    ELSE
+        WriteString("Terminal state not properly saved")
+    END;
+    termios.cfmakeraw (theterminal) ;
+END InitTerminal;
+
+BEGIN
+    (* VT 52 mode *)
+    Concat(ASCII.esc,"[<",setansiStr);
+
+    Concat(ASCII.esc,"[=",altkeypadStr);
+    Concat(ASCII.esc,"[>",numkeypadStr);
+
+    Concat(ASCII.esc,"[F",setgrStr);
+    Concat(ASCII.esc,"[G",resetgrStr);
+
+    Concat(ASCII.esc,"[A",cursorupStr);
+    Concat(ASCII.esc,"[B",cursordnStr);
+    Concat(ASCII.esc,"[C",cursorrtStr);
+    Concat(ASCII.esc,"[D",cursorlfStr);
+    Concat(ASCII.esc,"[H",cursorhomeStr);
+    Concat(ASCII.esc,"[Y",cursorposStr);
+    Concat(ASCII.esc,"[I",revindexStr);
+
+    Concat(ASCII.esc,"[K",cleareolStr);
+    Concat(ASCII.esc,"[J",cleareosStr);
+
+    Concat(ASCII.esc,"[Z",identStr);
+    Concat(ASCII.esc,"[/Z",identrespStr);
+
+    (* VT100 mode *)
+    Concat(ASCII.esc,"[",setnlStr);
+    Concat(ASCII.esc,"[",setapplStr);
+    Concat(ASCII.esc,"[",setansi1Str);
+    Concat(ASCII.esc,"[",setcolStr);
+    Concat(ASCII.esc,"[",setsmoothStr);
+    Concat(ASCII.esc,"[",setrevscrnStr);
+    Concat(ASCII.esc,"[",setorgrelStr);
+    Concat(ASCII.esc,"[",setwrapStr);
+    Concat(ASCII.esc,"[",setrepStr);
+    Concat(ASCII.esc,"[",setinterStr);
+
+    Concat(ASCII.esc,"[",setlfStr);
+    Concat(ASCII.esc,"[",setcursorStr);
+    Concat(ASCII.esc,"[",setvt52Str);
+    Concat(ASCII.esc,"[",resetcolStr);
+    Concat(ASCII.esc,"[",setjumpStr);
+    Concat(ASCII.esc,"[",setnormscrnStr);
+    Concat(ASCII.esc,"[",setorgabsStr);
+    Concat(ASCII.esc,"[",resetwrapStr);
+    Concat(ASCII.esc,"[",resetrepStr);
+    Concat(ASCII.esc,"[",resetinterStr);
+
+    Concat(ASCII.esc,"[",altkeypad1Str);
+    Concat(ASCII.esc,"[",numkeypad1Str);
+
+    Concat(ASCII.esc,"[",setukg0Str);
+    Concat(ASCII.esc,"[",setukg1Str);
+    Concat(ASCII.esc,"[",setusg0Str);
+    Concat(ASCII.esc,"[",setusg1Str);
+    Concat(ASCII.esc,"[",setspecg0Str);
+    Concat(ASCII.esc,"[",setspecg1Str);
+    Concat(ASCII.esc,"[",setaltg0Str);
+    Concat(ASCII.esc,"[",setaltg1Str);
+    Concat(ASCII.esc,"[",setaltspecg0Str);
+    Concat(ASCII.esc,"[",setaltspecg1Str);
+
+    Concat(ASCII.esc,"[",setss2Str);
+    Concat(ASCII.esc,"[",setss3Str);
+
+    Concat(ASCII.esc,"[m",modesoff0Str);
+    Concat(ASCII.esc,"[0m",modesoff1Str);
+    Concat(ASCII.esc,"[1m",boldStr);
+    Concat(ASCII.esc,"[2m",lowintStr);
+    Concat(ASCII.esc,"[3m",italicStr);
+    Concat(ASCII.esc,"[4m",underlineStr);
+    Concat(ASCII.esc,"[5m",blinkStr);
+    Concat(ASCII.esc,"[7m",reverseStr);
+    Concat(ASCII.esc,"[8m",invisibleStr);
+    Concat(ASCII.esc,"[9m",strikethroughStr);
+
+    Concat(ASCII.esc,"[22m",resetboldStr);
+    Concat(ASCII.esc,"[22m",resetlowintStr);
+    Concat(ASCII.esc,"[23m",resetitalicStr);
+    Concat(ASCII.esc,"[24m",resetunderlineStr);
+    Concat(ASCII.esc,"[25m",resetblinkStr);
+    Concat(ASCII.esc,"[27m",resetreverseStr);
+    Concat(ASCII.esc,"[28m",resetinvisibleStr);
+    Concat(ASCII.esc,"[29m",resetstrikethroughStr);
+
+
+    Concat(ASCII.esc,"[",setwinStr);
+
+    Concat(ASCII.esc,"[",cursorup1Str);
+    Concat(ASCII.esc,"[",cursordn1Str);
+    Concat(ASCII.esc,"[",cursorrt1Str);
+    Concat(ASCII.esc,"[",cursorlf1Str);
+    Concat(ASCII.esc,"[",cursorhome0Str);
+    Concat(ASCII.esc,"[;H",cursorhome1Str);
+    Concat(ASCII.esc,"[",cursorpos1Str);
+    Concat(ASCII.esc,"[6n",requestCursorPositionStr);
+    Concat(ASCII.esc,"[",hvhome0Str);
+    Concat(ASCII.esc,"[",hvhome1Str);
+    Concat(ASCII.esc,"[",cursorbnlStr);
+    Concat(ASCII.esc,"[",cursorblplStr);
+    Concat(ASCII.esc,"[",cursottocolStr);
+    Concat(ASCII.esc,"[",hvposStr);
+    Concat(ASCII.esc,"[",indexStr);
+    Concat(ASCII.esc,"[",revindex1Str);
+    Concat(ASCII.esc,"[",nextlineStr);
+    Concat(ASCII.esc,"[",savecursStr);
+    Concat(ASCII.esc,"[",restorecursorStr);
+
+    Concat(ASCII.esc,"[",tabsetStr);
+    Concat(ASCII.esc,"[",tabclr0Str);
+    Concat(ASCII.esc,"[",tabclr1Str);
+    Concat(ASCII.esc,"[",tabclrallStr);
+
+    Concat(ASCII.esc,"[",dhtopStr);
+    Concat(ASCII.esc,"[",dhbotStr);
+    Concat(ASCII.esc,"[",swshStr);
+    Concat(ASCII.esc,"[",dwshStr);
+
+    Concat(ASCII.esc,"[",cleareol0Str);
+    Concat(ASCII.esc,"[",cleareol1Str);
+    Concat(ASCII.esc,"[",clearbol2Str);
+    Concat(ASCII.esc,"[",clearlineStr);
+
+    Concat(ASCII.esc,"[",cleareos0Str);
+    Concat(ASCII.esc,"[",cleareos1Str);
+    Concat(ASCII.esc,"[",clearbos2Str);
+    Concat(ASCII.esc,"[2J",clearscreenStr);
+
+    Concat(ASCII.esc,"[",devstatStr);
+    Concat(ASCII.esc,"[",termokStr);
+    Concat(ASCII.esc,"[",termnokStr);
+
+    Concat(ASCII.esc,"[",getcursorStr);
+    Concat(ASCII.esc,"[",cursorpos2Str);
+
+    Concat(ASCII.esc,"[",ident1Str);
+    Concat(ASCII.esc,"[",ident2Str);
+    Concat(ASCII.esc,"[",gettypeStr);
+
+    Concat(ASCII.esc,"[",resetStr);
+
+    Concat(ASCII.esc,"[",alignStr);
+    Concat(ASCII.esc,"[",testpuStr);
+    Concat(ASCII.esc,"[",testlbStr);
+    Concat(ASCII.esc,"[",testpurepStr);
+    Concat(ASCII.esc,"[",testlbrepStr);
+
+    Concat(ASCII.esc,"[",ledsoffStr);
+    Concat(ASCII.esc,"[",led1Str);
+    Concat(ASCII.esc,"[",led2Str);
+    Concat(ASCII.esc,"[",led3Str);
+    Concat(ASCII.esc,"[",led4Str);
+Concat(ASCII.esc,"[=0h",M40x25BWStr);    (*	40 x 25 monochrome (text)*)
+Concat(ASCII.esc,"[=1h",M40x25CStr);     (* 	40 x 25 color (text)*)
+Concat(ASCII.esc,"[=2h",M40x25CStr);     (* 	80 x 25 monochrome (text)*)
+Concat(ASCII.esc,"[=3h",M80x25CStr);     (* 	80 x 25 color (text)*)
+Concat(ASCII.esc,"[=4h",M320x200C4Str);   (* 	320 x 200 4-color (graphics)*)
+Concat(ASCII.esc,"[=5h",M320x200BWStr);  (* 	320 x 200 monochrome (graphics)*)
+Concat(ASCII.esc,"[=6h",M640x200BWStr);  (* 	640 x 200 monochrome (graphics)*)
+Concat(ASCII.esc,"[=7h",resetLineWrappingStr);              (* 	Enables line wrapping*)
+Concat(ASCII.esc,"[=13h",M640x200BWStr); (* 	320 x 200 color (graphics)*)
+Concat(ASCII.esc,"[=14h",M640x200CStr);  (* 	640 x 200 color (16-color graphics)*)
+Concat(ASCII.esc,"[=15h",M640x200CStr);  (* 	640 x 350 monochrome (2-color graphics)*)
+Concat(ASCII.esc,"[=16h",M640x350CStr);  (* 	640 x 350 color (16-color graphics)*)
+Concat(ASCII.esc,"[=17h",M640x480BWStr); (*	640 x 480 monochrome (2-color graphics)*)
+Concat(ASCII.esc,"[=18h",M640x480CStr);  (* 	640 x 480 color (16-color graphics)*)
+Concat(ASCII.esc,"[=19h",M320x200CStr);  (* 	320 x 200 color (256-color graphics)*)
+(* ESC[={value}l *)
+
+
+Concat(ASCII.esc,"[?25l",makeCursorInvisibleStr); (* ESC[?25l 	make cursor invisible *)
+Concat(ASCII.esc,"[?25h",makeCursorVisibleStr); (* ESC[?25h 	make cursor visible *)
+Concat(ASCII.esc,"[?47l",restoreScreenStr); (* ESC[?47l 	restore screen *)
+Concat(ASCII.esc,"[?47h",saveScreenStr); (* ESC[?47h 	save screen *)
+Concat(ASCII.esc,"[?1049h",enableAlternativeBufferStr); (* ESC[?1049h 	enables the alternative buffer *)
+Concat(ASCII.esc,"[?1049l",disableAlternativeBufferStr); (* ESC[?1049l 	disables the alternative buffer *)
+
+
+Concat(ASCII.esc,"[21m",resetinvisibleStr);             (* ESC[21m *)
+Concat(ASCII.esc,"[24m",resetDoubleUnderlineStr);      (* ESC[24m. *)
+Concat(ASCII.esc,"[", setAttributStr);
+
+END VT100.
+
+   (*Debug*)
+    (* chaine := "toto"; *)
+    (* FOR i := 0 TO Length(tmpString) DO
+        WriteHex(ORD(tmpString[i]),2);
+        WriteChar(" ")
+    END; *)
+    (*End Debug*)

BIN
step40/VT100.o


+ 150 - 0
step40/Winsize.txt

@@ -0,0 +1,150 @@
+Programs (such as vi) which automatically adjust to screen resizing are responding to 
+the SIGWINCH signal, and using a system call to obtain the system's information about 
+the screen-size. See for example Get width/height of a terminal window in c++?. By the 
+way, though widely implemented, it does not appear to be documented in POSIX signal.h.
+
+Without taking SIGWINCH into account, a program could ask the terminal about its screensize.
+ The resize program does this, by sending the terminal control sequences to
+
+    move the cursor to the lower-right corner (actually, to row/column 999/999, which is 
+    good enough), and
+    asking the terminal where the cursor really is.
+
+The behavior of ls and vi (and other programs) regarding ANSI control sequences which would 
+be embedded in their output depends upon the design of the program. They likely detect 
+the redirection of their output to a file using the isatty function, and do something 
+different depending on whether the output is to a terminal, or to a file.
+
+
+    if (write_eintr(STDOUT_FILENO, "\x1b[999C\x1b[999B", len) == len) {
+        if (get_cursor_pos(wi) == TERM_SUCCESS) {
+            return TERM_SUCCESS;
+        }
+    }
+
+
+
+    ******************
+
+    // Source - https://codereview.stackexchange.com/a/292637
+// Posted by Madagascar, modified by community. See post 'Timeline' for change history
+// Retrieved 2026-05-28, License - CC BY-SA 4.0
+
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
+
+#define _POSIX_C_SOURCE     200819L
+#define _XOPEN_SOURCE       700
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "io.h"
+#include "sequences.h"
+#include "term.h"
+
+static bool parse_long(const char s[static 1], int base, long val[static 1])
+{
+    char *endptr;
+    errno = 0;
+    const long i = strtol(s, &endptr, base);
+    
+    if (endptr == s || *endptr != '\0' || errno != 0) {
+        return false;
+    }
+
+    *val = i;
+    return true;
+}
+
+static TermCodes get_cursor_pos(WinInfo wi[static 1])
+{
+    /* The cursor is positioned at the bottom right of the window. We can learn 
+     * how many rows and columns there must be on the screen by querying the
+     * position of the cursor. */
+    ssize_t len = (ssize_t) strlen("\x1b[6n");
+
+    if (write_eintr(STDOUT_FILENO, "\x1b[6n", len) != len) {
+        return TERM_FAILURE;
+    }
+
+    /* The reply is an escape sequence of the form '\x1b[24;80R', we will
+     * read it into a buffer until read() returns EOF or until we get to
+     * the 'R' character. */
+    char buf[32];   /* Should be more than enough. */
+
+    for (size_t i = 0; i < sizeof buf - 1; ++i) {
+        if (read_eintr(STDIN_FILENO, &buf[i], 1) != 1 || buf[i] == 'R') {
+            break;
+        }
+    }
+    *buf = '\0';
+
+    /* Skip the escape character and the left square brace. */
+    return memcmp(buf, "\x1b[", 2) != 0
+        || sscanf(&buf[2], "%u;%u", &wi->rows, &wi->cols) != 2
+        ? TERM_FAILURE
+        : TERM_SUCCESS;
+}
+
+TermCodes term_get_winsize(WinInfo wi[static 1])
+{
+#if defined(TIOCGWINSZ)
+    struct winsize ws;
+
+    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) {
+        wi->rows = ws.ws_row;
+        wi->cols = ws.ws_col;
+        return TERM_SUCCESS;
+    }
+#elif defined(TIOCGSIZE) 
+    struct ttysize ts;
+
+    if (ioctl(STDOUT_FILENO, TIOCGSIZE, &ts) == 0) {
+        wi->rows = ts.ts_row;
+        wi->cols = ts.ts_col;
+        return TERM_SUCCESS;
+    }
+#endif /* defined(TIOCGWINSZ) */
+
+    /* ioctl() failed. Fallback to VT100/ANSI escape sequences. */
+    ssize_t len = (ssize_t) strlen("\x1b[999C\x1b[999B");
+
+    if (write_eintr(STDOUT_FILENO, "\x1b[999C\x1b[999B", len) == len) {
+        if (get_cursor_pos(wi) == TERM_SUCCESS) {
+            return TERM_SUCCESS;
+        }
+    }
+    
+    /* write() or get_cursor_pos() failed as well. Now as a last resort, check
+     * LINES and COLUMNS environment variables. 
+     * Though note that these variables are not reliable, are not guaranteed 
+     * to exist, and might not be up to date if the user changes the terminal 
+     * size. If set, the sh, ash, dash, csh shells do not update LINES and
+     * COLUMNS, but bash, fish, zsh, ksh, ksh93u+m, and tcsh handle SIGWINCH to
+     * update these variables. */
+    const char *const rows = getenv("LINES");
+    const char *const cols = getenv("COLUMNS");
+
+    if (rows != nullptr && cols != nullptr) {
+        long r;
+        long c;
+        bool res = parse_long(rows, 10, &r) && parse_long(cols, 10, &c);
+    
+        if (!res || r > UINT_MAX || c > UINT_MAX) {
+            return TERM_FAILURE;
+        }
+
+        wi->rows = (unsigned int) r;
+        wi->cols = (unsigned int) c;
+        return TERM_SUCCESS;
+    }
+    return TERM_FAILURE; 
+}

BIN
step39/editor → step40/editor


+ 342 - 0
step40/editor.mod

@@ -0,0 +1,342 @@
+MODULE editor1;
+
+(* based on the kilo editor building course*)
+
+(* Step 39 *)
+
+(******************** INCLUDES ******************)
+
+IMPORT IO, Strings, ASCII, NumberIO, termios, FIO, Delay, SplitV1, STextIO;
+IMPORT libc, SYSTEM, Storage, MemUtils;
+
+(******************** DATA ******************)
+
+TYPE
+    abufType            = RECORD
+                            b   : SYSTEM.ADDRESS;
+                            len : CARDINAL;
+                          END;
+    abufTypePtr         = POINTER TO abufType;
+
+VAR
+    editorConfig        : RECORD
+                            screenrows : CARDINAL;
+                            screencols : CARDINAL;
+                            theTermios : termios.TERMIOS;
+                         END;
+
+    TCSAFLUSH           : INTEGER;
+
+    theStructure        : SplitV1.Structure;
+
+    cursorposStr        : ARRAY [0..15] OF CHAR;
+    clearScreenStr      : ARRAY[0..6] OF CHAR;
+    cursorHomeStr       : ARRAY[0..2] OF CHAR;
+    requestCursorPosStr : ARRAY[0..15] OF CHAR;
+    cursorOnStr         : ARRAY[0..6] OF CHAR;
+    cursorOffStr        : ARRAY[0..6] OF CHAR;
+    tildeStr            : ARRAY[0..3] OF CHAR;
+    eraseLineStr        : ARRAY[0..2] OF CHAR;
+
+    resultStr           : ARRAY [0..15] OF CHAR;
+    tmpString           : ARRAY[0..15] OF CHAR;
+    tmpString1          : ARRAY[0..15] OF CHAR;
+    tmpString2          : Strings.String1;
+    cc                  : Strings.String1;
+    i                   : CARDINAL;
+    str                 : ARRAY [0..15] OF CHAR;
+
+    abuf                : abufType;
+ 
+(******************** Utilities *****************)
+
+    PROCEDURE Card2Str ( x : CARDINAL; VAR str : ARRAY OF CHAR);
+
+    BEGIN
+    IF x < 10 THEN
+            NumberIO.CardToStr(x,1,str);
+        ELSIF x < 100 THEN
+            NumberIO.CardToStr(x,2,str);
+        ELSE
+            NumberIO.CardToStr(x,3,str);
+        END;
+    END Card2Str;
+
+    (******************** TERMINAL ******************)
+
+    PROCEDURE CtrlKey(c: CHAR) : CARDINAL;
+        (* return a value < ORD(" ") for the control keys *)
+        VAR
+            n : BITSET;
+
+    BEGIN
+        n := BITSET(ORD(c));
+        n := n * BITSET(1FH);
+        RETURN CARDINAL(n)
+    END CtrlKey;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        FOR i := 0 TO Strings.Length(s) DO
+            IO.Write(s[i])
+        END;
+        HALT
+    END die;
+
+    PROCEDURE disablerawMode() : INTEGER;
+
+        VAR
+            result : INTEGER;
+    BEGIN
+        IO.BufferedMode(0,TRUE);
+        IO.BufferedMode(1,TRUE);
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, editorConfig.theTermios);
+        IF result = -1 THEN
+            die("tcsetattr")
+        ELSE 
+            RETURN result
+        END;
+    END disablerawMode;
+
+    PROCEDURE enablerawMode;
+    BEGIN
+        libc.atexit(disablerawMode);
+
+        editorConfig.theTermios := termios.InitTermios();
+        (* raw := termios.InitTermios(); *)
+        IF termios.tcgetattr(FIO.StdIn, editorConfig.theTermios) = -1 THEN
+            die("tcgetattr")
+        END;
+
+        IO.UnBufferedMode(0,TRUE);
+        IO.UnBufferedMode(1,TRUE);
+    END enablerawMode;
+
+    PROCEDURE  editorReadKey() : CHAR;
+        VAR
+            c : CHAR;
+    BEGIN
+        IO.Read(c);
+        RETURN c
+    END editorReadKey; 
+
+    (******************** Buffer ******************)
+
+    PROCEDURE abufInit( VAR ptr : abufTypePtr);
+    BEGIN
+        Storage.ALLOCATE(ptr,SYSTEM.TSIZE(abufType) );
+        ptr^.b := NIL;
+        ptr^.len := 0;
+    END abufInit;
+
+    PROCEDURE abAppend (VAR ptr : abufTypePtr; str: ARRAY OF CHAR );
+
+        VAR
+            llen : CARDINAL;
+    BEGIN
+        llen := Strings.Length(str);
+        IF ptr <> NIL THEN
+            IF ptr^.b = NIL THEN
+                Storage.ALLOCATE(ptr^.b,llen);
+            ELSE
+                Storage.REALLOCATE( ptr^.b,ptr^.len + llen);
+            END;
+            MemUtils.MemCopy(SYSTEM.ADR(str),llen, SYSTEM.ADDADR(ptr^.b,ptr^.len));
+            ptr^.len := ptr^.len + llen;
+        END;
+    END abAppend;
+
+    PROCEDURE abFree (VAR ptr : abufTypePtr);
+
+    BEGIN
+        Storage.DEALLOCATE(ptr^.b, ptr^.len);
+        Storage.DEALLOCATE(ptr,SYSTEM.TSIZE(abufType));
+    END abFree;
+
+    (******************** output ******************)
+
+    PROCEDURE editorDrawRows(VAR ptr : abufTypePtr);
+
+        VAR
+            y : CARDINAL;
+            str : ARRAY [0..3] OF CHAR;
+
+    BEGIN
+        FOR y := 1 TO editorConfig.screenrows -1 DO
+            abAppend(ptr,tildeStr);
+            abAppend(ptr,eraseLineStr)
+        END;
+        abAppend(ptr,"~");
+        (* libc.write(FIO.StdOut,ptr^.b,ptr^.len); *)
+    END editorDrawRows;
+
+   PROCEDURE editorRefreshScreen;
+
+        VAR
+            ptr : abufTypePtr;
+    BEGIN
+        abufInit(ptr);
+        abAppend(ptr,cursorOffStr);
+        (* abAppend(ptr,clearScreenStr); *)
+        abAppend(ptr,cursorHomeStr);
+        editorDrawRows(ptr);
+        abAppend(ptr,cursorHomeStr);
+        abAppend(ptr,cursorOnStr);
+        libc.write(FIO.StdOut,ptr^.b,ptr^.len);
+        abFree(ptr);
+    END editorRefreshScreen;
+
+    PROCEDURE requestCursorPosition(VAR x,y : CARDINAL);
+
+        VAR
+            c   : CHAR;
+
+    BEGIN
+        str := "";
+        SplitV1.InitStructure(theStructure);
+        Strings.Concat(str,ASCII.esc,str);
+        Strings.Concat(str,"[6n", str);
+        libc.write(FIO.StdOut,SYSTEM.ADR(str),4);
+        (* getting answer *)
+        str := "";
+        REPEAT
+            IO.Read(c);
+            cc[0] := c;
+            Strings.Concat(str,cc,str);
+        UNTIL c = "R";
+        (* DEBUG*)
+        (* displaying the retour , changing the escape to ? *)
+        (* str[0] := "?"; *)
+        (* FOR i := 0 TO Strings.Length(str) DO
+            IO.Write(str[i])
+        END; *)
+        (* libc.write(FIO.StdOut,SYSTEM.ADR(str),Length(str)); *)
+        (* END DEBUG*)
+        (* extracting the coordinates *)
+        Strings.Delete(str,0,2);
+        Strings.Delete(str,Strings.Length(str) -1 ,1);
+        SplitV1.SplitStr(str, ";", theStructure);
+        NumberIO.StrToCard(theStructure[0].element,x);
+        NumberIO.StrToCard(theStructure[1].element,y);
+        
+        (* NumberIO.WriteCard(x, 5);
+        NumberIO.WriteCard(y, 5); *)
+    END requestCursorPosition;
+
+    PROCEDURE cursorpos(x,y : CARDINAL);
+    BEGIN
+        cursorposStr := "";
+        Strings.Concat(cursorposStr, ASCII.esc,cursorposStr);
+        Strings.Concat(cursorposStr, "[",cursorposStr);
+        tmpString := "";
+        Strings.Concat(tmpString,cursorposStr, tmpString);
+        tmpString1 := "";
+        Card2Str(y,tmpString1);
+        Strings.Concat(tmpString,tmpString1, tmpString);
+        tmpString2[0] := ";";
+        Strings.Concat(tmpString, tmpString2,tmpString);
+        tmpString1 := "";
+        Card2Str(x,tmpString1);
+        Strings.Concat(tmpString,tmpString1, tmpString);
+        tmpString2[0] := "H";
+        Strings.Concat(tmpString, tmpString2,tmpString);
+        (* FOR i := 0 TO Strings.Length(tmpString) DO
+            IO.Write(tmpString[i])
+        END; *)
+        libc.write(FIO.StdOut,SYSTEM.ADR(tmpString),Strings.Length(tmpString));
+    END cursorpos;
+
+    PROCEDURE getWindowSize(VAR y : CARDINAL; VAR x: CARDINAL);
+    
+    BEGIN
+        cursorpos(999,999);
+        requestCursorPosition(x,y);
+    END getWindowSize;
+
+    (******************** input  ******************)
+
+    PROCEDURE editorProcessKeypress;
+        VAR
+            c       : CHAR;
+            b       : BOOLEAN;
+    BEGIN
+        c := editorReadKey();
+        CASE ORD(c) OF
+          17 : HALT;
+        END
+    END editorProcessKeypress;
+
+    (********************  INIT  ******************)
+
+    PROCEDURE InitScreenEscapes;
+
+    VAR temp : ARRAY[0..10] OF CHAR;
+    BEGIN
+        cursorHomeStr := "";
+        Strings.Concat(cursorHomeStr,ASCII.esc,cursorHomeStr);
+        Strings.Concat(cursorHomeStr,"[H",cursorHomeStr);
+
+        clearScreenStr := "";
+        Strings.Concat(clearScreenStr,ASCII.esc,clearScreenStr);
+        Strings.Concat(clearScreenStr,"[2J",clearScreenStr);
+
+        cursorposStr := "";
+        Strings.Concat(cursorposStr,ASCII.esc,cursorposStr);
+        Strings.Concat(cursorposStr,"[",cursorposStr);
+    
+        requestCursorPosStr := "";
+        Strings.Concat(requestCursorPosStr,ASCII.esc,requestCursorPosStr);
+        Strings.Concat(requestCursorPosStr,"[6n",requestCursorPosStr);
+    
+        cursorOnStr := "";
+        Strings.Concat(cursorOnStr,ASCII.esc,cursorOnStr);
+        Strings.Concat(cursorOnStr,"[?25h",cursorOnStr);
+        
+        cursorOffStr := "";
+        Strings.Concat(cursorOffStr,ASCII.esc,cursorOffStr);
+        Strings.Concat(cursorOffStr,"[?25l",cursorOffStr);
+        
+        tildeStr := "~";
+        cc[0] := CHR(13);
+        Strings.Concat(tildeStr,cc,tildeStr);
+        cc[0] := CHR(10);
+        Strings.Concat(tildeStr,cc,tildeStr);
+
+        eraseLineStr := "";
+        Strings.Concat(eraseLineStr,ASCII.esc,eraseLineStr);
+        Strings.Concat(eraseLineStr,"[K",eraseLineStr);
+
+    END InitScreenEscapes;
+
+    PROCEDURE InitEditor;
+
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+
+        InitScreenEscapes;
+        getWindowSize(editorConfig.screenrows, editorConfig.screencols);
+
+    END InitEditor;
+
+
+BEGIN
+    
+    enablerawMode;
+    InitEditor;
+                            
+    LOOP
+        editorRefreshScreen;
+        editorProcessKeypress;
+        editorRefreshScreen;
+    END;
+
+
+    (* Delay.Delay(2000); *)
+    IF disablerawMode() = -1 THEN
+        HALT
+    END;    
+       
+    NumberIO.WriteCard(editorConfig.screencols, 5);
+    NumberIO.WriteCard(editorConfig.screenrows, 5);
+END editor1.

BIN
step40/kilo


+ 134 - 0
step40/kilo.c

@@ -0,0 +1,134 @@
+/*** includes ***/
+#include <ctype.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+/*** defines ***/
+#define CTRL_KEY(k) ((k) & 0x1f)
+
+/*** data ***/
+
+struct editorConfig {
+  int screenrows;
+  int screencols;
+  struct termios orig_termios;
+};
+struct editorConfig E;
+
+
+/*** terminal ***/
+void die(const char *s) {
+  write(STDOUT_FILENO, "\x1b[2J", 4);
+  write(STDOUT_FILENO, "\x1b[H", 3);
+  perror(s);
+  exit(1);
+}
+
+void disableRawMode() {
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &E.orig_termios) == -1)
+      die("tcsetattr");
+}
+
+void enableRawMode() {
+  if (tcgetattr(STDIN_FILENO, &E.orig_termios) == -1) die("tcgetattr");
+  atexit(disableRawMode);
+  struct termios raw = E.orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr");
+}
+
+char editorReadKey() {
+  int nread;
+  char c;
+  while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
+    if (nread == -1 && errno != EAGAIN) die("read");
+  }
+  return c;
+}
+
+int getWindowSize(int *rows, int *cols) {
+  struct winsize ws;
+  if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) {
+    return -1;
+  } else {
+    *cols = ws.ws_col;
+    *rows = ws.ws_row;
+    return 0;
+  }
+}
+
+/*** append buffer ***/
+
+struct abuf {
+  char *b;
+  int len;
+};
+#define ABUF_INIT {NULL, 0}
+
+void abAppend(struct abuf *ab, const char *s, int len) {
+  char *new = realloc(ab->b, ab->len + len);
+  if (new == NULL) return;
+  memcpy(&new[ab->len], s, len);
+  ab->b = new;
+  ab->len += len;
+}
+void abFree(struct abuf *ab) {
+  free(ab->b);
+}
+
+/*** output ***/
+
+void editorDrawRows(struct abuf *ab) {
+  int y;
+  for (y = 0; y < E.screenrows; y++) {
+    abAppend(ab, "~", 1);
+    abAppend(ab, "\x1b[K", 3);
+    if (y < E.screenrows - 1) {
+      abAppend(ab, "\r\n", 2);
+    }
+  }
+}
+void editorRefreshScreen() {
+  struct abuf ab = ABUF_INIT;
+  abAppend(&ab, "\x1b[?25l", 6);
+  abAppend(&ab, "\x1b[H", 3);
+  editorDrawRows(&ab);
+  abAppend(&ab, "\x1b[H", 3);
+  abAppend(&ab, "\x1b[?25h", 6);
+  write(STDOUT_FILENO, ab.b, ab.len);
+  abFree(&ab);
+}
+
+/*** input ***/
+void editorProcessKeypress() {
+  char c = editorReadKey();
+  switch (c) {
+    case CTRL_KEY('q'):
+      exit(0);
+      break;
+  }
+}
+/*** init ***/
+void initEditor() {
+  if (getWindowSize(&E.screenrows, &E.screencols) == -1) die("getWindowSize");
+}
+
+int main() {
+  enableRawMode();
+   initEditor();
+  while (1) {
+    editorRefreshScreen();
+    editorProcessKeypress();
+  }
+  return 0;
+}

+ 15 - 0
step41/Makefile

@@ -0,0 +1,15 @@
+all: kilo editor
+
+kilo: kilo.c
+#	echo "building the C version"
+	$(CC) kilo.c -o kilo -Wall -Wextra -pedantic -std=c99
+
+editor: editor.mod VT100.o SplitV1.o
+#	echo "building the Modula-2 version"
+	gm2 -fiso -o editor SplitV1.o VT100.o editor.mod
+
+SplitV1.o:
+	gm2 -fiso -c SplitV1.mod
+
+VT100.o:
+	gm2 -fiso -c VT100.mod

+ 28 - 0
step41/SplitV1.def

@@ -0,0 +1,28 @@
+DEFINITION MODULE SplitV1;
+
+TYPE
+  Element = RECORD
+              pos : CARDINAL;
+              element : ARRAY[0..255] OF CHAR;
+            END;  
+  Structure = ARRAY[0..20] OF Element;    
+ 
+VAR 
+  trimMode    : BOOLEAN;
+  allTrimMode : BOOLEAN;
+  noDupMode   : BOOLEAN;
+  rtrim       : BOOLEAN;
+  ltrim       : BOOLEAN;
+  
+                  
+PROCEDURE Ltrim ( VAR src : ARRAY OF CHAR; separator : CHAR  );
+  
+PROCEDURE Rtrim ( VAR src : ARRAY OF CHAR ; separator : CHAR );
+    
+PROCEDURE removeDuplicate ( VAR src : ARRAY OF CHAR ; separator : CHAR );             
+                  
+PROCEDURE SplitStr(s : ARRAY OF CHAR; separator : CHAR; VAR out : Structure); 
+
+PROCEDURE InitStructure ( VAR out : Structure);
+
+END SplitV1.

+ 157 - 0
step41/SplitV1.mod

@@ -0,0 +1,157 @@
+IMPLEMENTATION MODULE SplitV1;
+
+IMPORT Strings;
+FROM InOut IMPORT Write, WriteString, WriteCard, WriteLn;
+
+VAR
+  j : CARDINAL;
+  
+PROCEDURE Ltrim (VAR src : ARRAY OF CHAR; separator : CHAR  );
+
+VAR
+  longueur : CARDINAL;
+  
+  BEGIN
+    REPEAT
+      longueur := LENGTH(src);
+      IF src[0] = separator THEN
+      	(*PROCEDURE Delete (VAR stringVar: ARRAY OF CHAR; startIndex, numberToDelete:CARDINAL);*)
+        (* Deletes at most numberToDelete characters from stringVar, starting at position startIndex.*)
+        Strings.Delete(src,0,1);
+      END;  
+    UNTIL (src[0] # separator) OR (longueur = 0)
+  END Ltrim;     
+  
+PROCEDURE Rtrim ( VAR src : ARRAY OF CHAR ; separator : CHAR );
+
+VAR
+  longueur : CARDINAL;
+  
+  BEGIN
+    longueur := LENGTH(src);
+    REPEAT
+      longueur := LENGTH(src);
+      IF src[longueur - 1] = separator THEN
+      	(*PROCEDURE Delete (VAR stringVar: ARRAY OF CHAR; startIndex, numberToDelete:CARDINAL);*)
+        (* Deletes at most numberToDelete characters from stringVar, starting at position startIndex.*)
+        Strings.Delete(src,longueur - 1,1);
+      END;  
+      longueur := LENGTH(src);
+    UNTIL (src[longueur - 1] # separator) OR (longueur =0 ) 
+   END Rtrim;  
+  
+PROCEDURE removeDuplicate ( VAR src : ARRAY OF CHAR ; separator : CHAR );             
+
+VAR
+  longueur : CARDINAL;
+  pos      : CARDINAL;
+  
+  BEGIN
+    pos := 0;
+    longueur := LENGTH(src);
+    LOOP
+      IF (longueur = 0 ) OR (pos = longueur ) THEN
+        RETURN
+      END;
+      (*Write(src[pos]);Write(" ");*)
+      IF src[pos] = separator THEN 
+        pos := pos + 1;
+        WHILE src[pos] = separator DO 
+          Strings.Delete(src,pos,1);
+        END; 
+      ELSE 
+        INC(pos) 
+      END;  
+      longueur := LENGTH(src);
+    END; (* end loop*)
+  END removeDuplicate;   
+  
+PROCEDURE SplitStr(s : ARRAY OF CHAR; separator : CHAR; VAR out : Structure) ;
+
+(*
+  There are several cases to take account for :
+  - standard case : s begin with an element and end with an element
+  - s begins with a separator and end with an element
+  - s begins with a separator and ends with a separators
+  - there are consecutive separators inside s
+  - there are consecutive separators at the beginning
+  - there are consecutive separators at the end
+*)
+
+VAR 
+  i : CARDINAL;
+  indice : CARDINAL;
+  longueur : CARDINAL;
+  resultat : ARRAY[0..255] OF CHAR;
+  deja : BOOLEAN;
+  c : CHAR;
+  
+  BEGIN
+    indice := 0; 
+    (* modes de fonctionnement *)
+    (*  trimMode    : BOOLEAN;
+        allTrimMode : BOOLEAN;
+        noDupMode   : BOOLEAN;
+        rtrim       : BOOLEAN;
+        ltrim       : BOOLEAN;*)
+    IF trimMode THEN
+      Rtrim ( s, separator);
+      Ltrim ( s, separator);
+    END;
+    
+    IF ltrim THEN
+      Ltrim ( s, separator);
+    END;
+    
+    IF rtrim THEN
+      Rtrim ( s, separator);
+    END;    
+    
+    IF noDupMode THEN
+      removeDuplicate ( s, separator);
+    END;
+    
+    IF allTrimMode THEN
+      Rtrim ( s, separator);
+      Ltrim ( s, separator);
+      removeDuplicate ( s, separator);
+    END;  
+    
+    longueur := LENGTH(s);
+    resultat := "";
+    deja := FALSE;
+    FOR i := 0 TO longueur -1 DO
+      c := s[i]; 						(* the first character of the string s *)
+      IF c # separator THEN 					(* the character belongs to an element *)
+         Strings.Append(Strings.String1(c),resultat);
+      ELSE
+        out[indice].element := resultat;
+        resultat := ""; 
+        INC(indice);
+      END;
+      out[indice].element := resultat;
+    END;
+    FOR i := indice + 1 TO HIGH(out) DO 
+      out[i].pos := MAX(CARDINAL);
+    END;
+  END SplitStr;
+
+PROCEDURE InitStructure ( VAR out : Structure);
+
+VAR 
+  i : CARDINAL;
+  
+BEGIN 
+  FOR i := 0 TO HIGH(out)   DO
+    out[i].pos := i;
+    out[i].element := "";
+  END;
+END InitStructure;
+
+BEGIN 
+  trimMode    := FALSE;
+  allTrimMode := FALSE;
+  noDupMode   := FALSE;
+  ltrim       := FALSE;
+  rtrim       := FALSE; 
+END SplitV1. 

BIN
step41/SplitV1.o


+ 544 - 0
step41/VT100.def

@@ -0,0 +1,544 @@
+DEFINITION MODULE VT100;
+
+(*
+ The POSIX function cfmakeraw() sets the canonical
+ combination. Applications typically use tcgetattr()
+ to save the current settings, call cfmakeraw() 
+ to switch to raw mode, and call tcsetattr() with 
+ the saved settings on exit to restore the terminal.
+*)
+
+TYPE 
+    screenModes = (M40x25BW,M40x25C,M80x25BW,M80x25C,M320x200C4,M320x200BW,M640x200BW,
+                   M320x200C256,M640x200C,M640x350BW,M640x350C,M640x480BW,M640x480C,M320x200C);
+    Attribut    = (boldAt,dimAt,italicAt,underlineAt,blinkingAt,inverseAt,hiddenAt,
+                   strikethroughAt,doubleunderlineAt);
+
+    Colors      = (Black, Red, Green, Yellow, Blue, Magenta, Cyan, White, Default,
+                    BrightBlack, BrightRed, BrightGreen, BrightYellow, 
+                    BrightBlue, BrighMagenta, BrightCyan, BrightWhite);
+(*
+PROCEDURE setnl;
+(* LMN             Set new line mode                      ^[[20h *)
+
+PROCEDURE setappl;
+(* DECCKM        Set cursor key to application          ^[[?1h *)
+
+PROCEDURE setansi;
+(* DECANM        Set ANSI (versus VT52)                 none *)
+
+PROCEDURE setcol;
+(* DECCOLM        Set number of columns to 132           ^[[?3h *)
+
+PROCEDURE setsmooth;
+(* DECSCLM     Set smooth scrolling                   ^[[?4h *)
+
+PROCEDURE setrevscrn;
+(* DECSCNM    Set reverse video on screen            ^[[?5h *)
+
+PROCEDURE setorgrel;
+(* DECOM       Set origin to relative                 ^[[?6h *)
+
+PROCEDURE setwrap;
+(* DECAWM        Set auto-wrap mode                     ^[[?7h *)
+
+PROCEDURE setrep;
+(* DECARM         Set auto-repeat mode                   ^[[?8h *)
+
+PROCEDURE setinter;
+(* DECINLM      Set interlacing mode                   ^[[?9h *)
+
+PROCEDURE setlf;
+(* LMN             Set line feed mode                     ^[[20l *)
+
+PROCEDURE setcursor;
+(* DECCKM      Set cursor key to cursor               ^[[?1l *)
+
+PROCEDURE setvt52;
+(* DECANM        Set VT52 (versus ANSI)                 ^[[?2l *)
+
+PROCEDURE resetcol;
+(* DECCOLM      Set number of columns to 80            ^[[?3l *)
+
+PROCEDURE setjump;
+(* DECSCLM       Set jump scrolling                     ^[[?4l *)
+
+PROCEDURE setnormscrn;
+(* DECSCNM   Set normal video on screen             ^[[?5l *)
+
+PROCEDURE setorgabs;
+(* DECOM       Set origin to absolute                 ^[[?6l *)
+
+PROCEDURE resetwrap;
+(* DECAWM      Reset auto-wrap mode                   ^[[?7l *)
+
+PROCEDURE resetrep;
+(* DECARM       Reset auto-repeat mode                 ^[[?8l *)
+
+PROCEDURE resetinter;
+(* DECINLM    Reset interlacing mode                 ^[[?9l *)
+
+PROCEDURE altkeypad;
+(* DECKPAM     Set alternate keypad mode              ^[= *)
+
+PROCEDURE numkeypad;
+(* DECKPNM     Set numeric keypad mode                ^[> *)
+
+PROCEDURE setukg0;
+    (* Set United Kingdom G0 character set    ^[(A *)
+
+PROCEDURE setukg1;
+    (* Set United Kingdom G1 character set    ^[)A *)
+
+PROCEDURE setusg0;
+(* Set United States G0 character set     ^[(B *)
+
+PROCEDURE setusg1;
+(* Set United States G1 character set     ^[)B *)
+
+PROCEDURE setspecg0;
+(* Set G0 special chars. & line set       ^[(0 *)
+
+PROCEDURE setspecg1;
+(* Set G1 special chars. & line set       ^[)0 *)
+
+PROCEDURE setaltg0;
+(* Set G0 alternate character ROM         ^[(1 *)
+
+PROCEDURE setaltg1;
+(* Set G1 alternate character ROM         ^[)1 *)
+
+PROCEDURE setaltspecg0;
+(* Set G0 alt char ROM and spec. graphics ^[(2 *)
+
+PROCEDURE setaltspecg1;
+(* Set G1 alt char ROM and spec. graphics ^[)2 *)
+
+PROCEDURE setss2 ;
+(* SS2 Set single shift 2                 ^[N *)
+
+PROCEDURE setss3;
+(* SS3 Set single shift 3                  ^[O *)
+*)
+
+(*
+ESC Code Sequence 	Reset Sequence 	Description
+ESC[1;34;{...}m 		Set graphics modes for cell, separated by semicolon (;).
+ESC[1m 	ESC[22m 	set bold mode.
+ESC[2m 	ESC[22m 	set dim/faint mode.
+ESC[3m 	ESC[23m 	set italic mode.
+ESC[4m 	ESC[24m 	set underline mode.
+ESC[5m 	ESC[25m 	set blinking mode
+ESC[7m 	ESC[27m 	set inverse/reverse mode
+ESC[8m 	ESC[28m 	set hidden/invisible mode
+ESC[9m 	ESC[29m 	set strikethrough mode.
+ESC[21m ESC[24m    set double underline
+*)
+
+PROCEDURE modesoff; (*OK*)
+(* SGR0 Turn off character attributes          ^[[m *)
+
+PROCEDURE modesoff1; (*OK*)
+(* SGR0 Turn off character attributes          ^[[0m *)
+
+PROCEDURE bold; (*OK*)
+(* SGR1 Turn bold mode on                      ^[[1m *)
+
+PROCEDURE lowint; (*OK*)
+(* SGR2 Turn low intensity mode on             ^[[2m *)
+
+PROCEDURE italic; (*OK*)
+(* set italic mode                              ESC[3m *)
+
+PROCEDURE underline; (*OK*)
+(* SGR4 Turn underline mode on                 ^[[4m *)
+
+PROCEDURE blink; (*OK*)
+(* SGR5 Turn blinking mode on                  ^[[5m *)
+
+PROCEDURE reverse; (*OK*)
+(* SGR7 Turn reverse video on                  ^[[7m *)
+
+PROCEDURE invisible; (*OK*)
+(* SGR8 Turn invisible text mode on            ^[[8m *)
+
+PROCEDURE strikethrough; (*OK*)
+(* ESC[9m 	ESC[29m 	set strikethrough mode. *)
+
+PROCEDURE doubleUnderline;
+(* ESC[21m *)
+
+PROCEDURE resetbold; (*OK*)
+(* SGR1 Turn bold mode on                      ^[[1m *)
+
+PROCEDURE resetlowint; (*OK*)
+(* SGR2 Turn low intensity mode on             ^[[2m *)
+
+PROCEDURE resetitalic; (*OK*)
+(* set italic mode                              ESC[3m *)
+
+PROCEDURE resetunderline; (*OK*)
+(* SGR4 Turn underline mode on                 ^[[4m *)
+
+PROCEDURE resetblink; (*OK*)
+(* SGR5 Turn blinking mode on                  ^[[5m *)
+
+PROCEDURE resetreverse; (*OK*)
+(* SGR7 Turn reverse video on                  ^[[7m *)
+
+PROCEDURE resetinvisible; (*OK*)
+(* SGR8 Turn invisible text mode on            ^[[8m *)
+
+PROCEDURE resetstrikethrough; (*OK*)
+(* ESC[9m 	ESC[29m 	set strikethrough mode. *)
+
+PROCEDURE resetDoubleUnderline;
+(* ESC[24m. *)
+
+(*
+PROCEDURE setwin;
+(* DECSTBM Set top and bottom line#s of a window  ^[[<v>;<v>r *)
+*)
+
+(*
+ESC Code Sequence 	Description
+ESC[H 	moves cursor to home position (0, 0)
+ESC[{line};{column}H
+ESC[{line};{column}f 	moves cursor to line #, column #
+ESC[#A 	moves cursor up # lines
+ESC[#B 	moves cursor down # lines
+ESC[#C 	moves cursor right # columns
+ESC[#D 	moves cursor left # columns
+ESC[#E 	moves cursor to beginning of next line, # lines down
+ESC[#F 	moves cursor to beginning of previous line, # lines up
+ESC[#G 	moves cursor to column #
+
+ESC[6n 	request cursor position (reports as ESC[#;#R)
+ESC M 	moves cursor one line up, scrolling if needed
+ESC 7 	save cursor position (DEC)
+ESC 8 	restores the cursor to the last saved position (DEC)
+ESC[s 	save cursor position (SCO)
+ESC[u 	restores the cursor to the last saved position (SCO)
+*)
+
+PROCEDURE cursorup(n : CARDINAL); (*OK*)
+(* CUU Move cursor up n lines                 ^[[<n>A *)
+
+PROCEDURE cursordn(n : CARDINAL); (*OK*)
+(* CUD Move cursor down n lines               ^[[<n>B *)
+
+PROCEDURE cursorrt(n : CARDINAL); (*OK*)
+(* CUF Move cursor right n lines              ^[[<n>C *)
+
+PROCEDURE cursor1lf(n : CARDINAL); (*OK*)
+(* CUB Move cursor left n lines               ^[[<n>D *)
+
+PROCEDURE cursorbnl(n : CARDINAL);
+(* ESC[#E 	moves cursor to beginning of next line, # lines down *)
+
+PROCEDURE cursorblpl(n : CARDINAL);
+(* ESC[#F 	moves cursor to beginning of previous line, # lines up *)
+
+PROCEDURE cursottocol(n : CARDINAL);
+(* ESC[#G 	moves cursor to column # *)
+
+PROCEDURE requestCursorPosition(VAR x,y : CARDINAL);
+(* ESC[6n 	request cursor position (reports as ESC[#;#R) *)
+
+PROCEDURE cursorhome; (*OK*)
+(* Move cursor to upper left corner       ^[[H *)
+
+PROCEDURE cursorhome1; (*OK*)
+(* Move cursor to upper left corner       ^[[;H *)
+
+PROCEDURE cursorpos(x,y: CARDINAL); (*OK*)
+(* CUP Move cursor to screen location v,h     ^[[<v>;<h>H *)
+(*
+PROCEDURE hvhome;
+(* Move cursor to upper left corner       ^[[f *)
+
+PROCEDURE hvhome;
+(* Move cursor to upper left corner       ^[[;f *)
+
+PROCEDURE hvpos(v,h);
+(* CUP Move cursor to screen location v,h     ^[[<v>;<h>f *)
+
+PROCEDURE index;
+(* IND Move/scroll window up one line         ^[D *)
+
+PROCEDURE revindex;
+(* RI Move/scroll window down one line       ^[M *)
+
+PROCEDURE nextline;
+(* NEL Move to next line                      ^[E *)
+
+PROCEDURE savecursor;
+(* DECSC Save cursor position and attributes    ^[7 *)
+
+PROCEDURE restorecursor;
+(* DECSC Restore cursor position and attributes ^[8 *)
+
+PROCEDURE tabset;
+(* HTS Set a tab at the current column        ^[H *)
+
+PROCEDURE tabclr;
+(* TBC Clear a tab at the current column      ^[[g *)
+
+PROCEDURE tabclr;
+(* TBC Clear a tab at the current column      ^[[0g *)
+
+PROCEDURE tabclrall;
+(* TBC Clear all tabs                         ^[[3g *)
+
+PROCEDURE dhtop;
+(* DECDHL Double-height letters, top half        ^[#3 *)
+
+PROCEDURE dhbot;
+(* DECDHL Double-height letters, bottom half     ^[#4 *)
+
+PROCEDURE swsh;
+(* DECSWL Single width, single height letters    ^[#5 *)
+
+PROCEDURE dwsh;
+(* DECDWL Double width, single height letters    ^[#6 *)
+
+PROCEDURE cleareol;
+(* EL0 Clear line from cursor right           ^[[K *)
+
+PROCEDURE cleareol;
+(* EL0 Clear line from cursor right           ^[[0K *)
+
+PROCEDURE clearbol;
+(* EL1 Clear line from cursor left            ^[[1K *)
+
+PROCEDURE clearline;
+(* EL2 Clear entire line                      ^[[2K *)
+
+PROCEDURE cleareos;
+(* ED0 Clear screen from cursor down          ^[[J *)
+
+PROCEDURE cleareos;
+(* ED0 Clear screen from cursor down          ^[[0J *)
+
+PROCEDURE clearbos;
+(* ED1 Clear screen from cursor up            ^[[1J *)
+*)
+PROCEDURE clearscreen; (* OK *)
+(* ED2 Clear entire screen                    ^[[2J *)
+(*
+PROCEDURE devstat;
+(* DSR Device status report                   ^[5n *)
+
+PROCEDURE termok;
+(* DSR Response: terminal is OK            ^[0n *)
+
+PROCEDURE termnok;
+(* DSR Response: terminal is not OK        ^[3n *)
+
+PROCEDURE getcursor;
+(* DSR Get cursor position                    ^[6n *)
+
+PROCEDURE cursorpos;
+(* CPR Response: cursor is at v,h          ^[<v>;<h>R *)
+
+PROCEDURE ident;
+(* DA Identify what terminal type            ^[[c *)
+
+PROCEDURE ident;
+(* DA Identify what terminal type (another)  ^[[0c *)
+
+PROCEDURE gettype;
+(* DA Response: terminal type code n      ^[[?1;<n>0c *)
+
+PROCEDURE reset;
+(* RIS Reset terminal to initial state        ^[c *)
+
+PROCEDURE align;
+(* DECALN Screen alignment display               ^[#8 *)
+
+PROCEDURE testpu;
+(* DECTST Confidence power up test               ^[[2;1y *)
+
+PROCEDURE testlb;
+(* DECTST Confidence loopback test               ^[[2;2y *)
+
+PROCEDURE testpurep;
+(* DECTST Repeat power up test                   ^[[2;9y *)
+
+PROCEDURE testlbrep;
+(* DECTST Repeat loopback test                   ^[[2;10y *)
+
+PROCEDURE ledsoff;
+(* DECLL0 Turn off all four leds                 ^[[0q *)
+
+PROCEDURE led1;
+(* DECLL1 Turn on LED #1                         ^[[1q *)
+
+PROCEDURE led2;
+(* DECLL2 Turn on LED #2                         ^[[2q *)
+
+PROCEDURE led3;
+(* DECLL3 Turn on LED #3                         ^[[3q *)
+
+PROCEDURE led4;
+(* DECLL4 Turn on LED #4                         ^[[4q *)
+*)
+
+(*
+Screen Modes
+Set Mode
+ESC Code Sequence 	Description
+ESC[={value}h 	Changes the screen width or type to the mode specified by value.
+ESC[=0h 	40 x 25 monochrome (text)
+ESC[=1h 	40 x 25 color (text)
+ESC[=2h 	80 x 25 monochrome (text)
+ESC[=3h 	80 x 25 color (text)
+ESC[=4h 	320 x 200 4-color (graphics)
+ESC[=5h 	320 x 200 monochrome (graphics)
+ESC[=6h 	640 x 200 monochrome (graphics)
+ESC[=7h 	Enables line wrapping
+ESC[=13h 	320 x 200 color (graphics)
+ESC[=14h 	640 x 200 color (16-color graphics)
+ESC[=15h 	640 x 350 monochrome (2-color graphics)
+ESC[=16h 	640 x 350 color (16-color graphics)
+ESC[=17h 	640 x 480 monochrome (2-color graphics)
+ESC[=18h 	640 x 480 color (16-color graphics)
+ESC[=19h 	320 x 200 color (256-color graphics)
+ESC[={value}l 	Resets the mode by using the same values that Set Mode uses, except for 7, which disables line wrapping. The last character in this escape sequence is a lowercase L.
+Common Private Modes
+*)
+PROCEDURE screenMode(mode : screenModes);
+
+PROCEDURE resetScreenMode(mode : screenModes);
+
+PROCEDURE lineWrapping;
+
+PROCEDURE resetLineWrapping;
+
+(*
+These are some examples of private modes, which are not defined by the specification, but are implemented in most terminals.
+ESC Code Sequence 	Description
+ESC[?25l 	make cursor invisible
+ESC[?25h 	make cursor visible
+ESC[?47l 	restore screen
+ESC[?47h 	save screen
+ESC[?1049h 	enables the alternative buffer
+ESC[?1049l 	disables the alternative buffer
+*)
+
+PROCEDURE makeCursorInvisible;
+
+PROCEDURE makeCursorVisible;
+
+PROCEDURE restoreScreen;
+
+PROCEDURE saveScreen;
+
+PROCEDURE enableAlternativeBuffer;
+
+PROCEDURE disableAlternativeBuffer;
+
+(*
+Color codes
+
+Most terminals support 8 and 16 colors, as well as 256 (8-bit) colors. These colors are set by the user, but have commonly defined meanings.
+8-16 Colors
+Color Name 	Foreground Color Code 	Background Color Code
+Black 	30 	40
+Red 	31 	41
+Green 	32 	42
+Yellow 	33 	43
+Blue 	34 	44
+Magenta 	35 	45
+Cyan 	36 	46
+White 	37 	47
+Default 	39 	49
+Reset 	0 	0
+
+    Note: the Reset color is the reset code that resets all colors and text effects, Use Default color to reset colors only.
+
+Most terminals, apart from the basic set of 8 colors, also support the "bright" or "bold" colors. These have their own set of codes, mirroring the normal colors, but with an additional ;1 in their codes:
+
+# Set style to bold, red foreground.
+\x1b[1;31mHello
+# Set style to dimmed white foreground with red background.
+\x1b[2;37;41mWorld
+
+Terminals that support the aixterm specification provides bright versions of the ISO colors, without the need to use the bold modifier:
+Color Name 	Foreground Color Code 	Background Color Code
+Bright Black 	90 	100
+Bright Red 	91 	101
+Bright Green 	92 	102
+Bright Yellow 	93 	103
+Bright Blue 	94 	104
+Bright Magenta 	95 	105
+Bright Cyan 	96 	106
+Bright White 	97 	107
+256 Colors
+
+*)
+
+PROCEDURE setAttribut ( attribut: Attribut; front, back : Colors);
+
+(* 
+#
+#  All codes below are for use in VT52 compatibility mode.
+# 
+*)
+
+PROCEDURE VT52setansi; (*OK*)
+               (* Enter/exit ANSI mode (VT52)            ^[< *)
+
+PROCEDURE VT52altkeypad;
+             (* Enter alternate keypad mode            ^[= *)
+
+PROCEDURE VT52numkeypad;
+             (* Exit alternate keypad mode             ^[> *)
+
+PROCEDURE VT52setgr; (* NOT OK*)
+                 (* Use special graphics character set     ^[F *)
+
+PROCEDURE VT52resetgr; (* NOT OK*)
+               (* Use normal US/UK character set         ^[G *)
+
+PROCEDURE VT52cursorup; (*OK*)
+              (* Move cursor up one line                ^[A *)
+
+PROCEDURE VT52cursordn; (*OK*)
+              (* Move cursor down one line              ^[B *)
+
+PROCEDURE VT52cursorrt; (*OK*)
+              (* Move cursor right one char             ^[C *)
+
+PROCEDURE VT52cursorlf; (*OK*)
+              (* Move cursor left one char              ^[D *)
+
+PROCEDURE VT52cursorhome; (*OK*)
+            (* Move cursor to upper left corner       ^[H *)
+
+PROCEDURE VT52cursorpos(x, y : CARDINAL); (* NOT OK*)
+        (* Move cursor to v,h location            ^[<v><h> *)
+
+PROCEDURE VT52revindex;
+              (* Generate a reverse line-feed           ^[I *)
+
+PROCEDURE VT52cleareol; (*OK*)
+              (* Erase to end of current line           ^[K *)
+
+PROCEDURE VT52cleareos; (*OK*)
+              (* Erase to end of screen                 ^[J *)
+
+PROCEDURE VT52ident;
+                 (* Identify what the terminal is          ^[Z *)
+
+PROCEDURE VT52identresp;
+             (*Correct response to ident             ^[/Z   *) 
+
+PROCEDURE CloseTerminal;
+    (* PROCEDURE tcsetattr (fd: INTEGER; option: INTEGER; t: TERMIOS) : INTEGER ; *)
+
+PROCEDURE InitTerminal;
+(* PROCEDURE tcgetattr (fd: INTEGER; t: TERMIOS) : INTEGER ; *)
+
+
+END VT100.

+ 1594 - 0
step41/VT100.mod

@@ -0,0 +1,1594 @@
+IMPLEMENTATION MODULE VT100;
+
+IMPORT ASCII;
+FROM STextIO IMPORT WriteString, WriteChar, WriteLn, ReadString;
+FROM NumberIO IMPORT WriteCard, CardToStr,StrToCard;
+FROM Strings IMPORT Concat, Length, String1, Assign, Delete;
+FROM NumberIO IMPORT WriteHex;
+FROM Delay IMPORT Delay;
+IMPORT SplitV1;
+IMPORT termios;
+
+(*
+Name                  DASCII.escription                            ASCII.esc Code
+
+setnl LMN             Set new line mode                      ^[[20h
+setappl DECCKM        Set cursor key to application          ^[[?1h
+setansi DECANM        Set ANSI (versus VT52)                 none
+setcol DECCOLM        Set number of columns to 132           ^[[?3h
+setsmooth DECSCLM     Set smooth scrolling                   ^[[?4h
+setrevscrn DECSCNM    Set reverse video on screen            ^[[?5h
+setorgrel DECOM       Set origin to relative                 ^[[?6h
+setwrap DECAWM        Set auto-wrap mode                     ^[[?7h
+setrep DECARM         Set auto-repeat mode                   ^[[?8h
+setinter DECINLM      Set interlacing mode                   ^[[?9h
+
+setlf LMN             Set line feed mode                     ^[[20l
+setcursor DECCKM      Set cursor key to cursor               ^[[?1l
+setvt52 DECANM        Set VT52 (versus ANSI)                 ^[[?2l
+resetcol DECCOLM      Set number of columns to 80            ^[[?3l
+setjump DECSCLM       Set jump scrolling                     ^[[?4l
+setnormscrn DECSCNM   Set normal video on screen             ^[[?5l
+setorgabs DECOM       Set origin to absolute                 ^[[?6l
+resetwrap DECAWM      Reset auto-wrap mode                   ^[[?7l
+resetrep DECARM       Reset auto-repeat mode                 ^[[?8l
+resetinter DECINLM    Reset interlacing mode                 ^[[?9l
+
+altkeypad DECKPAM     Set alternate keypad mode              ^[=
+numkeypad DECKPNM     Set numeric keypad mode                ^[>
+
+setukg0               Set United Kingdom G0 character set    ^[(A
+setukg1               Set United Kingdom G1 character set    ^[)A
+setusg0               Set United States G0 character set     ^[(B
+setusg1               Set United States G1 character set     ^[)B
+setspecg0             Set G0 special chars. & line set       ^[(0
+setspecg1             Set G1 special chars. & line set       ^[)0
+setaltg0              Set G0 alternate character ROM         ^[(1
+setaltg1              Set G1 alternate character ROM         ^[)1
+setaltspecg0          Set G0 alt char ROM and spec. graphics ^[(2
+setaltspecg1          Set G1 alt char ROM and spec. graphics ^[)2
+
+setss2 SS2            Set single shift 2                     ^[N
+setss3 SS3            Set single shift 3                     ^[O
+
+modesoff SGR0         Turn off character attributes          ^[[m
+modesoff SGR0         Turn off character attributes          ^[[0m
+bold SGR1             Turn bold mode on                      ^[[1m
+lowint SGR2           Turn low intensity mode on             ^[[2m
+underline SGR4        Turn underline mode on                 ^[[4m
+blink SGR5            Turn blinking mode on                  ^[[5m
+reverse SGR7          Turn reverse video on                  ^[[7m
+invisible SGR8        Turn invisible text mode on            ^[[8m
+
+setwin DECSTBM        Set top and bottom line#s of a window  ^[[<v>;<v>r
+
+cursorup(n) CUU       Move cursor up n lines                 ^[[<n>A
+cursordn(n) CUD       Move cursor down n lines               ^[[<n>B
+cursorrt(n) CUF       Move cursor right n lines              ^[[<n>C
+cursorlf(n) CUB       Move cursor left n lines               ^[[<n>D
+cursorhome            Move cursor to upper left corner       ^[[H
+cursorhome            Move cursor to upper left corner       ^[[;H
+cursorpos(v,h) CUP    Move cursor to screen location v,h     ^[[<v>;<h>H
+hvhome                Move cursor to upper left corner       ^[[f
+hvhome                Move cursor to upper left corner       ^[[;f
+hvpos(v,h) CUP        Move cursor to screen location v,h     ^[[<v>;<h>f
+index IND             Move/scroll window up one line         ^[D
+revindex RI           Move/scroll window down one line       ^[M
+nextline NEL          Move to next line                      ^[E
+savecursor DECSC      Save cursor position and attributes    ^[7
+restorecursor DECSC   Restore cursor position and attributes ^[8
+
+tabset HTS            Set a tab at the current column        ^[H
+tabclr TBC            Clear a tab at the current column      ^[[g
+tabclr TBC            Clear a tab at the current column      ^[[0g
+tabclrall TBC         Clear all tabs                         ^[[3g
+
+dhtop DECDHL          Double-height letters, top half        ^[#3
+dhbot DECDHL          Double-height letters, bottom half     ^[#4
+swsh DECSWL           Single width, single height letters    ^[#5
+dwsh DECDWL           Double width, single height letters    ^[#6
+
+cleareol EL0          Clear line from cursor right           ^[[K
+cleareol EL0          Clear line from cursor right           ^[[0K
+clearbol EL1          Clear line from cursor left            ^[[1K
+clearline EL2         Clear entire line                      ^[[2K
+
+cleareos ED0          Clear screen from cursor down          ^[[J
+cleareos ED0          Clear screen from cursor down          ^[[0J
+clearbos ED1          Clear screen from cursor up            ^[[1J
+clearscreen ED2       Clear entire screen                    ^[[2J
+
+devstat DSR           Device status report                   ^[5n
+termok DSR               Response: terminal is OK            ^[0n
+termnok DSR              Response: terminal is not OK        ^[3n
+
+getcursor DSR         Get cursor position                    ^[6n
+cursorpos CPR            Response: cursor is at v,h          ^[<v>;<h>R
+
+ident DA              Identify what terminal type            ^[[c
+ident DA              Identify what terminal type (another)  ^[[0c
+gettype DA               Response: terminal type code n      ^[[?1;<n>0c
+
+reset RIS             Reset terminal to initial state        ^[c
+
+align DECALN          Screen alignment display               ^[#8
+testpu DECTST         Confidence power up test               ^[[2;1y
+testlb DECTST         Confidence loopback test               ^[[2;2y
+testpurep DECTST      Repeat power up test                   ^[[2;9y
+testlbrep DECTST      Repeat loopback test                   ^[[2;10y
+
+ledsoff DECLL0        Turn off all four leds                 ^[[0q
+led1 DECLL1           Turn on LED #1                         ^[[1q
+led2 DECLL2           Turn on LED #2                         ^[[2q
+led3 DECLL3           Turn on LED #3                         ^[[3q
+led4 DECLL4           Turn on LED #4                         ^[[4q
+
+#
+#  All codes below are for use in VT52 compatibility mode.
+#
+
+setansi               Enter/exit ANSI mode (VT52)            ^[<
+
+altkeypad             Enter alternate keypad mode            ^[=
+numkeypad             Exit alternate keypad mode             ^[>
+
+setgr                 Use special graphics character set     ^[F
+resetgr               Use normal US/UK character set         ^[G
+
+cursorup              Move cursor up one line                ^[A
+cursordn              Move cursor down one line              ^[B
+cursorrt              Move cursor right one char             ^[C
+cursorlf              Move cursor left one char              ^[D
+cursorhome            Move cursor to upper left corner       ^[H
+cursorpos(v,h)        Move cursor to v,h location            ^[<v><h>
+revindex              Generate a reverse line-feed           ^[I
+
+cleareol              Erase to end of current line           ^[K
+cleareos              Erase to end of screen                 ^[J
+
+ident                 Identify what the terminal is          ^[Z
+identresp             Correct response to ident              ^[/Z
+
+*)
+
+(*                    VT52 compatibility mode                 *)
+
+TYPE 
+    Array2  = ARRAY[0..1] OF CHAR;  
+    Array3  = ARRAY[0..2] OF CHAR;
+    Array4  = ARRAY[0..3] OF CHAR;
+    Array5  = ARRAY[0..4] OF CHAR;
+    Array6  = ARRAY[0..5] OF CHAR;
+    Array8  = ARRAY[0..7] OF CHAR;
+    Array10 = ARRAY[0..9] OF CHAR;
+
+
+VAR 
+    theterminal : termios.TERMIOS;
+    savedFd     : INTEGER;
+
+VAR                 (* cursor *)
+    cursorupStr     : Array3;
+    cursordnStr     : Array3;             
+    cursorrtStr     : Array3;            
+    cursorlfStr     : Array3;            
+    cursorhomeStr   : Array3;       
+    cursorposStr    : ARRAY [0..10] OF CHAR;
+    revindexStr     : Array3;        
+
+    cleareolStr     : Array3;         
+    cleareosStr     : Array3; 
+    
+VAR                 (* ident *)
+    identStr        : Array3; 
+    identrespStr    : ARRAY [0..3] OF CHAR;
+
+VAR                 (* graphic *)
+    setgrStr        : Array3;
+    resetgrStr      : Array3; 
+
+VAR                 (* VT52 mode *)
+    setansiStr      : Array3; 
+
+VAR                 (* keypad switch *)
+    altkeypadStr    : Array3;
+    numkeypadStr    :   Array3; 
+
+(*                                    VT100                                      *)
+VAR
+    setnlStr        : Array3;
+    setapplStr      : Array3;
+    setansi1Str     : Array3;
+    setcolStr       : Array3;
+    setsmoothStr    : Array3;
+    setrevscrnStr   : Array3;
+    setorgrelStr    : Array3;
+    setwrapStr      : Array3;
+    setrepStr       : Array3;
+    setinterStr     : Array3;
+
+    setlfStr        : Array3;
+    setcursorStr    : Array3;
+    setvt52Str      : Array3;
+    resetcolStr     : Array3;
+    setjumpStr      : Array3;
+    setnormscrnStr  : Array3;
+    setorgabsStr    : Array3;
+    resetwrapStr    : Array3;
+    resetrepStr     : Array3;
+    resetinterStr   : Array3;
+
+    altkeypad1Str   : Array3;
+    numkeypad1Str   : Array3;
+
+    setukg0Str      : Array3;
+    setukg1Str      : Array3;
+    setusg0Str      : Array3;
+    setusg1Str      : Array3;
+    setspecg0Str    : Array3;
+    setspecg1Str    : Array3;
+    setaltg0Str     : Array3;
+    setaltg1Str     : Array3;
+    setaltspecg0Str : Array3;
+    setaltspecg1Str : Array3;
+
+    setss2Str       : Array3;
+    setss3Str       : Array3;
+
+    modesoff0Str    : Array3;
+    modesoff1Str    : Array4;
+    boldStr         : Array4;
+    lowintStr       : Array4;
+    underlineStr    : Array4;
+    blinkStr        : Array4;
+    reverseStr      : Array4;
+    invisibleStr    : Array4;
+    italicStr       : Array4;
+    strikethroughStr: Array4; 
+
+    resetboldStr         : Array5;
+    resetlowintStr       : Array5;
+    resetunderlineStr    : Array5;
+    resetblinkStr        : Array5;
+    resetreverseStr      : Array5;
+    resetinvisibleStr    : Array5;
+    resetitalicStr       : Array5;
+    resetstrikethroughStr: Array5;
+
+    setwinStr       : Array3;
+
+    cursorup1Str    : Array3;
+    cursordn1Str    : Array3;
+    cursorrt1Str    : Array3;
+    cursorlf1Str    : Array3;
+    cursorhome0Str  : Array3;
+    cursorhome1Str  : Array4;
+    cursorpos1Str   : Array3;
+    hvhome0Str      : Array3;
+    hvhome1Str      : Array3;
+    hvposStr        : Array3;
+    indexStr        : Array3;
+    revindex1Str    : Array3;
+    nextlineStr     : Array3;
+    savecursStr     : Array3;
+    restorecursorStr: Array3;
+    requestCursorPositionStr: Array6;
+    tabsetStr       : Array3;
+    tabclr0Str      : Array3;
+    tabclr1Str      : Array3;
+    tabclrallStr    : Array3;
+
+    dhtopStr        : Array3;
+    dhbotStr        : Array3;
+    swshStr         : Array3;
+    dwshStr         : Array3;
+
+    cleareol0Str    : Array3;
+    cleareol1Str    : Array3;
+    clearbol2Str    : Array3;
+    clearlineStr    : Array3;
+
+    cleareos0Str    : Array3;
+    cleareos1Str    : Array3;
+    clearbos2Str    : Array3;
+    clearscreenStr  : Array4;
+
+    devstatStr      : Array3;
+    termokStr       : Array3;
+    termnokStr      : Array3;
+
+    getcursorStr    : Array3;
+    cursorpos2Str   : Array3;
+    cursorbnlStr    : Array3;
+    cursorblplStr   : Array3;
+    cursottocolStr  : Array3;
+    ident1Str       : Array3;
+    ident2Str       : Array3;
+    gettypeStr      : Array3;
+
+    resetStr        : Array3;
+
+    alignStr        : Array3;
+    testpuStr       : Array3;
+    testlbStr       : Array3;
+    testpurepStr    : Array3;
+    testlbrepStr    : Array3;
+    (* screen modes *)
+    resetScreenModeStr : Array6;
+    ledsoffStr      : Array3;
+    led1Str         : Array3;
+    led2Str         : Array3;
+    led3Str         : Array3;
+    led4Str         : Array3;
+    M40x25BWStr      : Array4;
+    M40x25CStr       : Array5;
+    M80x25BWStr      : Array5;
+    M80x25CStr       : Array5;
+    M320x200C4Str     : Array6;
+    M320x200BWStr    : Array6;
+    M640x200BWStr    : Array6;
+    M320x200C256Str     : Array6;
+    M640x200CStr     : Array6;
+    M640x350BWStr    : Array6;
+    M640x350CStr     : Array6;
+    M640x480BWStr    : Array6;
+    M640x480CStr     : Array6;
+    M320x200CStr     : Array6;
+    lineWrappingStr  : Array6;
+    resetLineWrappingStr : Array6;
+
+    (* some proprietary extensions *)
+    makeCursorInvisibleStr      : Array6;
+    makeCursorVisibleStr        : Array6;
+    restoreScreenStr            : Array6;
+    saveScreenStr               : Array6;
+    enableAlternativeBufferStr  : Array10;
+    disableAlternativeBufferStr : Array10;
+
+    doubleUnderlineStr           : Array6;
+    resetDoubleUnderlineStr     : Array6;
+    
+    (* colors *)
+    setAttributStr  : Array2;
+
+VAR
+    i : CARDINAL;
+
+PROCEDURE Card2Str ( x : CARDINAL; VAR str : ARRAY OF CHAR);
+
+BEGIN
+IF x < 10 THEN
+        CardToStr(x,1,str);
+    ELSIF x < 100 THEN
+        CardToStr(x,2,str);
+    ELSE
+        CardToStr(x,3,str);
+    END;
+END Card2Str;
+
+PROCEDURE affiche ( m : ARRAY OF CHAR; s : ARRAY OF CHAR);
+
+BEGIN
+    WriteString(m);WriteLn;
+    FOR i := 0 TO Length(s) DO
+        WriteHex(ORD(s[i]),2);
+        WriteChar(" ")
+    END; 
+    WriteLn;
+END affiche;
+
+(*
+PROCEDURE setnl;
+(* LMN             Set new line mode                      ^[[20h *)
+BEGIN
+END ;
+
+PROCEDURE setappl;
+(* DECCKM        Set cursor key to application          ^[[?1h *)
+BEGIN
+END ;
+
+PROCEDURE setansi;
+(* DECANM        Set ANSI (versus VT52)                 none *)
+BEGIN
+END ;
+
+PROCEDURE setcol;
+(* DECCOLM        Set number of columns to 132           ^[[?3h *)
+BEGIN
+END ;
+
+PROCEDURE setsmooth;
+(* DECSCLM     Set smooth scrolling                   ^[[?4h *)
+BEGIN
+END ;
+
+PROCEDURE setrevscrn;
+(* DECSCNM    Set reverse video on screen            ^[[?5h *)
+BEGIN
+END ;
+
+PROCEDURE setorgrel;
+(* DECOM       Set origin to relative                 ^[[?6h *)
+BEGIN
+END ;
+
+PROCEDURE setwrap;
+(* DECAWM        Set auto-wrap mode                     ^[[?7h *)
+BEGIN
+END ;
+
+PROCEDURE setrep;
+(* DECARM         Set auto-repeat mode                   ^[[?8h *)
+BEGIN
+END ;
+
+PROCEDURE setinter;
+(* DECINLM      Set interlacing mode                   ^[[?9h *)
+BEGIN
+END ;
+
+PROCEDURE setlf;
+(* LMN             Set line feed mode                     ^[[20l *)
+BEGIN
+END ;
+
+PROCEDURE setcursor;
+(* DECCKM      Set cursor key to cursor               ^[[?1l *)
+BEGIN
+END ;
+
+PROCEDURE setvt52;
+(* DECANM        Set VT52 (versus ANSI)                 ^[[?2l *)
+BEGIN
+END ;
+
+PROCEDURE resetcol;
+(* DECCOLM      Set number of columns to 80            ^[[?3l *)
+BEGIN
+END ;
+
+PROCEDURE setjump;
+(* DECSCLM       Set jump scrolling                     ^[[?4l *)
+BEGIN
+END ;
+
+PROCEDURE setnormscrn;
+(* DECSCNM   Set normal video on screen             ^[[?5l *)
+BEGIN
+END ;
+
+PROCEDURE setorgabs;
+(* DECOM       Set origin to absolute                 ^[[?6l *)
+BEGIN
+END ;
+
+PROCEDURE resetwrap;
+(* DECAWM      Reset auto-wrap mode                   ^[[?7l *)
+BEGIN
+END ;
+
+PROCEDURE resetrep;
+(* DECARM       Reset auto-repeat mode                 ^[[?8l *)
+BEGIN
+END ;
+
+PROCEDURE resetinter;
+(* DECINLM    Reset interlacing mode                 ^[[?9l *)
+BEGIN
+END ;
+
+PROCEDURE altkeypad;
+(* DECKPAM     Set alternate keypad mode              ^[= *)
+BEGIN
+END ;
+
+PROCEDURE numkeypad;
+(* DECKPNM     Set numeric keypad mode                ^[> *)
+BEGIN
+END ;
+
+PROCEDURE setukg0;
+    (* Set United Kingdom G0 character set    ^[(A *)
+BEGIN
+END ;
+
+PROCEDURE setukg1;
+    (* Set United Kingdom G1 character set    ^[)A *)
+BEGIN
+END ;
+
+PROCEDURE setusg0;
+(* Set United States G0 character set     ^[(B *)
+BEGIN
+END ;
+
+PROCEDURE setusg1;
+(* Set United States G1 character set     ^[)B *)
+BEGIN
+END ;
+
+PROCEDURE setspecg0;
+(* Set G0 special chars. & line set       ^[(0 *)
+BEGIN
+END ;
+
+PROCEDURE setspecg1;
+(* Set G1 special chars. & line set       ^[)0 *)
+BEGIN
+END ;
+
+PROCEDURE setaltg0;
+(* Set G0 alternate character ROM         ^[(1 *)
+BEGIN
+END ;
+
+PROCEDURE setaltg1;
+(* Set G1 alternate character ROM         ^[)1 *)
+BEGIN
+END ;
+
+PROCEDURE setaltspecg0;
+(* Set G0 alt char ROM and spec. graphics ^[(2 *)
+BEGIN
+END ;
+
+PROCEDURE setaltspecg1;
+(* Set G1 alt char ROM and spec. graphics ^[)2 *)
+BEGIN
+END ;
+
+PROCEDURE setss2 ;
+(* SS2 Set single shift 2                 ^[N *)
+BEGIN
+END ;
+
+PROCEDURE setss3;
+(* SS3 Set single shift 3                  ^[O *)
+BEGIN
+END ;
+*)
+PROCEDURE modesoff;
+(* SGR0 Turn off character attributes          ^[[m *)
+BEGIN
+    WriteString(modesoff0Str)
+END modesoff;
+
+PROCEDURE modesoff1;
+(* SGR0 Turn off character attributes          ^[[0m *)
+BEGIN
+    WriteString(modesoff1Str)
+END modesoff1;
+
+PROCEDURE bold;
+(* SGR1 Turn bold mode on                      ^[[1m *)
+BEGIN
+    WriteString(boldStr);
+END bold;
+
+PROCEDURE lowint;
+(* SGR2 Turn low intensity mode on             ^[[2m *)
+BEGIN
+    WriteString(lowintStr)
+END lowint;
+
+PROCEDURE italic;
+(* set italic mode                           ESC[3m *)
+BEGIN
+    WriteString(italicStr)
+END italic;
+
+PROCEDURE underline;
+(* SGR4 Turn underline mode on                 ^[[4m *)
+BEGIN
+    WriteString(underlineStr)
+END underline;
+
+PROCEDURE blink;
+(* SGR5 Turn blinking mode on                  ^[[5m *)
+BEGIN
+    WriteString(blinkStr)
+END blink;
+
+PROCEDURE reverse;
+(* SGR7 Turn reverse video on                  ^[[7m *)
+BEGIN
+    WriteString(reverseStr)
+END reverse;
+
+PROCEDURE invisible;
+(* SGR8 Turn invisible text mode on            ^[[8m *)
+BEGIN
+    WriteString(invisibleStr)
+END invisible;
+
+PROCEDURE strikethrough;
+BEGIN
+    WriteString(strikethroughStr)
+END strikethrough;
+
+PROCEDURE doubleUnderline;
+(* ESC[21m *)
+BEGIN
+    WriteString(doubleUnderlineStr)
+END doubleUnderline;
+
+PROCEDURE resetbold;
+(* SGR1 Turn bold mode on                      ^[[21m *)
+
+BEGIN
+    WriteString(resetboldStr)
+END resetbold;
+
+PROCEDURE resetlowint;
+(* SGR2 Turn low intensity mode on             ^[[22m *)
+BEGIN
+    WriteString(resetlowintStr)
+END resetlowint;
+
+
+PROCEDURE resetitalic;
+(* set italic mode                              ESC[23m *)
+BEGIN
+    WriteString(resetitalicStr)
+END resetitalic;
+
+
+PROCEDURE resetunderline;
+(* SGR4 Turn underline mode on                 ^[[24m *)
+BEGIN
+    WriteString(resetunderlineStr)
+END resetunderline;
+
+
+PROCEDURE resetblink;
+(* SGR5 Turn blinking mode on                  ^[[25m *)
+BEGIN
+    WriteString(resetblinkStr)
+END resetblink;
+
+
+PROCEDURE resetreverse;
+(* SGR7 Turn reverse video on                  ^[[27m *)
+BEGIN
+    WriteString(resetreverseStr)
+END resetreverse;
+
+
+PROCEDURE resetinvisible;
+(* SGR8 Turn invisible text mode on            ^[[28m *)
+BEGIN
+    WriteString(resetinvisibleStr)
+END resetinvisible;
+
+
+PROCEDURE resetstrikethrough;
+(* ESC[9m 	ESC[29m 	set strikethrough mode. *)
+BEGIN
+    WriteString(resetstrikethroughStr)
+END resetstrikethrough;
+
+PROCEDURE resetDoubleUnderline;
+(* ESC[24m. *)
+BEGIN
+    WriteString(resetDoubleUnderlineStr)
+END resetDoubleUnderline;
+
+
+(*
+PROCEDURE setwin;
+(* DECSTBM Set top and bottom line#s of a window  ^[[<v>;<v>r *)
+BEGIN
+END ;
+*)
+PROCEDURE cursorup(n : CARDINAL);
+(* CUU Move cursor up n lines                 ^[[<n>A *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+
+BEGIN
+    tmpString := "";
+    Card2Str(n,tmpString1);
+    tmpString2[0] := "A";
+
+    Concat(tmpString,cursorup1Str, tmpString);
+    Concat(tmpString, tmpString1,tmpString);
+    Concat(tmpString, tmpString2,tmpString);
+    WriteString(tmpString)
+END cursorup;
+
+PROCEDURE cursordn(n : CARDINAL);
+(* CUD Move cursor down n lines               ^[[<n>B *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+
+BEGIN
+    tmpString := "";
+    Card2Str(n,tmpString1);
+    tmpString2[0] := "B";
+
+    Concat(tmpString,cursordn1Str, tmpString);
+    Concat(tmpString, tmpString1,tmpString);
+    Concat(tmpString, tmpString2,tmpString);
+    WriteString(tmpString) 
+END cursordn;
+
+PROCEDURE cursorrt(n : CARDINAL);
+(* CUF Move cursor right n lines              ^[[<n>C *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+
+BEGIN
+    tmpString := "";
+    Card2Str(n,tmpString1);
+    tmpString2[0] := "C";
+
+    Concat(tmpString,cursorrt1Str, tmpString);
+    Concat(tmpString, tmpString1,tmpString);
+    Concat(tmpString, tmpString2,tmpString);
+    WriteString(tmpString)
+END cursorrt;
+
+PROCEDURE cursor1lf(n : CARDINAL);
+(* CUB Move cursor left n lines               ^[[<n>D *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+
+BEGIN
+    tmpString := "";
+    Card2Str(n,tmpString1);
+    tmpString2[0] := "D";
+
+    Concat(tmpString,cursorlf1Str, tmpString);
+    Concat(tmpString, tmpString1,tmpString);
+    Concat(tmpString, tmpString2,tmpString);
+    WriteString(tmpString)
+END cursor1lf;
+
+PROCEDURE cursorbnl(n : CARDINAL);
+(* ESC[#E 	moves cursor to beginning of next line, # lines down *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+    
+BEGIN
+    tmpString     := "";
+    tmpString2[0] := "E";
+    Card2Str(n,tmpString1);
+    Concat(tmpString,tmpString1,tmpString);
+    Concat(tmpString,tmpString2,tmpString);
+    WriteString(tmpString)
+END cursorbnl;
+
+PROCEDURE cursorblpl(n : CARDINAL);
+(* ESC[#F 	moves cursor to beginning of previous line, # lines up *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+    
+BEGIN
+    tmpString := "";
+    tmpString2[0] := "F";
+    Card2Str(n,tmpString1);
+    Concat(tmpString,tmpString1,tmpString);
+    Concat(tmpString,tmpString2,tmpString);
+    WriteString(tmpString)
+END cursorblpl;
+
+PROCEDURE cursottocol(n : CARDINAL);
+(* ESC[#G 	moves cursor to column # *)
+
+VAR
+    tmpString : ARRAY[0..5] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+    
+BEGIN
+    tmpString := "";
+    tmpString2[0] := "G";
+    Card2Str(n,tmpString1);
+    Concat(tmpString,tmpString1,tmpString);
+    Concat(tmpString,tmpString2,tmpString);
+    WriteString(tmpString)
+END cursottocol;
+
+PROCEDURE requestCursorPosition(VAR x,y : CARDINAL);
+(* ESC[6n 	request cursor position (reports as ESC[#;#R) *)
+
+VAR
+    str          : ARRAY [0..15] OF CHAR;
+    theStructure : SplitV1.Structure;
+
+BEGIN
+    SplitV1.InitStructure(theStructure);
+    (* sending the request *)
+    WriteString(requestCursorPositionStr);
+    (* quering the answer *)
+    ReadString(str);
+    (* extracting coodinates from the answer *)
+    (*PROCEDURE Delete (VAR stringVar: ARRAY OF CHAR; startIndex, numberToDelete: CARDINAL);
+D   eletes at most numberToDelete characters from stringVar, starting at position startIndex.
+    *)
+    Delete(str,0,2);
+    Delete(str,Length(str) -1 ,1);
+    SplitV1.SplitStr(str, ";", theStructure);
+    StrToCard(theStructure[0].element,x);
+    StrToCard(theStructure[1].element,y);
+
+END requestCursorPosition;
+
+PROCEDURE cursorhome;
+(* Move cursor to upper left corner       ^[[H *)
+BEGIN
+    WriteString(cursorhomeStr)
+END cursorhome;
+
+PROCEDURE cursorhome1;
+(* Move cursor to upper left corner       ^[[;H *)
+BEGIN
+    WriteString(cursorhome1Str)
+END cursorhome1;
+
+PROCEDURE cursorpos(x,y : CARDINAL);
+(* CUP Move cursor to screen location v,h     ^[[<v>;<h>H *)
+
+VAR
+    tmpString : ARRAY[0..10] OF CHAR;
+    tmpString1: ARRAY[0..5] OF CHAR;
+    tmpString2: String1;
+
+BEGIN
+    tmpString := "";
+    (* the preamble *)
+    Concat(tmpString,cursorpos1Str, tmpString);
+
+    (* the first coordinate *)
+    tmpString1 := "";
+    Card2Str(y,tmpString1);
+    Concat(tmpString,tmpString1, tmpString);
+
+    (* the separator *)
+    tmpString2[0] := ";";
+    Concat(tmpString, tmpString2,tmpString);
+
+    (* the second coordinate *)
+    tmpString1 := "";
+    Card2Str(x,tmpString1);
+    Concat(tmpString,tmpString1, tmpString);
+
+    (* the final *)
+    tmpString2[0] := "H";
+    Concat(tmpString, tmpString2,tmpString);
+
+    (*End Debug*)
+    WriteString(tmpString)
+
+END cursorpos;
+(*
+PROCEDURE hvhome;
+(* Move cursor to upper left corner       ^[[f *)
+BEGIN
+END ;
+
+PROCEDURE hvhome;
+(* Move cursor to upper left corner       ^[[;f *)
+BEGIN
+END ;
+
+PROCEDURE hvpos(v,h);
+(* CUP Move cursor to screen location v,h     ^[[<v>;<h>f *)
+BEGIN
+END ;
+
+PROCEDURE index;
+(* IND Move/scroll window up one line         ^[D *)
+
+PROCEDURE revindex;
+(* RI Move/scroll window down one line       ^[M *)
+BEGIN
+END ;
+
+PROCEDURE nextline;
+(* NEL Move to next line                      ^[E *)
+BEGIN
+END ;
+
+PROCEDURE savecursor;
+(* DECSC Save cursor position and attributes    ^[7 *)
+BEGIN
+END ;
+
+PROCEDURE restorecursor;
+(* DECSC Restore cursor position and attributes ^[8 *)
+BEGIN
+END ;
+
+PROCEDURE tabset;
+(* HTS Set a tab at the current column        ^[H *)
+BEGIN
+END ;
+
+PROCEDURE tabclr;
+(* TBC Clear a tab at the current column      ^[[g *)
+BEGIN
+END ;
+
+PROCEDURE tabclr;
+(* TBC Clear a tab at the current column      ^[[0g *)
+BEGIN
+END ;
+
+PROCEDURE tabclrall;
+(* TBC Clear all tabs                         ^[[3g *)
+BEGIN
+END ;
+
+PROCEDURE dhtop;
+(* DECDHL Double-height letters, top half        ^[#3 *)
+BEGIN
+END ;
+
+PROCEDURE dhbot;
+(* DECDHL Double-height letters, bottom half     ^[#4 *)
+BEGIN
+END ;
+
+PROCEDURE swsh;
+(* DECSWL Single width, single height letters    ^[#5 *)
+BEGIN
+END ;
+
+PROCEDURE dwsh;
+(* DECDWL Double width, single height letters    ^[#6 *)
+BEGIN
+END ;
+
+PROCEDURE cleareol;
+(* EL0 Clear line from cursor right           ^[[K *)
+BEGIN
+END ;
+
+PROCEDURE cleareol;
+(* EL0 Clear line from cursor right           ^[[0K *)
+BEGIN
+END ;
+
+PROCEDURE clearbol;
+(* EL1 Clear line from cursor left            ^[[1K *)
+BEGIN
+END ;
+
+PROCEDURE clearline;
+(* EL2 Clear entire line                      ^[[2K *)
+BEGIN
+END ;
+
+PROCEDURE cleareos;
+(* ED0 Clear screen from cursor down          ^[[J *)
+BEGIN
+END ;
+
+PROCEDURE cleareos;
+(* ED0 Clear screen from cursor down          ^[[0J *)
+BEGIN
+END ;
+
+PROCEDURE clearbos;
+(* ED1 Clear screen from cursor up            ^[[1J *)
+BEGIN
+END ;
+*)
+PROCEDURE clearscreen;
+(* ED2 Clear entire screen                    ^[[2J *)
+BEGIN
+    WriteString(clearscreenStr)
+END clearscreen;
+(*
+PROCEDURE devstat;
+(* DSR Device status report                   ^[5n *)
+BEGIN
+END ;
+
+PROCEDURE termok;
+(* DSR Response: terminal is OK            ^[0n *)
+BEGIN
+END ;
+
+PROCEDURE termnok;
+(* DSR Response: terminal is not OK        ^[3n *)
+BEGIN
+END ;
+
+PROCEDURE getcursor;
+(* DSR Get cursor position                    ^[6n *)
+BEGIN
+END ;
+
+PROCEDURE cursorpos;
+(* CPR Response: cursor is at v,h          ^[<v>;<h>R *)
+BEGIN
+END ;
+
+PROCEDURE ident;
+(* DA Identify what terminal type            ^[[c *)
+BEGIN
+END ;
+
+PROCEDURE ident;
+(* DA Identify what terminal type (another)  ^[[0c *)
+BEGIN
+END ;
+
+PROCEDURE gettype;
+(* DA Response: terminal type code n      ^[[?1;<n>0c *)
+BEGIN
+END ;
+
+PROCEDURE reset;
+(* RIS Reset terminal to initial state        ^[c *)
+BEGIN
+END ;
+
+PROCEDURE align;
+(* DECALN Screen alignment display               ^[#8 *)
+BEGIN
+END ;
+
+PROCEDURE testpu;
+(* DECTST Confidence power up test               ^[[2;1y *)
+BEGIN
+END ;
+
+PROCEDURE testlb;
+(* DECTST Confidence loopback test               ^[[2;2y *)
+BEGIN
+END ;
+
+PROCEDURE testpurep;
+(* DECTST Repeat power up test                   ^[[2;9y *)
+BEGIN
+END ;
+
+PROCEDURE testlbrep;
+(* DECTST Repeat loopback test                   ^[[2;10y *)
+BEGIN
+END ;
+
+PROCEDURE ledsoff;
+(* DECLL0 Turn off all four leds                 ^[[0q *)
+BEGIN
+END ;
+
+PROCEDURE led1;
+(* DECLL1 Turn on LED #1                         ^[[1q *)
+BEGIN
+END ;
+
+PROCEDURE led2;
+(* DECLL2 Turn on LED #2                         ^[[2q *)
+BEGIN
+END ;
+
+PROCEDURE led3;
+(* DECLL3 Turn on LED #3                         ^[[3q *)
+BEGIN
+END ;
+
+PROCEDURE led4;
+(* DECLL4 Turn on LED #4                         ^[[4q *)
+BEGIN
+END ;
+*)
+
+
+PROCEDURE screenMode(mode : screenModes);
+VAR
+    tmpString   : Array4;
+    scrMode     : screenModes;
+BEGIN
+    tmpString := "";
+    CASE scrMode OF
+        M40x25BW:       Assign(M40x25BWStr, tmpString);       |
+        M40x25C:        Assign(M80x25BWStr, tmpString);       |
+        M80x25BW:       Assign(M80x25BWStr, tmpString);       |
+        M80x25C:        Assign(M80x25CStr, tmpString);        |
+        M320x200C4:     Assign(M320x200C4Str, tmpString);     |
+        M320x200BW:     Assign(M320x200BWStr, tmpString);     |
+        M640x200BW:     Assign(M640x200BWStr, tmpString);     |
+        M320x200C256:   Assign(M320x200C256Str, tmpString);   |
+        M640x200C:      Assign(M640x200CStr, tmpString);      |
+        M640x350BW:     Assign(M640x350BWStr, tmpString);     |
+        M640x350C:      Assign(M640x350CStr, tmpString);      |
+        M640x480BW:     Assign(M640x480BWStr, tmpString);     |
+        M640x480C:      Assign(M640x480CStr, tmpString);      |
+        M320x200C:      Assign(M320x200CStr, tmpString);
+    END;
+    WriteString(tmpString)
+END screenMode;
+
+PROCEDURE resetScreenMode(mode : screenModes);
+BEGIN
+   WriteString(resetScreenModeStr)
+END resetScreenMode;
+
+PROCEDURE lineWrapping;
+BEGIN
+   WriteString(lineWrappingStr)
+END lineWrapping;
+
+PROCEDURE resetLineWrapping;
+BEGIN
+   WriteString(resetLineWrappingStr)
+END resetLineWrapping;
+
+PROCEDURE makeCursorInvisible;
+BEGIN
+   WriteString(makeCursorInvisibleStr)
+END makeCursorInvisible;
+
+PROCEDURE makeCursorVisible;
+BEGIN
+   WriteString(makeCursorVisibleStr)
+END makeCursorVisible;
+
+PROCEDURE restoreScreen;
+BEGIN
+   WriteString(restoreScreenStr)
+END restoreScreen;
+
+PROCEDURE saveScreen;
+BEGIN
+   WriteString(saveScreenStr)
+END saveScreen;
+
+PROCEDURE enableAlternativeBuffer;
+BEGIN
+   WriteString(enableAlternativeBufferStr)
+END enableAlternativeBuffer;
+
+PROCEDURE disableAlternativeBuffer;
+BEGIN
+   WriteString(disableAlternativeBufferStr)
+END disableAlternativeBuffer;
+
+PROCEDURE setAttribut ( attribut : Attribut; front, back : Colors );
+VAR
+    tmpString  : ARRAY [0..15] OF CHAR;
+    tmpString1 : ARRAY [0..1]  OF CHAR;
+    tmpString2 : ARRAY [0..2]  OF CHAR;
+    tmpString3 : String1;
+    tmpString4 : String1;
+    tmpString5 : String1;
+
+    (* esc + [ + attribut + ; + front + ; back + m *)
+BEGIN
+    tmpString1 := "";
+    tmpString2 := "";
+    tmpString3[0] := ";";
+    tmpString4[0] := "m";
+    (* esc [ *)
+    Concat(tmpString,setAttributStr,tmpString);
+    (* attribute *)
+    CASE attribut OF
+      boldAt:           tmpString5[0] := "1";   |
+      dimAt:            tmpString5[0] := "2";   |
+      italicAt:         tmpString5[0] := "3";   |
+      underlineAt:      tmpString5[0] := "4";   |
+      blinkingAt:       tmpString5[0] := "5";   |
+      inverseAt:        tmpString5[0] := "7";   |
+      hiddenAt:         tmpString5[0] := "8";   |
+      strikethroughAt:  tmpString5[0] := "9";   
+      (* doubleunderlineAt:tmpString2 := "21"; *)
+    END;
+    Concat(tmpString,tmpString5,tmpString);
+    (* special case with double underline *)
+    IF attribut = doubleunderlineAt THEN
+        Concat(tmpString,"21",tmpString);
+    END;
+    (* ; *)
+    Concat(tmpString,tmpString3,tmpString);
+    (* front *)
+    CASE front OF
+        Black:          tmpString1 := "30"; |
+        Red:            tmpString1 := "31"; |
+        Green:          tmpString1 := "32"; |
+        Yellow:         tmpString1 := "33"; |
+        Blue:           tmpString1 := "34"; |
+        Magenta:        tmpString1 := "35"; |
+        Cyan:           tmpString1 := "36"; |
+        White:          tmpString1 := "37"; |
+        Default:        tmpString1 := "39"; |
+        BrightBlack:    tmpString1 := "90"; |
+        BrightRed:      tmpString1 := "91"; |
+        BrightGreen:    tmpString1 := "92"; |
+        BrightYellow:   tmpString1 := "93"; |
+        BrightBlue:     tmpString1 := "94"; |
+        BrighMagenta:   tmpString1 := "95"; |
+        BrightCyan:     tmpString1 := "96"; |
+        BrightWhite:    tmpString1 := "97"; 
+    END;
+    Concat(tmpString,tmpString1,tmpString);
+    Concat(tmpString,tmpString3,tmpString);
+    (* back *)
+    CASE back OF
+        Black:          tmpString2 := "40";  |
+        Red:            tmpString2 := "41";  |
+        Green:          tmpString2 := "42";  |
+        Yellow:         tmpString2 := "43";  |
+        Blue:           tmpString2 := "44";  |
+        Magenta:        tmpString2 := "45";  |
+        Cyan:           tmpString2:= "46";   |
+        White:          tmpString2 := "47";  |
+        Default:        tmpString2 := "49";  |
+        BrightBlack:    tmpString2 := "100"; |
+        BrightRed:      tmpString2 := "101"; |
+        BrightGreen:    tmpString2 := "102"; |
+        BrightYellow:   tmpString2 := "103"; |
+        BrightBlue:     tmpString2 := "104"; |
+        BrighMagenta:   tmpString2 := "105"; |
+        BrightCyan:     tmpString2 := "106"; |
+        BrightWhite:    tmpString2 := "107"; 
+    END;
+    Concat(tmpString,tmpString2,tmpString);
+    (* m *)
+    Concat(tmpString,tmpString4,tmpString);
+    WriteString(tmpString)
+
+END setAttribut;
+
+(* 
+#
+#  All codes below are for use in VT52 compatibility mode.
+# 
+*)
+
+PROCEDURE VT52setansi;
+               (* Enter/exit ANSI mode (VT52)            ^[< *)
+BEGIN
+    WriteString(setansiStr)
+END VT52setansi ;
+
+PROCEDURE VT52altkeypad;
+             (* Enter alternate keypad mode            ^[= *)
+BEGIN
+    WriteString(altkeypadStr)
+END VT52altkeypad;
+
+PROCEDURE VT52numkeypad ;
+            (* Exit alternate keypad mode             ^[> *)
+BEGIN
+    WriteString(numkeypadStr)
+END VT52numkeypad;
+
+PROCEDURE VT52setgr ;
+                (* Use special graphics character set     ^[F *)
+BEGIN
+    WriteString(setgrStr)
+END VT52setgr;
+
+PROCEDURE VT52resetgr;
+               (* Use normal US/UK character set         ^[G *)
+BEGIN
+    WriteString(resetgrStr)
+END VT52resetgr;
+
+PROCEDURE VT52cursorup;
+              (* Move cursor up one line                ^[A *)
+BEGIN
+    WriteString(cursorupStr)
+END VT52cursorup;
+
+PROCEDURE VT52cursordn;
+              (* Move cursor down one line              ^[B *)
+BEGIN
+    WriteString(cursordnStr)
+END VT52cursordn;
+
+PROCEDURE VT52cursorrt;
+              (* Move cursor right one char             ^[C *)
+BEGIN
+    WriteString(cursorrtStr)
+END VT52cursorrt;
+
+PROCEDURE VT52cursorlf;
+              (* Move cursor left one char              ^[D *)
+BEGIN
+    WriteString(cursorlfStr)
+END VT52cursorlf;
+
+PROCEDURE VT52cursorhome;
+            (* Move cursor to upper left corner       ^[H *)
+BEGIN
+    WriteString(cursorhomeStr)
+END VT52cursorhome;
+
+PROCEDURE VT52cursorpos(y ,x : CARDINAL);
+        (* Move cursor to v,h location            ^[<v><h> *)
+    VAR
+        tmpString       : ARRAY [0..10] OF CHAR;
+        tmpString1,
+        tmpString2,
+        tmpString3      : String1;
+        xPos, yPos      : CARDINAL;
+
+BEGIN
+    Concat(tmpString,cursorposStr,tmpString);
+    xPos := x  + 31;  
+    yPos := y + 31;  
+    (* don't forget to flip x and y *)
+    tmpString1[0] :=  CHR(yPos);
+    tmpString2[0] :=  CHR(xPos);
+    (* tmpString3[0] :=  "H"; *)
+    Concat(tmpString,tmpString1, tmpString);
+    Concat(tmpString,tmpString2, tmpString);  
+    (* Concat(tmpString,tmpString3, tmpString); *)
+    WriteString(tmpString)
+END VT52cursorpos;
+
+PROCEDURE VT52revindex;
+              (* Generate a reverse line-feed           ^[I *)
+BEGIN
+    WriteString(revindexStr)
+END VT52revindex;
+
+PROCEDURE VT52cleareol;
+              (* Erase to end of current line           ^[K *)
+BEGIN
+    WriteString(cleareolStr)
+END VT52cleareol;
+
+PROCEDURE VT52cleareos;
+              (* Erase to end of screen                 ^[J *)
+BEGIN
+    WriteString(cleareosStr)
+END VT52cleareos;
+
+PROCEDURE VT52ident;
+                 (* Identify what the terminal is          ^[Z *)
+BEGIN
+    WriteString(identStr)
+END VT52ident;
+
+PROCEDURE VT52identresp;
+             (* Correct response to ident              ^[/Z *)
+BEGIN
+    WriteString(identrespStr)
+END VT52identresp; 
+
+PROCEDURE CloseTerminal;
+    (* PROCEDURE tcsetattr (fd: INTEGER; option: INTEGER; t: TERMIOS) : INTEGER ; *)
+
+   VAR
+        theResult : INTEGER;
+BEGIN
+    theResult  := termios.tcsetattr(savedFd,termios.lflusho,theterminal);
+    IF theResult <> 0 THEN
+        WriteString(" Terminal state properly restored !")
+    ELSE
+        WriteString("Terminal not properly restored !")
+    END;
+END CloseTerminal;
+
+
+PROCEDURE InitTerminal;
+(* PROCEDURE tcgetattr (fd: INTEGER; t: TERMIOS) : INTEGER ; *)
+
+    VAR
+        theResult : INTEGER;
+BEGIN
+    theterminal := termios.InitTermios();
+    theResult  := termios.tcgetattr(savedFd, theterminal);
+    IF theResult <> -1 THEN
+        WriteString(" Terminal state properly saved !")
+    ELSE
+        WriteString("Terminal state not properly saved")
+    END;
+    termios.cfmakeraw (theterminal) ;
+END InitTerminal;
+
+BEGIN
+    (* VT 52 mode *)
+    Concat(ASCII.esc,"[<",setansiStr);
+
+    Concat(ASCII.esc,"[=",altkeypadStr);
+    Concat(ASCII.esc,"[>",numkeypadStr);
+
+    Concat(ASCII.esc,"[F",setgrStr);
+    Concat(ASCII.esc,"[G",resetgrStr);
+
+    Concat(ASCII.esc,"[A",cursorupStr);
+    Concat(ASCII.esc,"[B",cursordnStr);
+    Concat(ASCII.esc,"[C",cursorrtStr);
+    Concat(ASCII.esc,"[D",cursorlfStr);
+    Concat(ASCII.esc,"[H",cursorhomeStr);
+    Concat(ASCII.esc,"[Y",cursorposStr);
+    Concat(ASCII.esc,"[I",revindexStr);
+
+    Concat(ASCII.esc,"[K",cleareolStr);
+    Concat(ASCII.esc,"[J",cleareosStr);
+
+    Concat(ASCII.esc,"[Z",identStr);
+    Concat(ASCII.esc,"[/Z",identrespStr);
+
+    (* VT100 mode *)
+    Concat(ASCII.esc,"[",setnlStr);
+    Concat(ASCII.esc,"[",setapplStr);
+    Concat(ASCII.esc,"[",setansi1Str);
+    Concat(ASCII.esc,"[",setcolStr);
+    Concat(ASCII.esc,"[",setsmoothStr);
+    Concat(ASCII.esc,"[",setrevscrnStr);
+    Concat(ASCII.esc,"[",setorgrelStr);
+    Concat(ASCII.esc,"[",setwrapStr);
+    Concat(ASCII.esc,"[",setrepStr);
+    Concat(ASCII.esc,"[",setinterStr);
+
+    Concat(ASCII.esc,"[",setlfStr);
+    Concat(ASCII.esc,"[",setcursorStr);
+    Concat(ASCII.esc,"[",setvt52Str);
+    Concat(ASCII.esc,"[",resetcolStr);
+    Concat(ASCII.esc,"[",setjumpStr);
+    Concat(ASCII.esc,"[",setnormscrnStr);
+    Concat(ASCII.esc,"[",setorgabsStr);
+    Concat(ASCII.esc,"[",resetwrapStr);
+    Concat(ASCII.esc,"[",resetrepStr);
+    Concat(ASCII.esc,"[",resetinterStr);
+
+    Concat(ASCII.esc,"[",altkeypad1Str);
+    Concat(ASCII.esc,"[",numkeypad1Str);
+
+    Concat(ASCII.esc,"[",setukg0Str);
+    Concat(ASCII.esc,"[",setukg1Str);
+    Concat(ASCII.esc,"[",setusg0Str);
+    Concat(ASCII.esc,"[",setusg1Str);
+    Concat(ASCII.esc,"[",setspecg0Str);
+    Concat(ASCII.esc,"[",setspecg1Str);
+    Concat(ASCII.esc,"[",setaltg0Str);
+    Concat(ASCII.esc,"[",setaltg1Str);
+    Concat(ASCII.esc,"[",setaltspecg0Str);
+    Concat(ASCII.esc,"[",setaltspecg1Str);
+
+    Concat(ASCII.esc,"[",setss2Str);
+    Concat(ASCII.esc,"[",setss3Str);
+
+    Concat(ASCII.esc,"[m",modesoff0Str);
+    Concat(ASCII.esc,"[0m",modesoff1Str);
+    Concat(ASCII.esc,"[1m",boldStr);
+    Concat(ASCII.esc,"[2m",lowintStr);
+    Concat(ASCII.esc,"[3m",italicStr);
+    Concat(ASCII.esc,"[4m",underlineStr);
+    Concat(ASCII.esc,"[5m",blinkStr);
+    Concat(ASCII.esc,"[7m",reverseStr);
+    Concat(ASCII.esc,"[8m",invisibleStr);
+    Concat(ASCII.esc,"[9m",strikethroughStr);
+
+    Concat(ASCII.esc,"[22m",resetboldStr);
+    Concat(ASCII.esc,"[22m",resetlowintStr);
+    Concat(ASCII.esc,"[23m",resetitalicStr);
+    Concat(ASCII.esc,"[24m",resetunderlineStr);
+    Concat(ASCII.esc,"[25m",resetblinkStr);
+    Concat(ASCII.esc,"[27m",resetreverseStr);
+    Concat(ASCII.esc,"[28m",resetinvisibleStr);
+    Concat(ASCII.esc,"[29m",resetstrikethroughStr);
+
+
+    Concat(ASCII.esc,"[",setwinStr);
+
+    Concat(ASCII.esc,"[",cursorup1Str);
+    Concat(ASCII.esc,"[",cursordn1Str);
+    Concat(ASCII.esc,"[",cursorrt1Str);
+    Concat(ASCII.esc,"[",cursorlf1Str);
+    Concat(ASCII.esc,"[",cursorhome0Str);
+    Concat(ASCII.esc,"[;H",cursorhome1Str);
+    Concat(ASCII.esc,"[",cursorpos1Str);
+    Concat(ASCII.esc,"[6n",requestCursorPositionStr);
+    Concat(ASCII.esc,"[",hvhome0Str);
+    Concat(ASCII.esc,"[",hvhome1Str);
+    Concat(ASCII.esc,"[",cursorbnlStr);
+    Concat(ASCII.esc,"[",cursorblplStr);
+    Concat(ASCII.esc,"[",cursottocolStr);
+    Concat(ASCII.esc,"[",hvposStr);
+    Concat(ASCII.esc,"[",indexStr);
+    Concat(ASCII.esc,"[",revindex1Str);
+    Concat(ASCII.esc,"[",nextlineStr);
+    Concat(ASCII.esc,"[",savecursStr);
+    Concat(ASCII.esc,"[",restorecursorStr);
+
+    Concat(ASCII.esc,"[",tabsetStr);
+    Concat(ASCII.esc,"[",tabclr0Str);
+    Concat(ASCII.esc,"[",tabclr1Str);
+    Concat(ASCII.esc,"[",tabclrallStr);
+
+    Concat(ASCII.esc,"[",dhtopStr);
+    Concat(ASCII.esc,"[",dhbotStr);
+    Concat(ASCII.esc,"[",swshStr);
+    Concat(ASCII.esc,"[",dwshStr);
+
+    Concat(ASCII.esc,"[",cleareol0Str);
+    Concat(ASCII.esc,"[",cleareol1Str);
+    Concat(ASCII.esc,"[",clearbol2Str);
+    Concat(ASCII.esc,"[",clearlineStr);
+
+    Concat(ASCII.esc,"[",cleareos0Str);
+    Concat(ASCII.esc,"[",cleareos1Str);
+    Concat(ASCII.esc,"[",clearbos2Str);
+    Concat(ASCII.esc,"[2J",clearscreenStr);
+
+    Concat(ASCII.esc,"[",devstatStr);
+    Concat(ASCII.esc,"[",termokStr);
+    Concat(ASCII.esc,"[",termnokStr);
+
+    Concat(ASCII.esc,"[",getcursorStr);
+    Concat(ASCII.esc,"[",cursorpos2Str);
+
+    Concat(ASCII.esc,"[",ident1Str);
+    Concat(ASCII.esc,"[",ident2Str);
+    Concat(ASCII.esc,"[",gettypeStr);
+
+    Concat(ASCII.esc,"[",resetStr);
+
+    Concat(ASCII.esc,"[",alignStr);
+    Concat(ASCII.esc,"[",testpuStr);
+    Concat(ASCII.esc,"[",testlbStr);
+    Concat(ASCII.esc,"[",testpurepStr);
+    Concat(ASCII.esc,"[",testlbrepStr);
+
+    Concat(ASCII.esc,"[",ledsoffStr);
+    Concat(ASCII.esc,"[",led1Str);
+    Concat(ASCII.esc,"[",led2Str);
+    Concat(ASCII.esc,"[",led3Str);
+    Concat(ASCII.esc,"[",led4Str);
+Concat(ASCII.esc,"[=0h",M40x25BWStr);    (*	40 x 25 monochrome (text)*)
+Concat(ASCII.esc,"[=1h",M40x25CStr);     (* 	40 x 25 color (text)*)
+Concat(ASCII.esc,"[=2h",M40x25CStr);     (* 	80 x 25 monochrome (text)*)
+Concat(ASCII.esc,"[=3h",M80x25CStr);     (* 	80 x 25 color (text)*)
+Concat(ASCII.esc,"[=4h",M320x200C4Str);   (* 	320 x 200 4-color (graphics)*)
+Concat(ASCII.esc,"[=5h",M320x200BWStr);  (* 	320 x 200 monochrome (graphics)*)
+Concat(ASCII.esc,"[=6h",M640x200BWStr);  (* 	640 x 200 monochrome (graphics)*)
+Concat(ASCII.esc,"[=7h",resetLineWrappingStr);              (* 	Enables line wrapping*)
+Concat(ASCII.esc,"[=13h",M640x200BWStr); (* 	320 x 200 color (graphics)*)
+Concat(ASCII.esc,"[=14h",M640x200CStr);  (* 	640 x 200 color (16-color graphics)*)
+Concat(ASCII.esc,"[=15h",M640x200CStr);  (* 	640 x 350 monochrome (2-color graphics)*)
+Concat(ASCII.esc,"[=16h",M640x350CStr);  (* 	640 x 350 color (16-color graphics)*)
+Concat(ASCII.esc,"[=17h",M640x480BWStr); (*	640 x 480 monochrome (2-color graphics)*)
+Concat(ASCII.esc,"[=18h",M640x480CStr);  (* 	640 x 480 color (16-color graphics)*)
+Concat(ASCII.esc,"[=19h",M320x200CStr);  (* 	320 x 200 color (256-color graphics)*)
+(* ESC[={value}l *)
+
+
+Concat(ASCII.esc,"[?25l",makeCursorInvisibleStr); (* ESC[?25l 	make cursor invisible *)
+Concat(ASCII.esc,"[?25h",makeCursorVisibleStr); (* ESC[?25h 	make cursor visible *)
+Concat(ASCII.esc,"[?47l",restoreScreenStr); (* ESC[?47l 	restore screen *)
+Concat(ASCII.esc,"[?47h",saveScreenStr); (* ESC[?47h 	save screen *)
+Concat(ASCII.esc,"[?1049h",enableAlternativeBufferStr); (* ESC[?1049h 	enables the alternative buffer *)
+Concat(ASCII.esc,"[?1049l",disableAlternativeBufferStr); (* ESC[?1049l 	disables the alternative buffer *)
+
+
+Concat(ASCII.esc,"[21m",resetinvisibleStr);             (* ESC[21m *)
+Concat(ASCII.esc,"[24m",resetDoubleUnderlineStr);      (* ESC[24m. *)
+Concat(ASCII.esc,"[", setAttributStr);
+
+END VT100.
+
+   (*Debug*)
+    (* chaine := "toto"; *)
+    (* FOR i := 0 TO Length(tmpString) DO
+        WriteHex(ORD(tmpString[i]),2);
+        WriteChar(" ")
+    END; *)
+    (*End Debug*)

BIN
step41/VT100.o


+ 150 - 0
step41/Winsize.txt

@@ -0,0 +1,150 @@
+Programs (such as vi) which automatically adjust to screen resizing are responding to 
+the SIGWINCH signal, and using a system call to obtain the system's information about 
+the screen-size. See for example Get width/height of a terminal window in c++?. By the 
+way, though widely implemented, it does not appear to be documented in POSIX signal.h.
+
+Without taking SIGWINCH into account, a program could ask the terminal about its screensize.
+ The resize program does this, by sending the terminal control sequences to
+
+    move the cursor to the lower-right corner (actually, to row/column 999/999, which is 
+    good enough), and
+    asking the terminal where the cursor really is.
+
+The behavior of ls and vi (and other programs) regarding ANSI control sequences which would 
+be embedded in their output depends upon the design of the program. They likely detect 
+the redirection of their output to a file using the isatty function, and do something 
+different depending on whether the output is to a terminal, or to a file.
+
+
+    if (write_eintr(STDOUT_FILENO, "\x1b[999C\x1b[999B", len) == len) {
+        if (get_cursor_pos(wi) == TERM_SUCCESS) {
+            return TERM_SUCCESS;
+        }
+    }
+
+
+
+    ******************
+
+    // Source - https://codereview.stackexchange.com/a/292637
+// Posted by Madagascar, modified by community. See post 'Timeline' for change history
+// Retrieved 2026-05-28, License - CC BY-SA 4.0
+
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
+
+#define _POSIX_C_SOURCE     200819L
+#define _XOPEN_SOURCE       700
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "io.h"
+#include "sequences.h"
+#include "term.h"
+
+static bool parse_long(const char s[static 1], int base, long val[static 1])
+{
+    char *endptr;
+    errno = 0;
+    const long i = strtol(s, &endptr, base);
+    
+    if (endptr == s || *endptr != '\0' || errno != 0) {
+        return false;
+    }
+
+    *val = i;
+    return true;
+}
+
+static TermCodes get_cursor_pos(WinInfo wi[static 1])
+{
+    /* The cursor is positioned at the bottom right of the window. We can learn 
+     * how many rows and columns there must be on the screen by querying the
+     * position of the cursor. */
+    ssize_t len = (ssize_t) strlen("\x1b[6n");
+
+    if (write_eintr(STDOUT_FILENO, "\x1b[6n", len) != len) {
+        return TERM_FAILURE;
+    }
+
+    /* The reply is an escape sequence of the form '\x1b[24;80R', we will
+     * read it into a buffer until read() returns EOF or until we get to
+     * the 'R' character. */
+    char buf[32];   /* Should be more than enough. */
+
+    for (size_t i = 0; i < sizeof buf - 1; ++i) {
+        if (read_eintr(STDIN_FILENO, &buf[i], 1) != 1 || buf[i] == 'R') {
+            break;
+        }
+    }
+    *buf = '\0';
+
+    /* Skip the escape character and the left square brace. */
+    return memcmp(buf, "\x1b[", 2) != 0
+        || sscanf(&buf[2], "%u;%u", &wi->rows, &wi->cols) != 2
+        ? TERM_FAILURE
+        : TERM_SUCCESS;
+}
+
+TermCodes term_get_winsize(WinInfo wi[static 1])
+{
+#if defined(TIOCGWINSZ)
+    struct winsize ws;
+
+    if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) {
+        wi->rows = ws.ws_row;
+        wi->cols = ws.ws_col;
+        return TERM_SUCCESS;
+    }
+#elif defined(TIOCGSIZE) 
+    struct ttysize ts;
+
+    if (ioctl(STDOUT_FILENO, TIOCGSIZE, &ts) == 0) {
+        wi->rows = ts.ts_row;
+        wi->cols = ts.ts_col;
+        return TERM_SUCCESS;
+    }
+#endif /* defined(TIOCGWINSZ) */
+
+    /* ioctl() failed. Fallback to VT100/ANSI escape sequences. */
+    ssize_t len = (ssize_t) strlen("\x1b[999C\x1b[999B");
+
+    if (write_eintr(STDOUT_FILENO, "\x1b[999C\x1b[999B", len) == len) {
+        if (get_cursor_pos(wi) == TERM_SUCCESS) {
+            return TERM_SUCCESS;
+        }
+    }
+    
+    /* write() or get_cursor_pos() failed as well. Now as a last resort, check
+     * LINES and COLUMNS environment variables. 
+     * Though note that these variables are not reliable, are not guaranteed 
+     * to exist, and might not be up to date if the user changes the terminal 
+     * size. If set, the sh, ash, dash, csh shells do not update LINES and
+     * COLUMNS, but bash, fish, zsh, ksh, ksh93u+m, and tcsh handle SIGWINCH to
+     * update these variables. */
+    const char *const rows = getenv("LINES");
+    const char *const cols = getenv("COLUMNS");
+
+    if (rows != nullptr && cols != nullptr) {
+        long r;
+        long c;
+        bool res = parse_long(rows, 10, &r) && parse_long(cols, 10, &c);
+    
+        if (!res || r > UINT_MAX || c > UINT_MAX) {
+            return TERM_FAILURE;
+        }
+
+        wi->rows = (unsigned int) r;
+        wi->cols = (unsigned int) c;
+        return TERM_SUCCESS;
+    }
+    return TERM_FAILURE; 
+}

BIN
step41/editor


+ 342 - 0
step41/editor.mod

@@ -0,0 +1,342 @@
+MODULE editor1;
+
+(* based on the kilo editor building course*)
+
+(* Step 39 *)
+
+(******************** INCLUDES ******************)
+
+IMPORT IO, Strings, ASCII, NumberIO, termios, FIO, Delay, SplitV1, STextIO;
+IMPORT libc, SYSTEM, Storage, MemUtils;
+
+(******************** DATA ******************)
+
+
+CONST 
+    KILO_VERSION =  "0.0.1";
+
+TYPE
+    abufType            = RECORD
+                            b   : SYSTEM.ADDRESS;
+                            len : CARDINAL;
+                          END;
+    abufTypePtr         = POINTER TO abufType;
+
+VAR
+    editorConfig        : RECORD
+                            screenrows : CARDINAL;
+                            screencols : CARDINAL;
+                            theTermios : termios.TERMIOS;
+                         END;
+
+    TCSAFLUSH           : INTEGER;
+
+    theStructure        : SplitV1.Structure;
+
+    cursorposStr        : ARRAY [0..15] OF CHAR;
+    clearScreenStr      : ARRAY[0..6] OF CHAR;
+    cursorHomeStr       : ARRAY[0..2] OF CHAR;
+    requestCursorPosStr : ARRAY[0..15] OF CHAR;
+    cursorOnStr         : ARRAY[0..6] OF CHAR;
+    cursorOffStr        : ARRAY[0..6] OF CHAR;
+    tildeStr            : ARRAY[0..3] OF CHAR;
+    eraseLineStr        : ARRAY[0..2] OF CHAR;
+
+    resultStr           : ARRAY [0..15] OF CHAR;
+    tmpString           : ARRAY[0..15] OF CHAR;
+    tmpString1          : ARRAY[0..15] OF CHAR;
+    tmpString2          : Strings.String1;
+    cc                  : Strings.String1;
+    i                   : CARDINAL;
+    str                 : ARRAY [0..15] OF CHAR;
+
+    abuf                : abufType;
+ 
+(******************** Utilities *****************)
+
+    PROCEDURE Card2Str ( x : CARDINAL; VAR str : ARRAY OF CHAR);
+
+    BEGIN
+    IF x < 10 THEN
+            NumberIO.CardToStr(x,1,str);
+        ELSIF x < 100 THEN
+            NumberIO.CardToStr(x,2,str);
+        ELSE
+            NumberIO.CardToStr(x,3,str);
+        END;
+    END Card2Str;
+
+    (******************** TERMINAL ******************)
+
+    PROCEDURE CtrlKey(c: CHAR) : CARDINAL;
+        (* return a value < ORD(" ") for the control keys *)
+        VAR
+            n : BITSET;
+
+    BEGIN
+        n := BITSET(ORD(c));
+        n := n * BITSET(1FH);
+        RETURN CARDINAL(n)
+    END CtrlKey;
+
+    PROCEDURE die (s : ARRAY OF CHAR);
+    BEGIN
+        libc.perror(s);
+        FOR i := 0 TO Strings.Length(s) DO
+            IO.Write(s[i])
+        END;
+        HALT
+    END die;
+
+    PROCEDURE disablerawMode() : INTEGER;
+
+        VAR
+            result : INTEGER;
+    BEGIN
+        IO.BufferedMode(0,TRUE);
+        IO.BufferedMode(1,TRUE);
+        result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, editorConfig.theTermios);
+        IF result = -1 THEN
+            die("tcsetattr")
+        ELSE 
+            RETURN result
+        END;
+    END disablerawMode;
+
+    PROCEDURE enablerawMode;
+    BEGIN
+        libc.atexit(disablerawMode);
+
+        editorConfig.theTermios := termios.InitTermios();
+        (* raw := termios.InitTermios(); *)
+        IF termios.tcgetattr(FIO.StdIn, editorConfig.theTermios) = -1 THEN
+            die("tcgetattr")
+        END;
+
+        IO.UnBufferedMode(0,TRUE);
+        IO.UnBufferedMode(1,TRUE);
+    END enablerawMode;
+
+    PROCEDURE  editorReadKey() : CHAR;
+        VAR
+            c : CHAR;
+    BEGIN
+        IO.Read(c);
+        RETURN c
+    END editorReadKey; 
+
+    (******************** Buffer ******************)
+
+    PROCEDURE abufInit( VAR ptr : abufTypePtr);
+    BEGIN
+        Storage.ALLOCATE(ptr,SYSTEM.TSIZE(abufType) );
+        ptr^.b := NIL;
+        ptr^.len := 0;
+    END abufInit;
+
+    PROCEDURE abAppend (VAR ptr : abufTypePtr; str: ARRAY OF CHAR );
+
+        VAR
+            llen : CARDINAL;
+    BEGIN
+        llen := Strings.Length(str);
+        IF ptr <> NIL THEN
+            IF ptr^.b = NIL THEN
+                Storage.ALLOCATE(ptr^.b,llen);
+            ELSE
+                Storage.REALLOCATE( ptr^.b,ptr^.len + llen);
+            END;
+            MemUtils.MemCopy(SYSTEM.ADR(str),llen, SYSTEM.ADDADR(ptr^.b,ptr^.len));
+            ptr^.len := ptr^.len + llen;
+        END;
+    END abAppend;
+
+    PROCEDURE abFree (VAR ptr : abufTypePtr);
+
+    BEGIN
+        Storage.DEALLOCATE(ptr^.b, ptr^.len);
+        Storage.DEALLOCATE(ptr,SYSTEM.TSIZE(abufType));
+    END abFree;
+
+    (******************** output ******************)
+
+    PROCEDURE editorDrawRows(VAR ptr : abufTypePtr);
+
+        VAR
+            y : CARDINAL;
+            str : ARRAY [0..3] OF CHAR;
+            welcome : ARRAY [0..79] OF CHAR;
+            welcomeLen : CARDINAL;
+
+    BEGIN
+        welcome := "Kilo editor -- version ";
+        Strings.Concat(welcome,KILO_VERSION,welcome);
+        welcomeLen := Strings.Length(welcome);
+        cc[0] := CHR(13);
+        Strings.Concat(welcome,cc,welcome);
+        cc[0] := CHR(10);
+        Strings.Concat(welcome,cc,welcome);
+
+        FOR y := 1 TO editorConfig.screenrows -1 DO
+            IF ((y = (editorConfig.screenrows / 3)) AND (editorConfig.screencols > welcomeLen)) THEN
+                abAppend(ptr,welcome);
+            ELSE
+                abAppend(ptr,tildeStr);
+            END;
+            abAppend(ptr,eraseLineStr)
+        END;
+        abAppend(ptr,"~");
+    END editorDrawRows;
+
+   PROCEDURE editorRefreshScreen;
+
+        VAR
+            ptr : abufTypePtr;
+    BEGIN
+        abufInit(ptr);
+        abAppend(ptr,cursorOffStr);
+        (* abAppend(ptr,clearScreenStr); *)
+        abAppend(ptr,cursorHomeStr);
+        editorDrawRows(ptr);
+        abAppend(ptr,cursorHomeStr);
+        abAppend(ptr,cursorOnStr);
+        libc.write(FIO.StdOut,ptr^.b,ptr^.len);
+        abFree(ptr);
+    END editorRefreshScreen;
+
+    PROCEDURE requestCursorPosition(VAR x,y : CARDINAL);
+
+        VAR
+            c   : CHAR;
+
+    BEGIN
+        str := "";
+        SplitV1.InitStructure(theStructure);
+        Strings.Concat(str,ASCII.esc,str);
+        Strings.Concat(str,"[6n", str);
+        libc.write(FIO.StdOut,SYSTEM.ADR(str),4);
+        (* getting answer *)
+        str := "";
+        REPEAT
+            IO.Read(c);
+            cc[0] := c;
+            Strings.Concat(str,cc,str);
+        UNTIL c = "R";
+        (* extracting the coordinates *)
+        Strings.Delete(str,0,2);
+        Strings.Delete(str,Strings.Length(str) -1 ,1);
+        SplitV1.SplitStr(str, ";", theStructure);
+        NumberIO.StrToCard(theStructure[0].element,y);
+        NumberIO.StrToCard(theStructure[1].element,x);
+    END requestCursorPosition;
+
+    PROCEDURE cursorpos(x,y : CARDINAL);
+    BEGIN
+        cursorposStr := "";
+        Strings.Concat(cursorposStr, ASCII.esc,cursorposStr);
+        Strings.Concat(cursorposStr, "[",cursorposStr);
+        tmpString := "";
+        Strings.Concat(tmpString,cursorposStr, tmpString);
+        tmpString1 := "";
+        Card2Str(y,tmpString1);
+        Strings.Concat(tmpString,tmpString1, tmpString);
+        tmpString2[0] := ";";
+        Strings.Concat(tmpString, tmpString2,tmpString);
+        tmpString1 := "";
+        Card2Str(x,tmpString1);
+        Strings.Concat(tmpString,tmpString1, tmpString);
+        tmpString2[0] := "H";
+        Strings.Concat(tmpString, tmpString2,tmpString);
+        libc.write(FIO.StdOut,SYSTEM.ADR(tmpString),Strings.Length(tmpString));
+    END cursorpos;
+
+    PROCEDURE getWindowSize(VAR y : CARDINAL; VAR x: CARDINAL);
+    
+    BEGIN
+        cursorpos(999,999);
+        requestCursorPosition(x,y);
+    END getWindowSize;
+
+    (******************** input  ******************)
+
+    PROCEDURE editorProcessKeypress;
+        VAR
+            c       : CHAR;
+            b       : BOOLEAN;
+    BEGIN
+        c := editorReadKey();
+        CASE ORD(c) OF
+          17 : HALT;
+        END
+    END editorProcessKeypress;
+
+    (********************  INIT  ******************)
+
+    PROCEDURE InitScreenEscapes;
+
+    VAR temp : ARRAY[0..10] OF CHAR;
+    BEGIN
+        cursorHomeStr := "";
+        Strings.Concat(cursorHomeStr,ASCII.esc,cursorHomeStr);
+        Strings.Concat(cursorHomeStr,"[H",cursorHomeStr);
+
+        clearScreenStr := "";
+        Strings.Concat(clearScreenStr,ASCII.esc,clearScreenStr);
+        Strings.Concat(clearScreenStr,"[2J",clearScreenStr);
+
+        cursorposStr := "";
+        Strings.Concat(cursorposStr,ASCII.esc,cursorposStr);
+        Strings.Concat(cursorposStr,"[",cursorposStr);
+    
+        requestCursorPosStr := "";
+        Strings.Concat(requestCursorPosStr,ASCII.esc,requestCursorPosStr);
+        Strings.Concat(requestCursorPosStr,"[6n",requestCursorPosStr);
+    
+        cursorOnStr := "";
+        Strings.Concat(cursorOnStr,ASCII.esc,cursorOnStr);
+        Strings.Concat(cursorOnStr,"[?25h",cursorOnStr);
+        
+        cursorOffStr := "";
+        Strings.Concat(cursorOffStr,ASCII.esc,cursorOffStr);
+        Strings.Concat(cursorOffStr,"[?25l",cursorOffStr);
+        
+        tildeStr := "~";
+        cc[0] := CHR(13);
+        Strings.Concat(tildeStr,cc,tildeStr);
+        cc[0] := CHR(10);
+        Strings.Concat(tildeStr,cc,tildeStr);
+
+        eraseLineStr := "";
+        Strings.Concat(eraseLineStr,ASCII.esc,eraseLineStr);
+        Strings.Concat(eraseLineStr,"[K",eraseLineStr);
+
+    END InitScreenEscapes;
+
+    PROCEDURE InitEditor;
+
+    BEGIN
+        TCSAFLUSH := termios.tcsflush (); 
+        InitScreenEscapes;
+        getWindowSize(editorConfig.screenrows, editorConfig.screencols);
+        libc.write(FIO.StdOut,SYSTEM.ADR(clearScreenStr),4);
+        (* NumberIO.WriteCard(editorConfig.screencols,5);
+        NumberIO.WriteCard(editorConfig.screenrows,5);
+        Delay.Delay(2000) *)
+    END InitEditor;
+
+
+BEGIN
+    enablerawMode;
+    InitEditor;
+
+    LOOP
+        editorRefreshScreen;
+        editorProcessKeypress;
+        (* editorRefreshScreen; *)
+    END;
+    IF disablerawMode() = -1 THEN
+        HALT
+    END;    
+    NumberIO.WriteCard(editorConfig.screencols, 5);
+    NumberIO.WriteCard(editorConfig.screenrows, 5);
+END editor1.

BIN
step41/kilo


+ 143 - 0
step41/kilo.c

@@ -0,0 +1,143 @@
+/*** includes ***/
+#include <ctype.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+/*** defines ***/
+#define CTRL_KEY(k) ((k) & 0x1f)
+#define KILO_VERSION "0.0.1"
+
+/*** data ***/
+
+struct editorConfig {
+  int screenrows;
+  int screencols;
+  struct termios orig_termios;
+};
+struct editorConfig E;
+
+
+/*** terminal ***/
+void die(const char *s) {
+  write(STDOUT_FILENO, "\x1b[2J", 4);
+  write(STDOUT_FILENO, "\x1b[H", 3);
+  perror(s);
+  exit(1);
+}
+
+void disableRawMode() {
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &E.orig_termios) == -1)
+      die("tcsetattr");
+}
+
+void enableRawMode() {
+  if (tcgetattr(STDIN_FILENO, &E.orig_termios) == -1) die("tcgetattr");
+  atexit(disableRawMode);
+  struct termios raw = E.orig_termios;
+  raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+  raw.c_oflag &= ~(OPOST);
+  raw.c_cflag |= (CS8);
+  raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+  raw.c_cc[VMIN] = 0;
+  raw.c_cc[VTIME] = 1;
+  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) == -1) die("tcsetattr");
+}
+
+char editorReadKey() {
+  int nread;
+  char c;
+  while ((nread = read(STDIN_FILENO, &c, 1)) != 1) {
+    if (nread == -1 && errno != EAGAIN) die("read");
+  }
+  return c;
+}
+
+int getWindowSize(int *rows, int *cols) {
+  struct winsize ws;
+  if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) {
+    return -1;
+  } else {
+    *cols = ws.ws_col;
+    *rows = ws.ws_row;
+    return 0;
+  }
+}
+
+/*** append buffer ***/
+
+struct abuf {
+  char *b;
+  int len;
+};
+#define ABUF_INIT {NULL, 0}
+
+void abAppend(struct abuf *ab, const char *s, int len) {
+  char *new = realloc(ab->b, ab->len + len);
+  if (new == NULL) return;
+  memcpy(&new[ab->len], s, len);
+  ab->b = new;
+  ab->len += len;
+}
+void abFree(struct abuf *ab) {
+  free(ab->b);
+}
+
+/*** output ***/
+
+void editorDrawRows(struct abuf *ab) {
+  int y;
+  for (y = 0; y < E.screenrows; y++) {
+    if (y == E.screenrows / 3) {
+          char welcome[80];
+          int welcomelen = snprintf(welcome, sizeof(welcome),
+            "Kilo editor -- version %s", KILO_VERSION);
+          if (welcomelen > E.screencols) welcomelen = E.screencols;
+          abAppend(ab, welcome, welcomelen);
+        } else {
+          abAppend(ab, "~", 1);
+        }
+    abAppend(ab, "\x1b[K", 3);
+    if (y < E.screenrows - 1) {
+      abAppend(ab, "\r\n", 2);
+    }
+  }
+}
+void editorRefreshScreen() {
+  struct abuf ab = ABUF_INIT;
+  abAppend(&ab, "\x1b[?25l", 6);
+  abAppend(&ab, "\x1b[H", 3);
+  editorDrawRows(&ab);
+  abAppend(&ab, "\x1b[H", 3);
+  abAppend(&ab, "\x1b[?25h", 6);
+  write(STDOUT_FILENO, ab.b, ab.len);
+  abFree(&ab);
+}
+
+/*** input ***/
+void editorProcessKeypress() {
+  char c = editorReadKey();
+  switch (c) {
+    case CTRL_KEY('q'):
+      exit(0);
+      break;
+  }
+}
+/*** init ***/
+void initEditor() {
+  if (getWindowSize(&E.screenrows, &E.screencols) == -1) die("getWindowSize");
+}
+
+int main() {
+  enableRawMode();
+   initEditor();
+  while (1) {
+    editorRefreshScreen();
+    editorProcessKeypress();
+  }
+  return 0;
+}