Procedure Putstr(Lin,Col:Integer; Atts:CRT_Attribute_set; Buffer:Packed array [lo..hi:integer] of char );external; {*USER* Pascal-3 procedure to display a string on a CRT at line Lin, column Col, with display attributes Attributes. Note that the attribute set has changed from the Pascal-2 version. If Save_cursor is in Atts, the cursor and CRT context are preserved across the field write. If not, the context is established by the PUTFLD parameters, and the cursor remains at the last character written. The Standard attribute overrides all other character attributes. Maximum input string length is about 80. bytes. The routine does not detect overflow, and may fail with excessive string lengths. Minimum input string length is 0 bytes. If Count=0, no text will be output, but the cursor position, attributes, and save will be done. If lin is negative, the entire screen will be erased prior to writing the field, which will appear at abs(lin). Column must be 00-132. lin must be 00-24. (or -24 for auto erase). If Col is negative, an erase to end-of-line sequence is generated at the end of the output, but before any restore sequence. The effect is to erase the remainder of the line specified by Lin. } Procedure Putstr; Var buff: packed array [1..150] of char; i:integer; {buffer index} j,top:integer; {temp index } ereol:boolean; {-------------- Put Numeric parameter to Buff ------------------------} Procedure PN(n:integer); {local} { will put out a numeric parameter with exactly the correct number of characters } Begin if n > 9 then PN(n div 10); buff[i] := chr(ord('0') + (N MOD 10)); i := i+1 end; {------------------- Put Escape sequence to Buff ----------------------} Procedure ESeq(str:packed array [lo..hi:integer] of char); { Local } { will append plus 'str' to buff. Only use type '1' strings. } Var j:integer; BEGIN buff[i] := chr(33B); for j := lo to hi do buff[i + j] := str[j]; i := i + hi + 1 END; {--------------- Put two character escape seq in Buff ----------------} Procedure Etwo(c:char); {local} BEGIN buff[i] := chr(33b); buff[i+1] := c; i := i+2 END; {------------------- Append string to Buff ---------------------------} Procedure APD(str:packed array [lo..hi:integer] of char); { local } Var j:integer; Begin for j := lo to hi do buff[i - 1 + j] := str[j]; i := i + hi END; {------------------- Put one char to Buff ----------------------------} Procedure ApdC(c:Char); { local } Begin Buff[i] := c; i := i + 1 end; {-------------------------- Putstr -----------------------------------} BEGIN buff[1] := chr(0); i := 2; { initialize buff index } if save_cursor in Atts then ETwo('7'); { process pre-erase and cursor position stuff } if lin < 0 then BEGIN lin := -lin; ESeq('[2J') END; lin := lin MOD 24; Etwo('['); {start cursor postition sequence } PN(lin); { dump line number } Apdc(';'); if col < 0 then BEGIN col := -col; ereol := true END else ereol := false; col := col MOD 132; pn(col); ApdC('H'); { process attributes } if Standard in Atts then Eseq('[m') else if [bold, underline, blink, reverse] * atts <> [] then BEGIN Etwo('['); { start of attribute sequence } if bold in atts then apd('1;'); if underline in atts then apd('4;'); if blink in atts then apd('5;'); if reverse in atts then apd('7;'); i := i-1; buff[i] := 'm' { overwrite last ';'} END; { process double high/wide stuff } if double_upper in atts then ESeq('#3') else if double_lower in atts then ESeq('#4'); if double_wide in atts then ESeq('#6'); { want a bell? } if ring_bell in atts then ApdC(chr(7)); { it is now time to copy the input to output buffer } if lo = 0 then top := ord(buffer[0]) else top := hi; for j := 1 to top do buff[i - 1 + j] := buffer[j]; i := i + top; { finish up with ereol and/or cursor restore } if ereol then ESeq('[K'); if save_cursor in atts then Etwo('8'); { at long last, write it out } i := i-1; { get length } writeln(buff:i) end;