-- Segments.mesa  Edited by Sandman on October 2, 1980  9:04 AM

DIRECTORY
  AltoDefs USING [PageCount, PageNumber],
  AltoFileDefs USING [FP, NullFP],
  DirectoryDefs USING [EnumerateDirectory],
  InlineDefs USING [LongDivMod, LongMult],
  SegmentDefs USING [
    AllocInfo, AccessOptions, DefaultAccess, DefaultANYBase, DefaultBase,
    DefaultMDSBase, DefaultVersion, DefaultXMBase, DeleteFileSegment, DestroyFile, EasyDown,
    EasyUp, EnumerateFiles, EnumerateFileSegments, FileError, FileHandle,
    FileNameError, FileSegmentHandle, GetEndOfFile, GetFileTimes, HardDown, HardUp, InsertFile,
    InsufficientVM, InvalidFP, LockFile, MakeSwappedIn, MoveFileSegment, NewFile,
    NewFileSegment, NewFileOnly, OldFileOnly, Read, ReadWrite, ReadWriteAppend,
    ReleaseFile, SegmentAddress, SetEndOfFile, SetFileTimes, SwapError, SwapOut,
    SwapUp, Unlock, UnlockFile, VersionOptions, VMtoFileSegment, WriteAppend],
  Time USING [Packed];


