diff options
Diffstat (limited to 'devel/debug/1/src/trace')
-rw-r--r-- | devel/debug/1/src/trace | 1020 |
1 files changed, 1020 insertions, 0 deletions
diff --git a/devel/debug/1/src/trace b/devel/debug/1/src/trace new file mode 100644 index 0000000..773b5f2 --- /dev/null +++ b/devel/debug/1/src/trace @@ -0,0 +1,1020 @@ +PACKET trace DEFINES trace: + +(**************************************************************) +(* Autor: G. Szalay *) +(* E U M E L 0 - T R A C E *) +(* Stand: 87-04-23 *) +(**************************************************************) + +LET packet area = 0, stack area = 1, text opd maxlen = 14, + stdds = 0, info lines = 4, crlf = ""13""10"", + beep = ""7"", carriage return = ""13"", cursor up = ""3"", + std charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456 + 7890<>.,:;-_+*!""�$%&/()=?'äÄöÖüÜ#^", + blanks = " ", + startindent = 10, indentincr = 2; +BOOL VAR trap set := FALSE, trapped, initial call := TRUE, quit, + single step := FALSE, protocol := FALSE, cond br follows, + prot just started := FALSE, prot stopped := TRUE, + users error := FALSE, users stpdis, prot operands := TRUE, + nontraceable found, errorstop processing := FALSE, + std procs traceable := id (1) = 4 (* processor = 68000 *), + longcall to trace flag; +INT VAR aret hi := 0, aret lo := 0, ic hi, ic lo, ic h, ic l, i, + atrap hi, atrap lo, nail1 hi, nail1 lo, nail2 hi, nail2 lo, + no of nails := 1, saved instr, saved instr w2, + saved1, saved1 w2, saved2, saved2 w2, + call to trace, call2 to trace, length of call to trace, + cmd, ilen, iclass, ilen1, iclass1, indentpos, + code addr modif, pbase, lbase, users lbase, + users errcode, users errline, old flags, flags, + module no, word, word1, word2, case, xpos, ypos, + cond br hi, cond br lo, maxlines:=12, lines, + opad hiword, opad hi, opad lo, opdds, br param, brcomp index, + ic off, opd ptr, int opd, text opd len, text opd tr len, + heap link, root word 2, no of results:=0, + no of nontraceables := 0, no of long nontraceables := 0, + pproc modno, pproc call, pproc ic lo := 0; +ROW 3 INT VAR res ds, res opadh, res opadl; +INT CONST lo byte mask := dec ("00ff"), + hi byte mask := dec ("ff00"), + branch param mask := dec ("87ff"), + opcode mask0 := dec ("83ff"), + opcode mask1 := dec ("7c00"), + bf mask1 := dec ("0040"), + ln br mask1 := dec ("7800"), + stpdis mask0 := dec ("ffbf"), + stpdis mask1 := dec ("0040"), + aritu mask1 := dec ("0010"), + error mask1 := dec ("0080"), + flags mask1 := dec ("00fc"), + mask 8000 := dec ("8000"), + mask 7fff := dec ("7fff"), + mask 7ffe := dec ("7ffe"), + mask 7f00 := dec ("7f00"), + mask 0400 := dec ("0400"), + mask fbff := dec ("fbff"), + mask 0007 := dec ("0007"), + mask fff8 := dec ("fff8"), + m l t start := dec ("0200"), + ln opcode := dec ("0000"), + br opcode := dec ("7000"), + rtn opcode := dec ("7f00"), + call opcode := dec ("7800"), + longcall opcode := dec ("ff78"), + pproc opcode := dec ("7f1e"), + estop opcode := dec ("7f4b"), + dstop opcode := dec ("7f4c"); +TEXT VAR buf, char, command, iname, iname1, ioplist, ioplist1, opd type, + opd buf, text opd, res types, users errmsg; + + +(********* following OPs and PROCs may be used by TRACE only ***********) + +PROC put (TEXT CONST a): + out (a); out (" ") +ENDPROC put; + +PROC putline (TEXT CONST a): + out (a); out (crlf) +ENDPROC putline; + + +(***********************************************************************) + +PROC eval br addr (INT CONST br para hi, br para lo, + INT VAR br addr hi, br addr lo): + br param := dsgetw (stdds, br para hi, br para lo) + AND branch param mask; + br addr hi := br para hi; + br addr lo := (br para lo AND hi byte mask) + OR (br param AND lo byte mask); + IF NOT br within page + THEN rotate (br param, 8); + br param := br param AND lo byte mask; + rotate (br param, 1); + IF br param > 255 + THEN br param INCR 1; + br param := br param AND 255 + FI; + rotate (br param, 8); + br addr lo INCR br param; + word := br addr lo AND hi byte mask; rotate (word, 8); + IF word >= code addr modif + THEN br addr lo DECR dec("1000") + FI + FI. + + br within page: + br param = (br param AND lo byte mask). + +ENDPROC eval br addr; + + +PROC eval opd addr (INT CONST ic offset): + word := dsgetw (stdds, ic hi, ic lo PLUS ic offset); + IF ic offset = 0 + THEN word := word AND opcode mask0 + FI; + IF global + THEN eval global addr + ELIF local + THEN eval local addr + ELSE eval ref addr + FI. + + global: (word AND mask 8000) = 0. + + local: (word AND 1) = 0. + + eval global addr: + opdds := stdds; + opad hi := packet area; + opad hiword := opad hi; + opad lo := pbase PLUS word; + perhaps put opad. + + eval local addr: + opdds := stdds; + opad hi := stack area; + opad hiword := opad hi; + word := word AND mask 7ffe; rotate (word, -1); + opad lo := users lbase PLUS word; + perhaps put opad. + + eval ref addr: + eval local addr; + opad hiword := dsgetw (stdds, stack area, opad lo PLUS 1); + opad lo := dsgetw (stdds, stack area, opad lo); + opdds := opad hiword AND hi byte mask; rotate (opdds, 8); + opad hi := opad hiword AND lo byte mask; + perhaps put opad. + +perhaps put opad: + (* put("opad=" CT hex(opad hiword) CT hex(opad lo)) *) . (*for tests*) + +ENDPROC eval opd addr; + + +PROC out int opd: + out (txt (int opd)); + IF int opd < 0 OR int opd > 9 + THEN out ("("); out (hex (int opd)); out (")") + FI +ENDPROC out int opd; + + +PROC fetch text opd: + root word 2 := dsgetw (opdds, opad hi, opad lo PLUS 1); + opd buf := subtext (blanks, 1, text opd maxlen + 2); + IF text on heap + THEN eval text from heap + ELSE eval text from root + FI; + convert nonstd chars; + text opd := """"; + text opd CAT subtext (opd buf, 1, text opd tr len); + text opd CAT """"; + IF text opd len > text opd tr len + THEN text opd CAT "(..."; + text opd CAT txt (text opd len); + text opd CAT "B)" + FI. + +text on heap: + (root word 2 AND lo byte mask) = 255. + +eval text from root: + text opd len := root word 2 AND lo byte mask; + text opd tr len := min (text opd len, text opd maxlen); + FOR i FROM 1 UPTO text opd tr len DIV 2 + 1 REP + replace (opd buf, i, dsgetw (opdds, opad hi, opad lo PLUS i)) + PER; + opd buf := subtext (opd buf, 2, text opd tr len + 1). + +eval text from heap: + rotate (root word 2, 8); + text opd len := root word 2 AND lo byte mask + OR (dsget2b (opdds, opad hi, opad lo PLUS 2) AND hi byte mask); + text opd tr len := min (text opd len, text opd maxlen); + heap link := dsgetw (opdds, opad hi, opad lo); + rotate (heap link, 15); + opad hi := heap link AND mask 0007; + opad lo := heap link AND mask fff8; + IF opdds = stdds THEN opad lo INCR 2 FI; + FOR i FROM 1 UPTO text opd tr len DIV 2 REP + replace (opd buf, i, dsgetw (opdds, opad hi, opad lo PLUS i)) + PER; + opd buf := subtext (opd buf, 1, text opd tr len). + +convert nonstd chars: + i := 1; + WHILE i <= LENGTH opd buf REP + char := opd buf SUB i; + IF pos (std charset, char) = 0 + THEN buf := txt (code (char)); + opd buf := subtext (opd buf, 1, i-1) CT + """" CT buf CT """" CT + subtext (opd buf, i+1); + i INCR 2 + length (buf); + ELIF char = """" + THEN opd buf := subtext (opd buf, 1, i-1) CT """""" CT + subtext (opd buf, i+1); + i INCR 2 + ELSE i INCR 1 + FI + PER; + text opd tr len := LENGTH opd buf. + +END PROC fetch text opd; + + +INT OP PLUS (INT CONST a, b): + unsigned arith; + a + b +ENDOP PLUS; + +PROC trace: + ROW 40 INT VAR dummy space for 20 pps; + get return address; + IF initial call + THEN save call to trace + ELSE process regular call + FI. + +get return address: + lbase:=local base; + users lbase := dsgetw (stdds, stack area, lbase); + aret lo := dsgetw (stdds, stack area, lbase+1); + word := dsgetw (stdds, stack area, lbase+2); + aret hi := word AND 3; + flags := word AND flags mask1; + ic hi := aret hi; ic lo := aret lo. + +save call to trace: + call to trace := dsgetw (stdds, aret hi, aret lo - 1); + IF (call to trace AND opcode mask1) = call opcode + THEN length of call to trace := 1; + longcall to trace flag := FALSE + ELSE call2 to trace := call to trace; + call to trace := dsgetw (stdds, aret hi, aret lo - 2); + length of call to trace := 2; + longcall to trace flag := TRUE; + putline ("WARNING: call to trace needs 2 words!!!") + FI; + initial call := FALSE. + +process regular call: + IF protocol + THEN pull old nails + ELSE indentpos := startindent; cond br follows := FALSE + FI; + get users error state and set modes for trace; + IF NOT errorstop processing + THEN normal processing of instructions + ELSE errorstop processing := FALSE + FI; + handle possible trace errors; + IF NOT protocol THEN restore users error state FI. + +normal processing of instructions: + trapped := trap set AND atrap lo = ic lo - length of call to trace + AND atrap hi = ic hi; + IF protocol THEN postprocess protocol FI; + IF trapped THEN handle trap FI; + IF protocol OR trapped + THEN ic lo DECR length of call to trace; + update icount on stack + FI; + IF trapped OR NOT protocol OR single step OR incharety <> "" + OR lines >= maxlines + THEN quit := FALSE; protocol := FALSE; single step := FALSE; lines := 0; + REP ask for next action; + execute command + UNTIL quit PER + FI; + IF protocol THEN protocol instruction and set nails FI. + +get users error state and set modes for trace: + signed arith; + IF NOT protocol + THEN users error := (flags AND error mask1) <> 0; + users stpdis := (flags AND stpdis mask1) <> 0; + IF users error + THEN save users error state; clear error; + line; putline ("trace called with user error " CT + txt (users errcode) CT ": " CT users errmsg) + ELSE disable stop + FI + ELIF is error + THEN IF first occurrence + THEN users error := TRUE; + save users error state; + line; + putline ("trace detected user error " CT + txt (users errcode) CT ": " CT users errmsg); + IF users stpdis + THEN out ("(stop disabled)") + ELSE errorstop processing := TRUE; stop op; + IF protocol THEN set nail1 FI + FI + ELSE line; + putline ("trace detected user error " CT + txt (error code) CT ": " CT error message); + out ("(ignored because of previous error(s)) "); + FI; + clear error + ELSE IF (flags AND stpdis mask1) = 0 + THEN set stpdis flag on stack; disable stop + FI + FI. + +first occurrence: NOT users error. + +save users error state: + users errmsg := error message; + users errline := error line; + users errcode := error code. + +handle possible trace errors: + IF is error + THEN line; + putline ("TRACE error " CT txt (error code) + CT " at line " CT txt (error line) + CT ": " CT error message); + clear error + FI. + +restore users error state: + IF users error + THEN error stop (users errcode, users errmsg); + users error := FALSE + FI; + restore users stpdis flag on stack. + +handle trap: + put trap message; + restore instruction; + trap set := FALSE. + +put trap message: + putline ("trap at address " CT txt (atrap hi) CT hex (atrap lo)). + +restore instruction: + dsputw (stdds, atrap hi, atrap lo, saved instr); + IF longcall to trace flag + THEN dsputw (stdds, atrap hi, atrap lo PLUS 1, saved instr w2) + FI. + +postprocess protocol: + IF prot operands THEN protocol result operands FI; + line; lines INCR 1; + IF cond br follows THEN protocol cond br op; cond br follows := FALSE FI. + +protocol cond br op: + outsubtext (blanks, 1, indentpos); + out (txt (cond br hi)); out (hex (cond br lo)); out (": "); + word := dsget2b (stdds, cond br hi, cond br lo); + IF (word AND bf mask1) <> 0 + THEN out ("BF ") + ELSE out ("BT ") + FI; + putline (hex (word)); lines INCR 1. + +pull old nails: + dsputw (stdds, nail1 hi, nail1 lo, saved1); + IF longcall to trace flag + THEN dsputw (stdds, nail1 hi, nail1 lo PLUS 1, saved1 w2) + FI; + IF no of nails = 2 + THEN dsputw (stdds, nail2 hi, nail2 lo, saved2); + IF longcall to trace flag + THEN dsputw (stdds, nail2 hi, nail2 lo PLUS 1, saved2 w2) + FI; + no of nails := 1 + FI. + +update icount on stack: + dsputw (stdds, 1, lbase + 1, ic lo). + +ask for next action: + putline (""15"" CT + "TRACE: step, more, trap, regs, lines, info, disasm, or quit"14""); + inchar (command). + +execute command: + cmd := pos ("tidqmsrl", command); + SELECT cmd OF + CASE 1: set address trap; prot stopped := TRUE + CASE 2: info (stdds, ic hi, ic lo, info lines); prot stopped := TRUE + CASE 3: disasm (ic hi, ic lo); prot stopped := TRUE + CASE 4: quit := TRUE; prot stopped := TRUE + CASE 5: initialize protocol; single step := FALSE; + quit := TRUE + CASE 6: initialize protocol; single step := TRUE; + quit := TRUE + CASE 7: show registers; prot stopped := TRUE + CASE 8: set new line count; prot stopped := TRUE + OTHERWISE out(beep CT carriage return CT cursor up) + ENDSELECT. + +set new line count: + out ("lines="); gethex (buf); maxlines := dec (buf). + +set address trap: + IF trap set + THEN putline ("current trap address: " CT txt (atrap hi) CT hex (atrap lo)); + out ("type <CR> to confirm, or ") + ELSE out ("type ") + FI; + out ("new trap addr ("); + IF std procs traceable THEN out ("2") ELSE out ("3") FI; + out ("0000...3ffff), or 0 for no trap:"); + gethex (buf); + IF buf <> "" + THEN IF trap set THEN restore instruction; trap set := FALSE FI; + buf:="0000" CT buf; + atrap hi := dec (subtext (buf, LENGTH buf-7, LENGTH buf-4)); + atrap lo := dec (subtext (buf, LENGTH buf-3)); + IF atrap hi=3 OR atrap hi=2 AND std procs traceable + THEN saved instr := dsgetw (stdds, atrap hi, atrap lo); + dsputw (stdds, atrap hi, atrap lo, call to trace); + IF longcall to trace flag + THEN saved instr w2 := dsgetw (stdds, atrap hi, atrap lo PLUS 1); + dsputw (stdds, atrap hi, atrap lo PLUS 1, call2 to trace); + FI; + trap set := TRUE + ELIF NOT (atrap hi=0 AND atrap lo=0) + THEN out (beep); putline ("address not in above range") + FI + ELSE IF NOT trap set THEN out (beep); putline ("no trap specified") FI + FI. + +initialize protocol: + pbase := dsgetw (stdds, stack area, lbase + 2) AND hi byte mask; + code addr modif := dsgetw (stdds, stack area, lbase + 3) + AND lo byte mask; + set stpdis flag on stack; + prot just started := TRUE; + protocol := TRUE. + +set stpdis flag on stack: + word := dsgetw (stdds, stack area, lbase + 2); + dsputw (stdds, stack area, lbase + 2, word OR stpdis mask1). + +restore users stpdis flag on stack: + word := dsgetw (stdds, stack area, lbase + 2) AND stpdis mask0; + IF users stpdis THEN word := word OR stpdis mask1 FI; + dsputw (stdds, stack area, lbase + 2, word). + +protocol instruction and set nails: + protocol instr; + SELECT iclass OF + CASE 0: standard ops + CASE 1: cond branch ops + CASE 2: branch ops + CASE 3: comp branch op + CASE 4: call op + CASE 5: exec op + CASE 6: pcall op + CASE 7: return ops + CASE 8: penter op + CASE 9: pp ops + CASE 10: line ops + CASE 11: stop ops + CASE 12: ke op + CASE 13: clrerr op + OTHERWISE: wrong ops + ENDSELECT; + IF protocol THEN set nail1 FI. + +protocol instr: + word1 := dsgetw (stdds, ic hi, ic lo); + disa (ic hi, ic lo, iname, ioplist, ilen, iclass); + protocol this instr. + +protocol this instr: + possibly delete command line; + outsubtext (blanks, 1, indentpos); + ic h := ic hi; ic l := ic lo; + out (txt (ic h)); out (hex (ic l)); out (": "); + out (iname); out (" "); + IF ilen > 0 + THEN FOR i FROM 1 UPTO ilen + REP out (hex (dsget2b (stdds, ic h, ic l))); out (" "); + ic l INCR 1 PER + ELSE out (hex (dsget2b (stdds, ic h, ic l))); out (" ") + FI; + IF prot operands THEN protocol operands FI. + +possibly delete command line: + IF prot just started + THEN prot just started := FALSE; + IF prot stopped + THEN prot stopped := FALSE + ELSE delete command line + FI + FI. + +delete command line: + get cursor (xpos, ypos); cursor (1, ypos-1); out(""4""). + +protocol operands: + out (" "); + IF (word1 AND mask 7f00) = mask 7f00 + THEN ic off := 1 + ELSE ic off := 0 + FI; + res types := ""; + no of results := 0; + FOR opd ptr FROM 1 UPTO LENGTH ioplist REP + opd type := ioplist SUB opd ptr; + IF opd type <> " " + THEN case := pos ("irtdpahIRTDPEH", opd type); + IF case > 0 + THEN eval opd addr (ic off); + SELECT case OF + CASE 1: prot int rd opd + CASE 2: prot real rd opd + CASE 3: prot text rd opd + CASE 4: prot dataspace rd opd + CASE 5: prot task rd opd + CASE 6: prot virt addr + CASE 7: prot hex rd opd + OTHERWISE save res type + ENDSELECT + FI; + ic off INCR 1 + FI + UNTIL opd type = " " PER. + +save res type: + res types CAT opd type; + no of results INCR 1; + res ds (no of results) := opdds; + res opadh (no of results) := opad hi; + res opadl (no of results) := opad lo. + +protocol result operands: + FOR opd ptr FROM 1 UPTO no of results REP prot this result PER. + +prot this result: + opdds := res ds (opd ptr); + opad hi := res opadh (opd ptr); + opad lo := res opadl (opd ptr); + opd type := res types SUB opd ptr; + SELECT pos ("IRTDPEH", opd type) OF + CASE 1: prot int result + CASE 2: prot real result + CASE 3: prot text result + CASE 4: prot dataspace result + CASE 5: prot task result + CASE 6: prot eva result + CASE 7: prot hex result + OTHERWISE out (opd type CT "(???) ") + ENDSELECT. + +prot int rd opd: + int opd := dsgetw (opdds, opad hi, opad lo); + out (">"); out int opd; out (" "). + +prot int result: + int opd := dsgetw (opdds, opad hi, opad lo); + out int opd; out ("> "). + +prot hex rd opd: + int opd := dsgetw (opdds, opad hi, opad lo); + out (">"); out (hex (int opd)); out (" "). + +prot hex result: + int opd := dsgetw (opdds, opad hi, opad lo); + out (hex (int opd)); out ("> "). + +prot real rd opd: + out (">"); + out (hex (dsget2b (opdds, opad hi, opad lo))); + out (hex (dsget2b (opdds, opad hi, opad lo PLUS 1))); + out (hex (dsget2b (opdds, opad hi, opad lo PLUS 2))); + out (hex (dsget2b (opdds, opad hi, opad lo PLUS 3))); out (" "). + +prot real result: + out (hex (dsget2b (opdds, opad hi, opad lo))); + out (hex (dsget2b (opdds, opad hi, opad lo PLUS 1))); + out (hex (dsget2b (opdds, opad hi, opad lo PLUS 2))); + out (hex (dsget2b (opdds, opad hi, opad lo PLUS 3))); + out ("> "). + +prot text rd opd: + fetch text opd; + out (">"); out (text opd); out (" "). + +prot text result: + fetch text opd; + out (text opd); out ("> "). + +prot dataspace rd opd: + int opd := dsgetw (opdds, opad hi, opad lo); + out (">"); out (hex (int opd)); out (" "). + +prot dataspace result: + int opd := dsgetw (opdds, opad hi, opad lo); + out (hex (int opd)); out ("> "). + +prot task rd opd: + out (">"); out (hex (dsgetw (opdds, opad hi, opad lo))); + out ("/"); out (hex (dsgetw (opdds, opad hi, opad lo PLUS 1))); out (" "). + +prot task result: + out (hex (dsgetw (opdds, opad hi, opad lo))); out ("/"); + out (hex (dsgetw (opdds, opad hi, opad lo PLUS 1))); out ("> "). + +prot virt addr: + out (">"); out (hex (opad hiword)); out (hex (opad lo)); out (" "). + +prot eva result: + out (hex (dsgetw (opdds, opad hi, opad lo PLUS 1))); + out (hex (dsgetw (opdds, opad hi, opad lo))); + out (">"). + +standard ops: + nail1 hi := ic hi; nail1 lo := ic lo PLUS ilen. + +set nail1: + saved1 := dsgetw (stdds, nail1 hi, nail1 lo); + dsputw (stdds, nail1 hi, nail1 lo, call to trace); + IF longcall to trace flag + THEN saved1 w2 := dsgetw (stdds, nail1 hi, nail1 lo PLUS 1); + dsputw (stdds, nail1 hi, nail1 lo PLUS 1, call2 to trace) + FI. + +set nail2: + saved2 := dsgetw (stdds, nail2 hi, nail2 lo); + dsputw (stdds, nail2 hi, nail2 lo, call to trace); + IF longcall to trace flag + THEN saved2 w2 := dsgetw (stdds, nail2 hi, nail2 lo PLUS 1); + dsputw (stdds, nail2 hi, nail2 lo PLUS 1, call2 to trace) + FI. + +cond branch ops: + cond br follows := TRUE; + cond br hi := ic hi; cond br lo := ic lo PLUS ilen; + nail1 hi := cond br hi; nail1 lo := cond br lo PLUS 1; + eval br addr (cond br hi, cond br lo, nail2 hi, nail2 lo); + no of nails := 2; set nail2. + +branch ops: + eval br addr (ic hi, ic lo, nail1 hi, nail1 lo). + +comp branch op: + eval opd addr (1); + brcomp index := dsgetw (stdds, opad hi, opad lo); + IF brcomp index < 0 OR brcomp index >= dsgetw (stdds, ic hi, ic lo PLUS 2) + THEN brcomp index := -1 + FI; + nail1 hi := ic hi; + nail1 lo := ic lo PLUS ilen PLUS brcomp index PLUS 1. + +call op: + eval module no; + call or exec. + +call or exec: + IF module no < 1280 AND NOT std procs traceable + THEN possibly append proc head; + out (" (*n.t.*)"); + nontraceable found := TRUE + ELSE check for nontraceable + FI; + IF NOT nontraceable found + THEN restore users stpdis flag on stack; + get proc address via module link table; + possibly append proc head; + indentpos INCR indentincr; + nail1 hi := ic hi; nail1 lo := ic lo PLUS 1 (*nail behind head*) + ELIF call to trace found + THEN skip instruction + ELIF possibly call to bool proc + THEN cond branch ops + ELSE standard ops + FI. + +eval module no: + IF word1 = longcall opcode + THEN module no := dsgetw (stdds, ic hi, ic lo PLUS 1) + ELSE module no := word1 AND opcode mask0; + IF (module no AND mask 8000) <> 0 + THEN module no := module no AND mask 7fff OR mask 0400 + FI + FI. + +check for nontraceable: + nontraceable found := FALSE; + IF word1 = longcall opcode + THEN word2 := dsgetw (stdds, ic hi, ic lo PLUS 1); + FOR j FROM 1 UPTO no of long nontraceables REP + IF word 2 = call2 to nontraceables (j) + THEN out (names of long nontraceables (j)); + nontraceable found := TRUE + FI + UNTIL nontraceable found PER + ELSE FOR j FROM 1 UPTO no of nontraceables REP + IF word1 = calls to nontraceables (j) + THEN out (names of short nontraceables (j)); + nontraceable found := TRUE + FI + UNTIL nontraceable found PER + FI. + +get proc address via module link table: + IF module no < 1280 THEN ic hi := 2 ELSE ic hi := 3 FI; + ic lo := dsgetw (stdds, packet area, m l t start + module no). + +possibly append proc head: + out (proc head (module no)). + +skip instruction: + ic lo INCR ilen; update icount on stack; + nail1 hi := ic hi; nail1 lo := ic lo. + +possibly call to bool proc: + word := dsgetw (stdds, ic hi, ic lo PLUS ilen) AND ln br mask1; + word = ln opcode OR word = br opcode. + +exec op: + eval opd addr (1); + module no := dsgetw (stdds, opad hi, opad lo); + call or exec. + +pcall op: + eval opd addr (1); + IF opad lo = 2 AND NOT std procs traceable + THEN out (" (*n.t.*)"); + nontraceable found := TRUE + ELSE check for nontraceable pproc + FI; + IF NOT nontraceable found + THEN restore users stpdis flag on stack; + possibly append proc head for pproc; + indentpos INCR indentincr; + nail1 hi := opad hi; nail1 lo := opad lo PLUS 1 (*nail behind head*) +(*ELIF word1 = call to trace + THEN skip instruction *) + ELIF possibly call to bool proc + THEN cond branch ops + ELSE standard ops + FI. + +check for nontraceable pproc: + nontraceable found := FALSE; + IF opad lo = pproc ic lo + THEN FOR j FROM 1 UPTO no of nontraceables REP + IF pproc call = calls to nontraceables (j) + THEN out (names of nontraceables (j)); + nontraceable found := TRUE + FI + UNTIL nontraceable found PER + ELSE nontraceable found := TRUE (*to be on the secure side*) + FI. + +possibly append proc head for pproc: + IF opad lo = pproc ic lo + THEN out (proc head (pproc modno)) + FI. + +return ops: + fetch eumel0 regs of caller from users stack; + out ("--> "); + put users flags; + IF (old flags AND aritu mask1) <> 0 + THEN put ("ARITU") + ELSE put ("ARITS") + FI; + IF nontraceable caller + THEN line; putline ("trace ended by returning to nontraceable caller"); + protocol := FALSE; prot stopped := TRUE + ELIF users error AND NOT users stpdis + THEN stop op + ELSE set nail for return ops + FI. + +set nail for return ops: + IF word1 = rtn opcode + THEN nail1 hi := ic hi; nail1 lo := ic lo + ELSE nail1 hi := ic hi; nail1 lo := ic lo PLUS 1; + eval br addr (ic hi, ic lo, nail2 hi, nail2 lo); + no of nails := 2; set nail2 + FI. + +penter op: + pbase := word1 AND lo byte mask; rotate (pbase, 8); + standard ops. + +line ops: + standard ops. + +stop ops: + IF word1 = estop opcode + THEN users stpdis := FALSE; + IF users error THEN stop op ELSE standard ops FI + ELIF word1 = dstop opcode + THEN users stpdis := TRUE; standard ops + ELSE stop op + FI. + +clrerr op: + users error := FALSE; standard ops. + +ke op: + skip instruction; + line; putline ("INFO: ke"); + info (stdds, ic hi, ic lo, info lines); + single step := TRUE. + +pp ops: + save modno and ic lo if pproc; + look at next instr; + WHILE iclass1 = 9 REP + ic lo INCR ilen; iname := iname1; ioplist := ioplist1; + ilen := ilen1; iclass := iclass1; + line; lines INCR 1; + protocol this instr; + save modno and ic lo if pproc; (*only the first one will be saved!!!*) + look at next instr + PER; + standard ops. + +save modno and ic lo if pproc: + IF word1 = pproc opcode + THEN pproc modno := dsgetw (stdds, ic hi, ic lo PLUS 1); + IF pproc modno < 256 + THEN putline ("*** this looks like a compiler error ***"); + protocol := FALSE; prot stopped := TRUE; users error := TRUE; + users errcode := 0; users errmsg := ("maybe a compiler error"); + LEAVE normal processing of instructions + ELIF (pproc modno AND mask 0400) <> 0 + THEN word := (pproc modno AND mask fbff) OR mask 8000 + ELSE word := pproc modno + FI; + pproc call := word OR opcode mask1; + pproc ic lo := dsgetw (stdds, packet area, m l t start + pproc modno) + FI. + +look at next instr: + word1 := dsgetw (stdds, ic hi, ic lo PLUS ilen); + disa (ic hi, ic lo PLUS ilen, iname1, ioplist1, ilen1, iclass1). + +wrong ops: + putline ("**** das kann ich (noch) nicht!!! ***"); + info (stdds, ic hi, ic lo, info lines); + protocol := FALSE. + +show registers: + pbase := dsgetw (stdds, stack area, lbase + 2) AND hi byte mask; + code addr modif := dsgetw (stdds, stack area, lbase + 3) + AND lo byte mask; + putline ("----------------- EUMEL0-registers: ------------------"); + put ("icount=" CT txt (ic hi) CT hex (ic lo) CT + " lbase=1" CT hex (users lbase) CT " pbase=" CT hex (pbase)); + put users flags; + IF (flags AND aritu mask1) <> 0 + THEN putline ("ARITU") + ELSE putline ("ARITS") + FI. + +put users flags: + IF users stpdis + THEN put ("STPDIS") + ELSE put ("STOPEN") + FI; + IF users error + THEN put ("ERROR") + ELSE put ("NOERR") + FI. + +ENDPROC trace; + + +PROC stop op: + line; + suppress result protocolling; + REP outsubtext (blanks, 1, indentpos); + fetch eumel0 regs of caller from users stack; + out ("stop/error induced return to addr "); + out (txt (ic hi)); out (hex (ic lo)); + IF users stpdis + THEN putline (" (STPDIS)") + ELSE putline (" (STOPEN)") + FI; + lines INCR 1; + IF nontraceable caller + THEN putline ("trace ended by returning to nontraceable caller"); + protocol := FALSE; prot stopped := TRUE + ELIF users stpdis + THEN copy stack of disabled caller to tracers stack + ELSE users lbase := dsgetw (stdds, stack area, users lbase) + FI + UNTIL users stpdis OR NOT protocol PER; + nail1 hi := ic hi; nail1 lo := ic lo. + +suppress result protocolling: + no of results := 0. + +copy stack of disabled caller to tracers stack: + FOR i FROM 1 UPTO 4 REP + word := dsgetw (stdds, stack area, users lbase + i - 1); + dsputw (stdds, stack area, lbase + i - 1, word) + PER. + +ENDPROC stop op; + + +i n i t i a l i z e t r a c e. + +nontraceable caller: + ic hi = 2 AND NOT std procs traceable + OR (old flags AND aritu mask1) <> 0 AND (flags AND aritu mask1) = 0. + +fetch eumel0 regs of caller from users stack: + indentpos DECR indentincr; + ic lo := dsgetw (stdds, stack area, users lbase + 1); + word := dsgetw (stdds, stack area, users lbase + 2); + ic hi := word AND 3; + old flags := word AND flags mask1; + users stpdis := (old flags AND stpdis mask1) <> 0; + pbase := word AND hi byte mask; + code addr modif := dsgetw (stdds, stack area, users lbase + 3) + AND lo byte mask. + +initialize trace: + LET maxno of nontraceables = 20; + INT VAR int, j; + TEXT VAR text; + ROW maxno of nontraceables TEXT VAR names of nontraceables; + ROW maxno of nontraceables TEXT VAR names of short nontraceables; + ROW maxno of nontraceables TEXT VAR names of long nontraceables; + ROW maxno of nontraceables INT VAR calls to nontraceables; + ROW maxno of nontraceables INT VAR call2 to nontraceables; + + putline("initializing ""trace"" ..."); + names of nontraceables (1) := "disa (I,I,T,T,I,I) (*n.t.*)"; + names of nontraceables (2) := "disasm (I,I) (*n.t.*)"; + names of nontraceables (3) := "info (I,I,I,I) (*n.t.*)"; + names of nontraceables (4) := "dec (T) (*n.t.*)"; + names of nontraceables (5) := "hex (I) (*n.t.*)"; + names of nontraceables (6) := "dsget2b (I,I,I) (*n.t.*)"; + names of nontraceables (7) := "trace (*ignored*)"; + trace; (* initialize 'call to trace', 'ic hi' and 'ic lo' *) + IF FALSE THEN + disa (int, int, text, text, int, int); + disasm (int, int); + info (int, int, int, int); + int := dec (text); + text := hex (int); + int := dsget2b (int, int, int); + trace (****** must be the last one !!! *****) + FI; + FOR j FROM 1 UPTO maxno of nontraceables REP + REP ic lo INCR 1; + word1 := dsgetw (stdds, ic hi, ic lo) + UNTIL call opcode found PER; + IF word1 <> longcall opcode + THEN no of nontraceables INCR 1; + calls to nontraceables (no of nontraceables) := word1; + names of short nontraceables (no of nontraceables) := + names of nontraceables (j) + ELSE no of long nontraceables INCR 1; + word2 := dsgetw (stdds, ic hi, ic lo PLUS 1); ic lo INCR 1; + call2 to nontraceables (no of long nontraceables) := word2; + names of long nontraceables (no of long nontraceables) := + names of nontraceables (j) + FI + UNTIL call to trace found + OR no of nontraceables = maxno of nontraceables + OR no of long nontraceables = maxno of nontraceables PER; + putline ("""trace"" initialized:"); + putline (" " CT txt (no of nontraceables) + CT " nontraceable shortcalls"); + putline (" " CT txt (no of long nontraceables) + CT " nontraceable longcalls"); + IF no of nontraceables = maxno of nontraceables + OR no of long nontraceables = maxno of nontraceables + THEN errorstop ("too many nontraceables") + ELSE test trace + FI. + +call opcode found: + (word1 AND opcode mask1) = call opcode OR word1 = longcall opcode. + +call to trace found: + IF word1 = call to trace + THEN IF longcall to trace flag + THEN word2 = call2 to trace + ELSE TRUE + FI + ELSE FALSE + FI. + +test trace:. + +END PACKET trace; + |