-- File: HelloLisp.mesa
-- Edit 23-Aug-84 10:18:20 Masinter
-- Created 9-Jul-84 15:06:38 Lichtenberg
DIRECTORY
File USING [Type,
Create, Delete, File, MakePermanent, nullFile, PageNumber, PageCount, GetSize, SetSize, Unknown ],
FileTypes USING [tUntypedFile],
OthelloDefs,
OthelloOps USING [
BootFileType,
MakeBootable, MakeUnbootable,
GetPhysicalVolumeBootFile, VoidPhysicalVolumeBootFile,
SetVolumeBootFile, GetVolumeBootFile, VoidVolumeBootFile
],
PhysicalVolume USING [ID],
Space USING [Map, CopyIn, Unmap, Window],
TemporaryBooting USING [InvalidParameters],
Volume USING [Close, ID, GetAttributes, nullID, InsufficientSpace, Open ];
-- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
HelloLisp: PROGRAM
IMPORTS
File, OthelloDefs, OthelloOps, Space, TemporaryBooting, Volume =
BEGIN
CopyVM: PROC = BEGIN
fromVolume, toVolume: Volume.ID;
fromFile, toFile: File.File;
pvID: PhysicalVolume.ID;
error: BOOLEAN ← FALSE;
currentBase: File.PageNumber;
nextCount: File.PageCount;
fromWindow,toWindow: Space.Window;
toPointer: LONG POINTER;
fromFileSize: File.PageCount;
tries: CARDINAL;
toFileSize: File.PageCount;
minFileSize: File.PageCount;
OthelloDefs.MyNameIs[
myNameIs: "Copy Lisp From Another Volume"L,
myHelpIs: "Copies lisp from one volume to another"L];
[pvID, fromVolume] ← OthelloDefs.GetLvIDFromUser[prompt:"Volume to copy from: "L];
IF fromVolume = Volume.nullID THEN OthelloDefs.AbortingCommand["Invalid volume."L];
toVolume ← OthelloDefs.GetLvIDFromUser[prompt:"Volume to copy to: "L].lvID;
IF toVolume = Volume.nullID THEN OthelloDefs.AbortingCommand["Invalid volume."L];
-- Open up the volumes
Volume.Open[fromVolume];
Volume.Open[toVolume];
-- Is there a source file?
fromFile ← OthelloOps.GetVolumeBootFile[fromVolume,hardMicrocode].file;
IF fromFile = File.nullFile THEN {
Volume.Close[fromVolume];
Volume.Close[toVolume];
OthelloDefs.AbortingCommand["No Lisp sysout on source volume"L];
};
-- Is there a dest file? Delete it if yes.
toFile ← OthelloOps.GetVolumeBootFile[toVolume,hardMicrocode].file;
IF toFile # File.nullFile THEN {
OthelloOps.VoidVolumeBootFile[toVolume,hardMicrocode];
File.Delete[toFile];
IF OthelloOps.GetPhysicalVolumeBootFile[pvID,hardMicrocode].file = toFile
THEN OthelloOps.VoidPhysicalVolumeBootFile[pvID,hardMicrocode];
};
-- Create the dest file
fromFileSize ← File.GetSize[fromFile];
toFileSize ← fromFileSize;
tries ← 20;
toFile ← File.Create[toVolume, toFileSize, FileTypes.tUntypedFile
! Volume.InsufficientSpace =>
{ tries ← tries - 1;
toFileSize ← toFileSize - 100;
OthelloDefs.WriteString["."L];
IF tries = 0 OR toFileSize < 0 THEN {error ← TRUE;
CONTINUE}
ELSE RETRY;};];
IF error THEN {Volume.Close[fromVolume];
Volume.Close[toVolume];
OthelloDefs.AbortingCommand["Destination volume does not contain sufficient space!"L];};
File.MakePermanent[toFile];
-- Create windows onto the file
OthelloDefs.WriteString["Copying..."L];
currentBase ← 0;
nextCount ← 100;
minFileSize ← fromFileSize;
IF toFileSize < fromFileSize THEN minFileSize ← toFileSize;
DO -- until file has been copied
fromWindow ← [file: fromFile,
base: currentBase,
count: nextCount];
toWindow ← [file: toFile,
base: currentBase,
count: nextCount];
toPointer ← Space.Map[toWindow].pointer;
nextCount ← Space.CopyIn[toPointer,fromWindow];
toPointer ← Space.Unmap[toPointer];
currentBase ← currentBase + nextCount;
OthelloDefs.WriteString["."L];
IF currentBase >= minFileSize THEN EXIT;
ENDLOOP;
OthelloDefs.WriteString["Installing..."L];
OthelloOps.MakeBootable[toFile, hardMicrocode, OthelloDefs.leaderPages
! TemporaryBooting.InvalidParameters => {
OthelloDefs.WriteLine["Warning, trouble making bootable"L]; CONTINUE}];
OthelloOps.SetVolumeBootFile[toFile,hardMicrocode,OthelloDefs.leaderPages];
OthelloDefs.WriteLine["done"L];
Volume.Close[fromVolume];
Volume.Close[toVolume];
END;
-- UGH.. This kludge sets the file's size to be as big as Pilot will let it be, on 100 page increments.
SetBootFileSize: PRIVATE PROC[file: File.File, lvID: Volume.ID] = BEGIN
tries: CARDINAL;
oldSize: File.PageCount ← File.GetSize[file];
newSize: File.PageCount ← oldSize + Volume.GetAttributes[lvID].freePageCount;
tries ← 20;
OthelloOps.MakeUnbootable[file, hardMicrocode, OthelloDefs.leaderPages];
File.SetSize[file, newSize
! File.Unknown => {OthelloDefs.WriteLine["Warning: Trouble making file fill volume - File.Unknown"L];
CONTINUE};
Volume.InsufficientSpace => {OthelloDefs.WriteString["."L]; newSize ← newSize - 100;
tries ← tries - 1;
IF tries = 0 OR newSize < oldSize THEN {OthelloDefs.WriteLine["Warning: Expanding volume failed!"]; CONTINUE;} ELSE RETRY};];
OthelloOps.MakeBootable[file,hardMicrocode, OthelloDefs.leaderPages];
END;
ExpandVM: PROC = BEGIN
pvID: PhysicalVolume.ID;
exVolume: Volume.ID;
exFile: File.File;
OthelloDefs.MyNameIs[
myNameIs: "Expand Vmem File"L,
myHelpIs: "Expand the lisp virtual mem file on a volume"L];
[pvID, exVolume] ← OthelloDefs.GetLvIDFromUser[prompt:"Volume to expand: "L];
IF exVolume = Volume.nullID THEN OthelloDefs.AbortingCommand["Invalid volume."L];
Volume.Open[exVolume];
exFile ← OthelloOps.GetVolumeBootFile[exVolume, hardMicrocode].file;
IF exFile = File.nullFile THEN OthelloDefs.AbortingCommand["No sysout on volume."L];
OthelloDefs.WriteString["Expanding file..."L];
SetBootFileSize[exFile,exVolume];
OthelloDefs.WriteLine["Done."L];
Volume.Close[exVolume];
END;
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- Central commands
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
commandProcessor: OthelloDefs.CommandProcessor ← [LispCommands];
LispCommands: PROC [index: CARDINAL] = {
SELECT index FROM
0 => CopyVM[];
1 => ExpandVM[];
ENDCASE => OthelloDefs.IndexTooLarge};
-- Initialize
OthelloDefs.RegisterCommandProc[@commandProcessor];
END...