-- XXDebugPC.mesa  Edited by Bruce,  October 14, 1980  10:52 AM

DIRECTORY
  AltoDefs: FROM "altodefs",
  DebugUsefulDefs: FROM "debugusefuldefs",
  PrincOps: FROM "princops",
  RESOut: FROM "resout",
  STDebugDefs USING [showLinks],
  StringDefs: FROM "stringdefs",
  Symbols: FROM "symbols",
  XXDebugDefs: FROM "xxdebugdefs";

XXDebugPC: PROGRAM 
  IMPORTS STDebugDefs, DebugUsefulDefs, RESOut, StringDefs, XXDebugDefs
  EXPORTS XXDebugDefs =
  BEGIN OPEN RESOut, XXDebugDefs;

-- defs copied from PCPack

  ItemNull: Item = LAST[Item];
  CacheLimit: CARDINAL = 
    (AltoDefs.PageSize/SIZE[ItemObject])*SIZE[ItemObject];
  CacheBase: TYPE = BASE POINTER TO UNSPECIFIED;
  Item: TYPE = CacheBase RELATIVE POINTER [0..256) TO ItemObject;

  ItemObject: TYPE = RECORD [
    link: Item,
    ep: [0..128), -- EntryPoint,
    gf: CARDINAL, -- GFHandle,
    start, end: CARDINAL, -- BytePC,
    hasSons: BOOLEAN,
    inner: BOOLEAN,
    dCbti: Symbols.CBTIndex,
    userCbti: Symbols.CBTIndex];


  PrintCacheItem: PUBLIC PROCEDURE [item: Item] =
    BEGIN
    cache: CacheBase = PCCache[];
    io: ItemObject;

    lastItemPrinted ← item;
    DebugUsefulDefs.ShortCopyREAD[
      to: @io, from: @cache[item], nwords: SIZE[ItemObject]];
    PCr[];
    PString["cache["L]; PUnsigned[LOOPHOLE[item]]; PString["] = gf: "L];
    POctal[io.gf];
    PNextOctal["ep"L, io.ep];
    PNextOctal["start"L, io.start];
    PNextOctal["end"L, io.end];
    PNextUnsigned["dBti"L, io.dCbti];
    PNextUnsigned["uBti"L, io.userCbti];
    IF io.inner THEN PNext["inner"L];
    IF io.hasSons THEN PNext["hasSons"L];
    IF STDebugDefs.showLinks THEN PNextUnsigned["link"L, io.link];
    END;
    
  lastItemPrinted: Item ← ItemNull;

  PrintNextCacheItem: PUBLIC PROCEDURE =
    BEGIN
    cache: CacheBase = PCCache[];
    io: ItemObject;

    IF lastItemPrinted = ItemNull THEN
      {Complain["No valid previous"L]; ERROR cancelAction};
    DebugUsefulDefs.ShortCopyREAD[
      to: @io, from: @cache[lastItemPrinted], nwords: SIZE[ItemObject]];
    PrintCacheItem[io.link];
    END;
    
  PrintPCCache: PUBLIC PROCEDURE =
    BEGIN
    item: Item ← PCHead[];

    IF item = ItemNull THEN
      {PCr[]; PString["PC Cache empty"]}
    ELSE PrintCacheItem[item];
    END;

-- generalized list chasing

  nodeSizeString: PUBLIC STRING ← NIL;
  nodeLinkString: PUBLIC STRING ← NIL;

  ConvertStrings: PRIVATE PROCEDURE RETURNS [size, link: CARDINAL] =
    BEGIN
    problems: BOOLEAN ← FALSE;
    size ← link ← 0;
    BEGIN -- to set up badSize label
    IF nodeSizeString = NIL THEN GO TO badSize;
    size ← StringDefs.StringToNumber[nodeSizeString, 10 ! 
      StringDefs.InvalidNumber => GO TO badSize];
    IF size NOT IN [2..10] THEN GO TO badSize;
    EXITS
      badSize =>
	BEGIN
	problems ← TRUE;
        Complain["set size IN [2..8] "L];
	END;
    END;
    BEGIN -- to set up badSize label
    IF nodeLinkString = NIL THEN GO TO badSize;
    link ← StringDefs.StringToNumber[nodeLinkString, 10 ! 
      StringDefs.InvalidNumber => GO TO badSize];
    IF link NOT IN [0..size) THEN GO TO badSize;
    EXITS
      badSize =>
	BEGIN
	problems ← TRUE;
        Complain["set link IN [0..size)"L, ~problems];
	END;
    END;
    IF problems THEN ERROR cancelAction;
    END;
    
  lastNode: POINTER ← NIL;

  PrintNextListNode: PUBLIC PROCEDURE =
    BEGIN
    node: ARRAY [0..8) OF POINTER;
    size, link: CARDINAL;
    [size: size, link: link] ← ConvertStrings[];
    IF lastNode = NIL THEN
      {Complain["No valid previous"L]; ERROR cancelAction};
    DebugUsefulDefs.ShortCopyREAD[from: lastNode, to: BASE[node], nwords: size];
    PrintListNode[node[link]];
    END;
  
  PrintListNode: PUBLIC PROCEDURE [p: POINTER] =
    BEGIN
    i: CARDINAL;
    node: ARRAY [0..8) OF POINTER;
    size: CARDINAL ← ConvertStrings[].size;
    IF p = NIL THEN RETURN;
    DebugUsefulDefs.ShortCopyREAD[from: p, to: BASE[node], nwords: size];
    PCr[]; POctal[p]; PString["↑ = "L];
    POctal[node[0]];
    FOR i IN [1..size) DO
      PNext[""L, Log8[LOOPHOLE[node[i]]]]; -- enough slop for probable B
      POctal[node[i]];
      ENDLOOP;
    lastNode ← p;
    END;
  
  END.