Segments: DEFINITIONS IMPORTS DirectoryDefs, InlineDefs, SegmentDefs =
  BEGIN

  Address: TYPE = POINTER;

  FP: TYPE = AltoFileDefs.FP;

  FPHandle: TYPE = POINTER TO FP;

  FHandle: TYPE = PRIVATE SegmentDefs.FileHandle;

  SHandle: TYPE = PRIVATE SegmentDefs.FileSegmentHandle;

  -- Assert: The word POINTER does not appear below here.

  PageCount: TYPE = AltoDefs.PageCount;
  PageNumber: TYPE = AltoDefs.PageNumber;

  NullFP: FP = AltoFileDefs.NullFP;

  -- S E G M E N T S

  AllocInfo: TYPE = PRIVATE SegmentDefs.AllocInfo;
  EasyUp: AllocInfo = SegmentDefs.EasyUp;
  EasyDown: AllocInfo = SegmentDefs.EasyDown;
  HardUp: AllocInfo = SegmentDefs.HardUp;
  HardDown: AllocInfo = SegmentDefs.HardDown;

  DefaultBase: PageNumber = SegmentDefs.DefaultBase;
  DefaultMDSBase: PageNumber = SegmentDefs.DefaultMDSBase;
  DefaultXMBase: PageNumber = SegmentDefs.DefaultXMBase;
  DefaultANYBase: PageNumber = SegmentDefs.DefaultANYBase;

  SwapProblem: PROC RETURNS [SIGNAL [seg: SHandle]] = INLINE {
    RETURN[SegmentDefs.SwapError]};

  OutOfMemory: PROC RETURNS [SIGNAL [x: CARDINAL]] = INLINE {
    RETURN[LOOPHOLE[SegmentDefs.InsufficientVM]]};

  DeleteSegment: PROCEDURE [seg: SHandle] = INLINE {
    SegmentDefs.DeleteFileSegment[seg]};

  EnumerateSegments: PROCEDURE [proc: PROCEDURE [SHandle] RETURNS [BOOLEAN]]
    RETURNS [SHandle] = INLINE {RETURN[SegmentDefs.EnumerateFileSegments[proc]]};

  FlushSegmentCache: PROCEDURE;
  Kill: PROCEDURE [seg: SHandle, base: PageNumber ← DefaultBase];
  MakeReadOnly: PROCEDURE [seg: SHandle];
  MoveSegment: PROCEDURE [seg: SHandle, base: PageNumber, pages: PageCount] =
    INLINE {SegmentDefs.MoveFileSegment[seg, base, pages]};

  NewSegment: PROCEDURE [
    file: FHandle, base: PageNumber, pages: PageCount,
    access: Access ← DefaultAccess] RETURNS [SHandle] = INLINE {
    RETURN[SegmentDefs.NewFileSegment[file, base, pages, access]]};

  SegmentAddress: PROCEDURE [seg: SHandle] RETURNS [Address] = INLINE {
    RETURN[SegmentDefs.SegmentAddress[seg]]};

  SwapIn: PROCEDURE [
    seg: SHandle, base: PageNumber ← DefaultBase, info: AllocInfo ← EasyUp] =
    INLINE {SegmentDefs.MakeSwappedIn[seg, base, info]};

  SwapOut: PROCEDURE [seg: SHandle] = INLINE {SegmentDefs.SwapOut[seg]};

  SwapUp: PROCEDURE [seg: SHandle] = INLINE {SegmentDefs.SwapUp[seg]};

  Unlock: PROCEDURE [seg: SHandle] = INLINE {SegmentDefs.Unlock[seg]};

  VMtoSegment: PROCEDURE [a: Address] RETURNS [SHandle] = INLINE {
    RETURN[SegmentDefs.VMtoFileSegment[a]]};

  FileFromSegment: PROC [seg: SHandle] RETURNS [FHandle] = INLINE {
    RETURN[seg.file]};

  BaseFromSegment: PROC [seg: SHandle] RETURNS [PageNumber] = INLINE {
    RETURN[seg.base]};

  IsSwappedIn: PROC [seg: SHandle] RETURNS [BOOLEAN] = INLINE {
    RETURN[seg.swappedin]};

  PagesFromSegment: PROC [seg: SHandle] RETURNS [PageCount] = INLINE {
    RETURN[seg.pages]};

  LockFromSegment: PROC [seg: SHandle] RETURNS [CARDINAL] = INLINE {
    RETURN[seg.lock]};

  UpdateUsageHint: PROC [seg: SHandle] = INLINE {seg.inuse ← TRUE};

  -- F I L E S: 

  VersionOptions: TYPE = PRIVATE SegmentDefs.VersionOptions;
  DefaultVersion: VersionOptions = SegmentDefs.DefaultVersion;
  NewFileOnly: VersionOptions = SegmentDefs.NewFileOnly;
  OldFileOnly: VersionOptions = SegmentDefs.OldFileOnly;

  Access: TYPE = PRIVATE SegmentDefs.AccessOptions;
  AllAccess: Access = SegmentDefs.ReadWriteAppend;
  DefaultAccess: Access = SegmentDefs.DefaultAccess;
  Read: Access = SegmentDefs.Read;
  ReadWrite: Access = SegmentDefs.ReadWrite;
  Write: Access = SegmentDefs.WriteAppend;

  FileNameProblem: PROCEDURE RETURNS [SIGNAL [name: STRING]] = INLINE {
    RETURN[SegmentDefs.FileNameError]};

  FileProblem: PROCEDURE RETURNS [SIGNAL [f: FHandle]] = INLINE {
    RETURN[SegmentDefs.FileError]};

  FileUnknown: PROCEDURE RETURNS [SIGNAL] = INLINE {
    RETURN[LOOPHOLE[SegmentDefs.InvalidFP]]};

  DestroyFile: PROCEDURE [file: FHandle] = INLINE
    {SegmentDefs.DestroyFile[file]};

  EnumerateFiles: PROCEDURE [proc: PROCEDURE [FHandle] RETURNS [BOOLEAN]]
    RETURNS [file: FHandle] = INLINE
    {RETURN[SegmentDefs.EnumerateFiles[proc]]};

  FPFromFile: PROCEDURE [file: FHandle, fp: FPHandle] = INLINE {fp↑ ← file.fp};

  GetFileProperties: PROCEDURE [file: FHandle]
    RETURNS [create, write, read: Time.Packed, length: LONG CARDINAL] = INLINE {
    [create: create, write: write, read: read] ← GetFileTimes[file];
    length ← GetFileLength[file]};

  GetFileTimes: PROCEDURE [file: FHandle]
    RETURNS [create, write, read: Time.Packed] = INLINE {
    [create: create, write: write, read: read] ←
      SegmentDefs.GetFileTimes[file]};

  GetFileLength: PROCEDURE [file: FHandle]
    RETURNS [LONG CARDINAL] = INLINE {
    page, byte: CARDINAL;
    [page: page, byte: byte] ← SegmentDefs.GetEndOfFile[file];
    RETURN[InlineDefs.LongMult[page, 512] + byte - 512]};

  InsertFile: PROCEDURE [file: FPHandle, access: Access ← DefaultAccess]
    RETURNS [FHandle] = INLINE {RETURN[SegmentDefs.InsertFile[file, access]]};

  LockFile: PROCEDURE [file: FHandle] = INLINE {SegmentDefs.LockFile[file]};

  NewFile: PROCEDURE [
    name: STRING, access: Access ← DefaultAccess,
    version: VersionOptions ← DefaultVersion] RETURNS [FHandle] = INLINE {
    RETURN[SegmentDefs.NewFile[name, access, version]]};

  ReleasableFile: PROCEDURE [file: FHandle] RETURNS [BOOLEAN] = INLINE {
    RETURN[file.segcount = 0 AND file.lock = 0]};

  ReleaseFile: PROCEDURE [file: FHandle] = INLINE {SegmentDefs.ReleaseFile[file]};

  SetFileTimes: PROCEDURE [
    file: FHandle, create, write, read: Time.Packed ← 0] = INLINE {
    SegmentDefs.SetFileTimes[
      file: file, create: create, write: write, read: read]};

  SetFileLength: PROCEDURE [file: FHandle, length: LONG CARDINAL] = INLINE {
    page, byte: CARDINAL;
    [quotient: page, remainder: byte] ← InlineDefs.LongDivMod[length, 512];
    SegmentDefs.SetEndOfFile[file: file, page: page+1, byte: byte]};

  UnlockFile: PROCEDURE [file: FHandle] = INLINE {SegmentDefs.UnlockFile[file]};

  -- D I R E C T O R Y: 

  EnumerateDirectory: PROCEDURE [proc: PROCEDURE [FPHandle, STRING] RETURNS [BOOLEAN]] =
    INLINE {DirectoryDefs.EnumerateDirectory[proc]};

  -- for Debugger Only: 

  NameForFile: PROCEDURE [name: STRING, file: FHandle];
  ModifyFile: PROCEDURE [name: STRING] RETURNS [BOOLEAN];
  AddModifyProc: PROCEDURE [PROCEDURE [STRING, FHandle] RETURNS [BOOLEAN]];
  InvalidateFileCache: PROCEDURE;
  FlushFileCache: PROCEDURE;

  END.