MODULE IntrDemo;
(*$ LargeVars:=FALSE StackChk:=FALSE StackParms:=FALSE *)
(* 28.8.90/bp *)

FROM SYSTEM	IMPORT	ADR,ADDRESS,REG,SETREG;
(* Wer behauptet da, der Import von Hardware kostet Code????! *)
(* KEIN einziges Byte! *)
FROM Hardware	IMPORT	custom;
FROM Terminal	IMPORT	WriteString, FormatNr, Read;
IMPORT		R; (* Register-Namen(Nummern) *)
IMPORT		ExecD, ExecL;

CONST colReg=0; (* Verändert Screenfarbe 0, aber nur ganz oben! *)

VAR
  (*$ LongAlign:=TRUE *) (* besser für 68020.. *)
  int:ExecD.Interrupt;
  counter:LONGINT;
  oldColor,color:CARDINAL;
  ch: CHAR;

(* Hier zwar nicht unbedingt notwendig, aber zum Angewöhnen...:
 * Wir könnten auch LoadA4 nehmen, oder in A1 (=intr.data) einen
 * Zeiger auf einen Variable oder einen RECORD übergeben.
 * Aber bei LoadA4:=TRUE wäre das Programm nicht mehr residentfähig!
 *)
(*$ OverflowChk:=FALSE RangeChk:=FALSE *) (* Jetzt bloß keinen Requester!! *)
(*$ SaveA4:=TRUE StackChk:=FALSE*) (* <-- Supervisor-Stack!! *)
PROCEDURE MyIntServer(data{R.A1}:ADDRESS):LONGINT;
BEGIN
  SETREG(R.A4,REG(R.A1)); (* A1 nach A4 kopieren, wo es hingehört! *)
  (* Nun bin ich eine NORMALE M2Amiga-Prozedur! *)
  INC(counter);
  IF color>0EEEH THEN
    color:=101H;
  ELSE
    INC(color,0111H)
  END;
  custom.color[colReg]:=color;
  RETURN 0; (* Wert ist egal, aber Z-flag muß gesetzt sein! *)
END MyIntServer;
(*$ POP OverflowChk POP RangeChk *)

BEGIN
  WriteString("Interrupt-Demo. (Abbruch mit RETURN)");
  int.node.type:=ExecD.interrupt;
  int.node.pri:=0;
  int.node.name:=ADR("M2Amiga.IntrDemo");
 (*
  * Wir übergeben A4 als Data. Könnte auch Adresse einer Variablen
  * sein, aber so darf der Interrupt alles tun, was Interrupts
  * tun dürfen [RKM Exec] und kann auf sämtliche globalen Variablen
  * und Libraries (mit Einschränkungen!) zugreifen.
  *)
  int.data:=REG(R.A4);
  int.code:=ADR(MyIntServer);
  oldColor:=custom.color[colReg];
  color:=0;
  ExecL.AddIntServer(LONGINT(ExecD.vertb),ADR(int));
  Read(ch); (* warte auf RETURN *)

CLOSE
  IF int.node.succ#NIL THEN (* Ist er schon eingehängt? *)
    ExecL.RemIntServer(LONGINT(ExecD.vertb),ADR(int));
  END;
  custom.color[colReg]:=oldColor; (* alte Farbe wieder *)
  FormatNr("Das waren %ld Vertical Blanking Interrupts\n",counter);
END IntrDemo.
