home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / MYUTIL / MULTITAS.M < prev    next >
Encoding:
Text File  |  1990-11-16  |  4.7 KB  |  3 lines

  1. ⓪ MODULE MultiTask; (*$E MOS *)
  2. ⓪ (*$R-*)
  3. ⓪ 
  4. ⓪ (*
  5. ⓪ >>> Das Ganze geht aus einem Grunde nicht:
  6. ⓪"Wenn z.b. der Timer-IR auftritt, während gerade der VBL-IR läuft,
  7. ⓪"würde durch den IOTRANSFER der VBL unterbrochen werden. Das darf
  8. ⓪"aber nicht sein, stattdessen müßte erst der VBL beendet und erst
  9. ⓪"dann der timer-IR zugelassen werden. Dies wird bei Multitask-Systemen
  10. ⓪"i.a. so gelöst, daß der scheduler-IR eine niedrigere Priorität als
  11. ⓪"alle System-IRs bekommt. Oder eben so, daß durch Semaphore o.ä.
  12. ⓪"dafür gesorgt wird, daß der Timer-IR bis zum Ende der System-IRs
  13. ⓪"wartet.
  14. ⓪"Hier könnte man es entweder so lösen, daß als timer-IR der VBL-
  15. ⓪"Hardware-Vektor verwendet wird oder daß man sich in alle Sytem-IRs
  16. ⓪"hängt und semaphore setzt.
  17. ⓪ *)
  18. ⓪ 
  19. ⓪ (*
  20. ⓪!* Demo für Modula-Coroutinen, die per Interrupt umgeschaltet werden
  21. ⓪!* ("Time Slice").
  22. ⓪!*
  23. ⓪!* Das Demo-Programm geht nur von zwei Coroutinen aus, die abwechselnd
  24. ⓪!* aktiviert werden sollen. Ein richtiger Scheduler (Prozeß-Verwalter/
  25. ⓪!* Umschalter) würde stattdessen eine erweiterbare Liste für beliebig
  26. ⓪!* viele Coroutinen verwalten und sie alle abwechselnd aktivieren.
  27. ⓪!*
  28. ⓪!* Die Coroutinen werden folgendermaßen abwechselnd aktiviert: Zuerst
  29. ⓪!* einmal läuft das Hauptprogramm (Prozedur 'mainProgram'). Jede zwanzigstel
  30. ⓪!* Sekunde wird die erste Coroutine für eine fünfzigstel Sekunde aktiviert.
  31. ⓪!* Nach Ablauf einer Sekunde wird dann stattdessen die zweite Coroutine
  32. ⓪!* alle 1/20s für jeweils 1/50s aktiviert. Nach einer weiteren Sekunde
  33. ⓪!* wieder die erste, usw.
  34. ⓪!*
  35. ⓪!* Das bedeutet:
  36. ⓪!
  37. ⓪!* Die scheduler-Funktion (s.u.) benutzt den 200Hz-Interrupt-Vektor,
  38. ⓪!* sie wird also 200 mal pro Sekunde aufgerufen. Die Funktion installiert
  39. ⓪!* sich auf den Vektor mit IOTRANSFER. Jedesmal, wenn der Vektor ange-
  40. ⓪!* sprungen wird, wird die unterbrochene Coroutine (bzw. das unterbrochene
  41. ⓪!* Programm) im ersten Parameter zu IOTRANSFER ('suspendedCor') gespeichert.
  42. ⓪!* Der Scheduler zählt nun einen Zähler herunter. Ist er nicht abgelaufen,
  43. ⓪!* wird gleich wieder mit IOTRANSFER zur unterbrochenen Routine zurückgekehrt.
  44. ⓪!* Andernfalls wird eine der zwei wartenden Coroutinen
  45. ⓪!*
  46. ⓪!Ist der Zähler abgelaufen, wird jeweils
  47. ⓪!* eine der wartenden Coroutinen aktiviert. Der Zähler zählt 400 Werte,
  48. ⓪!* die Coroutinen werden demnach alle 2 Sekunden umgeschaltet.
  49. ⓪!*
  50. ⓪!* Zur Sichtbarmachung der Aktionen der beiden Coroutinen
  51. ⓪!* sie beide an verschiedenen Stellen auf dem Bildschirm herum. Dies
  52. ⓪!* geschieht durch Direktzugriff auf den Bildschirmspeicher, weil
  53. ⓪!* ein Aufruf von Ein-/Ausgabe-Funktionen (GEM, GEMDOS, BIOS) in
  54. ⓪!* Interrupts so einfach nicht erlaubt ist.
  55. ⓪!!Info-Line raus!
  56. ⓪!*)
  57. ⓪ 
  58. ⓪ FROM SYSTEM IMPORT ADDRESS, ADR, IOTRANSFER, TRANSFER, NEWPROCESS, IOCALL;
  59. ⓪ FROM SYSTEM IMPORT ASSEMBLER;
  60. ⓪ (*
  61. ⓪ FROM SysVars IMPORT etv_timer;
  62. ⓪ *)
  63. ⓪ FROM XBIOS IMPORT ScreenLogicalBase;
  64. ⓪ FROM Terminal IMPORT WriteString, WriteLn, Write;
  65. ⓪ 
  66. ⓪ CONST etv_timer =$114;
  67. ⓪ 
  68. ⓪ VAR  mainCor: ADDRESS;                     (* Hauptprogramm *)
  69. ⓪%schedCor: ADDRESS;                    (* Scheduler-Coroutine *)
  70. ⓪%cor1, cor2: ADDRESS;                  (* die Hintergrund-Coroutinen *)
  71. ⓪ 
  72. ⓪%screen: POINTER TO ARRAY [0..399] OF ARRAY [0..39] OF BITSET;
  73. ⓪%seconds: CARDINAL;
  74. ⓪%terminate: BOOLEAN;
  75. ⓪ 
  76. ⓪ PROCEDURE lauflicht (offset: CARDINAL; VAR pos: CARDINAL);
  77. ⓪"VAR b: BITSET;
  78. ⓪"BEGIN
  79. ⓪$b:= {};
  80. ⓪$INCL (b, pos);
  81. ⓪$IF pos=0 THEN pos:= 15; ELSE DEC (pos) END;
  82. ⓪$screen^[1,offset]:= b;
  83. ⓪$screen^[2,offset]:= b;
  84. ⓪$screen^[3,offset]:= b;
  85. ⓪$screen^[4,offset]:= b;
  86. ⓪"END lauflicht;
  87. ⓪ 
  88. ⓪ PROCEDURE funktion1;
  89. ⓪"VAR pos: CARDINAL;
  90. ⓪"BEGIN
  91. ⓪$pos:= 0;
  92. ⓪$LOOP
  93. ⓪&lauflicht (4, pos);
  94. ⓪$END
  95. ⓪"END funktion1;
  96. ⓪ 
  97. ⓪ PROCEDURE funktion2;
  98. ⓪"VAR pos: CARDINAL;
  99. ⓪"BEGIN
  100. ⓪$pos:= 0;
  101. ⓪$LOOP
  102. ⓪&lauflicht (8, pos);
  103. ⓪$END
  104. ⓪"END funktion2;
  105. ⓪ 
  106. ⓪ PROCEDURE mainProgram;
  107. ⓪"(*
  108. ⓪#* Diese Prozedur läuft als Hauptprogramm, also nicht im Interrupt.
  109. ⓪#*)
  110. ⓪"VAR last: CARDINAL; l: LONGCARD;
  111. ⓪"BEGIN
  112. ⓪$seconds:= 0;              (* Sekundenzähler, wird vom Scheduler erhöht *)
  113. ⓪$last:= seconds;
  114. ⓪$REPEAT
  115. ⓪&(* Gibt jede Sekunde ein Zeichen aus: *)
  116. ⓪&IF last # seconds THEN
  117. ⓪(last:= seconds;
  118. ⓪(Write ('#');
  119. ⓪&END
  120. ⓪$UNTIL FALSE (*seconds = 6;  (* Ende nach 6 Sekunden *)*)
  121. ⓪"END mainProgram;
  122. ⓪ ə
  123. (* $FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$00000D26$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DC$FFEE50DCÇ$00000027T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$00000027$000000EA$FFEE50DC$00000EA4$00000B77$00001031$0000105B$FFEE50DC$FFEE50DC$000002F0$00000091$0000006B$000002F0$000002E1$00000031$000002F0êÇé*)
  124.