// PrintInitUtils.bcpl - PRESS INSTALLATION UTILITIES // last modified by Butterfield, October 22, 1980 1:54 PM // - IndexFile, set nPressRecs if FILEPress - 10/22 // - GetFileWhere, let FILEPress be on Tridents - 10/20 // - IndexFile, add ISF file map to F - 4/18 // - CloseDrive1, use BFSClose - 3/10 // - SetupDrive1, use BFSInit - 3/10/80 // errors 280 get "PressInternals.df" get "PressParams.df" get "AltoFileSys.d" get "Disks.d" get "Streams.d" get "SysDefs.d" get "IfsIsf.d" structure BFSDSK: [ @DSK @KDH //other stuff not used here.... ] structure KD: [ @KDH //Header part diskBitTable ^1,1 word //The bit table itself (1,1 means nothing) ] // outgoing procedures external [ IndexFile SetupDrive1 CloseDrive1 GetFileName GetFileStatic ] // outgoing statics //external // [ // ] //static // [ // ] // incoming procedures external [ //PRESS PressError DblShift //PRESSML DoubleAdd Ugt //Used for initialization of files, etc. -- removed by Junta OpenFile DeleteFile Closes ReadBlock WriteBlock FileLength GetCompleteFa Resets PositionPage ReadLeaderPage WriteLeaderPage //WINDOW WindowInit WindowClose WindowWriteBlock //SCAN TypeForm ReadNumber //ALLOC Allocate //OS MoveBlock Zero ActOnDiskPages ReturnFrom BFSClose BFSInit //TFS TFSInit ReleaseDiskPage AssignDiskPage //DiskFindHole DiskFindHole //IfsIsf InitFmap; IndexedPageIO; LookupFmap; ] // incoming statics external [ BitsFile ScratchFile LeftOverFile1 LeftOverFile2 BandFile MeterFile GodFile PressFile RunFile tridentVec tridentUsed sysDisk PressZone nPressRecs ] // internal statics static [ drive1disk ] // File-wide structure and manifest declarations. structure STR[ length byte char^1,255 byte ] // Procedures //Index a file: (called from above and PressInit) // p=vector in which to index // findex=index of file for the structure // fname=file name string let IndexFile(p, findex, fname) = valof [ // Get code for where to look (0= main Model 31 disk, 1=alternate disks, then main Model 31) let where=GetFileWhere(findex) // Alter=0 (RO,silent), 1 (RO,print), 2 (RW,print) let alter=GetFileType(findex) let filetype=(alter eq 2)? FILERW,FILERO if alter then TypeForm("File: ",fname) //Now index the file named "fname" let str=vec 20 let s=0 let disk=nil let bestDisk=nil [ //giant loop, deleting all inappropriate versions of file //first, find most likely file for i=(where? (2+8*3-1),0) to 0 by -1 do [ disk=DiskStuff(i, 2) if disk eq 0 then loop s=OpenFile(fname,ksTypeReadOnly,0,0,0,0,PressZone,0,disk) bestDisk=i if s ne 0 then break ] //end of "find most likely file" if alter eq 0 & s eq 0 then resultis 0 //Error if alter ne 0 test s ne 0 then [ TypeForm(" on ",DiskStuff(bestDisk,0)) let v=vec 1 FileLength(s, v) DblShift(v, disk>>DSK.lnPageSize+1) TypeForm(", length is ",10,v!1," pages.") test alter eq 2 then [ TypeForm(" Ok?",1,str) let c=str>>STR.char^1 if str>>STR.length ne 0 & (c eq $n % c eq $N) then [ Closes(s) DeleteFile(fname, 0, 0, PressZone, 0, disk) s=0 ] ] or TypeForm(0) ] or TypeForm(" -- does not exist.*n") //now, decide if we're done with giant loop if s ne 0 then break //found it!!! if bestDisk eq 0 then break //nowhere!!! ] repeat //end of giant loop, either choosing file, or deleting all versions if s eq 0 then [ for i=2+8*3-1 to 0 by -1 do if DiskStuff(i, 2) then [ TypeForm("Do you want it on the ",DiskStuff(i, 0),"?",1,str) let c=str>>STR.char^1 if str>>STR.length ne 0 & (c eq $n % c eq $N) then loop bestDisk=i break ] //end of for i=2+8*3-1 to 0 loop disk=DiskStuff(bestDisk, 2) TypeForm("How long do you want it to be (in pages): ",1,str) let pagcnt=ReadNumber(str) if bestDisk ge 2 then [ let bVDA=DiskFindHole(disk,pagcnt+2) //1 for leader, 1 for numchrs=0 if bVDA eq -1 then [ TypeForm("Unable to find contiguous hole that size on the disk! Try again.*n") loop ] ReleaseDiskPage(disk, AssignDiskPage(disk,bVDA-1)) ] s=OpenFile(fname,ksTypeWriteOnly,0,0,0,0,PressZone,0,disk) if bestDisk ge 2 then [ ReadLeaderPage(s, p) p>>LD.consecutive=true WriteLeaderPage(s, p) ] // Because of bug in TransferPages, go slowly: let cp=0 while cp ne pagcnt+1 do [ let toPage=pagcnt+1 if Ugt(toPage-cp, 200) then toPage=cp+200 PositionPage(s, toPage) cp=toPage ] break //Normal case -- done ] repeat //keep going until you find a contiguous hole let consecutive=false ReadLeaderPage(s, p) if p>>LD.consecutive then consecutive=true //Believe the hint!!! Zero(p,3000) Resets(s) let cfa=vec lCFA GetCompleteFa(s, cfa) p>>F.version=cfa>>CFA.fp.version MoveBlock(lv p>>F.serialNumber, lv cfa>>CFA.fp.serialNumber, lSN) //Compute number of pages included in FileLength: let lnPageSize = disk>>DSK.lnPageSize; // log of words per page let fileLength = vec 1; FileLength(s, fileLength); // length in bytes let pageCount = vec 1; pageCount!0 = 0; if findex eq FILEPress then // use pageCount to compute record count [ pageCount!1 = 2 * PressRecordSize - 1; DoubleAdd(pageCount, fileLength); // round up to next record boundary DblShift(pageCount, LogPressRecordSize + 1); nPressRecs = pageCount!1; ] pageCount!1 = 1 lshift (lnPageSize + 1) - 1; // i.e. bytes per page - 1 DoubleAdd(pageCount, fileLength); // round up to next page boundary DblShift(pageCount, lnPageSize + 1); p>>F.Pagecnt = pageCount!1; Closes(s) let plen = nil; // length of this F test consecutive ifso [ p>>F.DAFirst = cfa>>CFA.fa.da; // DA for first data page. plen = (offset F.fmap / 16); // length is just length of F ] ifnot [ let fmap = lv p>>F.fmap; let initOK = InitFmap(fmap, 3000 - offset F.fmap / 16, lv cfa>>CFA.fp, 0, 10, -1, disk); if initOK then [ let page = vec 1024; IndexedPageIO(fmap, p>>F.Pagecnt, page, 1, 0); ] let lastDA = LookupFmap(fmap, p>>F.Pagecnt, true); unless initOK & lastDA ne fillInDA do [ TypeForm("This non-consecutive file cannot be used by Press.*n"); resultis 0; ] let last = fmap>>FM.last; fmap>>FM.end = last; plen = lv fmap>>FM.fmap!last + lenMapEntry - p; // include fmap ] //Special treatment for bits file -- always make it look like 1024 word pages if findex eq FILEBits then [ p>>F.Pagecnt=p>>F.Pagecnt rshift (10-lnPageSize) lnPageSize=10 ] p>>F.Name=findex p>>F.Device=DiskStuff(bestDisk, 1) p>>F.Pagesize=1 lshift lnPageSize p>>F.LogPagesize=lnPageSize p>>F.Type=filetype resultis plen ] and DiskStuff(i, what) = selecton what into [ case 0: selecton i into [ //Names case 0: "Model 31" case 1: "Model 31, drive 1" default: valof [ let tString="Trident drive x, filesys x" tString>>STR.char^15=$0+7-((i-2)/3) tString>>STR.char^26=$0+2-((i-2) rem 3) resultis tString ] ] //end of names case 1: i //Press code case 2: selecton i into [ //"disk" structures case 0: sysDisk case 1: drive1disk default: tridentVec!(i-2) ] ] (635)\3887f1 29f0 // Set up for dealing with second Model 31 drive, if it is there. //---------------------------------------------------------------------------- and SetupDrive1() = valof //---------------------------------------------------------------------------- [ drive1disk = BFSInit(PressZone, true, 1); resultis drive1disk ] //---------------------------------------------------------------------------- and CloseDrive1() be //---------------------------------------------------------------------------- [ if drive1disk then drive1disk = BFSClose(drive1disk); ] //---------------------------------------------------------------------------- and GetFileName(findex) = ( //---------------------------------------------------------------------------- selecton findex into [ case FILEBits: "Press.Bits" case FILEScratch: "Press.Scratch" case FILELeftOver1: "Press.LO1" case FILELeftOver2: "Press.LO2" case FILEBands: "Press.Bands" case FILEMeter: "Press.Meter" case FILEFontDictionary: "Press.Fonts" case FILEPressProgram: "Press.Run" default: PressError(280) ] ) and GetFileType(findex) = ( selecton findex into [ case FILEExternal: case FILEPress: 0 //Read-only, silent case FILEPressProgram: case FILEFontDictionary: 1 //Read-only, print it out default: 2 //Read-write, print it out ] ) and GetFileWhere(findex) = ( selecton findex into [ case FILEPressProgram: 0 // case FILEPress: default: 1 ] ) and GetFileStatic(findex) = ( selecton findex into [ case FILEBits: lv BitsFile case FILEScratch: lv ScratchFile case FILELeftOver1: lv LeftOverFile1 case FILELeftOver2: lv LeftOverFile2 case FILEBands: lv BandFile case FILEMeter: lv MeterFile case FILEFontDictionary: lv GodFile case FILEPressProgram: lv RunFile default: PressError(280) ] )