home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1990-07-22 | 2.8 KB | 107 lines |
- IMPLEMENTATION MODULE IntHandler[1];
-
- FROM SYSTEM IMPORT ADDRESS,
- BYTE,
- ADR,
- WORD,
- NEWPROCESS,
- IOTRANSFER,
- TRANSFER;
-
- FROM ClockIO IMPORT ClkClr,
- Z80M1;
-
- FROM RealTime IMPORT DateAndTime,
- IsLaterOrEqual,
- RealTime;
-
- FROM EventQueue IMPORT Event,
- QueueEmpty,
- PopEvent,
- NextEventAt;
-
- FROM DoTask IMPORT Perform;
-
-
-
- CONST
- M1Vector = 38H; (* we end up here on mode 1 interrupt *)
- M2VecAddress = M1Vector + 2; (* have iotransfer patch it's vector here *)
-
- (* Z80 code for 'poking' *)
- JMP = 0C3H;
- dummy = 0000H;
-
-
- VAR
- std, int : ADDRESS; (* per definition of IOTRANSFER *)
-
- WorkSpace : ARRAY[1..512] OF BYTE;
- (* must calculate by phases of the moon..*)
-
- (* create a structure at the Mode 1 vector, to enable use of TM2's way of
- dealing with things.. This is two different ways of looking at the same
- thing, the so-called 'free union' *)
-
- Mode2Xlate[M1Vector] : RECORD
- CASE : BOOLEAN OF
- TRUE : b : ARRAY[1..4] OF BYTE |
- FALSE : w : ARRAY[1..2] OF WORD |
- END;
- END;
-
-
- PROCEDURE IntHandler;
-
- VAR
- TimeNow,
- EventTime : DateAndTime;
- Task : Event;
-
- BEGIN
- LOOP;
- IOTRANSFER(int, std, M2VecAddress);
- (* when control passes to the above statement the interrupt vector
- is patched into 3Ah, and control returns to the body. The
- next interrupt will proceed with the following statement! *)
-
- RealTime(TimeNow); (* read the time, kill clock ints *)
- NextEventAt(EventTime);
- WHILE IsLaterOrEqual(TimeNow, EventTime) AND NOT QueueEmpty DO
- PopEvent(Task);
- Perform(Task);
- NextEventAt(EventTime);
- END;
-
- (* The above code is from a real-time control system. The realtime clock is
- checked, and the time compared with the scheduled execution time of the
- next event up on the event queue. If it is time, then the event is executed,
- if not, we re-start clock interrupts and return *)
-
- ClkClr; (* start clock interrupts again *)
-
- END;
-
- END IntHandler;
-
-
- BEGIN
- WITH Mode2Xlate DO
- b[1] := NOP; (* NOP *)
- b[2] := JMP; (* JP *)
- w[2] := dummy; (* M2Vec, patched in by iotransfer! *)
- END;
-
- (* patch our stub into page 0 *)
-
- Z80M1; (* set interrupt mode 1 *)
- (* let's have the correct interrupt mode *)
-
- NEWPROCESS(IntHandler, ADR(WorkSpace), SIZE(WorkSpace), int);
- (* grab space for the interrupt co-routine *)
-
- TRANSFER(std, int);
- (* make it initialize itself *)
-
- END IntHandler.