// RaidStack.bcpl. Raid printing routines for Lisp stack // last edited September 19, 1981 3:05 PM by Bill van Melle // From RaidPrint.bcpl August 26, 1981 by Bill van Melle get "Raid.decl" external [ // procedures defined LispStack; LispFrame; ShowStackBlocks PrintFxtn; PrintBF; PrintAddrs; PrintBytes // statics defined lastFrame; linkUsed; raidStackFX // statics used dsp; keys; @lvNIL; @lvVPtr; @VPtr0; @VPtr1 // procedures used PrintPtr; PrintName; Lprint; RaidReset; CRLF; ReadNum; ReadChar GetStkBlkType; GetFXP Negate; Divide; Usc; Min; Wc; Ws; Wo; Wn; Wb; EqNIL; VP; Gets; UCase @BGetBasePtr; @XGetBasePtr; @XGetBase32; IGetBase @SGetBase; @XSetBR; @RRead; @BGetBase; @XGetBase; @XGetBase1 GetLmarg; SetLmarg; GetBitPos ] static [ raidStackFX = 0 lastFrame = 0 linkUsed = 0 ] manifest [ usedClink = 1 usedAlink = 2 ] let LispStack(FX; numargs na) be [ if na ls 1 % FX eq 0 then FX = GetFXP() let p = CheckFXP(FX) raidStackFX = FX // now working on this stack let r = p // do the two link chains differ? [ if (GetAlink(r) ne GetClink(r)) then [ r = UseCLink(); break ] r = GetAlink(r) ] repeatwhile r CRLF() let n = 0 [ n = n + 1 Wn(n, 10); Ws(": ") PrintFXName(p) p = r ? GetClink(p), GetAlink(p) ] repeatwhile p ] and UseCLink() = valof [ [ Ws(" following ") switchon ReadChar() into [ case $A: case $a: Ws("ccess links") linkUsed = usedAlink resultis false; endcase case $C: case $c: Ws("ontrol links") linkUsed = usedClink resultis true; endcase default: Ws("XXX - either Access or Control ") ] ] repeat ] and CheckFXP(nfx, cl, ofx; numargs n) = valof [ unless (nfx eq 0) % (GetStkBlkType(nfx) eq FxtnBlock) do [ Wo(nfx, true); Ws(" invalid frame extension") if n gr 1 then [ Ws(" at "); Ws(cl ? "C", "A"); Ws("Link of "); Wo(ofx, true) ] RaidReset("") ] resultis nfx ] and GetAlink(fx) = CheckFXP((SGetBase(fx + FXalink) & (not FXXMask)) - FXPvar, false, fx) and GetBlink(fx) = GetSlow(fx) ? SGetBase(fx + FXblink), fx-2 and GetClink(fx) = CheckFXP(SGetBase(fx + (GetSlow(fx) ? FXclink, FXalink)) - FXPvar, false, fx) and GetNameT(fx, lvNT) = valof [ // store address of name table of fx into lvNT let v = (SGetBase(fx + flagword) & FXVMask) ne 0 // Name table valid? lvNT>>VA.vahi = SGetBase(fx + (v ? FXNThi, FXFHhi))<>VA.valo = SGetBase(fx + (v ? FXNTlo, FXFHlo)) resultis lvNT ] and GetNVars (fx, lvnp, lvnf) be // number of pvars, fvars [ // use fn header, not name table, because nt does not guarantee PV field let fnhd = vec 1 fnhd>>VA.vahi = SGetBase(fx + FXFHhi)<>VA.valo = SGetBase(fx + FXFHlo) @lvnp = BGetBase(fnhd!0, fnhd!1 + NTnPV)< start of BF if GetStkBlkType(BF) ne BFBlock % (Usc(ivar, BF) gr 0) then [ CRLF(); Wo(BF, true); Ws(" is not a basic frame"); return] test residual ifso Ws ("*NResidual ") ifnot Ws ("*N") Ws("Basic Frame at "); Wo(BF, true); CRLF() if BF ne ivar then [ let padded = SGetBase(BF + flagword) & BFPmask let nvars = ((BF-ivar)-(padded ? 2, 0)) rshift 1 test na gr 1 ifso [ // names are available let NT = vec 1 GetNameT (fx, NT) PrintVars (ivar, 0, nvars, NT, ivarCode, false) ] ifnot PrintVals(ivar, nvars) if padded then [ // one 2word pad PrintStk(BF-2) CRLF() ] ] PrintStk(BF) // the BF word itself ] and PrintFxtn(P) be [ CheckFXP(P) let NT = vec 1 GetNameT (P, NT) // get name table into NT Ws("*NFrame Extension at "); Wo(P, true); Ws(" Frame Name is: "); PrintFXName(P) // print Fx header PrintStk(P); Ws (" ["); PrintFXFlags (P); Ws (", alink]"); CRLF() PrintStk(P+2); Ws (" [fn header]"); CRLF() PrintStk(P+4); Ws (" [next, PC]"); CRLF() PrintStk(P+6); Ws (" [name table]"); CRLF() PrintStk(P+8); Ws (" [blink, clink]"); CRLF() let npv, nfv = nil, nil GetNVars (P, lv npv, lv nfv) // find out how many of each // print PVars let pvStart = P+FXPvar PrintVars(pvStart, 0, npv, NT, pvarCode, false) let start = pvStart + npv lshift 1 // print FVars PrintFVars(start, nfv, npv, NT) start = start + nfv lshift 1 + 6 PrintStk(start-6); CRLF() // 3 junk cells (should be 2?) PrintStk(start-4); CRLF() PrintStk(start-2); CRLF() let nextblk = SGetBase(P + FXnxt) // print temporary values if (NT!0 eq STACKspace) & (NT!1 gr P) & (NT!1 ls nextblk) then [ // name table is on stack, so we must be sure to skip over it nfv = (NT!1 - start) rshift 1 if nfv gr 0 then PrintVars (start, (start-pvStart) rshift 1, nfv, NT, pvarCode, true) // print stuff before nt. Use PrintVars because there may be funny PVars in here start = NT!1 let ntlen = SGetBase (NT!1+offNtSize) + (ntOvheadWords rshift 1) // number of double words in nt for i = 1 to ntlen // print nt simply do [ PrintStk(start); CRLF() start = start+2 ] ] test nextblk ls start ifso [ Ws ("Next blk too soon??"); CRLF() ] ifnot PrintVals(start, (nextblk-start) rshift 1) ] and PrintFXName(s) be [ let ntp = vec 1 GetNameT(s, ntp) ntp>>VA.valo = ntp>>VA.valo + NTfname Lprint(XGetBasePtr(ntp)) ] and PrintFXFlags(FX) be // interpret the FX flags [ let flags = SGetBase(FX+flagword) if (flags & FXFMask) ne 0 then Wc ($F) if (flags & FXLMask) ne 0 then Wc ($L) if (flags & FXCMask) ne 0 then Wc ($C) if (flags & FXVMask) ne 0 then Wc ($V) if (flags & FXNMask) ne 0 then Wc ($N) let X = SGetBase(FX+FXalink) & FXXMask test X ifso Wc ($X) ifnot if (flags & (FXFMask % FXLMask % FXCMask % FXVMask % FXNMask)) eq 0 then Wc ($-) ] and PrintStk(i) be // print the two stack words at i,i+1 [ Ws(" "); Wo(i); Ws(": ") Wo(SGetBase(i)); Wc($*S); Wo(SGetBase(i+1)) ] and PrintVals(p, n) be // print n val ptrs starting at p for i = 1 to n do [ PrintStk(p) test SGetBase(p)<