-- PilotCommUtil.mesa (last edited by: BLyon on: February 10, 1981  11:53 AM)
-- Function: The implementation module for Pilot provided utilities.

DIRECTORY
  CommunicationInternal USING [],
  CommUtilDefs USING [],
  DriverDefs USING [],
  Environment USING [wordsPerPage],
  Inline USING [COPY, LongCOPY, LowHalf],
  Process USING [MsecToTicks, SecondsToTicks, Ticks],
  PupDefs USING [], --EXPORTS Time Conversion stuff
  PupStream USING [Tocks], --EXPORTS Time Conversion stuff
  ResidentHeap USING [MakeNode, FreeNode, first64K],
  Runtime USING [CallDebugger],
  Space USING [
    Handle, Create, defaultBase, defaultWindow, GetHandle,
    PageFromLongPointer, Map, Unmap, Delete, virtualMemory,
    LongPointer],
  SpecialSpace USING [MakeSwappable, MakeResident],
  Zone USING [Status, BlockSize, Base];

PilotCommUtil: PROGRAM
  IMPORTS Inline, Process, ResidentHeap, Runtime, Space, SpecialSpace
  EXPORTS CommunicationInternal, CommUtilDefs, DriverDefs, PupDefs, PupStream =
  BEGIN


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

  -- IOCB allocation.
  AllocateIocbs: PUBLIC PROC [nwords: CARDINAL] RETURNS [LONG POINTER] =
    BEGIN
    status: Zone.Status;
    p: Zone.Base RELATIVE POINTER;
    [p, status] ← ResidentHeap.MakeNode[LOOPHOLE[nwords, Zone.BlockSize], a4];
    IF status # okay THEN Glitch[ResidentZoneTrouble];
    RETURN[@ResidentHeap.first64K[p]]; -- make into a LONG absolute

    END;

  FreeIocbs: PUBLIC PROC [iocbPtr: LONG POINTER] =
    BEGIN
    p: Zone.Base RELATIVE POINTER ← Inline.LowHalf[
      iocbPtr - LOOPHOLE[ResidentHeap.first64K, LONG POINTER]];
    [] ← ResidentHeap.FreeNode[p];
    END;

  -- Clumps of pages

  AllocateBuffers: PUBLIC PROC [nwords: CARDINAL] RETURNS [base: LONG POINTER] =
    BEGIN
    pages: CARDINAL =
      (nwords + Environment.wordsPerPage - 1)/Environment.wordsPerPage;
    h: Space.Handle = Space.Create[pages, Space.virtualMemory, Space.defaultBase];
    Space.Map[h, Space.defaultWindow];
    base ← Space.LongPointer[h];
    END;

  FreeBuffers: PUBLIC PROC [base: LONG POINTER] =
    BEGIN
    h: Space.Handle = Space.GetHandle[Space.PageFromLongPointer[base]];
    Space.Unmap[h];
    Space.Delete[h];
    END;

  LockBuffers: PUBLIC PROC [p: LONG POINTER] =
    BEGIN
    SpecialSpace.MakeResident[Space.GetHandle[Space.PageFromLongPointer[p]]];
    END;

  UnlockBuffers: PUBLIC PROC [p: LONG POINTER] =
    BEGIN
    SpecialSpace.MakeSwappable[Space.GetHandle[Space.PageFromLongPointer[p]]];
    END;


  -- Other goodies

  Zero: PUBLIC PROC [p: POINTER, l: CARDINAL] =
    BEGIN
    IF l = 0 THEN RETURN;
    p↑ ← 0;
    Inline.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 PROC [t: CARDINAL] RETURNS [PupStream.Tocks] =
    BEGIN
    tks: Process.Ticks = Process.SecondsToTicks[t];
    IF tks = LAST[Process.Ticks] THEN ERROR TockConversionTroubles;
    RETURN[LOOPHOLE[tks]];
    END;

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

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

  -- Communication error handler

  errorHandler: PROC [ERROR] ← DefaultErrorHandler;

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

  DefaultErrorHandler: PROC [why: ERROR] =
    BEGIN Runtime.CallDebugger["CommunicationGlitch"L]; Glitch[why]; END;

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

  FriendOfCopyLong: PUBLIC PROC [from: LONG POINTER, nwords: CARDINAL, to: LONG POINTER] =
    {Inline.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*.