-- Copyright (C) 1983  by Xerox Corporation. All rights reserved. 
-- FixBootFileDates.mesa, HGM,  6-Nov-84 13:53:25

DIRECTORY
  FormSW USING [
    AllocateItemDescriptor, ClientItemsProcType, CommandItem, newLine, ProcType,
    StringItem],
  Heap USING [systemZone],
  MFile USING [Error, Handle, ReadWrite],
  MSegment USING [Address, Create, Delete, Handle],
  Runtime USING [GetBcdTime],
  String USING [AppendString],
  Time USING [Append, Current, Unpack],
  Tool USING [Create, MakeSWsProc, MakeFormSW],
  ToolWindow USING [TransitionProcType],
  UserTerminal USING [BlinkDisplay],
  Window USING [Handle],

  PupWireFormat USING [BcplLongNumber, MesaToBcplLongNumber];

FixBootFileDates: PROGRAM
  IMPORTS
    FormSW, Heap, MFile, MSegment, Runtime, String, Time, Tool, UserTerminal,
    PupWireFormat =
  BEGIN

  z: UNCOUNTED ZONE = Heap.systemZone;

  filename: LONG STRING ← NIL;
  form: Window.Handle;

  BootFileHeader: TYPE = RECORD [  -- disk boot loader is first page
    other: ARRAY [0..3) OF WORD, timeStamp: PupWireFormat.BcplLongNumber];


  Init: PROCEDURE =
    BEGIN
    herald: STRING = [100];
    String.AppendString[herald, "FixBootFileDates of  "L];
    Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]];
    [] ← Tool.Create[
      name: herald, makeSWsProc: MakeSWs, clientTransition: ClientTransition];
    END;

  Smash: FormSW.ProcType =
    BEGIN
    bfh: LONG POINTER TO BootFileHeader;
    creation: LONG POINTER TO PupWireFormat.BcplLongNumber;
    file: MFile.Handle ← NIL;
    seg: MSegment.Handle;
    buffer: LONG POINTER;
    file ← MFile.ReadWrite[filename, [], binary ! MFile.Error => CONTINUE];
    IF file = NIL THEN BEGIN UserTerminal.BlinkDisplay[]; RETURN; END;
    seg ← MSegment.Create[file, [], 0, 1];
    buffer ← MSegment.Address[seg];
    bfh ← LOOPHOLE[buffer];
    creation ← LOOPHOLE[buffer + 10];
    IF creation↑ = [0, 0] THEN creation↑ ← bfh.timeStamp;  -- hack to remember when microcode was built
    bfh.timeStamp ← PupWireFormat.MesaToBcplLongNumber[Time.Current[]];
    MSegment.Delete[seg];
    END;

  MakeSWs: Tool.MakeSWsProc =
    BEGIN form ← Tool.MakeFormSW[window: window, formProc: MakeForm]; END;

  MakeForm: FormSW.ClientItemsProcType =
    BEGIN
    nParams: CARDINAL = 2;
    items ← FormSW.AllocateItemDescriptor[nParams];
    items[0] ← FormSW.CommandItem[
      tag: "Smash"L, proc: Smash, place: FormSW.newLine];
    items[1] ← FormSW.StringItem[tag: "Filename"L, string: @filename, inHeap: TRUE];
    RETURN[items, TRUE];
    END;

  ClientTransition: ToolWindow.TransitionProcType =
    BEGIN
    SELECT TRUE FROM
      old = inactive => filename ← z.NEW[StringBody[10]];
      new = inactive => z.FREE[@filename];
      ENDCASE;
    END;

  Init[];
  END.