procedure Get_InStr (X,Y : integer; Prompt : Str80; Max_Len : integer);
const
  editset: charset = [BS, RUB, CAN, TAB];
  termset: charset = [LF, CR, SUB];
  dispset: charset = [' '..'~'];
var
  Ch          : char;
  CurX, Len   : integer;
begin
  CurX := X + length(Prompt);
  if Max_Len > 80 - length(Prompt) then Max_Len := 80 - length(Prompt);
  InStr := ''; Len := 0; GotoXY(X,Y); LowVideo; Write(Prompt);
  Write(copy(Mask,1,Max_Len)); Cursor_On; NormVideo; GotoXY(CurX,Y);
  repeat
    read(Kbd, Ch);
    if Ch = ESC then
      begin
        InStr := ESC;
        write(copy(Spaces,1,Max_Len - Len));
        Exit
      end
    else if (Ch in dispset) and (Len < Max_Len)
      then
        begin
          InStr := InStr + Ch;
          write(Ch)
        end
    else if ch = TAB
      then
        repeat
          InStr := InStr + ' ';
          write(' ')
        until (0 = length(InStr) mod 8) or (length(InStr) >= Max_Len)
    else if ((Ch = RUB) or (Ch = BS)) and (Len > 0)
      then
        begin
          delete(InStr, Len, 1); LowVideo;
          write(BS, copy(Mask,1,1), BS); NormVideo
        end
    else if ch = CAN
      then
        begin
          InStr := '';
          GotoXY(CurX,Y); LowVideo;
          write(copy(Mask,1,Max_Len)); NormVideo;
          GotoXY(CurX,Y)
        end;
    Len := length(InStr)
  until (Ch in termset);
  write(copy(Spaces,1,Max_Len - Len))
end;
