-- PilotCommUtil.mesa (last edited by: BLyon on: February 10, 1981  11:53 AM)
-- Function: The implementation module for Pilot provided utilities.
-- Last Edited by: Levin, August 9, 1983 9:19 am

DIRECTORY
  CommunicationInternal USING [],
  CommUtilDefs USING [],
  DriverDefs USING [],
  PrincOpsUtils USING [COPY, LongCOPY],
  Process USING [MsecToTicks, SecondsToTicks, Ticks],
  PupDefs USING [], --EXPORTS Time Conversion stuff
  PupStream USING [Tocks], --EXPORTS Time Conversion stuff
  VM USING [
    AddressForPageNumber, Allocate, Free, Interval, lowCore, PageNumberForAddress,
    PagesForWords, Pin];

PilotCommUtil: MONITOR
  IMPORTS PrincOpsUtils, Process, VM
  EXPORTS CommunicationInternal, CommUtilDefs, DriverDefs, PupDefs, PupStream =
  BEGIN


  -- Heap nodes.  All these are currently resident, and in first 64K
  MixedIocbSize: ERROR = CODE;

  -- IOCB allocation.
  
  iocbSize: CARDINAL ← 0;
  IocbType: TYPE = RECORD[next: LONG POINTER TO IocbType,
    rest: SEQUENCE COMPUTED CARDINAL OF WORD];
  freeIocb: LONG POINTER TO IocbType ← NIL;
  
  AllocateIocb: PUBLIC ENTRY PROC [nwords: CARDINAL] RETURNS [i: LONG POINTER] =
    BEGIN
    IF iocbSize = 0 THEN iocbSize ← nwords;
    IF iocbSize # nwords THEN Glitch[MixedIocbSize];
    IF freeIocb # NIL
    THEN { i ← freeIocb; freeIocb ← freeIocb.next }
    ELSE i ← VM.lowCore.NEW[IocbType[iocbSize-SIZE[IocbType[0]]]];
    END;

  FreeIocb: PUBLIC ENTRY PROC [iocbPtr: LONG POINTER] =
    BEGIN
    i: LONG POINTER TO IocbType = LOOPHOLE[iocbPtr];
    i.next ← freeIocb; freeIocb ← i;
    END;

  -- Clumps of pages

  AllocateBuffers: PUBLIC PROC [nwords: CARDINAL] RETURNS [base: LONG POINTER] =
    BEGIN
    interval: VM.Interval = VM.Allocate[VM.PagesForWords[nwords]];
    VM.Pin[interval];
    base ← VM.AddressForPageNumber[interval.page];
    END;

  FreeBuffers: PUBLIC PROC [base: LONG POINTER, nwords: CARDINAL] =
    BEGIN
    VM.Free[[page: VM.PageNumberForAddress[base], count: VM.PagesForWords[nwords]]];
    END;


  -- Other goodies

  Zero: PUBLIC PROC [p: POINTER, l: CARDINAL] =
    BEGIN
    IF l = 0 THEN RETURN;
    p↑ ← 0;
    PrincOpsUtils.COPY[from: p, to: p + 1, nwords: l - 1];
    END;

  -- TimeCoversion for Pup package
  -- implement with Process.Tick = Tock
  -- Code depends upon Process.MsecToTicks corectly
  -- rounding up the argument before caculating the result,
  -- and SecondsToTicks returning LAST[Ticks] for large seconds.

  TockConversionTroubles: PUBLIC ERROR = CODE;

  SecondsToTocks: PUBLIC SAFE PROC [t: CARDINAL] RETURNS [PupStream.Tocks] =
    CHECKED BEGIN
    tks: Process.Ticks = Process.SecondsToTicks[t];
    IF tks = LAST[Process.Ticks] THEN ERROR TockConversionTroubles;
    RETURN[[tks]];
    END;

  -- this assumes that a tock is longer than an millisecond

  MsToTocks: PUBLIC SAFE PROC [t: CARDINAL] RETURNS [PupStream.Tocks] =
    CHECKED BEGIN
    IF t = 0 THEN ERROR TockConversionTroubles;
    RETURN[[Process.MsecToTicks[t]]];
    END;

  -- Communication error handler

  errorHandler: PROC [ERROR] ← DefaultErrorHandler;

  CaptureErrors: PUBLIC PROC [proc: PROC [ERROR]] = {errorHandler ← proc};

  DefaultErrorHandler: PROC [why: ERROR] =
    BEGIN SIGNAL LOOPHOLE[why, SIGNAL] END;

  Glitch: PUBLIC PROC [why: ERROR] = {DO errorHandler[why] ENDLOOP};

  FriendOfCopyLong: PUBLIC PROC [from: LONG POINTER, nwords: CARDINAL, to: LONG POINTER] =
    {PrincOpsUtils.LongCOPY[from, nwords, to]};

  END....  -- PilotCommUtil module

LOG

Time: June 18, 1979  2:13 PM  By: Dalal  Action: conversion to Pilot 3.0.
Time: August 25, 1979  1:40 PM  By: Dalal  Action: made msPerTick a constant.
Time: August 31, 1979  12:34 PM  By: Dalal  Action: deleted AllocateHeapNode.
Time: August 11, 1980  4:53 PM  By: BLyon  Action: deleted ByteBlt*.