-- Copyright (C) 1983  by Xerox Corporation. All rights reserved. 
-- PupBooterFast.mesa, HGM, 24-Sep-83 12:20:16

DIRECTORY
  Inline USING [LongDivMod],
  Space USING [nullInterval],
  System USING [Pulses, GetClockPulses, PulsesToMicroseconds],
  EFTPDefs USING [
    EFTPAbortSending, EFTPFinishSending, EFTPOpenForSending, EFTPSendBlock,
    EFTPSetSendTimeout, EFTPTimeOut, EFTPTroubleSending],
  BootServerDefs USING [WhatHappened],
  BootServerFriends USING [BootFile, LockFileRead, SetupSpace, UnlockFile],
  PupTypes USING [PupAddress];

PupBooterFast: PROGRAM
  IMPORTS Inline, System, EFTPDefs, BootServerFriends
  EXPORTS BootServerDefs =
  BEGIN

  FastBooter: PUBLIC PROCEDURE [
    bf: BootServerFriends.BootFile, him: PupTypes.PupAddress]
    RETURNS [what: BootServerDefs.WhatHappened] =
    BEGIN OPEN EFTPDefs;
    from: LONG POINTER;
    wordsPerPage: CARDINAL = 256;  -- Alto/EtherBoot needs this to be 1 page
    page, pages, bytes: CARDINAL;
    pulses: System.Pulses ← System.GetClockPulses[];
    IF ~BootServerFriends.LockFileRead[bf] THEN RETURN[diskBusy];
    EFTPSetSendTimeout[100, 5];
    BEGIN
    EFTPOpenForSending[
      him, FALSE ! EFTPTimeOut, EFTPTroubleSending => GOTO NeverStarted];
    IF bf.space = Space.nullInterval THEN BootServerFriends.SetupSpace[bf];
    [pages, bytes] ← Inline.LongDivMod[bf.bytes, wordsPerPage*2];
    from ← bf.space.pointer;
    FOR page IN [0..pages) DO
      -- This must total about 5 seconds to keep Pilot's EtherGerm happy
      IF page = 1 THEN EFTPSetSendTimeout[200, 25];
      EFTPSendBlock[
        from, wordsPerPage*2 ! EFTPTimeOut, EFTPTroubleSending => GOTO Trouble];
      from ← from + wordsPerPage;
      ENDLOOP;
    IF bytes # 0 THEN
      BEGIN
      EFTPSendBlock[
        from, bytes ! EFTPTimeOut, EFTPTroubleSending => GOTO Trouble];
      END;
    EFTPFinishSending[ ! EFTPTimeOut, EFTPTroubleSending => GOTO Trouble];
    pulses ← System.Pulses[System.GetClockPulses[] - pulses];
    bf.count ← bf.count + 1;
    bf.ms ← bf.ms + System.PulsesToMicroseconds[pulses]/1000;
    what ← fast;
    EXITS
      Trouble => BEGIN EFTPAbortSending["Trouble sending"L]; what ← troubles; END;
      NeverStarted =>
        BEGIN EFTPAbortSending["Never started"L]; what ← neverStarted; END;
    END;
    BootServerFriends.UnlockFile[bf];
    END;


  END.