// LocalVMemInit.bcpl - does VMem setup for MainInit
// Last change October 6, 1982 6:44 PM by Bill van Melle
// Last change July 20, 1982 10:33 PM by Bill van Melle
// everything from here on gets flushed after /I is finished
get "LispBcpl.decl"
get "Stats.decl"
get "VMem.decl"
get "AltoDefs.d"
get "AltoFileSys.d"
get "Streams.d"
external [ // procedures defined here
LocalInitVmem; CheckIPage
GiveUp; ShortStack
// O.S. procedures
Closes; Endofs; ReadBlock; OpenFile; PositionPage
CallSwat; OpenFileFromFp; WriteBlock
// statics
VmemStream; MinLispForRam; RamVersion; haveUcode; SysinName
]
manifest [ // same as in RemoteVmemInit.bcpl
firstMouseX = 260
firstMouseY = 50
lastMouseY = 800
]
let LocalInitVmem (SYSINid, VMEMid) be
[
let sst = OpenFile(0, ksTypeReadOnly, 0, 0, SYSINid)
unless sst do GiveUp("Can't find sysin file ", SysinName)
VmemStream = OpenFileFromFp(VMEMid)
unless VmemStream do GiveUp("Can't open Lisp.virtualmem")
@mouseX, @mouseY = firstMouseX, firstMouseY
// We can use the rest of the space between the end of the code and the
// current end of stack for buffers. This space will eventually go to
// the assorted allocations, but for now it is empty.
let Buffers = (@StackEnd+WordsPerPage-1) & not (WordsPerPage-1)
// first buf page, page-aligned
let LowStackPage = ShortStack(1000) // allow 1000 words of stack
let bsize = LowStackPage - Buffers // size of buffer region
if bsize ls WordsPerPage
then CallSwat("No buffers for SYSIN")
let OldLowStack = @StackEnd // save old low stack
@StackEnd = LowStackPage // enforce stack end in read
// figure out how big the sysout is so we can move cursor appropriately
PositionPage (sst, 0)
ReadBlock (sst, Buffers, WordsPerPage) // read leader page
let sysPages = Buffers>>LD.hintLastPageFa.pageNumber
let mouseInc = 0
if (sysPages gr 600) & (sysPages ls 10000) // plausible file size
then [
let nbufs = bsize / WordsPerPage
sysPages = (sysPages+nbufs-1) / nbufs // number buffers full
mouseInc = ((lastMouseY-firstMouseY) lshift 4) / sysPages
]
let mouseOff = mouseInc
// thus the mouse crawls down screen as we read.
// mouseInc is 2↑4 times amount to move per buffer full
// mouseOff = mouseInc*pgno
// Restore SavedVMEMstate from the InterfacePage
PositionPage(sst, FirstVmemBlock)
PositionPage(VmemStream, FirstVmemBlock)
ReadBlock(sst, Buffers, WordsPerPage)
// First page of Buffers now has InterfacePage of sysin - write it into vmem
CheckIPage(Buffers)
WriteBlock(VmemStream, Buffers, WordsPerPage)
// now read the pages off the file and into vmem - the entries in
// the page maps on the file have the correct vmem address already
until Endofs(sst) do
[ let wordsRead = ReadBlock(sst, Buffers, bsize)
WriteBlock(VmemStream, Buffers, wordsRead)
@mouseY = firstMouseY + (mouseOff rshift 4)
mouseOff = mouseOff + mouseInc
]
Closes(sst)
Closes(VmemStream); VmemStream = 0
@StackEnd = OldLowStack // restore previous stack end
]
and CheckIPage(buffer) be
[ // checks the critical items in buffer, a copy of the Interface
// page before it gets written into the vmem
// Key check - verify file is valid and complete
if @(buffer+IFPKey) ne IFPValidKey
then GiveUp(@(buffer+IFPKey) eq (not IFPValidKey) ?
"Can't resume: Inconsistent VMem file " ,
"Invalid or obselete Lisp VMem ", SysinName)
// unless haveUcode do return
let LispV = @(buffer+IFPLVersion)
unless LispV ge MinLispForRam
do GiveUp("Sysout too old for this microcode")
unless LispV ge MinLispForBcpl
do GiveUp("Sysout too old for this Lisp.Run")
unless RamVersion ge @(buffer+IFPMinRVersion)
do GiveUp("Microcode too old for this sysout")
unless BcplVersion ge @(buffer+IFPMinBVersion)
then GiveUp("Lisp.Run too old for this sysout")
]