-- Copyright (C) 1983  by Xerox Corporation. All rights reserved. 
-- TestEikonix.mesa, HGM, 30-Jul-83 17:11:57

DIRECTORY
  FormSW USING [
    AllocateItemDescriptor, ClientItemsProcType, CommandItem, newLine, ProcType, StringItem],
  Inline USING [BITAND],
  Process USING [Pause],
  Put USING [CR, Line, LongDecimal, Number, Text],
  Runtime USING [GetBcdTime],
  String USING [AppendString],
  System USING [GetClockPulses, Microseconds, Pulses, PulsesToMicroseconds],
  Time USING [Append, Unpack],
  Tool USING [Create, MakeSWsProc, MakeFormSW, MakeFileSW, UnusedLogName],
  ToolWindow USING [TransitionProcType],
  Window USING [Handle],

  MesaRPC USING [ImportFailed],
  Multibus USING [IOAddress, Page, RawRead, RawReadPage, RawWrite, wordsPerPage],
  MultibusRpcControl USING [ImportInterface, UnimportInterface];

TestEikonix: PROGRAM
  IMPORTS
    FormSW, Inline, Process, Put, Runtime, String, System, Time, Tool,
    MesaRPC, Multibus, MultibusRpcControl =
  BEGIN

  target: LONG STRING ← NIL;
  connected: BOOLEAN ← FALSE;

  Connect: FormSW.ProcType =
    BEGIN
    start, end: System.Pulses;
    cycles: LONG CARDINAL ← 0;
    ms: LONG CARDINAL;
    noBind: BOOLEAN ← FALSE;
    IF connected THEN
      BEGIN
      connected ← FALSE;
      MultibusRpcControl.UnimportInterface[];
      END;
    start ← System.GetClockPulses[];
    MultibusRpcControl.ImportInterface[[NIL, target] !
      MesaRPC.ImportFailed =>
        BEGIN
	noBind ← TRUE;
	Put.Text[log, "Import from "L];
	Put.Text[log, target];
	Put.Text[log, " failed: "L];
	SELECT why FROM
	  communications => Put.Text[log, "communications"L];
	  badInstance => Put.Text[log, "badInstance"L];
	  badVersion => Put.Text[log, "badVersion"L];
	  wrongVersion => Put.Text[log, "wrongVersion"L];
	  unbound => Put.Text[log, "unbound"L];
	  stubProtocol => Put.Text[log, "stubProtocol"L];
	  ENDCASE => Put.Text[log, "??"L];
	Put.Line[log, "."L];
	CONTINUE;
	END];
    IF noBind THEN RETURN;
    connected ← TRUE;
    end ← System.GetClockPulses[];
    ms ← System.PulsesToMicroseconds[[end-start]]/1000;
    Put.Text[log, "It took "L];
    Put.LongDecimal[log, ms];
    Put.Line[log, " ms to Import Multibus."L];
    Put.CR[log];
    END;

  deviceCommandLoc: Multibus.IOAddress = LOOPHOLE[407001H];
  statusLoc: Multibus.IOAddress = LOOPHOLE[407002H];
  deviceStatusLoc: Multibus.IOAddress = LOOPHOLE[407003H];
  functionControlLoc: Multibus.IOAddress = LOOPHOLE[407007H];
  dataBuffer0: Multibus.IOAddress = LOOPHOLE[405000H];
  
  Status: FormSW.ProcType =
    BEGIN
    status: WORD;
    IF ~connected THEN
      BEGIN
      Put.Line[log, "Not Connected."L];
      RETURN;
      END;
    status ← Multibus.RawRead[statusLoc];
    Put.Text[log, "Status = "L];
    Put.Number[log, status, [16, FALSE, TRUE, 0]];
    Put.Line[log, "."L];
    Put.CR[log];
    END;

  Home: FormSW.ProcType =
    BEGIN
    IF ~connected THEN
      BEGIN
      Put.Line[log, "Not Connected."L];
      RETURN;
      END;
    Multibus.RawWrite[20A0H, deviceCommandLoc];
    Put.CR[log];
    END;

  Full: FormSW.ProcType =
    BEGIN
    IF ~connected THEN
      BEGIN
      Put.Line[log, "Not Connected."L];
      RETURN;
      END;
    Multibus.RawWrite[10A0H, deviceCommandLoc];
    Put.CR[log];
    END;

  StepIn: FormSW.ProcType =
    BEGIN
    IF ~connected THEN
      BEGIN
      Put.Line[log, "Not Connected."L];
      RETURN;
      END;
    Multibus.RawWrite[08A0H, deviceCommandLoc];
    Put.CR[log];
    END;

  StepOut: FormSW.ProcType =
    BEGIN
    IF ~connected THEN
      BEGIN
      Put.Line[log, "Not Connected."L];
      RETURN;
      END;
    Multibus.RawWrite[04A0H, deviceCommandLoc];
    Put.CR[log];
    END;

  MoveIn: FormSW.ProcType =
    BEGIN
    IF ~connected THEN
      BEGIN
      Put.Line[log, "Not Connected."L];
      RETURN;
      END;
    FOR i: CARDINAL IN [0..50) DO
      Multibus.RawWrite[08A0H, deviceCommandLoc];
      WaitUntilFinished[];
      ENDLOOP;
    Put.CR[log];
    END;

  MoveOut: FormSW.ProcType =
    BEGIN
    IF ~connected THEN
      BEGIN
      Put.Line[log, "Not Connected."L];
      RETURN;
      END;
    FOR i: CARDINAL IN [0..20) DO
      Multibus.RawWrite[04A0H, deviceCommandLoc];
      WaitUntilFinished[];
      ENDLOOP;
    Put.CR[log];
    END;

  ShowScanLine: FormSW.ProcType =
    BEGIN
    page: Multibus.Page;
    fcr: WORD;
    IF ~connected THEN
      BEGIN
      Put.Line[log, "Not Connected."L];
      RETURN;
      END;
    Put.Text[log, "Scanning a line..."L];
    Multibus.RawWrite[80A0H, deviceCommandLoc];  -- Step out after scan
    WaitUntilFinished[];
    Multibus.RawWrite[0501H, functionControlLoc];
    fcr ← Multibus.RawRead[functionControlLoc];
    Put.Number[log, fcr, [16, FALSE, TRUE, 5]];
    WaitUntilFinished[];
    page ← Multibus.RawReadPage[dataBuffer0+1000];
    FOR i: CARDINAL IN [0..Multibus.wordsPerPage) DO
      IF i MOD 8 = 0 THEN Put.CR[log];
      Put.Number[log, page[i], [16, FALSE, TRUE, 5]];
      ENDLOOP;
    Put.CR[log];
    END;

  WaitUntilFinished: PROCEDURE =
    BEGIN
    FOR j: CARDINAL IN [0..100) DO
      status: WORD;
      IF FALSE THEN Process.Pause[2];
      status ← Multibus.RawRead[statusLoc];
      IF Inline.BITAND[status, 80H] = 0 THEN  -- Busy bit
        BEGIN
        EXIT;
        END;
      REPEAT FINISHED => Put.Line[log, ".  !!!!"L];
      ENDLOOP;
    END;

  form, log: PUBLIC Window.Handle ← NIL;

  Init: PROCEDURE =
    BEGIN
    herald: STRING = [100];
    String.AppendString[herald, "TestEikonix of  "L];
    Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]];
    [] ← Tool.Create[
      name: herald, makeSWsProc: MakeSWs,
      clientTransition: ClientTransition];
    END;

  MakeSWs: Tool.MakeSWsProc =
    BEGIN
    logFileName: STRING = [40];
    Tool.UnusedLogName[logFileName, "TestEikonix.log$"L];
    form ← Tool.MakeFormSW[window: window, formProc: MakeForm];
    log ← Tool.MakeFileSW[window: window, name: logFileName];
    END;

  MakeForm: FormSW.ClientItemsProcType =
    BEGIN
    nParams: CARDINAL = 10;
    items ← FormSW.AllocateItemDescriptor[nParams];
    items[0] ← FormSW.CommandItem[tag: "Connect"L, proc: Connect, place: FormSW.newLine];
    items[1] ← FormSW.CommandItem[tag: "Status"L, proc: Status];
    items[2] ← FormSW.CommandItem[tag: "Home"L, proc: Home];
    items[3] ← FormSW.CommandItem[tag: "Full"L, proc: Full];
    items[4] ← FormSW.StringItem[tag: "Target"L, string: @target, inHeap: TRUE];
    items[5] ← FormSW.CommandItem[tag: "StepIn"L, proc: StepIn, place: FormSW.newLine];
    items[6] ← FormSW.CommandItem[tag: "StepOut"L, proc: StepOut];
    items[7] ← FormSW.CommandItem[tag: "MoveIn"L, proc: MoveIn, place: FormSW.newLine];
    items[8] ← FormSW.CommandItem[tag: "MoveOut"L, proc: MoveOut];
    items[9] ← FormSW.CommandItem[tag: "ShowScanLine"L, proc: ShowScanLine];
    RETURN[items, TRUE];
    END;

  ClientTransition: ToolWindow.TransitionProcType =
    BEGIN IF new = inactive THEN form ← log ← NIL; END;

  Init[];

  END.