home *** CD-ROM | disk | FTP | other *** search
- (*-------------------------------------------------------------------------*)
- (* *)
- (* Amiga Oberon Library Module: Debug Date: 02-Nov-92 *)
- (* *)
- (* © 1992 by Fridtjof Siebert *)
- (* *)
- (*-------------------------------------------------------------------------*)
-
- (*-------------------------------------------------------------------------*)
- (* *)
- (* This Module is not meant to be used by application programs! It will *)
- (* be imported automatically when you compile a module using option '-g'. *)
- (* *)
- (*-------------------------------------------------------------------------*)
-
- (*-------------------------------------------------------------------------*)
- (* *)
- (* Dieses Modul wird beim Compilieren mit Option '-g' automatisch *)
- (* importiert. Es sollte nicht in eigenen Programmen verwendet werden!!! *)
- (* *)
- (*-------------------------------------------------------------------------*)
-
- MODULE Debug;
-
- IMPORT e * := Exec,
- es := ExecSupport,
- rq := Requests,
- d := Dos,
- ol := OberonLib,
- sys := SYSTEM;
-
-
- CONST
- ODebugPort = "ODebug_V1.0_HereIAm";
- (* $IF English THEN *)
- ODebugAktiv1 = "ODebug ist currently active. Select";
- ODebugAktiv2 = "'Run' to start without using ODebug.";
- StartODebug1 = "Please start ODebug first, or select";
- StartODebug2 = "'Run' to start without using ODebug.";
- Run = " Run ";
- Retry = " Retry ";
- Cancel = " Cancel ";
- oom = "Out of memory!";
- (* $ELSE *)
- ODebugAktiv1 = "ODebug ist gerade aktiv. 'Run' startet";
- ODebugAktiv2 = "das Programm ohne ODebug.";
- StartODebug1 = "Bitte zuerst ODebug starten,";
- StartODebug2 = "oder 'Run' selektieren.";
- Run = " Run ";
- Retry = " Retry ";
- Cancel = " Cancel ";
- oom = "Nicht genügend Speicher vorhanden!";
- (* $END *)
-
- TYPE
- String * = ARRAY 256 OF CHAR;
- StringPtr * = UNTRACED POINTER TO String;
- Breaks = UNTRACED POINTER TO ARRAY MAX(LONGINT) DIV 6 OF STRUCT
- module : StringPtr;
- statement: INTEGER;
- END;
- DebugMsgPtr = UNTRACED POINTER TO DebugMsg;
- DebugMsg = STRUCT (msg: e.Message)
- action: INTEGER; (* siehe unten *)
- module: StringPtr; (* Name des aktiven Moduls *)
- statement: INTEGER; (* nächstes Statment *)
- guru: LONGINT; (* Fehler bei action=runtimeerr (s.u.) *)
- odebugAlive: BOOLEAN;(* Lebt ODebug() noch? *)
- sprint: BOOLEAN; (* Sprint-Modus? *)
- procedure: INTEGER; (* Prozedur (bei action=newproc) *)
- varbase: e.ADDRESS; (* Basisadr. der Variablen (newproc) *)
- mod: INTEGER; (* Modulenummer bei (bei newmod) *)
- runQuick: BOOLEAN; (* RunQuick-Modus? *)
- anzBreaks: LONGINT; (* Anzahl der Brkpoints (bei runQuick) *)
- breakPoints: Breaks; (* Breakpointliste (bei runQuick) *)
- END;
-
- DebugPortPtr = UNTRACED POINTER TO DebugPort;
- DebugPort = STRUCT (port: e.MsgPort)
- inuse: BOOLEAN;
- END;
-
-
- CONST
- (* DebugMsg.action *)
- tracing = 0; (* normales Trace (jeweils vor dem Statement) *)
- hereweare = 1; (* Begrüßung *)
- cheerio = 2; (* Verabschiedung *)
- runtimeerr= 3; (* Laufzeitfehler! *)
- newproc = 4; (* Neue Prozedur beginnt *)
- endproc = 5; (* Prozedur beendet *)
- newmod = 6; (* Varbase von importiertem Modul wird übergeben *)
- varbase = 7; (* Varbase von debuggtem Modul wird übergeben *)
-
- VAR
- Me: d.ProcessPtr;
- dbPort : e.MsgPortPtr;
- replyPort: e.MsgPortPtr;
- msg: DebugMsgPtr;
- Module* : StringPtr; (* In welchem Modul sind wir gerade? *)
-
- i: LONGINT; (* Zäher für Trace() (global, damit keine Localen Vars nötig sind) *)
-
-
- (* $StackChk- *)
-
- TYPE
- TrapInfoType = STRUCT
- trap: LONGINT;
- ssw: INTEGER;
- adr: LONGINT;
- ir: INTEGER;
- sr: INTEGER;
- pc: LONGINT;
- END;
-
- VAR
- TrapInfo: TrapInfoType;
-
-
- PROCEDURE TrapHandler;
- BEGIN
- IF msg.odebugAlive & (Me=e.exec.thisTask) THEN
- msg.action := runtimeerr;
- msg.guru := TrapInfo.trap;
- e.PutMsg(dbPort,msg);
- REPEAT
- e.WaitPort(replyPort);
- UNTIL e.GetMsg(replyPort)=msg;
- END;
- HALT(20);
- END TrapHandler;
-
-
- PROCEDURE * TrapProc; (* $NilChk- *)
-
- BEGIN
- (* $IFNOT SmallData *)
- sys.INLINE(0588FH); (* ADDQ.L #4,A7 *)
- (* $END *)
- ol.SetA5;
- sys.SETREG(8,TrapHandler);
- sys.SETREG(9,sys.ADR(TrapInfo));
- sys.INLINE(
- 0201FH, (* move.l (A7)+,D0 *)
- 02280H, (* move.l D0,(A1) *)
- 0B07CH,00003H, (* cmp #3,D0 *)
- 06208H, (* bhi.s l *)
- 0235FH,00004H, (* move.l (a7)+, 4(a1) *)
- 0235FH,00008H, (* move.l (a7)+, 8(a1) *)
- 03357H,0000CH, (* l: move.w (a7) ,12(a1) *)
- 0236FH,00002H,0000EH, (* move.l 2(a7),14(a1) *)
- 02F48H,00002H, (* move.l A0, 2(A7) *)
- 04E73H); (* rte *)
- END TrapProc;
-
-
-
- PROCEDURE Trace*(stat: INTEGER); (* $SaveAllRegs+ *)
- BEGIN
- IF msg.odebugAlive & (Me=e.exec.thisTask) THEN
- msg.statement := stat;
- msg.module := Module;
- IF msg.sprint THEN RETURN END;
- IF msg.runQuick THEN
- i := msg.anzBreaks;
- LOOP
- DEC(i);
- IF i<0 THEN RETURN END;
- IF (stat =msg.breakPoints[i].statement) &
- (Module=msg.breakPoints[i].module ) THEN
- EXIT;
- END;
- END;
- END;
- Me.task.trapCode := TrapProc;
- msg.action := tracing;
- e.PutMsg(dbPort,msg);
- REPEAT
- e.WaitPort(replyPort);
- UNTIL e.GetMsg(replyPort)=msg;
- IF ~ msg.odebugAlive THEN HALT(20) END;
- END;
- END Trace;
-
-
- PROCEDURE NewProc*(vars: e.ADDRESS; proc: INTEGER); (* $SaveAllRegs+ *)
- BEGIN
- IF msg.odebugAlive & ~ msg.sprint & (Me=e.exec.thisTask) THEN
- msg.action := newproc;
- msg.module := Module;
- msg.procedure := proc;
- msg.varbase := vars;
- e.PutMsg(dbPort,msg);
- REPEAT
- e.WaitPort(replyPort);
- UNTIL e.GetMsg(replyPort)=msg;
- IF ~ msg.odebugAlive THEN HALT(20) END;
- END;
- END NewProc;
-
-
- PROCEDURE EndProc*; (* $SaveAllRegs+ *)
- BEGIN
- IF msg.odebugAlive & ~ msg.sprint & (Me=e.exec.thisTask) THEN
- msg.action := endproc;
- msg.module := Module;
- e.PutMsg(dbPort,msg);
- REPEAT
- e.WaitPort(replyPort);
- UNTIL e.GetMsg(replyPort)=msg;
- IF ~ msg.odebugAlive THEN HALT(20) END;
- END;
- END EndProc;
-
-
- PROCEDURE NewMod*(mod: INTEGER; vars: e.ADDRESS); (* $SaveAllRegs+ *)
- BEGIN
- IF msg.odebugAlive & ~ msg.sprint & (Me=e.exec.thisTask) THEN
- msg.action := newmod;
- msg.module := Module;
- msg.mod := mod;
- msg.varbase := vars;
- e.PutMsg(dbPort,msg);
- REPEAT
- e.WaitPort(replyPort);
- UNTIL e.GetMsg(replyPort)=msg;
- IF ~ msg.odebugAlive THEN HALT(20) END;
- END;
- END NewMod;
-
-
- PROCEDURE VarBase*(vars: e.ADDRESS); (* $SaveAllRegs+ *)
- BEGIN
- (* TrapProc nochmal setzen, da sie evtl. von anderem Modul (NoGuru)
- auch gesetzt wurde. *)
- IF msg.odebugAlive & (Me=e.exec.thisTask) THEN
- Me.task.trapCode := TrapProc;
- msg.action := varbase;
- msg.module := Module;
- msg.varbase := vars;
- e.PutMsg(dbPort,msg);
- REPEAT
- e.WaitPort(replyPort);
- UNTIL e.GetMsg(replyPort)=msg;
- IF ~ msg.odebugAlive THEN HALT(20) END;
- END;
- END VarBase;
-
-
- BEGIN
-
- Me := sys.VAL(d.ProcessPtr,ol.Me);
-
- INCL(ol.MemReqs,e.public);
- NEW(msg);
- EXCL(ol.MemReqs,e.public);
- rq.Assert(msg#NIL,oom);
- replyPort := es.CreatePort("",0); rq.Assert(replyPort#NIL,oom);
- msg.msg.replyPort := replyPort;
- msg.msg.length := sys.SIZE(DebugMsg);
- msg.odebugAlive := TRUE;
-
- LOOP
- e.Forbid;
- dbPort := e.FindPort(ODebugPort);
- IF dbPort#NIL THEN
- WITH dbPort : DebugPort DO
- IF dbPort.inuse THEN
- dbPort := NIL;
- e.Permit;
- msg.odebugAlive := FALSE;
- IF rq.Request(ODebugAktiv1,ODebugAktiv2,Run,Cancel) THEN EXIT
- ELSE HALT(20);
- END;
- END;
- dbPort.inuse := TRUE;
- END;
- e.Permit;
- EXIT
- END;
- e.Permit;
- IF ~ rq.Request(StartODebug1,StartODebug2,Retry,Run) THEN
- msg.odebugAlive := FALSE;
- EXIT
- END;
- END;
-
- IF msg.odebugAlive THEN
- msg.action := hereweare;
- e.PutMsg(dbPort,msg);
- REPEAT
- e.WaitPort(replyPort);
- UNTIL e.GetMsg(replyPort)=msg;
- END;
-
- CLOSE
-
- IF dbPort#NIL THEN
- IF msg.odebugAlive THEN
- msg.action := cheerio;
- e.PutMsg(dbPort,msg);
- REPEAT
- e.WaitPort(replyPort);
- UNTIL e.GetMsg(replyPort)=msg;
- END;
- END;
-
- IF replyPort#NIL THEN es.DeletePort(replyPort) END;
-
- END Debug.
-
-
-
-