summaryrefslogtreecommitdiff
path: root/system/net/1.7.5
diff options
context:
space:
mode:
Diffstat (limited to 'system/net/1.7.5')
-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
6 files changed, 2067 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. 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
+ 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.
+
+ 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 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 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 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 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, fhren zu feh-
+ lerhaften Verhalten. Dies liegt daran, daá durch #on("bold")#define station#off("bold")# alle
+ Task-Id's ge„ndert werden mssen, 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 fr 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 fr 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")# 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. 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 berprfen. 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) berprfen 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.
+ š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" verf„lscht.
+
+ - 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 ge„ndert werden, daá sie
+beliebige andere Netzhardware untersttzt. 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 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, m”glichst wenig Unter-
+sttzung 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-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 F„lle 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 n”tig (siehe Systemhandbuch 173, Teil 4,
+Punkt 5). Fr 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 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 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 zurckschickt. 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 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 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”tbrcken)
+
+ 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 mssen an den je-
+ weiligen Boxen ber L”tbrcken 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 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 groáe Stcke zerlegt wird. Es werden nur echt allokierte Seiten
+ bermittelt. Um nicht jedes Telegramm voll qualifizieren zu mssen, 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 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 hochgez„hlt. 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 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 zurcksetzen.
+
+ -3: šbertragung abbrechen.
+
+
+2.5 Vermittlungsebene
+
+ Diese Ebene ist dafr 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 Verfgung steht, ist eine
+Fenstertechnik (wie bei HDLC) nicht n”tig. 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-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. 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 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")#: Rckmeldung -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.
+
+
+
+
+
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 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,
+ 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+". Empf„nger: """
+ +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 ("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.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-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
+ (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 Kommunikationsstr”men *)
+
+ 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 m”glich")
+ 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 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;
+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 gel”scht 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,"empf„ngt 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 Fluákontrolle 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;