// IfsLeafVPBIInit.bcpl - Virtual PBI Initialiization
// Copyright Xerox Corporation 1979

// Last modified by Wobber, January 21, 1980  1:58 PM

get FD, lookupStatus, lsNonexistent, lcVHighest, lcCreate,
 modeWrite, modeReadWrite from "IfsDirs.decl";
get ecCantCreateVPBIFile, ecVPBIFileFD, ecCantOpenVPBIFile from
 "IfsLeafErrors.decl";
get lenVPBIPageBitMap, lenVPBILockTable, lastVPBIPage from "IfsLeafVPBI.decl";
get "IfsLeafStats.decl"; get "IfsLeaf.decl"; get "IfsSequin.decl";
get lenLVMD from "IfsLeafVMem.decl";

external
[
//outgoing procedures
InitVirtualPBIs; FreeVPBILocks;

//incoming procedures
Allocate; AllocateLeafVMem; AllocateVPBIPage; CloseIFSStream;
FreePointer; IFSError; LockCell; LockDirFD; LookupIFSFile; OpenIFSFile;
OpenIFSStream; PositionPage; UnlockCell; Zero;

//incoming statics
CtxRunning; ctxSequinCtx; system; sysZone;

//outgoing statics
vPageLock; vpbiStats;
vpbiLVMD; vpbiPageBitMap; vpbiLockTable;
]

static
[
vPageLock = 0; vpbiStats = 0;
vpbiLVMD = 0; vpbiPageBitMap = 0; vpbiLockTable = 0;
]

//----------------------------------------------------------------------------
let InitVirtualPBIs() be
//----------------------------------------------------------------------------
[
// Allocate bitMap and lockTable.
vpbiPageBitMap = Allocate(sysZone, lenVPBIPageBitMap);
Zero(vpbiPageBitMap, lenVPBIPageBitMap);
vpbiLockTable = Allocate(sysZone, lenVPBILockTable+1);
Zero(vpbiLockTable, lenVPBILockTable+1);
vpbiLockTable!0 = lenVPBILockTable;

// Do lockcells.
for i = 1 to lenVPBILockTable do LockCell(lv vpbiLockTable!i);
LockCell(lv vPageLock);

// Set up the allocation information blocks.
InitAllocInfo(lv ctxSequinCtx>>SequinCtx.inputAllocInfo);
InitAllocInfo(lv ctxSequinCtx>>SequinCtx.outputAllocInfo);

if vpbiLVMD ne 0 return;

// Create the statics block.
vpbiStats = Allocate(sysZone, lenVPBIStats);
Zero(vpbiStats, lenVPBIStats);

// Lookup/create vpbi swapping file.
let filename = "VPBI.swap"; CtxRunning>>RSCtx.userInfo = system;
let ec = 0; let fd = LookupIFSFile(filename, lcVHighest+lcCreate, lv ec);
if fd eq 0 then IFSError(ecVPBIFileFD);
if fd>>FD.lookupStatus eq lsNonexistent then CreateVPBIFile(fd);
ec = OpenIFSFile(fd, modeReadWrite);
unless ec eq 0 do IFSError(ecCantOpenVPBIFile);

// Finally allocate the lvmd.
vpbiLVMD = Allocate(sysZone, lenLVMD); Zero(vpbiLVMD, lenLVMD);
AllocateLeafVMem(vpbiLVMD, fd);
]

//----------------------------------------------------------------------------
and FreeVPBILocks() be
//----------------------------------------------------------------------------
[
UnlockCell(lv vPageLock);
for i = 1 to vpbiLockTable!0 do UnlockCell(lv vpbiLockTable!i);
FreePointer(lv vpbiPageBitMap, lv vpbiLockTable);
]

//----------------------------------------------------------------------------
and CreateVPBIFile(fd, lvEc) be
//----------------------------------------------------------------------------
[
let str = OpenIFSStream(fd, lvEc, modeWrite);
if str eq 0 then IFSError(ecCantCreateVPBIFile);
PositionPage(str, lastVPBIPage, true);
CloseIFSStream(str); LockDirFD(fd);
]

//----------------------------------------------------------------------------
and InitAllocInfo(alloc) be
//----------------------------------------------------------------------------
[
let firstPage = AllocateVPBIPage();
alloc>>AllocInfo.vPageQ.head = firstPage;
alloc>>AllocInfo.vPageQ.tail = firstPage;
alloc>>AllocInfo.nextVPage = AllocateVPBIPage();
]