// 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) ]