// PupBootInit.bcpl -- boot server initialization
// Last modified February 15, 1979 1:52 AM by Boggs
get "Pup0.decl"
get "Pup1.decl"
get "Streams.d"
get "PupBootServ.decl"
external
[
// outgoing procedures
CreateBootServ; DestroyBootServ
AddNameToBFQ; SetBootBcstInterval
// incoming procedures
BootServCtx; LockBootServ
Allocate; Free; InitializeContext
MoveBlock; Zero; Enqueue; Dequeue; Unqueue
SetFilePos; Endofs; Closes; ReadBlock; WriteBlock
OpenFile; DeleteFile; RenameFile
// incoming statics
@bs; @ms
]
manifest bsss = alto? 200, 100 // boot server stack size
//----------------------------------------------------------------------------
let CreateBootServ() be
//----------------------------------------------------------------------------
[
bs = Allocate(ms>>MS.zone, lenBS); Zero(bs, lenBS)
bs>>BS.ctx = InitializeContext(Allocate(ms>>MS.zone, bsss), bsss, BootServCtx)
Enqueue(ms>>MS.ctxQ, bs>>BS.ctx)
bs>>BS.stats.version = bootStatsVersion
bs>>BS.bcstTimer = 12 // wait 1 minute before first dir bcst
SetBootBcstInterval(1) // default is 1 hour
]
//----------------------------------------------------------------------------
and DestroyBootServ() be
//----------------------------------------------------------------------------
[
LockBootServ()
Unqueue(ms>>MS.ctxQ, bs>>BS.ctx)
Free(ms>>MS.zone, bs>>BS.ctx)
let bfe = bs>>BS.bfeQ.head; while bfe ne 0 do
Free(ms>>MS.zone, Dequeue(lv bs>>BS.bfeQ))
Free(ms>>MS.zone, bs)
]
//----------------------------------------------------------------------------
and SetBootBcstInterval(hours) be bs>>BS.bcstInterval = hours * 720
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
and AddNameToBFQ(bfn, name) be
//----------------------------------------------------------------------------
[
let bfe = Allocate(ms>>MS.zone, lenBFE + name>>String.length rshift 1 +1)
Zero(bfe, lenBFE+1)
bfe>>BFE.bfn = bfn
MoveBlock(lv bfe>>BFE.name, name, name>>String.length rshift 1 +1)
// AddNameToBFQ (cont'd)
let bootFile = OpenFile(name, ksTypeReadOnly, charItem, 0, lv bfe>>BFE.fp)
if bootFile ne 0 then
[
bfe>>BFE.exists = true
//There are two kinds of boot file.
//For more on boot files see the BuildBoot documentation
//B-Files produced by BuildBoot.run:
// File page 1: DiskBoot loader
// File page 2: locations 0-377b
// File page 3: locations 1000b - 1377b
// File page 4: locations 1400b - 1777b
// ...
// File page n: locations (n-1)*400b - (n-1)*400b+377b
//B-Files have 0 in the second data word
//B-Files are started by jmp @0 when loading is complete
//S-Files produced by Swat OutLd:
// File page 1: InOutLd loader
// File page 2: locations 1000b - 1377b
// File page 3: locations 1400 - 1777b
// ...
// File page 253: locations 176400b-176777b
// File page 254: locations 400b - 777b
// File page 255: locations 0 - 377b
//S-Files have a non-zero value in the second data word
//Some S-Files can be started by jmp @0.
//This is the kind we use, but we re-format them first
let buffer = Allocate(ms>>MS.zone, 256)
ReadBlock(bootFile, buffer, 256)
MoveBlock(lv bfe>>BFE.date, buffer+3, 2)
test buffer!1 eq 0
ifso // B-file
Closes(bootFile)
ifnot //InLd format file - make it B-format
[
buffer!1 = 0 // mark it as a B-format file
let newFile = OpenFile("TEMP.BOOT", ksTypeWriteOnly, charItem)
WriteBlock(newFile, buffer, 256) //useless swat InLdr
//read page containing loc 0-#377
SetFilePos(bootFile, 1, 254 lshift 9) //last page of file (255)
WriteBlock(newFile, buffer, ReadBlock(bootFile, buffer, 256))
//now copy the rest of the file; stop on page count not end of file
//note that file page 254 (core page 1) is discarded
SetFilePos(bootFile, 0, 512) //set up to read page 2
//S-Format files are guaranteed to be at least 255 pages long
for i = 2 to 253 do
WriteBlock(newFile, buffer, ReadBlock(bootFile, buffer, 256))
Closes(bootFile); DeleteFile(name)
Closes(newFile); RenameFile("TEMP.BOOT", name)
compileif alto then
[
Zero(lv bfe>>BFE.fp, 5)
Closes(OpenFile(name, ksTypeReadOnly, 0, 0, lv bfe>>BFE.fp))
]
]
Free(ms>>MS.zone, buffer)
]
Enqueue(lv bs>>BS.bfeQ, bfe)
]