-- MicroSample.mesa GMcD  December 3, 1980  3:04 PM

-- This module implents MicroSampleDefs.Mesa.  Basically, it provides a Mesa interface to the microcode Pc-sampling feature of the Dorado.  This module does not provide analysis facilities.

DIRECTORY
  BcplOps USING[ CleanupReason],
  ImageDefs USING[AddCleanupProcedure, CleanupItem, CleanupProcedure,
     RemoveCleanupProcedure],
--  InlineDefs USING[LongCOPY],
  MicroSampleDefs USING[setMicroPcSampling, sizeMicroPcData, tlprMicroPcData],
  SegmentDefs USING [DataSegmentHandle, DefaultXMBase, DeleteDataSegment,
     GetMemoryConfig, LongSegmentAddress, NewDataSegment],
  StreamDefs USING [Append, NewWordStream, StreamHandle, Write]
  ;
microsample: PROGRAM
  IMPORTS ImageDefs, --InlineDefs,-- ms: MicroSampleDefs,
    seg: SegmentDefs, strm: StreamDefs
  EXPORTS MicroSampleDefs =
BEGIN

lpHistData: PUBLIC ms.tlprMicroPcData← NIL;
dsh: seg.DataSegmentHandle;
cleanup: ImageDefs.CleanupItem;

notRunningOnDorado: PUBLIC SIGNAL=CODE;
noAllocatedMicroPcBuffer: PUBLIC SIGNAL=CODE;

startMicroSampling: PUBLIC PROCEDURE=
  BEGIN
  IF ~ onDorado[] THEN SIGNAL notRunningOnDorado;

  dsh← seg.NewDataSegment[seg.DefaultXMBase, (ms.sizeMicroPcData+255)/256];
  lpHistData← seg.LongSegmentAddress[dsh];
  longZero[lpHistData, ms.sizeMicroPcData];

  cleanup.proc← cleanupMicroPc;
  cleanup.mask← 177777B;
  ImageDefs.AddCleanupProcedure[@cleanup];

  ms.setMicroPcSampling[lpHistData];
  END;

saveMicroSamples: PUBLIC PROCEDURE=
  BEGIN
  saveMicroSamplesOnFile["MicroSamples.Counts"];
  END;

saveMicroSamplesOnFile: PUBLIC PROCEDURE[n: STRING]=
  BEGIN
  s: StreamDefs.StreamHandle;

  s← strm.NewWordStream[n, strm.Write+strm.Append];
  FOR i: CARDINAL IN [0..ms.sizeMicroPcData) DO
     s.put[s, LOOPHOLE[(lpHistData+i), LONG POINTER TO WORD]↑];
     ENDLOOP;
  s.destroy[s];
  END;

stopMicroSampling: PUBLIC PROCEDURE=
  BEGIN
  ms.setMicroPcSampling[NIL];
  ImageDefs.RemoveCleanupProcedure[@cleanup];
  IF dsh#NIL THEN { seg.DeleteDataSegment[dsh]; dsh← NIL; };
  lpHistData← NIL;
  END;

pauseMicroSampling: PUBLIC PROCEDURE=
  BEGIN
  IF ~ onDorado[] THEN SIGNAL notRunningOnDorado;
  ms.setMicroPcSampling[NIL];
  ImageDefs.RemoveCleanupProcedure[@cleanup]
  END;

resumeMicroSampling: PUBLIC PROCEDURE=
  BEGIN
  IF ~ onDorado[] THEN SIGNAL notRunningOnDorado;
  IF lpHistData#NIL
    THEN {ImageDefs.AddCleanupProcedure[@cleanup];
       ms.setMicroPcSampling[lpHistData]}
    ELSE SIGNAL noAllocatedMicroPcBuffer;
  END;

resetMicroPcData: PUBLIC PROCEDURE=
  BEGIN
  IF lpHistData=NIL THEN SIGNAL noAllocatedMicroPcBuffer
  ELSE longZero[lpHistData, ms.sizeMicroPcData];
  END;

onDorado: PUBLIC PROCEDURE RETURNS[BOOLEAN]=
  BEGIN
  RETURN [seg.GetMemoryConfig[].AltoType=Dorado];
  END;

longZero: PUBLIC PROCEDURE[lp: LONG POINTER, count: CARDINAL]=
  BEGIN
  IF lp=NIL THEN ERROR;
  lp↑←0;
  FOR i: CARDINAL IN [0..count] DO
     LOOPHOLE[lp+i, LONG POINTER]↑← 0;
     ENDLOOP;
--  InlineDefs.LongCOPY[from: lp, to: lp+1, nwords: count-1];
  END;

cleanupMicroPc: ImageDefs.CleanupProcedure=
  BEGIN
  SELECT why FROM
    InLd,Restart,Continue =>
       IF lpHistData#NIL
       THEN ms.setMicroPcSampling[lpHistData]
       ELSE SIGNAL noAllocatedMicroPcBuffer;
    ENDCASE=> ms.setMicroPcSampling[NIL];
  END;

END.