// SpruceInstall.Bcpl -- Spruce Spooler Installation // errors 250 // get "Spruce.d" was too big: only need get "SprucePrinters.d" get "Sprucedoc.d" get "spruceMisc.d" get "SpruceFiles.d" get "Streams.d" get "BcplFiles.d" get "MenuDefs.d" get "SpruceParamsNames.d" get "SpruceFilesNames.d" external // defined here [ SpruceInstall ] external // external [ // SpruceFiles ForgetSpruceFile InitSpruceFile ResetSpruceFile // SpruceInUtil DiskObject MakeValidSpruceFile SetupDrive StatusOf31s // SpruceCheck CheckPoint LevelPos OpenCheckPointFile RestoreFromCheckPoint // Spruce Utils CreateFPRD CursorChar FSGetX FSInit FSPut InitRam LoadRam SpruceError // StringUtil CopyString StringCompare // ReadUserCmItem ReadUserCmItem // Template PutTemplate // TFS TFSClose TFSInit // BFS BFSClose // OS CallSwat dsp Gets MyFrame OpenFile ShowDisplayStream SetFilePos FilePos ReadBlock Wss Wo Zero // statics BandFile BitMarginAdjust breakPage Capabilities CheckPrAttr Debug DebugSystem DutyCycle drive1Disk LogoFont LogoText ErrorFile PressServer Facets FontFile QueueFile LandscapeDevice maxQueued menu menuBuf seed Verbose xmFonts // MenuData menuStream NumBins OverlayTop PaperDimensionB PaperDimensionS PaperSpeedInches PermanentBottom PolygonRatio printerDevice printerForward printerName PRamImage ResolutionB ResolutionS ScanLengthInches ScanMarginAdjust SpoolFile sprintFPRD spruceFPRD SpruceZone tridentDisk tridentUsed statusOf31s UserName // **** See SpruceStatics, SpruceUtils, below -- more memory for installation MoreLow; MoreHigh ] static InstallStackSize = 2000 static map = 0 static [ menu; menuStream; menuBuf; MenuInitHelp=0; ChangeRoutine ] static [ errorSpecs; fontSpecs; spoolSpecs; bandSpecs; okToInstall ] structure SPECS: [ fileId word; devId word; defDev word; sizeId word; defSize word ] manifest //param types [ pNum = 1 pString = 2 pFile = 3 pResFile = 4 //file that already existed ] // ------------------------------------------------------ let SpruceInstall(doInstall, runCfa) be // ------------------------------------------------------ // After loading RAM, and reclaiming its storage, validate the Checkpoint file. // If the Sprint version statics are NIL, or the checkpoint file doesn't exist, // Sprint probably hasn't been installed - inform the user and exit. // Otherwise, proceed with installation. // The objective of installation is to somehow get default values into the CheckPoint // file. This is accomplished by extracting the defaults from the User.CM file. // Defaults are stored in User.CM as pairs of keyword & value(s). // (i.e. DebugSystem: 040) // For simple statics, we can just assign values to the appropriate static locations. // For structures (e.g. SpoolFile, etc.) we need to parse the values found in User.CM // and create the structures before checkpointing. // // Since the installation defaults are few in number [ InitRam(PRamImage, OrbitRMR) OverlayTop=LoadRam //Bottom of free storage for FSInit let PermanentTop = MyFrame()-InstallStackSize @#335 = PermanentTop; PermanentBottom = PermanentTop statusOf31s = StatusOf31s() // (if allowed&necc.), create and init. file -- if had to init, install independent of request let CpFileOK = OpenCheckPointFile(runCfa) if (not doInstall) & CpFileOK return PutTemplate(dsp, "Installing...*N") FSInit() InitStatics() // Compute FPRDs (InLd, OutLd arguments) for self and Spruce printer CursorChar($B) spruceFPRD = CreateFPRD("Spruce.Boot", true) unless spruceFPRD do SpruceError(257) CheckPoint(LEVSharedInstStatics, LEVInstallationStatics) finish ] // ------------------------------------------------------ and GetStaticInfo(s) = valof // ------------------------------------------------------ // given a static name, return the address of the cooresponding table entry. [ unless map do [ map = FSGetX(100) map!1 = "Debug"; map!2 = lv Debug; map!3 = pNum map!4 = "Verbose"; map!5 = lv Verbose; map!6 = pNum map!7 = "PressServer"; map!8 = lv PressServer; map!9 = pNum map!10 = "DebugSystem"; map!11 = lv DebugSystem; map!12 = pNum map!13 = "xmFonts"; map!14 = lv xmFonts; map!15 = pNum map!16 = "ErrorFile"; map!17 = lv ErrorFile; map!18 = pResFile map!19 = "SpoolFile"; map!20 = lv SpoolFile; map!21 = pFile map!22 = "QueueFile"; map!23 = lv QueueFile; map!24 = pFile map!25 = "BandFile"; map!26 = lv BandFile; map!27 = pFile map!28 = "FontFile"; map!29 = lv FontFile; map!30 = pResFile map!31 = "printerName"; map!32 = lv printerName; map!33 = pString map!34 = "LogoFont"; map!35 = lv LogoFont; map!36 = pString map!37 = "LogoText"; map!38 = lv LogoText; map!39 = pString map!40 = "LandscapeDevice"; map!41 = lv LandscapeDevice; map!42 = pNum map!43 = "PaperDimensionB"; map!44 = lv PaperDimensionB; map!45 = pNum map!46 = "PaperDimensionS"; map!47 = lv PaperDimensionS; map!48 = pNum map!49 = "printerDevice"; map!50 = lv printerDevice; map!51 = pNum map!52 = "printerForward"; map!53 = lv printerForward; map!54 = pNum map!55 = "PaperSpeedInches"; map!56 = lv PaperSpeedInches; map!57 = pNum map!58 = "ScanLengthInches"; map!59 = lv ScanLengthInches; map!60 = pNum map!61 = "ScanMarginAdjust"; map!62 = lv ScanMarginAdjust; map!63 = pNum map!64 = "BitMarginAdjust"; map!65 = lv BitMarginAdjust; map!66 = pNum map!67 = "Capabilities"; map!68 = lv Capabilities; map!69 = pNum map!70 = "DutyCycle"; map!71 = lv DutyCycle; map!72 = pNum map!73 = "Facets"; map!74 = lv Facets; map!75 = pNum map!76 = "PolygonRatio"; map!77 = lv PolygonRatio; map!78 = pNum map!79 = "NumBins"; map!80 = lv NumBins; map!81 = pNum map!82 = "ResolutionB"; map!83 = lv ResolutionB; map!84 = pNum map!85 = "ResolutionS"; map!86 = lv ResolutionS; map!87 = pNum map!88 = "BreakPage"; map!89 = lv breakPage; map!90 = pNum map!91 = 0 ] let pos = 1 until map!pos eq 0 do [ unless StringCompare(s, map!pos) do resultis lv (map!pos) pos = pos + 3 ] resultis 0 ] // ------------------------------------------------------ and InitStatics() be // ------------------------------------------------------ // For simple statics, the value found in the UserCmSlice is deposited in the // statics' location. Other statics may reference structures (i.e. strings, SpruceFiles, etc), // which may need to be created, and initialized. [ let s = OpenFile("User.Cm", ksTypeReadOnly, charItem, 0, 0, 0, SpruceZone) unless s do CallSwat("Can't read file User.Cm for installation defaults") let addr, buf, buf1 = 0, FSGetX(80), FSGetX(80) let needSpruce = true [ switchon ReadUserCmItem(s, buf) into [ case $E: break; endcase case $N: needSpruce = StringCompare(buf, "Spruce"); endcase case $L: unless needSpruce do [ addr = GetStaticInfo(buf) unless addr do CallSwat("Unknown static mentioned in User.Cm: ", buf) ] endcase case $P: case $S: unless needSpruce do [ CallSwat("Additional parameter in User.Cm file:", buf) finish ] endcase ] if addr ne 0 then [ if @(addr+2) eq pNum then [ unless GetNextItem(s, $P, buf1) do CallSwat("User.Cm Error - numeric paramater expected after:", buf) unless StringCompare(buf1, "true") do @(@(addr+1)) = -1 unless StringCompare(buf1, "false") do @(@(addr+1)) = 0 @(@(addr+1)) = StringToNumber(buf1) ] if @(addr+2) eq pString then [ unless GetNextItem(s, $P, buf1) do CallSwat("User.Cm Error - string paramater expected after:", buf) @(@(addr+1)) = FSGetX((buf1>>STRING.length+2) rshift 1) CopyString(@(@(addr+1)), buf1) ] if @(addr+2) eq pFile % @(addr+2) eq pResFile then [ Wss(dsp, "*N") let fileName, pages, device = 0, 0, 0 unless GetNextItem(s, $P, buf1) do //get filename CallSwat("User.Cm Error - fileName expected after:", buf) fileName = FSGetX((buf1>>STRING.length+2) rshift 1) CopyString(fileName, buf1) unless GetNextItem(s, $P, buf1) do //get number of pages (if any) CallSwat("User.Cm Error - page-length expected for:", buf) pages = StringToNumber(buf1) if pages eq 0 % @(addr + 2) eq pResFile then pages = -1 unless GetNextItem(s, $P, buf1) do //get device spec [dp0, dp1, tp0] CallSwat("User.Cm Error - device specification expected for:", buf) unless StringCompare("DP0", buf1) do [ device = DISK31 ] unless StringCompare("DP1", buf1) do [ device = DISK31B ] unless StringCompare("TP0", buf1) do [ device = DISKT80 ] let OK = MakeValidSpruceFile(@(addr+1), fileName, pages, device) if @(addr+2) eq pResFile & not OK then CallSwat("Installation error - non-existant file:", fileName) Wss(dsp, fileName); Wss(dsp, " ") ] addr = 0 ] ] repeat FSPut(buf) ] // ------------------------------------------------------ and StringToNumber(s) = valof // ------------------------------------------------------ [ // return numeric value for string // convert in octal if leading digit is zero. let octal, pwr, pos, result = false, 1, 0, 0 let length = s>>STRING.length if s>>STRING.char^1 eq #60 then octal = true [ result = result + (((s>>STRING.char^(length - pos)) - #60) * (octal ? (1 lshift (pos*3)), pwr)) pos = pos + 1; pwr = pwr * 10 ] repeatwhile pos ne length resultis result ] (635)\408b33B // ------------------------------------------------------ and GetNextItem(s, item, buf) = valof // ------------------------------------------------------ [ let itemType = ReadUserCmItem(s, buf) if itemType eq $E % itemType eq $N % itemType ne item then resultis false resultis itemType ]