summaryrefslogtreecommitdiff
path: root/system/net
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2019-02-04 13:09:03 +0100
committerLars-Dominik Braun <lars@6xq.net>2019-02-04 13:09:03 +0100
commit04e68443040c7abad84d66477e98f93bed701760 (patch)
tree2b6202afae659e773bf6916157d23e83edfa44e3 /system/net
downloadeumel-src-04e68443040c7abad84d66477e98f93bed701760.tar.gz
eumel-src-04e68443040c7abad84d66477e98f93bed701760.tar.bz2
eumel-src-04e68443040c7abad84d66477e98f93bed701760.zip
Initial import
Diffstat (limited to 'system/net')
-rw-r--r--system/net/1.7.5/doc/EUMEL Netz832
-rw-r--r--system/net/1.7.5/src/basic net840
-rw-r--r--system/net/1.7.5/src/callee14
-rw-r--r--system/net/1.7.5/src/net inserter50
-rw-r--r--system/net/1.7.5/src/net manager-M302
-rw-r--r--system/net/1.7.5/src/net report-M29
-rw-r--r--system/net/1.8.7/doc/netzhandbuch2045
-rw-r--r--system/net/1.8.7/doc/netzhandbuch.anhang58
-rw-r--r--system/net/1.8.7/doc/netzhandbuch.index259
-rw-r--r--system/net/1.8.7/source-disk1
-rw-r--r--system/net/1.8.7/src/basic net1148
-rw-r--r--system/net/1.8.7/src/net files-M5
-rw-r--r--system/net/1.8.7/src/net hardware interface389
-rw-r--r--system/net/1.8.7/src/net inserter145
-rw-r--r--system/net/1.8.7/src/net manager797
-rw-r--r--system/net/1.8.7/src/net report41
-rw-r--r--system/net/1.8.7/src/netz20
-rw-r--r--system/net/1.8.7/src/port server164
-rw-r--r--system/net/1.8.7/src/printer server99
-rw-r--r--system/net/1.8.7/src/spool cmd112
-rw-r--r--system/net/1.8.7/src/spool manager915
-rw-r--r--system/net/unknown/doc/EUMEL Netz829
22 files changed, 9094 insertions, 0 deletions
diff --git a/system/net/1.7.5/doc/EUMEL Netz b/system/net/1.7.5/doc/EUMEL Netz
new file mode 100644
index 0000000..ad39db3
--- /dev/null
+++ b/system/net/1.7.5/doc/EUMEL Netz
@@ -0,0 +1,832 @@
+#type ("trium8")##limit (11.0)#
+#start(2.5,1.5)##pagelength (17.4)#
+#block#
+#headeven#
+
+% EUMEL-Netzbeschreibung
+
+
+#end#
+#headodd#
+
+#center#Inhalt#right#%
+
+
+#end#
+
+#type ("triumb12")#
+1. Einleitung
+
+
+Teil 1: Netz einrichten und benutzen
+#type ("trium8")#
+
+1. Benutzung des Netzes
+
+2. Hardwarevoraussetzungen
+
+3. Einrichten des Netzes
+
+4. Informationsmglichkeiten
+
+5. Eingriffsmglichkeiten
+
+6. Fehlerbehebung im Netz
+
+#type ("triumb12")#
+
+Teil 2: Arbeitsweise der Netzsoftware
+#type ("trium8")#
+
+1. Die Netztask
+
+2. Protokollebenen
+
+3. Stand der Netzsoftware
+
+#page#
+#headodd#
+
+#center#Einleitung#right#%
+
+
+#end#
+
+#type("triumb12")#
+1. Einleitung #type("trium8")#
+
+
+Das EUMEL-Netz dient dazu mehrere EUMEL-Rechner (sog. Stationen) mit-
+einander zu koppeln. Diese Kopplung wird von Betriebsystem dazu benutzt, das
+Sendungskonzept (siehe Systemhandbuch 1.7, Intertaskkommunikation) so auszu-
+dehnen, da Tasks verschiedener Stationen einander Datenrume zusenden
+knnen. Auf dem Sendungskonzept aufbauende Konzepte nutzen daher automa-
+tisch das Netz aus: So ist es z.B. mglich
+
+- von einer Station aus auf einer anderen zu Drucken,
+
+- in PUBLIC einer anderen Station Dateien zu sichern (save), vorausgesetzt, da
+ PUBLIC dort ein free global manager ist,
+
+- auf einer anderen Station zu archivieren (z.B. wenn das eigene Archivlaufwerk
+ defekt ist oder ein anderes Format hat).
+
+Das Netz kann ab EUMEL-Version 1.7.3 eingesetzt werden.
+
+
+#type("triumb12")#
+Teil 1: Netz einrichten und benutzen
+
+1. Benutzung des Netzes #type("trium8")#
+#headodd#
+
+#center#Teil 1: Netz einrichten und benutzen#right#%
+
+
+#end#
+
+ Zur Benutzung des Netzes stehen folgende Operatoren und Prozeduren zur
+ Verfgung:
+
+
+1.1
+
+ TASK OP / (INT CONST station, TEXT CONST taskname)
+
+ liefert die Task #on("bold")#taskname#off("bold")# von der Station #on("bold")#station#off("bold")#.
+
+ Wenn die Station #on("bold")#station#off("bold")# nicht am Netz ist oder nicht eingeschaltet ist, wird
+ solange gewartet, bis das der Fall ist.
+
+ Fehlerflle:
+
+ - task "..." gibt es nicht
+
+ Die angeforderte Task gibt es in der Zielstation nicht.
+
+ - Collectortask fehlt
+
+ Das Kommando #on("bold")#define collector#off("bold")# wurde nicht gegeben (siehe 4.2).
+
+ - Station x antwortet nicht
+
+ Eine nicht vorhandene oder abgeschaltete Station wurde angesprochen.
+ Hinweis: Dieser Fehler wird angenommen, wenn eine berwachungszeit
+ von ca. 30 Sekunden verschrichen ist, ohne da Station x die
+ Taskidentifikation angeliefert hat.
+
+ Beispiel:
+
+ list (5/"PUBLIC")
+
+ Dateiliste von PUBLIC auf Station 5 wird angefordert.
+
+1.2
+
+ TASK OP / (INT CONST station, TASK CONST task)
+
+ liefert
+
+ station / name (task) .
+
+
+ Beispiel:
+
+ list (4/archive)
+
+
+1.3
+
+ INT PROC station (TASK CONST task)
+
+ liefert die Stationsnummer der Task #on("bold")#task#off("bold")#.
+
+ Beispiel:
+
+ put (station (myself))
+
+ gibt die eigene Stationsnummer aus.
+
+
+1.4
+
+ PROC archive (TEXT CONST archivename, INT CONST station)
+
+ dient dazu das Archiv auf der Station #on("bold")#station#off("bold")# anzumelden.
+
+ Beispiel:
+
+ archive ("std", 4); list (4/archive)
+
+ gibt das Inhaltsverzeichnis der Archivfloppy im Laufwerk der Station 4 aus.
+ Hinweis: Vergessen Sie bei solchen Querarchivierungen nicht die Stations-
+ angabe bei jedem einzelnen Archivkommando (z.B fetch ("xxx", #on("bold")#4/#off("bold")#
+ archive).
+ Hinweis: Querarchivieren ist langsam. Verwenden Sie es nur, wenn Sie Flop-
+ pyformate umsetzen wollen.
+
+
+1.5
+
+ PROC free global manager
+
+ dient dazu, die eigene Task ber das Netz ansprechbar zu machen. Jede
+ andere Task im Netz kann dann die blichen Manageraufrufe ('save', 'fetch',
+ u.s.w.) an die eigene Task machen, sofern diese nicht an ein Terminal gekop-
+ pelt ist.
+
+ Die Task wird (wie bei 'break') abgekoppelt und meldet sich in Zukunft mit
+ 'maintenance' statt mit 'gib kommando'.
+
+ Beispiel:
+
+ An Station 4 ruft man in der Task 'hugo' das Kommando #on("bold")#free global manager#off("bold")#
+ auf. Anschlieend kann man von jeder Station aus z.B. 'list (4/"hugo")' u.s.w.
+ machen.
+
+
+1.6
+
+ TEXT PROC name (TASK CONST t)
+
+ Diese (schon immer vorhandene) Prozedur wurde dahingehend erweitert, da der
+ Name einer Task einer anderen Station ber Netz angefordert wird.
+
+ Fehlerfall:
+
+ Station x antwortet nicht
+
+
+
+
+#type("triumb12")#2. Hardwarevoraussetzungen#type("trium8")#
+
+2.1 Zwei Stationen
+
+ Sie knnen zwei Stationen miteinander Vernetzen, wenn Sie dafr an jeder
+ Station eine V24-Schnittstelle zur Verfgung stellen.
+
+ Diese beiden Schnittstellen verbinden Sie mit einem Kabel zur Rechner-
+ kopplung (siehe Systemhandbuch 1.7 Teil 2).
+
+2.2 Mehrere Stationen
+
+ Wenn Sie mehr als zwei Stationen vernetzen wollen, brauchen neben je
+ einer V24 an jeder Station noch je eine Netzanschlubox.
+
+ Jede Box besitzt eine V24-Schnittstelle zum Anschlu an die V24-
+ Schnittstelle der zugeorneten Station und eine weitere Schnittstelle zur
+ Verbindung der Boxen untereinander.
+
+
+#type("triumb12")#3. Einrichten des Netzes #type("trium8")#
+
+Hinweis: Dieses Kapitel ist nur fr Systembetreuer wichtig.
+
+3.1 Legen Sie Stationsnummern fr die am Netz beteiligten Rechner fest (von 1 an
+ aufsteigend).
+
+ Die Boxen haben ebenfalls Stationsnummern. Die Stationsnummern der Box
+ und des zugeordneten Rechners mssen bereinstimmen.
+
+
+3.2 Holen Sie an jeder Station die Task #on("bold")#configurator#off("bold")# an ein Terminal und geben Sie
+ das Kommando #on("bold")#define collector ("net port")#off("bold")#. Geben Sie auerdem das
+ Kommando #on("bold")#define station (x)#off("bold")#, wobei #on("bold")#x#off("bold")# die gewhlte Stationsnummer ist.
+
+ Hinweis: Taskkommunikationen, die zu dem Zeitpunkt laufen, fhren zu feh-
+ lerhaften Verhalten. Dies liegt daran, da durch #on("bold")#define station#off("bold")# alle
+ Task-Id's gendert werden mssen, weil eine Task-Id u.a. die
+ Stationsnummer der eigenen Station enthlt (siehe 2.3). TASK-
+ Variable, die noch Task-Id's mit keiner oder falscher Stationsnum-
+ mer enthalten, knnen nicht mehr zum Ansprechen einer Task
+ verwendet werden.
+
+ Beispiel: Der Spoolmanager (siehe Benutzerhandbuch 1.7 Teil 12) richtet
+ beim Kommando #on("bold")#start#off("bold")# einen Worker ein und merkt sich dessen
+ Task-Id in einer TASK-Variablen, um sicherzustellen, da nur der
+ Worker Dateien zum Drucken abholt. Wird jetzt das Kommando #on("bold")#
+ define station#off("bold")# gegeben, kann der Spoolmanager seinen Worker
+ nicht mehr identifizieren, weil der Worker eine neue Task-Id er-
+ halten hat. Man mu daher den Worker lschen und mit dem
+ Kommando #on("bold")#start#off("bold")# im Spoolmanager wieder neu einrichten.
+
+
+ Sinnvollerweise gibt man #on("bold")#define station#off("bold")# sofort nach den Laden eines
+ frischen Systems von Archiv.
+
+ Konfigurieren Sie mit dem Kommando #on("bold")#configurate#off("bold")# den fr das Netz vorgese-
+ henen Kanal auf
+
+ - transparent
+ - 9600 Baud (Standardeinstellung der Boxen)
+ - RTS/CTS-Protokoll
+ - groen Puffer
+ - 8 bit
+ - even parity
+ - 1 stopbit.
+
+ Falls diese Einstellungen nicht alle angeboten werden, klren Sie mit Ihrem
+ Rechnerlieferanten, ob und wie diese Einstellungen erreicht werden knnen.
+ Hinweis: Notfalls kann auf das RTS/CTS-Protokoll verzichtet werden, wenn
+ der Eingabepuffer der Station gro genug ist. Die Anzahl simultan
+ laufender Netzkommunikationen ist dann auf
+
+ puffergre DIV 150
+
+ begrenzt (bei Z80, 8086: 3; bei M20: 10).
+ Hinweis: Es knnen auch andere Baudraten (2400, 4800, 19200) an der Box
+ eingestellt werden.
+
+3.3 Achten Sie bei der Verbindung von der Station zur Netzbox (bzw. zur Gegen-
+ station bei einem Zweistationennetz ohne Boxen) darauf, da neben den
+ Empfangs- und Sendeleitungen auch die Leitungen RTS und CTS verdrahtet
+ werden, also ein 5 poliges Kabel verwendet wird (siehe Systemhandbuch 1.7
+ Teil 2). Die Pin-Belegung der Boxen entspricht den dortigen Angaben.
+
+ Beispiel:
+
+ Verbindung eines CSK-Systems mit der Box:
+
+ Stecker Stecker
+ Pin Pin
+
+ 2 <---------> 3
+ 3 <---------> 2
+ 4 <---------> 5
+ 5 <---------> 4
+ 7 <---------> 7
+
+
+3.4 Richten Sie eine Task #on("bold")#net#off("bold")# unter #on("bold")#SYSUR#off("bold")# ein und insertieren Sie dort die Datei-
+en
+
+ net report/M
+ basic net
+ net manager/M.
+
+ Beantworten Sie die Frage nach dem Kanal fr das Netz und nach der Flu-
+ kontrolle (RTS/CTS).
+
+
+#type("triumb12")#4. Informationsmglichkeiten #type("trium8")#
+
+ In der Task #on("bold")#net#off("bold")# wird eine Datei #on("bold")#report#off("bold")# gefhrt in der Fehlersituationen des
+ Netzes verzeichnet werden. Diese Datei kann in jeder anderen Task mit #on("bold")#list
+ (/"net")#off("bold")# angezeigt werden.
+
+ In jeder Task kann durch das Kommando #on("bold")#list (/"net port")#off("bold")# eine bersicht ber
+ die momentan laufenden Netzbertragungen der eigenen Station erhalten
+ werden.
+
+
+#type("triumb12")#5. Eingriffsmglichkeiten #type("trium8")#
+#headodd#
+
+#center#Eingriffsmglichkeiten#right#%
+
+
+#end#
+
+5.1 Jede Task kann Sende- und Empfangsstrme, die bei #on("bold")#list (/"net port")#off("bold")# gemel-
+ det worden sind und die eigene Task betreffen, abbrechen. Hierzu ist das
+ Kommando #on("bold")#erase ("x",/"net port")#off ("bold")# zu geben, wobei x die Stromnummer (aus
+ dem 'list') ist.
+
+ Unberechtigte Lschversuche werden abgewiesen.
+
+ Von der Task 'net' aus knnen jedoch damit beliebige Strme abgebrochen
+ werden.
+
+5.2 Durch das Kommando #on("bold")#start#off("bold")# kann von der Task 'net' aus das Netz neu gestartet
+ werden. Dabei werden alle augenblicklichen Netzkommunikationen gelscht.
+ Die Tasks 'net port' und 'net timer' werden dabei gelscht und neu eingerich-
+ tet.
+
+ #on("bold")#start (kanal, quit)#off("bold")# wirkt wie #on("bold")#start#off("bold")#. Zustzlich wird als Netzkanal 'kanal' eingestellt
+ und maximal 'quit' Empfangsstrme zugelassen. 'quit' ist auf 3 zu setzen,
+ wenn der Kanal ohne RTS/CTS angeschlossen ist (siehe 3.2).
+
+
+#type("triumb12")#6. Fehlersuche im Netz #type("trium8")#
+
+ Fehler im Netz knnen sich verschiedenartig auswirken. Im Folgenden wird auf
+ einige Beispiele eingegangen:
+
+ Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung 'Station 4 antwortet nicht'.
+
+ Fehlermglichkeiten:
+
+ - Station 4 gibt es nicht am Netz.
+ Abhilfe: Richtige Station angeben.
+
+ - Station 4 ist nicht eingeschaltet.
+ Abhilfe: Station 4 einschalten. Kommando erneut geben.
+
+ - Netztask an Station 4 ist nicht arbeitsfhig.
+ Abhilfe: Kommando 'start' in der Task 'net'.
+
+ - Stationsnummern und Boxnummern stimmen nicht berein.
+ Abhilfe: Mit 'define station' Stationsnummern korrigieren (siehe 3.2).
+
+ - Verbindung Rechner/Box am eigenen Rechner oder an Station 4 fehlt.
+ Abhilfe: Verbindungen berprfen. Durch Ansprechen einer dritten Station
+ kann oft schnell geklrt werden, welche Rechner/Box-Verbindung
+ defekt sein mu.
+
+ - Verbindung der Boxen untereinander defekt.
+ Abhilfe: Fehlende Verbindung, Masseschlu und Dreher (keine 1:1 Ver-
+ bindung) berprfen und beheben.
+ Hinweis: Liegt z.B. ein Masseschlu vor, so kann es durchaus sein, da
+ Boxen, die nicht in der Nhe des Masseschlu stehen noch mitei-
+ nander arbeiten knnen. Man kann aus der Tatsache, da zwei
+ Boxen miteinander arbeiten knnen, also nicht schlieen, da man
+ nicht nach diesem Fehler suchen mu.
+
+
+ Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt keine Reaktion.
+
+
+ - Station 4 ist whrend dieser Sendung zusammengebrochen.
+ Abhilfe: Station 4 wieder starten. Die Bearbeitung des 'list'-Kommandos
+ wird automatisch wieder aufgenommen.
+
+ - PUBLIC auf Station 4 ist nicht im Managerzustand.
+ Abhilfe: PUBLIC in den Managerzustand versetzen.
+
+
+ Hinweis: Das Netz hat nocht nicht die volle Sendungslogik des EUMEL. So
+ wird nur ca. 10 Minuten lang versucht, eine Sendung zuzustellen.
+ Danach wird die Sendung gelscht. Ist dies eingetreten, so mu
+ das list-Kommando erneut gegeben werden.
+
+ - Fehler in der Netzhardware.
+ berprfen Sie, ob
+
+ - die Boxen eingeschaltet sind,
+ - die Bereitlampe blinkt (wenn nicht: RESET an der Box)
+ - die V24-Kabel richtig stecken,
+ - die Boxen untereinander verbunden sind (1 zu 1 Verbindungen der 5
+ poligen Diodenbuchsen).
+
+
+ - Die Netzsoftware ist auf einen nicht vorhergesehenen Fehler gelaufen.
+ Dieser wird im Report vermerkt.
+ Abhilfe: Geben Sie in der Task #on("bold")#net#off("bold")# das Kommando #on("bold")#start#off("bold")#. Dadurch wird die
+ Netzsoftware neu gestartet. Alle Netzkommunikationen dieser
+ Station gehen verloren.
+
+
+ Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung 'Collectortask fehlt'.
+
+ - In der Task 'configurator' wurde das Kommando 'define collector' (siehe 3.2)
+ nicht gegeben.
+
+ - Die Task 'net port' existiert nicht mehr.
+ Abhilfe: Kommando 'start' in der Task 'net'.
+
+
+ Beispiel:
+
+ Nach #on("bold")#fetch ("hugo",4/public)#off("bold")# sind Teile von der Datei "hugo" verflscht.
+
+ - Die V24-Verbindung zur Box ist nicht in Ordnung.
+ Abhilfe: Abstand zwischen Rechner und Box verkrzen; Baudrate ernie-
+ drigen; Durch Wechseln der V24-Schnittstelle feststellen, ob
+ diese defekt ist.
+ Hinweis: Die Verbindung zwischen den Boxen ist durch Prfsummen abge-
+ sichert (Hardware).
+
+#headodd#
+
+#center#Teil 2: Arbeitsweise der Netzsoftware#right#%
+
+
+#end#
+#page#
+#type("triumb12")#
+
+Teil 2: Arbeitsweise der Netzsoftware
+
+
+1. Die Netztask #type ("trium8")#
+
+In diesem Kapitel wird beschrieben, wie eine Netztask in das System
+eingebettet ist und welche Aufgaben sie hat. Unter Einhaltung dieser
+Konzepte kann die ausgelieferte Netztask so gendert werden, da sie
+beliebige andere Netzhardware untersttzt. Z.Zt. ist die Netzsoftware noch
+nicht so gegliedert, da nur eine hardwareabhngige Komponente ausgetauscht
+werden mu.
+
+Die Kommunikation zwischen Tasks im EUMEL-Betriebssystem basiert auf einem
+Rendevouskonzept: Die Zieltask einer Sendung mu empfangsbereit sein, wenn die
+Quelltask sendet.
+
+Die Kommunikationsprozeduren auf der niedrigsten Ebene sind 'send' (Senden)
+und 'wait' (Warten auf Empfang). Bei der Kommunikation werden eine Integer
+'code' und ein Datenraum 'dr' bergeben. 'code' mu >= 0 sein, da negative
+Codes systemintern verwandt werden. Ist die empfangende Task an einen Kanal
+gekoppelt ('continue'), so fhrt eine Zeicheneingabe auf diesem Kanal dazu,
+da eine
+Sendung mit dem Code -4 ankommt. Die Eingabedaten mssen mit den blichen
+Eingabeprozeduren ('inchar' u.s.w.) abgeholt werden. Der bermittelte Datenraum
+und die Absendertask sind dabei ohne Bedeutung und drfen nicht interpretiert
+werden.
+
+Die Prozedur 'send' hat einen Rckmeldeparameter, der besagt, ob die Sendung
+bermittelt wurde. Gibt es die Zieltask nicht oder steht sie nicht im 'wait', so kann
+die Sendung nicht bermittelt werden.
+
+
+Ein Entwicklungskriterium fr das EUMEL-Netz war es, mglichst wenig Unter-
+sttzung von der virtuellen EUMEL-Maschine (EUMEL0) zu fordern, damit weit-
+gehend in ELAN programmiert werden kann. Dadurch ist es mglich eine (privili-
+gierte) Task mit der Netzabwicklung zu betrauen.
+
+Zunchst wird auf die EUMEL0-Untersttzung eingegangen:
+
+1.1. Es gibt die Prozedur 'define collector', mit der die fr das Netz verantwort-
+ liche Task der EUMEL0-Maschine bekannt gemacht wird. Diese Task wird im
+ folgenden Collector genannt.
+
+1.2. Es gibt die Prozedur 'define station', die fr den Rechner eine Stationsnum-
+ mer einstellt. Anhand dieser Nummer werden die Rechner eines Netzes un-
+ terschieden. Das Einstellen bewirkt, da fr alle Tasks die Stationsnummer in
+ ihre Task-Id eingetragen wird (Task-Id's sind die Werte, die der Typ TASK
+ annehmen kann).
+
+1.3. Der Befehl 'station (task)' liefert die Stationsnummer der 'task'. So liefert z.B.
+ 'station (myself)' die Stationsnummer des eigenen Rechners.
+
+1.4. Eine Sendung, deren Zieltask in einem anderen Rechner liegt (also station
+ (ziel) <> station (myself)), wird auf die Collectortask geleitet.
+
+1.5. Es gibt eine Prozedur 'collected destination', die es dem Collector erlaubt, die
+ eigentliche Zieltask einer auf ihn geleiteten Sendung zu erfahren.
+
+1.6. Es gibt eine Variante der Prozedur 'send', die es dem Collector gestattet, der
+ Zieltask eine beliebige andere Task als Absender vorzumachen.
+
+1.7. Es gibt eine spezielle Task-Id 'collector', durch die der augenblicklich ein-
+ gestellte Collector erreicht wird. Diese wird als Zieltask beim Aufruf der Ver-
+ mittlungsdienste angegeben (siehe 2.5). Eine Sendung an 'collector' wird von
+ EUMEL0 an den derzeitigen Collector geschickt.
+
+Ein Collector kann also auf drei Wegen von den brigen Tasks desselben Rechners
+Sendungen erhalten:
+
+ 1. ber ein normales Send (z.B. bei 'list (/"net port")', wenn "net port" der der-
+ zeitige Collector ist),
+
+ 2. ber ein Send an die Task 'collector' (s.u.) und
+
+ 3. als umgeleitete Sendung (z.B. bei 'list' an eine Task auf einem anderen
+ Rechner).
+
+Der Collector kann diese Flle anhand von 'collected destination' unterscheiden.
+
+Die Punkte 1.4...1.6 dienen dazu, den Collector fr ber Netz kommunizierende
+Task unsichtbar zu machen: Der Collector taucht nicht als Ziel oder Quelle von
+Sendungen auf. Das ist notwendig, damit normale Tasks sich nicht darum kmmern
+mssen, ob eine Sendung bers Netz geht oder im eigenen Rechner bleibt.
+
+Wenn ein Datenraum an einen anderen Rechner geschickt wird, mu der gesamte
+Inhalt (z. Zt. max. 1 MB) bertragen werden. Dies macht bei der blichen Netz-
+hardware eine Zerlegung in Packete ntig (siehe Systemhandbuch 173, Teil 4,
+Punkt 5). Fr Netze ber V24-Kanle stehen spezielle Blockbefehle zur verf-
+gung:
+
+1.8. blockin / blockout (dr,seite,512+abstand,anzahl,rest)
+
+ Es werden maximal 'anzahl' Bytes transferiert. In 'rest' wird zurckgemeldet,
+ wieviel Bytes nicht bearbeitet wurden (z.B. weil der Kanal nichts anliefert).
+ Bearbeitet werden die Bytes
+
+ 'seite' * 512 + 'abstand'
+
+ bis maximal
+
+ 'seite' * 512 + 'abstand' + 'anzahl' - 1
+
+ Der Kanal, an den die Task gekoppelt ist, wird dabei ber Stream-IO (d.h.
+ 'incharety' bei 'blockin' bzw. 'out' bei 'blockout') angesprochen.
+
+ Hinweis: Die Anforderung darf nicht ber Seitengrenze gehen, d.h.
+
+ 'abstand' + 'anzahl' <= 512
+
+ mu erfllt sein.
+
+
+Eine Netzsendung luft wie folgt ab:
+
+Die Task q auf Rechner rq mache ein 'send' an die Task z auf Rechner rz.
+
+1. Die Prozedur send ist ein EUMEL0-Befehl. Die EUMEL0-Ebene erkennt, da
+ die Sendung an die Station rz geht, da die Stationsnummer in der Task-Id
+ enthalten ist. Daher wird die Sendung zum Collector, den EUMEL0 wegen 'de-
+ fine collector' kennt, umgeleitet.
+
+2. Die Task Collector empfngt ber 'wait' den Datenraum, den Sendecode und
+ die Absendertask q. Die Zieltask z erfhrt sie durch 'collected destination'.
+
+3. Der Collector nimmt Kontakt mit dem Collector des Rechner rz, dessen Sta-
+ tionsnummer ja 'station(z)' ist, auf und bermittelt diesem Sendecode, Quelltask
+ (q), eigentliche Zieltask (z) und den Datenraum. Da die Collectoren in ELAN
+ geschrieben sind, knnen sie an beliebige Netzhardware und Protokolle ange-
+ pat werden.
+
+4. Der Collector auf Rechner rz verwendet das spezielle 'send', um der Zieltask die
+ Sendung zuzustellen. Dadurch erscheint nicht der Collector sondern die Task q
+ als Absender der Sendung.
+
+Zur Abwicklung der Vermittlungsebene (Teil 1: 2.4) mu der Collector noch
+spezielle Funktionen beherrschen. Diese sind
+
+ der /-Operator (Taskname in Task-Id wandeln) und
+ die name-Prozedur (Task-Id in Namen wandeln).
+
+Der /-Operator macht eine Sendung an den 'collector', wobei im Datenraum der
+Name der Task steht und der Sendecode gleich der Stationsnummer ist (siehe
+Quellcode 173, Packet tasks). Der Collector setzt sich mit dem Collector dieser Sta-
+tion in Verbindung, damit dieser die Task-Id ermittelt und zurckschickt. Der
+eigene Collector schickt dann dem /-Operator als Antwort einen Datenraum, der
+die Task-Id enthlt.
+
+Umgekehrt luft 'name' ab: Wenn die Task-Id von einer fremden Station ist,
+schickt 'name' eine Sendung an den 'collector', wobei im Datenraum die Task-Id
+steht und Sendecode = 256 ist. Der Collector entnimmt die Stationnummer der
+Task aus der Task-Id und lt sich vom entsprechenden Collector den Tasknamen
+geben. Dieser wird der 'name'-Prozedur im Antwortdatenraum bergeben.
+
+#type ("triumb12")#2. Ebenen #type("trium8")#
+
+In diesem Kapitel werden die Protokollebenen fr das Netz beschrieben, wie
+sie die ausgelieferte Netzsoftware benutzt und erwartet. Bei anderer
+Netzhardware mssen die Ebenen 1 bis 3 ausgetauscht werden. Unter Einhaltung
+der im vorigen Kapitel beschriebenen Randbedingungen knnen auch die hheren
+Ebenen gendert werden.
+
+
+2.1 Physikalische Ebene
+
+ 2.1.1 Station <--> Box
+
+ V24-Schnittstelle mit RTS/CTS-Handshake. Vollduplex.
+
+ 2.1.2 Box <--> Box
+
+ RS422 ber 2 verdrillte Leitungspaare (Takt und Daten).
+
+2.2 Verbindungsebene
+
+ 2.2.1 Station <--> Box
+
+ Asynchron
+ 8 Bit
+ Even Parity
+ 2400/4800/9600/19200 Baud (einstellbar ber Ltbrcken)
+
+ 2.2.2 Box <--> Box
+
+ SDLC
+ 400 KBaud
+
+2.3 Netzebene
+
+ 2.3.1 Station <--> Box
+
+ Telegrammformat: STX, <n>, <ziel>, <quelle>, <(n-4) byte>
+
+ <n> ist Lngenangabe ( 8 <= n <= 160)
+ <ziel>, <quelle> sind Stationsnummern. Diese mssen an den je-
+ weiligen Boxen ber Ltbrcken eingestellt sein.
+
+ Box --> Station:
+
+ Ein Telegramm kommt nur bei der Station an, bei deren Box die
+ Nummer <ziel> eingestellt ist. Dadurch ist ein Mithren fremder
+ bertragungen nicht mglich (Datenschutz).
+
+ Zwischen Telegrammen knnen Fehlermeldungen der Box (Klartext)
+ bermittelt werden (z.B. 'skipped x', wenn ein STX von der Box er-
+ wartet wurde, aber 'x' von der Station ankommt).
+
+ Station --> Box:
+
+ Ein Telegramm wird nur abgeschickt, wenn <quelle> mit der einge-
+ stellten Nummer bereinstimmt (Datenschutz: Man kann nicht eine
+ beliebige Station zu sein vorschwindeln, es sei denn man hat physi-
+ schen Zugriff zur Box und stellt dort die Stationsnummer um).
+
+ 2.3.2 Box <--> Box
+
+ Telegrammformat: FRAME, <ziel>, <quelle>, <daten> ,
+ <CRC-Code>
+
+ Eine Lngenangabe ist nicht ntig, da SDLC eine Rekonstruktion der
+ Lnge erlaubt.
+
+ Telegramme mit falschen CRC-Code werden vernichtet. Auf hheren
+ Ebenen mu dies durch Zeitberwachung erkannt und behandelt
+ werden.
+
+
+2.4 Transportebene
+
+ Diese Ebene wickelt das Rendevous zwischen einer Task, die 'send' macht,
+ und einer Task, die im 'wait' steht, ab (siehe: EUMEL-Systemhandbuch).
+
+ Der im 'send' angegebene Datenraum wird als Folge von Seiten (im
+ EUMEL-Sinne: Pagingeinheit und Allokiereinheit) bermittelt, wobei jede Seite
+ noch in 64 Byte groe Stcke zerlegt wird. Es werden nur echt allokierte Seiten
+ bermittelt. Um nicht jedes Telegramm voll qualifizieren zu mssen, wird
+ zunchst eine Art virtuelle Verbindung durch ein OPEN-Telegramm erffnet.
+ Danach folgen variable viele DATA-Telegramme. Beide Sorten werden durch
+ QUIT-Telegramme quittiert, um folgende Funktionen zu ermglichen:
+
+ Flukontrolle (z.B. Zielrechner langsam)
+ Wiederaufsetzen (verlorene Telegramme)
+ Abbruch (z.B. weil Zieltask inzwischen beendet).
+
+ Ein CLOSE-Telegramm ist nicht ntig, da das letzte DATA-Telegramm als
+ solches erkannt werden kann (siehe unten).
+
+ 2.4.1 OPEN-Telegramm
+
+ STX, 20, <ziel>, <quelle>, <strom>, <sequenz>, <seite>,
+ <quelltask>, <zieltask>, <code>
+
+ <ziel>, <quelle> siehe 2.3.1
+
+ <strom> Die Stromnummer identifiziert die virtuelle Verbindung.
+ Sie mu in den QUIT-Telegrammen angegeben wer-
+ den.
+
+ <sequenz> -1 (Kennzeichen fr OPEN)
+
+ <seite> Nummer der ersten echt allokierten Seite des Datenra-
+ ums (=-1, falls Nilspace)
+
+ <quelltask> Taskid der sendenden Task
+
+ <zieltask> Taskid der empfangenden Task
+
+ <code> Wert des im 'send' angegebenen Codes.
+
+ 2.4.2 DATA-Telegramm
+
+ STX, 74, <ziel>, <quelle>, <sequenz>, <seite>, <64 byte>
+
+ <sequenz> wird von Telegramm zu Telegramm hochgezhlt. Dient
+ der berwachung gegen verlorengegangene Telegramme
+ bzw. durch Zeitberwachung verdoppelter Telegramme.
+
+ <seite> Nummer der x.ten echt allokierten Seite des Datenra-
+ ums. (x = (<sequenz>+16) DIV 8).
+
+ <64 byte> Nutzinformation. Diese gehrt zur Adresse a des Daten-
+ raums.
+
+ a = N (<sequenz> DIV 8 + 1) * 512
+ + (<sequenz> MOD 8) * 64
+
+ wobei N (x) die Nummer der x.ten Seite ist.
+
+ Aus den Formeln ergibt sich, da diese Nummer schon in
+ einem vorhergehenden DATA/OPEN-Telegramm ber-
+ mittelt wurde (im Feld <seite>).
+
+ 2.4.3 QUIT-Telegramm
+
+ STX, 8, <ziel>, <quelle>, <strom>, <quit>
+
+ <strom> mu die Stromnummer sein, die in dem OPEN/DATA-
+ Telegramm stand, das quittiert wird.
+
+ <quit> 0 : ok. Nchstes Telegramm schicken.
+
+ -1: bertragung neu starten (mit OPEN), weil die
+ Empfangsstation das OPEN nicht erhalten hat.
+
+ -2: bertragung ca. 20 Telegramme zurcksetzen.
+
+ -3: bertragung abbrechen.
+
+
+2.5 Vermittlungsebene
+
+ Diese Ebene ist dafr zustndig, Tasknamen von Task auf anderen Stationen
+ in Taskids (Werte des Typs TASK) zu wandeln und umgekehrt. Hierzu wird im
+ entsprechenden OPEN-Telegramm der Code -6 (bzw. -7) als <code>
+ eingetragen. Die Netzempfangstask erkennt diese Codes und wickelt die
+ Aufgaben selbst ab, soda es dabei nicht ntig ist, irgendeine Taskid der
+ Zielstation zu kennen.
+
+ Dieses Verfahren ist mglich, weil im 'send' nur positive Codes erlaubt sind.
+
+2.6 Hhere Ebenen
+
+ Hhere Ebenen sind nicht mehr netzspezifisch. Sie basieren alle auf dem
+ Send/Wait-Konzept des EUMEL. So gibt es z.B. den 'global manager', der
+ Aufbewahrung und Zugriff von Dateien in einer Task regelt. Dabei darf diese
+ Task (bei der Variante 'free global manager') auf einer beliebigen Station im
+ Netz liegen. Wegen des Rendevous-Konzepts knnen beliebige Sicherheit-
+ strategien benutzt werden (z.B.: Keine Dateien an Station 11 ausliefern). Von
+ groen Wert ist z.B., da man ohne weiteres das Archiv (Floppylaufwerk) einen
+ anderen Station anmelden und benuzten kann, wodurch eine einfache Kon-
+ vertierung von Floppyformaten mglich ist. Dies ist mglich, weil auch die Ar-
+ chiv-Task der Stationen sich an das Globalmanagerprotokoll halten.
+
+
+#type("triumb12")#
+Bemerkungen#type("trium8")#
+
+Fehlerbehandlung besteht bis Ebene 3 darin, fehlerhafte Telegramme einfach zu
+entfernen. Die Ebene 4 berwacht den Netzverkehr sowieso ber Timeouts, die
+eine Wiederhohlung eines Telegrammes bewirken, wenn die Quittung ausbleibt.
+
+Da bei der sendenden Station der ganze Datenraum zur Verfgung steht, ist eine
+Fenstertechnik (wie bei HDLC) nicht ntig. Es kann zu jedem Zeitpunkt um beliebig
+viele Telegramme zurckgesetzt werden.
+
+Da im EUMEL eine Textdatei ein Datenraum mit sehr komplexer Struktur ist (wegen
+der Insert/Delete-Mglichkeiten, ohne den Rest der Datei zu schieben), ist es ein
+hoher Aufwand, von einem fremden Betriebssytem her Textdateien ins EUMEL-
+Netz zu senden. Fr solche Zwecke mu noch eine einfachere Dateistruktur defi-
+niert werden und entsprechende Dateikonverter erstellt werden.
+
+
+
+#type("triumb12")#3. Stand der Netzsoftware #type("trium8")#
+
+Das EUMEL-System wickelt die Prozedur #on("bold")#send#off("bold")# ber das Netz ab, wenn die
+Stationsnummer der Zieltask ungleich der eigenen Stationsnummer ist. Umge-
+kehrt kann man der von der Prozedur #on("bold")#wait#off("bold")# gelieferten Absendertask die Absen-
+derstation entnehmen (siehe Prozedur #on("bold")#station#off("bold")# in Abschnitt 3).
+
+Nicht untersttzt wird z.Zt. die Logik der Prozeduren #on("bold")#call#off("bold")# und #on("bold")#pingpong#off("bold")#. Diese
+funktionieren nur in der gewohnten Weise, wenn die Zieltask in #on("bold")#wait#off("bold")# steht. Ist
+die Zieltask lnger als ca. 10 Minuten #on("bold")#busy#off("bold")# oder nicht mehr vorhanden, geht die
+Sendung einfach verloren (Gefordert ist: bei #on("bold")#call#off("bold")#: immer wieder versuchen; bei #on("bold")#
+pingpong#off("bold")#: Rckmeldung -2).
+
+Wegen dieser Einschrnkung kann man z.B. ein sicheres Drucken von Station a
+auf einen Drucker der Station b nur durch einen eigenen Spoolmanager auf
+Station a verwirklichen. Die Einrichtung eines solchen Managers ist allerdings
+sowieso sinnvoll, damit man
+
+- das normale 'print'-Kommando verwenden kann (statt z.B. save ("xxx",
+4/printer);) und
+- nicht zu warten braucht, bis die Datei bers Netz gesendet ist.
+
+
+
+
+
diff --git a/system/net/1.7.5/src/basic net b/system/net/1.7.5/src/basic net
new file mode 100644
index 0000000..41c8402
--- /dev/null
+++ b/system/net/1.7.5/src/basic net
@@ -0,0 +1,840 @@
+PACKET basic net DEFINES (* D. Heinrichs *)
+ (* 02.10.85 *)
+ nam,
+ max verbindungsnummer,
+ neuer start,
+ packet eingang,
+ neue sendung,
+ zeitueberwachung,
+ verbindung,
+ loesche verbindung:
+
+TEXT PROC nam (TASK CONST t):
+ IF t = collector THEN name (t)
+ ELIF station (t) <> station (myself)
+ THEN "** fremd **"
+ ELSE name (t)
+ FI
+END PROC nam;
+
+INT PROC tasknr (TASK CONST t):
+ IF t = collector THEN maxtasks
+ ELSE index (t)
+ FI
+END PROC tasknr;
+
+LET
+ maxtasks = 127,
+ max strom = 20,
+ max strom 1 = 21,
+ stx = ""2"",
+ code stx = 2,
+ ack = 0,
+ nak = 1,
+ error nak = 2,
+ zeichen eingang = 4,
+ list code = 15,
+ fetch code = 11,
+ inspect code = 30,
+ continue code = 100,
+ erase code = 14,
+ report code = 99,
+ seiten groesse = 512,
+ dr verwaltungslaenge = 8,
+ dr verwaltungslaenge2=10,
+ nutzlaenge = 64,
+ openlaenge = 20,
+ vorspannlaenge = 10,
+ neue ack laenge = 10,
+ ack laenge = 8,
+
+ (* Typen von Kommunikationsstrmen *)
+
+ send wait = 0,
+ zustellung = 1,
+ call pingpong = 2,
+ call im wait = 3,
+ call im abbruch = 4,
+ call in zustellung = 5,
+
+ (*quittungscodes*)
+
+ ok = 0,
+ von vorne = 1,
+ wiederhole = 2,
+ loesche = 3,
+ beende = 4;
+
+LET STEUER =
+ STRUCT (
+ INT head,
+ rechner nummern,
+ strom,
+ sequenz,
+ seitennummer,
+ TASK quelle,ziel,
+ INT sende code);
+
+BOUND STEUER VAR open block;
+
+BOUND STRUCT (STEUER steuer, INT typ) VAR info block;
+
+BOUND STRUCT (
+ INT head,
+ rechner nummern,
+ strom,
+ sequenz,
+ seitennummer) VAR vorspann ;
+
+BOUND STRUCT (
+ INT head,
+ rechner nummern,
+ strom,
+ code) VAR ack packet ;
+
+INT CONST max verbindungsnummer := max strom;
+
+BOOL PROC blockin (DATASPACE VAR ds, INT CONST seite, abstand, laenge):
+ INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512;
+ REAL VAR time out := clock (1) + 10.0;
+ REP
+ blockin (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge);
+ UNTIL hilfslaenge = 0 OR clock (1) > time out PER ;
+ hilfslaenge = 0
+END PROC blockin;
+
+PROC blockout (DATASPACE CONST ds, INT CONST seite, abstand, laenge):
+ INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512;
+ REP
+ blockout (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge);
+ UNTIL hilfslaenge = 0 PER
+END PROC blockout;
+
+
+
+
+DATASPACE VAR work space;
+
+
+INT CONST packete pro seite:= seitengroesse DIV nutzlaenge,
+ packete pro seite minus 1 := packete pro seite -1,
+ datenpacketlaenge := vorspannlaenge + nutzlaenge;
+
+INT VAR err,strom;
+
+INT VAR own:=station (myself) ,
+ quit max := 3,
+ quit zaehler := 3,
+ own256 := 256*own;
+INT CONST stx open := code stx+256*openlaenge,
+ stx quit := code stx+256*acklaenge;
+
+ ROW maxstrom1 STEUER VAR verbindungen;
+ ROW maxstrom1 DATASPACE VAR netz dr;
+ ROW maxstrom1 INT VAR zeit, typ;
+ FOR strom FROM 1 UPTO maxstrom1 REP vdr := nilspace; forget (vdr) PER;
+ ROW maxstrom INT VAR dr page ;
+ ROW maxtasks INT VAR alter call;
+ STEUER VAR opti;
+
+.vx : verbindungen (strom).
+
+vdr: netz dr (strom).
+
+falsche stromnummer: strom < 1 OR strom > maxstrom.
+
+call aufruf: typ(strom) >= call pingpong.
+
+alles raus: vx.seitennummer = -1 AND letztes packet der seite .
+
+letztes packet der seite :
+(vx.sequenz AND packete pro seite minus 1) = packete pro seite minus 1.
+
+PROC neuer start (INT CONST empfangsstroeme):
+ workspace := nilspace;
+ open block := workspace;
+ info block := workspace;
+ vorspann := workspace;
+ ack packet := workspace;
+ FOR strom FROM 1 UPTO maxstrom1 REP
+ vx.strom := 0; forget (vdr)
+ PER;
+ INT VAR i;
+ FOR i FROM 1 UPTO maxtasks REP alter call (i) := 0 PER;
+ quitmax := empfangsstroeme;
+ own:=station (myself);
+ quit zaehler := quit max;
+ own256 := 256*own;
+ reset box.
+
+reset box:
+ out (90*""4"");
+ REP UNTIL incharety (1) = "" PER.
+
+END PROC neuer start;
+
+DATASPACE PROC verbindung (INT CONST nr):
+ infoblock.steuer := verbindungen (nr);
+ infoblock.typ := typ (nr);
+ workspace
+END PROC verbindung;
+
+PROC neue sendung (TASK CONST q,z, INT CONST cod, DATASPACE CONST dr):
+
+ naechste verbindung vorbereiten;
+ forget (vdr); vdr := dr;
+ IF z = collector
+ THEN
+ verbindungsebene
+ ELSE
+ sendung starten (q,z,cod)
+ FI.
+
+verbindungsebene:
+ IF cod = 256 THEN name von fremdstation
+ ELIF cod > 256
+ THEN
+ taskinfo fremd
+ ELSE
+ task id von fremd
+ FI.
+
+taskinfo fremd: sendung starten (q, collector, cod-256, -8).
+
+task id von fremd: sendung starten (q,collector, zielstation,-6) .
+
+name von fremdstation:
+ BOUND TASK VAR tsk := vdr;
+ TASK VAR tsk1 := tsk;
+ forget (vdr);
+ vdr := nilspace;
+ sendung starten (q, tsk1, -7).
+
+zielstation: cod.
+
+END PROC neue sendung;
+
+PROC zeitueberwachung
+ (INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr):
+ snr INCR 1;
+ FOR strom FROM snr UPTO maxstrom REP zeitkontrolle PER;
+ snr := 0.
+
+zeitkontrolle:
+ IF vx.strom <> 0 AND zeit(strom) > 0
+ THEN
+ zeit(strom) DECR 1;
+ IF sendung noch nicht zugestellt
+ THEN
+ IF zeit(strom) = 0 THEN
+ report ("Nicht zustellbar. """+nam (vx.ziel)+""". "+
+ text (vx.rechnernummernDIV256));
+ loesche verbindung (strom)
+ ELSE
+ snr := strom;
+ q := vx.quelle;
+ z := vx.ziel;
+ ant := vx.sendecode;
+ dr := vdr;
+ LEAVE zeitueberwachung
+ FI
+ ELIF zeit(strom) = 0 THEN wiederholen FI
+ FI.
+
+sendung noch nicht zugestellt:
+ typ (strom) = zustellung.
+
+wiederholen:
+ IF sendeeintrag
+ THEN
+ sendung wiederholen
+ ELSE
+ empfangseintrag freigeben
+ FI.
+
+sendeeintrag : vx.rechnernummern DIV 256 = own .
+
+sendung wiederholen:
+ IF wiederholung noch sinnvoll
+ THEN
+ IF frisch
+ THEN
+ time out bei open
+ ELSE
+ datenteil wiederholen
+ FI
+ ELSE
+ sendung loeschen
+ FI.
+
+wiederholung noch sinnvoll:
+ task noch da AND bei call noch im call.
+
+task noch da: vx.quelle = collector OR exists (vx.quelle).
+
+bei call noch im call:
+ IF call aufruf
+ THEN
+ callee (vx.quelle) = vx.ziel
+ ELSE
+ TRUE
+ FI.
+
+frisch: vx.sequenz = -1.
+
+time out bei open:
+ IF vx.sendecode > -4 THEN open wiederholen ELSE nak an quelle senden FI.
+
+nak an quelle senden:
+ forget (vdr); vdr := nilspace;
+ BOUND TEXT VAR erm := vdr;
+ erm := "Station "+text(vx.rechnernummernMOD256)+" antwortet nicht";
+ snr := strom;
+ q := collector;
+ z := vx.quelle;
+ ant := error nak;
+ dr := vdr;
+ sendung loeschen;
+ LEAVE zeitueberwachung .
+
+open wiederholen:
+ sendereport ("wdh open");
+ zeit(strom) := 20;
+ openblock := vx;
+ openblock.head := stx open;
+ ab die post.
+
+datenteil wiederholen:
+ sendereport ("wdh data. sqnr "+text (vx.sequenz));
+ senden .
+
+empfangseintrag freigeben:
+ IF antwort auf call
+ THEN
+ weiter warten
+ ELSE
+ empfangsreport ("Empfangseintrag freigegeben");
+ empfang loeschen
+ FI.
+antwort auf call: callee (vx.ziel) = vx.quelle.
+
+weiter warten: zeit (strom) := 200.
+
+END PROC zeitueberwachung;
+
+PROC sendereport (TEXT CONST txt):
+ report (text (strom)+":"+txt+". Absender: """+nam (vx.quelle)+
+ """. Ziel "+text(vx.rechnernummernMOD256));
+END PROC sendereport;
+
+PROC empfangsreport (TEXT CONST txt):
+ report (text (strom)+":"+txt+". Empfnger: """
+ +nam (vx.ziel)+""". Quelle "+text (vx.rechnernummernDIV256));
+END PROC empfangsreport ;
+
+PROC sendung loeschen:
+ IF callaufruf CAND alter call (tasknr (vx.quelle)) = strom
+ THEN
+ alter call (tasknr (vx.quelle)) := 0
+ FI;
+ vx.strom := 0;
+ forget (vdr)
+END PROC sendung loeschen;
+
+PROC empfang loeschen:
+ quit zaehler INCR 1;
+ IF callaufruf AND alter call (tasknr (vx.ziel)) = strom
+ THEN
+ alter call (tasknr (vx.ziel)) := 0
+ FI;
+ forget (vdr);
+ vx.strom := 0
+END PROC empfang loeschen;
+
+PROC loesche verbindung (INT CONST nr):
+ strom := nr;
+ IF sendeeintrag
+ THEN
+ sendung loeschen
+ ELSE
+ gegenstelle zum loeschen auffordern;
+ empfang loeschen
+ FI.
+
+gegenstelle zum loeschen auffordern:
+ IF verbindung aktiv THEN quittieren (-loesche) FI.
+
+verbindung aktiv: vx.strom > 0.
+
+sendeeintrag: vx.rechnernummern DIV 256 = own .
+
+END PROC loesche verbindung;
+
+PROC weiter senden:
+ IF NOT alles raus
+ THEN
+ sequenz zaehlung;
+ IF neue seite THEN seitennummer eintragen FI;
+ senden
+ FI.
+
+sequenz zaehlung:
+ vx.sequenz INCR 1.
+
+neue seite:
+ (vx.sequenz AND packete pro seite minus 1) = 0.
+
+seitennummer eintragen:
+ dr page (strom) := vx.seiten nummer;
+ vx.seitennummer := next ds page (vdr, dr page (strom)).
+
+
+END PROC weiter senden;
+
+PROC senden:
+ zeit(strom) := 3;
+ vorspann senden;
+ daten senden.
+
+vorspann senden:
+ openblock := vx;
+ blockout (workspace, 1, dr verwaltungslaenge, vorspannlaenge).
+
+daten senden:
+ blockout (vdr,dr page (strom),distanz,nutzlaenge).
+
+distanz: nutzlaenge* (vx.sequenz AND (packete pro seite minus 1)).
+
+END PROC senden;
+
+PROC naechste verbindung vorbereiten:
+ FOR strom FROM 1 UPTO maxstrom REP
+ UNTIL vx.strom = 0 PER;
+ IF vx.strom <> 0 THEN errorstop ("Verbindungsengpass") FI.
+END PROC naechste verbindung vorbereiten;
+
+PROC sendung starten (TASK CONST quelle, ziel, INT CONST code):
+ sendung starten (quelle,ziel, station(ziel), code)
+END PROC sendung starten;
+
+PROC sendung starten (TASK CONST quelle, ziel, INT CONST ziel station,code):
+ IF ziel station = own
+ THEN
+ report ("Irrlufer: Sendung an eigene Station. Absender:"""+
+ nam (quelle)+""".");
+ vx.strom := 0;
+ forget (vdr)
+ ELSE
+ openblock.ziel := ziel;
+ openblock.quelle :=quelle;
+ openblock.sendecode := code;
+ openblock.rechnernummern:= ziel station + own256;
+ alten call loeschen (quelle);
+ IF call oder ping pong
+ THEN typ (strom) := call pingpong; call merken
+ ELSE typ (strom) := send wait FI;
+ sendung neu starten
+ FI.
+
+call oder pingpong: openblock.ziel = callee (openblock.quelle).
+
+call merken: alter call (tasknr (quelle)) := strom.
+
+END PROC sendung starten;
+
+PROC sendung neu starten:
+ openblock.head:= stx open;
+ openblock.sequenz := -1;
+ openblock.seitennummer:= next ds page (vdr,-1);
+ openblock.strom := strom;
+ vx := open block;
+ zeit(strom) := 3;
+ ab die post;
+ vx.head:=code stx+256*(vorspannlaenge+nutzlaenge).
+
+END PROC sendung neu starten; .
+
+ab die post:
+ block out (work space,1, dr verwaltungslaenge,open laenge).
+
+PROC alten call loeschen (TASK CONST quelle):
+ IF alter call aktiv
+ THEN
+ INT VAR lstrom := strom;
+ vx:=openblock;
+ strom := alter call (tasknr (quelle));
+ IF in ausfuehrungsphase
+ THEN
+ sendereport ("Call-Lschung vorgemerkt");
+ loeschung vormerken
+ ELSE
+ report ("Call gelscht."""+nam(quelle)+""". Strom "+text(strom));
+ loesche verbindung (strom)
+ FI;
+ strom := lstrom;
+ openblock := vx
+ FI.
+
+in ausfuehrungsphase:
+ typ(strom) = call im wait OR typ (strom) = call in zustellung.
+
+loeschung vormerken:
+ typ(strom) := call im abbruch;
+ alter call (tasknr (quelle)) := 0.
+
+
+ alter call aktiv:
+ alter call (tasknr (quelle)) > 0.
+
+END PROC alten call loeschen;
+
+PROC packet eingang
+ (TEXT CONST ft, INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr):
+ snr := 0;
+ vorspann holen;
+ IF NOT ring logik THEN daten teil FI.
+
+ring logik: FALSE.
+# IF selbst quelle THEN daten aus puffer entfernen ; TRUE
+ ELIF NOT selbst ziel THEN weitergeben; TRUE
+ ELSE FALSE
+ FI.
+
+selbst quelle: openblock.rechnernummern DIV 256 = station (myself).
+
+selbst ziel: (openblock.rechnernummern AND 255) = own.
+#
+daten aus puffer entfernen:
+ IF code (t) > nutzlaenge
+ THEN
+ BOOL VAR dummy :=blockin (workspace, 1, drverwaltungslaenge, nutzlaenge)
+ FI.
+#
+weitergeben:
+ IF code (t) > nutzlaenge
+ THEN
+ IF NOT blockin (workspace, 2, 0, nutzlaenge)
+ THEN LEAVE test auf packeteingang FI;
+ FI;
+ out (stx+t);
+ blockout (workspace, 1, drverwaltungslaenge2, blocklaenge);
+ IF code (t) > nutzlaenge
+ THEN
+ blockout (workspace, 2, 0, nutzlaenge)
+ FI.
+#
+vorspann holen:
+ sync;
+ IF NOT blockin (workspace, 1, dr verwaltungslaenge2, block laenge)
+ THEN LEAVE packeteingang
+ FI.
+
+
+blocklaenge: IF code t > nutzlaenge
+ THEN
+ vorspannlaenge-2
+ ELSE
+ code t -2
+ FI.
+
+sync:
+ TEXT VAR skipped:=ft , t :="";
+ REP
+ skipped CAT t;
+ t := incharety (1);
+ IF t = "" THEN
+ report ("skipped",skipped);
+ LEAVE packet eingang
+ FI ;
+ INT VAR codet := code (t);
+ UNTIL blockanfang PER;
+ IF skipped <> stx THEN report ("skipped bei sync:", skipped) FI.
+
+blockanfang:
+ (skipped SUB length(skipped)) = stx
+ AND
+ (codet = datenpacketlaenge
+ OR codet = ack laenge OR codet = neue ack laenge OR code t = openlaenge).
+
+daten teil:
+ IF neue verbindung
+ THEN
+ verbindung bereitstellen
+ ELIF quittung
+ THEN
+ strom := ack packet.strom;
+ IF falsche stromnummer THEN report ("Strom falsch in Quittung");
+ LEAVE datenteil FI;
+ IF vx.strom = 0 THEN LEAVE datenteil FI;
+ IF ackpacket.code >= ok THEN weiter senden
+ ELIF ackpacket.code = -von vorne THEN
+ sendereport ("Neustart");
+ openblock := vx;
+ sendung neu starten
+ ELIF ackpacket.code = -wiederhole THEN back 16
+ ELIF ackpacket.code = -loesche THEN fremdloeschung
+ ELIF ackpacket.code = -beende AND alles raus THEN strom abschliessen
+ FI
+ ELIF verbindung festgestellt
+ THEN
+ zeit(strom) := 200;
+ opti := vx;
+ datenpacket
+ ELSE
+ strom := maxstrom1;
+ vx:=openblock;
+ report ("Daten ohne Eroeffnung von " +text(vx.rechnernummernDIV256)
+ +" Sequenznr "+text(openblock.sequenz));
+ daten aus puffer entfernen;
+ IF alles raus THEN quittieren (-beende) ELSE quittieren(-von vorne) FI
+ FI.
+
+verbindung bereitstellen:
+ IF openblock.ziel = collector OR station (openblock.ziel) = own
+ THEN
+ freie verbindungsnummer;
+ vdr := nilspace;
+ vx := open block;
+ zeit(strom) := 10;
+ quittieren falls genug pufferplatz;
+ vx.sequenz := 0 ;
+ IF loeschung vorgemerkt
+ THEN
+ loesche verbindung (strom)
+ ELSE
+ opti := vx;
+ abschluss testen
+ FI;
+ FI.
+
+loeschung vorgemerkt: typ(strom) = call im abbruch.
+
+strom abschliessen:
+ IF call aufruf THEN zeit(strom) := 80; ausfuehrungsphase merken
+ ELSE
+ vx.strom := 0;
+ forget (vdr)
+ FI.
+
+ausfuehrungsphase merken: typ(strom) := call in zustellung.
+
+back16:
+ datenraum etwas rueckspulen;
+ nicht sofort senden (* wegen vagabundierender Quittungen *).
+
+nicht sofort senden: zeit(strom) := 2.
+
+datenraum etwas rueckspulen:
+ sendereport ("etwas rueckgespult");
+ INT VAR sk , vs :=-1;
+ dr page (strom) := -1;
+ INT VAR i;
+ FOR i FROM 1 UPTO vx.sequenz DIV packete pro seite - etwas REP
+ vs INCR packete pro seite;
+ dr page (strom) := next ds page (vdr, dr page (strom))
+ PER;
+ vx.seiten nummer := next ds page (vdr, dr page (strom)) ;
+ vx.sequenz := vs.
+
+etwas: 3.
+
+fremdloeschung:
+ IF fremdrechner ok und sendung
+ THEN
+ IF typ (strom) = call in zustellung
+ THEN
+ typ (strom) := call im wait
+ ELSE
+ sendereport ("Sendung von Gegenstelle geloescht");
+ sendung loeschen
+ FI
+ FI.
+
+fremdrechner ok und sendung:
+ (ackpacket.rechnernummern DIV 256) = (vx.rechnernummern AND 255).
+
+
+quittieren falls genug pufferplatz:
+ IF quit zaehler > 0 THEN
+ quit zaehler DECR 1;
+ open quittieren;
+ block vorab quittieren
+ FI.
+
+open quittieren: quittieren (ok).
+block vorab quittieren: quittieren (ok).
+
+quittung: code t <= neue ack laenge.
+
+neue verbindung: code t = open laenge.
+
+verbindung festgestellt:
+ FOR strom FROM maxstrom DOWNTO 1 REP
+ IF bekannter strom
+ THEN LEAVE verbindung festgestellt WITH TRUE FI
+ PER;
+ FALSE.
+
+bekannter strom:
+ vx.strom = vorspann.strom AND vom selben rechner.
+
+vom selben rechner:
+ vx.rechnernummern = vorspann.rechnernummern.
+
+daten:
+ IF NOT blockin (vdr, opti.seiten nummer, distanz, nutzlaenge)
+ THEN quittieren (-wiederhole); LEAVE packeteingang
+ FI;
+ sequenz zaehlung;
+ IF neue seite kommt
+ THEN
+ vx.seiten nummer := vorspann.seiten nummer
+ FI.
+
+datenpacket:
+ IF sendung wartet auf zustellung THEN auffrischen ELSE daten holen FI.
+
+sendung wartet auf zustellung: typ (strom) = zustellung.
+
+auffrischen: zeit (strom) := 100; daten aus puffer entfernen.
+
+daten holen:
+ IF opti.sequenz >= vorspann.sequenz AND opti.sequenz < vorspann.sequenz+100
+ THEN
+ IF opti.sequenz <> vorspann.sequenz
+ THEN empfangsreport ("Sequenzreset von "+text(opti.sequenz)+" auf "+
+ text (vorspann.sequenz));
+ vx.sequenz := vorspann.sequenz;
+ vorabquittung regenerieren
+ FI;
+ quittieren(ok);
+ daten ;
+ abschluss testen
+ ELSE
+ empfangsreport ("Sequenzfehler: soll "+text(vx.sequenz)+" ist "+
+ text(vorspann.sequenz));
+ quittieren (-wiederhole);
+ daten aus puffer entfernen
+ FI.
+
+vorabquittung regenerieren: quittieren (ok).
+
+distanz: (opti.sequenz AND packete pro seite minus 1 ) * nutzlaenge.
+
+sequenz zaehlung:
+ vx.sequenz INCR 1.
+
+neue seite kommt:
+(vx.sequenz AND packete pro seite minus1) = 0.
+
+freie verbindungsnummer:
+ INT VAR h strom :=0;
+ FOR strom FROM 1 UPTO maxstrom REP
+ IF vx.strom = 0 THEN h strom := strom
+ ELIF bekannter strom
+ THEN empfangsreport ("Reopen");
+ quit zaehler INCR 1;
+ forget (vdr);
+ LEAVE freie verbindungsnummer
+ ELIF antwort auf call
+ THEN
+ typ (strom) := call pingpong;
+ forget (vdr);
+ LEAVE freie verbindungsnummer
+ FI
+ PER;
+ strom := h strom;
+ IF strom = 0 THEN
+ error stop ("Zuviele simulatane Verbindungen")
+ FI;
+ typ(strom) := send wait.
+
+antwort auf call:
+ openblock.sendecode >= 0 AND
+ call aufruf AND vx.quelle = openblock.ziel AND vx.ziel = openblock.quelle.
+
+abschluss testen:
+ IF neue seite kommt AND vx.seiten nummer = -1
+ THEN
+ quittieren (-beende);
+ an ziel weitergeben
+ FI.
+
+an ziel weitergeben:
+ IF tasknummerfrage THEN taskfrage beantworten ;pufferplatz freigeben;
+ ELIF tasknamenfrage THEN name senden ;pufferplatz freigeben;
+ ELIF taskinfofrage THEN task info senden;pufferplatz freigeben;
+ ELSE senden
+ FI.
+
+pufferplatz freigeben: quitzaehler INCR 1.
+
+senden:
+ max 100 versuche;
+ snr := strom;
+ IF NOT callaufruf THEN typ (strom) := zustellung FI;
+ q := vx.quelle;
+ z := vx.ziel;
+ ant := vx.sendecode;
+ dr := vdr;
+ LEAVE packet eingang.
+
+tasknummerfrage:opti.sendecode = -6.
+
+tasknamenfrage: opti.sendecode = -7.
+
+taskinfofrage: opti.sendecode = -8.
+
+max 100 versuche: zeit(strom) := 100.
+
+taskfrage beantworten:
+ BOUND TEXT VAR tsk := vdr;
+ TEXT VAR save tsk := tsk;
+ forget (vdr); vdr := nilspace;
+ BOUND TASK VAR task id := vdr;
+ disable stop;
+ task id := task(save tsk);
+ IF is error THEN
+ clear error; enable stop;
+ forget (vdr); vdr := nilspace;
+ BOUND TEXT VAR errtxt := vdr;
+ errtxt := text(station(myself))+"/"""+save tsk+""" gibt es nicht";
+ sendung starten (collector, opti.quelle, 2)
+ ELSE
+ enable stop;
+ sendung starten (collector, opti.quelle, 0)
+ FI.
+
+name senden:
+ forget (vdr); vdr := nilspace;
+ tsk := vdr;
+ disable stop;
+ tsk := nam (opti.ziel);
+ clear error; enable stop;
+ sendung starten (collector, opti.quelle, 0).
+
+task info senden:
+ BOUND INT VAR ti code := vdr;
+ INT VAR ti cd := ti code;
+ forget (vdr); vdr := nilspace;
+ FILE VAR task inf := sequential file (output,vdr);
+ head line (task inf,"Station "+text(own));
+ task info (ti cd, task inf);
+ sendung starten (collector,opti.quelle,0).
+
+END PROC packet eingang;
+
+PROC quittieren(INT CONST code) :
+ quellrechner wird zielrechner;
+ ackpacket.code := code;
+ ackpacket.head := stx quit;
+ ackpacket.strom := vx.strom;
+ blockout (workspace,1,dr verwaltungslaenge, ack laenge).
+
+quellrechner wird zielrechner:
+ ack packet.rechnernummern := vx.rechnernummern DIV 256
+ + own256.
+
+END PROC quittieren;
+
+END PACKET basic net;
diff --git a/system/net/1.7.5/src/callee b/system/net/1.7.5/src/callee
new file mode 100644
index 0000000..42d80da
--- /dev/null
+++ b/system/net/1.7.5/src/callee
@@ -0,0 +1,14 @@
+PACKET callee DEFINES callee:
+
+TASK PROC callee (TASK CONST t):
+ IF im wait THEN trick 1 (t); trick 2 ELSE niltask FI.
+im wait: (status(t) AND 3) = 2.
+END PROC callee;
+
+PROC trick 1 (TASK CONST t):
+ INT VAR x := pcb(t,11), y:=pcb(t,12);
+END PROC trick1;
+
+TASK PROC trick 2: TASK VAR calle; calle END PROC trick2;
+
+END PACKET callee;
diff --git a/system/net/1.7.5/src/net inserter b/system/net/1.7.5/src/net inserter
new file mode 100644
index 0000000..8cccedd
--- /dev/null
+++ b/system/net/1.7.5/src/net inserter
@@ -0,0 +1,50 @@
+
+{ Inserter fr EUMEL - Netz - Software; 04.12.83
+ bercksichtigt EUMEL - Versionen 1.7.3 und 1.7.5, sowie Multi / Single }
+
+
+INT VAR version :: id (0), cy :: 4;
+IF online THEN head FI;
+
+IF ich bin multi THEN insert multi net
+ ELSE meldung an single
+FI.
+
+ich bin multi : (pcb (9) AND 255) > 1.
+
+insert multi net :
+ IF version >= 173 THEN IF version < 175 THEN insert and say ("callee") FI;
+ insert and say ("net report/M");
+ insert and say ("basic net");
+ insert and say ("net manager/M")
+ ELSE versionsnummer zu klein
+ FI.
+
+meldung an single :
+ cursor (1, cy);
+ putline
+ ("Das EUMEL - Netz ist zur Zeit nur auf Multi - User - Versionen");
+ putline ("installierbar !").
+
+head :
+ page;
+ putline (" E U M E L - Netz - Inserter");
+ put ("---------------------------------").
+
+versionsnummer zu klein :
+ cursor (1, cy);
+ putline ("Netzsoftware erst ab Version 1.7.3 insertierbar !").
+
+PROC insert and say (TEXT CONST name of packet):
+ IF online THEN cl eop (1, cy);
+ put ("Paket '" + name of packet + "' wird insertiert");
+ line (2);
+ cy INCR 1
+ FI;
+ insert (name of packet);
+END PROC insert and say;
+
+PROC cl eop (INT CONST cx, cy) :
+ cursor (cx, cy);
+ out (""4"")
+END PROC cl eop;
diff --git a/system/net/1.7.5/src/net manager-M b/system/net/1.7.5/src/net manager-M
new file mode 100644
index 0000000..0383211
--- /dev/null
+++ b/system/net/1.7.5/src/net manager-M
@@ -0,0 +1,302 @@
+PACKET net manager DEFINES start,stop,net manager,frei:
+TEXT VAR stand := "Netzsoftware vom 02.09.85";
+ (*Heinrichs *)
+
+LET
+ ack = 0,
+ nak = 1,
+ error nak = 2,
+ zeichen eingang = 4,
+ list code = 15,
+ fetch code = 11,
+ freigabecode = 29,
+ continue code = 100,
+ erase code = 14,
+ report code = 99,
+
+ (* Typen von Kommunikationsstrmen *)
+
+ send wait = 0,
+ zustellung = 1,
+ call pingpong = 2,
+ call im wait = 3,
+ call im abbruch = 4,
+ call in zustellung = 5;
+
+LET STEUER =
+ STRUCT (
+ INT head,
+ rechner nummern,
+ strom,
+ INT sequenz,
+ seiten nummer,
+ TASK quelle,ziel,
+ INT sende code);
+
+LET INFO = STRUCT (STEUER steuer, INT typ);
+
+TASK VAR sohn;
+INT VAR strom,c.
+
+vx: v.steuer.
+
+PROC frei (INT CONST stat,lvl):
+ DATASPACE VAR ds := nilspace;
+ BOUND STRUCT (INT x,y) VAR msg := ds;
+ msg.x := stat; msg.y := lvl;
+ INT VAR return;
+ call (/"net port", freigabecode, ds, return) ;
+ forget (ds)
+END PROC frei;
+
+PROC net manager (DATASPACE VAR ds, INT CONST order, phase, TASK CONST
+ ordertask):
+
+ IF order = report code
+ THEN
+ forget ("report",quiet);
+ copy (ds,"report");
+ forget (ds)
+ ELSE
+ IF ordertask < myself
+ OR order = list code
+ OR order > continue code
+ THEN
+ IF order = list code
+ THEN
+ enable stop;
+ forget (ds); ds := old ("report");
+ FILE VAR ff := sequential file (output,ds);
+ putline (ff,stand);
+ putline (ff,"Rechner "+text(station(myself))+" um "+time of day);
+ send (ordertask, ack, ds)
+ ELSE
+ free manager (ds,order,phase,order task)
+ FI
+ ELSE
+ errorstop ("nur 'list' ist erlaubt")
+ FI
+ FI
+END PROC net manager;
+
+TASK VAR cd,stask;
+ROW 255 INT VAR erlaubt;
+INT VAR i;
+FOR i FROM 1 UPTO 255 REP erlaubt (i) := 0 PER;
+
+PROC communicate:
+ enable stop;
+ INT VAR scode;
+ DATASPACE VAR dr := nilspace;
+ neuer start (quit max);
+REP
+ forget (dr);
+ wait (dr, scode, stask);
+ cd := collected destination;
+ IF zeichen da OR zeit abgelaufen
+ THEN
+ packet
+ ELIF cd = myself
+ THEN
+ netz info und steuerung
+ ELSE
+ neue sendung (stask, cd, scode, dr)
+ FI
+PER.
+
+zeichen da: scode < 0 .
+
+zeit abgelaufen: scode = ack AND cd = myself.
+
+packet:
+ TEXT VAR t := incharety;
+ INT VAR snr, ant,err;
+ TASK VAR quelle, ziel;
+ snr := 0;
+ REP
+ IF t = ""
+ THEN
+ zeitueberwachung (snr, quelle, ziel, ant, dr);
+ ELSE
+ packet eingang (t, snr, quelle, ziel, ant, dr);
+ FI;
+ IF snr > 0
+ THEN
+ IF ant > 5 AND erlaubt(station (quelle)) < 0
+ THEN unerlaubt
+ ELSE
+ send (quelle,ziel,ant,dr,err);
+ fehlerbehandlung ;
+ FI
+ FI
+ UNTIL snr = 0 OR zeichen da PER.
+
+fehlerbehandlung:
+ IF ok oder ziel nicht da THEN loesche verbindung (snr) FI.
+
+ok oder ziel nicht da: err=0 OR err=-1.
+
+netz info und steuerung:
+ IF scode = list code THEN list status
+ ELIF scode = erase code THEN strom beenden
+ ELIF scode = freigabe code AND stask = father THEN freigabelevel
+ ELSE forget (dr); ablehnen ("nicht mglich")
+ FI.
+
+freigabelevel:
+ BOUND STRUCT (INT stat,lvl) VAR lv := dr;
+ IF lv.stat > 0 AND lv.stat < 256 THEN erlaubt (lv.stat) := lv.lvl FI;
+ send (stask,ack,dr).
+
+unerlaubt:
+ report ("Fremdzugriff von "+text(station (quelle))+" auf "+nam(ziel)
+ +" code "+text(ant));
+ loesche verbindung (snr).
+
+strom beenden:
+ BOUND TEXT VAR stromtext := dr;
+ INT VAR erase strom := int (stromtext);
+ forget (dr);
+ strom := erase strom;
+ IF falsche stromnummer THEN ablehnen ("Strom gibt es nicht")
+ ELSE
+ BOUND INFO VAR v := verbindung (strom);
+ IF
+ stask = father OR stask = vx.quelle OR stask = vx.ziel
+ THEN
+ loeschen
+ ELSE ablehnen ("Nur Empfnger/Absender darf lschen")
+ FI
+ FI.
+
+loeschen:
+ IF sendeeintrag THEN
+ IF callee (vx.quelle) = vx.ziel THEN absender warnen FI;
+ loesche verbindung (strom)
+ ELSE
+ IF callee (vx.ziel) = vx.quelle THEN warnen FI;
+ loesche verbindung (strom)
+ FI;
+ dr := nilspace;
+ send (stask,ack,dr).
+
+absender warnen:
+ dr := nilspace;
+ send(vx.ziel,vx.quelle,1,dr,err) .
+
+warnen:
+ dr := nilspace;
+BOUND TEXT VAR errtxt := dr; errtxt:= "Station antwortet nicht";
+send (vx.quelle,vx.ziel,error nak, dr, err).
+
+falsche stromnummer: strom < 1 OR strom > max verbindungsnummer.
+sendeeintrag: vx.rechnernummern DIV256 = station (myself).
+END PROC communicate;
+
+PROC ablehnen (TEXT CONST t):
+ DATASPACE VAR vdr := nilspace;
+ BOUND TEXT VAR errtxt := vdr;
+ errtxt := t;
+ send (stask, error nak, vdr).
+END PROC ablehnen;
+
+PROC stop:
+ disable stop;
+ end (task ("net port"));
+ end (task ("net timer"));
+ clear error;
+END PROC stop;
+
+PROC list status:
+
+ DATASPACE VAR ds := nilspace;
+ FILE VAR f:=sequential file (output, ds);
+ FOR strom FROM 1 UPTO max verbindungsnummer REP
+ BOUND INFO VAR v := verbindung (strom);
+ IF vx.strom <> 0 THEN info FI
+ PER;
+ send (stask, ack, ds).
+
+info:
+ put (f,"Strom "+text(strom)+" (sqnr"+text(vx.sequenz)+")");
+ IF sendeeintrag THEN sendeinfo ELSE empfangsinfo FI;
+ line (f).
+
+sendeeintrag: vx.rechnernummern DIV 256 = station(myself) .
+
+sendeinfo:
+ IF v.typ = call im wait THEN put (f,"erwartet Antwort von")
+ ELIF v.typ = call in zustellung THEN put (f,"Ziel busy. Zielstation:")
+ ELIF v.typ = call im abbruch THEN put (f,"wird gelscht bei Antwort von")
+ ELSE put (f,"sendet an")
+ FI;
+ put (f,vx.rechnernummernMOD256);
+ put (f,". Absender ist """+nam (vx.quelle)+""".").
+
+empfangsinfo:
+ IF v.typ = zustellung THEN
+ put (f,"Sendung noch nicht zustellbar")
+ ELSE
+ put (f,"empfngt von");
+ put (f,vx.rechnernummernDIV256);
+ FI;
+ put (f,". Empfaenger ist """+nam (vx.ziel)+""".").
+END PROC list status;
+
+
+PROC start (INT CONST chan):
+ c:=chan;
+ start
+END PROC start;
+INT VAR quitmax := 3;
+PROC start (INT CONST chan,quit):
+ quitmax := quit;
+ c:=chan;
+ start
+END PROC start;
+
+PROC start:
+stop;
+IF exists ("report") THEN forget ("report") FI;
+FILE VAR s := sequential file (output,"report");
+putline (s," N e u e r S t a r t "+time of day);
+begin ("net port",PROC net io, sohn);
+TASK VAR dummy;
+begin ("net timer",PROC timer,dummy);
+define collector (sohn)
+END PROC start;
+
+PROC timer:
+ disable stop;
+ REP
+ clear error;
+ DATASPACE VAR ds := nilspace;
+ pause (100);
+ send (sohn, ack, ds)
+ PER;
+END PROC timer;
+
+PROC net io:
+ disable stop;
+ fetch ("report");
+ commanddialogue (FALSE);
+ continue (c);
+ communicate;
+ TEXT VAR emsg := "++++++ "+error message +" Zeile "+text(errorline);
+ clear error;
+ report (emsg);
+ save ("report");
+ end (myself)
+END PROC net io;
+
+put ("Netzkanalnummer:"); get (c);line;
+IF yes ("Ist der Netzkanal mit Flukontrolle verdrahtet") THEN
+ quit max := 10
+ELSE
+ quit max := 3
+FI;
+END PACKET net manager;
+
+
+start; global manager (PROC (DATASPACE VAR,INT CONST,INT CONST, TASK
+CONST) net manager )
diff --git a/system/net/1.7.5/src/net report-M b/system/net/1.7.5/src/net report-M
new file mode 100644
index 0000000..3ce67ff
--- /dev/null
+++ b/system/net/1.7.5/src/net report-M
@@ -0,0 +1,29 @@
+PACKET net report DEFINES report:
+
+LET reportcode = 99;
+
+PROC report (TEXT CONST x):
+ report(x,"")
+END PROC report;
+
+PROC report (TEXT CONST txt, info):
+ IF storage (old("report")) > 20 THEN forget ("report",quiet) FI;
+ reportfile := sequential file (output, "report");
+ put (reportfile, date);
+ put (reportfile, time of day);
+ put (reportfile, txt);
+ INT VAR i;
+ FOR i FROM 1 UPTO length (info) REP
+ INT VAR z := code (infoSUBi) ;
+ IF z < 32 OR z > 126
+ THEN put (reportfile,"%"+text(z))
+ ELSE put (reportfile,infoSUBi)
+ FI
+ PER;
+ line (reportfile);
+ DATASPACE VAR net report := old ("report");
+ send (father, report code , net report)
+END PROC report;
+FILE VAR reportfile;
+
+END PACKET net report;
diff --git a/system/net/1.8.7/doc/netzhandbuch b/system/net/1.8.7/doc/netzhandbuch
new file mode 100644
index 0000000..7083462
--- /dev/null
+++ b/system/net/1.8.7/doc/netzhandbuch
@@ -0,0 +1,2045 @@
+____________________________________________________________________________
+
+
+#on("b")##on ("u")#
+#center#Betriebssystem E U M E L
+#off ("u")#
+
+
+#center#Netzsoftware
+
+
+
+
+#off("b")#
+#center#Lizenzfreie Software der
+#on ("b")#
+
+#center#Gesellschaft für Mathematik und Datenverarbeitung mbH,
+#center#5205 Sankt Augustin
+
+
+#off("b")#
+#center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für
+#center#nichtkommerzielle Zwecke gestattet.
+
+#center#Gewährleistung und Haftung werden ausgeschlossen
+
+
+____________________________________________________________________________
+#page#
+#pagenr ("%",1)##setcount(1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Inhalt
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right# GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+
+#center#Inhalt
+
+#clear pos##lpos(1.0)##rpos(9.5)#
+#table#
+
+1. Einleitung #topage("0")#
+
+Teil 1: Netz einrichten und benutzen #topage("1")#
+
+
+1.1. Hardwarevoraussetzungen #topage("1.1")#
+1.2. Einrichten des Netzes #topage("1.2")#
+1.3. Benutzung des Netzes #topage("1.3")#
+1.4. Informationsmöglichkeiten #topage("1.4")#
+1.5. Eingriffsmöglichkeiten #topage("1.5")#
+1.6. Fehlerbehebung im Netz #topage("1.6")#
+1.7. Sicherheit im Netz #topage("1.7")#
+
+
+
+Teil 2: Arbeitsweise der Netzsoftware #topage("2")#
+
+
+2.1. Die Netztask #topage("2.1")#
+2.2. Protokollebenen #topage("2.2")#
+2.3. Stand der Netzsoftware #topage("2.3")#
+
+
+
+Teil 3: Netz-Hardware-Interface #topage("3")#
+
+
+3.1. Einführung #topage("3.1")#
+3.2. Arbeitsweise des Netz-Hardware-Interfaces #topage("3.2")#
+3.3. Netztreiber #topage("3.3")#
+3.4. Prozedurschnittstelle des EUMEL-Netzes #topage("3.4")#
+
+
+
+Anhang #topage("A")#
+
+
+1. Fehlermeldungen #topage("A.1")#
+2. Literaturhinweise #topage("A.2")#
+3. Index #topage("A.3")#
+
+#table end#
+#clear pos#
+
+#page#
+#pagenr ("%", 2)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Einleitung
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+
+1. Einleitung
+
+#goalpage("0")#
+Das EUMEL-Netz dient dazu, mehrere EUMEL-Rechner (sog. #ib#Station#ie#en) miteinan­
+der zu koppeln. Diese Kopplung wird vom Betriebssystem dazu benutzt, das Sen­
+dungskonzept [1] so auszudehnen, daß Tasks verschiedener Stationen einander
+Datenräume zusenden können. Auf dem #ib#Sendungskonzept#ie# aufbauende Konzepte
+nutzen daher automatisch das Netz aus: So ist es z.B. möglich
+
+- von einer Station aus auf einer anderen zu drucken,
+
+- in die Task PUBLIC einer anderen Station #ib#Datei#ie#en zu sichern (save), vorausge­
+ setzt, daß PUBLIC dort ein #on("b")#free global manager#off("b")# ist,
+
+- auf einer anderen Station zu archivieren (z.B. wenn das eigene Archivlaufwerk
+ defekt ist oder ein anderes Format hat).
+
+Diese #ib#Netzversion#ie# kann ab EUMEL-Version 1.8.1 eingesetzt werden.
+
+Diese Netzbeschreibung besteht aus drei Teilen. In Teil 1 wird beschrieben, wie das
+EUMEL-Netz benutzt und eingerichtet wird. Als Benutzer eines EUMEL-
+Rechners, der vernetzt ist, ist nur dieser Teil der Netzbeschreibung für Sie wichtig.
+Teil 2 erklärt die Funktionsweise der #ib#Netzsoftware#ie#, im dritten Teil wird die Schnitt­
+stelle für die Anpassung anderer #ib#Netzhardware#ie# definiert.
+
+Hinweis:
+
+Zur erstmaligen #ib#Installation#ie# des EUMEL-Netzes ist außer dieser Beschreibung noch
+die Netzsoftware (auf Floppy) und die EUMEL-Netz-#ib#Installationsanleitung#ie#, die mit
+der Software geliefert wird, notwendig.
+
+In der vorliegenden Netzbeschreibung wird das EUMEL-Netz möglichst "hardware
+unabhängig" beschrieben. Wenn hardwareabhängige Beispiele gegeben werden, so
+ist die dort beschriebene Hardware stets die #ib#Datenbox#ie#.
+#pagenr ("%", 3)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#cneter#____________________________________________________________
+
+#end#
+#headodd#
+#center#Teil 1 : Netz einrichten und benutzen
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#page#
+
+Teil 1: Netz einrichten und benutzen
+#goalpage("1")#
+
+
+
+1.1. Hardwarevoraussetzungen
+#goalpage("1.1")#
+
+
+Zwei Stationen
+
+Sie können zwei #ib#Station#ie# miteinander vernetzen, wenn Sie dafür an jeder Station eine
+#ib#V.24#ie#-#ib#Schnittstelle#ie# zur Verfügung stellen.
+
+Diese beiden Schnittstellen verbinden Sie mit einem Kabel zur #ib#Rechnerkopplung#ie# [2].
+
+
+Mehrere Stationen
+
+Wenn Sie mehr als zwei Stationen vernetzen wollen, stehen Ihnen zwei Konzepte zur
+Verfügung: das Anlegen von #ib#Netzknoten#ie# bzw. das Verwenden eines #ib#Strang#ie#es. Die
+Konzepte können gemischt eingesetzt werden.
+
+Ein Strang besteht aus einer Anzahl von #ib#Netzbox#ie#en (z.B. KHW-Box oder Ethernet­
+anschluß).
+
+Jede Box besitzt eine #ib#Schnittstelle#ie# (z.B. #ib#V.24#ie#) zum Anschluß an einen der Kanäle
+1...15 der zugeordneten #ib#Station#ie# und eine weitere Schnittstelle zur #ib#Verbindung#ie# der
+Boxen untereinander.
+
+Ein #ib#Knoten#ie# ist eine Station, bei der der Netzbetrieb über mehrere Kanäle läuft.
+
+Da die #ib#Netzsoftware#ie# pro #ib#Kanal#ie# eines Knotens eine Task generiert, ist das Knoten­
+konzept dem Strangkonzept hinsichtlich des #ib#Durchsatz#ie#es unterlegen. Preisgünstiger
+ist jedoch das #ib#Knotenkonzept#ie#, weil dabei #ib#Netzbox#ie#en überflüssig werden.
+
+Beim Knotenkonzept wird eine #ib#Vermaschung#ie# nicht zur Optimierung benutzt (Ver­
+maschung heißt, daß eine #ib#Zielstation#ie# über verschiedene Knoten erreichbar ist). Daher
+sollte man keine Vermaschung vorsehen.
+
+#ib#Nachbarn#ie# sind Stationen, die an denselben #ib#Netzstrang#ie# angeschlossen oder direkt
+über ein #ib#V.24#ie#-Kabel verbunden sind.
+
+Bei der Entscheidung, welche Stationen man zu #ib#Knoten#ie# macht, sollte beachtet wer­
+den, daß (a) Stationen, zwischen denen hoher Verkehr besteht, Nachbarn werden und
+daß (b) besonders leistungsfähige Rechner #ib#Knoten#ie#stationen sein sollten.
+#page#
+
+1.2. Einrichten des Netzes
+#goalpage("1.2")#
+
+
+Hinweis: Dieses Kapitel ist nur für Systembetreuer wichtig.
+
+a) Legen Sie für die am Netz beteiligten Rechner #ib#Stationsnummer#ie#n fest (von 1 an
+ aufsteigend).
+
+ Die Boxen haben ebenfalls Stationsnummern. Die Stationsnummern der Box und
+ des zugeordneten Rechners müssen übereinstimmen.
+
+
+b) Holen Sie an jeder #ib#Station#ie# die Task #on("bold")#configurator#off("bold")# an ein Terminal und geben Sie
+ das Kommando #on("bold")##ib#define station#ie# (x)#off("bold")#, wobei #on("bold")#x#off("bold")# die gewählte Stationsnummer ist.
+
+ Hinweis: Taskkommunikationen, die zu diesem Zeitpunkt laufen, führen zu feh­
+ lerhaftem Verhalten. Dies liegt daran, daß durch #on("bold")#define station#off("bold")# alle
+ #ib#Task-Id#ie#'s geändert werden müssen, weil eine #ib#Task-Id#ie# u.a. die
+ Stationsnummer der eigenen Station enthält (siehe 1.3). TASK-
+ Variablen, die noch Task-Id's mit keiner oder falscher Stationsnum­
+ mer enthalten, können nicht mehr zum Ansprechen einer Task ver­
+ wendet werden.
+
+ Beispiel: Der #ib#Spoolmanager#ie# [3] richtet beim Kommando #on("bold")#start#off("bold")# einen #ib#Worker#ie# ein
+ und merkt sich dessen #ib#Task-Id#ie# in einer TASK-Variablen, um sicher­
+ zustellen, daß nur der Worker #ib#Datei#ie#en zum Drucken abholt. Wird jetzt
+ das Kommando #on("bold")# define station#off("bold")# gegeben, kann der Spoolmanager
+ seinen Worker nicht mehr identifizieren, weil der Worker eine neue
+ Task-Id erhalten hat. Man muß daher vor #on("b")#define station#off("b")# den Worker
+ löschen und ihn danach mit dem Kommando #on("bold")##ib#start#ie##off("bold")# im Spoolmanager
+ wieder neu einrichten.
+
+
+ Sinnvollerweise gibt man #on("bold")#define station#off("bold")# sofort nachdem man ein frisches System
+ vom Archiv geladen hat.
+
+ Zum Anschluß einer #ib#Datenbox#ie# #ib#konfigurieren#ie# Sie mit dem Kommando #on("bold")##ib#configurate#ie##off("bold")#
+ den für das Netz vorgesehenen #ib#Kanal#ie# auf
+
+ - transparent
+ - 9600 #ib#Baud#ie# (Standardeinstellung der Boxen)
+ - #ib#RTS/CTS#ie#-#ib#Protokoll#ie#
+ - großen Puffer
+ - 8 bit
+ - even parity
+ - 1 stopbit.
+
+ Falls diese Einstellungen nicht alle angeboten werden, klären Sie mit Ihrem
+ Rechnerlieferanten, ob und wie diese Einstellungen erreicht werden können.
+
+ Hinweis: Notfalls kann auf das #ib#RTS/CTS#ie#-Protokoll verzichtet werden, wenn der
+ Eingabepuffer der #ib#Station#ie# groß genug ist. Die Anzahl simultan laufen­
+ der Netzkommunikationen ist dann auf
+
+ puffergröße DIV 150
+
+ begrenzt (bei Z80, 8086: 3; bei M20: 10).
+
+ Hinweis: Es können auch andere #ib#Baud#ie#raten (2400, 4800, 19200) an der Box
+ eingestellt werden.
+
+
+c) Achten Sie bei der #ib#Verbindung#ie# von der Station zur #ib#Netzbox#ie# (bzw. zur Gegen­
+ station bei einem Zweistationennetz ohne Boxen) darauf, daß neben den Emp­
+ fangs- und Sendeleitungen auch die Leitungen RTS und CTS verdrahtet wer­
+ den, also ein 5-poliges Kabel verwendet wird [2]. Die #ib#Pin-Belegung#ie# der Boxen
+ entspricht der eines Kabels zur Rechner-Rechner-Kopplung.
+
+ Beispiel:
+
+ Verbindung eines BICOS-Systems mit der Box:
+
+ Stecker Stecker
+ Pin Pin
+
+ 2 <---------> 3
+ 3 <---------> 2
+ 4 <---------> 5
+ 5 <---------> 4
+ 7 <---------> 7
+
+
+d) Richten Sie eine Task #on("bold")##ib#net#ie##off("bold")# unter #on("bold")#SYSUR#off("bold")# ein und legen Sie eine #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# an, die
+ Ihre #ib#Netzkonfiguration#ie# enthält, oder ändern Sie die mitgelieferte Datei ent­
+ sprechend ab (siehe auch 1.5.).#goalpage("sperre")#
+
+
+ Dem bisherigen Netz entspricht eine Datei #on("b")#netz#off("b")# mit folgendem Inhalt:
+
+ definiere netz;
+ routen (1,127,k);
+ starte kanal (k,1,x);
+ aktiviere netz.
+
+ k: ihr netzkanal.
+ x: IF yes ("#ib#Flußkontrolle#ie#") THEN 10 ELSE 3 FI.
+
+
+
+ Laden Sie die Datei #on("b")##ib#net install#ie##off("b")# vom Archiv #on("b")#net#off("b")# und übersetzen Sie diese. Je nach­
+ dem, welche EUMEL-Version auf der Maschine installiert ist, werden die notwen­
+ digen Programmdateien insertiert.
+
+ Es sind dies
+
+ net report
+ net hardware interface
+ basic net
+ net manager
+
+
+ Das Netz wird dabei gestartet.
+
+
+ Hinweis: Obwohl die Task #on("b")#net#off("b")# sich noch mit #on("bold")##ib#continue#ie##off ("bold")# an ein Terminal holen
+ läßt, sollte man dies nur kurzzeitig tun, da der Netzverkehr solange
+ blockiert ist.
+
+ In der #ib#Datei#ie# #on("b")#netz#off("b")# sollte der #ib#Kanal#ie#, über den der meiste Verkehr erwar­
+ tet wird, zuerst gestartet werden. Für ihn wird die Task #on("b")##ib#net port#ie##off("b")# gene­
+ riert, für jeden weiteren Kanal wird eine Task #on("b")##ib#net port#ie# k#off("b")# (k=Kanal­
+ nummer) generiert.
+#page#
+
+1.3. Benutzung des Netzes
+#goalpage("1.3")#
+
+
+Zur Benutzung des Netzes stehen folgende Operatoren und Prozeduren zur Verfü­
+gung:
+
+
+
+TASK OP #ib#/#ie# (INT CONST station, TEXT CONST taskname)
+
+liefert die Task #on("bold")#taskname#off("bold")# von der #ib#Station#ie# #on("bold")#station#off("bold")#.
+
+
+#ib#Fehlerfälle#ie#:
+
+ - #ib(4)#Task "...." gibt es nicht#ie(4)#
+
+ Die angeforderte Task gibt es auf der #ib#Zielstation#ie# nicht.
+
+ - #ib(4)##ib#Collectortask#ie# fehlt#ie(4)#
+
+ die Task #on("b")##ib#net port#ie##off("b")# existiert nicht (siehe 6).
+
+ Hinweis: #on("b")#net port#off("b")# wird bei jedem Start des Netzes neu generiert und beim
+ Auftreten eines nicht vorhergesehenen #ib#Fehler#ie#s beendet. Die Feh­
+ lermeldung steht im #on("b")##ib#report#ie##off("b")# (siehe 4).
+
+ - #ib(4)#Station x antwortet nicht#ie(4)#
+
+ Eine nicht vorhandene oder abgeschaltete Station wurde angesprochen.
+
+ Hinweis: Dieser #ib#Fehler#ie# wird angenommen, wenn eine Überwachungszeit von
+ ca. 30 Sekunden verstrichen ist, ohne daß Station x die Taskidenti­
+ fikation angeliefert hat.
+
+ - #ib(4)#Station x gibt es nicht#ie(4)#
+
+ #ib#Station#ie# x steht nicht in den #ib#Routentabelle#ie#n.
+
+ Diese Meldung kann auch erscheinen, wenn Station x erst kürzlich an das Netz
+ angeschlossen wurde. Sie steht dann noch nicht in den Routentabellen (siehe
+ auch 5.3.).
+
+ Beispiel:
+
+ list (5/"PUBLIC")
+
+ Die Dateiliste von PUBLIC der Station 5 wird angefordert.
+
+
+
+TASK OP #ib#/#ie# (INT CONST station, TASK CONST task)
+
+liefert
+
+station / name (task)
+
+Beispiel:
+
+ list (4/public)
+
+
+Fehlerfall:
+
+ "......" #ib(4)#gibt es nicht#ie(4)#
+
+ Auf der eigenen Station gibt es die Task #on("b")#task#off("b")# nicht.
+ Der Taskname wird auf der eigenen Station bestimmt, wenn es dort die Task
+ nicht gibt, führt dies zur obigen Fehlermeldung.
+
+Abhilfe:
+
+ Statt list(4/public) das Kommando list (4/"PUBLIC") verwenden.
+
+
+
+INT PROC #ib#station#ie# (TASK CONST task)
+
+liefert die #ib#Stationsnummer#ie# der Task #on("bold")#task#off("bold")#.
+
+Beispiel:
+
+ put (station (myself))
+
+ gibt die eigene Stationsnummer aus.
+
+
+
+
+PROC #ib#reserve#ie# (TEXT CONST archivename, TASK CONST archivetask)
+
+dient dazu, das Archiv auf der #ib#Station#ie# #on("bold")#station#off("bold")# anzumelden.
+
+Beispiel:
+
+ reserve ("std", 4/"ARCHIVE"); #ib#list#ie# (4/"ARCHIVE")
+
+ gibt das Inhaltsverzeichnis der Archivfloppy im Laufwerk der Station 4 aus.
+
+ Hinweis: Vergessen Sie bei solchen #ib#Querarchivierungen#ie# nicht die Stationsangabe
+ bei jedem einzelnen Archivkommando (z.B fetch ("xxx", #on("bold")#4/#off("bold")#
+ "ARCHIVE")).
+
+ Hinweis: Querarchivieren ist langsam. Verwenden Sie es nur, wenn Sie Floppy­
+ formate umsetzen wollen.
+
+
+
+
+PROC #ib#free global manager#ie#
+
+dient dazu, die eigene Task über das Netz ansprechbar zu machen. Jede andere
+Task im Netz kann dann die üblichen #ib#Manager#ie#aufrufe (#on("bold")##ib#save#ie##off ("bold")#, #on("bold")##ib#fetch#ie##off ("bold")#, usw.) an die
+eigene Task machen, sofern diese nicht an ein Terminal gekoppelt ist.
+
+Die Task wird (wie bei #on("bold")#break#off ("bold")#) abgekoppelt und meldet sich in Zukunft mit #on("bold")#mainte­
+nance#off ("bold")# statt mit #on("bold")#gib kommando#off ("bold")#.
+
+Beispiel:
+
+ An Station 4 ruft man in der Task "hugo" das Kommando #on("bold")#free global manager#off("bold")#
+ auf. Anschließend kann man von jeder Station aus z.B. #on("bold")#list (4/"hugo")#off ("bold")# usw. auf­
+ rufen.
+
+
+
+
+TEXT PROC #ib#name#ie# (TASK CONST t)
+
+Diese (schon immer vorhandene) Prozedur wurde dahingehend erweitert, daß der
+Name einer auf einer anderen Station existierenden Task über Netz angefordert wird.
+
+Existiert die Task nicht, so wird #on("bold")##ib#niltext#ie##off ("bold")# geliefert.
+
+Hinweis: Die Prozedur #on("bold")##ib#exists#ie##off ("bold")# wurde nicht auf das Netz ausgedehnt, da sie in Situa­
+ tionen eingesetzt wird, wo es auf eine sehr schnelle Antwort ankommt.
+ Daher liefert #on("bold")#exists#off ("bold")# für eine stationsfremde Task immer FALSE. Will man
+ wissen, ob eine solche Task existiert, verwende man die Abfrage
+
+ #on("bold")#IF name (task) <> "" THEN ... #off ("bold")#.
+
+#ib#Fehlerfall#ie#:
+
+ - #ib(4)#Station x antwortet nicht#ie(4)#
+
+ - #ib(4)##ib#Station#ie# x gibt es nicht#ie(4)#
+
+#page#
+
+1.4. Informationsmöglichkeiten
+
+#goalpage("1.4")#
+
+In der Task #on("bold")#net#off("bold")# wird eine #ib#Datei#ie# #on("bold")##ib#report#ie##off("bold")# geführt, in der #ib#Fehlersituationen#ie# des Netzes
+verzeichnet werden. Diese Datei kann in jeder anderen Task auf derselben Station mit
+#on("bold")##ib#list#ie# (/"#ib#net#ie#")#off("bold")# angesehen werden. Eine Erklärung der wichtigsten Meldungen finden Sie
+im Anhang.
+
+In jeder Task kann durch das Kommando #on("bold")##ib#list#ie# (/"#ib#net port#ie#")#off("bold")# eine Übersicht über die
+momentan laufenden #ib#Netzübertragungen#ie# der eigenen #ib#Station#ie# erhalten werden (nur für
+den #ib#Kanal#ie#, an dem #on("b")##ib#net port#ie##off("b")# hängt). Entsprechendes gilt für die weiteren Netports der
+eigenen Station.
+
+Mit #on("bold")##ib#list#ie# (/"#ib#net list")#ie##off("bold")# erhält man die Informationen, die man mit #on("b")#list (/"net")#off("b")# und #on("b")##ib#list#ie##off("b")# auf
+alle Netports bekommt, sofern #on("b")##ib#listoption#ie##off("b")# (siehe S. #topage("listop")#) beim Generieren des Netzes
+aufgerufen wurde. Dieser Aufruf funktioniert auch bei fremden Stationen (z.B. #on("b")#list
+(5/"net list")#off("b")#).
+
+#page#
+
+1.5. Eingriffsmöglichkeiten
+
+#goalpage("1.5")#
+
+- Jede Task kann #ib#Sende#ie(1,"ströme")#- und #ib#Empfangsströme#ie#, die bei #on("bold")#list (/"net port")#off("bold")# gemel­
+ det worden sind und die eigene Task betreffen, abbrechen. Hierzu ist das Kom­
+ mando #on("bold")##ib#erase#ie# ("x", /"#ib#net port#ie#")#off ("bold")# zu geben, wobei x die #ib#Stromnummer#ie# (aus dem #on("bold")#list#off ("bold")#)
+ ist.
+ Unberechtigte #ib#Löschversuche#ie# werden abgewiesen.
+ Von privilegierten Tasks aus können jedoch mit #on("b")##ib#erase#ie##off("b")# beliebige Ströme abge­
+ brochen werden.
+
+
+- Durch das Kommando #on("bold")##ib#start#ie##off("bold")# kann von der Task #on("b")##ib#net#ie##off("b")# aus das Netz neu gestartet
+ werden. Dies setzt eine gültige #ib#Datei#ie# #on("bold")#netz#off("bold")# voraus. Es wird ein #on("bold")##ib#run#ie##off("bold")# auf diese Datei
+ gegeben. Das Kommando #on("b")##ib#start#ie##off("b")# ist nur noch aus Kompatibilitätsgründen zum alten
+ Netz vorhanden.
+
+
+- Durch das Kommando #on("bold")##ib#routen aufbauen#ie##off("bold")# in der Task #on("b")##ib#net#ie##off("b")# werden die #ib#Routentabelle#ie#n
+ neu aufgebaut. Dies kann notwendig werden, wenn eine neue #ib#Station#ie# ans Netz
+ angeschlossen wurde (#ib#Fehlermeldung#ie# '#ib(4)#Station x gibt es nicht#ie(4)#'). #on("bold")#routen aufbauen#off ("bold")#
+ muß zuvor auch an allen dazwischenliegenden #ib#Knotenstation#ie#en gegeben werden.
+
+ #on("bold")#routen aufbauen#off ("bold")# erzeugt eine Task #on("b")##ib#router#ie##off("b")#, die sich an das Terminal koppelt (die
+ Task #on("b")#net#off("b")# koppelt sich ab) und ein #ib#Protokoll#ie# ausgibt. Sind die #ib#Route#ie#n aufgebaut,
+ beendet sich die Task #on("b")#router#off("b")# mit der Meldung #on("b")#fertig#off("b")#. Es werden nur Stationen
+ bearbeitet, die nicht #ib#gesperrt#ie# (siehe S. #topage("sperre")#), und für die keine festen Routen
+ vereinbart sind. Der Vorgang dauert ca. 5 Sek. pro nicht gesperrter Station und
+ #ib#Netzkanal#ie#. Die #ib#Route#ie#n werden in einem #ib#Datenraum#ie# #on("b")##ib#port intern#ie##off("b")# hinterlegt.
+
+
+- Der Aufruf #on("bold")##ib#definiere netz#ie##off("bold")# leitet eine #ib#Netzdefinition#ie# in der #ib#Datei#ie# #on("bold")##ib#netz#ie##off("bold")# ein. Dabei
+ werden alle augenblicklichen Netzkommunikationen gelöscht. Die Tasks #on("b")##ib#net port#ie#
+ (k)#off("b")#, wobei #on("b")#k#off("b")# die #ib#Kanalnummer#ie# ist, und #on("b")##ib#net timer#ie##off("b")# werden gelöscht.
+
+ Dieser Aufruf muß vor den Aufrufen von #on("bold")##ib#starte kanal#ie#, #ib#erlaube#ie#, #ib#sperre#ie#, #ib#routen#ie#,
+ #ib#aktiviere netz#ie# und #ib#list option#ie##off("bold")# erfolgen.
+
+
+- PROC #ib#sperre#ie# (INT CONST a,z)
+ bewirkt, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# keine Manageraufrufe an Tasks dieser Station
+ geben dürfen (Genauer gesagt werden sendecodes > 6 nicht weitergeleitet, son­
+ dern ein errornak mit dem Text "#ib(4)#kein Zugriff auf Station#ie(4)#" zurückgeschickt).
+
+ Dieser Aufruf muß vor dem ersten #on("bold")##ib#starte kanal#ie##off("bold")# erfolgen.
+
+
+- PROC #ib#erlaube#ie# (INT CONST a,z)
+ bewirkt, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# Manageraufrufe an Tasks dieser Station geben
+ dürfen.
+
+ Dieser Aufruf muß vor dem ersten #on("bold")##ib#starte kanal#ie##off("bold")# erfolgen.
+
+ Beispiel: Alle Stationen außer 8 und 10 sollen #ib#gesperrt#ie# sein:
+
+ #ib#sperre#ie# (1,127); erlaube (8,8); erlaube (10,10)
+
+ Hinweis: 127 ist z.Zt. die maximale #ib#Stationsnummer#ie(1," maximale")#.
+
+
+- PROC #ib#routen#ie# (INT CONST a,z,k)
+ legt fest, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# an #ib#Kanal#ie# #on("bold")#k#off("bold")# direkt angeschlossen sind. Sen­
+ dungen dieser Stationen werden nur bearbeitet, wenn sie über diesen Kanal her­
+ einkommen (siehe 1.7.). Fehlt für eine Station ein entsprechender Routenaufruf, so
+ darf sie über einen beliebigen #ib#Netzkanal#ie# angeschlossen sein. Dies wird dann von
+ #on("bold")##ib#routen aufbauen#ie##off("bold")# ermittelt.
+
+ PROC routen (INT CONST a,z,k,zw)
+ legt fest, daß die Stationen #on("bold")#a#off("bold")# bis #on("bold")#z#off("bold")# indirekt über die #ib#Knotenstation#ie# #on("bold")#zw#off("bold")# angeschlos­
+ sen sind, und #on("b")#zw#off("b")# am Kanal #on("bold")#k#off("bold")# hängt.
+
+
+- PROC #ib#starte kanal#ie# (INT CONST k,m,q)
+ startet eine #ib#Netztask#ie# am #ib#Kanal#ie# #on("bold")#k#off("bold")# im Modus #on("bold")#m#off("bold")# [4]. Dabei wird mit #on("bold")#q#off("bold")# die Anzahl
+ paralleler #ib#Empfangsströme#ie# festgelegt. Dadurch kann erreicht werden, daß der
+ #ib#Empfangspuffer#ie# nicht überläuft, indem nicht mehr als #on("b")#q#off("b")# Ströme quittiert werden.
+ Bei #ib#V.24#ie#-#ib#Schnittstelle#ie#n gebe man 3 (ohne #ib#Flußkontrolle#ie#) bzw. 10 (mit Flußkon­
+ trolle) an.
+
+
+- PROC #ib#aktiviere netz#ie#
+ muß als Abschluß in der Datei #on("bold")##ib#netz#ie##off("bold")# aufgerufen werden. Dabei wird die Task vom
+ Terminal abgekoppelt. Falls es bei #on("bold")##ib#definere netz#ie##off("bold")# den #ib#Datenraum#ie# #on("b")##ib#port intern#ie##off("b")#, der
+ die #ib#Route#ie#n enthält, nicht gab, wird #on("bold")##ib#routen aufbauen#ie##off("bold")# aufgerufen.
+
+
+- PROC #ib#listoption#ie##goalpage("listop")#
+ erzeugt eine Task #on("b")##ib#net list#ie##off("b")#, die bei #on("bold")#list#off("bold")# den #ib#Fehlermeldung#ie#sreport und den Zustand
+ aller Netports liefert. Diese Task ist auch über Netz ansprechbar. In der Regel
+ sollte man #on("b")#listoption#off("b")# in der Datei #on("b")#netz#off("b")# aufrufen, es sei denn, das System ist sehr
+ klein.
+
+#page#
+
+1.6. #ib#Fehlersuche#ie# im Netz
+
+#goalpage("1.6")#
+
+#ib#Fehler#ie# im Netz können sich verschiedenartig auswirken. Im folgenden wird auf einige
+Beispiele eingegangen:
+
+Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung '#ib(4)#Station#ie(4, " x antwortet nicht")# 4 antwortet nicht'.
+
+
+#ib#Fehler#ie#möglichkeiten:
+
+ - #ib#Station#ie# 4 ist nicht eingeschaltet.
+ Abhilfe: Station 4 einschalten. Kommando erneut geben.
+
+
+ - #ib#Netztask#ie# an Station 4 ist nicht arbeitsfähig.
+ Abhilfe: Kommando #on("bold")##ib#start#ie##off ("bold")# in der Task "net" auf Station 4.
+
+
+ - Stationsnummern und Boxnummern stimmen nicht überein.
+ Abhilfe: Mit #on("bold")#define station#off ("bold")# #ib#Stationsnummer#ie#n korrigieren (siehe 3.2).
+
+
+ - #ib#Verbindung#ie# Rechner/Box am eigenen Rechner oder an Station 4 fehlt.
+ Abhilfe: Verbindungen überprüfen. Durch Ansprechen einer dritten Station
+ kann oft schnell geklärt werden, welche Rechner/Box-Verbindung
+ defekt sein muß.
+
+
+ - Verbindung der Boxen untereinander defekt.
+ Abhilfe: Fehlende Verbindung, #ib#Masseschluß#ie# und #ib#Dreher#ie# (keine 1:1 Verbin­
+ dung) überprüfen und beheben.
+
+ Hinweis: Liegt z.B. ein Masseschluß vor, so kann es durchaus sein, daß
+ Boxen, die nicht in der Nähe des Masseschlusses stehen, noch
+ miteinander arbeiten können. Man kann aus der Tatsache, daß zwei
+ Boxen miteinander arbeiten können, also nicht schließen, daß man
+ nicht nach diesem Fehler suchen muß.
+
+
+
+Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt keine Reaktion.
+
+
+ - Station 4 ist während dieser Sendung zusammengebrochen.
+ Abhilfe: Station 4 wieder starten. Die Bearbeitung des #on("bold")##ib#list#ie##off ("bold")#-Kommandos wird
+ automatisch wieder aufgenommen.
+
+
+ - PUBLIC auf Station 4 ist nicht im Managerzustand.
+ Abhilfe: PUBLIC in den Managerzustand versetzen.
+
+
+ - #ib#Fehler#ie# in der #ib#Netzhardware#ie#.
+ Überprüfen Sie, ob
+
+ - die Boxen eingeschaltet sind,
+ - die Bereitlampe blinkt (wenn nicht: #ib#RESET#ie# an der Box),
+ - die #ib#V.24#ie#-Kabel richtig stecken,
+ - die Boxen untereinander verbunden sind (1 zu 1 Verbindungen der 5 poli­
+ gen Diodenbuchsen).
+
+
+ - Fehler bei der #ib#Netzinstallation#ie#.
+ Überprüfen Sie, ob
+
+ - alle Stationen an einem #ib#Strang#ie# gleiche oder kompatible Netzmodi einge­
+ stellt haben [4],
+ - alle Stationen an einem #ib#Netzstrang#ie# auf die gleiche #ib#Nutzdatenlänge#ie# einge­
+ stellt sind,
+ - bei der #ib#Kommunikation#ie# über #ib#Knoten#ie# alle Stationen die gleiche Nutzdaten­
+ länge bei indirekten Sendungen eingestellt haben,
+ - die #ib#Route#ie#n auf allen beteiligten Stationen korrekt eingestellt sind.
+
+
+
+Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung '#ib(4)##ib#Collectortask#ie# fehlt#ie(4)#'.
+
+ - Das Kommando #on("b")##ib#start#ie##off("b")# (bzw #on("b")##ib#aktiviere netz#ie##off("b")# in der #ib#Datei#ie# #on("b")#netz#off("b")#) wurde nicht gege­
+ ben. Somit existiert #on("b")##ib#net port#ie##off("b")# nicht.
+ Abhilfe: Kommando #on("bold")#start#off ("bold")# in der Task #on("b")#net#off("b")# geben.
+
+
+ - Die #ib#Netzsoftware#ie# ist auf einen nicht vorhergesehenen #ib#Fehler#ie# gelaufen. Dieser
+ wird im #ib#Report#ie# vermerkt. #on("b")##ib#net port#ie##off("b")# wird dabei gelöscht.
+ Abhilfe: Geben Sie in der Task #on("bold")#net#off("bold")# das Kommando #on("bold")#start#off("bold")#. Dadurch wird die
+ Netzsoftware neu gestartet. Alle Netzkommunikationen dieser Station
+ gehen verloren.
+
+
+
+Beispiel:
+
+ Nach #on("bold")##ib#fetch#ie# ("hugo",4/public)#off("bold")# sind Teile der Datei "hugo" verfälscht.
+
+ - Die #ib#V.24#ie#-#ib#Verbindung#ie# zur Box ist nicht in Ordnung.
+ Abhilfe: Abstand zwischen Rechner und Box verkürzen; #ib#Baud#ie#rate ernie­
+ drigen; durch Wechseln der #ib#V.24#ie#-#ib#Schnittstelle#ie# feststellen, ob diese
+ defekt ist.
+ Hinweis: Die Verbindung zwischen den Boxen ist durch #ib#Prüfsummen#ie# abge­
+ sichert (Hardware).
+
+#page#
+
+1.7. Sicherheit im Netz
+
+#goalpage("1.7")#
+
+Bei Benutzung eines Rechnernetzes tauchen neue #ib#Sicherheitsprobleme#ie# auf. Um sie
+verstehen und eingrenzen zu können, muß man sich mit dem #ib#Sicherheitskonzept#ie# des
+Betriebssystems EUMEL vertraut machen:
+
+Eine Task im EUMEL kann nur manipuliert werden, wenn man sie entweder an ein
+Terminal koppelt oder ihr Sendungen zustellt.
+
+Das Ankoppeln kann über #ib#Paßwort#ie# abgesichert werden. Nach dem Ankoppeln kann
+die Task außerdem selbst bestimmen, wie sie die dann möglichen Eingaben behan­
+delt. So kann z.B. noch ein komplizierter Paßalgorithmus zu durchlaufen sein, bis
+man auf einer offenen Programmierumgebung landet.
+
+Sendungen können eine Task auch nur mit ihrem Einverständnis beeinflussen, da
+eine Sendung nur zugestellt wird, wenn die Task in der Prozedur #on("b")##ib#wait#ie##off("b")# steht. Insbe­
+sondere kann die Task den Absender einer Sendung überprüfen und gewisse Opera­
+tionen nur bei gewissen Absendern zulassen. So lehnt ein #on("b")##ib#global manager#ie##off("b")# z.B. alle
+Dateimanagerkommandos ab, die nicht von Nachkommen (z.B. Söhnen) der Task
+kommt. #on("b")##ib#free global manager#ie##off("b")# hingegen läßt Operationen wie #on("b")##ib#save#ie##off("b")# oder #on("b")##ib#erase#ie##off("b")# von
+beliebigen Tasks, auch von fremden #ib#Station#ie#en, zu. Will man nur bestimmte Fremd­
+stationen zulassen, kann man z.B. folgendes Schema verwenden:
+
+ PROC my #ib#manager#ie#
+ (DATASPACE VAR ds, INT CONST code, phase, TASK CONST source):
+
+ IF station (source) = station (myself) OR station (source) = 10
+ THEN
+ free manager (ds, code, phase, source)
+ ELSE
+ errorstop ("kein Zugriff")
+ FI
+
+ END PROC my manager;
+
+ global manager (PROC my manager)
+#page#
+Hier werden nur #on("b")#save#off("b")# usw. von Tasks der eigenen Station und der Station 10 zuge­
+lassen. Der Rest erhält die #ib#Fehlermeldung#ie# "kein Zugriff".
+
+Dieses Verfahren gewährt nur dann Sicherheit, wenn es nicht möglich ist, daß eine
+beliebige Station sich als Station 10 ausgibt.
+
+Damit das Netz diese Sicherheit garantieren kann, müssen natürlich gewisse phy­
+sische Voraussetzungen erfüllt sein. Wenn z.B. die Station 10 über eine #ib#V.24#ie# ange­
+schlossen ist, aber jeder die Möglichkeit hat, an diese #ib#Schnittstelle#ie# seinen eigenen
+Rechner anzuschliessen, dann kann das Netz natürlich nicht erkennen, ob es mit der
+echten Station 10 verkehrt.
+
+Es muß also sichergestellt sein, daß an Kanälen für das Netz nicht manipuliert werden
+kann. Bei einem #ib#Strang#ie# (Anschluß über #ib#Netzbox#ie#en) heißt das für die Boxen, daß sie
+nur #ib#Telegramm#ie#e weitervermitteln, die die eingestellte #ib#Quellstationsnummer#ie# enthalten.
+Sonst könnte jemand, der an denselben Strang wie #ib#Station#ie# 10 angeschlossen ist,
+#ib#Telegramm#ie#e erzeugen, die so aussehen, als kämen sie von 10.
+
+Die #ib#Netzsoftware#ie# ihrerseits darf nur Telegramme auswerten, die über die richtige
+#ib#Route#ie# (#ib#Kanal#ie# und #ib#Knotenstation#ie#) einlaufen.
+
+Leider hat dies die unangenehme Konsequenz, daß man automatisches Aufbauen und
+Ändern von Routen verbieten muß, wodurch die Wartung der #ib#Netzkonfiguration#ie#
+erschwert wird.
+
+Diese Version der #ib#Netzsoftware#ie# bietet den folgenden Kompromiß an: Nur für sicher­
+heitsrelevante #ib#Stationen#ie(1,", sicherheitsrelevante")# (im Beispiel Station 10) muß in der #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# die Route
+angegeben werden. Dies muß in allen Stationen geschehen, für die die Station
+sicherheitsrelevant ist, und in allen #ib#Knoten#ie# dazwischen.
+
+Für nicht sicherheitsrelevante Stationen werden #ib#Routeninformationen#ie# automatisch
+aufgebaut und geändert.
+
+Hinweis:
+Man wird oft ohne sicherheitsrelevante Stationen auskommen, indem man auf Ebenen
+oberhalb der Netzebene Paßwortkontrollen einführt. So ist es z.B. ja möglich, Dateien
+durch Paßworte zu schützen. Ein weiteres Beispiel ist ein #ib#Printerserver#ie#, der nur
+ausdruckt, wenn eine mitgegebene Abrechnungskennung stimmt. Dabei ist es sogar
+wünschenswert, daß die #ib#Station#ie# irrelevant ist, die den Druckauftrag gibt.
+#pagenr ("%",21)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Teil 2 : Arbeitsweise der Netzsoftware
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#page#
+
+Teil 2: Arbeitsweise der Netzsoftware
+#goalpage("2")#
+
+
+
+2.1. Die Netztask
+#goalpage("2.1")#
+
+
+In diesem Kapitel wird beschrieben, wie eine #ib#Netztask#ie# in das System eingebettet ist
+und welche Aufgaben sie hat. Unter Einhaltung dieser Konzepte kann die ausgeliefer­
+te Netzsoftware so geändert werden, daß sie beliebige andere #ib#Netzhardware#ie# unter­
+stützt. Die Netzsoftware ist so gegliedert, daß i.allg. nur eine hardwareabhängige
+Komponente ausgetauscht werden muß (siehe Teil 3).
+
+Die Kommunikation zwischen Tasks im EUMEL-Betriebssystem basiert auf einem
+#ib#Rendezvouskonzept#ie#: Die #ib#Zieltask#ie# einer Sendung muß empfangsbereit sein, wenn die
+#ib#Quelltask#ie# sendet.
+
+Die Kommunikationsprozeduren auf der niedrigsten Ebene sind #on("bold")##ib#send#ie##off ("bold")# (Senden) und
+#on("bold")##ib#wait#ie##off ("bold")# (Warten auf Empfang). Bei der Kommunikation werden ein Integer #on("bold")#code#off ("bold")# und ein
+#ib#Datenraum#ie# #on("bold")#dr#off ("bold")# übergeben. #on("bold")#code#off ("bold")# muß >= 0 sein, da negative Codes systemintern ver­
+wandt werden. Ist die empfangende Task an einen #ib#Kanal#ie# gekoppelt (#on("bold")##ib#continue#ie##off ("bold")#), so
+führt eine Zeicheneingabe auf diesem Kanal dazu, daß eine Sendung mit dem Code
+-4 ankommt. Die Eingabedaten müssen mit den üblichen #ib#Eingabeprozeduren#ie# (#on("bold")##ib#inchar#ie##off ("bold")#
+usw.) abgeholt werden. Der übermittelte #ib#Datenraum#ie# und die Absendertask sind dabei
+ohne Bedeutung und dürfen nicht interpretiert werden.
+
+Die Prozedur #on("bold")#send#off ("bold")# hat einen #ib#Rückmeldeparameter#ie#, der besagt, ob die Sendung
+übermittelt wurde. Gibt es die Zieltask nicht oder steht sie nicht im #on("bold")#wait#off ("bold")#, so kann die
+Sendung nicht übermittelt werden.
+
+Ein Entwicklungskriterium für das EUMEL-Netz war es, möglichst wenig Unterstüt­
+zung von der virtuellen EUMEL-Maschine (#ib#EUMEL0#ie#) zu fordern, damit weitgehend in
+ELAN programmiert werden kann. Dadurch ist es möglich, eine (privilegierte) Task mit
+der Netzabwicklung zu betrauen.
+#page#
+Zunächst wird auf die #ib#EUMEL0#ie#-Unterstützung eingegangen:
+
+a) Es gibt die Prozedur #on("bold")##ib#define collector#ie##off ("bold")#, mit der die für das Netz verantwortliche
+ Task der EUMEL0-Maschine bekannt gemacht wird. Diese Task wird im fol­
+ genden #ib#Collector#ie# genannt.
+
+b) Es gibt die Prozedur #on("bold")##ib#define station#ie##off ("bold")#, die für den Rechner eine #ib#Stationsnummer#ie#
+ einstellt. Anhand dieser Nummer werden die Rechner eines Netzes unterschie­
+ den. Das Einstellen bewirkt, daß für alle Tasks die Stationsnummer in ihre
+ #ib#Task-Id#ie# eingetragen wird (Task-Id's sind die Werte, die der Typ TASK anneh­
+ men kann).
+
+c) Der Befehl #on("bold")##ib#station#ie# (task)#off ("bold")# liefert die Stationsnummer der #on("bold")#task#off ("bold")#. So liefert z.B.
+ #on("bold")##ib#station#ie# (myself)#off ("bold")# die #ib#Stationsnummer#ie# des eigenen Rechners.
+
+d) Eine Sendung, deren #ib#Zieltask#ie# auf einem anderen Rechner liegt (also station (ziel)
+ <> station (myself)), wird auf die #ib#Collectortask#ie# geleitet.
+
+e) Es gibt eine Prozedur #on("bold")##ib#collected destination#ie##off ("bold")#, die es dem Collector erlaubt, die
+ eigentliche Zieltask einer auf ihn geleiteten Sendung zu erfahren.
+
+f) Es gibt eine Variante der Prozedur #on("bold")##ib#send#ie##off ("bold")#, die es dem Collector gestattet, der
+ #ib#Zieltask#ie# eine andere Task als Absender vorzutäuschen.
+
+g) Es gibt eine spezielle #ib#Task-Id#ie# #on("bold")##ib#collector#ie##off ("bold")#, durch die der augenblicklich eingestell­
+ te #ib#Collector#ie# erreicht wird. Diese wird als Zieltask beim Aufruf der Vermittlungs­
+ dienste angegeben (siehe S. #topage("collector")#). Eine Sendung an #on("bold")#collector#off ("bold")# wird von EUMEL0
+ an den derzeitig eingestellten Collector geschickt.
+
+Ein Collector kann also auf drei Wegen von den übrigen Tasks desselben Rechners
+Sendungen erhalten:
+
+ 1. Über ein normales #on("b")#send#off("b")# (z.B. bei #on("bold")#list (/"net port")#off ("bold")#, wenn #on("b")#net port#off("b")# der derzeitige
+ #ib#Collector#ie# ist),
+
+ 2. über ein #on("b")#send#off("b")# an die Task #on("bold")#collector#off ("bold")# (s.u.) und
+
+ 3. als umgeleitete Sendung (z.B. bei #on("bold")#list#off ("bold")# an eine Task auf einem anderen
+ Rechner).
+
+Der Collector kann diese Fälle anhand von #on("bold")#collected destination#off ("bold")# unterscheiden.
+
+Die Punkte d) bis f) dienen dazu, den Collector für über Netz kommunizierende Tasks
+unsichtbar zu machen: Der Collector taucht nicht als Ziel oder #ib#Quelle#ie# von Sendungen
+auf. Das ist notwendig, damit normale Tasks sich nicht darum kümmern müssen, ob
+eine Sendung übers Netz geht oder im eigenen Rechner bleibt.
+
+Wenn ein #ib#Datenraum#ie# an einen anderen Rechner geschickt wird, muß der gesamte
+Inhalt (z. Zt. max. 1 MB) übertragen werden. Dies macht bei der üblichen Netzhard­
+ware eine Zerlegung in #ib#Paket#ie#e nötig [5]. Bei der Zerlegung eines Datenraumes in
+Pakete (#ib#Telegramm#ie#e) gelten folgende Einschränkungen:
+
+ - Ein Paket kann maximal eine #ib#Datenraumseite#ie# als #ib#Nutzdaten#ie# enthalten.
+
+ - Die #ib#Nutzdatenlänge#ie# ist für einen #ib#Übertragungsweg#ie# konstant.
+
+ - Alle Stationen eines #ib#Netzstrang#ie#s senden mit gleicher Nutzdatenlänge (#on("b")##ib#data
+ length#ie##off("b")#).
+
+ - Bei indirekter #ib#Kommunikation#ie(1,"indirekte")# (über #ib#Knoten#ie#) muß die Nutzdatenlänge für in­
+ direkte Verbindungen (#on("b")##ib#data length via node#ie##off("b")#) auf allen beteiligten Stationen
+ gleich eingestellt sein.
+
+
+Für Netze stehen spezielle Blockbefehle zur Verfügung:
+
+
+g) #ib#blockin#ie# / #ib#blockout#ie# (dr,seite,512+abstand,anzahl,rest)
+
+ Es werden maximal #on("bold")#anzahl#off ("bold")# Bytes transferiert. In #on("bold")#rest#off ("bold")# wird zurückgemeldet, wie
+ viele Bytes nicht bearbeitet wurden (z.B. weil der #ib#Kanal#ie# nichts anliefert). Bear­
+ beitet werden die Bytes
+
+ #on("bold")#seite#off ("bold")# * 512 + #on("bold")#abstand#off ("bold")#
+
+ bis maximal
+
+ #on("bold")#seite#off ("bold")# * 512 + #on("bold")#abstand#off ("bold")# + #on("bold")#anzahl#off ("bold")# - 1
+
+ Der Kanal, an den die Task gekoppelt ist, wird dabei über #ib#Stream-IO#ie# (d.h.
+ #on("bold")##ib#incharety#ie##off ("bold")#, bei #on("bold")#blockin#off ("bold")# bzw. #on("bold")#out#off ("bold")# bei #on("bold")#blockout#off ("bold")#) angesprochen.
+
+ Hinweis: Die Anforderung darf nicht über #ib#Seitengrenze#ie# gehen, d.h.
+
+ #on("bold")#abstand#off ("bold")# + #on("bold")#anzahl#off ("bold")# <= 512
+
+ muß erfüllt sein.
+
+
+Eine Netzsendung läuft wie folgt ab:
+
+Die Task q auf Rechner rq mache ein #on("bold")##ib#send#ie##off ("bold")# an die Task z auf Rechner rz.
+
+1. Die Prozedur #on("bold")#send#off ("bold")# ist ein #ib#EUMEL0#ie#-Befehl. Die EUMEL0-Ebene erkennt, daß die
+ Sendung an die #ib#Station#ie# rz geht, da die #ib#Stationsnummer#ie# in der #ib#Task-Id#ie# enthalten
+ ist. Daher wird die Sendung zum #ib#Collector#ie# umgeleitet, den EUMEL0 wegen der
+ Einstellung durch #on("bold")##ib#define collector#ie##off ("bold")# kennt, umgeleitet.
+
+2. Die Task Collector empfängt über #on("bold")##ib#wait#ie##off ("bold")# den #ib#Datenraum#ie#, den #ib#Sendecode#ie# und die
+ Absendertask q. Die #ib#Zieltask#ie# z erfährt sie durch #on("bold")##ib#collected destination#ie##off ("bold")#.
+
+3. Der Collector nimmt Kontakt mit dem Collector des Rechners #on("b")#rz#off("b")# auf, dessen Sta­
+ tionsnummer ja #on("bold")##ib#station#ie#(z)#off ("bold")# ist, und übermittelt diesem Sendecode, #ib#Quelltask#ie# (q),
+ eigentliche Zieltask (z) und den #ib#Datenraum#ie#. Da die Collectoren in ELAN geschrie­
+ ben sind, können sie an beliebige #ib#Netzhardware#ie# und #ib#Protokoll#ie#e angepaßt werden.
+
+4. Der #ib#Collector#ie# auf Rechner #on("b")#rz#off("b")# verwendet das spezielle #on("bold")#send#off ("bold")#, um der Zieltask die
+ Sendung zuzustellen. Dadurch erscheint nicht der Collector, sondern die Task #on("b")#q#off("b")#
+ als Absender der Sendung.
+
+Zur Abwicklung der #ib#Vermittlungsebene#ie# (siehe S. #topage("vermittlung")#) muß der Collector noch spe­
+zielle Funktionen beherrschen. Diese sind
+
+ der #on("b")##ib#/#ie#-Operator#off("b")# (Taskname in #ib#Task-Id#ie# wandeln) und
+ die #on("b")##ib#name#ie##off("b")#-Prozedur (Task-Id in Namen wandeln).
+
+Der #on("b")#/#off("b")#-Operator macht eine Sendung an den #on("bold")##ib#collector#ie##off ("bold")#, wobei im #ib#Datenraum#ie# der Name
+der Task steht und der #ib#Sendecode#ie# gleich der Stationsnummer ist (siehe [6] ). Der
+#ib#Collector#ie# setzt sich mit dem Collector dieser Station in Verbindung, damit dieser die
+Task-Id ermittelt und zurückschickt. Der eigene Collector schickt dann dem #on("b")#/#off("b")#-Oper­
+ator als Antwort einen Datenraum, der die #ib#Task-Id#ie# enthält.
+
+Umgekehrt läuft #on("bold")##ib#name#ie##off ("bold")# ab: Wenn die Task-Id von einer fremden Station ist, schickt
+#on("bold")#name#off ("bold")# eine Sendung an den #on("bold")##ib#collector#ie##off ("bold")#, wobei im Datenraum die Task-Id steht und
+Sendecode = 256 ist. Der Collector entnimmt die #ib#Stationsnummer#ie# der Task aus der
+Task-Id und läßt sich vom entsprechenden Collector den Tasknamen geben. Dieser
+wird der #on("bold")#name#off ("bold")#-Prozedur im Antwortdatenraum übergeben.
+
+Netztasks bauen sich #ib#Routentabellen#ie# auf (#ib#Datei#ie#name #on("b")##ib#port intern#ie##off("b")#). Aufgrund dieser
+Tabellen weiß jede #ib#Netztask#ie#, über welchen #ib#Kanal#ie# und welche #ib#Nachbarstation#ie# eine
+#ib#Zielstation#ie# erreichbar ist. Wenn der #ib#Collector#ie# einen Sendeauftrag erhält, prüft er, ob
+die Zielstation über seinen Kanal erreichbar ist. Wenn nicht, leitet er Parameter und
+#ib#Datenraum#ie# der Sendung an die geeignete Netztask weiter.
+#page#
+
+2.2. Ebenen
+
+#goalpage("2.2")#
+
+In diesem Kapitel werden die #ib#Protokollebenen#ie# für das Netz beschrieben, wie sie die
+ausgelieferte Netzsoftware benutzt und erwartet. Bei anderer Netzhardware als Daten­
+boxen müssen die Ebenen a) bis c) ausgetauscht werden [4]. Unter Einhaltung der im
+vorigen Kapitel beschriebenen Randbedingungen können auch die höheren Ebenen
+geändert werden.
+
+
+a) Physikalische Ebene
+
+ - #ib#Station#ie# <--> Box
+
+ #ib#V.24#ie#-#ib#Schnittstelle#ie# mit #ib#RTS/CTS#ie#-Handshake. Vollduplex.
+
+ - Box <--> Box
+
+ #ib#RS422#ie# über 2 verdrillte Leitungspaare (Takt und Daten).
+
+
+b) Verbindungsebene
+
+ - Station <--> Box
+
+ Asynchron
+ 8 Bit
+ Even Parity
+ 2400/4800/9600/19200 #ib#Baud#ie# einstellbar über Lötbrücken)
+
+ - Box <--> Box
+
+ #ib#SDLC#ie#
+ 400 KBaud
+#page#
+c) #ib#Netzebene#ie#
+#goalpage("quelle")#
+
+ - Station <--> Box
+
+ #ib#Telegrammformat#ie#: #ib#STX#ie#, <n>, <ziel>, <#ib#quelle#ie#>, <(n-4) byte>
+
+ <n> ist #ib#Längenangabe#ie# ( 8 <= n <= 160)
+ <ziel>, <quelle> sind #ib#Stationsnummer#ie#n. Diese müssen an den jeweiligen
+ Boxen eingestellt sein.
+
+ Box --> Station:
+
+ Ein #ib#Telegramm#ie# kommt nur bei der #ib#Station#ie# an, bei deren Box die Nummer
+ <ziel> eingestellt ist. Dadurch ist ein Mithören fremder #ib#Übertragung#ie# nicht
+ möglich (Datenschutz).
+
+ Zwischen Telegrammen können #ib#Fehlermeldung#ie#en der Box (Klartext) übermittelt
+ werden (z.B. 'skipped x', wenn ein #ib#STX#ie# von der Box erwartet wurde, aber 'x'
+ von der Station ankommt).
+
+ Station --> Box:
+
+ Ein Telegramm wird nur abgeschickt, wenn <#ib#quelle#ie#> mit der eingestellten
+ Nummer übereinstimmt (Datenschutz: Man kann nicht vorschwindeln, eine
+ beliebige Station zu sein, es sei denn, man hat physischen Zugriff zur Box und
+ stellt dort die Stationsnummer um).
+
+ - Box <--> Box
+
+ #ib#Telegrammformat#ie#:
+ FRAME, <ziel>, <#ib#quelle#ie#>, <daten>, <CRC-Code>
+
+ Eine #ib#Längenangabe#ie# ist nicht nötig, da #ib#SDLC#ie# eine Rekonstruktion der Länge
+ erlaubt.
+
+ Telegramme mit falschen #ib#CRC-Code#ie# werden vernichtet. Auf höheren Ebenen
+ muß dies durch #ib#Zeitüberwachung#ie# erkannt und behandelt werden.
+
+#page#
+d) Transportebene
+
+ Diese Ebene wickelt das Rendezvous zwischen einer Task, die #on("bold")##ib#send#ie##off ("bold")# macht, und
+ einer Task, die im #on("bold")##ib#wait#ie##off ("bold")# steht, ab [1].
+
+ Der im #on("bold")#send#off ("bold")# angegebene #ib#Datenraum#ie# wird als Folge von #ib#Seiten#ie# (im EUMEL-
+ Sinne: Pagingeinheit und Allokiereinheit) übermittelt, wobei jede Seite ggf. noch in
+ n Byte große Stücke zerlegt wird. Es werden nur echt allokierte Seiten übermit­
+ telt. Um nicht jedes #ib#Telegramm#ie# voll qualifizieren zu müssen, wird zunächst eine
+ Art virtuelle #ib#Verbindung#ie# durch ein #ib#OPEN#ie#-Telegramm eröffnet. Danach folgen
+ variabel viele #ib#DATA#ie#-Telegramme. Beide Sorten werden durch #ib#QUIT#ie#-Tele­
+ gramme quittiert, um folgende Funktionen zu ermöglichen:
+
+ #ib#Flußkontrolle#ie# (z.B. Zielrechner langsam),
+ Wiederaufsetzen (verlorene Telegramme),
+ Abbruch (z.B. weil Zieltask inzwischen beendet).
+
+ Ein #ib#CLOSE#ie#-Telegramm ist nicht nötig, da das letzte DATA-Telegramm als
+ solches erkannt werden kann (siehe unten).
+#page#
+ - #ib#OPEN#ie#-Telegramm
+
+#clear pos#
+ 0 1 2 3 4 5 6 7 8 9. Byte
++------+------+------+------+-------------+-------------+-------------------+
+I STX I 24 I Ziel IQuelleI Endziel I Endquelle I Strom I
++------+------+------+------+-------------+-------------+-------------------+
+
+ 10 11 12 13 14 15 16 17
++-------------+-------------+---------------------------+
+I Sequenz I Seite I Quelltask I
++-------------+-------------+---------------------------+
+
+ 18 19 20 21 22 23
++---------------------------+-------------+
+I Zieltask I Code I
++---------------------------+-------------+
+
+
+
+ <#ib#ziel#ie#>, <#ib#quelle#ie#> siehe S. #topage("quelle")#
+
+ <#ib#endziel#ie#> Eigentliche #ib#Zielstation#ie#. Ist <ziel> = <endziel>, so ist
+ das #ib#Telegramm#ie# angekommen. Andernfalls muß die Station
+ <ziel> den #ib#Nachbarn#ie# zum Erreichen des <endziel> als
+ neues <ziel> einsetzen und das Telegramm an diesen
+ Nachbarn weiterleiten.
+
+ <#ib#endquelle#ie#> Eigentliche #ib#Absenderstation#ie#. <quelle> ist dagegen immer
+ die Nummer der sendenden #ib#Nachbarstation#ie#.
+
+ <#ib#strom#ie#> Die #ib#Stromnummer#ie# identifiziert die virtuelle #ib#Verbindung#ie#. Sie
+ muß in den #ib#QUIT#ie#-Telegrammen angegeben werden.
+
+ <#ib#sequenz#ie#> -1 (Kennzeichen für OPEN)
+
+ <#ib#seite#ie#> Nummer der ersten echt allokierten #ib#Seite#ie# des #ib#Datenraum#ie#s
+ (=-1, falls Nilspace)
+
+ <#ib#quelltask#ie#> #ib#Task-Id#ie# der sendenden Task
+
+ <#ib#zieltask#ie#> Task-Id der empfangenden Task
+
+ <code> Wert des im #on("bold")##ib#send#ie##off ("bold")# angegebenen Codes
+#page#
+ - #ib#DATA#ie#-Telegramm
+
+
+
+
+
+ 0 1 2 3 4 5 6 7 8 9. Byte
++------+------+------+------+-------------+-------------+-------------------+
+I STX I LängeI Ziel IQuelleI Endziel I Endquelle I Strom I
++------+------+------+------+-------------+-------------+-------------------+
+
+ 10 11 12 13 14
++-------------+-------------+-----------------------------------------------+
+I Sequenz I Seite I n Byte Daten (Länge = 14 + n) I
++-------------+-------------+-----------------------------------------------+
+
+
+ <#ib#laenge#ie#> Gesamtlänge des Telegramms.
+ #on("b")#laenge#off("b")# = #on("b")##ib#nutzlaenge#ie##off("b")# + 14.
+ Für #on("b")#nutzlaenge#off("b")# sind nur die Werte 64,128,256 und 512
+ zugelassen (siehe 1). #on("b")#laenge#off("b")# wird codiert dargestellt (siehe
+ Teil 3).
+
+
+ <#ib#sequenz#ie#> wird von Telegramm zu Telegramm hochgezählt. Sie dient
+ der Überwachung bzgl. verlorengegangener Telegramme
+ bzw. durch #ib#Zeitüberwachung#ie# verdoppelter Telegramme.
+
+ <#ib#seite#ie#> Nummer der x-ten echt allokierten Seite des #ib#Datenraum#ie#s
+ (x = ((<sequenz> DIV anzahl pakete pro seite) + 2)
+
+ <n byte> #ib#Nutzinformation#ie#. Diese gehört zur #ib#Adresse#ie# a des Daten­
+ raums.
+
+ a =
+ N (<sequenz> DIV anzahl pakete pro seite + 1) * 512
+ + (<sequenz> MOD anzahl pakete pro seite) * n
+
+ wobei N (x) die Nummer der x-ten Seite und
+ n die #ib#Nutzdatenlänge#ie# ist.
+
+ Aus den Formeln ergibt sich, daß diese Nummer schon in
+ einem vorhergehenden DATA/OPEN-Telegramm über­
+ mittelt wurde (im Feld <seite>).
+
+ - #ib#QUIT#ie#-Telegramm
+
+
+ 0 1 2 3 4 5 6 7 8 9. Byte
++------+------+------+------+-------------+-------------+-------------------+
+I STX I 12 I Ziel IQuelleI Endziel I Endquelle I Strom I
++------+------+------+------+-------------+-------------+-------------------+
+
+ 10 11
++-------------+
+I Quit I
++-------------+
+
+
+
+ <#ib#strom#ie#> muß die #ib#Stromnummer#ie# sein, die in dem #ib#OPEN#ie#/#ib#DATA#ie#­
+ Telegramm stand, das quittiert wird.
+
+ <quit> 0 : ok. Nächstes Telegramm schicken.
+
+ -1: #ib#Übertragung#ie# neu starten (mit #ib#OPEN#ie#), weil die Emp­
+ fangsstation das OPEN nicht erhalten hat.
+
+ -2: Übertragung ca. 20 Telegramme zurücksetzen.
+
+ -3: Übertragung abbrechen.
+
+ -4: #ib#Quittung#ie# für letztes Telegramm einer Sendung.
+
+
+e) #ib#Vermittlungsebene#ie##goalpage("vermittlung")# #goalpage("collector")#
+
+ Diese Ebene ist dafür zuständig, Namen von Tasks auf anderen Stationen in
+ #ib#Task-Id#ie#'s (Werte des Typs TASK) zu wandeln und umgekehrt. Hierzu wird im
+ entsprechenden #ib#OPEN#ie#-Telegramm der Code -6 (bzw. -7) als <code> ein­
+ getragen. Die #ib#Netzempfangstask#ie# erkennt diese #ib#Codes#ie# und wickelt die Aufgaben
+ selbst ab, so daß es dabei nicht nötig ist, irgendeine Task-Id der #ib#Zielstation#ie# zu
+ kennen.
+
+ Dieses Verfahren ist möglich, weil im #on("bold")##ib#send#ie##off ("bold")# nur positive Codes erlaubt sind.
+#page#
+f) #ib#Höhere Ebenen#ie#
+
+ Höhere Ebenen sind nicht mehr netzspezifisch. Sie basieren alle auf dem Send/
+ Wait-Konzept des EUMEL. So gibt es z.B. den #on("bold")##ib#global manager#ie##off ("bold")#, der Aufbewah­
+ rung und Zugriff von #ib#Datei#ie#en in einer Task regelt. Dabei darf diese Task (bei der
+ Variante #on("bold")##ib#free global manager#ie##off ("bold")#) auf einer beliebigen #ib#Station#ie# im Netz liegen. Wegen
+ des #ib#Rendezvous-Konzept#ie#s können beliebige Sicherheitsstrategien benutzt werden
+ (z.B.: keine Dateien an Station 11 ausliefern). Von großem Wert ist z.B., daß
+ man ohne weiteres das Archiv (Floppylaufwerk) einer anderen Station anmelden
+ und benutzen kann, wodurch eine einfache Konvertierung von Floppyformaten
+ möglich ist. Dies ist möglich, weil auch die Archiv-Task der Stationen sich an
+ das Globalmanagerprotokoll halten.
+
+
+
+
+
+Bemerkungen
+
+#ib#Fehlerbehandlung#ie# besteht bis Ebene c) darin, fehlerhafte #ib#Telegramm#ie#e einfach zu
+entfernen. Die Ebene d) überwacht den Netzverkehr sowieso über #ib#Timeout#ie#s, die eine
+Wiederholung eines Telegrammes bewirken, wenn die #ib#Quittung#ie# ausbleibt.
+
+Da bei der sendenden #ib#Station#ie# der ganze #ib#Datenraum#ie# zur Verfügung steht, ist eine
+#ib#Fenstertechnik#ie# (wie bei #ib#HDLC#ie#) nicht nötig. Es kann zu jedem Zeitpunkt um beliebig
+viele Telegramme zurückgesetzt werden.
+
+Da im EUMEL eine #ib#Textdatei#ie# ein #ib#Datenraum#ie# mit sehr komplexer Struktur ist (wegen
+der Insert/Delete-Möglichkeiten, ohne den Rest der #ib#Datei#ie# zu verschieben), ist es ein
+hoher Aufwand, von einem fremden Betriebssytem aus eine Textdatei in das
+EUMEL-Netz zu senden. Für solche Zwecke muß noch eine einfachere Dateistruktur
+definiert und entsprechende Dateikonverter erstellt werden.
+#page#
+
+2.3. Stand der Netzsoftware
+
+#goalpage("2.3")#
+
+Das EUMEL-System wickelt die Prozedur #on("bold")##ib#send#ie##off("bold")# über das Netz ab, wenn die Sta­
+tionsnummer der #ib#Zieltask#ie# ungleich der eigenen #ib#Stationsnummer#ie# ist. Umgekehrt kann
+man der von der Prozedur #on("bold")##ib#wait#ie##off("bold")# gelieferten Absendertask die #ib#Absenderstation#ie# entneh­
+men (siehe Prozedur #on("bold")##ib#station#ie##off("bold")# in Teil 1).
+
+Anders als bei einem #on("bold")##ib#send#ie##off("bold")# innerhalb einer Station meldet ein #on("bold")#send#off("bold")# an eine Task einer
+fremden Station immer 0 zurück (Task gibt es und Task war im wait), obwohl dies
+nicht der Fall sein muß. Ist die Sendung vollständig zur Zielstation übertragen, so
+versucht der dortige #ib#Collector#ie# diese hundertmal im Sekundenabstand zuzustellen.
+Bleibt das erfolglos, wird die Sendung vernichtet.
+#pagenr ("%", 33)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Teil 3 : Netz Hardware Interface
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#page#
+
+Teil 3: Netz-Hardware-Interface
+
+
+#goalpage("3")#
+
+
+3.1. Einführung
+
+ #goalpage("3.1")#
+
+In diesem Teil der Netzbeschreibung wird die #ib#Schnittstelle#ie# beschrieben, über die
+#ib#Netzhardware#ie# (also #ib#Datenbox#ie#en, #ib#Netzbox#ie#en oder Netzkarten) an die EUMEL-Netz­
+Software angepaßt werden kann. Dieser Teil der Beschreibung ist also nur für Netz­
+implementatoren wichtig.
+
+Das EUMEL-Netz wurde dazu konzipiert, zwei oder mehr EUMEL-Rechner über
+#ib#V.24#ie#-Leitungen oder Datenboxen miteinander zu vernetzen. Dem heutigen Stand der
+Technik entsprechend, werden auf dem Markt eine Reihe von Möglichkeiten ange­
+boten, um PC's zu vernetzen. Diese Netze unterscheiden sich auch dadurch, daß
+unterschiedliche Medien zur Datenübertragung benutzt werden. Das #ib#EUMEL-
+Datenboxen-Netz#ie# benutzt Telefonkabel, #ib#Ethernet#ie# beispielsweise Koax-Kabel. Auch
+Lichtleiter werden zur Datenübertragung benutzt. Entsprechend gibt es eine ganze
+Menge Hardware (#ib#Treiber#ie#, Netzzugangsgeräte, Datenboxen, Anschlußkarten), die die
+Kopplung zwischen einem #ib#I/O-Kanal#ie# eines Rechners und dem Übertragungsmedium
+(Kabel) übernimmt. Das Netz-Hardware-Interface soll als #ib#Schnittstelle#ie# zwischen der
+Netz­Software und dem Treiber dienen. Damit wird es möglich, mehrere EUMEL-
+Rechner über verschiedene (Teil-) Netze (in dieser Beschreibung Stränge genannt)
+und unterschiedliche #ib#Netzhardware#ie# (Treiber) miteinander zu verbinden. Für den
+EUMEL-Benutzer soll dabei kein Unterschied in der Benutzung des EUMEL-Netzes
+feststellbar sein.
+#page#
+Neben unterschliedlichen Übertragungsmedien und Treibern gibt es weitere Unter­
+schiede zwischen Netzen:
+
+ - in der Netztopologie (Bus-, Ring- oder Sternnetze),
+
+ - in den Netzzugangsverfahren (Token passing, time slice token, slotting oder
+ CSMA/CD),
+
+ - in der #ib#Übertragungsgeschwindigkeit#ie#,
+
+ - im Aufbau der einzelnen #ib#Pakete#ie(1,", Aufbau der")# (#ib#Netztelegramm#ie#e).
+
+Alles, was mit den ersten drei Punkten zusammenhängt, wird von den Netzzugangs­
+geräten behandelt.
+
+Der Paketaufbau aber muß zumeist im Rechner geschehen und kann in den seltens­
+ten Fällen ganz vom Treiber übernommen werden. Ebenso kann der Treiber aus den
+empfangenen Paketen nicht immer die Teile herausfiltern, die von der EUMEL-
+#ib#Netzsoftware#ie# gebraucht werden. Diese Aufgaben übernimmt das #ib#Netz-Hardware-
+Interface#ie#. Das Netz-Hardware-Interface stellt die #ib#Verbindung#ie# zwischen EUMEL-
+#ib#Netzsoftware#ie# und den verschiedenen Netzhardwarearten dar. Ähnlich wie bei den
+Drucker- und Terminal-Anpassungen wurde ein hardwareabhängiger Teil aus der
+Netzsoftware abgetrennt und in einem eigenen #ib#Paket#ie# zusammengefaßt. Beim Start
+des Netzes wird durch Angabe des entsprechenden #ib#Netzmodus#ie# für den jeweiligen
+#ib#Kanal#ie# die entsprechende Anpassung für den benutzten Treiber ausgewählt. Wenn
+andere, neue Treiber angepaßt werden sollen, so müssen lediglich in dem Paket #on("b")##ib#net
+hardware interface#ie##off("b")# die entsprechenden Prozeduren hinzugefügt und die #ib#Sprungleisten#ie#
+(#ib#SELECT#ie#-Statements) erweitert werden.
+
+Durch das #ib#Knotenkonzept#ie# in der #ib#Netzsoftware#ie# ist es möglich, über einen #ib#Knoten­
+rechner#ie# Teilnetze (Stränge), die mit unterschiedlicher #ib#Netzhardware#ie# arbeiten, mitein­
+ander zu verbinden. Es sind dann beispielsweise Verbindungen zwischen Rechnern,
+die über #ib#Ethernet#ie# vernetzt sind, und Rechnern auf dem EUMEL-Datenboxen-Netz
+möglich. Es ist auch möglich, mit einem Rechner Zugang zu einem Netz zu erhalten,
+für das spezielle #ib#Netzhardware#ie# erforderlich ist (Datenboxen, Ethernet-Anschluß). Man
+kann den Rechner über eine Rechner-Rechner-Kopplung (#ib#V.24#ie#) mit einem Rechner
+verbinden, der bereits ans Netz angeschlossen ist, und so (allerdings auf Kosten der
+Leistung des #ib#Knotenrechner#ie#s) Netzhardware einsparen.
+#page#
+
+3.2. Arbeitsweise des
+ Netz-Hardware-Interfaces
+
+
+
+
+
+ #goalpage("3.2")#
+
+Grob vereinfacht kann man sich die Arbeitsweise der #ib#EUMEL-Netz-Software#ie# so vor­
+stellen:
+
+ reset box;
+ REP
+ IF zeichen da THEN lies telegramm ein
+ ELIF telegramm auszugeben THEN gib telegramm aus
+ FI
+ PER .
+
+(Es ist nur der Teil der Software beschrieben, der die Kanalbehandlung betrifft).
+
+
+Das Zusammenspiel zwischen EUMEL-Netz und Netz-Hardware-Interface ge­
+schieht auf folgende Weise:
+
+
+ #on("b")#reset box;#off("b")#
+ REP
+ IF zeichen da THEN #on("b")#next packet start#off("b")#;
+ lies telegramm ein
+ ELIF telegramm auszugeben THEN gib telegramm aus
+ FI
+ PER.
+
+ gib telegramm aus:
+ #on("b")#transmit header#off("b")#;
+ gib eumelnetztelegramm aus;
+ #on("b")#transmit trailer #off("b")#.
+
+Die fett gedruckten Programmteile werden im Netz-Hardware-Interface realisiert, die
+anderen Teile stecken in den darüberliegenden Teilen der EUMEL-Netz-Software.
+#page#
+Beim Senden eines #ib#Telegramm#ie#s wird von der #ib#Netzsoftware#ie# zuerst der #ib#Vorspann#ie# in
+einem #ib#Datenraum#ie# an das Hardware-Interface übergeben (#on("b")##ib#transmit header#ie##off("b")#). Im Hard­
+ware-Interface können aus dem Vorspann die entsprechenden Informationen (Tele­
+grammlänge, #ib#Zielstation#ie# usw.) entnommen werden. Dann wird von der Netzsoftware
+das Telegramm (inklusive Vorspann) per #on("b")##ib#blockout#ie##off("b")# übergeben. Danach wird #on("b")##ib#transmit
+trailer#ie##off("b")# aufgerufen, um dem Hardware-Interface das Ende des Telegramms zu mel­
+den. Beim Empfang ruft die Netzsoftware zuerst die #ib#I/O Control#ie# #ib#Telegrammfreigabe#ie#
+auf [7]. Danach wird das erste #ib#Zeichen#ie# des Telegramms angefordert (#on("b")##ib#next packet
+start#ie##off("b")#). Falls ein #ib#STX#ie# geliefert wurde, wird das Telegramm per #on("b")##ib#blockin#ie##off("b")# eingelesen. Falls
+#ib#Niltext#ie# zurückgeliefert wird, wird von der Netzsoftware #ib#Timeout#ie# angenommen. Alle
+anderen Zeichen werden so interpretiert, als ob Störungen aufgetreten wären. Die
+Netzsoftware übernimmt die #ib#Fehlerbehandlung#ie#. Dazu wird u. U. ein Leerlesen des
+Puffers vom Hardware-Interface verlangt (#on("b")##ib#flush buffers#ie##off("b")#).
+
+Bei der Einstellung der #ib#Nutzdatenlänge#ie# (#on("b")##ib#data length#ie##off("b")#) ist zu beachten, daß
+
+a) alle #ib#Station#ie#en, die an einem #ib#Strang#ie# hängen, auf die gleiche Nutzdatenlänge
+ eingestellt sein müssen.
+
+b) Wenn mehrere Stränge über #ib#Knoten#ie# miteinander verbunden sind, muß die Nutz­
+ länge für Sendungen über Knoten (#on("b")##ib#data length via node#ie##off("b")#) auf allen Stationen des
+ gesamten Netzes gleich eingestellt sein. Die Zusammenfassung oder Aufteilung
+ von #ib#Telegramm#ie#en in Knoten ist nicht möglich.
+
+c) Als mögliche Nutzdatenlänge sind folgende Werte erlaubt:
+
+ 64, 128, 256 und 512 Byte.
+
+ Größere Nutzdatenlängen sind zur Zeit nicht möglich.
+
+d) Je größer die #ib#Nutzdatenlänge#ie# ist, desto geringer ist der Overhead an #ib#Zeichen#ie#,
+ die auf den Rechnern verarbeitet werden müssen. Allerdings muß der Rechner
+ leistungsfähig genug sein, die ankommenden Blöcke schnell genung zu verarbei­
+ ten, und die Netztreiber müssen entsprechend große Puffer haben.
+
+
+Alle implementierten Netzanpassungen sollen in einem Netz-Hardware-Interface
+zusammengefaßt werden. Dies ist notwendig, um über #ib#Knotenrechner#ie# Netzstränge
+verbinden zu können, die mit unterschiedlicher #ib#Netzhardware#ie# arbeiten. So können
+zum Beispiel ein #ib#Strang#ie#, der mit Datenboxen aufgebaut ist, und ein #ib#Ethernet#ie#-#ib#Strang#ie#
+über einen Knotenrechner miteinander verkoppelt werden.
+#page#
+Aus diesem Grund wurden #on("b")#Netzmodi#off("b")# eingeführt. Man kann dadurch, daß die Netz­
+modi, genau wie die #ib#Kanal#ie#angaben, in der #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# niedergelegt sind, ohne Aus­
+tausch einer Softwarekomponente die Netzhardware wechseln. Es gibt auch die
+Möglichkeit, durch verschiedene Netzmodi unterschiedliche Treiber an ein und das­
+selbe Netz anzuschließen. Beispielsweise gibt es für einige Rechnertypen Steckkarten,
+mit denen der Rechner an das Ethernet angeschlossen werden kann. Man kann,
+wenn diese Karten angepaßt sind, den #ib#Ethernet#ie#-Zugang über verschiedene Netz­
+anschlußkarten realisieren.
+
+Das Netz-Hardware-Interface muß folgende Aufgaben übernehmen:
+
+ Bei der Ausgabe an den Treiber:
+
+ - Generieren und Ausgeben des #ib#Paket#ie#headers,
+ - Umsetzen von logischen Stationsadressen (#ib#Stationsnummer#ie#n) in phy­
+ sische #ib#Adresse#ie#n,
+ - Ausgeben der Daten (EUMEL-Netz-#ib#Telegramm#ie#e),
+ - Generieren und Ausgeben des Trailers und evtl. Auffüllen des Pakets mit
+ #ib#Füllzeichen#ie#, falls auf dem Netz eine Mindestlänge für Pakete gefordert
+ wird.
+
+ Bei der Eingabe vom Treiber:
+
+ - Weglesen von #ib#Füllzeichen#ie#,
+ - Prüfen der #ib#Adresse#ie#n,
+ - Weglesen von #ib#Paket#ie#teilen, die in der EUMEL-Netz-Software nicht
+ gebraucht werden.
+
+ Weiterhin können Funktionen wie
+
+ - Reset des Treibers,
+ - Prüfung, ob Stationsadresse und #ib#Adresse#ie# im Treiber übereinstimmen,
+ - Statistik und Service
+
+ durch das Netz-Hardware-Interface übernommen werden.
+
+Dazu wird ein Satz von Prozeduren über die #ib#DEFINES#ie#-#ib#Schnittstelle#ie# des Netz-
+Hardware-Interfaces zur Verfügung gestellt. Wenn neue Treiber oder Netzarten
+implementiert werden sollen, so muß an diesem Interface nichts geändert werden. Die
+herausgereichten Prozeduren realisieren #ib#Sprungleisten#ie# (#ib#SELECT#ie#-Statements), über
+die durch Erweiterung (#ib#CASE#ie#) die Prozeduren erreicht werden können, die den ent­
+sprechenden #ib#Netzmodus#ie# realisieren. Außerdem werden Informationsprozeduren für die
+darüberliegenden Programmteile zur Verfügung gestellt.
+#page#
+
+3.3. Netztreiber
+
+ #goalpage("3.3")#
+Unter #ib#Netztreiber#ie#n versteht man die Einheiten, die den Anschluß des Rechners an ein
+Netz realisieren. Das können #ib#Netzbox#ie#en sein, die mit dem Rechner über eine #ib#V.24#ie#-
+Leitung verbunden sind, aber auch Anschlußkarten, die direkt auf den Datenbus des
+Rechners gehen. Falls die #ib#Schnittstelle#ie# der Treiber-Hardware eine andere als die
+serielle #ib#V.24#ie# ist, muß in der Regel eine Anpassung für die Hardware im #ib#SHard#ie# vorge­
+nommen werden.
+
+Falls der Treiber über eine serielle #ib#V.24#ie#-#ib#Schnittstelle#ie# mit dem Rechner verbunden
+ist, wie das auch bei der direkten Kopplung oder dem Datenboxennetz der Fall ist,
+wird die hohe #ib#Übertragungsgeschwindigkeit#ie# auf dem eigentlichen Netz durch die
+relativ geringe Übertragungsgeschwindigkeit auf der #ib#V.24#ie#-#ib#Schnittstelle#ie# zwischen
+Rechner und Treiber (Box) gebremst. Über andere Schnittstellen im Rechner, wenn
+sie mit #ib#Stream I/O#ie# [7] betrieben werden, kann man dies vermeiden. Diese Schnitt­
+stellen müssen vom SHard bedient werden.
+
+Wenn in den Rechner integrierte Netztreiber (Netzanschlußkarten) benutzt werden
+sollen, so muß in der Regel die Behandlung dieser Netzanschlußkarte im SHard
+durchgeführt werden.
+
+Um effizient implementieren zu können, sollte darauf geachtet werden, daß möglichst
+wenig zusätzliche #ib#Zeichen#ie# von der #ib#Netzsoftware#ie# bzw. dem Netz-Hardware-Inter­
+face bearbeitet werden müssen. Das Auffüllen von Paketen auf eine Mindestlänge
+sollte möglichst vom Treiber gemacht werden, ebenso wie das Weglesen dieser
+Zeichen.
+
+Um einen sicheren und effektiven Netzbetrieb zu garantieren, sollten die Treiber
+folgende Eigenschaften haben:
+
+ - Die #ib#Stationsadresse#ie# ist im Treiber festgelegt, sie soll nicht ohne weiteres
+ verändert werden können (Datenschutz).
+ - Der Treiber reicht nur #ib#Paket#ie#e mit richtiger #ib#Zieladresse#ie#, keine #ib#Broad- oder
+ Multicasts#ie# an die Netzsoftware weiter.
+ - Der Treiber sendet nur #ib#Paket#ie#e mit richtiger #ib#Absenderadresse#ie# bzw. setzt die
+ Absenderadresse selbst ein.
+ - Die am Treiber eingestellte #ib#Adresse#ie# kann abgefragt werden, oder es wird,
+ wenn ein Paket mit falscher #ib#Absenderadresse#ie# vom Rechner kommt, eine
+ #ib#Fehlermeldung#ie# an den Rechner gegeben. Die Fehlermeldung muß durch das
+ Netz-Hardware-Interface in den #on("b")##ib#report#ie##off("b")# eingetragen werden.
+ - Falls Pakete mit #ib#Füllzeichen#ie# aufgefüllt werden müssen, sollten die Füll­
+ zeichen durch den Treiber generiert und beim Empfang wieder entfernt
+ werden.
+ - Falls mehrere Betriebsmodi möglich sind, so sollten sie softwaremäßig
+ einstellbar sein.
+ - Falls die Treiber über eine serielle #ib#Schnittstelle#ie# an den Rechner angeschlos­
+ sen werden, so sollte der Treiber konfigurierbar sein. In jedem Fall sollte die
+ serielle Schnittstelle mit #ib#Flußkontrolle#ie# (#ib#RTS/CTS#ie#) implementiert werden.
+
+Zusätzlich ist ein Transparent-Modus als #ib#Netzmodus#ie# von Vorteil:
+
+ - Der Modus (transparent) kann zu Testzwecken benutzt werden. Beispiels­
+ weise um auch mit Rechnern kommunizieren zu können, die über Netz
+ erreichbar sind, aber kein EUMEL-Netz-#ib#Protokoll#ie# benutzen.
+
+ Modus n: transparent.
+
+ Ausgabeseitig: Das #ib#Paket#ie# wird unverändert ausgegeben.
+ #ib#Adresse#ie#n usw. müssen schon im Paket vor­
+ handen sein. Es wird nicht mit #ib#Füllzeichen#ie#
+ aufgefüllt.
+ Eingabeseitig: Das Paket wird unverändert an die Netzsoft­
+ ware weitergegeben.
+
+#page#
+
+3.4. Prozedurschnittstelle
+ des EUMEL-Netzes
+
+
+
+
+
+ #goalpage("3.4")#
+Im PACKET #on("b")##ib#net hardware interface#ie##off("b")# sind folgende Prozeduren untergebracht:
+
+
+
+ BOOL PROC #ib#blockin#ie#
+ (DATASPACE VAR ds, INT CONST seite, abstand, länge):
+
+ Versucht, #on("b")#länge#off("b")# Zeichen vom #ib#Kanal#ie# einzulesen. Liefert TRUE, wenn alle
+ Zeichen eingelesen wurden, FALSE, wenn innerhalb einer bestimmten
+ Zeit nicht alle #on("b")#länge#off("b")# Zeichen eingelesen werden konnten (z.B. weil der
+ Kanal nicht mehr Zeichen anliefert). Die eingelesenen Zeichen werden im
+ #ib#Datenraum#ie# #on("b")#ds#off("b")# in #ib#Seite#ie# #on("b")#seite#off("b")# ab #on("b")#abstand#off("b")# bis #on("b")#abstand#off("b")# + #on("b")#länge#off("b")# - 1 abge­
+ legt.
+
+ #ib#Fehlerfall#ie#:
+
+ #on("b")#blockin Abbruch#off("b")#
+
+ Es werden weniger #ib#Zeichen#ie# innerhalb einer festgelegten Zeitspanne über
+ den Kanal angeliefert, als mit #on("b")#länge#off("b")# gefordert.
+
+ Passiert z.B., wenn die Kabel während einer Netzübertragung unter­
+ brochen werden, oder wenn die Gegenstelle abgeschaltet wird. Das
+ #ib#Telegramm#ie# wird vernichtet, die Prozedur liefert FALSE, es wird eine
+ entsprechende Meldung im #on("b")##ib#report#ie##off("b")# erzeugt.
+
+ PROC #ib#blockout#ie#
+ (DATASPACE CONST ds, INT CONST seite, abstand, länge):
+
+ Der Inhalt von Seite #on("b")#seite#off("b")# des #ib#Datenraum#ie#s #on("b")#ds#off("b")# wird von #on("b")#abstand#off("b")# bis
+ #on("b")#abstand#off("b")# + #on("b")#länge#off("b")# - 1 ausgegeben.
+#page#
+ PROC #ib#set net mode#ie# (INT CONST mode):
+
+ Es wird der #ib#Netzmodus#ie# #on("b")#mode#off("b")# eingestellt. Im Netz-Hardware-Interface
+ müssen alle Initialisierungen und Einstellungen vorgenommen werden,
+ damit die mit #on("b")#mode#off("b")# geforderte #ib#Netzhardware#ie# unterstützt wird. Diese
+ Prozedur wird bei jedem #on("b")##ib#start#ie##off("b")#-Kommando in der Netztask aufgerufen.
+ Kann als Initialisierungsprozedur für dieses PACKET verwendet werden.
+ Übergibt den in der #ib#Datei#ie# #on("b")##ib#netz#ie##off("b")# für diesen #ib#Kanal#ie# verlangten Netzmodus an
+ das Netz-Hardware-Interface. Nach Aufruf dieser Prozedur müssen die
+ wertliefernden Prozeduren #on("b")##ib#net mode#ie#, #ib#mode text#ie#, #ib#data length#ie##off("b")# und #on("b")##ib#data
+ length via node#ie##off("b")# korrekt initialisiert sein. Der Aufruf von #on("b")##ib#net addess#ie##off("b")# muß
+ die korrekten (physikalischen) #ib#Adresse#ie# der #ib#Station#ie#en liefern.
+
+ TEXT PROC net address (INT CONST stationsnummer):
+
+ Liefert die (Hardware-) Netz-#ib#Adresse#ie#, über die der EUMEL-Rechner
+ mit der Stationsnummer #on("b")##ib#stationsnummer#ie##off("b")# beim aktuell für diesen Kanal
+ eingestellten #ib#Netzmodus#ie# erreichbar ist. Auf diese #ib#Adresse#ie# muß der Treiber
+ des entsprechenden Rechners eingestellt sein. Auch die eigene Netz-
+ Adresse muß mit der im Treiber eingestellten #ib#Adresse#ie# übereinstimmen.
+ Insbesondere müssen alle Stationen, die auf dem Netz arbeiten, dieselbe
+ Netz-Adresse für eine #ib#Stationsnummer#ie# errechnen.
+
+ TEXT PROC #ib#mode text#ie#:
+
+ Liefert den Text (Namen) des eingestellten #ib#Netzmodus#ie#. Wird in #on("b")##ib#net
+ manager#ie##off("b")# benutzt, um den Netzmodus im #on("b")##ib#report#ie##off("b")# anzugeben.
+
+ TEXT PROC mode text (INT CONST mode):
+
+ Liefert den Text (Namen) zu dem #ib#Netzmodus#ie# #on("b")#mode#off("b")#.
+
+ INT PROC #ib#data length#ie# (INT CONST mode):
+
+ Liefert die #ib#Nutzdatenlänge#ie# (#ib#Länge#ie# der Nettodaten des Eumel-
+ Telegramms) im Netz. Wird von #on("b")##ib#basic net#ie##off("b")# beim Neustart aufgerufen. Muß
+ in einem Netz auf allen Stationen eines #ib#Strang#ie#s denselben Wert liefern.
+
+ Erlaubte Werte: 64, 128, 256 und 512.
+#page#
+ INT CONST #ib#data length via node#ie#:
+
+ Liefert die #ib#Nutzdatenlänge#ie# für Sendungen, die über #ib#Knoten#ie# gehen.
+ Muß auf allen Stationen des Netzes gleich sein.
+
+ Erlaubte Werte: 64, 128, 256 und 512.
+
+ PROC #ib#decode packet length#ie# (INT VAR value):
+
+ Die #ib#Länge#ie# eines Netztelegramms ist im #ib#Telegramm#ie# codiert enthalten. Mit
+ dieser Prozedur wird aus dem Telegrammkopf die Telegrammlänge ermit­
+ telt:
+
+ Falls beim Aufruf dieser Prozedur in #on("b")#value#off("b")# der Wert des Feldes #on("b")#head#off("b")# aus
+ der Struktur #on("b")#vorspann#off("b")#, die in #on("b")#ds#off("b")# per #on("b")##ib#transmit header#ie##off("b")# übergeben wurde,
+ enthalten ist, so wird in #on("b")#value#off("b")# die Länge des EUMEL-Netztelegramms
+ zurückgeliefert.
+
+ PROC #ib#flush buffers#ie#:
+
+ Liest den Eingabepuffer des #ib#Netzkanal#ie#s leer. Die eingelesenen Zeichen
+ werden vernichtet. Wird nach Erkennen von #ib#Übertragungsfehler#ie#n aufge­
+ rufen.
+
+ TEXT PROC #ib#next packet start#ie#:
+
+ Liefert genau ein #ib#Zeichen#ie# (in der Regel das erste Zeichen des EUMEL-
+ Netztelegramms). Wird von der Netzsoftware immer dann aufgerufen,
+ wenn ein neues #ib#Paket#ie# erwartet wird.
+
+ Bedeutung des gelieferten Zeichens für die #ib#Netzsoftware#ie#:
+
+ #ib#STX#ie#: korrekter #ib#Telegrammanfang#ie# (ist das erste Zeichen des
+ EUMEL-Netztelegramms). Der Rest des EUMEL-Netztele­
+ gramms steht im Eingabepuffer, ist also über #ib#blockin#ie# lesbar.
+ Vorher wurden nur Zeichen eingelesen, die zum verwendeten
+ #ib#Netzprotokoll#ie# gehören (z.B. #ib#Ethernet#ie#-#ib#Adresse#ie#n, #ib#Füllzeichen#ie#
+ usw.).
+ niltext: kein neues Telegramm da
+
+ jedes andere Zeichen:
+ Fehler. Entweder wurden Störzeichen eingelesen oder es
+ gingen Zeichen verloren. #ib#Fehlerbehandlung#ie# erfolgt durch die
+ Netzsoftware.
+#page#
+ PROC #ib#transmit header#ie# (DATASPACE CONST ds):
+
+ Wird vor Ausgabe eines jeden #ib#Telegramm#ie#s aufgerufen. In dem #ib#Datenraum#ie#
+ #on("b")#ds#off("b")# wird von der EUMEL-Netz-Software der #on("b")##ib#Vorspann#ie##off("b")# übergeben. Über
+ den jeweiligs eingestellten #ib#Netzmodus#ie# kann für jede implementierte Netz­
+ art über eine #ib#Sprungleiste#ie# (#ib#SELECT#ie#) die Prozedur angesprungen werden,
+ die den #ib#Header#ie# für den eingestellten Netzmodus erstellt und ausgibt.
+ Struktur des von der EUMEL-Netz-Software benutzten Headers:
+
+ BOUND STRUCT
+ (INT head,
+ zwischenziel,
+ zielrechner,
+ quellrechner,
+ strom,
+ sequenz,
+ seitennummer ) VAR vorspann.
+
+ Aus dem Inhalt des Feldes #on("b")#head#off("b")# kann mittels #on("b")##ib#decode packet length#ie##off("b")# die
+ Gesamtlänge des EUMEL-Netztelegramms errechnet werden.
+
+ PROC #ib#transmit trailer#ie#:
+
+ Wird nach Ausgabe eines jeden Telegramms aufgerufen. Evtl. notwendige
+ Nachspänne können ausgegeben werden. Die notwenigen Informationen
+ wurden in #on("b")##ib#transmit header#ie##off("b")# übergeben und müssen aufbewahrt werden,
+ falls sie im Trailer mitgeliefert werden müssen. Kann auch dazu benutzt
+ werden, den unter diesem Packet liegenden Schichten (#ib#SHard#ie# oder Hard­
+ ware) das Ende des Telegramms mitzuteilen. Notwendige #ib#Füllzeichen#ie#
+ können in dieser Prozedur in das #ib#Paket#ie# eingebaut werden.
+
+ PROC #ib#reset box#ie# (INT CONST net mode):
+
+ Kann zur Initialisierung der #ib#Netzhardware#ie# benutzt werden. Wird von #on("b")##ib#basic
+ net#ie##off("b")# beim jedem Neustart aufgerufen.
+
+ INT PROC #ib#max mode#ie#:
+
+ Liefert den Wert des größten erlaubten (implementierten) #ib#Netzmodus#ie#.
+
+ INT PROC #ib#net mode#ie#:
+
+ Liefert den eingestellten Netzmodus.
+#page#
+#pagenr ("%", 45)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Anhang
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#clear pos##lpos(1.0)##rpos(9.5)##goalpage("A")#
+
+Anhang: Netz-Meldungen#goalpage("A.1")#
+
+Mit dem Kommando #on("b")##ib#list#ie# (/"net list")#off("b")# (siehe Teil 1) erhalten Sie eine temporäre #ib#Datei#ie#
+auf den Bildschirm. Diese Datei könnte ungefähr so aussehen:
+
+____________________________________________________________________________
+
+ N e u e r S t a r t 12:44 Stationsnummer : 38
+ 01.06.87 12:55 net port 8:20:Nicht zustellbar. . Empfänger: "net dok". Quelle 34 Taskindex: 255
+ 02.06.87 06:30 net port 8:1:wdh data. sqnr 7. Absender: "net dok". Ziel 34 Taskindex: 255
+ 02.06.87 07:03 net port:20:Sequenzfehler: soll 13 ist 14. Empfänger: "POST". Quelle 33 Taskindex:
+ 02.06.87 07:03 net port:blockin abbruch
+ 02.06.87 07:03 net port:20:Sequenzreset von 13 auf 10. Empfänger: "POST". Quelle 33 Taskindex: 29
+ 02.06.87 07:36 net port:Call gelöscht."net dok". Strom 1
+ 02.06.87 07:43 net port 8:verbotene Route: 34
+ 02.06.87 07:50 net port:Header inkorret eingelesen: %0 %2
+ 02.06.87 07:50 net port:buffers flushed
+ 02.06.87 07:52 net port:Weiterleitung nicht möglich für 34
+ 02.06.87 07:53 net port 8:skipped0 6 G O 1 0 . 0 %13 %10 2 8 0 6 0 6 G O 1 0 . 0 %13 %10 2 8 0
+ 02.06.87 08:14 net port 8:skipped%13 %10 S p e c . R e c e i v e E r r o r C 2
+ 02.06.87 08:21 net port:20:Reopen. Empfänger: "WÜFE". Quelle 40 Taskindex: 22
+ 02.06.87 09:25 net port:1:etwas rueckgespult. Absender: "-". Ziel 33 Taskindex: 51
+ 02.06.87 09:25 net port:1:wdh data. sqnr 20. Absender: "-". Ziel 33 Taskindex: 51
+ 02.06.87 09:54 net port:20:Blocknummer falsch, neu: 192, alt : -1. Empfänger: "WÜFE". Quelle 44
+ 02.06.87 10:12 net port:Daten ohne Eroeffnung von 40 Sequenznr 7
+ 02.06.87 10:23 net port:Header inkorret eingelesen: O X 0 3 8 B O X 0 4 4 E U %2
+ 02.06.87 10:23 net port:buffers flushed
+ 02.06.87 10:49 net port:1:wdh open. Absender: "-". Ziel 33 Taskindex: 255
+ 02.06.87 10:49 net port:2:wdh open. Absender: "net dok". Ziel 33 Taskindex: 255
+ 02.06.87 10:53 net port:1:Sequenzfehler: soll 2 ist 3. Empfänger: "net dok". Quelle 33 Taskindex:
+ 02.06.87 10:54 net port:1:Sequenzreset von 8 auf 5. Empfänger: "net dok". Quelle 33 Taskindex: 11
+ 02.06.87 10:56 net port:2:etwas rueckgespult. Absender: "-". Ziel 33 Taskindex: 51
+ bekannte Stationen:
+ 1(8,1) 2(8,2) 3(8,3) 4(8,4) 5(8,5) 6(8,6) 7(8,7) 8(8,8) 9(8,9) 10(8,10)
+ 11(8,11) 12(8,12) 13(8,13) 14(8,14) 15(8,15) 16(8,16) 17(8,17) 18(8,18)
+ 19(8,19) 20(8,20) 21(8,21) 22(8,22) 23(8,23) 24(8,24) 25(8,25) 26(8,26)
+ 27(8,27) 28(8,28) 29(8,29) 30(8,30) 31(8,31) 32(8,32) 33(9,33) 34(8,34)
+ 35(9,35) 36(9,36) 37(9,37) 39(9,39) 40(9,40) 41(9,41) 42(9,42) 43(9,43)
+ 44(9,44) 45(9,45) 46(9,46) 47(9,47) 48(9,48)
+ --------
+ Eingestellte Netzmodi:
+ net port 8 haengt an Kanal 8, Modus: (1) EUMEL-Netz 64 Byte
+ net port haengt an Kanal 9, MODUS: (11) ETHERNET via V.24 512 Byte
+
+ Nutzdatenlänge 512 Byte
+ Nutzdatenlänge bei indirekter Verbindung: 64 Byte
+ ********
+ Netz-Software vom 23.05.87
+ Rechner 38 um 11:11
+ net port 8
+
+ Strom 1 (sqnr7/8) sendet an 34 . Absender ist "net dok".
+ net port
+
+ Strom 1 (sqnr45/45) empfaengt von 40 . Empfaenger ist "PUBLIC".
+
+____________________________________________________________________________
+#page#
+Die Datei enthält den aktuellen #on("b")##ib#report#ie##off("b")#, in dem #ib#Fehlermeldung#ie#en der einzelnen Tasks
+gesammelt werden. Außerdem wird der Zustand aller Verbindungen (Ströme) von allen
+#on("b")##ib#net port#ie##off("b")#'s angezeigt. Im #on("b")#report#off("b")#-Teil kann man drei Informationsblöcke unterscheiden:
+
+a) den Block mit den Fehlermeldungen. Es werden jeweils Datum, Uhrzeit, der Name
+ des betroffenen #on("b")#net port#off("b")# und, wenn notwendig, die #ib#Stromnummer#ie# angegeben.
+ Darauf folgt der Meldungstext, der auch Informationen über Absender und Emp­
+ fänger enthalten kann.
+
+ <Datum> <Zeit> <Name der #ib#Kanaltask#ie#> : [<#ib#Stromnummer#ie#> : ] <Meldung>
+
+
+b) den Block mit der Liste der bekannten #ib#Station#ie#en. Ein Eintrag in dieser Liste ent­
+ hält jeweils die Stationsnummer der bekannten Station und in Klammern dahin­
+ ter die Nummer des Kanals auf diesem Rechner, über den die Station erreichbar
+ ist und die Nummer der nächsten #ib#Zwischenstation#ie#.
+
+ <Zielstation> (<Kanalnr>,<Zwischenstation>)
+
+ Bei direkt erreichbaren Stationen ist Zwischenstation gleich #ib#Zielstation#ie#.
+
+ Hinweis: Auch #ib#gesperrt#ie#e Stationen erscheinen in dieser Liste.
+
+
+c) den Block, der Auskunft über die Netzinstallation gibt. Es werden für jeden Netz­
+ kanal die eingestellten Netzmodi angegeben. Des weiteren werden die beiden
+ Größen #on("b")##ib#data length#ie##off("b")# (#ib#Nutzdatenlänge#ie#) und #on("b")##ib#data length via node#ie##off("b")# (Nutzdatenlänge bei
+ indirekter Verbindung) angegeben. Zusätzlich erscheinen noch die #ib#Netzversion#ie# und
+ die genaue Uhrzeit, zu der dieser #on("b")#report#off("b")# erstellt wurde.
+
+#page#
+Für jeden #on("b")##ib#net port#ie##off("b")# wird pro aktivem #ib#Strom#ie# folgende Meldung generiert:
+
+Strom <Stromnr> (sqnr<akt Seqnr>/<max Seqnr>) <Zustand> <Partner>
+
+
+<Stromnr> #ib#Stromnummer#ie#
+
+<akt Seqnr> #ib#Sequenznummer#ie# des gerade bearbeiteten #ib#Telegramm#ie#s
+
+<max Seqnr> Bei #ib#Sendeströme#ie#n die Nummer der letzten zu übertragenden
+ #ib#Sequenz#ie#, bei Empfangsströmen in der Regel die Nummer der
+ letzten Sequenz der gerade übertragenen #ib#Datenraumseite#ie#.
+
+<#ib#Zustand#ie#> Hier wird die Aktion (senden, empfangen usw.) und die Partner­
+ station angegeben.
+
+<#ib#Partner#ie#> Der Name der Task mit der kommuniziert wird.
+
+
+Die Meldungen, die in der #ib#Datei#ie# #on("b")##ib#report#ie##off("b")# protokolliert werden, kann man in verschiedene
+Gruppen einordnen. Die eine Gruppe beschreibt Störungen durch #ib#Zeichenverluste#ie#
+oder ­verfälschungen, eine andere Gruppe protokolliert besondere Situationen, bei­
+spielsweise den Abbruch von #ib#Übertragung#ie#en, und die letzte Gruppe befasst sich mit
+#ib#Fehlermeldung#ie#en, die ein Eingreifen von aussen notwendig machen. Je nachdem, ob
+die Station, auf der die Meldung protokolliert wird, Empfänger oder Absender ist, wird
+bei den Meldungen #ib#Stationsnummer#ie# und Taskname des Kommunikationspartners mit
+angegeben.
+
+Zur ersten Gruppe gehören:
+
+#ib(4)##ib#skipped#ie##ie(4)#
+ 'skipped' oder skipped mit einem Zusatztext erscheint, wenn Zei­
+ chen eingelesen wurden, die zu keinem gültigen #ib#Telegramm#ie# ge­
+ hören. Dies kann passieren, wenn auf der Leitung zwischen
+ Rechner und Box #ib#Zeichen#ie# verlorengegangen sind. Auch nach dem
+ Einschalten oder nach einem Reset auf Box oder Rechner kann
+ diese Meldung kommen. Mindestens ein Teil der eingelesenen
+ Daten wird mit ausgegeben, wobei Steuerzeichen durch % und den
+ Code des Steuerzeichens dargestellt werden. Die einzelnen Zeichen
+ werden durch ein Blank voneinander getrennt.
+#page#
+#ib(4)##ib#Sequenzfehler#ie##ie(4)#
+ Die #ib#Sequenznummer#ie# ist zu groß, es fehlen also Telegramme. Die
+ Gegenstation wird aufgefordert, ab einem früheren Telegramm zu
+ wiederholen.
+
+#ib(4)#wdh data#ie(4)#
+ Das letzte Telegramm wird erneut geschickt. Passiert, wenn die
+ #ib#Quittung#ie# für dieses Telegramm nach einer bestimmten Zeit nicht
+ angekommen ist.
+
+#ib(4)##ib#Sequenzreset#ie##ie(4)#
+ Die #ib#Sequenznummer#ie# des empfangenen Telegramms ist kleiner als
+ die Sequenznummer des vorher empfangenen Telegramms. Die
+ Verbindung wird bei der zuletzt empfangenen Sequenznummer
+ fortgesetzt.
+
+#ib(4)#Blocknummer falsch#ie(4)#
+ Die #ib#Seitennummer#ie# in dem #ib#Telegramm#ie# ist falsch.
+
+#ib(4)#etwas rueckgespult#ie(4)#
+ Auf Anforderung der Gegenseite werden die letzten drei #ib#Datenraum­
+ seite#ie#n erneut übertragen.
+
+#ib(4)#Daten ohne Eroeffnung#ie(4)#
+ Es werden Telegramme mit einer #ib#Stromnummer#ie# empfangen, zu der
+ vorher kein OPEN-Telegramm empfangen wurde. In diesem Fall
+ wird die Gegenstation aufgefordert, die #ib#Übertragung#ie# von vorn zu
+ beginnen. Diese Meldung kann auch kommen, wenn das Netz neu
+ gestartet wurde.
+
+#ib(4)#wdh open#ie(4)#
+ Die Übertragung wird mit dem #ib#OPEN#ie#-Telegramm von vorn begon­
+ nen. Passiert auf Aufforderung durch die Gegenstation oder wenn
+ das erste OPEN-Telegramm nicht quittiert wurde.
+
+#ib(4)##ib#buffers flushed#ie##ie(4)#
+ Alle bereits eingelesenen, aber noch nicht bearbeiteten Zeichen
+ wurden gelöscht (der #ib#Eingabepuffer#ie# wurde komplett gelöscht). Verur­
+ sacht durch schwere Störungen (#ib#Zeichenverluste#ie# oder -verfäl­
+ schungen).
+#page#
+#ib(4)#blockin abbruch#ie(4)#
+ Es wurden nicht alle Zeichen eines Telegramms innerhalb eines
+ bestimmten Zeitraums angeliefert.
+
+#ib(4)#Header inkorrekt eingelesen#ie(4)#
+ Es wurde ein Fehler in dem Teil des Netztelegramms gefunden, der
+ nicht zum EUMEL-Netz gehört.
+
+#ib(4)#Strom falsch in Quittung#ie(4)#:
+ In der #ib#Quittung#ie# wurde eine nicht zulässige #ib#Stromnummer#ie# festge­
+ stellt. Zulässig sind Stromnummern zwischen 1 und 20.
+
+#ib(4)#Neustart#ie(4)#
+ Die Gegenstation hat die #ib#Verbindung#ie# von vorne begonnen.
+
+#ib(4)#Falsche Seitennummer#ie(4)#
+ Die #ib#Seitennummer#ie# in dem empfangenen Telegramm ist falsch.
+ Einige Telegramme werden wiederholt.
+
+#ib(4)#Absteigende Seitennummern#ie(4)#
+ Die Seitennummer in dem empfangenen Telegramm ist kleiner als
+ die Seitennummer im vorigen #ib#Telegramm#ie#. Es müssen einige Tele­
+ gramme wiederholt werden.
+
+
+Die folgenden Meldungen beschreiben Situationen, die nicht durch #ib#Zeichenverluste#ie#
+entstehen, mit denen die #ib#Netzsoftware#ie# selbst fertig wird:
+
+
+#ib(4)#Sendung von Gegenstelle gelöscht#ie(4)#
+ Die Verbindung wurde von der Gegenstelle abgebrochen.
+
+#ib(4)#Empfangseintrag freigegeben#ie(4)#
+ Die Verbindung wurde von der empfangenden #ib#Station#ie# gelöscht, weil
+ seit dem Eintreffen des letzten Telegramms zuviel Zeit vergangen ist
+ (#ib#Timeout#ie#).
+
+#ib(4)#Irrläufer#ie(4)#
+ Eine #ib#Intertaskkommunikation#ie# innerhalb der eigenen Station wurde
+ fälschlicherweise über den #on("b")##ib#Collector#ie##off("b")# abgewickelt. Dieser Vorgang
+ wird abgebrochen.
+#page#
+#ib(4)#Call-Löschung vorgemerkt#ie(4)#
+ Sobald der Call abgewickelt ist, wird diese Verbindung gelöscht.
+ Beispielsweise führt ein vom Benutzer abgebrochenes #on("b")##ib#name#ie##off("b")# zu
+ dieser Meldung.
+
+#ib(4)#Call gelöscht#ie(4)#
+ Die #ib#Verbindung#ie# wurde auf Anforderung durch den Auftraggeber
+ gelöscht.
+
+#ib(4)#Quellrechner#ie(4)#
+ Als #ib#Quellrechnernummer#ie# wurde ein unzulässiger Wert festgestellt.
+ Zulässig sind Zahlen zwischen 1 und 127.
+
+#ib(4)#Nicht zustellbar#ie(4)#
+ Innerhalb eines bestimmten Zeitraums war die #ib#Zieltask#ie# nicht emp­
+ fangsbereit. Die Verbindung wird abgebrochen.
+
+Bei diesen Meldungen sollten die #ib#Routenanweisungen#ie# überprüft werden:
+
+#ib(4)#Verbotene Route bei Quittung#ie(4)#
+ Die #ib#Quittung#ie# kommt auf einer nicht erlaubten #ib#Route#ie# an. Dies kann
+ bei #ib#Vermaschung#ie# passieren, oder aber, wenn eine Station versucht,
+ sich für eine andere Station auszugeben.
+
+#ib(4)#Verbotene Route#ie(4)#
+ Die danach bezeichnete Station versucht, auf einer anderen Route
+ mit diesem Rechner zu kommunizieren, als auf der Route, die für
+ diesen Rechner in der Datei #on("b")##ib#netz#ie##off("b")# festgelegt wurde.
+
+ Abhilfe:
+ #ib#Routentabellen#ie# der beiden (oder, falls die Meldung auf einer
+ #ib#Knotenstation#ie# erscheint, auf allen beteiligten) Stationen abgleichen.
+
+#ib(4)#Weiterleitung nicht möglich#ie(4)#
+ Die #ib#Routeninformationen#ie# auf dem #ib#Knotenrechner#ie#, wo diese Meldung
+ erscheint, und der sendenden #ib#Station#ie# stimmen nicht überein. Die
+ angegebene Station ist von dieser Station aus nicht erreichbar.
+
+ Abhilfe:
+ #ib#Routentabellen#ie# der Stationen überprüfen.
+
+#ib(4)#Fremdzugriff#ie(4)#
+ Eine #ib#gesperrt#ie#e Station hat versucht, auf diesen Rechner mit #ib#Sende­
+ codes#ie# > 6 zuzugreifen.
+
+
+Folgende Meldungen betreffen '#ib#harte Fehler#ie#'. Diese Fehler werden von der Netzsoft­
+ware nicht abgefangen. In jedem Fall muß das Netz nach einer solchen #ib#Fehler­
+meldung#ie# neu gestartet werden.
+
+#ib(4)#++++++#ie(4)#
+ Meldungen dieser Form sind 'harte' Fehler. Der aufgetretene Fehler
+ wird mit angegeben. Das Netz muß neu gestartet werden, da die
+ Task, in welcher der Fehler aufgetreten ist, gelöscht wird.
+
+#ib(4)#Verbindungsengpaß#ie(4)#
+ Es sind mehr Verbindungen festgestellt worden, als zulässig sind.
+ Nach dieser Meldung wurde der entsprechende Netport gelöscht.
+
+
+Literaturverzeichnis
+
+
+#goalpage("A.2")#
+
+#clear pos#
+#lpos(1.0)##lpos(2.5)#
+#table#
+[1] EUMEL-Systemhandbuch, Teil 5, Intertaskkommunikation
+ GMD St. Augustin, 1986
+[2] EUMEL-Systemhandbuch, Teil 2, Hardware und ihre Steuerung
+[3] EUMEL-Systemhandbuch, Teil 8, Spooler
+[4] EUMEL-Netz Installationsanweisung
+ GMD St. Augustin, 1987
+[5] EUMEL-Systemhandbuch, Teil 4, Blockorientierte Ein/Ausgabe
+[6] EUMEL-Quellcode, Packet #on("b")#tasks#off("b")#
+ GMD St. Augustin, 1986
+[7] EUMEL-Portierungshandbuch 8086, Version 8
+ GMD St. Augustin, 1987
+
+#table end#
+
+
diff --git a/system/net/1.8.7/doc/netzhandbuch.anhang b/system/net/1.8.7/doc/netzhandbuch.anhang
new file mode 100644
index 0000000..17d1ece
--- /dev/null
+++ b/system/net/1.8.7/doc/netzhandbuch.anhang
@@ -0,0 +1,58 @@
+#pagenr ("%", 51)##setcount##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Anhang
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#clear pos##lpos(0.0)##rpos(11.0)##fillchar(".")#
+Anhang: Netz-Fehlermeldungen
+
+#table#
+++++++ 50
+Absteigende Seitennummern 48
+blockin abbruch 48
+Blocknummer falsch 47
+buffers flushed 47
+Call gelöscht 49
+Call-Löschung vorgemerkt 49
+Collectortask fehlt 8, 18
+Daten ohne Eroeffnung 47
+Empfangseintrag freigegeben 48
+etwas rueckgespult 47
+Falsche Seitennummer 48
+Fremdzugriff 50
+Header inkorrekt eingelesen 48
+Irrläufer 48
+kein Zugriff auf Station 14
+Neustart 48
+Nicht zustellbar 49
+Quellrechner 49
+Sendung von Gegenstelle gelöscht 48
+Sequenzfehler 47
+Sequenzreset 47
+skipped 46
+Station x antwortet nicht 8, 11, 16
+Station x gibt es nicht 9, 11, 13
+Strom falsch in Quittung 48
+Task "..." gibt es nicht 8
+Verbindungsengpaß 50
+Verbotene Route 49
+Verbotene Route bei Quittung 49
+wdh data 47
+wdh open 47
+Weiterleitung nicht möglich 49
+#table end#
+
diff --git a/system/net/1.8.7/doc/netzhandbuch.index b/system/net/1.8.7/doc/netzhandbuch.index
new file mode 100644
index 0000000..01d8a0f
--- /dev/null
+++ b/system/net/1.8.7/doc/netzhandbuch.index
@@ -0,0 +1,259 @@
+#pagenr ("%", 52)##setcount (1)##block##pageblock##count per page#
+#headeven#
+#center#EUMEL Netzbeschreibung
+#center#____________________________________________________________
+
+#end#
+#headodd#
+#center#Anhang
+#center#____________________________________________________________
+
+#end#
+#bottomeven#
+#center#____________________________________________________________
+Netz - % #right#GMD
+#end#
+#bottomodd#
+#center#____________________________________________________________
+GMD #right#Netz - %
+#end#
+#clear pos##lpos(0.0)##rpos(11.0)##fillchar(".")#
+Anhang: Index
+
+#table#
+/ 8, 9, 24
+Absenderadresse 39
+Absenderstation 28, 32
+Adresse 29, 37, 39, 41, 42
+aktiviere netz 14, 15, 18
+basic net 41, 43
+Baud 6, 18, 25
+blockin 23, 36, 40, 42
+blockout 23, 36, 40
+Broad- oder Multicasts 38
+buffers flushed 47
+CASE 37
+CLOSE 27
+collected destination 22, 24
+Collector 22, 24, 32, 48
+Collectortask 8, 18, 22
+configurate 6
+continue 7, 21
+CRC-Code 26
+DATA 27, 29, 30
+data length 23, 36, 41, 45
+data length via node 23, 36, 41, 42, 45
+Datei 2, 5, 7, 12, 13, 14, 18, 20, 24, 31, 37, 41, 44, 46
+Datenbox 2, 6, 33
+Datenraum 13, 15, 21, 23, 24, 27, 28, 29, 31, 36, 40, 43
+Datenraumseite 23, 46, 47
+decode packet length 42, 43
+define collector 22, 24
+definere netz 15
+DEFINES 37
+define station 5, 22
+definiere netz 14
+Dreher 16
+Durchsatz 3
+Eingabeprozeduren 21
+Eingabepuffer 47
+Empfangspuffer 15
+Empfangsströme 13, 15
+endquelle 28
+endziel 28
+erase 13, 19
+erlaube 14
+Ethernet 33, 34, 36, 37, 42
+EUMEL0 21, 22, 24
+EUMEL-Datenboxen-Netz 33
+EUMEL-Netz-Software 35
+exists 11
+Fehler 8, 16, 17, 18
+Fehlerbehandlung 31, 36, 42
+Fehlerfälle 8
+Fehlerfall 11, 40
+Fehlermeldung 13, 15, 20, 26, 39, 45, 46, 50
+Fehlersituationen 12
+Fehlersuche 16
+Fenstertechnik 31
+fetch 10, 18
+flush buffers 36, 42
+Flußkontrolle 7, 15, 27, 39
+free global manager 10, 19, 31
+Füllzeichen 37, 39, 42, 43
+gesperrt 13, 14, 45, 50
+global manager 19, 31
+harte Fehler 50
+HDLC 31
+Header 43
+Höhere Ebenen 31
+inchar 21
+incharety 23
+Installation 2
+Installationsanleitung 2
+Intertaskkommunikation 48
+I/O Control 36
+I/O-Kanal 33
+Kanal 3, 6, 7, 12, 14, 15, 20, 21, 23, 24, 34, 37, 40, 41
+Kanalnummer 14
+Kanaltask 45
+Knoten 3, 4, 17, 20, 23, 36, 42
+Knotenkonzept 3, 34
+Knotenrechner 34, 36, 49
+Knotenstation 13, 14, 20, 49
+Kommunikation 17
+Kommunikationindirekte 23
+konfigurieren 6
+Länge 29, 41, 42
+Längenangabe 26
+list 10, 12, 17, 44
+listoption 12, 14, 15
+Löschversuche 13
+Manager 10, 19
+Masseschluß 16
+max mode 43
+mode text 41
+Nachbarn 4, 28
+Nachbarstation 24, 28
+name 11, 24, 49
+net 7, 12, 13
+net addess 41
+net hardware interface 34, 40
+net install 7
+net list 12, 15
+net manager 41
+net mode 41, 43
+net port 7, 8, 12, 13, 18, 45, 46
+net timer 14
+netz 7, 14, 15, 20, 37, 41, 49
+Netzbox 3, 6, 20, 33, 38
+Netzdefinition 14
+Netzebene 26
+Netzempfangstask 30
+Netzhardware 2, 17, 21, 24, 33, 34, 36, 41, 43
+Netz-Hardware-Interface 34
+Netzinstallation 17
+Netzkanal 13, 14, 42
+Netzknoten 3
+Netzkonfiguration 7, 20
+Netzmodus 34, 37, 39, 41, 43
+Netzprotokoll 42
+Netzsoftware 2, 3, 18, 20, 34, 36, 38, 42, 48
+Netzstrang 4, 17, 23
+Netztask 15, 16, 21, 24
+Netztelegramm 34
+Netztreiber 38
+Netzübertragungen 12
+Netzversion 2, 45
+next packet start 36, 42
+niltext 11, 36
+Nutzdaten 23
+Nutzdatenlänge 17, 23, 29, 36, 41, 42, 45
+Nutzinformation 29
+nutzlaenge 29
+OPEN 27, 28, 30, 47
+Paket 23, 34, 37, 38, 39, 42, 43
+Pakete, Aufbau der 34
+Partner 46
+Paßwort 19
+Pin-Belegung 6
+port intern 13, 15, 24
+Printerserver 20
+Protokoll 6, 13, 24, 39
+Protokollebenen 25
+Prüfsummen 18
+Quelle 23, 26, 28
+Quellrechnernummer 49
+Quellstationsnummer 20
+quelltask 21, 24, 28
+Querarchivierungen 10
+QUIT 27, 28, 30
+Quittung 30, 31, 47, 48, 49
+Rechnerkopplung 3
+Rendezvouskonzept 21, 31
+report 8, 12, 18, 39, 40, 41, 45, 46
+reserve 10
+RESET 17
+reset box 43
+Route 13, 15, 17, 20, 49
+routen 14
+Routenanweisungen 49
+routen aufbauen 13, 14, 15
+Routeninformationen 20, 49
+Routentabelle 9, 13
+Routentabellen 24, 49
+router 13
+RS422 25
+RTS/CTS 6, 25, 39
+Rückmeldeparameter 21
+run 13
+save 10, 19
+Schnittstelle 3, 15, 18, 20, 25, 33, 37, 38, 39
+SDLC 25, 26
+seite 28, 29, 40
+Seiten 27
+Seitengrenze 23
+Seitennummer 47, 48
+SELECT 34, 37, 43
+send 21, 22, 24, 27, 28, 30, 32
+Sendecode 24
+Sendecodes 50
+Sendeströme 13, 46
+Sendungskonzept 2
+sequenz 28, 29, 46
+Sequenzfehler 47
+Sequenznummer 46, 47
+Sequenzreset 47
+set net mode 41
+SHard 38, 43
+Sicherheitskonzept 19
+Sicherheitsprobleme 19
+skipped 46
+sperre 14
+Spoolmanager 5
+Sprungleiste 43
+Sprungleisten 34, 37
+start 5, 13, 16, 18, 41
+starte kanal 14, 15
+station 2, 5, 8, 10, 12, 13, 16, 19, 20, 22, 24, 26, 31, 32, 36, 41, 45, 48, 49
+Stationen, sicherheitsrelevante 20
+Stationsadresse 38
+Stationsnummer 5, 10, 16, 22, 24, 26, 32, 37, 41, 46
+Stationsnummer maximale 14
+Strang 3, 17, 20, 36, 41
+Stream I/O 23, 38
+strom 28, 30, 46
+Stromnummer 13, 28, 30, 45, 46, 47, 48
+STX 26, 36, 42
+Task-Id 5, 22, 24, 28, 30
+Telegramm 20, 23, 26, 27, 28, 31, 36, 37, 40, 42, 43, 46, 47, 48
+Telegrammanfang 42
+Telegrammformat 26
+Telegrammfreigabe 36
+Textdatei 31
+Timeout 31, 36, 48
+transmit header 36, 42, 43
+transmit trailer 36, 43
+Treiber 33
+Übertragung 26, 30, 46, 47
+Übertragungsfehler 42
+Übertragungsgeschwindigkeit 34, 38
+Übertragungsweg 23
+V24 3, 4, 15, 17, 18, 20, 25, 33, 34, 38
+Verbindung 3, 6, 16, 18, 27, 28, 34, 48, 49
+Vermaschung 4, 49
+Vermittlungsebene 24, 30
+Vorspann 36, 43
+wait 19, 21, 24, 27, 32
+Worker 5
+Zeichen 36, 38, 40, 42, 46
+Zeichenverluste 46, 47, 48
+Zeitüberwachung 26, 29
+ziel 28
+Zieladresse 38
+Zielstation 4, 8, 24, 28, 30, 36, 45
+Zieltask 21, 22, 24, 28, 32, 49
+Zustand 46
+Zwischenstation 45
+#table end#
+
diff --git a/system/net/1.8.7/source-disk b/system/net/1.8.7/source-disk
new file mode 100644
index 0000000..5a39f6c
--- /dev/null
+++ b/system/net/1.8.7/source-disk
@@ -0,0 +1 @@
+grundpaket/11_austausch.img
diff --git a/system/net/1.8.7/src/basic net b/system/net/1.8.7/src/basic net
new file mode 100644
index 0000000..c5e9278
--- /dev/null
+++ b/system/net/1.8.7/src/basic net
@@ -0,0 +1,1148 @@
+PACKET basic net DEFINES (* D. Heinrichs *)
+ (* Version 10 (!) *) (* 18.02.87 *)
+ nam, (* 03.06.87 *)
+ max verbindungsnummer, (* *)
+ neuer start,
+ neue routen,
+ packet eingang,
+ neue sendung,
+ zeitueberwachung,
+ verbindung,
+ loesche verbindung:
+
+TEXT PROC nam (TASK CONST t):
+ IF t = collector THEN name (t)
+ ELIF station (t) <> station (myself)
+ THEN "** fremd "+text(station(t))+" **"
+ ELSE name (t)
+ FI
+END PROC nam;
+
+INT PROC tasknr (TASK CONST t):
+ IF t = collector THEN maxtasks
+ ELSE index (t)
+ FI
+END PROC tasknr;
+
+LET
+ maxtasks = 127,
+ maxstat = 127,
+ max strom = 20,
+ max strom 1 = 21,
+ stx = ""2"",
+ code stx = 2,
+ error nak = 2,
+ seiten groesse = 512,
+ dr verwaltungslaenge = 8,
+ dr verwaltungslaenge2=10,
+ openlaenge = 24,
+ vorspannlaenge = 14,
+ ack laenge = 12,
+ min data length = 64,
+ (* Codes der Verbindungsebene *)
+
+ task id code = 6,
+ name code = 7,
+ task info code = 8,
+ routen liefern code = 9,
+
+ (* Typen von Kommunikationsströmen *)
+
+ send wait = 0,
+ zustellung = 1,
+ call pingpong = 2,
+ call im wait = 3,
+ call im abbruch = 4,
+ call in zustellung = 5,
+
+ (*quittungscodes*)
+
+ ok = 0,
+ von vorne = 1,
+ wiederhole = 2,
+ loesche = 3,
+ beende = 4;
+
+LET STEUER =
+ STRUCT (
+ INT head,
+ zwischenziel,
+ zielrechner,
+ quellrechner,
+ strom,
+ sequenz,
+ seitennummer,
+ TASK quelle,ziel,
+ INT sende code);
+
+BOUND STEUER VAR open block;
+
+BOUND STRUCT (STEUER steuer, INT typ, maxseq) VAR info block;
+
+BOUND STRUCT (
+ INT head,
+ zwischenziel,
+ zielrechner,
+ quellrechner,
+ strom,
+ sequenz,
+ seitennummer) VAR vorspann ;
+
+LET ACK = STRUCT (
+ INT head,
+ zwischenziel,
+ zielrechner,
+ quellrechner,
+ strom,
+ code);
+BOUND ACK VAR ack packet ;
+BOUND ACK VAR transmitted ack packet;
+
+BOUND STRUCT (ROW maxstat INT port,
+ ROW maxstat INT zwischen) VAR route;
+
+INT CONST max verbindungsnummer := max strom;
+INT VAR codet,net mode, nutzlaenge := data length,
+ data len via node := data length via node;
+
+TEXT VAR buffer first;
+
+DATASPACE VAR work space := nilspace;
+DATASPACE VAR transmitted ack space := nilspace;
+
+
+INT VAR pakete pro seite,
+ pakete pro seite minus 1,
+ packets per page via node,
+ packets per page via node minus 1,
+ datenpacketlaenge via node,
+ datenpacketlaenge ;
+
+INT VAR strom;
+INT VAR last data := -1;
+INT VAR own:=station (myself) ,
+ quit max := 3,
+ quit zaehler := 3,
+ own256 := 256*own;
+INT CONST stx open := code stx+256*openlaenge,
+ stx quit := code stx+256*acklaenge;
+
+ STEUER VAR opti;
+ ROW maxstrom1 STEUER VAR verbindungen;
+ ROW maxstrom1 DATASPACE VAR netz dr;
+ ROW maxstrom1 INT VAR zeit, typ, open try;
+ FOR strom FROM 1 UPTO maxstrom1 REP vdr := nilspace; forget (vdr) PER;
+ ROW maxstrom INT VAR dr page ;
+ ROW maxtasks INT VAR alter call;
+
+.vx : verbindungen (strom).
+
+vdr: netz dr (strom).
+
+ via node:
+ vx.zielrechner <= 0 OR vx.quellrechner <= 0 OR
+ transmit via node OR receive via node.
+
+ transmit via node:
+ route.zwischen (vx.zielrechner) <> vx.zielrechner AND vx.zielrechner <> own.
+
+ receive via node:
+ route.zwischen (vx.quellrechner) <> vx.quellrechner AND vx.quellrechner <> own.
+
+falsche stromnummer: strom < 1 OR strom > maxstrom.
+
+zielrechner ok: vorspann.zielrechner > 0 AND vorspann.zielrechner <= maxstat.
+
+quellrechner ok: vorspann.quellrechner > 0
+ AND vorspann.quellrechner <= maxstat.
+
+call aufruf: typ(strom) >= call pingpong.
+
+alles raus: vx.seitennummer = -1 AND letztes packet der seite .
+
+letztes packet der seite :
+(vx.sequenz AND packets per page minus 1) = packets per page minus 1.
+
+neue verbindung: code t = open laenge.
+
+PROC neue routen:
+ route := old ("port intern");
+END PROC neue routen;
+
+PROC neuer start (INT CONST empfangsstroeme, mode):
+ net mode := mode;
+ strom := 1;
+ neue routen;
+ transmitted ack space := nilspace;
+ workspace := nilspace;
+ open block := workspace;
+ info block := workspace;
+ nutzlaenge := data length;
+ data len via node := data length via node;
+ pakete pro seite:= seitengroesse DIV nutzlaenge;
+ pakete pro seite minus 1 := pakete pro seite -1;
+ packets per page via node := seitengroesse DIV data len via node;
+ packets per page via node minus 1 := packets per page via node - 1;
+ datenpacketlaenge := vorspannlaenge + nutzlaenge;
+ datenpacketlaenge via node := vorspannlaenge + data len via node;
+ vorspann := workspace;
+ ack packet := workspace;
+ transmitted ack packet := transmitted ack space;
+ FOR strom FROM 1 UPTO maxstrom1 REP
+ vx.strom := 0; forget (vdr)
+ PER;
+ INT VAR i;
+ FOR i FROM 1 UPTO maxtasks REP alter call (i) := 0 PER;
+ quitmax := empfangsstroeme;
+ own:=station (myself);
+ quit zaehler := quit max;
+ own256 := 256*own;
+ reset box (net mode);
+ buffer first := "";
+ flush buffers;
+ INT VAR err;
+ fehlermeldung ruecksetzen.
+
+ fehlermeldung ruecksetzen:
+ control (12,0,0,err).
+
+END PROC neuer start;
+
+DATASPACE PROC verbindung (INT CONST nr):
+ INT VAR memory := strom;
+ strom := nr;
+ infoblock.steuer := verbindungen (nr);
+ infoblock.typ := typ (nr);
+ infoblock.maxseq := dspages (netzdr(nr)) * packets per page;
+ strom := memory;
+ workspace
+END PROC verbindung;
+
+PROC neue sendung (TASK CONST q,z, INT CONST cod,z stat, DATASPACE CONST dr):
+
+ naechste verbindung vorbereiten;
+ forget (vdr); vdr := dr;
+ sendung starten (q, z, z stat, cod)
+END PROC neue sendung;
+
+PROC zeitueberwachung
+ (INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr):
+ snr INCR 1;
+ FOR strom FROM snr UPTO maxstrom REP zeitkontrolle PER;
+ snr := 0.
+
+zeitkontrolle:
+ IF vx.strom <> 0 AND zeit(strom) > 0
+ THEN
+ zeit(strom) DECR 1;
+ IF sendung noch nicht zugestellt
+ THEN
+ IF zeit(strom) = 0
+ THEN
+ empfangsreport ("Nicht zustellbar. ");
+ loesche verbindung (strom)
+ ELSE
+ snr := strom;
+ q := vx.quelle;
+ z := vx.ziel;
+ ant := vx.sendecode;
+ dr := vdr;
+ LEAVE zeitueberwachung
+ FI
+ ELIF zeit(strom) = 0
+ THEN wiederholen
+ FI
+ FI.
+
+sendung noch nicht zugestellt:
+ typ (strom) = zustellung.
+
+wiederholen:
+ IF sendeeintrag
+ THEN
+ sendung wiederholen
+ ELSE
+ empfangseintrag freigeben
+ FI.
+
+sendeeintrag : vx.quellrechner = own .
+
+sendung wiederholen:
+ IF wiederholung noch sinnvoll
+ THEN
+ IF frisch
+ THEN
+ time out bei open
+ ELSE
+ datenteil wiederholen
+ FI
+ ELSE
+ sendung loeschen
+ FI.
+
+wiederholung noch sinnvoll:
+ task noch da AND bei call noch im call.
+
+task noch da: vx.quelle = collector OR exists (vx.quelle).
+
+bei call noch im call:
+ IF call aufruf
+ THEN
+ callee (vx.quelle) = vx.ziel
+ ELSE
+ TRUE
+ FI.
+
+frisch: vx.sequenz = -1.
+
+time out bei open:
+ IF vx.sendecode > -4 OR opentry (strom) > 0
+ THEN
+ open wiederholen ;
+ opentry (strom) DECR 1
+ ELSE
+ nak an quelle senden
+ FI.
+
+nak an quelle senden:
+ dr := nilspace;
+ BOUND TEXT VAR erm := dr;
+ erm := "Station "+text(vx.zielrechner)+" antwortet nicht";
+ snr := strom;
+ q := vx.ziel;
+ z := vx.quelle;
+ ant := error nak;
+ sendung loeschen;
+ LEAVE zeitueberwachung .
+
+open wiederholen:
+ sendereport ("wdh open");
+ IF opentry (strom) > 0 THEN zeit(strom) := 4 ELSE zeit(strom) := 40 FI;
+ openblock := vx;
+ openblock.head := stx open;
+ ab die post.
+
+datenteil wiederholen:
+ sendereport ("wdh data. sqnr "+text (vx.sequenz));
+ senden .
+
+empfangseintrag freigeben:
+ IF antwort auf call
+ THEN
+ weiter warten
+ ELSE
+ empfangsreport ("Empfangseintrag freigegeben");
+ loesche verbindung (strom)
+ FI.
+antwort auf call: callee (vx.ziel) = vx.quelle.
+
+weiter warten: zeit (strom) := 400.
+
+END PROC zeitueberwachung;
+
+PROC sendereport (TEXT CONST txt):
+ report (text (strom)+":"+txt+". Absender: """+nam (vx.quelle)+
+ """. Ziel "+text(vx.zielrechner) + " Taskindex: " +
+ text (index (vx.ziel)));
+END PROC sendereport;
+
+PROC empfangsreport (TEXT CONST txt):
+ report (text (strom)+":"+txt+". Empfänger: """
+ +nam (vx.ziel)+""". Quelle "+text (vx.quellrechner) +
+ " Taskindex: " + text (index (vx.quelle)));
+END PROC empfangsreport ;
+
+PROC sendung loeschen:
+ strom loeschen (tasknr (vx.quelle))
+END PROC sendung loeschen;
+
+PROC strom loeschen (INT CONST tasknr):
+ IF callaufruf CAND alter call (tasknr ) = strom
+ THEN
+ alter call (tasknr ) := 0
+ FI;
+ vx.strom := 0;
+ forget (vdr)
+END PROC strom loeschen;
+
+PROC empfang loeschen:
+ quit zaehler INCR 1;
+ strom loeschen (tasknr (vx.ziel))
+END PROC empfang loeschen;
+
+PROC loesche verbindung (INT CONST nr):
+ strom := nr;
+ IF sendeeintrag
+ THEN
+ sendung loeschen
+ ELSE
+ gegenstelle zum loeschen auffordern;
+ empfang loeschen
+ FI.
+
+gegenstelle zum loeschen auffordern:
+ IF verbindung aktiv THEN quittieren (-loesche) FI.
+
+verbindung aktiv: vx.strom > 0.
+
+sendeeintrag: vx.quellrechner = own .
+
+END PROC loesche verbindung;
+
+PROC weiter senden:
+ IF NOT alles raus
+ THEN
+ sequenz zaehlung;
+ IF neue seite THEN seitennummer eintragen FI;
+ senden
+ FI.
+
+sequenz zaehlung:
+ vx.sequenz INCR 1.
+
+neue seite:
+ IF via node THEN (vx.sequenz AND packets per page via node minus 1) = 0
+ ELSE (vx.sequenz AND pakete pro seite minus 1) = 0
+ FI.
+
+seitennummer eintragen:
+ dr page (strom) := vx.seiten nummer;
+ vx.seitennummer := next ds page (vdr, dr page (strom)).
+
+
+END PROC weiter senden;
+
+.packets per page:
+
+ IF via node THEN packets per page via node
+ ELSE pakete pro seite
+ FI.
+
+packets per page minus 1:
+ IF via node THEN packets per page via node minus 1
+ ELSE pakete pro seite minus 1
+ FI.
+
+used length:
+
+ IF via node THEN data len via node
+ ELSE nutzlaenge
+ FI.
+
+PROC senden:
+ INT VAR nl;
+ zeit(strom) := 6;
+ openblock := vx;
+ nl := used length;
+ transmit header (workspace);
+ vorspann senden;
+ daten senden;
+ transmit trailer.
+
+vorspann senden:
+ blockout (workspace, 1, dr verwaltungslaenge, vorspannlaenge).
+
+daten senden:
+ blockout (vdr,dr page (strom),distanz,nl).
+
+distanz: nl* (vx.sequenz AND packets per page minus 1).
+
+END PROC senden;
+
+PROC naechste verbindung vorbereiten:
+ FOR strom FROM 1 UPTO maxstrom REP
+ UNTIL vx.strom = 0 PER;
+ IF vx.strom <> 0 THEN errorstop ("Verbindungsengpass") FI.
+END PROC naechste verbindung vorbereiten;
+
+PROC sendung starten (TASK CONST quelle, ziel, INT CONST code):
+ sendung starten (quelle,ziel, station(ziel), code)
+END PROC sendung starten;
+
+PROC sendung starten (TASK CONST quelle, ziel, INT CONST ziel station,code):
+ IF ziel station = own
+ THEN
+ report ("Irrläufer: Sendung an eigene Station. Absender:"""+
+ nam (quelle)+""".");
+ vx.strom := 0;
+ forget (vdr)
+ ELSE
+ openblock.ziel := ziel;
+ openblock.quelle :=quelle;
+ openblock.sendecode := code;
+ openblock.zielrechner:= ziel station;
+ openblock.quellrechner :=own;
+ openblock.zwischenziel := route.zwischen (ziel station)+own256;
+ alten call loeschen (quelle);
+ IF call oder ping pong
+ THEN typ (strom) := call pingpong; call merken
+ ELSE typ (strom) := send wait FI;
+ sendung neu starten
+ FI.
+
+call oder pingpong: openblock.ziel = callee (openblock.quelle).
+
+call merken: alter call (tasknr (quelle)) := strom.
+
+END PROC sendung starten;
+
+PROC encode packet length (INT VAR val):
+
+ IF val < 96 THEN
+ ELIF val < 160 THEN val DECR 32
+ ELIF val < 288 THEN val DECR 128
+ ELIF val < 544 THEN val DECR 352
+ ELIF val < 1056 THEN val DECR 832
+ ELIF val < 2080 THEN val DECR 1824
+ FI;
+ rotate (val, 8)
+
+ENDPROC encode packet length;
+
+PROC sendung neu starten:
+ INT VAR value;
+ openblock.head:= stx open;
+ openblock.sequenz := -1;
+ openblock.seitennummer:= next ds page (vdr,-1);
+ openblock.strom := strom;
+ vx := open block;
+ schnelles nak bei routen liefern;
+ ab die post;
+ value := vorspannlaenge + used length;
+ encode packet length (value);
+ vx.head:=code stx+value.
+
+schnelles nak bei routen liefern:
+ IF openblock.sendecode = -routen liefern code
+ THEN
+ openblock.zwischenziel := openblock.zielrechner+own256;
+ zeit(strom) := 2;
+ opentry (strom) := 0
+ ELSE
+ zeit (strom) :=8;
+ opentry (strom) := 2
+ FI.
+
+END PROC sendung neu starten; .
+
+ab die post:
+ transmit header (workspace);
+ block out (work space,1, dr verwaltungslaenge,open laenge);
+ transmit trailer.
+
+PROC alten call loeschen (TASK CONST quelle):
+ IF alter call aktiv
+ THEN
+ INT VAR lstrom := strom;
+ vx:=openblock;
+ strom := alter call (tasknr (quelle));
+ IF in ausfuehrungsphase
+ THEN
+ sendereport ("Call-Löschung vorgemerkt");
+ loeschung vormerken
+ ELSE
+ report ("Call gelöscht."""+nam(quelle)+""". Strom "+text(strom));
+ loesche verbindung (strom)
+ FI;
+ strom := lstrom;
+ openblock := vx
+ FI.
+
+in ausfuehrungsphase:
+ typ(strom) = call im wait OR typ (strom) = call in zustellung.
+
+loeschung vormerken:
+ typ(strom) := call im abbruch;
+ alter call (tasknr (quelle)) := 0.
+
+
+ alter call aktiv:
+ alter call (tasknr (quelle)) > 0.
+
+END PROC alten call loeschen;
+
+PROC packet eingang
+ ( INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr):
+ snr := 0;
+ fehlertest;
+ vorspann holen;
+ IF NOT ring logik THEN daten teil FI.
+
+ring logik: FALSE.
+
+fehlertest:
+#
+ INT VAR c12;
+ control (12,0,0,c12);
+ IF c12 <> 0
+ THEN
+ flush buffers;
+ report ("E/A-Fehler "+text (c12));
+ control (12,0,0,c12);
+ LEAVE packet eingang
+ FI.
+
+ #.
+
+vorspann holen:
+ sync;
+ IF NOT blockin (workspace, 1, dr verwaltungslaenge2, block laenge)
+ THEN LEAVE packeteingang
+ FI.
+
+
+blocklaenge: IF code t > min data length
+ THEN
+ vorspannlaenge-2
+ ELSE
+ code t -2
+ FI.
+
+sync:
+ IF NOT packet start already inspected
+ THEN
+ TEXT VAR skipped, t:= "";
+ skipped := next packet start;
+ IF skipped = "" THEN LEAVE packet eingang FI;
+ t := incharety (1);
+ code t := code (t);
+ ELSE
+ skipped := buffer first;
+ buffer first := "";
+ t := incharety (1);
+ code t := code (t);
+ FI;
+ decode packet length;
+IF skipped=stx AND laenge ok THEN LEAVE sync FI;
+ REP
+ skipped CAT t;
+ t := incharety (1); (* next character *)
+ IF t = "" THEN
+ report ("skipped",skipped);
+ LEAVE packet eingang
+ FI ;
+ codet := code (t);
+ UNTIL blockanfang OR length (skipped) > 200 PER;
+ decode packet length;
+ IF skipped <> stx THEN report ("skipped bei sync:", skipped) FI.
+
+decode packet length:
+
+IF code t < 96 THEN
+ ELIF code t < 128 THEN code t INCR 32
+ ELIF code t < 160 THEN code t INCR 128
+ ELIF code t < 192 THEN code t INCR 352
+ ELIF code t < 224 THEN code t INCR 832
+ ELIF code t < 256 THEN code t INCR 1824
+FI.
+
+packet start already inspected: buffer first <> "".
+
+blockanfang:
+ (skipped SUB length(skipped)) = stx AND laenge ok.
+
+laenge ok:
+ (codet = datenpacketlaenge OR codet = datenpacketlaenge via node
+ OR codet = ack laenge OR code t = openlaenge).
+
+zielnummer: vorspann.zielrechner.
+
+daten teil:
+ IF zielnummer = own
+ THEN
+ ziel erreicht (openblock,snr,q,z,ant,dr)
+ ELSE
+ weiter faedeln
+ FI.
+
+weiter faedeln:
+ INT VAR value;
+ IF zielrechner ok
+ THEN
+ IF neue verbindung
+ THEN
+ IF (openblock.sendecode = -routenlieferncode) OR NOT route ok
+ THEN LEAVE packet eingang
+ FI
+ FI;
+ value := code t;
+ encode packet length (value);
+ vorspann.head := code stx + value;
+ vorspann.zwischenziel := own256 + route.zwischen (vorspann.zielrechner);
+ nutzdaten einlesen;
+ dr := workspace;
+ snr := 1000;
+ ant := zielnummer
+ FI.
+
+nutzdaten einlesen:
+ IF code t > data len via node
+ THEN
+ IF NOT blockin (workspace, 1, drverwaltungslaenge+vorspannlaenge, data len via node)
+ THEN
+ LEAVE packeteingang
+ FI;
+ IF NOT next packet ok THEN LEAVE packeteingang FI
+ FI.
+
+END PROC packet eingang;
+
+PROC ziel erreicht (STEUER CONST prefix,
+ INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr):
+ last data := -1;
+ IF NOT quellrechner ok
+ THEN
+ report ("Quellrechner "+text(prefix.quellrechner));
+ LEAVE ziel erreicht
+ FI;
+ IF neue verbindung
+ THEN
+ IF NOT route ok OR NOT quelltask ok
+ THEN report ("verbotene Route: " + text (prefix.quellrechner));
+ LEAVE ziel erreicht
+ FI;
+ verbindung bereitstellen
+ ELIF quittung
+ THEN
+ strom := ack packet.strom;
+ IF falsche stromnummer THEN report ("Strom falsch in Quittung");
+ LEAVE ziel erreicht FI;
+ IF vx.strom = 0 THEN LEAVE ziel erreicht FI;
+ IF ackpacket.code >= ok THEN weiter senden
+ ELIF NOT route ok THEN
+ sendereport ("verbotene Route bei Quittung");
+ LEAVE ziel erreicht
+ ELIF ackpacket.code = -von vorne THEN
+ sendereport ("Neustart");
+ openblock := vx;
+ sendung neu starten
+ ELIF ackpacket.code = -wiederhole THEN back 16
+ ELIF ackpacket.code = -loesche THEN fremdloeschung
+ ELIF ackpacket.code = -beende AND alles raus THEN strom abschliessen
+ FI
+ ELIF verbindung festgestellt
+ THEN
+ zeit(strom) := 400;
+ opti := vx;
+ datenpacket
+ ELSE
+ strom := maxstrom1;
+ vx:=prefix;
+ report ("Daten ohne Eroeffnung von " +text(prefix.quellrechner)
+ +" Sequenznr "+text(prefix.sequenz));
+ daten entfernen (used length);
+ IF alles raus THEN quittieren (-beende) ELSE quittieren(-von vorne) FI
+ FI.
+
+quelltask ok:
+ prefix.quelle = collector OR antwort auf routen liefern
+ OR station (prefix.quelle) = prefix.quellrechner.
+
+antwort auf routen liefern: prefix.quelle = myself.
+
+verbindung bereitstellen:
+ IF (prefix.sendecode < 0 OR station (prefix.ziel) = own)
+ AND quellrechner ok
+ THEN
+ freie verbindungsnummer;
+ vdr := nilspace;
+ vx := open block;
+ zeit(strom) := 30;
+ quittieren falls genug pufferplatz;
+ vx.sequenz := 0 ;
+ opti := vx;
+ dr page (strom) :=-2;
+ IF abschluss THEN rueckmeldung FI
+ FI.
+
+loeschung vorgemerkt: typ(strom) = call im abbruch.
+
+strom abschliessen:
+ IF call aufruf
+ THEN
+ wdh data vor ablauf der zustellversuche bei der gegenstation;
+ ausfuehrungsphase merken
+ ELSE
+ wdh data sperren
+ FI.
+
+wdh data sperren:
+ zeit (strom) := 12000.
+
+wdh data vor ablauf der zustellversuche bei der gegenstation:
+ zeit (strom) := 80.
+
+ausfuehrungsphase merken: typ(strom) := call in zustellung.
+
+back16:
+ datenraum etwas rueckspulen;
+ opentry (strom) := 2;
+ nicht sofort senden (* wegen vagabundierender Quittungen *).
+
+nicht sofort senden: zeit(strom) := 2.
+
+datenraum etwas rueckspulen:
+ INT VAR pps := packets per page ;
+ sendereport ("etwas rueckgespult");
+ INT VAR vs :=-1;
+ dr page (strom) := -1;
+ INT VAR i;
+ FOR i FROM 1 UPTO vx.sequenz DIV pps - etwas REP
+ vs INCR pps;
+ dr page (strom) := next ds page (vdr, dr page (strom))
+ PER;
+ vx.seiten nummer := next ds page (vdr, dr page (strom)) ;
+ vx.sequenz := vs.
+
+etwas: 3.
+
+fremdloeschung:
+ IF fremdrechner ok und sendung
+ THEN
+ IF typ (strom) = call in zustellung
+ THEN
+ typ (strom) := call im wait
+ ELSE
+ IF NOT alles raus
+ THEN
+ sendereport ("Sendung von Gegenstelle geloescht")
+ FI;
+ sendung loeschen
+ FI
+ FI.
+
+fremdrechner ok und sendung:
+ ackpacket.quellrechner = vx.zielrechner .
+
+
+quittieren falls genug pufferplatz:
+ IF quit zaehler > 0 THEN
+ quit zaehler DECR 1;
+ open quittieren;
+ block vorab quittieren
+ ELSE
+ quittieren (-wiederhole)
+ FI.
+
+open quittieren: quittieren (ok).
+block vorab quittieren:
+ IF prio (myself) < 3 THEN quittieren (ok) FI.
+
+quittung: code t <= ack laenge.
+
+
+verbindung festgestellt:
+ FOR strom FROM maxstrom DOWNTO 1 REP
+ IF bekannter strom
+ THEN LEAVE verbindung festgestellt WITH TRUE FI
+ PER;
+ FALSE.
+
+bekannter strom:
+ vx.strom = prefix.strom AND vom selben rechner.
+
+vom selben rechner:
+ vx.quellrechner = prefix.quellrechner.
+
+daten:
+ IF neue seite da THEN check for valid pagenr;
+ dr page(strom) := prefix.seitennummer;
+ ELIF prefix.seitennummer < dr page(strom)
+ THEN empfangsreport ("Falsche Seitennummer, Soll: " +
+ text(drpage(strom)) + " ist: " +
+ text (prefix.seitennummer)
+ + " bei Sequenznr: " +
+ text(prefix.sequenz));
+ flush buffers;
+ quittieren (- wiederhole);
+ LEAVE ziel erreicht
+ FI;
+ sequenz zaehlung;
+ IF neue seite kommt
+ THEN
+ vx.seiten nummer := prefix.seiten nummer;
+ dr page(strom) := prefix.seitennummer;
+ FI;
+ quittieren(ok);
+ IF NOT blockin (vdr, opti.seiten nummer, distanz, nl)
+ COR NOT next packet ok
+ THEN quittieren (-wiederhole);
+ LEAVE ziel erreicht
+ FI;
+ last data := strom.
+
+check for valid pagenr:
+ IF prefix.seitennummer < dr page(strom) AND prefix.seitennummer > -1
+ THEN report ("Absteigende Seitennummern, alt: " + text(drpage(strom))+
+ " neu: "+ text(prefix.seitennummer) + " Seq.nr: " +
+ text(vx.sequenz) ) ;
+ flush buffers;
+ quittieren (- von vorne);
+ LEAVE ziel erreicht;
+ FI.
+
+datenpacket:
+ INT VAR nl := used length;
+ INT VAR pps1 := packets per page minus 1;
+ IF sendung wartet auf zustellung THEN auffrischen ELSE daten holen FI.
+
+sendung wartet auf zustellung: typ (strom) = zustellung.
+
+auffrischen: zeit (strom) := 200; daten entfernen (nl).
+
+daten holen:
+ IF opti.sequenz >= prefix.sequenz AND opti.sequenz < prefix.sequenz+100
+ AND prefix.sequenz >= 0
+ THEN
+ IF opti.sequenz <> prefix.sequenz
+ THEN empfangsreport ("Sequenzreset von "+text(opti.sequenz)+" auf "+
+ text (prefix.sequenz));
+ vx.sequenz := prefix.sequenz;
+ IF pagenumber ok
+ THEN dr page (strom) := prefix.seitennummer
+ ELSE empfangsreport ("Blocknummer falsch, neu: "+
+ text (prefix.seitennummer) + ", alt : " +
+ text (drpage(strom)) );
+ FI;
+ vorabquittung regenerieren
+ FI;
+ daten ;
+ IF abschluss THEN rueckmeldung FI;
+ ELSE
+ empfangsreport ("Sequenzfehler: soll "+text(vx.sequenz)+" ist "+
+ text(prefix.sequenz));
+ quittieren (-wiederhole);
+ daten entfernen (nl)
+ FI.
+
+pagenumber ok:
+ dr page (strom) >= prefix.seitennummer .
+
+rueckmeldung:
+ snr := strom;
+ q := vx.quelle;
+ z := vx.ziel;
+ ant := vx.sendecode;
+ dr := vdr;
+ LEAVE ziel erreicht.
+
+vorabquittung regenerieren:
+ IF prio (myself) < 3
+ THEN
+ quittieren (ok)
+ FI.
+
+distanz: (opti.sequenz AND pps1 ) * nl.
+
+sequenz zaehlung:
+ vx.sequenz INCR 1.
+
+neue seite da:
+ neue seite kommt.
+
+neue seite kommt:
+(vx.sequenz AND pps1) = 0.
+
+freie verbindungsnummer:
+ INT VAR h strom :=maxstrom1, cstrom := 0;
+ FOR strom FROM 1 UPTO maxstrom REP
+ IF vx.strom = 0 THEN h strom := strom ;
+ typ(strom) := send wait
+ ELIF bekannter strom
+ THEN empfangsreport ("Reopen");
+ quit zaehler INCR 1;
+ IF typ (strom) = zustellung THEN typ (strom) := send wait FI;
+ forget (vdr);
+ LEAVE freie verbindungsnummer
+ ELIF antwort auf call
+ THEN
+ IF loeschung vorgemerkt
+ THEN
+ vx := prefix;
+ loesche verbindung (strom);
+ LEAVE ziel erreicht
+ FI;
+ cstrom := strom;
+ typ (strom) := call pingpong;
+ forget (vdr);
+ FI
+ PER;
+ IF cstrom > 0 THEN strom := cstrom ELSE strom := h strom FI;
+ IF strom = maxstrom1 THEN
+ vx:=prefix;
+ empfangsreport ("Verbindungsengpass");
+ quittieren (-wiederhole);
+ LEAVE ziel erreicht
+ FI.
+
+antwort auf call:
+ prefix.sendecode >= 0 AND
+ call aufruf AND vx.quelle = prefix.ziel AND vx.ziel = prefix.quelle.
+
+END PROC ziel erreicht;
+
+PROC daten entfernen (INT CONST wieviel):
+ BOOL VAR dummy ;
+ dummy:=blockin (workspace, 2, 0, wieviel)
+END PROC daten entfernen;
+
+BOOL PROC route ok:
+ INT VAR zwischenquelle := vorspann.zwischenziel DIV 256,
+ endquelle := vorspann.quellrechner;
+ zwischenquelle abgleichen;
+ endquelle abgleichen;
+ TRUE.
+
+zwischenquelle abgleichen:
+ IF NOT zwischenroute gleich
+ THEN
+ IF NOT zwischenabgleich erlaubt THEN LEAVE route ok WITH FALSE FI;
+ route.port (zwischenquelle) := channel;
+ route.zwischen (zwischenquelle) := zwischenquelle;
+ abgleich (zwischenquelle, zwischenquelle)
+ FI.
+
+zwischenabgleich erlaubt: route.port (zwischenquelle) < 256.
+
+endquelle abgleichen:
+ IF NOT endroute gleich
+ THEN
+ IF NOT endabgleich erlaubt THEN LEAVE route ok WITH FALSE FI;
+ route.port (endquelle) := channel;
+ route.zwischen (endquelle) := zwischenquelle;
+ abgleich (endquelle, zwischenquelle)
+ FI.
+
+endabgleich erlaubt: route.port (endquelle) < 256.
+
+zwischenroute gleich:
+ (route.port (zwischenquelle) AND 255) = channel
+ AND
+ route.zwischen (zwischenquelle) = zwischenquelle.
+
+endroute gleich:
+ (route.port (endquelle) AND 255) = channel
+ AND
+ route.zwischen (endquelle) = zwischenquelle.
+
+END PROC route ok;
+
+BOOL PROC abschluss:
+
+ last data := -1;
+ IF neue seite kommt AND vx.seiten nummer = -1
+ THEN
+ quittieren (-beende);
+ an ziel weitergeben
+ ELSE
+ FALSE
+ FI.
+neue seite kommt:
+(vx.sequenz AND packets per page minus 1) = 0.
+
+an ziel weitergeben:
+ IF tasknummerfrage THEN taskfrage beantworten ;pufferplatz ; FALSE
+ ELIF tasknamenfrage THEN name senden ;pufferplatz ; FALSE
+ ELIF taskinfofrage THEN task info senden;pufferplatz ; FALSE
+ ELIF routenfrage THEN routen senden; pufferplatz; FALSE
+ ELSE senden ; TRUE
+ FI.
+
+pufferplatz : quitzaehler INCR 1 .
+
+senden:
+ IF callaufruf
+ THEN
+ ein versuch (* bei Antwort auf Call muß ein Zustellversuch reichen *)
+ ELSE
+ max 100 versuche;
+ typ (strom) := zustellung
+ FI.
+
+tasknummerfrage:opti.sendecode = -taskid code.
+
+tasknamenfrage: opti.sendecode = -name code.
+
+taskinfofrage: opti.sendecode = -task info code.
+
+routenfrage: opti.sendecode = -routen liefern code.
+
+max 100 versuche: zeit(strom) := 100.
+
+ein versuch: zeit (strom) := 1.
+
+taskfrage beantworten:
+ disable stop;
+ BOUND TEXT VAR tsk := vdr;
+ TEXT VAR save tsk := tsk;
+ forget (vdr); vdr := nilspace;
+ BOUND TASK VAR task id := vdr;
+ task id := task(save tsk);
+ IF is error THEN
+ clear error; enable stop;
+ forget (vdr); vdr := nilspace;
+ BOUND TEXT VAR errtxt := vdr;
+ errtxt := text(own)+"/"""+save tsk+""" gibt es nicht";
+ sendung starten (collector, opti.quelle, 2)
+ ELSE
+ enable stop;
+ sendung starten (collector, opti.quelle, 0)
+ FI.
+
+name senden:
+ quittieren (-loesche);
+ forget (vdr); vdr := nilspace;
+ tsk := vdr;
+ tsk := nam (opti.ziel);
+ sendung starten (collector, opti.quelle, 0).
+
+routen senden:
+ forget (vdr); vdr := old ("port intern");
+ sendung starten (opti.ziel, opti.quelle, 0).
+
+task info senden:
+ disable stop;
+ BOUND INT VAR ti code := vdr;
+ INT VAR ti cd := ti code;
+ forget (vdr); vdr := nilspace;
+ FILE VAR task inf := sequential file (output,vdr);
+ head line (task inf,"Station "+text(own));
+ task info (ti cd, task inf);
+ IF is error
+ THEN
+ forget (vdr); vdr := nilspace;
+ errtxt := vdr;
+ errtxt := errormessage;
+ clear error;
+ sendung starten (collector, opti.quelle, 2)
+ ELSE
+ sendung starten (collector,opti.quelle,0)
+ FI;
+ enable stop
+END PROC abschluss ;
+
+PROC quittieren(INT CONST code) :
+ INT VAR quell := vx.quellrechner ;
+ transmitted ackpacket := ACK:(stx quit, route.zwischen (quell)+own256, quell, own,
+ vx.strom, code);
+ transmit header (transmitted ack space);
+ blockout (transmitted ack space,1,dr verwaltungslaenge, ack laenge);
+ transmit trailer;
+END PROC quittieren;
+
+BOOL PROC next packet ok:
+ buffer first := next packet start;
+ buffer first = "" COR normal packet start.
+
+normal packet start:
+ IF buffer first = stx
+ THEN
+ TRUE
+ ELSE
+ buffer first := ""; flush buffers; FALSE
+ FI.
+
+END PROC next packet ok;
+END PACKET basic net;
+
+
diff --git a/system/net/1.8.7/src/net files-M b/system/net/1.8.7/src/net files-M
new file mode 100644
index 0000000..ae6f9f3
--- /dev/null
+++ b/system/net/1.8.7/src/net files-M
@@ -0,0 +1,5 @@
+net report
+net hardware interface
+basic net
+net manager
+
diff --git a/system/net/1.8.7/src/net hardware interface b/system/net/1.8.7/src/net hardware interface
new file mode 100644
index 0000000..4e3466a
--- /dev/null
+++ b/system/net/1.8.7/src/net hardware interface
@@ -0,0 +1,389 @@
+PACKET net hardware
+
+(************************************************************************)
+(**** Netzprotokoll Anpassung *)
+(**** Komplette Version mit BUS Anpassung 10.06.87 *)
+(**** mit I/0 Controls fuer integrierte Karten *)
+(**** Verschiedene Nutztelegrammgrössen *)
+(**** Version: GMD 2.0 A.Reichpietsch *)
+(************************************************************************)
+
+ DEFINES
+ blockin,
+ blockout,
+ set net mode,
+ net address,
+ mode text,
+ data length,
+ data length via node,
+ decode packet length,
+ next packet start,
+ flush buffers,
+ transmit header,
+ transmit trailer,
+ version,
+ reset box,
+ max mode,
+ net mode:
+
+
+
+
+ LET eak prefix laenge = 6,
+ packet length before stx = 14 (*eth header =14 *),
+ maximum mode nr = 12,
+ stx = ""2"",
+ niltext = "",
+ null = "0",
+ hex null = ""0"",
+ blank = " ",
+ eak prefix = ""0""0""0""0"",
+ typefield = "EU",
+ prefix adresse = "BOX",
+ second prefix adresse = ""0"BOX",
+ second address type bound = 90;
+
+ INT CONST data length via node :: 64;
+ TEXT CONST version :: "GMD 2.0 (10.6.87)";
+
+
+ TEXT VAR own address;
+ INT VAR paketlaenge, eumel paket laenge, mode, rahmenlaenge, actual data length;
+
+BOOL PROC blockin (DATASPACE VAR ds, INT CONST seite, abstand, laenge):
+ INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512;
+ REAL VAR time out := clock (1) + 10.0;
+ REP
+ blockin (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge);
+ UNTIL hilfslaenge = 0 OR clock (1) > time out PER ;
+ IF hilfslaenge <> 0
+ THEN report ("blockin abbruch, fehlende Zeichen: "+text(hilfslaenge));
+ FI;
+ hilfslaenge = 0
+END PROC blockin;
+
+PROC blockout (DATASPACE CONST ds, INT CONST seite, abstand, laenge):
+ INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512;
+ REP
+ blockout (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge);
+ UNTIL hilfslaenge = 0 PER
+END PROC blockout;
+
+PROC set net mode (INT CONST new mode):
+ mode := new mode ;
+ own address := net address (station(myself));
+ SELECT mode OF
+ CASE 1,3 : set data length (64);
+ CASE 2 : std framelength; set data length (64)
+ CASE 4,6 : set data length (128)
+ CASE 5 : std framelength; set data length (128)
+ CASE 7,9 : set data length (256)
+ CASE 8 : std framelength; set data length (256)
+ CASE 10,12 : set data length (512)
+ CASE 11 : std framelength; set data length (512);
+
+ OTHERWISE
+ END SELECT.
+
+ std framelength:
+ rahmenlaenge := eak prefix laenge + packet length before stx.
+
+ENDPROC set net mode;
+
+INT PROC max mode:
+ maximum mode nr
+ENDPROC max mode;
+
+INT PROC net mode:
+ mode
+ENDPROC net mode;
+
+TEXT PROC mode text:
+ mode text (mode)
+ENDPROC mode text;
+
+TEXT PROC mode text (INT CONST act mode):
+ SELECT act mode OF
+ CASE 1: "Modus: (1) EUMEL-Netz 64 Byte"
+ CASE 2: "Modus: (2) ETHERNET via V.24 64 Byte"
+ CASE 3: "Modus: (3) ETHERNET integrated 64 Byte"
+ CASE 4: "Modus: (4) EUMEL-Netz 128 Byte"
+ CASE 5: "Modus: (5) ETHERNET via V.24 128 Byte"
+ CASE 6: "Modus: (6) ETHERNET integrated 128 Byte"
+ CASE 7: "MODUS: (7) EUMEL-Netz 256 Byte"
+ CASE 8: "MODUS: (8) ETHERNET via V.24 256 Byte"
+ CASE 9: "MODUS: (9) ETHERNET integrated 256 Byte"
+ CASE 10: "MODUS: (10) EUMEL-Netz 512 Byte"
+ CASE 11: "MODUS: (11) ETHERNET via V.24 512 Byte"
+ CASE 12: "MODUS: (12) ETHERNET integrated 512 Byte"
+ OTHERWISE errorstop ("Modus " + text(mode) + " gibt es nicht");
+ error message
+ END SELECT
+
+ENDPROC mode text;
+
+PROC set data length (INT CONST new data length):
+ actual data length := new data length
+ENDPROC set data length;
+
+INT PROC data length:
+ actual data length
+ENDPROC data length;
+
+PROC reset box (INT CONST net mode):
+ SELECT net mode OF
+ CASE 1,4,7,10 : eumel net box reset
+ CASE 2,5,8,11 : eak reset
+ OTHERWISE controler reset
+ END SELECT.
+
+ eumel net box reset:
+ out (90*""4"");
+ REP UNTIL incharety (1) = niltext PER.
+
+ eak reset:
+ out ("E0"13"E0"13"").
+
+ controler reset:
+ INT VAR dummy;
+ control (-35, 0,0,dummy);
+ control (22,0,0,dummy).
+
+ENDPROC reset box;
+
+PROC remove frame
+ (TEXT VAR erstes zeichen vom eumel telegramm, BOOL VAR kein telegramm da):
+ kein telegramm da := FALSE;
+ SELECT net mode OF
+ CASE 2,5,8,11 : remove ethernet frame
+ (erstes zeichen vom eumel telegramm, kein telegramm da)
+ OTHERWISE
+ END SELECT;
+ENDPROC remove frame;
+
+PROC remove ethernet frame (TEXT VAR string, BOOL VAR schrott):
+ TEXT VAR speicher, t;
+ INT VAR lg;
+
+ t := string;
+ speicher := niltext;
+ WHILE kein stx da REP
+ lies zeichen ein;
+ teste auf timeout;
+ UNTIL textoverflow PER;
+ melde eingelesene zeichen.
+
+ lies zeichen ein:
+ speicher CAT t;
+ t := incharety (1).
+
+ teste auf timeout:
+ IF t = niltext THEN schrott := (speicher <> niltext)
+ CAND not only fill characters;
+ string := niltext;
+ LEAVE remove ethernet frame
+ FI.
+
+ not only fill characters:
+ pos (speicher, ""1"", ""254"",1) <> 0.
+
+ kein stx da :
+ t <> stx.
+
+ textoverflow:
+ length (speicher) > 1000.
+
+ melde eingelesene zeichen:
+ IF kein stx da
+ THEN kein eumeltelegrammanfang
+ ELSE untersuche ethernet header
+ FI.
+
+ kein eumeltelegrammanfang:
+ report ("skipped ,fehlendes <STX> ,letztes Zeichen:", t);
+ string := t;
+ schrott := TRUE.
+
+ untersuche ethernet header:
+ string := t;
+ IF ethernet header inkorrekt
+ THEN melde fehler
+ FI.
+
+ ethernet header inkorrekt:
+ lg := length (speicher);
+ packet zu kurz COR adresse falsch.
+
+ packet zu kurz:
+ lg < packet length before stx.
+
+ adresse falsch:
+ INT VAR adrpos := pos (speicher, own address);
+ zieladresse falsch COR adresse nicht an der richtigen pos .
+
+ zieladresse falsch:
+ adrpos < 1.
+
+ adresse nicht an der richtigen pos:
+ adrpos <> lg - packet length before stx + 1.
+
+ melde fehler:
+ report ("Header inkorrekt eingelesen: ", speicher + t);
+ string := t;
+ schrott := TRUE.
+
+ENDPROC remove ethernet frame;
+
+TEXT PROC next packet start:
+
+ TEXT VAR t := niltext;
+ BOOL VAR schrott := FALSE;
+
+ t:= incharety (1);
+ IF t = niltext THEN LEAVE next packet start WITH niltext
+ ELSE remove frame (t, schrott)
+ FI;
+ IF schrott THEN no stx or niltext
+ ELSE t
+ FI.
+
+ no stx or niltext:
+ IF t = stx THEN "2"
+ ELIF t = niltext THEN "0"
+ ELSE t
+ FI.
+
+ENDPROC next packet start;
+
+PROC flush buffers:
+ REP UNTIL incharety (5) = niltext PER;
+ report ("buffers flushed");
+ENDPROC flush buffers;
+
+PROC transmit header (DATASPACE CONST w):
+ BOUND INT VAR laengeninformation := w;
+ eumel paket laenge := laengeninformation ;
+ decode packet length (eumel paket laenge);
+ SELECT net mode OF
+ CASE 1,4,7,10 :
+ CASE 2,5,8,11 : eak und eth header senden (w)
+ OTHERWISE : telegrammanfang melden;
+ std ethernet header senden (w)
+ END SELECT;
+
+ENDPROC transmit header;
+
+PROC decode packet length (INT VAR decoded length):
+
+ decoded length DECR 2;
+ rotate (decoded length, 8);
+
+ IF decoded length < 96 THEN
+ ELIF decoded length < 128 THEN decoded length INCR 32
+ ELIF decoded length < 160 THEN decoded length INCR 128
+ ELIF decoded length < 192 THEN decoded length INCR 352
+ ELIF decoded length < 224 THEN decoded length INCR 832
+ ELIF decoded length < 256 THEN decoded length INCR 1824
+ FI;
+
+ENDPROC decode packet length;
+
+PROC transmit trailer:
+ INT VAR dummy;
+ SELECT net mode OF
+ CASE 3,6,9,12 : control (21,0,0,dummy)
+ OTHERWISE
+ END SELECT.
+
+ENDPROC transmit trailer;
+
+PROC std ethernet header senden (DATASPACE CONST x):
+ TEXT VAR eth adresse, ethernet kopf := niltext;
+ INT VAR adresse;
+ BOUND STRUCT (INT head, zwischennummern) VAR header := x;
+ zieladresse holen;
+ zieladresse senden;
+ quelladresse senden;
+ typfeld senden;
+ ausgeben.
+
+ zieladresse holen:
+ adresse := header.zwischennummern AND 255;
+ eth adresse := net address (adresse).
+
+ zieladresse senden:
+ ethernetkopf CAT eth adresse.
+
+ quelladresse senden:
+ ethernetkopf CAT own address.
+
+ typfeld senden:
+ ethernetkopf CAT typefield.
+
+ ausgeben:
+ out (ethernetkopf).
+
+ENDPROC std ethernet header senden;
+
+PROC telegrammanfang melden:
+ INT VAR dummy;
+ control (20,eumel paket laenge + packet length before stx,0, dummy).
+
+ENDPROC telegrammanfang melden;
+
+PROC eak und eth header senden (DATASPACE CONST x):
+ TEXT VAR res:= niltext;
+
+ neue laenge berechnen;
+ eak kopf senden;
+ std ethernet header senden (x).
+
+ neue laenge berechnen:
+ paket laenge := rahmenlaenge + eumel paket laenge.
+
+ eak kopf senden:
+ res := code (paket laenge DIV 256);
+ res CAT (code (paket laenge AND 255));
+ res CAT eak prefix;
+ out(res).
+
+ENDPROC eak und eth header senden;
+
+TEXT PROC net address (INT CONST eumel address):
+ TEXT VAR res ;
+ INT VAR low byte;
+
+SELECT mode OF
+ CASE 1,4,7,10 : eumel net address
+ OTHERWISE ethernet address
+END SELECT.
+
+eumel net address:
+ text(eumel address).
+
+ethernet address:
+ IF second adress kind THEN second eth header
+ ELSE first eth header
+ FI;
+ res.
+
+ second adress kind:
+ eumel address = 34 COR
+ eumel address > second address type bound.
+
+ second eth header:
+ low byte := eumel address AND 255;
+ res := second prefix adresse + code (low byte);
+ res CAT hex null.
+
+ first eth header:
+ res := prefix adresse + text (eumel address, 3);
+ changeall (res, blank, null).
+
+ENDPROC net address;
+
+ENDPACKET net hardware;
+
+
+
+
diff --git a/system/net/1.8.7/src/net inserter b/system/net/1.8.7/src/net inserter
new file mode 100644
index 0000000..c89d0f0
--- /dev/null
+++ b/system/net/1.8.7/src/net inserter
@@ -0,0 +1,145 @@
+(*************************************************************************)
+(*** Insertiert alle notwendigen Pakete, die zum Betrieb des Netzes ***)
+(*** notwendig sind. ***)
+(*** Berücksichtigt nur EUMEL - Versionen ab 1.8.1, sowie ***)
+(*** Multi-User-Version ***)
+(*** ***)
+(*** ***)
+(*** 23.05.87 ar ***)
+(*************************************************************************)
+
+LET netfile = "netz",
+ multi files = "net files/M";
+
+
+INT CONST version :: id (0);
+THESAURUS VAR tesa;
+
+head;
+IF no privileged task
+ THEN errorstop (name (myself) + " ist nicht privilegiert!")
+ ELIF station number wrong
+ THEN errorstop ("'define station' vergessen ")
+FI;
+
+IF version < 181 THEN versionsnummer zu klein
+ ELSE install net
+FI.
+
+no privileged task:
+ NOT (myself < supervisor).
+
+station number wrong:
+ station (myself) < 1.
+
+install net :
+ IF NOT exists (netfile)
+ THEN errorstop ("Datei " + netfile +" existiert nicht")
+ FI;
+ IF is multi THEN insert multi net
+ ELSE errorstop ("Diese Netzversion ist nur für Multi-user Versionen freigegeben")
+ FI;
+ forget ("net install", quiet);
+ net start.
+
+net start :
+ say line (" ");
+ do ("start");
+ do ("global manager (PROC (DATASPACE VAR, INT CONST, INT CONST, TASK CONST)
+ net manager)").
+
+is multi :
+ (pcb(9) AND 255) > 1.
+
+insert multi net :
+ hole dateien vom archiv;
+ insert say and forget (tesa).
+
+hole dateien vom archiv :
+ fetch if necessary (multi files);
+ tesa := ALL (multi files);
+ forget (multi files, quiet);
+ fetch if necessary (tesa - all);
+ say line (" ");
+ say line ("Archiv-Floppy kann entnommen werden.");
+ release (archive).
+
+
+head :
+ IF online THEN page;
+ put center (" E U M E L - Netz wird installiert.");
+ line;
+ put center ("----------------------------------------");
+ line (2)
+ FI.
+
+versionsnummer zu klein :
+ errorstop ("Netzsoftware erst ab Version 1.8.1 insertierbar !").
+
+PROC fetch if necessary (TEXT CONST datei) :
+ IF NOT exists (datei) THEN say line ("Loading """ + datei + """...");
+ fetch (datei, archive)
+ FI.
+END PROC fetch if necessary;
+
+PROC fetch if necessary (THESAURUS CONST tes) :
+ do (PROC (TEXT CONST) fetch if necessary, tes)
+END PROC fetch if necessary;
+
+PROC insert say and forget (TEXT CONST name of packet):
+ IF online THEN INT VAR cx, cy;
+ put ("Inserting """ + name of packet + """...");
+ get cursor (cx, cy)
+ FI;
+ insert (name of packet);
+ IF online THEN cl eop (cx, cy); line FI;
+ forget (name of packet, quiet)
+END PROC insert say and forget;
+
+PROC insert say and forget (THESAURUS CONST tes):
+ do (PROC (TEXT CONST) insert say and forget, tes)
+END PROC insert say and forget;
+
+PROC put center (TEXT CONST t):
+ put center (t, xsize);
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t):
+ put center (zeile, t, xsize);
+END PROC put center;
+
+PROC put center (TEXT CONST t, INT CONST gesamtbreite):
+ INT VAR cy;
+ get cursor (cy, cy);
+ put center (cy, t, gesamtbreite)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t, INT CONST gesamtbreite):
+ cursor ((gesamtbreite - length (t)) DIV 2, zeile);
+ put (t).
+END PROC put center;
+
+PROC cl eol:
+ out (""5"")
+END PROC cl eol;
+
+PROC cl eop:
+ out (""4"")
+END PROC cl eop;
+
+PROC cl eol (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eol
+END PROC cl eol;
+
+PROC cl eop (INT CONST cx, cy):
+ cursor (cx, cy);
+ cl eop
+END PROC cl eop;
+
+PROC say line (TEXT CONST t):
+ IF online THEN put line (t) FI
+ENDPROC say line;
+
+
+
diff --git a/system/net/1.8.7/src/net manager b/system/net/1.8.7/src/net manager
new file mode 100644
index 0000000..05f530e
--- /dev/null
+++ b/system/net/1.8.7/src/net manager
@@ -0,0 +1,797 @@
+PACKET net manager DEFINES stop,net manager,frei, routen aufbauen,
+ (* 175 net manager 8 (!) *)
+ start,
+ definiere netz,
+ aktiviere netz,
+ list option,
+ erlaube, sperre, starte kanal, routen:
+
+TEXT VAR stand := "Netzsoftware vom 10.06.87 ";
+ (*Heinrichs *)
+LET
+ maxstat = 127,
+ ack = 0,
+(* nak = 1, *)
+ error nak = 2,
+(* zeichen eingang = 4, *)
+ list code = 15,
+(* fetch code = 11, *)
+ freigabecode = 29,
+ tabellencode = 500,
+ continue code = 100,
+ erase code = 14,
+ report code = 99,
+ abgleichcode = 98,
+ neue routen code = 97,
+ dr verwaltungslaenge = 8,
+
+ (* Codes der Verbindungsebene *)
+
+ task id code = 6,
+ name code = 7,
+ task info code = 8,
+ routen liefern code = 9,
+
+ (* Weitergabecodes für Netzknoten *)
+
+ route code = 1001,
+ out code = 1003,
+
+ (* Typen von Kommunikationsströmen *)
+
+ zustellung = 1,
+ call im wait = 3,
+ call im abbruch = 4,
+ call in zustellung = 5;
+
+LET STEUER =
+ STRUCT (
+ INT head,
+ zwischenziel,
+ zielrechner,
+ quellrechner,
+ strom,
+ INT sequenz,
+ seiten nummer,
+ TASK quelle,ziel,
+ INT sende code);
+
+LET INFO = STRUCT (STEUER steuer, INT typ,maxseq);
+
+LET PARA = STRUCT (TASK quelle, ziel, INT sendecode, zielstation);
+
+
+TASK VAR sohn;
+INT VAR strom,c,kanalmode, rzaehler := 20;
+BOUND STRUCT (ROW maxstat INT port,
+ ROW maxstat INT zwischen) VAR route;
+
+
+TASK PROC netport (INT CONST ziel):
+ INT VAR kan := route.port (ziel) AND 255;
+ IF kan < 1 OR kan > 15
+ THEN
+ niltask
+ ELSE
+ IF NOT exists (nettask (kan))
+ THEN
+ access catalogue;
+ nettask (kan) := task (kan);
+ IF NOT (nettask (kan) < father) THEN nettask (kan) := niltask FI;
+ FI;
+ nettask (kan)
+ FI
+END PROC netport;
+
+PROC frei (INT CONST stat,lvl):
+ DATASPACE VAR ds := nilspace;
+ BOUND STRUCT (INT x,y) VAR msg := ds;
+ msg.x := stat; msg.y := lvl;
+ INT VAR return;
+ call (netport (stat), freigabecode, ds, return) ;
+ forget (ds)
+END PROC frei;
+
+PROC net manager (DATASPACE VAR ds, INT CONST order, phase, TASK CONST
+ ordertask):
+
+ IF order = report code AND ordertask < myself
+ THEN
+ IF storage (old("report")) > 20 THEN forget ("report", quiet) FI;
+ FILE VAR rp := sequential file (output, "report");
+ BOUND TEXT VAR rpt := ds;
+ putline (rp, rpt);
+ send (ordertask, ack, ds)
+ ELIF order = abgleichcode AND ordertask < myself
+ THEN
+ BOUND STRUCT (INT ende, zwischen) VAR x := ds;
+ route.port (x.ende) := channel (ordertask);
+ route.zwischen (x.ende) := x.zwischen;
+ send (ordertask, ack, ds)
+ ELIF order = neue routen code AND ordertask < myself
+ THEN
+ forget ("port intern");
+ copy (ds,"port intern");
+ route := old ("port intern");
+ send (ordertask, ack, ds)
+ ELIF station (ordertask) = station (myself)
+ THEN
+ IF ordertask < myself
+ OR order = list code
+ OR order > continue code
+ THEN
+ IF order = list code
+ THEN
+ enable stop;
+ forget (ds); ds := old ("report");
+ FILE VAR ff := sequential file (output,ds);
+ putline (ff,"bekannte Stationen:");
+ stationen; line (ff); putline (ff,"--------");
+ putline (ff,"Eingestellte Netzmodi:");
+ kanaele ;
+ paketgroessen;
+ line (ff); putline (ff,"********");
+ putline (ff,stand);
+ putline (ff,"Rechner "+text(station(myself))+" um "+time of day);
+ send (ordertask, ack, ds)
+ ELSE
+ free manager (ds,order,phase,order task)
+ FI
+ ELSE
+ errorstop ("nur 'list' ist erlaubt")
+ FI
+ FI .
+
+stationen:
+INT VAR stat;
+INT VAR mystation := station (myself);
+FOR stat FROM 1 UPTO maxstat REP
+ IF route.port (stat) > 0 AND stat <> mystation
+ THEN
+ put (ff,text(stat)+"("+text (route.port (stat) AND 255)+","+
+ text(route.zwischen(stat))+")")
+ FI
+PER.
+
+paketgroessen:
+
+ line(ff);
+ put (ff, "Nutzlaenge bei indirekter Verbindung "+
+ text (data length via node) + " Byte "); line (ff).
+
+kanaele:
+ INT VAR portnummer;
+ TASK VAR tsk;
+ FOR portnummer FROM 1 UPTO 15 REP
+ tsk := task (portnummer);
+ IF tsk < myself THEN beschreibe kanal FI;
+ PER.
+
+beschreibe kanal:
+ putline (ff, name (tsk) + " haengt an Kanal " + text (channel (tsk))
+ + ", " + mode text (netz mode (portnummer))).
+
+END PROC net manager;
+
+TASK VAR cd,stask;
+ROW maxstat INT VAR erlaubt;
+
+PROC communicate:
+ enable stop;
+ INT VAR scode, merken :=0;
+ DATASPACE VAR dr := nilspace;
+ neuer start (quit max, kanalmode);
+REP
+ forget (dr);
+ telegrammfreigabe;
+ wait (dr, scode, stask);
+ cd := collected destination;
+ IF weiterleitung steht noch aus
+ THEN
+ send (netport (merken), out code, mds, reply);
+ IF reply <> -2 THEN forget (mds); merken := 0 FI
+ FI;
+ IF zeichen da OR zeit abgelaufen
+ THEN
+ packet
+ ELIF cd = myself
+ THEN
+ netz info und steuerung
+ ELSE
+ sendung untersuchen (stask, cd, scode, dr)
+ FI
+PER.
+
+telegrammfreigabe:
+ INT VAR dummy;
+ control (22,0,0,dummy).
+
+zeichen da: scode < 0 .
+
+zeit abgelaufen: scode = ack AND cd = myself.
+
+packet:
+ INT VAR snr, ant,err;
+ TASK VAR quelle, ziel;
+ snr := 0;
+ IF NOT zeichen da THEN routen erneuern FI;
+ REP
+ IF NOT zeichen da
+ THEN
+ forget (dr);
+ zeitueberwachung (snr, quelle, ziel, ant, dr);
+ ELIF NOT weiterleitung steht noch aus
+ THEN
+ packet eingang (snr, quelle, ziel, ant, dr);
+ FI;
+ IF snr = 1000
+ THEN
+ packet weiterleiten
+ ELIF snr > 0
+ THEN
+ IF ant > 6 AND erlaubt(station (quelle)) < 0
+ THEN unerlaubt
+ ELSE
+ send (quelle,ziel,ant,dr,err);
+ fehlerbehandlung ;
+ FI
+ FI
+ UNTIL snr = 0 OR zeichen da PER.
+
+routen erneuern:
+ rzaehler DECR 1;
+ IF rzaehler = 0
+ THEN
+ rzaehler := 20;
+ neue routen holen
+ FI.
+
+weiterleitung steht noch aus: merken <> 0.
+
+packet weiterleiten:
+ INT VAR reply;
+ IF NOT ((route.port (ant) AND 255) = channel OR route.port (ant) < 0)
+ THEN
+ send (netport (ant), out code, dr, reply);
+ IF reply = -2
+ THEN
+ merken := ant;
+ DATASPACE VAR mds := dr
+ FI
+ ELSE
+ report ("Weiterleitung nicht möglich für "+text(ant))
+ FI.
+
+fehlerbehandlung:
+ IF ok oder ziel nicht da THEN loesche verbindung (snr) FI.
+
+ok oder ziel nicht da: err=0 OR err=-1.
+
+netz info und steuerung:
+ IF scode = list code THEN list status
+ ELIF scode = erase code THEN strom beenden
+ ELIF scode = freigabe code AND stask = father THEN freigabelevel
+ ELIF scode >= route code THEN weitergaben
+ ELIF scode > tabellencode THEN routen ausliefern
+ ELSE forget (dr); ablehnen ("nicht möglich")
+ FI.
+
+weitergaben:
+ IF stask < father
+ THEN
+ IF scode = out code
+ THEN
+ BOUND INT VAR stx lng := dr;
+ INT VAR decoded lng := stx lng;
+ decode packet length (decoded lng);
+ transmit header (dr);
+ blockout (dr,1,drverwaltungslaenge,decoded lng);
+ transmit trailer
+ ELIF scode = route code
+ THEN
+ BOUND PARA VAR parah := dr;
+ PARA VAR para := parah;
+ pingpong (stask, ack, dr, reply);
+ neue sendung (para.quelle, para.ziel, para.sendecode,
+ para.zielstation, dr);
+ forget (dr); dr := nilspace;
+ send (stask, ack, dr)
+ FI
+ ELSE
+ forget (dr);
+ ablehnen ("nicht Sohn von "+name(father))
+ FI.
+
+routen ausliefern:
+ neue sendung (stask, myself, -routen liefern code, scode-tabellencode,dr).
+
+freigabelevel:
+ BOUND STRUCT (INT stat,lvl) VAR lv := dr;
+ IF lv.stat > 0 AND lv.stat <= maxstat THEN erlaubt (lv.stat) := lv.lvl FI;
+ send (stask,ack,dr).
+
+unerlaubt:
+ report ("Fremdzugriff von "+text(station (quelle))+" auf "+nam(ziel)
+ +" code "+text(ant));
+ loesche verbindung (snr);
+ forget (dr); dr := nilspace;
+ BOUND TEXT VAR errtxt := dr;
+ errtxt:="Kein Zugriff auf Station "+text (station (myself));
+ neue sendung (ziel, quelle, error nak, station (quelle), dr).
+
+strom beenden:
+ BOUND TEXT VAR stromtext := dr;
+ INT VAR erase strom := int (stromtext);
+ forget (dr);
+ strom := erase strom;
+ IF falsche stromnummer THEN ablehnen ("Strom gibt es nicht")
+ ELSE
+ BOUND INFO VAR v := verbindung (strom);
+ IF
+ stask < supervisor OR stask = vx.quelle OR stask = vx.ziel
+ THEN
+ loeschen
+ ELSE ablehnen ("Nur Empfänger/Absender darf löschen")
+ FI
+ FI.
+
+loeschen:
+ IF sendeeintrag THEN
+ IF callee (vx.quelle) = vx.ziel THEN absender warnen FI;
+ loesche verbindung (strom)
+ ELSE
+ IF callee (vx.ziel) = vx.quelle THEN warnen FI;
+ loesche verbindung (strom)
+ FI;
+ dr := nilspace;
+ send (stask,ack,dr).
+
+absender warnen:
+ dr := nilspace;
+ send(vx.ziel,vx.quelle,1,dr,err) .
+
+warnen:
+ dr := nilspace;
+errtxt := dr; errtxt:= "Station antwortet nicht";
+send (vx.quelle,vx.ziel,error nak, dr, err).
+
+falsche stromnummer: strom < 1 OR strom > max verbindungsnummer.
+sendeeintrag: vx.quellrechner = station (myself).
+vx: v.steuer.
+END PROC communicate;
+
+PROC list option:
+ begin ("net list",PROC list net, sohn)
+END PROC list option;
+
+PROC list net:
+ disable stop;
+ DATASPACE VAR ds ;
+ INT VAR scode;
+ REP
+ wait (ds, scode, stask);
+ forget (ds); ds := nilspace;
+ FILE VAR f := sequential file (output, ds);
+ list (f, father);
+ list netports;
+ IF is error THEN clear error;
+ forget(ds);
+ ds := nilspace;
+ f := sequential file (output, ds);
+ output (f); putline (f,errormessage);
+ clear error
+ FI;
+ send (stask, ack, ds)
+ PER.
+
+list netports:
+ INT VAR k;
+ FOR k FROM 1 UPTO 15 REP
+ TASK VAR tsk := task (k);
+ IF tsk < father
+ THEN
+ putline (f, name (tsk));
+ list (f,tsk)
+ FI
+ PER.
+
+END PROC list net;
+
+PROC neue routen holen:
+ forget ("port intern", quiet);
+ fetch ("port intern");
+ route := old ("port intern");
+ neue routen
+END PROC neue routen holen;
+
+PROC sendung untersuchen (TASK CONST q, z, INT CONST cod, DATASPACE VAR dr):
+ IF z = collector
+ THEN
+ verbindungsebene
+ ELIF station (z) <> 0
+ THEN
+ sendung (q,z,cod,station (z),dr)
+ ELSE
+ ablehnen ("Station 0")
+ FI.
+
+verbindungsebene:
+ IF cod = 256 THEN name von fremdstation
+ ELIF cod > 256
+ THEN
+ taskinfo fremd
+ ELIF callee (q) = z (* gegen errornak an collector *)
+ THEN
+ task id von fremd
+ FI.
+
+taskinfo fremd: sendung (q, collector, -task info code,cod-256,dr).
+
+task id von fremd: sendung (q, collector, -task id code, zielstation, dr) .
+
+name von fremdstation:
+ BOUND TASK VAR tsk := dr;
+ TASK VAR tsk1 := tsk;
+ forget (dr);
+ dr := nilspace;
+ sendung (q, tsk1, -name code, station (tsk1), dr).
+
+zielstation: cod.
+END PROC sendung untersuchen;
+
+PROC sendung (TASK CONST q, z, INT CONST code, z stat, DATASPACE VAR dr):
+ IF z stat < 1 OR z stat > maxstat
+ THEN
+ ablehnen ("ungültige Stationsnummer");
+ LEAVE sendung
+ FI;
+ INT VAR reply;
+ INT VAR rp := route.port (z stat) AND 255;
+ IF rp = 255 THEN neue routen holen ;rp := route.port (z stat) AND 255 FI;
+ IF rp = channel
+ THEN
+ sendung selbst betreiben
+ ELIF rp > 0 AND rp < 16
+ THEN
+ sendung weitergeben
+ ELSE
+ ablehnen ("Station "+text(z stat)+" gibt es nicht")
+ FI.
+
+sendung selbst betreiben:
+ neue sendung (q, z, code, z stat, dr).
+
+sendung weitergeben:
+ DATASPACE VAR ds := nilspace;
+ BOUND PARA VAR p := ds;
+ p.quelle := q;
+ p.ziel := z;
+ p.zielstation := z stat;
+ p.sendecode := code;
+ call (netport (z stat), route code, ds, reply);
+ forget (ds);
+ pingpong (netport (z stat), 0, dr, reply);
+ forget (dr);
+ IF reply < 0 THEN ablehnen ("netport "+text(route.port(zstat)AND255)
+ + " fehlt") FI
+END PROC sendung;
+
+PROC ablehnen (TEXT CONST t):
+ DATASPACE VAR vdr := nilspace;
+ BOUND TEXT VAR errtxt := vdr;
+ INT VAR err;
+ errtxt := t;
+ send (cd,stask, error nak, vdr,err);
+ forget (vdr).
+END PROC ablehnen;
+
+PROC stop:
+ access catalogue;
+ IF exists task ("net timer")
+ THEN
+ TASK VAR nets := father (/"net timer");
+ ELSE
+ nets := myself
+ FI;
+ nets := son (nets);
+ WHILE NOT (nets = niltask) REP
+ IF text (name (nets),3) = "net" OR name (nets) = "router"
+ THEN
+ end (nets)
+ FI;
+ nets := brother (nets)
+ PER
+END PROC stop;
+
+PROC list status:
+
+ DATASPACE VAR ds := nilspace;
+ FILE VAR f:=sequential file (output, ds);
+ line(f);
+ FOR strom FROM 1 UPTO max verbindungsnummer REP
+ IF strom > 0 THEN
+ BOUND INFO VAR v := verbindung (strom);
+ IF vx.strom <> 0 THEN info FI
+ FI;
+ PER;
+ send (stask, ack, ds).
+
+info:
+ put (f,"Strom "+text(strom));
+ put (f,"(sqnr"+text(vx.sequenz)+"/"+text (v.maxseq)+")");
+ IF sendeeintrag THEN sendeinfo ELSE empfangsinfo FI;
+ line (f).
+
+sendeeintrag: vx.quellrechner = station(myself) .
+
+sendeinfo:
+ IF v.typ = call im wait THEN put (f,"erwartet Antwort von")
+ ELIF v.typ = call in zustellung THEN put (f,"Ziel busy. Zielstation:")
+ ELIF v.typ = call im abbruch THEN put (f,"wird gelöscht bei Antwort von")
+ ELSE put (f,"sendet an")
+ FI;
+ put (f,vx.zielrechner);
+ put (f,". Absender ist """+nam (vx.quelle)+""".").
+
+empfangsinfo:
+ IF v.typ = zustellung THEN
+ put (f,"Sendung noch nicht zustellbar")
+ ELSE
+ put (f,"empfängt von");
+ put (f,vx.quellrechner);
+ FI;
+ put (f,". Empfaenger ist """+nam (vx.ziel)+""".").
+
+vx: v.steuer.
+END PROC list status;
+
+INT VAR quitmax := 3;
+
+ROW 15 TASK VAR net task;
+ROW 15 INT VAR netz mode;
+
+PROC erlaube (INT CONST von, bis):
+ IF ein kanal gestartet
+ THEN
+ putline ("Warnung: 'erlaube' muß vor 'starte kanal'")
+ FI;
+ test (von); test (bis);
+ INT VAR i;
+ FOR i FROM von UPTO bis REP erlaubt (i) := 0 PER
+END PROC erlaube;
+
+PROC sperre (INT CONST von, bis):
+ IF ein kanal gestartet
+ THEN
+ putline ("Warnung: 'sperre' muß vor 'starte kanal'")
+ FI;
+ test (von); test (bis);
+ INT VAR i;
+ FOR i FROM von UPTO bis REP erlaubt (i) :=-1 PER
+END PROC sperre ;
+
+BOOL VAR alte routen, ein kanal gestartet;
+
+PROC definiere netz:
+ stop;
+ INT VAR i;
+ FOR i FROM 1 UPTO 15 REP net task (i) := niltask PER;
+ ein kanal gestartet := FALSE;
+ FILE VAR s := sequential file (output,"report");
+ putline (s," N e u e r S t a r t " + date + " " + time of day );
+ alte routen := exists ("port intern");
+ IF alte routen
+ THEN
+ route := old ("port intern")
+ ELSE
+ route := new ("port intern");
+ initialize routes
+ FI.
+
+ initialize routes:
+ FOR i FROM 1 UPTO maxstat REP
+ route.zwischen(i) := i
+ PER.
+
+END PROC definiere netz;
+
+PROC starte kanal (INT CONST k,modus,stroeme):
+ ein kanal gestartet := TRUE;
+ IF exists (canal (k)) THEN end (canal (k)) FI;
+ IF stroeme <= 0 THEN errorstop ("3.Parameter negativ") FI;
+ quitmax := stroeme;
+ c := k;
+ IF c < 1 OR c > 15 THEN errorstop ("unzulässiger Kanal:"+text(c)) FI;
+ kanalmode := modus;
+ IF kanalmode < 1 OR kanalmode > max mode
+ THEN errorstop ("unzulässiger Netzbetriebsmodus:"+text(kanalmode))
+ ELSE netz mode (c) := kanalmode
+ FI;
+ IF NOT exists task ("net port")
+ THEN
+ begin ("net port",PROC net io, net task (c));
+ define collector (/"net port")
+ ELSE
+ begin ("net port "+text (c),PROC net io, net task (c))
+ FI.
+END PROC starte kanal;
+
+PROC routen (INT CONST von, bis, kanal, zw):
+ INT VAR i;
+ IF kanal < 0 OR kanal > 15 THEN errorstop ("Kanal unzulässig") FI;
+ test (von); test (bis);
+ FOR i FROM von UPTO bis REP
+ route.port (i) := kanal+256;
+ IF zw=0
+ THEN
+ route.zwischen (i) := i
+ ELSE
+ test (zw);
+ route.zwischen (i) := zw
+ FI
+ PER.
+END PROC routen;
+
+PROC routen (INT CONST von, bis, kanal):
+ routen (von, bis, kanal, 0)
+END PROC routen;
+
+PROC test (INT CONST station):
+ IF station < 1 OR station > maxstat
+ THEN
+ errorstop (text (station) + " als Stationsnummer unzulässig")
+ FI
+END PROC test;
+
+PROC aktiviere netz:
+vorgegebene routen pruefen;
+IF existstask ("net timer") THEN end (/"net timer") FI;
+begin ("net timer",PROC timer,sohn);
+IF NOT alte routen
+THEN
+ routen aufbauen
+ELSE
+ IF online THEN break FI
+FI.
+
+vorgegebene routen pruefen:
+ INT VAR i;
+ FOR i FROM 1 UPTO maxstat REP
+ INT VAR s := route.port (i) AND 255;
+ IF s > 0 AND s <= 15 CAND nettask (s) = niltask
+ THEN
+ errorstop ("Kanal "+text(s)+" nicht gestartet, steht aber in Routen")
+ FI
+ PER.
+END PROC aktiviere netz;
+
+
+PROC routen aufbauen:
+ alte routen := TRUE;
+ c := channel;
+ break (quiet);
+ begin ("router", PROC rout0, sohn).
+END PROC routen aufbauen;
+
+PROC rout0:
+ disable stop;
+ rout;
+ IF is error
+ THEN
+ put error
+ FI;
+ end (myself)
+END PROC rout0;
+
+PROC rout:
+ IF c>0 THEN continue (c) FI;
+ clear error; enable stop;
+ fetch ("port intern");
+ route := old ("port intern");
+ routen aufbauen;
+ ds := old ("port intern");
+ call (father, neue routen code, ds, reply).
+
+routen aufbauen:
+ access catalogue;
+ TASK VAR port := brother (myself);
+ WHILE NOT (port = niltask) REP
+ IF text (name (port),8) = "net port" THEN nachbarn FI;
+ port := brother (port)
+ PER;
+ IF online THEN putline ("Fertig. Weiter mit SV !") FI.
+
+aenderbar: route.port (st) < 256.
+
+nachbarn:
+ INT VAR st,reply;
+ FOR st FROM 1 UPTO maxstat REP
+ IF erlaubt (st) >= 0 AND st <> station (myself) AND aenderbar
+ THEN
+ IF online THEN put (name (port)); put (st) FI;
+ DATASPACE VAR ds := nilspace;
+ call (port, tabellencode+st, ds, reply);
+ IF reply = ack
+ THEN
+ BOUND STRUCT (ROW maxstat INT port,
+ ROW maxstat INT zwischen) VAR fremd := ds;
+ route.port (st) := channel(port);
+ route.zwischen (st) := st;
+ indirekte ziele
+ ELIF reply < 0
+ THEN
+ errorstop ("netz läuft nicht (Kanalnummer falsch)")
+ ELSE
+ BOUND TEXT VAR xt := ds;
+ IF online THEN put (xt) FI;
+ FI;
+ IF online THEN line FI;
+ forget (ds)
+ FI
+ PER.
+
+indirekte ziele:
+ INT VAR kanal := fremd.port (station (myself)) AND 255;
+ INT VAR ind;
+ FOR ind FROM 1 UPTO maxstat REP
+ IF ind bei st bekannt AND NOT ((fremd.port (ind) AND 255) = kanal)
+ AND route.port (ind) < 256
+ THEN
+ route.port (ind) := channel (port);
+ route.zwischen (ind) := st
+ FI
+ PER.
+
+ind bei st bekannt: NOT (fremd.port (ind) = -1).
+
+END PROC rout;
+
+
+PROC timer:
+ disable stop;
+ access catalogue;
+ INT VAR old session := 1;
+ REP
+ IF session <> old session
+ THEN
+ define collector (/"net port");
+ old session := session
+ FI;
+ clear error;
+ pause (30);
+ sende tick an alle ports
+ PER.
+
+sende tick an alle ports :
+ TASK VAR fb := son (father);
+ REP
+ IF NOT exists (fb) THEN access catalogue;LEAVE sende tick an alle portsFI;
+ IF channel (fb) > 0
+ THEN
+ DATASPACE VAR ds := nilspace;
+ send (fb, ack, ds);
+ pause (10)
+ FI;
+ fb := brother (fb)
+ UNTIL fb = niltask PER.
+
+END PROC timer;
+
+PROC net io:
+ disable stop;
+ set net mode (kanalmode);
+ fetch ("port intern");
+ route := old ("port intern");
+ commanddialogue (FALSE);
+ continue (c);
+ communicate;
+ TEXT VAR emsg := "++++++ "+error message +" Zeile "+text(errorline);
+ clear error;
+ report (emsg);
+ end (myself)
+END PROC net io;
+
+PROC start: run ("netz") END PROC start;
+
+END PACKET net manager;
+
diff --git a/system/net/1.8.7/src/net report b/system/net/1.8.7/src/net report
new file mode 100644
index 0000000..ddc19d2
--- /dev/null
+++ b/system/net/1.8.7/src/net report
@@ -0,0 +1,41 @@
+PACKET net report DEFINES report, abgleich:
+(* Version 3 (!) *)
+
+LET reportcode = 99, abgleichcode = 98;
+
+PROC abgleich (INT CONST ende, zwischen):
+ DATASPACE VAR ds := nilspace;
+ BOUND STRUCT (INT ende, zwischen) VAR x := ds;
+ x.ende := ende;
+ x.zwischen := zwischen;
+ call (father, abgleichcode, ds, rep);
+ INT VAR rep;
+ forget (ds)
+END PROC abgleich;
+
+PROC report (TEXT CONST x):
+ report(x,"")
+END PROC report;
+
+PROC report (TEXT CONST txt, info):
+ DATASPACE VAR net report := nilspace;
+ BOUND TEXT VAR rinfo := net report;
+ rinfo := date;
+ rinfo CAT " "+time of day +" ";
+ rinfo CAT name(myself)+":";
+ rinfo CAT txt;
+ INT VAR i;
+ FOR i FROM 1 UPTO length (info) REP
+ INT VAR z := code (infoSUBi) ;
+ IF z < 32 OR z > 126
+ THEN rinfo CAT "%"+text(z)+" "
+ ELSE rinfo CAT (infoSUBi)+" "
+ FI
+ PER;
+ call (father, report code , net report, reply);
+ INT VAR reply;
+ forget (net report);
+END PROC report;
+
+END PACKET net report;
+
diff --git a/system/net/1.8.7/src/netz b/system/net/1.8.7/src/netz
new file mode 100644
index 0000000..c237ba2
--- /dev/null
+++ b/system/net/1.8.7/src/netz
@@ -0,0 +1,20 @@
+IF exists ("port intern") THEN forget ("port intern") FI;
+definiere netz;
+list option;
+erlaube(1,127);
+sperre (1,9);
+sperre (15,32);
+sperre (37,37);
+sperre (42,42);
+sperre (46,47);
+sperre (49,127);
+routen (1, 32,8);
+routen (33,43, 9);
+routen (34,34,8);
+routen (35,48,9);
+starte kanal (9,11,10);
+starte kanal (8,1,10);
+aktiviere netz;
+
+
+
diff --git a/system/net/1.8.7/src/port server b/system/net/1.8.7/src/port server
new file mode 100644
index 0000000..46c647f
--- /dev/null
+++ b/system/net/1.8.7/src/port server
@@ -0,0 +1,164 @@
+PACKET port server: (* Autor : R. Ruland *)
+ (* Stand : 21.03.86 *)
+
+INT VAR port station;
+TEXT VAR port := "PRINTER";
+
+put ("gib Name des Zielspools : "); editget (port); line;
+put ("gib Stationsnummer des Zielspools : "); get (port station);
+
+server channel (15);
+spool duty ("Verwalter fuer Task """ + port +
+ """ auf Station " + text (port station));
+
+LET max counter = 10 ,
+ time slice = 300 ,
+
+ ack = 0 ,
+ fetch code = 11 ,
+ param fetch code = 21 ,
+ file save code = 22 ,
+ file type = 1003 ,
+
+ begin char = ""0"",
+ end char = ""1"";
+
+
+INT VAR reply, old heap size;
+TEXT VAR file name, write pass, read pass, sendername, buffer;
+FILE VAR file;
+
+DATASPACE VAR ds, file ds, send ds;
+
+BOUND STRUCT (TEXT file name, write pass, read pass, sendername, INT station) VAR msg;
+BOUND TEXT VAR error msg ;
+
+spool manager (PROC save file);
+
+PROC save file :
+
+ disable stop ;
+ command dialogue (FALSE);
+ ds := nilspace; file ds := nilspace; send ds := nil space;
+ old heap size := heap size;
+
+ REP
+ execute save file;
+
+ IF is error THEN save error (error message) FI;
+
+ IF heap size > old heap size + 4
+ THEN collect heap garbage ;
+ old heap size := heap size
+ FI;
+
+ PER
+
+ENDPROC save file;
+
+
+PROC execute save file :
+
+enable stop;
+forget (file ds) ; file ds := nilspace;
+call (father, fetch code, file ds, reply);
+IF reply <> ack
+ THEN error msg := ds; errorstop (error msg);
+ ELSE save file ds
+FI;
+
+. save file ds :
+ IF type (file ds) = file type
+ THEN get file params;
+ insert file params;
+ call station (port station, port, file save code, file ds);
+ ELSE errorstop ("Datenraum hat falschen Typ")
+ FI;
+
+. get file params :
+ forget (ds); ds := nilspace;
+ call (father, param fetch code, ds, reply);
+ IF reply <> ack
+ THEN error msg := ds; errorstop (error msg);
+ ELSE msg := ds;
+ file name := msg. file name;
+ write pass := msg. write pass;
+ read pass := msg. read pass;
+ sendername := msg. sender name;
+ FI;
+
+. insert file params :
+ buffer := "";
+ in headline (filename);
+ in headline (write pass);
+ in headline (read pass);
+ in headline (sendername);
+ file := sequential file (input, file ds) ;
+ headline (file, buffer);
+
+END PROC execute save file;
+
+
+PROC call station (INT CONST order task station, TEXT CONST order task name,
+ INT CONST order code, DATASPACE VAR order ds) :
+
+ INT VAR counter := 0;
+ TASK VAR order task;
+ disable stop;
+ REP order task := order task station // order task name;
+ IF is error CAND pos (error message, "antwortet nicht") > 0
+ THEN clear error;
+ counter := min (max counter, counter + 1);
+ pause (counter * time slice);
+ ELSE enable stop;
+ forget (send ds); send ds := order ds;
+ call (order task, order code, send ds, reply);
+ disable stop;
+ IF reply = ack
+ THEN forget (order ds); order ds := send ds;
+ forget (send ds);
+ LEAVE call station
+ ELSE error msg := send ds;
+ errorstop (error msg);
+ FI;
+ FI;
+ PER;
+
+END PROC call station;
+
+
+TASK OP // (INT CONST station, TEXT CONST name) :
+
+ enable stop;
+ station / name
+
+END OP //;
+
+
+PROC in headline (TEXT CONST information) :
+ IF pos (information, begin char) <> 0
+ OR pos (information, end char) <> 0
+ THEN errorstop ("Name darf nicht Code 0 oder Code 1 enthalten") FI;
+ buffer CAT begin char;
+ buffer CAT information;
+ buffer CAT end char;
+END PROC in headline;
+
+
+PROC save error (TEXT CONST message) :
+ clear error;
+ file name CAT ".";
+ file name CAT sender name;
+ file name CAT ".ERROR";
+ file := sequential file (output, file name);
+ putline (file, " ");
+ putline (file, "Uebertragung nicht korrekt beendet ");
+ putline (file, " ");
+ put (file, "ERROR :"); put (file, message);
+ save (file name, public);
+ clear error;
+ forget(file name, quiet);
+END PROC save error;
+
+ENDPACKET port server;
+
diff --git a/system/net/1.8.7/src/printer server b/system/net/1.8.7/src/printer server
new file mode 100644
index 0000000..b1a30bc
--- /dev/null
+++ b/system/net/1.8.7/src/printer server
@@ -0,0 +1,99 @@
+PACKET multi user printer : (* Autor : Rudolf Ruland *)
+ (* Stand : 24.03.86 *)
+
+INT VAR c;
+put ("gib Druckerkanal : "); get (c);
+
+ server channel (c);
+ station only (FALSE) ;
+ spool duty ("Ausgabe mit dem Drucker");
+ spool control task (myself);
+
+LET ack = 0 ,
+
+ fetch code = 11 ,
+ param fetch code = 21 ,
+ file type = 1003 ;
+
+INT VAR reply, old heap size, sender station;
+TEXT VAR file name, userid, password, sendername;
+FILE VAR file ;
+
+DATASPACE VAR ds, file ds;
+
+BOUND STRUCT (TEXT file name, userid, password, sendername, INT station) VAR msg;
+BOUND TEXT VAR error msg ;
+
+spool manager (PROC printer);
+
+PROC printer :
+
+ disable stop ;
+ command dialogue (FALSE);
+ ds := nilspace; file ds := nilspace;
+ continue (server channel) ;
+ check error ("Kanal belegt");
+
+ old heap size := heap size ;
+ REP
+ execute print ;
+
+ IF is error
+ THEN put error;
+ clear error;
+ FI ;
+
+ IF heap size > old heap size + 4
+ THEN collect heap garbage ;
+ old heap size := heap size
+ FI
+ PER
+
+ENDPROC printer ;
+
+
+PROC execute print :
+
+ enable stop ;
+ forget (file ds) ; file ds := nilspace ;
+ call (father, fetch code, file ds, reply) ;
+ IF reply = ack CAND type (file ds) = file type
+ THEN get file params;
+ print file
+ FI ;
+
+. get file params :
+ forget (ds); ds := nilspace;
+ call (father, param fetch code, ds, reply);
+ IF reply <> ack
+ THEN error msg := ds; errorstop (error msg);
+ ELSE msg := ds;
+ file name := msg. file name;
+ userid := msg. userid;
+ password := msg. password;
+ sendername := msg. sender name;
+ sender station := msg. station;
+ FI;
+
+. print file :
+ file := sequential file (input, file ds);
+ print (file,
+ PROC (INT CONST, INT VAR, INT VAR) open,
+ PROC (INT CONST, INT CONST) close,
+ PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+
+ENDPROC execute print ;
+
+
+PROC check error (TEXT CONST message) :
+ IF is error
+ THEN clear error;
+ rename myself (message);
+ IF is error THEN clear error; end (myself) FI;
+ pause (18000);
+ end (myself);
+ FI;
+END PROC check error;
+
+ENDPACKET multi user printer ;
+
diff --git a/system/net/1.8.7/src/spool cmd b/system/net/1.8.7/src/spool cmd
new file mode 100644
index 0000000..b44e799
--- /dev/null
+++ b/system/net/1.8.7/src/spool cmd
@@ -0,0 +1,112 @@
+PACKET spool cmd (* Autor: R. Ruland *)
+ (* Stand: 01.04.86 *)
+ DEFINES killer,
+ first,
+ start,
+ stop,
+ halt,
+ wait for halt :
+
+LET error nak = 2 ,
+
+ entry line code = 23 ,
+ killer code = 24 ,
+ first code = 25 ,
+ start code = 26 ,
+ stop code = 27 ,
+ halt code = 28 ,
+ wait for halt code = 29 ;
+
+DATASPACE VAR ds;
+
+BOUND STRUCT (TEXT entry line, INT index) VAR control msg;
+BOUND TEXT VAR error msg ;
+
+INT VAR reply;
+
+INITFLAG VAR in this task := FALSE;
+
+
+PROC control spool (TASK CONST spool, INT CONST control code,
+ TEXT CONST question, BOOL CONST leave) :
+
+ enable stop;
+ initialize control msg;
+ WHILE valid spool entry
+ REP IF control question THEN control spool entry FI PER;
+
+ . initialize control msg :
+ IF NOT initialized (in this task) THEN ds := nilspace FI;
+ forget (ds); ds := nilspace; control msg := ds;
+ control msg. entry line := "";
+ control msg. index := 0;
+ say (""13""10"");
+
+ . valid spool entry :
+ call (spool, entry line code, ds, reply);
+ IF reply = error nak
+ THEN error msg := ds;
+ errorstop (error msg);
+ FI;
+ control msg. index <> 0
+
+ . control question :
+ say (control msg. entry line);
+ yes (question)
+
+ . control spool entry :
+ call (spool, control code, ds, reply);
+ IF reply = error nak
+ THEN error msg := ds;
+ errorstop (error msg);
+ FI;
+ IF leave THEN LEAVE control spool FI;
+
+END PROC control spool;
+
+
+PROC killer (TASK CONST spool) :
+
+ control spool (spool, killer code, " loeschen", FALSE)
+
+END PROC killer;
+
+
+PROC first (TASK CONST spool) :
+
+ control spool (spool, first code, " als erstes", TRUE)
+
+END PROC first;
+
+
+PROC start (TASK CONST spool) :
+
+ call (stop code, "", spool);
+ call (start code, "", spool);
+
+END PROC start;
+
+
+PROC stop (TASK CONST spool) :
+
+ call (stop code, "", spool);
+
+END PROC stop;
+
+
+PROC halt (TASK CONST spool) :
+
+ call (halt code, "", spool);
+
+END PROC halt;
+
+
+PROC wait for halt (TASK CONST spool) :
+
+ call (wait for halt code, "", spool);
+
+END PROC wait for halt;
+
+
+END PACKET spool cmd;
+
diff --git a/system/net/1.8.7/src/spool manager b/system/net/1.8.7/src/spool manager
new file mode 100644
index 0000000..e711ab4
--- /dev/null
+++ b/system/net/1.8.7/src/spool manager
@@ -0,0 +1,915 @@
+PACKET spool manager DEFINES (* Autor: J. Liedtke *)
+ (* R. Nolting *)
+ (* R. Ruland *)
+ (* Stand: 22.07.86 *)
+
+ spool manager ,
+
+ server channel ,
+ spool duty,
+ station only,
+ spool control task :
+
+LET que size = 101 ,
+
+ ack = 0 ,
+ nak = 1 ,
+ error nak = 2 ,
+ message ack = 3 ,
+ question ack = 4 ,
+ second phase ack = 5 ,
+ false code = 6 ,
+
+ fetch code = 11 ,
+ save code = 12 ,
+ exists code = 13 ,
+ erase code = 14 ,
+ list code = 15 ,
+ all code = 17 ,
+ param fetch code = 21 ,
+ file save code = 22 ,
+ entry line code = 23 ,
+ killer code = 24 ,
+ first code = 25 ,
+ start code = 26 ,
+ stop code = 27 ,
+ halt code = 28 ,
+ wait for halt code = 29 ,
+
+ continue code = 100 ,
+
+ file type = 1003 ;
+
+LET begin char = ""0"",
+ end char = ""1"";
+
+LET PARAMS = STRUCT (TEXT name, userid, password, sendername, INT station),
+ ENTRY = STRUCT (PARAMS ds params, TEXT entry line, DATASPACE space);
+
+ROW que size ENTRY VAR que ;
+
+PARAMS CONST empty params := PARAMS : ("", "", "", "", -1);
+
+PARAMS VAR save params, file save params;
+
+ENTRY VAR fetch entry;
+
+FILE VAR file;
+
+INT VAR order, last order, phase, reply, old heap size, first, last, list index,
+ begin pos, end pos, order task station, sp channel, counter;
+
+TEXT VAR order task name, buffer, sp duty, start time;
+
+BOOL VAR server is waiting, stop command pending, stat only, valid fetch entry;
+
+TASK VAR order task, last order task, server, calling parent, task in control;
+
+INITFLAG VAR in this task := FALSE;
+
+DATASPACE VAR ds;
+
+BOUND STRUCT (TEXT name, userid, password) VAR msg;
+BOUND STRUCT (TEXT entry line, INT index) VAR control msg;
+BOUND PARAMS VAR fetch msg;
+BOUND THESAURUS VAR all msg;
+BOUND TEXT VAR error msg ;
+
+
+. first entry : que (first)
+. list entry : que (list index)
+. last entry : que (last)
+
+. que is empty : first = last
+. que is full : first = next (last)
+.;
+
+sp channel := 0;
+sp duty := "";
+stat only := FALSE;
+task in control := myself;
+
+PROC server channel (INT CONST channel nr) :
+ IF channel nr <= 0 OR channel nr >= 33
+ THEN errorstop ("falsche Kanalangabe") FI;
+ sp channel := channel nr;
+END PROC server channel;
+
+INT PROC server channel :
+ sp channel
+END PROC server channel;
+
+
+PROC station only (BOOL CONST flag) :
+ stat only := flag
+END PROC station only;
+
+BOOL PROC station only :
+ stat only
+END PROC station only;
+
+
+PROC spool duty (TEXT CONST duty) :
+ sp duty := duty;
+END PROC spool duty;
+
+TEXT PROC spool duty :
+ sp duty
+END PROC spool duty;
+
+
+PROC spool control task (TASK CONST task id):
+ task in control := task id;
+END PROC spool control task;
+
+TASK PROC spool control task :
+ task in control
+END PROC spool control task;
+
+
+PROC spool manager (PROC server start) :
+
+ spool manager (PROC server start, TRUE)
+
+END PROC spool manager;
+
+
+PROC spool manager (PROC server start, BOOL CONST with start) :
+
+ set autonom ;
+ break ;
+ disable stop ;
+ initialize spool manager ;
+ REP forget (ds) ;
+ wait (ds, order, order task) ;
+ IF order <> second phase ack
+ THEN prepare first phase ;
+ spool (PROC server start);
+ ELIF order task = last order task
+ THEN prepare second phase ;
+ spool (PROC server start);
+ ELSE send nak
+ FI ;
+ send error if necessary ;
+ collect heap garbage if necessary
+ PER
+
+ . initialize spool manager :
+ initialize if necessary;
+ stop;
+ erase fetch entry;
+ IF with start THEN start (PROC server start) FI;
+
+ . initialize if necessary :
+ IF NOT initialized (in this task)
+ THEN FOR list index FROM 1 UPTO que size
+ REP list entry. space := nilspace PER;
+ fetch entry. space := nilspace;
+ ds := nilspace;
+ last order task := niltask;
+ server := niltask;
+ calling parent := niltask;
+ server is waiting := FALSE;
+ stop command pending := FALSE;
+ old heap size := 0;
+ clear spool;
+ FI;
+
+ . prepare first phase :
+ IF order = save code OR order = erase code OR order = stop code
+ THEN phase := 1 ;
+ last order := order ;
+ last order task := order task ;
+ FI;
+
+ . prepare second phase :
+ phase INCR 1 ;
+ order := last order
+
+ . send nak :
+ forget (ds) ;
+ ds := nilspace ;
+ send (order task, nak, ds);
+
+ . send error if necessary :
+ IF is error
+ THEN forget (ds) ;
+ ds := nilspace ;
+ error msg := ds ;
+ CONCR (error msg) := error message;
+ clear error;
+ send (order task, error nak, ds)
+ FI;
+
+ . collect heap garbage if necessary :
+ IF heap size > old heap size + 2
+ THEN collect heap garbage;
+ old heap size := heap size;
+ FI;
+
+END PROC spool manager;
+
+
+PROC spool (PROC server start):
+
+ command dialogue (FALSE);
+ enable stop;
+ IF station only CAND station (ordertask) <> station (myself)
+ THEN errorstop ("kein Zugriffsrecht auf Task " + text (station(myself))
+ + "/""" + name(myself) + """")
+ FI;
+
+ SELECT order OF
+
+ CASE fetch code : out of que
+ CASE param fetch code : send fetch params
+ CASE save code : new que entry
+ CASE file save code : new file que entry
+ CASE exists code : exists que entry
+ CASE erase code : erase que entry
+ CASE list code : send spool list
+ CASE all code : send owners ds names
+
+ OTHERWISE :
+
+ IF order >= continue code AND order task = supervisor
+ THEN forget (ds);
+ spool command (PROC server start)
+
+ ELIF spool control allowed by order task
+ THEN SELECT order OF
+ CASE entry line code : send next entry line
+ CASE killer code : kill entry
+ CASE first code : make to first
+ CASE start code : start server
+ CASE stop code : stop server
+ CASE halt code : halt server
+ CASE wait for halt code : wait for halt
+ OTHERWISE : errorstop ("falscher Auftrag fuer Task """
+ + name(myself) + """")
+ END SELECT
+
+ ELSE errorstop ("falscher Auftrag fuer Task """
+ + name(myself) + """")
+ FI;
+ END SELECT;
+
+
+. spool control allowed by order task :
+ (order task = spool control task OR order task < spool control task
+ OR spool control task = supervisor)
+ AND station (order task) = station (myself)
+.
+ out of que :
+ IF NOT (order task = server)
+ THEN errorstop ("keine Servertask")
+ ELIF stop command pending
+ THEN forget (ds);
+ stop;
+ erase fetch entry;
+ ELIF que is empty
+ THEN forget (ds) ;
+ erase fetch entry;
+ server is waiting := TRUE;
+ ELSE send first entry;
+ FI;
+
+.
+ send fetch params :
+ IF order task = server
+ THEN send params
+ ELSE errorstop ("keine Servertask")
+ FI;
+
+ . send params :
+ forget(ds); ds := nilspace; fetch msg := ds;
+ fetch msg := fetch entry. ds params;
+ send (order task, ack, ds);
+
+.
+ new que entry :
+ IF phase = 1
+ THEN prepare into que
+ ELSE into que
+ FI;
+
+.
+ prepare into que :
+ msg := ds ;
+ save params. name := msg.name;
+ save params. userid := msg.userid;
+ save params. password := msg.password;
+ save params. sendername := name (order task);
+ save params. station := station (order task);
+ forget (ds); ds := nilspace;
+ send (order task, second phase ack, ds);
+
+.
+ new file que entry :
+ IF type (ds) <> file type
+ THEN errorstop ("Datenraum hat falschen Typ");
+ ELSE get file params;
+ into que;
+ FI;
+
+ . get file params :
+ file := sequential file (input, ds);
+ end pos := 0;
+ next headline information (file save params. name);
+ next headline information (file save params. userid);
+ next headline information (file save params. password);
+ next headline information (file save params. sendername);
+ next headline information (buffer);
+ file save params. station := int (buffer);
+ IF NOT last conversion ok
+ THEN file save params. station := station (order task) FI;
+ IF file save params. sendername = ""
+ THEN file save params. sendername := name (order task) FI;
+ IF file save params. name = ""
+ THEN IF headline (file) <> ""
+ THEN file save params. name := headline (file);
+ ELSE errorstop ("Name unzulaessig")
+ FI;
+ ELSE headline (file, file save params. name);
+ FI;
+
+.
+ exists que entry :
+ msg := ds ;
+ order task name := name (order task);
+ order task station := station (order task);
+ to first que entry;
+ WHILE next que entry found
+ REP IF is entry from order task (msg. name)
+ THEN send ack;
+ LEAVE exists que entry
+ FI;
+ PER ;
+ forget (ds); ds := nilspace;
+ send (order task, false code, ds)
+
+.
+ erase que entry :
+ msg := ds ;
+ order task name := name (order task);
+ order task station := station (order task);
+ IF phase = 1
+ THEN ask for erase
+ ELSE erase entry from order task
+ FI;
+
+ . ask for erase :
+ to first que entry;
+ WHILE next que entry found
+ REP IF is entry from order task (msg. name)
+ THEN manager question ("""" + msg.name + """ loeschen");
+ LEAVE erase que entry
+ FI;
+ PER ;
+ manager message ("""" + msg.name + """ existiert nicht");
+
+ . erase entry from order task :
+ IF is entry from order task (msg. name)
+ THEN delete que entry;
+ LEAVE erase que entry
+ ELSE to first que entry;
+ WHILE next que entry found
+ REP IF is entry from order task (msg. name)
+ THEN delete que entry;
+ LEAVE erase que entry
+ FI ;
+ PER ;
+ manager message ("""" + msg.name + """ existiert nicht");
+ FI;
+
+ . delete que entry :
+ erase entry (list index) ;
+ send ack;
+
+.
+ send owners ds names:
+ order task name := name (order task);
+ order task station := station (order task);
+ forget (ds); ds := nilspace; all msg := ds;
+ all msg := empty thesaurus;
+ to first que entry;
+ WHILE next que entry found
+ REP IF is entry from order task ("")
+ THEN insert (all msg, list entry. ds params. name)
+ FI;
+ PER;
+ send (order task, ack, ds)
+
+.
+ send spool list :
+ list spool;
+ send (order task, ack, ds);
+
+.
+ send next entry line :
+ control msg := ds;
+ get next entry line (control msg. entry line, control msg. index);
+ send (order task, ack, ds);
+
+.
+ kill entry :
+ control msg := ds;
+ list index := control msg. index;
+ IF is valid que entry (list index)
+ THEN erase entry (list index)
+ FI;
+ send (order task, ack, ds);
+
+.
+ make to first :
+ control msg := ds;
+ list index := control msg. index;
+ IF is valid que entry (list index)
+ THEN new first (list entry);
+ erase entry (list index);
+ FI;
+ send (order task, ack, ds);
+
+.
+ start server :
+ IF exists (server) THEN errorstop ("Spool muß zuerst gestoppt werden") FI;
+ start (PROC server start);
+ IF server channel <= 0 OR server channel >= 33
+ THEN manager message ("WARNUNG : Serverkanal nicht eingestellt");
+ ELSE send ack
+ FI;
+
+.
+ stop server:
+ IF phase = 1
+ THEN stop;
+ IF valid fetch entry
+ THEN valid fetch entry := FALSE;
+ manager question (""13""10"" +
+ fetch entry. entry line + " neu eintragen");
+ ELSE erase fetch entry;
+ send ack;
+ FI;
+ ELSE IF fetch entry. entry line <> "" THEN new first (fetch entry) FI;
+ erase fetch entry;
+ send ack;
+ FI;
+
+.
+ halt server :
+ stop command pending := TRUE;
+ IF NOT exists (server) OR server is waiting
+ THEN stop;
+ erase fetch entry;
+ FI;
+ send ack;
+
+.
+ wait for halt :
+ IF exists (calling parent)
+ THEN errorstop ("Task """ + name (calling parent) + """ wartet schon auf halt")
+ ELSE calling parent := order task;
+ stop command pending := TRUE;
+ forget (ds);
+ IF NOT exists (server) OR server is waiting
+ THEN stop;
+ erase fetch entry;
+ FI;
+ FI;
+
+END PROC spool;
+
+
+PROC send first entry :
+
+ forget (ds); ds := first entry. space;
+ send (server, ack, ds, reply) ;
+ IF reply = ack
+ THEN server is waiting := FALSE;
+ start time := time of day;
+ start time CAT " am ";
+ start time CAT date;
+ erase fetch entry;
+ fetch entry := first entry;
+ erase entry (first);
+ valid fetch entry := TRUE;
+ ELSE forget (ds);
+ FI;
+
+END PROC send first entry;
+
+
+PROC into que :
+
+ IF que is full
+ THEN errorstop ("Spool ist voll")
+ ELSE make new entry;
+ send ack;
+ awake server if necessary
+ FI;
+
+ . make new entry :
+ IF order = save code
+ THEN last entry. ds params := save params;
+ save params := empty params;
+ ELSE last entry. ds params := file save params;
+ file save params := empty params;
+ FI;
+ last entry. space := ds;
+ counter INCR 1;
+ build entry line;
+ last := next (last) ;
+
+ . build entry line :
+ IF LENGTH last entry. ds params. sender name > 16
+ THEN buffer := subtext (last entry. ds params. sender name, 1, 13);
+ buffer CAT "...""";
+ ELSE buffer := last entry. ds params. sender name;
+ buffer CAT """";
+ buffer := text (buffer, 17);
+ FI;
+ last entry. entry line := entry station text;
+ last entry. entry line CAT "/""";
+ last entry. entry line CAT buffer;
+ last entry. entry line CAT " : """ ;
+ last entry. entry line CAT last entry. ds params. name;
+ last entry. entry line CAT """ (" ;
+ last entry. entry line CAT text (storage (last entry. space));
+ last entry. entry line CAT " K)";
+
+ . entry station text :
+ IF last entry. ds params. station = 0
+ THEN " "
+ ELSE text (last entry. ds params. station, 3)
+ FI
+
+ . awake server if necessary :
+ IF server is waiting THEN send first entry FI;
+
+END PROC into que;
+
+
+PROC list spool :
+
+ forget (ds); ds := nilspace;
+ file := sequential file (output, ds) ;
+ max line length (file, 1000);
+ headline(file, station text + "/""" + name (myself) + """");
+ put spool duty;
+ put current job;
+ put spool que;
+
+ . station text :
+ IF station(myself) = 0
+ THEN ""
+ ELSE text (station(myself))
+ FI
+
+ . put spool duty :
+ IF spool duty <> ""
+ THEN write (file, "Aufgabe: ");
+ write (file, spool duty );
+ line (file, 2);
+ FI;
+
+ . put current job :
+ IF valid fetch entry AND exists (server)
+ THEN write (file, "In Bearbeitung seit ");
+ write (file, start time);
+ write (file, ":");
+ line (file, 2);
+ putline (file, fetch entry. entry line);
+ IF stop command pending
+ THEN putline (file, "Spool wird nach diesem Auftrag deaktiviert");
+ FI;
+ line (file);
+ ELSE write (file, "kein Auftrag in Bearbeitung");
+ IF NOT exists (server)
+ THEN write (file, ", da Spool deaktiviert");
+ ELIF que is empty
+ THEN write (file, ", da Warteschlange leer");
+ LEAVE list spool;
+ FI;
+ line (file, 2);
+ FI;
+
+ . put spool que :
+ IF que is empty
+ THEN putline (file, "Warteschlange ist leer");
+ ELSE write (file, "Warteschlange (");
+ write (file, text (counter));
+ write (file, " Auftraege):");
+ line (file, 2);
+ to first que entry ;
+ WHILE next que entry found
+ REP putline (file, list entry. entry line) PER;
+ FI;
+
+END PROC list spool ;
+
+
+PROC clear spool :
+
+ first := 1;
+ last := 1;
+ counter := 0;
+ FOR list index FROM 1 UPTO que size
+ REP list entry. ds params := empty params;
+ list entry. entry line := "";
+ forget (list entry. space)
+ PER;
+
+END PROC clear spool;
+
+(*********************************************************************)
+(* Hilfsprozeduren zum Spoolmanager *)
+
+BOOL PROC is valid que entry (INT CONST index) :
+
+ que (index). entry line <> ""
+
+END PROC is valid que entry;
+
+
+INT PROC next (INT CONST index) :
+
+ IF index < que size
+ THEN index + 1
+ ELSE 1
+ FI
+
+END PROC next;
+
+
+PROC to first que entry :
+
+ list index := first - 1;
+
+ENDPROC to first que entry ;
+
+
+BOOL PROC next que entry found :
+
+ list index := next (list index);
+ WHILE is not last que entry
+ REP IF is valid que entry (list index)
+ THEN LEAVE next que entry found WITH TRUE FI;
+ list index := next (list index);
+ PER;
+ FALSE
+
+ . is not last que entry :
+ list index <> last
+
+ENDPROC next que entry found ;
+
+
+PROC get next entry line (TEXT VAR entry line, INT VAR index) :
+
+ IF index = 0
+ THEN list index := first - 1
+ ELSE list index := index
+ FI;
+ IF next que entry found
+ THEN entry line := list entry. entry line;
+ index := list index;
+ ELSE entry line := "";
+ index := 0;
+ FI;
+
+END PROC get next entry line;
+
+
+PROC new first (ENTRY VAR new first entry) :
+
+ IF que is full
+ THEN errorstop ("Spool ist voll")
+ ELSE first DECR 1 ;
+ IF first = 0 THEN first := que size FI;
+ first entry := new first entry;
+ counter INCR 1;
+ FI;
+
+END PROC new first;
+
+
+PROC erase entry (INT CONST index) :
+
+ entry. ds params := empty params;
+ entry. entry line := "";
+ forget (entry.space) ;
+ counter DECR 1;
+ IF index = first
+ THEN inc first
+ FI ;
+
+ . entry : que (index)
+
+ . inc first :
+ REP first := next (first)
+ UNTIL que is empty OR is valid que entry (first) PER
+
+END PROC erase entry;
+
+
+PROC erase fetch entry :
+
+ fetch entry. ds params := empty params;
+ fetch entry. entry line := "";
+ forget (fetch entry. space);
+ valid fetch entry := FALSE;
+
+END PROC erase fetch entry;
+
+
+BOOL PROC is entry from order task (TEXT CONST file name) :
+
+ correct order task CAND correct filename
+
+ . correct order task :
+ order task name = list entry. ds params. sendername
+ AND order task station = list entry. ds params. station
+
+ . correct file name :
+ file name = "" OR file name = list entry. ds params. name
+
+END PROC is entry from order task;
+
+
+PROC start (PROC server start):
+
+ begin (PROC server start, server);
+
+END PROC start;
+
+
+PROC stop :
+
+ stop server;
+ send calling parent reply if necessary;
+
+ . stop server:
+ IF exists (server) THEN end (server) FI;
+ server := niltask;
+ server is waiting := FALSE;
+ stop command pending := FALSE;
+
+ . send calling parent reply if necessary :
+ IF exists (calling parent)
+ THEN forget (ds); ds := nilspace;
+ send (calling parent, ack, ds);
+ calling parent := niltask;
+ FI;
+
+END PROC stop;
+
+
+PROC next headline information (TEXT VAR t):
+
+ begin pos := pos (headline (file), begin char, end pos + 1);
+ IF begin pos = 0
+ THEN begin pos := LENGTH headline (file) + 1;
+ t := "";
+ ELSE end pos := pos (headline (file), end char, begin pos + 1);
+ IF end pos = 0
+ THEN end pos := LENGTH headline (file) + 1;
+ t := "";
+ ELSE t := subtext (headline (file), begin pos+1, end pos-1)
+ FI
+ FI
+
+END PROC next headline information;
+
+
+PROC send ack :
+
+ forget (ds); ds := nilspace;
+ send (order task, ack, ds)
+
+END PROC send ack;
+
+
+PROC manager question (TEXT CONST question) :
+
+ forget (ds); ds := nilspace; error msg := ds ;
+ error msg := question ;
+ send (order task, question ack, ds)
+
+ENDPROC manager question ;
+
+
+PROC manager message (TEXT CONST message) :
+
+ forget (ds); ds := nilspace; error msg := ds ;
+ error msg := message ;
+ send (order task, message ack, ds)
+
+ENDPROC manager message ;
+
+(*********************************************************************)
+(* Spool - Kommandos *)
+
+INT VAR command index , params ;
+TEXT VAR command line, param 1, param 2 ;
+
+LET spool command list =
+"break:1.0start:2.01stop:4.0halt:5.0first:6.0killer:7.0listspool:8.0
+clearspool:9.0spoolcontrolby:10.1";
+
+PROC spool command (PROC server start) :
+
+ enable stop ;
+ continue (order - continue code) ;
+ disable stop ;
+ REP command dialogue (TRUE) ;
+ get command ("gib Spool-Kommando:", command line);
+ analyze command (spool command list, command line, 3, command index,
+ params, param1, param2);
+ execute command (PROC server start);
+ UNTIL NOT online PER;
+ command dialogue (FALSE);
+ break (quiet);
+ set autonom;
+
+END PROC spool command;
+
+
+PROC execute command (PROC server start) :
+
+ enable stop;
+ SELECT command index OF
+ CASE 1 : break
+ CASE 2 : start server
+ CASE 3 : start server with new channel
+ CASE 4 : stop server
+ CASE 5 : halt server
+ CASE 6 : first cmd
+ CASE 7 : killer cmd
+ CASE 8 : show spool list
+ CASE 9 : clear spool
+ CASE 10 : spool control task (task (param1))
+ OTHERWISE do (command line)
+ END SELECT;
+
+ . start server :
+ IF server channel <= 0 OR server channel >= 33
+ THEN line;
+ putline ("WARNUNG : Serverkanal nicht eingestellt");
+ FI;
+ stop server;
+ start (PROC server start);
+
+ . start server with new channel:
+ INT VAR i := int (param1);
+ IF last conversion ok
+ THEN server channel (i);
+ start server;
+ ELSE errorstop ("falsche Kanalangabe")
+ FI;
+
+ . stop server :
+ disable stop;
+ stop;
+ IF valid fetch entry CAND
+ yes (""13""10"" + fetch entry. entry line + " neu eintragen")
+ THEN new first (fetch entry) FI;
+ erase fetch entry;
+ enable stop;
+
+ . halt server :
+ stop command pending := TRUE;
+ IF NOT exists (server) OR server is waiting
+ THEN stop server;
+ erase fetch entry;
+ FI;
+
+ . first cmd :
+ line ;
+ to first que entry ;
+ WHILE next que entry found
+ REP say (list entry. entry line) ;
+ IF yes (" als erstes")
+ THEN new first (list entry);
+ erase entry (list index);
+ LEAVE first cmd
+ FI ;
+ PER;
+
+ . killer cmd :
+ line ;
+ to first que entry ;
+ WHILE next que entry found
+ REP say (list entry. entry line) ;
+ IF yes (" loeschen") THEN erase entry (list index) FI ;
+ PER;
+
+ . show spool list :
+ list spool;
+ disable stop;
+ show (file);
+ forget (ds);
+
+ENDPROC execute command ;
+
+ENDPACKET spool manager;
+
diff --git a/system/net/unknown/doc/EUMEL Netz b/system/net/unknown/doc/EUMEL Netz
new file mode 100644
index 0000000..941e2ea
--- /dev/null
+++ b/system/net/unknown/doc/EUMEL Netz
@@ -0,0 +1,829 @@
+#type ("trium8")##limit (11.0)#
+#start(2.5,1.5)##pagelength (17.4)#
+#block#
+#headeven#
+
+% EUMEL-Netzbeschreibung
+
+
+#end#
+#headodd#
+
+#center#Inhalt#right#%
+
+
+#end#
+
+#type ("triumb12")#
+1. Einleitung
+
+
+Teil 1: Netz einrichten und benutzen
+#type ("trium8")#
+
+1. Benutzung des Netzes
+
+2. Hardwarevoraussetzungen
+
+3. Einrichten des Netzes
+
+4. Informationsmöglichkeiten
+
+5. Eingriffsmöglichkeiten
+
+6. Fehlerbehebung im Netz
+
+#type ("triumb12")#
+
+Teil 2: Arbeitsweise der Netzsoftware
+#type ("trium8")#
+
+1. Die Netztask
+
+2. Protokollebenen
+
+3. Stand der Netzsoftware
+
+#page#
+#headodd#
+
+#center#Einleitung#right#%
+
+
+#end#
+
+#type("triumb12")#
+1. Einleitung #type("trium8")#
+
+
+Das EUMEL-Netz dient dazu mehrere EUMEL-Rechner (sog. Stationen) mit­
+einander zu koppeln. Diese Kopplung wird von Betriebsystem dazu benutzt, das
+Sendungskonzept (siehe Systemhandbuch 1.7, Intertaskkommunikation) so auszu­
+dehnen, daß Tasks verschiedener Stationen einander Datenräume zusenden
+können. Auf dem Sendungskonzept aufbauende Konzepte nutzen daher automa­
+tisch das Netz aus: So ist es z.B. möglich
+
+- von einer Station aus auf einer anderen zu Drucken,
+
+- in PUBLIC einer anderen Station Dateien zu sichern (save), vorausgesetzt, daß
+ PUBLIC dort ein free global manager ist,
+
+- auf einer anderen Station zu archivieren (z.B. wenn das eigene Archivlaufwerk
+ defekt ist oder ein anderes Format hat).
+
+Das Netz kann ab EUMEL-Version 1.7.3 eingesetzt werden.
+
+
+#type("triumb12")#
+Teil 1: Netz einrichten und benutzen
+
+1. Benutzung des Netzes #type("trium8")#
+#headodd#
+
+#center#Teil 1: Netz einrichten und benutzen#right#%
+
+
+#end#
+
+ Zur Benutzung des Netzes stehen folgende Operatoren und Prozeduren zur
+ Verfügung:
+
+
+1.1
+
+ TASK OP / (INT CONST station, TEXT CONST taskname)
+
+ liefert die Task #on("bold")#taskname#off("bold")# von der Station #on("bold")#station#off("bold")#.
+
+ Wenn die Station #on("bold")#station#off("bold")# nicht am Netz ist oder nicht eingeschaltet ist, wird
+ solange gewartet, bis das der Fall ist.
+
+ Fehlerfälle:
+
+ - task "..." gibt es nicht
+
+ Die angeforderte Task gibt es in der Zielstation nicht.
+
+ - Collectortask fehlt
+
+ Das Kommando #on("bold")#define collector#off("bold")# wurde nicht gegeben (siehe 4.2).
+
+ - Station x antwortet nicht
+
+ Eine nicht vorhandene oder abgeschaltete Station wurde angesprochen.
+ Hinweis: Dieser Fehler wird angenommen, wenn eine Überwachungszeit
+ von ca. 30 Sekunden verschrichen ist, ohne daß Station x die
+ Taskidentifikation angeliefert hat.
+
+ Beispiel:
+
+ list (5/"PUBLIC")
+
+ Dateiliste von PUBLIC auf Station 5 wird angefordert.
+
+1.2
+
+ TASK OP / (INT CONST station, TASK CONST task)
+
+ liefert
+
+ station / name (task) .
+
+
+ Beispiel:
+
+ list (4/archive)
+
+
+1.3
+
+ INT PROC station (TASK CONST task)
+
+ liefert die Stationsnummer der Task #on("bold")#task#off("bold")#.
+
+ Beispiel:
+
+ put (station (myself))
+
+ gibt die eigene Stationsnummer aus.
+
+
+1.4
+
+ PROC archive (TEXT CONST archivename, INT CONST station)
+
+ dient dazu das Archiv auf der Station #on("bold")#station#off("bold")# anzumelden.
+
+ Beispiel:
+
+ archive ("std", 4); list (4/archive)
+
+ gibt das Inhaltsverzeichnis der Archivfloppy im Laufwerk der Station 4 aus.
+ Hinweis: Vergessen Sie bei solchen Querarchivierungen nicht die Stations­
+ angabe bei jedem einzelnen Archivkommando (z.B fetch ("xxx", #on("bold")#4/#off("bold")#
+ archive).
+ Hinweis: Querarchivieren ist langsam. Verwenden Sie es nur, wenn Sie Flop­
+ pyformate umsetzen wollen.
+
+
+1.5
+
+ PROC free global manager
+
+ dient dazu, die eigene Task über das Netz ansprechbar zu machen. Jede
+ andere Task im Netz kann dann die üblichen Manageraufrufe ('save', 'fetch',
+ u.s.w.) an die eigene Task machen, sofern diese nicht an ein Terminal gekop­
+ pelt ist.
+
+ Die Task wird (wie bei 'break') abgekoppelt und meldet sich in Zukunft mit
+ 'maintenance' statt mit 'gib kommando'.
+
+ Beispiel:
+
+ An Station 4 ruft man in der Task 'hugo' das Kommando #on("bold")#free global manager#off("bold")#
+ auf. Anschließend kann man von jeder Station aus z.B. 'list (4/"hugo")' u.s.w.
+ machen.
+
+
+1.6
+
+ TEXT PROC name (TASK CONST t)
+
+ Diese (schon immer vorhandene) Prozedur wurde dahingehend erweitert, daß der
+ Name einer Task einer anderen Station über Netz angefordert wird.
+
+ Fehlerfall:
+
+ Station x antwortet nicht
+
+
+
+
+#type("triumb12")#2. Hardwarevoraussetzungen#type("trium8")#
+
+2.1 Zwei Stationen
+
+ Sie können zwei Stationen miteinander Vernetzen, wenn Sie dafür an jeder
+ Station eine V24-Schnittstelle zur Verfügung stellen.
+
+ Diese beiden Schnittstellen verbinden Sie mit einem Kabel zur Rechner­
+ kopplung (siehe Systemhandbuch 1.7 Teil 2).
+
+2.2 Mehrere Stationen
+
+ Wenn Sie mehr als zwei Stationen vernetzen wollen, brauchen neben je
+ einer V24 an jeder Station noch je eine Netzanschlußbox.
+
+ Jede Box besitzt eine V24-Schnittstelle zum Anschluß an die V24-
+ Schnittstelle der zugeorneten Station und eine weitere Schnittstelle zur
+ Verbindung der Boxen untereinander.
+
+
+#type("triumb12")#3. Einrichten des Netzes #type("trium8")#
+
+Hinweis: Dieses Kapitel ist nur für Systembetreuer wichtig.
+
+3.1 Legen Sie Stationsnummern für die am Netz beteiligten Rechner fest (von 1 an
+ aufsteigend).
+
+ Die Boxen haben ebenfalls Stationsnummern. Die Stationsnummern der Box
+ und des zugeordneten Rechners müssen übereinstimmen.
+
+
+3.2 Holen Sie an jeder Station die Task #on("bold")#configurator#off("bold")# an ein Terminal und geben Sie
+ das Kommando #on("bold")#define collector ("net port")#off("bold")#. Geben Sie außerdem das
+ Kommando #on("bold")#define station (x)#off("bold")#, wobei #on("bold")#x#off("bold")# die gewählte Stationsnummer ist.
+
+ Hinweis: Taskkommunikationen, die zu dem Zeitpunkt laufen, führen zu feh­
+ lerhaften Verhalten. Dies liegt daran, daß durch #on("bold")#define station#off("bold")# alle
+ Task-Id's geändert werden müssen, weil eine Task-Id u.a. die
+ Stationsnummer der eigenen Station enthält (siehe 2.3). TASK-
+ Variable, die noch Task-Id's mit keiner oder falscher Stationsnum­
+ mer enthalten, können nicht mehr zum Ansprechen einer Task
+ verwendet werden.
+
+ Beispiel: Der Spoolmanager (siehe Benutzerhandbuch 1.7 Teil 12) richtet
+ beim Kommando #on("bold")#start#off("bold")# einen Worker ein und merkt sich dessen
+ Task-Id in einer TASK-Variablen, um sicherzustellen, daß nur der
+ Worker Dateien zum Drucken abholt. Wird jetzt das Kommando #on("bold")#
+ define station#off("bold")# gegeben, kann der Spoolmanager seinen Worker
+ nicht mehr identifizieren, weil der Worker eine neue Task-Id er­
+ halten hat. Man muß daher den Worker löschen und mit dem
+ Kommando #on("bold")#start#off("bold")# im Spoolmanager wieder neu einrichten.
+
+
+ Sinnvollerweise gibt man #on("bold")#define station#off("bold")# sofort nach den Laden eines
+ frischen Systems von Archiv.
+
+ Konfigurieren Sie mit dem Kommando #on("bold")#configurate#off("bold")# den für das Netz vorgese­
+ henen Kanal auf
+
+ - transparent
+ - 9600 Baud (Standardeinstellung der Boxen)
+ - RTS/CTS-Protokoll
+ - großen Puffer
+ - 8 bit
+ - even parity
+ - 1 stopbit.
+
+ Falls diese Einstellungen nicht alle angeboten werden, klären Sie mit Ihrem
+ Rechnerlieferanten, ob und wie diese Einstellungen erreicht werden können.
+ Hinweis: Notfalls kann auf das RTS/CTS-Protokoll verzichtet werden, wenn
+ der Eingabepuffer der Station groß genug ist. Die Anzahl simultan
+ laufender Netzkommunikationen ist dann auf
+
+ puffergröße DIV 150
+
+ begrenzt (bei Z80, 8086: 3; bei M20: 10).
+ Hinweis: Es können auch andere Baudraten (2400, 4800, 19200) an der Box
+ eingestellt werden.
+
+3.3 Achten Sie bei der Verbindung von der Station zur Netzbox (bzw. zur Gegen­
+ station bei einem Zweistationennetz ohne Boxen) darauf, daß neben den
+ Empfangs- und Sendeleitungen auch die Leitungen RTS und CTS verdrahtet
+ werden, also ein 5 poliges Kabel verwendet wird (siehe Systemhandbuch 1.7
+ Teil 2). Die Pin-Belegung der Boxen entspricht den dortigen Angaben.
+
+ Beispiel:
+
+ Verbindung eines CSK-Systems mit der Box:
+
+ Stecker Stecker
+ Pin Pin
+
+ 2 <---------> 3
+ 3 <---------> 2
+ 4 <---------> 5
+ 5 <---------> 4
+ 7 <---------> 7
+
+
+3.4 Richten Sie eine Task #on("bold")#net#off("bold")# unter #on("bold")#SYSUR#off("bold")# ein und insertieren Sie dort die Datei­
+en
+
+ net report/M
+ basic net
+ net manager/M.
+
+ Beantworten Sie die Frage nach dem Kanal für das Netz und nach der Fluß­
+ kontrolle (RTS/CTS).
+
+
+#type("triumb12")#4. Informationsmöglichkeiten #type("trium8")#
+
+ In der Task #on("bold")#net#off("bold")# wird eine Datei #on("bold")#report#off("bold")# geführt in der Fehlersituationen des
+ Netzes verzeichnet werden. Diese Datei kann in jeder anderen Task mit #on("bold")#list
+ (/"net")#off("bold")# angezeigt werden.
+
+ In jeder Task kann durch das Kommando #on("bold")#list (/"net port")#off("bold")# eine Übersicht über
+ die momentan laufenden Netzübertragungen der eigenen Station erhalten
+ werden.
+
+
+#type("triumb12")#5. Eingriffsmöglichkeiten #type("trium8")#
+#headodd#
+
+#center#Eingriffsmöglichkeiten#right#%
+
+
+#end#
+
+5.1 Jede Task kann Sende- und Empfangsströme, die bei #on("bold")#list (/"net port")#off("bold")# gemel­
+ det worden sind und die eigene Task betreffen, abbrechen. Hierzu ist das
+ Kommando #on("bold")#erase ("x",/"net port")#off ("bold")# zu geben, wobei x die Stromnummer (aus
+ dem 'list') ist.
+
+ Unberechtigte Löschversuche werden abgewiesen.
+
+ Von der Task 'net' aus können jedoch damit beliebige Ströme abgebrochen
+ werden.
+
+5.2 Durch das Kommando #on("bold")#start#off("bold")# kann von der Task 'net' aus das Netz neu gestartet
+ werden. Dabei werden alle augenblicklichen Netzkommunikationen gelöscht.
+ Die Tasks 'net port' und 'net timer' werden dabei gelöscht und neu eingerich­
+ tet.
+
+ #on("bold")#start (kanal, quit)#off("bold")# wirkt wie #on("bold")#start#off("bold")#. Zustzlich wird als Netzkanal 'kanal' eingestellt
+ und maximal 'quit' Empfangsströme zugelassen. 'quit' ist auf 3 zu setzen,
+ wenn der Kanal ohne RTS/CTS angeschlossen ist (siehe 3.2).
+
+
+#type("triumb12")#6. Fehlersuche im Netz #type("trium8")#
+
+ Fehler im Netz können sich verschiedenartig auswirken. Im Folgenden wird auf
+ einige Beispiele eingegangen:
+
+ Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung 'Station 4 antwortet nicht'.
+
+ Fehlermöglichkeiten:
+
+ - Station 4 gibt es nicht am Netz.
+ Abhilfe: Richtige Station angeben.
+
+ - Station 4 ist nicht eingeschaltet.
+ Abhilfe: Station 4 einschalten. Kommando erneut geben.
+
+ - Netztask an Station 4 ist nicht arbeitsfähig.
+ Abhilfe: Kommando 'start' in der Task 'net'.
+
+ - Stationsnummern und Boxnummern stimmen nicht überein.
+ Abhilfe: Mit 'define station' Stationsnummern korrigieren (siehe 3.2).
+
+ - Verbindung Rechner/Box am eigenen Rechner oder an Station 4 fehlt.
+ Abhilfe: Verbindungen überprüfen. Durch Ansprechen einer dritten Station
+ kann oft schnell geklärt werden, welche Rechner/Box-Verbindung
+ defekt sein muß.
+
+ - Verbindung der Boxen untereinander defekt.
+ Abhilfe: Fehlende Verbindung, Masseschluß und Dreher (keine 1:1 Ver­
+ bindung) überprüfen und beheben.
+ Hinweis: Liegt z.B. ein Masseschluß vor, so kann es durchaus sein, daß
+ Boxen, die nicht in der Nähe des Masseschluß stehen noch mitei­
+ nander arbeiten können. Man kann aus der Tatsache, daß zwei
+ Boxen miteinander arbeiten können, also nicht schließen, daß man
+ nicht nach diesem Fehler suchen muß.
+
+
+ Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt keine Reaktion.
+
+
+ - Station 4 ist während dieser Sendung zusammengebrochen.
+ Abhilfe: Station 4 wieder starten. Die Bearbeitung des 'list'-Kommandos
+ wird automatisch wieder aufgenommen.
+
+ - PUBLIC auf Station 4 ist nicht im Managerzustand.
+ Abhilfe: PUBLIC in den Managerzustand versetzen.
+
+
+ Hinweis: Das Netz hat nocht nicht die volle Sendungslogik des EUMEL. So
+ wird nur ca. 10 Minuten lang versucht, eine Sendung zuzustellen.
+ Danach wird die Sendung gelöscht. Ist dies eingetreten, so muß
+ das list-Kommando erneut gegeben werden.
+
+ - Fehler in der Netzhardware.
+ Überprüfen Sie, ob
+
+ - die Boxen eingeschaltet sind,
+ - die Bereitlampe blinkt (wenn nicht: RESET an der Box)
+ - die V24-Kabel richtig stecken,
+ - die Boxen untereinander verbunden sind (1 zu 1 Verbindungen der 5
+ poligen Diodenbuchsen).
+
+
+ - Die Netzsoftware ist auf einen nicht vorhergesehenen Fehler gelaufen.
+ Dieser wird im Report vermerkt.
+ Abhilfe: Geben Sie in der Task #on("bold")#net#off("bold")# das Kommando #on("bold")#start#off("bold")#. Dadurch wird die
+ Netzsoftware neu gestartet. Alle Netzkommunikationen dieser
+ Station gehen verloren.
+
+
+ Beispiel:
+
+ Auf #on("bold")#list (4/public)#off("bold")# erfolgt die Meldung 'Collectortask fehlt'.
+
+ - In der Task 'configurator' wurde das Kommando 'define collector' (siehe 3.2)
+ nicht gegeben.
+
+ - Die Task 'net port' existiert nicht mehr.
+ Abhilfe: Kommando 'start' in der Task 'net'.
+
+
+ Beispiel:
+
+ Nach #on("bold")#fetch ("hugo",4/public)#off("bold")# sind Teile von der Datei "hugo" verfälscht.
+
+ - Die V24-Verbindung zur Box ist nicht in Ordnung.
+ Abhilfe: Abstand zwischen Rechner und Box verkürzen; Baudrate ernie­
+ drigen; Durch Wechseln der V24-Schnittstelle feststellen, ob
+ diese defekt ist.
+ Hinweis: Die Verbindung zwischen den Boxen ist durch Prüfsummen abge­
+ sichert (Hardware).
+
+#headodd#
+
+#center#Teil 2: Arbeitsweise der Netzsoftware#right#%
+
+
+#end#
+#page#
+#type("triumb12")#
+
+Teil 2: Arbeitsweise der Netzsoftware
+
+
+1. Die Netztask #type ("trium8")#
+
+In diesem Kapitel wird beschrieben, wie eine Netztask in das System
+eingebettet ist und welche Aufgaben sie hat. Unter Einhaltung dieser
+Konzepte kann die ausgelieferte Netztask so geändert werden, daß sie
+beliebige andere Netzhardware unterstützt. Z.Zt. ist die Netzsoftware noch
+nicht so gegliedert, daß nur eine hardwareabhängige Komponente ausgetauscht
+werden muß.
+
+Die Kommunikation zwischen Tasks im EUMEL-Betriebssystem basiert auf einem
+Rendevouskonzept: Die Zieltask einer Sendung muß empfangsbereit sein, wenn die
+Quelltask sendet.
+
+Die Kommunikationsprozeduren auf der niedrigsten Ebene sind 'send' (Senden)
+und 'wait' (Warten auf Empfang). Bei der Kommunikation werden eine Integer
+'code' und ein Datenraum 'dr' übergeben. 'code' muß >= 0 sein, da negative
+Codes systemintern verwandt werden. Ist die empfangende Task an einen Kanal
+gekoppelt ('continue'), so führt eine Zeicheneingabe auf diesem Kanal dazu,
+daß eine
+Sendung mit dem Code -4 ankommt. Die Eingabedaten müssen mit den üblichen
+Eingabeprozeduren ('inchar' u.s.w.) abgeholt werden. Der übermittelte Datenraum
+und die Absendertask sind dabei ohne Bedeutung und dürfen nicht interpretiert
+werden.
+
+Die Prozedur 'send' hat einen Rückmeldeparameter, der besagt, ob die Sendung
+übermittelt wurde. Gibt es die Zieltask nicht oder steht sie nicht im 'wait', so kann
+die Sendung nicht übermittelt werden.
+
+
+Ein Entwicklungskriterium für das EUMEL-Netz war es, möglichst wenig Unter­
+stützung von der virtuellen EUMEL-Maschine (EUMEL0) zu fordern, damit weit­
+gehend in ELAN programmiert werden kann. Dadurch ist es möglich eine (privili­
+gierte) Task mit der Netzabwicklung zu betrauen.
+
+Zunächst wird auf die EUMEL0-Unterstützung eingegangen:
+
+1.1. Es gibt die Prozedur 'define collector', mit der die für das Netz verantwort­
+ liche Task der EUMEL0-Maschine bekannt gemacht wird. Diese Task wird im
+ folgenden Collector genannt.
+
+1.2. Es gibt die Prozedur 'define station', die für den Rechner eine Stationsnum­
+ mer einstellt. Anhand dieser Nummer werden die Rechner eines Netzes un­
+ terschieden. Das Einstellen bewirkt, daß für alle Tasks die Stationsnummer in
+ ihre Task-Id eingetragen wird (Task-Id's sind die Werte, die der Typ TASK
+ annehmen kann).
+
+1.3. Der Befehl 'station (task)' liefert die Stationsnummer der 'task'. So liefert z.B.
+ 'station (myself)' die Stationsnummer des eigenen Rechners.
+
+1.4. Eine Sendung, deren Zieltask in einem anderen Rechner liegt (also station
+ (ziel) <> station (myself)), wird auf die Collectortask geleitet.
+
+1.5. Es gibt eine Prozedur 'collected destination', die es dem Collector erlaubt, die
+ eigentliche Zieltask einer auf ihn geleiteten Sendung zu erfahren.
+
+1.6. Es gibt eine Variante der Prozedur 'send', die es dem Collector gestattet, der
+ Zieltask eine beliebige andere Task als Absender vorzumachen.
+
+1.7. Es gibt eine spezielle Task-Id 'collector', durch die der augenblicklich ein­
+ gestellte Collector erreicht wird. Diese wird als Zieltask beim Aufruf der Ver­
+ mittlungsdienste angegeben (siehe 2.5). Eine Sendung an 'collector' wird von
+ EUMEL0 an den derzeitigen Collector geschickt.
+
+Ein Collector kann also auf drei Wegen von den übrigen Tasks desselben Rechners
+Sendungen erhalten:
+
+ 1. Über ein normales Send (z.B. bei 'list (/"net port")', wenn "net port" der der­
+ zeitige Collector ist),
+
+ 2. über ein Send an die Task 'collector' (s.u.) und
+
+ 3. als umgeleitete Sendung (z.B. bei 'list' an eine Task auf einem anderen
+ Rechner).
+
+Der Collector kann diese Fälle anhand von 'collected destination' unterscheiden.
+
+Die Punkte 1.4...1.6 dienen dazu, den Collector für über Netz kommunizierende
+Task unsichtbar zu machen: Der Collector taucht nicht als Ziel oder Quelle von
+Sendungen auf. Das ist notwendig, damit normale Tasks sich nicht darum kümmern
+müssen, ob eine Sendung übers Netz geht oder im eigenen Rechner bleibt.
+
+Wenn ein Datenraum an einen anderen Rechner geschickt wird, muß der gesamte
+Inhalt (z. Zt. max. 1 MB) übertragen werden. Dies macht bei der üblichen Netz­
+hardware eine Zerlegung in Packete nötig (siehe Systemhandbuch 173, Teil 4,
+Punkt 5). Für Netze über V24-Kanäle stehen spezielle Blockbefehle zur verfü­
+gung:
+
+1.8. blockin / blockout (dr,seite,512+abstand,anzahl,rest)
+
+ Es werden maximal 'anzahl' Bytes transferiert. In 'rest' wird zurückgemeldet,
+ wieviel Bytes nicht bearbeitet wurden (z.B. weil der Kanal nichts anliefert).
+ Bearbeitet werden die Bytes
+
+ 'seite' * 512 + 'abstand'
+
+ bis maximal
+
+ 'seite' * 512 + 'abstand' + 'anzahl' - 1
+
+ Der Kanal, an den die Task gekoppelt ist, wird dabei über Stream-IO (d.h.
+ 'incharety' bei 'blockin' bzw. 'out' bei 'blockout') angesprochen.
+
+ Hinweis: Die Anforderung darf nicht über Seitengrenze gehen, d.h.
+
+ 'abstand' + 'anzahl' <= 512
+
+ muß erfüllt sein.
+
+
+Eine Netzsendung läuft wie folgt ab:
+
+Die Task q auf Rechner rq mache ein 'send' an die Task z auf Rechner rz.
+
+1. Die Prozedur send ist ein EUMEL0-Befehl. Die EUMEL0-Ebene erkennt, daß
+ die Sendung an die Station rz geht, da die Stationsnummer in der Task-Id
+ enthalten ist. Daher wird die Sendung zum Collector, den EUMEL0 wegen 'de­
+ fine collector' kennt, umgeleitet.
+
+2. Die Task Collector empfängt über 'wait' den Datenraum, den Sendecode und
+ die Absendertask q. Die Zieltask z erfährt sie durch 'collected destination'.
+
+3. Der Collector nimmt Kontakt mit dem Collector des Rechner rz, dessen Sta­
+ tionsnummer ja 'station(z)' ist, auf und Übermittelt diesem Sendecode, Quelltask
+ (q), eigentliche Zieltask (z) und den Datenraum. Da die Collectoren in ELAN
+ geschrieben sind, können sie an beliebige Netzhardware und Protokolle ange­
+ paßt werden.
+
+4. Der Collector auf Rechner rz verwendet das spezielle 'send', um der Zieltask die
+ Sendung zuzustellen. Dadurch erscheint nicht der Collector sondern die Task q
+ als Absender der Sendung.
+
+Zur Abwicklung der Vermittlungsebene (Teil 1: 2.4) muß der Collector noch
+spezielle Funktionen beherrschen. Diese sind
+
+ der /-Operator (Taskname in Task-Id wandeln) und
+ die name-Prozedur (Task-Id in Namen wandeln).
+
+Der /-Operator macht eine Sendung an den 'collector', wobei im Datenraum der
+Name der Task steht und der Sendecode gleich der Stationsnummer ist (siehe
+Quellcode 173, Packet tasks). Der Collector setzt sich mit dem Collector dieser Sta­
+tion in Verbindung, damit dieser die Task-Id ermittelt und zurückschickt. Der
+eigene Collector schickt dann dem /-Operator als Antwort einen Datenraum, der
+die Task-Id enthält.
+
+Umgekehrt läuft 'name' ab: Wenn die Task-Id von einer fremden Station ist,
+schickt 'name' eine Sendung an den 'collector', wobei im Datenraum die Task-Id
+steht und Sendecode = 256 ist. Der Collector entnimmt die Stationnummer der
+Task aus der Task-Id und läßt sich vom entsprechenden Collector den Tasknamen
+geben. Dieser wird der 'name'-Prozedur im Antwortdatenraum übergeben.
+
+#type ("triumb12")#2. Ebenen #type("trium8")#
+
+In diesem Kapitel werden die Protokollebenen für das Netz beschrieben, wie
+sie die ausgelieferte Netzsoftware benutzt und erwartet. Bei anderer
+Netzhardware müssen die Ebenen 1 bis 3 ausgetauscht werden. Unter Einhaltung
+der im vorigen Kapitel beschriebenen Randbedingungen können auch die höheren
+Ebenen geändert werden.
+
+
+2.1 Physikalische Ebene
+
+ 2.1.1 Station <--> Box
+
+ V24-Schnittstelle mit RTS/CTS-Handshake. Vollduplex.
+
+ 2.1.2 Box <--> Box
+
+ RS422 über 2 verdrillte Leitungspaare (Takt und Daten).
+
+2.2 Verbindungsebene
+
+ 2.2.1 Station <--> Box
+
+ Asynchron
+ 8 Bit
+ Even Parity
+ 2400/4800/9600/19200 Baud (einstellbar über Lötbrücken)
+
+ 2.2.2 Box <--> Box
+
+ SDLC
+ 400 KBaud
+
+2.3 Netzebene
+
+ 2.3.1 Station <--> Box
+
+ Telegrammformat: STX, <n>, <ziel>, <quelle>, <(n-4) byte>
+
+ <n> ist Längenangabe ( 8 <= n <= 160)
+ <ziel>, <quelle> sind Stationsnummern. Diese müssen an den je­
+ weiligen Boxen über Lötbrücken eingestellt sein.
+
+ Box --> Station:
+
+ Ein Telegramm kommt nur bei der Station an, bei deren Box die
+ Nummer <ziel> eingestellt ist. Dadurch ist ein Mithören fremder
+ Übertragungen nicht möglich (Datenschutz).
+
+ Zwischen Telegrammen können Fehlermeldungen der Box (Klartext)
+ übermittelt werden (z.B. 'skipped x', wenn ein STX von der Box er­
+ wartet wurde, aber 'x' von der Station ankommt).
+
+ Station --> Box:
+
+ Ein Telegramm wird nur abgeschickt, wenn <quelle> mit der einge­
+ stellten Nummer übereinstimmt (Datenschutz: Man kann nicht eine
+ beliebige Station zu sein vorschwindeln, es sei denn man hat physi­
+ schen Zugriff zur Box und stellt dort die Stationsnummer um).
+
+ 2.3.2 Box <--> Box
+
+ Telegrammformat: FRAME, <ziel>, <quelle>, <daten> ,
+ <CRC-Code>
+
+ Eine Längenangabe ist nicht nötig, da SDLC eine Rekonstruktion der
+ Länge erlaubt.
+
+ Telegramme mit falschen CRC-Code werden vernichtet. Auf höheren
+ Ebenen muß dies durch Zeitüberwachung erkannt und behandelt
+ werden.
+
+
+2.4 Transportebene
+
+ Diese Ebene wickelt das Rendevous zwischen einer Task, die 'send' macht,
+ und einer Task, die im 'wait' steht, ab (siehe: EUMEL-Systemhandbuch).
+
+ Der im 'send' angegebene Datenraum wird als Folge von Seiten (im
+ EUMEL-Sinne: Pagingeinheit und Allokiereinheit) übermittelt, wobei jede Seite
+ noch in 64 Byte große Stücke zerlegt wird. Es werden nur echt allokierte Seiten
+ übermittelt. Um nicht jedes Telegramm voll qualifizieren zu müssen, wird
+ zunächst eine Art virtuelle Verbindung durch ein OPEN-Telegramm eröffnet.
+ Danach folgen variable viele DATA-Telegramme. Beide Sorten werden durch
+ QUIT-Telegramme quittiert, um folgende Funktionen zu ermöglichen:
+
+ Flußkontrolle (z.B. Zielrechner langsam)
+ Wiederaufsetzen (verlorene Telegramme)
+ Abbruch (z.B. weil Zieltask inzwischen beendet).
+
+ Ein CLOSE-Telegramm ist nicht nötig, da das letzte DATA-Telegramm als
+ solches erkannt werden kann (siehe unten).
+
+ 2.4.1 OPEN-Telegramm
+
+ STX, 20, <ziel>, <quelle>, <strom>, <sequenz>, <seite>,
+ <quelltask>, <zieltask>, <code>
+
+ <ziel>, <quelle> siehe 2.3.1
+
+ <strom> Die Stromnummer identifiziert die virtuelle Verbindung.
+ Sie muß in den QUIT-Telegrammen angegeben wer­
+ den.
+
+ <sequenz> -1 (Kennzeichen für OPEN)
+
+ <seite> Nummer der ersten echt allokierten Seite des Datenra­
+ ums (=-1, falls Nilspace)
+
+ <quelltask> Taskid der sendenden Task
+
+ <zieltask> Taskid der empfangenden Task
+
+ <code> Wert des im 'send' angegebenen Codes.
+
+ 2.4.2 DATA-Telegramm
+
+ STX, 74, <ziel>, <quelle>, <sequenz>, <seite>, <64 byte>
+
+ <sequenz> wird von Telegramm zu Telegramm hochgezählt. Dient
+ der Überwachung gegen verlorengegangene Telegramme
+ bzw. durch Zeitüberwachung verdoppelter Telegramme.
+
+ <seite> Nummer der x.ten echt allokierten Seite des Datenra­
+ ums. (x = (<sequenz>+16) DIV 8).
+
+ <64 byte> Nutzinformation. Diese gehört zur Adresse a des Daten­
+ raums.
+
+ a = N (<sequenz> DIV 8 + 1) * 512
+ + (<sequenz> MOD 8) * 64
+
+ wobei N (x) die Nummer der x.ten Seite ist.
+
+ Aus den Formeln ergibt sich, daß diese Nummer schon in
+ einem vorhergehenden DATA/OPEN-Telegramm über­
+ mittelt wurde (im Feld <seite>).
+
+ 2.4.3 QUIT-Telegramm
+
+ STX, 8, <ziel>, <quelle>, <strom>, <quit>
+
+ <strom> muß die Stromnummer sein, die in dem OPEN/DATA-
+ Telegramm stand, das quittiert wird.
+
+ <quit> 0 : ok. Nächstes Telegramm schicken.
+
+ -1: Übertragung neu starten (mit OPEN), weil die
+ Empfangsstation das OPEN nicht erhalten hat.
+
+ -2: Übertragung ca. 20 Telegramme zurücksetzen.
+
+ -3: Übertragung abbrechen.
+
+
+2.5 Vermittlungsebene
+
+ Diese Ebene ist dafür zuständig, Tasknamen von Task auf anderen Stationen
+ in Taskids (Werte des Typs TASK) zu wandeln und umgekehrt. Hierzu wird im
+ entsprechenden OPEN-Telegramm der Code -6 (bzw. -7) als <code>
+ eingetragen. Die Netzempfangstask erkennt diese Codes und wickelt die
+ Aufgaben selbst ab, sodaß es dabei nicht nötig ist, irgendeine Taskid der
+ Zielstation zu kennen.
+
+ Dieses Verfahren ist möglich, weil im 'send' nur positive Codes erlaubt sind.
+
+2.6 Höhere Ebenen
+
+ Höhere Ebenen sind nicht mehr netzspezifisch. Sie basieren alle auf dem
+ Send/Wait-Konzept des EUMEL. So gibt es z.B. den 'global manager', der
+ Aufbewahrung und Zugriff von Dateien in einer Task regelt. Dabei darf diese
+ Task (bei der Variante 'free global manager') auf einer beliebigen Station im
+ Netz liegen. Wegen des Rendevous-Konzepts können beliebige Sicherheit­
+ strategien benutzt werden (z.B.: Keine Dateien an Station 11 ausliefern). Von
+ großen Wert ist z.B., daß man ohne weiteres das Archiv (Floppylaufwerk) einen
+ anderen Station anmelden und benuzten kann, wodurch eine einfache Kon­
+ vertierung von Floppyformaten möglich ist. Dies ist möglich, weil auch die Ar­
+ chiv-Task der Stationen sich an das Globalmanagerprotokoll halten.
+
+
+#type("triumb12")#
+Bemerkungen#type("trium8")#
+
+Fehlerbehandlung besteht bis Ebene 3 darin, fehlerhafte Telegramme einfach zu
+entfernen. Die Ebene 4 überwacht den Netzverkehr sowieso über Timeouts, die
+eine Wiederhohlung eines Telegrammes bewirken, wenn die Quittung ausbleibt.
+
+Da bei der sendenden Station der ganze Datenraum zur Verfügung steht, ist eine
+Fenstertechnik (wie bei HDLC) nicht nötig. Es kann zu jedem Zeitpunkt um beliebig
+viele Telegramme zurückgesetzt werden.
+
+Da im EUMEL eine Textdatei ein Datenraum mit sehr komplexer Struktur ist (wegen
+der Insert/Delete-Möglichkeiten, ohne den Rest der Datei zu schieben), ist es ein
+hoher Aufwand, von einem fremden Betriebssytem her Textdateien ins EUMEL-
+Netz zu senden. Für solche Zwecke muß noch eine einfachere Dateistruktur defi­
+niert werden und entsprechende Dateikonverter erstellt werden.
+
+
+
+#type("triumb12")#3. Stand der Netzsoftware #type("trium8")#
+
+Das EUMEL-System wickelt die Prozedur #on("bold")#send#off("bold")# über das Netz ab, wenn die
+Stationsnummer der Zieltask ungleich der eigenen Stationsnummer ist. Umge­
+kehrt kann man der von der Prozedur #on("bold")#wait#off("bold")# gelieferten Absendertask die Absen­
+derstation entnehmen (siehe Prozedur #on("bold")#station#off("bold")# in Abschnitt 3).
+
+Nicht unterstützt wird z.Zt. die Logik der Prozeduren #on("bold")#call#off("bold")# und #on("bold")#pingpong#off("bold")#. Diese
+funktionieren nur in der gewohnten Weise, wenn die Zieltask in #on("bold")#wait#off("bold")# steht. Ist
+die Zieltask länger als ca. 10 Minuten #on("bold")#busy#off("bold")# oder nicht mehr vorhanden, geht die
+Sendung einfach verloren (Gefordert ist: bei #on("bold")#call#off("bold")#: immer wieder versuchen; bei #on("bold")#
+pingpong#off("bold")#: Rückmeldung -2).
+
+Wegen dieser Einschränkung kann man z.B. ein sicheres Drucken von Station a
+auf einen Drucker der Station b nur durch einen eigenen Spoolmanager auf
+Station a verwirklichen. Die Einrichtung eines solchen Managers ist allerdings
+sowieso sinnvoll, damit man
+
+- das normale 'print'-Kommando verwenden kann (statt z.B. save ("xxx",
+4/printer);) und
+- nicht zu warten braucht, bis die Datei übers Netz gesendet ist.
+
+