home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / beehive / program / tm2not10.arc / INTHANDL.MOD < prev    next >
Encoding:
Modula Implementation  |  1990-07-22  |  2.8 KB  |  107 lines

  1. IMPLEMENTATION MODULE IntHandler[1];
  2.  
  3. FROM SYSTEM IMPORT ADDRESS,
  4.                    BYTE,
  5.                    ADR,
  6.                    WORD,
  7.                    NEWPROCESS,
  8.                    IOTRANSFER,
  9.                    TRANSFER;
  10.  
  11. FROM ClockIO IMPORT ClkClr,
  12.                     Z80M1;
  13.  
  14. FROM RealTime IMPORT DateAndTime,
  15.                      IsLaterOrEqual,
  16.                      RealTime;
  17.  
  18. FROM EventQueue IMPORT Event,
  19.                        QueueEmpty,
  20.                        PopEvent,
  21.                        NextEventAt;
  22.  
  23. FROM DoTask IMPORT Perform;
  24.  
  25.  
  26.  
  27. CONST
  28.   M1Vector = 38H;        (* we end up here on mode 1 interrupt *)
  29.   M2VecAddress = M1Vector + 2;    (* have iotransfer patch it's vector here *)
  30.  
  31.                   (* Z80 code for 'poking' *)
  32.   JMP = 0C3H;
  33.   dummy = 0000H;
  34.  
  35.  
  36. VAR
  37.   std, int : ADDRESS;        (* per definition of IOTRANSFER *)
  38.  
  39.   WorkSpace : ARRAY[1..512] OF BYTE;
  40.                 (* must calculate by phases of the moon..*)
  41.  
  42. (* create a structure at the Mode 1 vector, to enable use of TM2's way of
  43. dealing with things.. This is two different ways of looking at the same
  44. thing, the so-called 'free union' *)
  45.  
  46.   Mode2Xlate[M1Vector] : RECORD
  47.     CASE : BOOLEAN OF
  48.       TRUE : b : ARRAY[1..4] OF BYTE  |
  49.       FALSE : w : ARRAY[1..2] OF WORD  |
  50.     END;
  51.   END;
  52.  
  53.  
  54. PROCEDURE IntHandler;
  55.  
  56. VAR
  57.   TimeNow,
  58.   EventTime : DateAndTime;
  59.   Task : Event;
  60.  
  61. BEGIN
  62.   LOOP;
  63.     IOTRANSFER(int, std, M2VecAddress);
  64. (* when control passes to the above statement the interrupt vector
  65. is patched into 3Ah, and control returns to the body. The
  66. next interrupt will proceed with the following statement! *)
  67.  
  68.     RealTime(TimeNow);               (* read the time, kill clock ints *)
  69.     NextEventAt(EventTime);
  70.     WHILE IsLaterOrEqual(TimeNow, EventTime) AND NOT QueueEmpty DO
  71.       PopEvent(Task);
  72.       Perform(Task);
  73.       NextEventAt(EventTime);
  74.     END;
  75.  
  76. (* The above code is from a real-time control system. The realtime clock is
  77. checked, and the time compared with the scheduled execution time of the
  78. next event up on the event queue. If it is time, then the event is executed,
  79. if not, we re-start clock interrupts and return *)
  80.  
  81.     ClkClr;        (* start clock interrupts again *)
  82.  
  83.   END;
  84.  
  85. END IntHandler;
  86.  
  87.  
  88. BEGIN
  89.   WITH Mode2Xlate DO
  90.     b[1] := NOP;    (* NOP *)
  91.     b[2] := JMP;    (* JP *)
  92.     w[2] := dummy;    (*       M2Vec, patched in by iotransfer! *)
  93.   END;
  94.  
  95. (* patch our stub into page 0 *)
  96.  
  97.   Z80M1;        (* set interrupt mode 1 *)
  98. (* let's have the correct interrupt mode *)
  99.  
  100.   NEWPROCESS(IntHandler, ADR(WorkSpace), SIZE(WorkSpace), int);
  101. (* grab space for the interrupt co-routine *)
  102.  
  103.   TRANSFER(std, int);
  104. (* make it initialize itself *)
  105.  
  106. END IntHandler.
  107.