DIRECTORY Boot USING [Location, LVBootFiles], BootFile USING [ currentVersion, Entry, Header, maxEntriesPerHeader, maxEntriesPerTrailer, MDSIndex, Trailer], BootStartList USING [Base, versionID], ConvertUnsafe USING [AppendRope, ToRope], Device USING [Type], Directory USING [Error, Lookup], Environment USING [PageNumber, wordsPerPage], File USING [Capability, nullCapability, nullID, PageCount, PageNumber, read, write], Inline USING [LongDivMod, LongNumber, LowHalf], IO USING [GetToken, EndOfStream, PutF, PutRope, RIS, rope, STREAM, WhiteSpace], PhysicalVolume USING [ GetAttributes, GetContainingPhysicalVolume, Handle, ID, InterpretHandle], Rope USING [Concat, Find, Length, ROPE], Space USING [CopyIn, CopyOut, Create, Delete, Handle, LongPointer, Map, virtualMemory], SpecialVolume USING [GetLogicalVolumeBootFiles], Commander USING [CommandProc, Register], Volume USING [GetLabelString, GetNext, ID, maxNameLength, nullID, TypeSet]; SDP: PROGRAM IMPORTS ConvertUnsafe, Directory, Inline, IO, PhysicalVolume, Rope, Space, SpecialVolume, Commander, Volume SHARES File = BEGIN BootHeadPtr: TYPE = LONG POINTER TO BootFile.Header; Outcome: TYPE = {success, startListHeaderHasBadVersion, notInitialBootFile}; SetDebuggerPointers: Commander.CommandProc = TRUSTED { commandLine: IO.STREAM = IO.RIS[cmd.commandLine]; typescript: IO.STREAM = cmd.out; FindDebugger: PROC RETURNS [debugger: Volume.ID _ Volume.nullID] = { debugTypeOnly: Volume.TypeSet = [debugger: TRUE]; DO debuggerBootFiles: Boot.LVBootFiles; IF (debugger _ Volume.GetNext[debugger, debugTypeOnly]) = Volume.nullID THEN EXIT; SpecialVolume.GetLogicalVolumeBootFiles[debugger, @debuggerBootFiles]; IF debuggerBootFiles[pilot].fID ~= File.nullID AND debuggerBootFiles[debugger].fID ~= File.nullID AND debuggerBootFiles[debuggee].fID ~= File.nullID THEN { debuggerNameS: STRING _ [Volume.maxNameLength]; Volume.GetLabelString[debugger, debuggerNameS]; debuggerName _ ConvertUnsafe.ToRope[debuggerNameS]; EXIT }; ENDLOOP; }; debuggerName: Rope.ROPE _ NIL; debugger: Volume.ID = FindDebugger[]; fileName: Rope.ROPE _ NIL; fileNameS: STRING _ [100]; debuggeeFile: File.Capability _ File.nullCapability; fileName _ commandLine.GetToken[IO.WhiteSpace ! IO.EndOfStream => CONTINUE]; SELECT TRUE FROM fileName.Length[] = 0 => fileName _ "BasicCedarDorado.boot"; fileName.Find["."] = -1 => fileName _ fileName.Concat[".boot"]; ENDCASE; ConvertUnsafe.AppendRope[to: fileNameS, from: fileName]; debuggeeFile _ Directory.Lookup[fileNameS ! Directory.Error => CONTINUE]; IF debuggeeFile = File.nullCapability THEN { typescript.PutF["'%g' cannot be found./N", IO.rope[fileName]]; RETURN }; IF debugger = Volume.nullID THEN { typescript.PutRope["No installed debugger can be found./N"]; RETURN }; debuggeeFile.permissions _ File.read+File.write; IF SetDebugger[debuggeeFile, 1, debugger] = success THEN typescript.PutF[ "'%g' will now world-swap to the debugger installed on volume '%g'.\N", IO.rope[fileName], IO.rope[debuggerName]] ELSE typescript.PutF["'%g' is an unsuitable boot file./N", IO.rope[fileName]]; }; SetDebugger: PROC [ debuggeeFile: File.Capability, debuggeePage: File.PageNumber, debugger: Volume.ID] RETURNS [outcome: Outcome] = { bootSpace: Space.Handle = Space.Create[1, Space.virtualMemory]; pBootHeader: BootHeadPtr = Space.LongPointer[bootSpace]; BEGIN ENABLE UNWIND => Space.Delete[bootSpace]; Space.Map[bootSpace]; Space.CopyIn[bootSpace, [debuggeeFile, debuggeePage]]; SELECT TRUE FROM pBootHeader.version ~= BootFile.currentVersion => outcome _ startListHeaderHasBadVersion; pBootHeader.continuation.kind ~= initial => outcome _ notInitialBootFile; ENDCASE => { filePage: File.PageNumber _ debuggeePage + 1; -- start at page following header pStartListHeader: BootStartList.Base; bufferSpace: Space.Handle = Space.Create[1, Space.virtualMemory]; BEGIN ENABLE UNWIND => Space.Delete[bufferSpace]; FindStartListHeader: PROC = --INLINE-- { buffer: LONG POINTER = Space.LongPointer[bufferSpace]; pTrailer: LONG POINTER TO BootFile.Trailer = LOOPHOLE[buffer]; pagesRemaining: File.PageCount _ pBootHeader.countData; entries: LONG DESCRIPTOR FOR ARRAY OF BootFile.Entry; slPage: Environment.PageNumber; slOffset: [0..377B]; PointerMunge: PROC [p: POINTER, n: BootFile.MDSIndex] = INLINE { ln: Inline.LongNumber = [num[lowbits: LOOPHOLE[p], highbits: n]]; [slPage, slOffset] _ Inline.LongDivMod[ln.lc, Environment.wordsPerPage]; }; PointerMunge[ pBootHeader.pStartListHeader, WITH pBootHeader.continuation SELECT FROM initial => mdsi, ENDCASE => ERROR ]; Space.Map[bufferSpace]; entries _ DESCRIPTOR[ @pBootHeader.entries, Inline.LowHalf[MIN[pagesRemaining, BootFile.maxEntriesPerHeader]]]; DO FOR i: CARDINAL IN [0..LENGTH[entries]) DO IF entries[i].page = slPage THEN {filePage _ filePage + i; GO TO found}; ENDLOOP; filePage _ filePage + LENGTH[entries]; pagesRemaining _ pagesRemaining - LENGTH[entries]; IF pagesRemaining = 0 THEN ERROR; Space.CopyIn[bufferSpace, [debuggeeFile, filePage]]; filePage _ filePage.SUCC; entries _ DESCRIPTOR[ @pTrailer.entries, Inline.LowHalf[MIN[pagesRemaining, BootFile.maxEntriesPerTrailer]]]; REPEAT found => NULL; ENDLOOP; Space.CopyIn[bufferSpace, [debuggeeFile, filePage]]; pStartListHeader _ LOOPHOLE[buffer + slOffset]; }; FindStartListHeader[]; SELECT TRUE FROM pStartListHeader.version ~= BootStartList.versionID => outcome _ startListHeaderHasBadVersion; ENDCASE => { pv: PhysicalVolume.ID = PhysicalVolume.GetContainingPhysicalVolume[debugger]; h: PhysicalVolume.Handle = PhysicalVolume.GetAttributes[pv].instance; dT: Device.Type = PhysicalVolume.InterpretHandle[h].type; dO: --DeviceOrdinal--CARDINAL = PhysicalVolume.InterpretHandle[h].index; debuggerBootFiles: Boot.LVBootFiles; SpecialVolume.GetLogicalVolumeBootFiles[debugger, @debuggerBootFiles]; pStartListHeader.locDebuggerMicrocode _ LOOPHOLE[Boot.Location[ deviceType: dT, deviceOrdinal: dO, vp: disk[debuggerBootFiles[softMicrocode]]]]; pStartListHeader.locDebuggerGerm _ LOOPHOLE[Boot.Location[ deviceType: dT, deviceOrdinal: dO, vp: disk[debuggerBootFiles[germ]]]]; pStartListHeader.locDebugger _ LOOPHOLE[Boot.Location[ deviceType: dT, deviceOrdinal: dO, vp: disk[debuggerBootFiles[debugger]]]]; pStartListHeader.locDebuggee _ LOOPHOLE[Boot.Location[ deviceType: dT, deviceOrdinal: dO, vp: disk[debuggerBootFiles[debuggee]]]]; Space.CopyOut[bufferSpace, [debuggeeFile, filePage]]; outcome _ success; }; Space.Delete[bufferSpace]; END; }; END; Space.Delete[bootSpace]; }; Commander.Register["SDP", SetDebuggerPointers, NIL]; END. @SDP.mesa last edited by Levin on August 16, 1983 10:30 am ÊG˜Jšœ™Jšœ0™0J˜šÏk ˜ Jšœœ˜#šœ œ˜J˜]—Jšœœ˜&Jšœœ˜)Jšœœ˜Jšœ œ˜ Jšœ œ˜-JšœœJ˜TJšœœ#˜/Jšœœ(œœ˜Ošœœ˜Jšœ4œ˜I—Jšœœœ˜(JšœœL˜WJšœœ˜0Jšœ œ˜(Jšœœœ"˜KJ˜—šœ˜ šœ˜Jšœ"œ?˜c—Jšœ˜ —J˜Jš˜J˜Jš œ œœœœ˜4J˜Jšœ œ?˜LJ˜šœ-œ˜6Jš œ œœœœ˜1Jšœ œœ ˜ šÏn œœœœ˜DJšœ+œ˜1š˜J˜$JšœFœœ˜RJ˜Fšœ-˜2Jšœ/˜2šœ/œ˜5Jšœœ˜/J˜/Jšœ3˜3Jš˜Jšœ˜——Jšœ˜—J˜—Jšœœœ˜Jšœœ˜%Jšœœœ˜Jšœ œ ˜J˜4Jšœ œœœ˜Lšœœ˜Jšœ<˜Jš˜J˜—šœœ˜"Jšœ<˜J˜7Jšœ œœœ˜5Jšœ˜Jšœ˜šž œœœœ˜@Jšœ&œ˜AJšœH˜HJšœ˜—šœ ˜ Jšœ˜šœœ˜)Jšœœ˜!—Jšœ˜—J˜šœ œ˜Jšœ˜Jšœœ1˜C—š˜š œœœœ ˜*Jšœœœœ˜HJšœ˜—Jšœœ ˜&Jšœ"œ ˜2Jšœœœ˜!Jšœ4˜4Jšœœ˜šœ œ˜Jšœ˜Jšœœ2˜D—š˜Jšœ œ˜—Jšœ˜—Jšœ4˜4Jšœ œ˜/Jšœ˜—J˜š˜šœ6˜6Jšœ'˜'—šœ˜ J˜MJ˜EJ˜9JšœŸœ+˜HJ˜$J˜Fšœ(œ˜?J˜P—šœ#œ˜:J˜G—šœœ˜6J˜K—šœœ˜6J˜K—J˜5J˜J˜——Jšœ˜Jšœ˜J˜——Jšœ˜J˜Jšœ˜J˜—J˜Jšœ/œ˜4J˜Jšœ˜J˜—…—€