{ GREGORY P. SMITH Here's a Unit I just pieced together from some old code I wrote a couple years ago. It'll generate AVT/0+ and ANSI codes: } Unit TermCode; {$S-,D-,L-,R-,F-,O-} { Generate ANSI and AVT/0+ codes For color and cursor ctrl } { Public Domain -- by Gregory P. Smith } { untested } Interface Type Str12 = String[12]; { Maximum size For most ANSI Strings } Str3 = String[3]; grTermType = (TTY, ANSI, AVT0); { TTY, ANSI or Avatar/0+ } Var grTerm : grTermType; grColor : Byte; { Last color set } { Non Specific Functions } Function grRepChar(c:Char;n:Byte): String; { Repeat Chars } Function grSetPos(x,y:Byte): Str12; { Set Cursor Position } Function grCLS: Str12; { Clear Screen + reset Attr } Function grDelEOL: Str12; { Delete to EOL } Function grSetAttr(a:Byte): Str12; { Change writing color } Function grSetColor(fg,bg:Byte): Str12; { Change color fg & bg } { AVT/0+ Specific Functions } Function AVTRepPat(pat:String;n:Byte): String; { Repeat Pattern (AVT/0+) } Function AVTScrollUp(n,x1,y1,x2,y2:Byte): Str12; Function AVTScrollDown(n,x1,y1,x2,y2:Byte): Str12; Function AVTClearArea(a,l,c:Byte): Str12; Function AVTInitArea(ch:Char;a,l,c:Byte): Str12; Implementation Const hdr = #27'['; { ansi header } { Misc support Functions } Function bts(x:Byte): str3; { Byte to String } Var z: str3; begin Str(x,z); bts := z; end; Function Repl(n:Byte; c:Char): String; Var z : String; begin fillChar(z[1],n,c); z[0] := chr(n); repl := z; end; { Cursor Control Functions } Function grRepChar(c:Char;n:Byte): String; begin if grTerm = AVT0 then grRepChar := ^Y+c+chr(n) else grRepChar := repl(n,c); end; { repcahr } Function grSetPos(x,y:Byte): Str12; begin Case grTerm of ANSI : if (x = 1) and (y > 1) then grSetPos := hdr+bts(y)+'H' { x defualts to 1 } else grSetPos := hdr+bts(y)+';'+bts(x)+'H'; AVT0 : grSetPos := ^V+^H+chr(y)+chr(x); TTY : grSetPos := ''; end; { Case } end; Function grCLS: Str12; begin Case grTerm of ANSI : grCLS := hdr+'2J'; TTY, AVT0 : grCLS := ^L; end; if grTerm = AVT0 then GrColor := 3; { reset the color } end; { cls } Function grDelEOL: Str12; { clear rest of line } begin Case grTerm of ANSI : grDelEOL := hdr+'K'; AVT0 : grDelEOL := ^V^G; TTY : grDelEOL := ''; end; end; { Color Functions } Function grSetAttr(a:Byte): Str12; Const ANS_Colors : Array[0..7] of Char = ('0','4','2','6','1','5','3','7'); Var tmp : Str12; begin tmp := ''; Case grTerm of ANSI : begin tmp := hdr; if (a and $08)=8 then tmp := tmp+'1' else tmp := tmp+'0'; { bright } if (a and $80)=$80 then tmp := tmp+';5'; { blink } tmp := tmp+';3'+ANS_Colors[a and $07]; { foreground } tmp := tmp+';4'+ANS_Colors[(a shr 4) and $07]; { background } grSetAttr := tmp+'m'; { complete ANSI code } end; AVT0 : begin tmp := ^V+^A+chr(a and $7f); if a > 127 then tmp := tmp+^V+^B; { Blink } grSetAttr := tmp; end; TTY : grSetAttr := ''; end; { Case } GrColor := a; { Current Attribute } end; { setattr } Function grSetColor(fg,bg:Byte): Str12; begin grSetColor := grSetAttr((bg shl 4) or (fg and $0f)); end; { SetColor } { AVATAR Specific Functions: } Function AVTRepPat(pat:String;n:Byte): String; { Repeat Pattern (AVT/0+) } begin AVTRepPat := ^V+^Y+pat[0]+pat+chr(n); { Repeat pat n times } end; Function AVTScrollUp(n,x1,y1,x2,y2:Byte): Str12; begin AVTScrollUp := ^V+^J+chr(n)+chr(y1)+chr(x1)+chr(y2)+chr(x2); end; { AVTScrollUp } Function AVTScrollDown(n,x1,y1,x2,y2:Byte): Str12; begin AVTScrollDown := ^V+^K+chr(n)+chr(y1)+chr(x1)+chr(y2)+chr(x2); end; { AVTScrollDown } Function AVTClearArea(a,l,c:Byte): Str12; Var b:Byte; s:Str12; begin { Clear lines,columns from cursor pos With Attr } b := a and $7f; s := ^V+^L+chr(b)+chr(l)+chr(c); if a > 127 then Insert(^V+^B,s,1); { blink on } AVTClearArea := s; GrColor := a; end; { AVTClearArea } Function AVTInitArea(ch:Char;a,l,c:Byte): Str12; Var b:Byte; s:Str12; begin b := a and $7f; s := ^V+^M+chr(b)+ch+chr(l)+chr(c); if a > 127 then Insert(^V+^B,s,1); AvtInitArea := s; GrColor := a; end; { AVTInitArea } { Initalization code } begin GrTerm := AVT0; { Default to Avatar } GrColor := 3; { Cyan is the AVT/0+ defualt } end. { set GrTerm to whatever terminal codes you want to create; then you can use the common routines to generate ANSI or Avatar codes. Here's a Print Procedure that you were mentioning: } Procedure Print(Var msg:String); Var idx : Byte begin if length(msg) > 0 then For idx := 1 to length(msg) do begin Parse_AVT1(msg[idx]); SendOutComPortThingy(msg[idx]); end; { For } end; { You could modify this so that it pays attention to the TextAttr Variable of the Crt Unit if you wish so that it compares TextAttr to GrColor and adds a SetAttr(TextAttr) command in before it sends msg. }