[inherit ('SYS$LIBRARY:STARLET')] Module PDPSubs(Output, Terminal); const NUL = chr(0); LF = chr(10); CR = chr(13); ControlU = chr(21); MaxStrings = 20; StringMax = 40; NoAnswer = 0; type Word = [WORD] -32768 .. 32767; StringSet = set of 1..MaxStrings; String = packed array [1..StringMax] of char; var Terminal: text; ProgramName: packed array [1..8] of char; DSW: Word; Channel: Word; Status: [QUAD] record Stat: Word; Count: Word; Junk: integer; end; Strings: array [1..MaxStrings] of record Str: String; Len: 0..StringMax; Pos: integer; end; NumStrings: 0..MaxStrings; Line: packed array [1..80] of char; Start, Len: integer; Term: char; TimeOut: boolean; I: integer; [INITIALIZE] procedure Init; begin open(Terminal, File_Name := 'TERM$PDP11', Carriage_Control := NONE); rewrite(Terminal); DSW := $Assign (DevNam := 'TERM$PDP11', Chan := Channel); if DSW <> SS$_Normal then writeln(output, 'Assign Error -- DSW = ', DSW:1); end { InitTimed }; procedure TimedRead(MaxTime: integer; var Line: packed array [LMin..LMax: integer] of char; var LineLength: integer; var Terminator: char; var TimeOut: boolean); var LineSize: integer; begin LineSize := LMax - LMin; DSW := $QIOW (EFN := 1, Chan := Channel, Func := IO$_ReadVBlk + IO$M_NoEcho + IO$M_Timed, IOSB := Status, P1 := Line, P2 := LineSize, P3 := MaxTime); if DSW <> SS$_Normal then begin writeln(Output, ProgramName, ' -- Read directive error, DSW = ', DSW:1); halt; end else with Status do if Stat = SS$_Normal then begin TimeOut := false; LineLength := Count; if Count = LineSize then Terminator := NUL else Terminator := Line[Count + 1]; end else if Stat = SS$_TimeOut then begin TimeOut := true; LineLength := Count; Terminator := NUL; end else begin writeln(Output, ProgramName, ' -- Read error, DSW = ', DSW:1); halt; end; end { TimedRead }; procedure PutString(Str: packed array [Min..Max: integer] of char; Len: integer; Flush, ShowOutput, EOL: boolean); var Last, I: integer; begin if Flush then writeln(Terminal, ControlU); if Len < 0 then Last := Max else Last := Min + Len - 1; if ShowOutput then for I := Min to Last do write(output, Str[I]); if EOL then writeln(output); for I := Min to Last do write(Terminal, Str[I]); if EOL then write(Terminal, CR); writeln(Terminal); end { PutString }; procedure EnterString(Index, Position: integer; String: packed array [Min..Max: integer] of char); var I: integer; begin with Strings[Index] do if Position < 0 then begin Pos := - Position; Len := 1; Str[1] := String[Min]; end else begin Pos := Position; Len := 0; for I := Min to Max do begin Len := Len + 1; Str[Len] := String[I]; end; end; end { EnterString }; function WaitFor(SSet: StringSet; MaxTime: integer): integer; var S: integer; Found: boolean; function Equal(Line: packed array [LMin..LMax: integer] of char; Strng: packed array [SMin..SMax: integer] of char; Start, Len: integer): boolean; var Last, L, S: integer; begin Last := Start + Len - 1; if Last > LMax then Equal := false else begin L := Start; S := SMin; while (Line[L] = Strng[S]) and (S < Len) do begin L := L + 1; S := S + 1; end; Equal := Line[L] = Strng[S]; end; end { Equal }; begin { WaitFor } repeat TimedRead(MaxTime, Line, Len, Term, TimeOut); if Line[1] = LF then Start := 2 else Start := 1; for I := Start to Len do write(output, Line[I]); if Term <> NUL then writeln(output); S := 0; repeat S := S + 1; if S in SSet then with Strings[S] do Found := Equal(Line, Str, Start + Pos - 1, Len) else Found := false; until Found or (S = NumStrings); until Found or TimeOut; if Found then WaitFor := S else WaitFor := NoAnswer; end { WaitFor }; end { PDPSubs }.