-- InitialPack.Mesa Edited by:
-- Evans on May 19, 1980 4:33 PM
-- Bruce on October 7, 1980 1:29 PM
-- Sandman on July 30, 1980 9:49 AM
-- Johnsson on July 15, 1980 2:54 PM
-- Mark on August 20, 1980 8:32 PM
DIRECTORY
BP USING [BBHandle, BytePC, Conditionalize, FindBB, ResetBBs],
Commands USING [Go, WriteError],
Cursor USING [Set],
DebugFormat USING [BBHandle, Foo],
DebugOps USING [
BBHandle, Display, Foo, GFHandle, InvalidateFileCache, Numeric, ReadCodeByte,
ShortCopyREAD, ShortCopyWRITE, ShortREAD, UserAborted],
DI USING [ValFormat],
DLoadState USING [Init],
DOutput USING [Char, Decimal, EOL, Line, Octal, Text],
DPsb USING [ResetCache],
Drum USING [FlushCodeSegmentCache, FlushCoreCache, Initialize],
DSyms USING [Clean, FreeItems, Prune],
Dump USING [Num, ResetPrinters, UserText, XferFrame, XferName],
Event USING [AddNotifier, Item, Masks, Notifier, Notify],
Frames USING [FlushFrameCache, Invalid],
Gf USING [FrameGfi],
Init USING [
CheckMemory, CoreSwap, CoreSwapMessages, LoadStateReason, usermessage, WriteHerald],
Lf USING [Display, GF, Handle, PC, Validate],
Lookup USING [Signal, StateCtx],
MachineDefs USING [BYTE, FHandle, GFHandle, ProcDesc],
Mopcodes USING [zBRK],
Pc USING [EvalStackEmpty, ResetCache],
PrincOps USING [BYTE, BytePC, SignalDesc, StateVector, SVPointer],
SDDefs USING [SD, sSignal],
Source USING [ResetFrames],
State USING [GetGS, GSHandle, Msg],
Storage USING [FreeString],
Symbols USING [ISEIndex, ISENull, RecordSENull],
SymbolTable USING [Missing],
TajoMisc USING [SetState],
UserInput USING [ResetUserAbort];
InitialPack: PROGRAM
IMPORTS BP, Commands, Cursor, DebugOps, DOutput, DPsb, Drum, DSyms,
Dump, Event, Frames, Gf, Init, Lf, DLoadState, Lookup, Pc,
Source, State, Storage, SymbolTable, TajoMisc, UserInput
EXPORTS BP, Dump, Init =
BEGIN OPEN Event, Init, MachineDefs, PrincOps;
Debug: PUBLIC SIGNAL = CODE;
UCS: PUBLIC SIGNAL = CODE;
MapLog: PUBLIC SIGNAL = CODE;
bootLoaded: PUBLIC BOOLEAN ← FALSE;
data: State.GSHandle;
event: Event.Item ← [eventMask: Event.Masks[newFiles], eventProc: Notify];
warning: PUBLIC CoreSwapMessages;
RestartMsg: PUBLIC PROC =
BEGIN OPEN DOutput;
SELECT data.restartMsg FROM
none => RETURN;
interrupt => Line["*** interrupt ***"L];
punt => Line["*** Fatal System Error (Punt) ***"L];
bootloaded => Line["*** Debugger Bootloaded ***"L];
invalid => Line["*** Invalid Swap Reason - Context Invalid ***"L];
maplog => Line["*** Processing VM Map ***"L];
ENDCASE;
data.restartMsg ← none;
END;
SaveSignallerGF: PROCEDURE =
BEGIN
pd: MachineDefs.ProcDesc ←
DebugOps.ShortREAD[@SDDefs.SD[SDDefs.sSignal]];
data.sigGF ← Gf.FrameGfi[pd.gfi];
RETURN;
END;
BreakInstToState: PROCEDURE [sp: SVPointer, b: MachineDefs.BYTE] =
BEGIN OPEN MachineDefs;
state: StateVector;
DebugOps.ShortCopyREAD[
from: sp, to: @state, nwords: SIZE[StateVector]];
state.instbyte ← b;
DebugOps.ShortCopyWRITE[
to: sp, from: @state, nwords: SIZE[StateVector]];
RETURN
END;
CodeByteFromState: PROCEDURE [state: PrincOps.SVPointer]
RETURNS [MachineDefs.BYTE] =
BEGIN
f: MachineDefs.FHandle = DebugOps.ShortREAD[@state.dest];
RETURN[DebugOps.ReadCodeByte[Lf.GF[f],Lf.PC[f]]]
END;
Validate: PUBLIC PROC [sv: PrincOps.SVPointer] RETURNS [BOOLEAN] =
BEGIN
RETURN[sv # NIL AND CodeByteFromState[sv] = Mopcodes.zBRK]
END;
Break: PUBLIC PROCEDURE =
BEGIN OPEN MachineDefs;
-- breakpoint interpreter
sp: SVPointer = data.StatePtr;
f: FHandle ← DebugOps.ShortREAD[@sp.dest];
gframe: GFHandle ← DebugOps.ShortREAD[@f.accesslink];
bp: DebugOps.BBHandle;
IF ~Lf.Validate[f] THEN
BEGIN
DOutput.Text["Breakpoint"L];
Commands.Go[];
RETURN
END;
data.breakFrame ← f;
IF (bp ← BP.FindBB[gframe, Lf.PC[f]]) = NIL THEN
DOutput.Text["Breakpoint not found!"L]
ELSE {
DOutput.EOL[];
BreakInstToState[sp, bp.inst];
WriteBreakHerald[f,bp]};
Commands.Go[bp];
RETURN
END;
WriteBreakHerald: PROCEDURE [f: FHandle, b: DebugOps.BBHandle] =
BEGIN OPEN DOutput;
BreakNum: PROC = BEGIN Text[" #"L]; Decimal[b.num] END;
IF b.bt.ex = octal THEN
BEGIN
Text["Octal-break"L]; BreakNum[]; Text[" in frame: "L];
Octal[Lf.GF[f]]; Text[", byte-pc: "L]; Octal[b.pc];
EOL[]
END
ELSE
BEGIN
Text[IF b.bt.bt = break THEN "Break"L ELSE "Trace"L];
BreakNum[];
Text[SELECT b.bt.ex FROM
entry => " at entry to "L,
exit => " at exit from "L,
ENDCASE => " in "L];
Lf.Display[f];
IF b.condition # NIL AND DebugOps.Numeric[b.condition] THEN
BEGIN
s: STRING ← b.condition;
BP.Conditionalize[b,s];
Storage.FreeString[s];
END;
END;
SELECT TRUE FROM
Pc.EvalStackEmpty[] => NULL;
b.bt.ex = entry AND b.symbolsAvailable => NULL;
b.bt.ex = exit => NULL;
ENDCASE => {EOL[]; Line[" Eval-Stack not empty!"L]};
RETURN
END;
UCSHandler: PUBLIC PROCEDURE = {DOutput.Text["*** uncaught SIGNAL "L]; Commands.Go[]};
Msg: PROCEDURE = INLINE
BEGIN
vf: DI.ValFormat = [none[]];
DOutput.Text[" msg = "L];
Dump.Num[DebugOps.ShortREAD[@data.StatePtr.stk[0]], vf];
RETURN
END;
PreDeclared: PROCEDURE [u: UNSPECIFIED] RETURNS [BOOLEAN] =
BEGIN
Sigs: ARRAY [0..3) OF INTEGER = [-1,3,5];
Names: ARRAY [0..3) OF STRING = ["ERROR"L, "UNWIND"L, "ABORTED"L];
FOR i: CARDINAL IN [0..3) DO
IF Sigs[i] = u THEN {DOutput.Text[Names[i]]; RETURN[TRUE]};
ENDLOOP;
RETURN[FALSE];
END;
PrintUCS: PUBLIC PROCEDURE =
BEGIN
signal: PrincOps.SignalDesc ← data.signal;
isei: Symbols.ISEIndex ← Symbols.ISENull;
IF PreDeclared[signal] THEN RETURN;
isei ← Lookup.Signal[signal];
Dump.XferName[signal, isei];
SignalCtxFromState[signal, data.StatePtr ! SymbolTable.Missing => {Msg[]; CONTINUE}];
Dump.XferFrame[signal];
RETURN;
END;
SignalCtxFromState: PUBLIC PROC [
cl: PrincOps.SignalDesc, sv: PrincOps.SVPointer] =
BEGIN
f: DebugOps.Foo ← Lookup.StateCtx[Lookup.Signal[cl], sv, in, 1];
IF f = NIL THEN ERROR SymbolTable.Missing[NIL];
IF f.tsei = Symbols.RecordSENull THEN RETURN;
f.xfer ← FALSE;
DebugOps.Display[f, TRUE ! Frames.Invalid => {
DOutput.Char[' ]; DOutput.Octal[f]; Commands.WriteError[nGframe,FALSE]; CONTINUE}];
END;
NewLoadState: PUBLIC PROCEDURE [why: LoadStateReason] =
BEGIN
DLoadState.Init[];
data.initBCD ← TRUE;
SELECT why FROM
debug => SIGNAL Debug;
ucs => SIGNAL UCS;
maplog => SIGNAL MapLog;
ENDCASE => ERROR;
END;
CoreSwapMsg: PUBLIC PROC [msg: CoreSwapMessages] =
BEGIN
IF msg = none THEN RETURN;
DOutput.Text[SELECT msg FROM
cantSwap => "Core image not healthy, can't swap"L,
evalstack => "Eval-Stack not empty!"L,
interrupt => "*** interrupt ***"L,
maplog => "*** Processing VM Map ***"L,
ENDCASE => ERROR];
END;
usermessage: PUBLIC STRING ← NIL;
GetUserMessage: PUBLIC PROCEDURE =
BEGIN OPEN MachineDefs;
s: StateVector;
DebugOps.ShortCopyREAD[
from: data.StatePtr, to: @s, nwords: SIZE[StateVector]];
Init.usermessage ← IF s.stkptr = 1 THEN s.stk[0] ELSE NIL;
s.stkptr ← 0;
DebugOps.ShortCopyWRITE[
from: @s, to: data.StatePtr, nwords: SIZE[StateVector]];
RETURN
END;
-- type: Cursor.Type = Cursor.UniqueType[];
FlushCaches: PUBLIC Event.Notifier =
BEGIN
-- toilet: Cursor.Object ← [
-- info: [type,8,8],
-- array: [36B, 42B, 102B, 702B, 102B, 102B, 102B, 7702B, 70042B,
-- 120142B, 114602B, 103002B, 60004B, 14004B, 3004B, 774B]];
-- Cursor.Store[@toilet];
SELECT why FROM
newSession =>
BEGIN
Cursor.Set[textPointer];
CheckMemory[];
DebugOps.InvalidateFileCache[];
Drum.FlushCodeSegmentCache[];
Drum.FlushCoreCache[];
Drum.Initialize[];
BP.ResetBBs[];
Source.ResetFrames[];
SaveSignallerGF[];
data.loggedIn ← FALSE;
data.worryBreaks ← FALSE;
Frames.FlushFrameCache[];
DPsb.ResetCache[];
FlushCaches[flushSymbols];
-- Cursor.Set[questionMark];
Event.Notify[why];
[] ← TajoMisc.SetState[on];
END;
newFiles =>
BEGIN
DebugOps.InvalidateFileCache[];
DSyms.Clean[];
END;
flushSymbols =>
BEGIN
DSyms.Prune[];
DSyms.FreeItems[];
Pc.ResetCache[];
Dump.ResetPrinters[];
END;
resumeSession =>
BEGIN
Frames.FlushFrameCache[];
DPsb.ResetCache[];
-- Cursor.Set[questionMark];
Event.Notify[why];
[] ← TajoMisc.SetState[on];
END;
resumeDebuggee, abortSession =>
BEGIN
-- Cursor.Set[questionMark];
Event.Notify[why];
-- Cursor.Store[@toilet];
Frames.FlushFrameCache[];
DPsb.ResetCache[];
Drum.FlushCodeSegmentCache[];
Drum.FlushCoreCache[];
END;
ENDCASE;
-- Cursor.Set[textPointer];
END;
Notify: Event.Notifier = {IF why = newFiles THEN FlushCaches[why]};
DebugState: TYPE = {installing, initial, ucs, maplog};
StartDebugger: PUBLIC PROC [boot: BOOLEAN ← TRUE] =
BEGIN
case: DebugState ← installing;
bootLoaded ← ~boot;
data ← State.GetGS[];
DO
Init.WriteHerald[TRUE];
DebugIt[case !
DebugOps.UserAborted => {UserInput.ResetUserAbort[]; RESUME};
Debug => {case ← initial; CONTINUE};
UCS => {case ← ucs; CONTINUE};
MapLog => {case ← maplog; CONTINUE}];
FlushCaches[newSession];
IF warning # none THEN {CoreSwapMsg[warning]; DOutput.EOL[]};
ENDLOOP;
END;
DebugIt: PROC [case: DebugState] =
BEGIN
Init.WriteHerald[];
SELECT case FROM
installing => CoreSwap[install];
ucs => BEGIN UCSHandler[]; CoreSwap[resume] END;
maplog => CoreSwap[proceed];
ENDCASE;
DO
IF Init.usermessage # NIL THEN Dump.UserText[Init.usermessage];
Commands.Go[];
CoreSwap[proceed];
ENDLOOP;
END;
Event.AddNotifier[@event];
END.