(* Einzigste Änderung: Terminal -> NewInOut *) IMPLEMENTATION MODULE Break; (* 28.7.90/bp A4 in tc.exceptData merken! *) (*$ LargeVars:=FALSE StackChk:=FALSE RangeChk:=FALSE OverflowChk:=FALSE Volatile:=FALSE NilChk:=FALSE StackParms:=FALSE LongAlign:=TRUE *) FROM SYSTEM IMPORT ADR, LONGSET, CAST, SETREG, REG, ASSEMBLE; FROM Arts IMPORT Terminate, BreakPoint, thisTask; FROM ExecD IMPORT sigDos; FROM ExecL IMPORT SetSignal, SetExcept, Forbid,Permit, GetMsg, WaitPort; FROM DosD IMPORT ProcessPtr, ctrlC, ctrlD, ctrlE, ctrlF; FROM NewInOut IMPORT WriteString; VAR (* Alles Langworte, sollten auch auf Langwortgrenze! *) actualBreak: LONGSET; process: ProcessPtr; oldExceptCode: PROC; oldExceptData:LONGINT; PROCEDURE SetBreakMode(when:LONGSET); BEGIN actualBreak := when*FullBreak; END SetBreakMode; PROCEDURE ExitBreak; BEGIN WriteString(BreakText); Terminate; END ExitBreak; PROCEDURE TestBreak; BEGIN (* ask and clear all *) IF SetSignal(NoBreak,actualBreak)*actualBreak # NoBreak THEN ExitBreak() END; END TestBreak; PROCEDURE GetBreak():LONGSET; BEGIN (* ask and clear all *) RETURN SetSignal(NoBreak,actualBreak)*actualBreak; END GetBreak; (* * In einer Exception sind die Register zerstört, leider auch A4! * In einer NICHTresidenten Version kann mittels H- A4 neu geladen * werden. In einer RESIDENTEN Version ist das nicht möglich, da * A4 auf einen allozierten Speicherbereich zeigt und die Adresse * dieses Bereiches auf keine Weise erreichbar ist. * Deshalb merken wir uns A4 in task^.exceptData! *) (*$ SaveA4:=TRUE *) (* VERY IMPORTANT, save A4!!! *) PROCEDURE ExceptionHandler; VAR inDos: BOOLEAN; oldD0: LONGINT; BEGIN oldD0:=REG(0); ASSEMBLE( MOVE.L A1,A4 (* sonst kein Exec oder process^. ...! *) END); Forbid; (* exclusive access to signals! *) WITH process^.task DO inDos:=sigDos IN (sigWait/sigRecvd); (* sigWait / sigReceived X=sigDos IN, 0 not * 0 0 no Dos call pending, should be no problem * X 0 in Dos waiting for answer, return quietly * 0 X in Dos(?) answer just received, curious * X X just finished dos call, remove message *) END; Permit; IF ~inDos THEN (* get any pending message *) SETREG(0,GetMsg(ADR(process^.msgPort))); ExitBreak; END; SETREG(0,oldD0) (* reenable exception -> [RKM] *) END ExceptionHandler; PROCEDURE InstallException; BEGIN Forbid; process^.task.exceptCode:=ExceptionHandler; process^.task.exceptData:=REG(4+8); SETREG(0,SetSignal(NoBreak,FullBreak)); (* alle löschen! *) SETREG(0,SetExcept(CBreak,CBreak)); Permit; END InstallException; PROCEDURE RemoveException; BEGIN Forbid; SETREG(0,SetExcept(NoBreak,CBreak)); process^.task.exceptCode:=oldExceptCode; process^.task.exceptData:=oldExceptData; Permit; END RemoveException; BEGIN (* Break *) process:=thisTask; oldExceptCode:=process^.task.exceptCode; (* Alte Proc merken! *) oldExceptData:=process^.task.exceptData; (* Alte Data merken! *) SETREG(0,SetExcept(NoBreak,FullBreak)); (* Alle Excxeptions aus! *) actualBreak:=CBreak; (* Beachtet nur CtrlC *) CLOSE SETREG(0,SetExcept(NoBreak,FullBreak)); (* Alle Exceptions aus! *) process^.task.exceptCode:=oldExceptCode; process^.task.exceptData:=oldExceptData; END Break.mod