From 724cc003460ec67eda269911da85c9f9e40aa6cf Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Fri, 30 Sep 2016 16:57:23 +0200
Subject: Add extracted sources from floppy disk images

Some files have no textual representation (yet) and were added as raw
dataspaces.
---
 at/AT Generator                                    |  135 +
 at/AT Utilities                                    | 1057 ++++++
 at/AT install                                      |   93 +
 basic/BASIC.Administration                         | 1886 +++++++++++
 basic/BASIC.Compiler                               | 2305 +++++++++++++
 basic/BASIC.Runtime                                | 1571 +++++++++
 basic/eumel coder 1.8.1                            | 3086 +++++++++++++++++
 basic/eumel0 codes                                 |  Bin 0 -> 512 bytes
 basic/gen.BASIC                                    |   80 +
 datatype/complex                                   |  115 +
 datatype/longint                                   |  423 +++
 datatype/matrix                                    |  482 +++
 datatype/vector                                    |  213 ++
 dialog/ls-DIALOG 1                                 |   60 +
 dialog/ls-DIALOG 2                                 |   77 +
 dialog/ls-DIALOG 3                                 |   48 +
 dialog/ls-DIALOG 4                                 |   71 +
 dialog/ls-DIALOG 5                                 |  118 +
 dialog/ls-DIALOG 6                                 |  102 +
 dialog/ls-DIALOG 7                                 |   54 +
 dialog/ls-DIALOG MENUKARTEN MANAGER                |   28 +
 dialog/ls-DIALOG MM-gen                            |   27 +
 dialog/ls-DIALOG decompress                        |  150 +
 dialog/ls-DIALOG-gen                               |   34 +
 dialog/ls-MENUKARTE:Archiv                         |  Bin 0 -> 40960 bytes
 doc/basic/basic handbuch.1                         | 1075 ++++++
 doc/basic/basic handbuch.2                         | 2441 ++++++++++++++
 doc/basic/basic handbuch.3                         |  698 ++++
 doc/basic/basic handbuch.index                     |  232 ++
 doc/dialog/gs-dialog handbuch.impressum            |   89 +
 doc/dialog/gs-dialog-1                             |  107 +
 doc/dialog/gs-dialog-2                             |  215 ++
 doc/dialog/gs-dialog-3                             |  683 ++++
 doc/dialog/gs-dialog-4                             |  672 ++++
 doc/dialog/gs-dialog-5                             |  176 +
 doc/dialog/gs-dialog-Inhaltsverzeichnis            |   45 +
 doc/dynamo/dynamo handbuch                         | 1826 ++++++++++
 doc/dynamo/dynamo handbuch.index                   |   69 +
 doc/dynamo/dynamo handbuch.inhalt                  |  131 +
 doc/eudas/abb.1-1                                  |   94 +
 doc/eudas/abb.4-1                                  |   43 +
 doc/eudas/abb.4-2                                  |   46 +
 doc/eudas/abb.6-1                                  |   75 +
 doc/eudas/abb.6-2                                  |   77 +
 doc/eudas/abb.7-1                                  |   46 +
 doc/eudas/abb.9-1                                  |   41 +
 doc/eudas/abb.9-2                                  |   96 +
 doc/eudas/abb.9-3                                  |  113 +
 doc/eudas/abb.9-4                                  |   98 +
 doc/eudas/abb.9-5                                  |   51 +
 doc/eudas/bildergenerator                          |   25 +
 doc/eudas/eudas.hdb.1                              |  267 ++
 doc/eudas/eudas.hdb.10                             |  510 +++
 doc/eudas/eudas.hdb.11                             |  674 ++++
 doc/eudas/eudas.hdb.12                             |  446 +++
 doc/eudas/eudas.hdb.13                             |  757 +++++
 doc/eudas/eudas.hdb.14                             |  724 ++++
 doc/eudas/eudas.hdb.15                             |  286 ++
 doc/eudas/eudas.hdb.16                             |  350 ++
 doc/eudas/eudas.hdb.2                              |  178 +
 doc/eudas/eudas.hdb.3                              |  515 +++
 doc/eudas/eudas.hdb.5                              |  386 +++
 doc/eudas/eudas.hdb.6                              |  394 +++
 doc/eudas/eudas.hdb.7                              |  687 ++++
 doc/eudas/eudas.hdb.8                              |  211 ++
 doc/eudas/eudas.hdb.9                              |  556 ++++
 doc/eudas/eudas.hdb.inhalt                         |  133 +
 doc/eudas/eudas.hdb.macros                         |   80 +
 doc/eudas/eudas.hdb.titel                          |   99 +
 doc/eudas/eudas.hdb.vorwort                        |   89 +
 doc/eudas/eudas.ref.1                              |  326 ++
 doc/eudas/eudas.ref.10                             |  406 +++
 doc/eudas/eudas.ref.11                             |  347 ++
 doc/eudas/eudas.ref.2                              |  830 +++++
 doc/eudas/eudas.ref.3                              |  270 ++
 doc/eudas/eudas.ref.4                              |  441 +++
 doc/eudas/eudas.ref.5                              |  432 +++
 doc/eudas/eudas.ref.6                              |  399 +++
 doc/eudas/eudas.ref.7                              |  447 +++
 doc/eudas/eudas.ref.8                              |  454 +++
 doc/eudas/eudas.ref.9                              |  194 ++
 doc/eudas/eudas.ref.fehler                         |  139 +
 doc/eudas/eudas.ref.inhalt                         |  120 +
 doc/eudas/eudas.ref.macros                         |   73 +
 doc/eudas/eudas.ref.proz                           |  205 ++
 doc/eudas/eudas.ref.reg                            |  436 +++
 doc/eudas/eudas.ref.titel                          |   91 +
 doc/eudas/eudas.ref.vorwort                        |   81 +
 doc/eudas/ref.abb.1-1                              |   42 +
 doc/eudas/register                                 |  490 +++
 doc/eudas/uedas.hdb.4                              |  686 ++++
 doc/graphic/Altes Handbuch - Teil 10 - Graphik     |  831 +++++
 doc/graphic/GRAPHIK.book                           |  897 +++++
 doc/graphic/graphik beschreibung                   |  661 ++++
 ...Doku: gs-Herbert und Robbi - Inhaltsverzeichnis |   45 +
 .../A5 - Doku: gs-Herbert und Robbi - Kapitel 1    |   93 +
 .../A5 - Doku: gs-Herbert und Robbi - Kapitel 2    |  389 +++
 .../A5 - Doku: gs-Herbert und Robbi - Kapitel 3    |  199 ++
 .../A5 - Doku: gs-Herbert und Robbi - Kapitel 4    | 1312 ++++++++
 .../A5 - Doku: gs-Herbert und Robbi - Kapitel 5    |  167 +
 .../A5 - Doku: gs-Herbert und Robbi - Kapitel 6    |   73 +
 .../gs-Herbert und Robbi handbuch.impressum        |   87 +
 doc/lisp/lisp handbuch                             | 2260 +++++++++++++
 doc/menugenerator/menu-generator handbuch.1        |  100 +
 doc/menugenerator/menu-generator handbuch.2        |   87 +
 doc/menugenerator/menu-generator handbuch.3        |  155 +
 doc/menugenerator/menu-generator handbuch.4        |  424 +++
 doc/menugenerator/menu-generator handbuch.5        |  975 ++++++
 doc/menugenerator/menu-generator handbuch.6        |  235 ++
 doc/menugenerator/menu-generator handbuch.7        |  367 +++
 doc/menugenerator/menu-generator handbuch.8        | 1676 ++++++++++
 .../menu-generator handbuch.impressum              |   88 +
 doc/menugenerator/menu-generator handbuch.index    |  258 ++
 doc/menugenerator/menu-generator handbuch.inhalt   |   72 +
 .../A5 - Doku: gs-MP BAP - Inhaltsverzeichnis      |   50 +
 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1        |  119 +
 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2        |  302 ++
 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3        |  237 ++
 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4        |  638 ++++
 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5        |  699 ++++
 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 6        |   53 +
 doc/mp-bap/gs-MP BAP handbuch.impressum            |  104 +
 doc/programming/programmierhandbuch.1              |  650 ++++
 doc/programming/programmierhandbuch.2a             | 1845 +++++++++++
 doc/programming/programmierhandbuch.2b             | 1395 ++++++++
 doc/programming/programmierhandbuch.3              |  728 ++++
 doc/programming/programmierhandbuch.4              | 1692 ++++++++++
 doc/programming/programmierhandbuch.5              | 1329 ++++++++
 doc/programming/programmierhandbuch.5b             | 1481 +++++++++
 doc/programming/programmierhandbuch.6              | 1441 ++++++++
 doc/programming/programmierhandbuch.index          |  449 +++
 doc/programming/programmierhandbuch.inhalt         |  249 ++
 doc/programming/programmierhandbuch.titel          |   52 +
 doc/prolog/prolog handbuch                         |  581 ++++
 doc/prozess/Anhang Prozess                         |   92 +
 doc/prozess/Inhalt Prozess                         |   84 +
 doc/prozess/gs-Prozess handbuch.impressum          |  104 +
 doc/prozess/gs-Prozess-2                           |  255 ++
 doc/prozess/gs-Prozess-3                           |  346 ++
 doc/prozess/gs-Prozess-4                           |  173 +
 doc/prozess/gs-prozess-1                           |   99 +
 doc/prozess/gs-prozess-5                           |  819 +++++
 doc/prozess/gs-prozess-6                           |  641 ++++
 doc/prozess/gs-prozess-7                           | 1121 +++++++
 doc/prozess/gs-prozess-8                           |  377 +++
 doc/prozess/gs-prozess-9                           |  477 +++
 doc/system/systemhandbuch.1                        | 1685 ++++++++++
 doc/system/systemhandbuch.2                        | 1351 ++++++++
 doc/system/systemhandbuch.3                        | 1366 ++++++++
 doc/system/systemhandbuch.4                        | 1185 +++++++
 doc/user/benutzerhandbuch.1                        |  580 ++++
 doc/user/benutzerhandbuch.2                        |  443 +++
 doc/user/benutzerhandbuch.3                        | 2019 ++++++++++++
 doc/user/benutzerhandbuch.4                        | 2242 +++++++++++++
 doc/user/benutzerhandbuch.5a                       | 1446 ++++++++
 doc/user/benutzerhandbuch.5b                       | 1632 +++++++++
 doc/user/benutzerhandbuch.5c                       |  711 ++++
 doc/user/benutzerhandbuch.5d                       |  211 ++
 doc/user/benutzerhandbuch.5e                       |  223 ++
 doc/user/benutzerhandbuch.6                        |  474 +++
 doc/user/benutzerhandbuch.anhang                   |  484 +++
 doc/warenhaus/Anhang Warenhaus                     |   65 +
 doc/warenhaus/Inhalt Warenhaus                     |   50 +
 doc/warenhaus/gs-Warenhaus handbuch.impressum      |   89 +
 doc/warenhaus/gs-Warenhaus-1                       |  124 +
 doc/warenhaus/gs-Warenhaus-2                       |   72 +
 doc/warenhaus/gs-Warenhaus-3                       |  309 ++
 doc/warenhaus/gs-Warenhaus-4                       |  378 +++
 doc/warenhaus/gs-Warenhaus-5                       | 1468 +++++++++
 doc/warenhaus/gs-Warenhaus-6                       |  589 ++++
 doc/warenhaus/gs-Warenhaus-7                       |  235 ++
 dos/block i-o                                      |  180 +
 dos/dir.dos                                        |  693 ++++
 dos/disk descriptor.dos                            |  339 ++
 dos/dos hd inserter                                |   41 +
 dos/dos inserter                                   |   59 +
 dos/dos-dat-handbuch                               |  650 ++++
 dos/dump                                           |   49 +
 dos/eu disk descriptor                             |  107 +
 dos/fat.dos                                        |  369 +++
 dos/fetch                                          |  371 +++
 dos/fetch save interface                           |   70 +
 dos/get put interface.dos                          |  368 +++
 dos/insert.dos                                     |   14 +
 dos/konvert                                        |   75 +
 dos/manager-M.dos                                  |  211 ++
 dos/manager-S.dos                                  |  268 ++
 dos/name conversion.dos                            |   77 +
 dos/open                                           |   66 +
 dos/save                                           |  233 ++
 dos/shard interface                                |   20 +
 dynamo/dyn.33                                      | 2073 ++++++++++++
 dynamo/dyn.abnahme                                 |   19 +
 dynamo/dyn.bev                                     |   50 +
 dynamo/dyn.cob                                     |   19 +
 dynamo/dyn.delaytest                               |    8 +
 dynamo/dyn.errors                                  |   68 +
 dynamo/dyn.forest                                  |   47 +
 dynamo/dyn.forst7                                  |   76 +
 dynamo/dyn.gekoppeltependel                        |   19 +
 dynamo/dyn.grashasenfuchs                          |   42 +
 dynamo/dyn.help                                    |   24 +
 dynamo/dyn.inserter                                |   54 +
 dynamo/dyn.mac                                     |   44 +
 dynamo/dyn.mehreredelays                           |    9 +
 dynamo/dyn.natchez                                 |   14 +
 dynamo/dyn.oszillator                              |   26 +
 dynamo/dyn.plot                                    |  235 ++
 dynamo/dyn.plot+                                   |  729 ++++
 dynamo/dyn.print                                   |   43 +
 dynamo/dyn.proc                                    |  160 +
 dynamo/dyn.quadrat                                 |   13 +
 dynamo/dyn.rts                                     |  376 +++
 dynamo/dyn.ruestungswettlauf                       |   32 +
 dynamo/dyn.simon                                   |   28 +
 dynamo/dyn.std                                     |    9 +
 dynamo/dyn.steifedgl                               |   15 +
 dynamo/dyn.tool                                    |  217 ++
 dynamo/dyn.vec                                     |  209 ++
 dynamo/dyn.wachstum                                |   19 +
 "dynamo/dyn.wasser\303\266ko"                      |   64 +
 dynamo/dyn.welt-forrester                          |  124 +
 dynamo/dyn.wohnen                                  |  105 +
 dynamo/dyn.workfluc                                |   44 +
 dynamo/dyn.wurzel                                  |   14 +
 dynamo/out.world                                   |   43 +
 eudas/Adressen                                     |  Bin 0 -> 3584 bytes
 eudas/dummy.text                                   |   14 +
 eudas/eudas.1                                      |   52 +
 eudas/eudas.2                                      |   62 +
 eudas/eudas.3                                      |   58 +
 eudas/eudas.4                                      |  150 +
 eudas/eudas.generator                              |   86 +
 eudas/eudas.init                                   | 1463 +++++++++
 eudas/pos.173                                      |   19 +
 graphic/Beispiel.Kreuz                             |   41 +
 graphic/Beispiel.Sinus                             |   45 +
 graphic/GRAPHIK.Picfile                            |  738 +++++
 graphic/GRAPHIK.Plot                               |  285 ++
 graphic/GRAPHIK.Plotter                            |  247 ++
 graphic/GRAPHIK.Server                             |   97 +
 graphic/GRAPHIK.Transform                          |  366 +++
 graphic/GRAPHIK.vektor plot                        |  506 +++
 graphic/HP7475.plot                                |  254 ++
 graphic/PC.plot                                    |  758 +++++
 graphic/ZEICHENSATZ                                |  Bin 0 -> 11776 bytes
 graphic/gen Graphik                                |   16 +
 graphic/gen Plotter                                |   16 +
 graphic/graphik editor                             |  324 ++
 hamster/ls-Herbert und Robbi 1                     |   84 +
 hamster/ls-Herbert und Robbi 2                     |   31 +
 hamster/ls-Herbert und Robbi 3                     |   84 +
 hamster/ls-Herbert und Robbi-gen                   |   33 +
 hamster/ls-MENUKARTE:Herbert und Robbi             |  Bin 0 -> 94720 bytes
 lisp/lisp.1                                        | 1306 ++++++++
 lisp/lisp.2                                        |  584 ++++
 lisp/lisp.3                                        |  767 +++++
 lisp/lisp.4                                        |  143 +
 lisp/lisp.bootstrap                                |  118 +
 menugenerator/Generatordatei: Archivmenu           |  323 ++
 menugenerator/fonttab.ls-Menu-Generator            |  Bin 0 -> 2560 bytes
 menugenerator/ls-MENUBASISTEXTE                    |  Bin 0 -> 17408 bytes
 menugenerator/ls-Menu-Generator 1                  |   47 +
 menugenerator/ls-Menu-Generator 2                  |   72 +
 menugenerator/ls-Menu-Generator-gen                |   30 +
 mp-bap/ls-MENUKARTE:MP-BAP                         |  Bin 0 -> 79872 bytes
 mp-bap/ls-MP BAP 1                                 |  119 +
 mp-bap/ls-MP BAP 2                                 |  126 +
 mp-bap/ls-MP BAP-gen                               |   30 +
 net/basic net                                      | 1148 +++++++
 net/net files-M                                    |    5 +
 net/net hardware interface                         |  389 +++
 net/net inserter                                   |  145 +
 net/net manager                                    |  797 +++++
 net/net report                                     |   41 +
 net/netz                                           |   20 +
 net/netzhandbuch                                   | 2045 ++++++++++++
 net/netzhandbuch.anhang                            |   58 +
 net/netzhandbuch.index                             |  259 ++
 net/port server                                    |  164 +
 net/printer server                                 |   99 +
 net/spool cmd                                      |  112 +
 net/spool manager                                  |  915 ++++++
 printer/dotmatrix24/beschreibungen24               |   62 +
 printer/dotmatrix24/fonttab.brother                |  Bin 0 -> 38400 bytes
 printer/dotmatrix24/fonttab.epson.lq1500           |  Bin 0 -> 35840 bytes
 printer/dotmatrix24/fonttab.epson.lq850            |  Bin 0 -> 38400 bytes
 printer/dotmatrix24/fonttab.nec.p5                 |  Bin 0 -> 39936 bytes
 printer/dotmatrix24/fonttab.nec.p5.new             |  Bin 0 -> 39936 bytes
 printer/dotmatrix24/fonttab.nec.p6+                |  Bin 0 -> 48128 bytes
 printer/dotmatrix24/fonttab.oki                    |  Bin 0 -> 38400 bytes
 printer/dotmatrix24/fonttab.toshiba.p321           |  Bin 0 -> 15872 bytes
 printer/dotmatrix24/inserter                       |  793 +++++
 printer/dotmatrix24/module24                       | 1554 +++++++++
 printer/dotmatrix24/printer.24.nadel               |  776 +++++
 printer/dotmatrix24/readme                         |  320 ++
 printer/dotmatrix9/beschreibungen9                 |   97 +
 printer/dotmatrix9/fonttab.1                       |  Bin 0 -> 11264 bytes
 printer/dotmatrix9/fonttab.10                      |  Bin 0 -> 15872 bytes
 printer/dotmatrix9/fonttab.20                      |  Bin 0 -> 36864 bytes
 printer/dotmatrix9/fonttab.20.lc                   |  Bin 0 -> 36864 bytes
 printer/dotmatrix9/fonttab.20.lx                   |  Bin 0 -> 24576 bytes
 printer/dotmatrix9/fonttab.7                       |  Bin 0 -> 46080 bytes
 printer/dotmatrix9/fonttab.7.cxp                   |  Bin 0 -> 46080 bytes
 printer/dotmatrix9/fonttab.7.fuj                   |  Bin 0 -> 56832 bytes
 printer/dotmatrix9/fonttab.7.mt                    |  Bin 0 -> 46080 bytes
 printer/dotmatrix9/module9                         | 1099 +++++++
 printer/dotmatrix9/printer.neun.nadel              | 1129 +++++++
 printer/dotmatrix9/readme                          |  324 ++
 printer/laser/fonttab.apple.laserwriter            |  Bin 0 -> 100864 bytes
 printer/laser/fonttab.canon.lbp-8                  |  Bin 0 -> 58368 bytes
 printer/laser/fonttab.epson.sq                     |  Bin 0 -> 29696 bytes
 printer/laser/fonttab.hp.laserjet                  |  Bin 0 -> 24064 bytes
 printer/laser/fonttab.kyocera.f-1010               |  Bin 0 -> 71168 bytes
 printer/laser/fonttab.nec.lc-08                    |  Bin 0 -> 38400 bytes
 printer/laser/genfont.kyocera.f-1010.dynamic1      |   30 +
 printer/laser/genfont.kyocera.f-1010.dynamic2      |   30 +
 printer/laser/laser.inserter                       |  275 ++
 printer/laser/printer.apple.laserwriter            |  770 +++++
 printer/laser/printer.canon.lbp-8                  |  327 ++
 printer/laser/printer.epson.sq                     |  585 ++++
 printer/laser/printer.hp.laserjet                  |  417 +++
 printer/laser/printer.kyocera.f-1010               |  373 +++
 printer/laser/printer.nec.lc-08                    |  626 ++++
 printer/laser/readme                               |  155 +
 prolog/calc                                        |   32 +
 prolog/family                                      |   29 +
 prolog/permute                                     |   15 +
 prolog/prieks                                      |   58 +
 prolog/prolog                                      | 2488 ++++++++++++++
 prolog/prolog installation                         |  117 +
 prolog/puzzle                                      |   24 +
 prolog/quicksort                                   |   14 +
 prolog/standard                                    |   35 +
 prolog/sum                                         |   13 +
 prolog/thesaurus                                   |  360 ++
 prolog/topographie                                 |   59 +
 prozess/ls-MENUKARTE:Prozess                       |  Bin 0 -> 62464 bytes
 "prozess/ls-Prozess 1 f\303\274r AKTRONIC-Adapter" |   57 +
 ...-Prozess 1 f\303\274r MUFI als Endger\303\244t" |   57 +
 .../ls-Prozess 1 f\303\274r MUFI im Terminalkanal" |   55 +
 prozess/ls-Prozess 2                               |   39 +
 prozess/ls-Prozess 3                               |   26 +
 prozess/ls-Prozess 4                               |   61 +
 prozess/ls-Prozess 5                               |   84 +
 prozess/ls-Prozess-gen                             |  146 +
 system/crypt                                       |  138 +
 system/eumel printer.5                             | 3473 ++++++++++++++++++++
 system/eumelmeter                                  |  131 +
 system/font convertor 9                            | 1095 ++++++
 system/free channel                                |  430 +++
 system/port server                                 |  164 +
 system/printer server                              |   99 +
 system/purge                                       |   85 +
 system/referencer                                  | 1077 ++++++
 system/reporter                                    |  531 +++
 system/scheduler                                   |  420 +++
 system/spool cmd                                   |  178 +
 system/spool manager                               | 1058 ++++++
 system/std analysator                              |   68 +
 tecal/TeCal                                        |  856 +++++
 tecal/TeCal Auskunft                               |  Bin 0 -> 45056 bytes
 tecal/TeCal.gen                                    |   55 +
 warenhaus/ls-MENUKARTE:Warenhaus                   |  Bin 0 -> 60928 bytes
 ...arenhaus 0: mit Kartenleser an AKTRONIC-Adapter |   36 +
 ...0: mit Kartenleser an MUFI als Endger\303\244t" |   36 +
 ...aus 0: mit Kartenleser an MUFI im Terminalkanal |   30 +
 warenhaus/ls-Warenhaus 0: ohne Kartenleser         |   27 +
 warenhaus/ls-Warenhaus 1                           |   37 +
 warenhaus/ls-Warenhaus 2                           |  112 +
 warenhaus/ls-Warenhaus 3                           |   82 +
 warenhaus/ls-Warenhaus 4                           |   48 +
 warenhaus/ls-Warenhaus 5                           |  103 +
 warenhaus/ls-Warenhaus-gen                         |   29 +
 374 files changed, 134225 insertions(+)
 create mode 100644 at/AT Generator
 create mode 100644 at/AT Utilities
 create mode 100644 at/AT install
 create mode 100644 basic/BASIC.Administration
 create mode 100644 basic/BASIC.Compiler
 create mode 100644 basic/BASIC.Runtime
 create mode 100644 basic/eumel coder 1.8.1
 create mode 100644 basic/eumel0 codes
 create mode 100644 basic/gen.BASIC
 create mode 100644 datatype/complex
 create mode 100644 datatype/longint
 create mode 100644 datatype/matrix
 create mode 100644 datatype/vector
 create mode 100644 dialog/ls-DIALOG 1
 create mode 100644 dialog/ls-DIALOG 2
 create mode 100644 dialog/ls-DIALOG 3
 create mode 100644 dialog/ls-DIALOG 4
 create mode 100644 dialog/ls-DIALOG 5
 create mode 100644 dialog/ls-DIALOG 6
 create mode 100644 dialog/ls-DIALOG 7
 create mode 100644 dialog/ls-DIALOG MENUKARTEN MANAGER
 create mode 100644 dialog/ls-DIALOG MM-gen
 create mode 100644 dialog/ls-DIALOG decompress
 create mode 100644 dialog/ls-DIALOG-gen
 create mode 100644 dialog/ls-MENUKARTE:Archiv
 create mode 100644 doc/basic/basic handbuch.1
 create mode 100644 doc/basic/basic handbuch.2
 create mode 100644 doc/basic/basic handbuch.3
 create mode 100644 doc/basic/basic handbuch.index
 create mode 100644 doc/dialog/gs-dialog handbuch.impressum
 create mode 100644 doc/dialog/gs-dialog-1
 create mode 100644 doc/dialog/gs-dialog-2
 create mode 100644 doc/dialog/gs-dialog-3
 create mode 100644 doc/dialog/gs-dialog-4
 create mode 100644 doc/dialog/gs-dialog-5
 create mode 100644 doc/dialog/gs-dialog-Inhaltsverzeichnis
 create mode 100644 doc/dynamo/dynamo handbuch
 create mode 100644 doc/dynamo/dynamo handbuch.index
 create mode 100644 doc/dynamo/dynamo handbuch.inhalt
 create mode 100644 doc/eudas/abb.1-1
 create mode 100644 doc/eudas/abb.4-1
 create mode 100644 doc/eudas/abb.4-2
 create mode 100644 doc/eudas/abb.6-1
 create mode 100644 doc/eudas/abb.6-2
 create mode 100644 doc/eudas/abb.7-1
 create mode 100644 doc/eudas/abb.9-1
 create mode 100644 doc/eudas/abb.9-2
 create mode 100644 doc/eudas/abb.9-3
 create mode 100644 doc/eudas/abb.9-4
 create mode 100644 doc/eudas/abb.9-5
 create mode 100644 doc/eudas/bildergenerator
 create mode 100644 doc/eudas/eudas.hdb.1
 create mode 100644 doc/eudas/eudas.hdb.10
 create mode 100644 doc/eudas/eudas.hdb.11
 create mode 100644 doc/eudas/eudas.hdb.12
 create mode 100644 doc/eudas/eudas.hdb.13
 create mode 100644 doc/eudas/eudas.hdb.14
 create mode 100644 doc/eudas/eudas.hdb.15
 create mode 100644 doc/eudas/eudas.hdb.16
 create mode 100644 doc/eudas/eudas.hdb.2
 create mode 100644 doc/eudas/eudas.hdb.3
 create mode 100644 doc/eudas/eudas.hdb.5
 create mode 100644 doc/eudas/eudas.hdb.6
 create mode 100644 doc/eudas/eudas.hdb.7
 create mode 100644 doc/eudas/eudas.hdb.8
 create mode 100644 doc/eudas/eudas.hdb.9
 create mode 100644 doc/eudas/eudas.hdb.inhalt
 create mode 100644 doc/eudas/eudas.hdb.macros
 create mode 100644 doc/eudas/eudas.hdb.titel
 create mode 100644 doc/eudas/eudas.hdb.vorwort
 create mode 100644 doc/eudas/eudas.ref.1
 create mode 100644 doc/eudas/eudas.ref.10
 create mode 100644 doc/eudas/eudas.ref.11
 create mode 100644 doc/eudas/eudas.ref.2
 create mode 100644 doc/eudas/eudas.ref.3
 create mode 100644 doc/eudas/eudas.ref.4
 create mode 100644 doc/eudas/eudas.ref.5
 create mode 100644 doc/eudas/eudas.ref.6
 create mode 100644 doc/eudas/eudas.ref.7
 create mode 100644 doc/eudas/eudas.ref.8
 create mode 100644 doc/eudas/eudas.ref.9
 create mode 100644 doc/eudas/eudas.ref.fehler
 create mode 100644 doc/eudas/eudas.ref.inhalt
 create mode 100644 doc/eudas/eudas.ref.macros
 create mode 100644 doc/eudas/eudas.ref.proz
 create mode 100644 doc/eudas/eudas.ref.reg
 create mode 100644 doc/eudas/eudas.ref.titel
 create mode 100644 doc/eudas/eudas.ref.vorwort
 create mode 100644 doc/eudas/ref.abb.1-1
 create mode 100644 doc/eudas/register
 create mode 100644 doc/eudas/uedas.hdb.4
 create mode 100644 doc/graphic/Altes Handbuch - Teil 10 - Graphik
 create mode 100644 doc/graphic/GRAPHIK.book
 create mode 100644 doc/graphic/graphik beschreibung
 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Inhaltsverzeichnis
 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 1
 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 2
 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 3
 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 4
 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 5
 create mode 100644 doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 6
 create mode 100644 doc/hamster/gs-Herbert und Robbi handbuch.impressum
 create mode 100644 doc/lisp/lisp handbuch
 create mode 100644 doc/menugenerator/menu-generator handbuch.1
 create mode 100644 doc/menugenerator/menu-generator handbuch.2
 create mode 100644 doc/menugenerator/menu-generator handbuch.3
 create mode 100644 doc/menugenerator/menu-generator handbuch.4
 create mode 100644 doc/menugenerator/menu-generator handbuch.5
 create mode 100644 doc/menugenerator/menu-generator handbuch.6
 create mode 100644 doc/menugenerator/menu-generator handbuch.7
 create mode 100644 doc/menugenerator/menu-generator handbuch.8
 create mode 100644 doc/menugenerator/menu-generator handbuch.impressum
 create mode 100644 doc/menugenerator/menu-generator handbuch.index
 create mode 100644 doc/menugenerator/menu-generator handbuch.inhalt
 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Inhaltsverzeichnis
 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1
 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2
 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3
 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4
 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5
 create mode 100644 doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 6
 create mode 100644 doc/mp-bap/gs-MP BAP handbuch.impressum
 create mode 100644 doc/programming/programmierhandbuch.1
 create mode 100644 doc/programming/programmierhandbuch.2a
 create mode 100644 doc/programming/programmierhandbuch.2b
 create mode 100644 doc/programming/programmierhandbuch.3
 create mode 100644 doc/programming/programmierhandbuch.4
 create mode 100644 doc/programming/programmierhandbuch.5
 create mode 100644 doc/programming/programmierhandbuch.5b
 create mode 100644 doc/programming/programmierhandbuch.6
 create mode 100644 doc/programming/programmierhandbuch.index
 create mode 100644 doc/programming/programmierhandbuch.inhalt
 create mode 100644 doc/programming/programmierhandbuch.titel
 create mode 100644 doc/prolog/prolog handbuch
 create mode 100644 doc/prozess/Anhang Prozess
 create mode 100644 doc/prozess/Inhalt Prozess
 create mode 100644 doc/prozess/gs-Prozess handbuch.impressum
 create mode 100644 doc/prozess/gs-Prozess-2
 create mode 100644 doc/prozess/gs-Prozess-3
 create mode 100644 doc/prozess/gs-Prozess-4
 create mode 100644 doc/prozess/gs-prozess-1
 create mode 100644 doc/prozess/gs-prozess-5
 create mode 100644 doc/prozess/gs-prozess-6
 create mode 100644 doc/prozess/gs-prozess-7
 create mode 100644 doc/prozess/gs-prozess-8
 create mode 100644 doc/prozess/gs-prozess-9
 create mode 100644 doc/system/systemhandbuch.1
 create mode 100644 doc/system/systemhandbuch.2
 create mode 100644 doc/system/systemhandbuch.3
 create mode 100644 doc/system/systemhandbuch.4
 create mode 100644 doc/user/benutzerhandbuch.1
 create mode 100644 doc/user/benutzerhandbuch.2
 create mode 100644 doc/user/benutzerhandbuch.3
 create mode 100644 doc/user/benutzerhandbuch.4
 create mode 100644 doc/user/benutzerhandbuch.5a
 create mode 100644 doc/user/benutzerhandbuch.5b
 create mode 100644 doc/user/benutzerhandbuch.5c
 create mode 100644 doc/user/benutzerhandbuch.5d
 create mode 100644 doc/user/benutzerhandbuch.5e
 create mode 100644 doc/user/benutzerhandbuch.6
 create mode 100644 doc/user/benutzerhandbuch.anhang
 create mode 100644 doc/warenhaus/Anhang Warenhaus
 create mode 100644 doc/warenhaus/Inhalt Warenhaus
 create mode 100644 doc/warenhaus/gs-Warenhaus handbuch.impressum
 create mode 100644 doc/warenhaus/gs-Warenhaus-1
 create mode 100644 doc/warenhaus/gs-Warenhaus-2
 create mode 100644 doc/warenhaus/gs-Warenhaus-3
 create mode 100644 doc/warenhaus/gs-Warenhaus-4
 create mode 100644 doc/warenhaus/gs-Warenhaus-5
 create mode 100644 doc/warenhaus/gs-Warenhaus-6
 create mode 100644 doc/warenhaus/gs-Warenhaus-7
 create mode 100644 dos/block i-o
 create mode 100644 dos/dir.dos
 create mode 100644 dos/disk descriptor.dos
 create mode 100644 dos/dos hd inserter
 create mode 100644 dos/dos inserter
 create mode 100644 dos/dos-dat-handbuch
 create mode 100644 dos/dump
 create mode 100644 dos/eu disk descriptor
 create mode 100644 dos/fat.dos
 create mode 100644 dos/fetch
 create mode 100644 dos/fetch save interface
 create mode 100644 dos/get put interface.dos
 create mode 100644 dos/insert.dos
 create mode 100644 dos/konvert
 create mode 100644 dos/manager-M.dos
 create mode 100644 dos/manager-S.dos
 create mode 100644 dos/name conversion.dos
 create mode 100644 dos/open
 create mode 100644 dos/save
 create mode 100644 dos/shard interface
 create mode 100644 dynamo/dyn.33
 create mode 100644 dynamo/dyn.abnahme
 create mode 100644 dynamo/dyn.bev
 create mode 100644 dynamo/dyn.cob
 create mode 100644 dynamo/dyn.delaytest
 create mode 100644 dynamo/dyn.errors
 create mode 100644 dynamo/dyn.forest
 create mode 100644 dynamo/dyn.forst7
 create mode 100644 dynamo/dyn.gekoppeltependel
 create mode 100644 dynamo/dyn.grashasenfuchs
 create mode 100644 dynamo/dyn.help
 create mode 100644 dynamo/dyn.inserter
 create mode 100644 dynamo/dyn.mac
 create mode 100644 dynamo/dyn.mehreredelays
 create mode 100644 dynamo/dyn.natchez
 create mode 100644 dynamo/dyn.oszillator
 create mode 100644 dynamo/dyn.plot
 create mode 100644 dynamo/dyn.plot+
 create mode 100644 dynamo/dyn.print
 create mode 100644 dynamo/dyn.proc
 create mode 100644 dynamo/dyn.quadrat
 create mode 100644 dynamo/dyn.rts
 create mode 100644 dynamo/dyn.ruestungswettlauf
 create mode 100644 dynamo/dyn.simon
 create mode 100644 dynamo/dyn.std
 create mode 100644 dynamo/dyn.steifedgl
 create mode 100644 dynamo/dyn.tool
 create mode 100644 dynamo/dyn.vec
 create mode 100644 dynamo/dyn.wachstum
 create mode 100644 "dynamo/dyn.wasser\303\266ko"
 create mode 100644 dynamo/dyn.welt-forrester
 create mode 100644 dynamo/dyn.wohnen
 create mode 100644 dynamo/dyn.workfluc
 create mode 100644 dynamo/dyn.wurzel
 create mode 100644 dynamo/out.world
 create mode 100644 eudas/Adressen
 create mode 100644 eudas/dummy.text
 create mode 100644 eudas/eudas.1
 create mode 100644 eudas/eudas.2
 create mode 100644 eudas/eudas.3
 create mode 100644 eudas/eudas.4
 create mode 100644 eudas/eudas.generator
 create mode 100644 eudas/eudas.init
 create mode 100644 eudas/pos.173
 create mode 100644 graphic/Beispiel.Kreuz
 create mode 100644 graphic/Beispiel.Sinus
 create mode 100644 graphic/GRAPHIK.Picfile
 create mode 100644 graphic/GRAPHIK.Plot
 create mode 100644 graphic/GRAPHIK.Plotter
 create mode 100644 graphic/GRAPHIK.Server
 create mode 100644 graphic/GRAPHIK.Transform
 create mode 100644 graphic/GRAPHIK.vektor plot
 create mode 100644 graphic/HP7475.plot
 create mode 100644 graphic/PC.plot
 create mode 100644 graphic/ZEICHENSATZ
 create mode 100644 graphic/gen Graphik
 create mode 100644 graphic/gen Plotter
 create mode 100644 graphic/graphik editor
 create mode 100644 hamster/ls-Herbert und Robbi 1
 create mode 100644 hamster/ls-Herbert und Robbi 2
 create mode 100644 hamster/ls-Herbert und Robbi 3
 create mode 100644 hamster/ls-Herbert und Robbi-gen
 create mode 100644 hamster/ls-MENUKARTE:Herbert und Robbi
 create mode 100644 lisp/lisp.1
 create mode 100644 lisp/lisp.2
 create mode 100644 lisp/lisp.3
 create mode 100644 lisp/lisp.4
 create mode 100644 lisp/lisp.bootstrap
 create mode 100644 menugenerator/Generatordatei: Archivmenu
 create mode 100644 menugenerator/fonttab.ls-Menu-Generator
 create mode 100644 menugenerator/ls-MENUBASISTEXTE
 create mode 100644 menugenerator/ls-Menu-Generator 1
 create mode 100644 menugenerator/ls-Menu-Generator 2
 create mode 100644 menugenerator/ls-Menu-Generator-gen
 create mode 100644 mp-bap/ls-MENUKARTE:MP-BAP
 create mode 100644 mp-bap/ls-MP BAP 1
 create mode 100644 mp-bap/ls-MP BAP 2
 create mode 100644 mp-bap/ls-MP BAP-gen
 create mode 100644 net/basic net
 create mode 100644 net/net files-M
 create mode 100644 net/net hardware interface
 create mode 100644 net/net inserter
 create mode 100644 net/net manager
 create mode 100644 net/net report
 create mode 100644 net/netz
 create mode 100644 net/netzhandbuch
 create mode 100644 net/netzhandbuch.anhang
 create mode 100644 net/netzhandbuch.index
 create mode 100644 net/port server
 create mode 100644 net/printer server
 create mode 100644 net/spool cmd
 create mode 100644 net/spool manager
 create mode 100644 printer/dotmatrix24/beschreibungen24
 create mode 100644 printer/dotmatrix24/fonttab.brother
 create mode 100644 printer/dotmatrix24/fonttab.epson.lq1500
 create mode 100644 printer/dotmatrix24/fonttab.epson.lq850
 create mode 100644 printer/dotmatrix24/fonttab.nec.p5
 create mode 100644 printer/dotmatrix24/fonttab.nec.p5.new
 create mode 100644 printer/dotmatrix24/fonttab.nec.p6+
 create mode 100644 printer/dotmatrix24/fonttab.oki
 create mode 100644 printer/dotmatrix24/fonttab.toshiba.p321
 create mode 100644 printer/dotmatrix24/inserter
 create mode 100644 printer/dotmatrix24/module24
 create mode 100644 printer/dotmatrix24/printer.24.nadel
 create mode 100644 printer/dotmatrix24/readme
 create mode 100644 printer/dotmatrix9/beschreibungen9
 create mode 100644 printer/dotmatrix9/fonttab.1
 create mode 100644 printer/dotmatrix9/fonttab.10
 create mode 100644 printer/dotmatrix9/fonttab.20
 create mode 100644 printer/dotmatrix9/fonttab.20.lc
 create mode 100644 printer/dotmatrix9/fonttab.20.lx
 create mode 100644 printer/dotmatrix9/fonttab.7
 create mode 100644 printer/dotmatrix9/fonttab.7.cxp
 create mode 100644 printer/dotmatrix9/fonttab.7.fuj
 create mode 100644 printer/dotmatrix9/fonttab.7.mt
 create mode 100644 printer/dotmatrix9/module9
 create mode 100644 printer/dotmatrix9/printer.neun.nadel
 create mode 100644 printer/dotmatrix9/readme
 create mode 100644 printer/laser/fonttab.apple.laserwriter
 create mode 100644 printer/laser/fonttab.canon.lbp-8
 create mode 100644 printer/laser/fonttab.epson.sq
 create mode 100644 printer/laser/fonttab.hp.laserjet
 create mode 100644 printer/laser/fonttab.kyocera.f-1010
 create mode 100644 printer/laser/fonttab.nec.lc-08
 create mode 100644 printer/laser/genfont.kyocera.f-1010.dynamic1
 create mode 100644 printer/laser/genfont.kyocera.f-1010.dynamic2
 create mode 100644 printer/laser/laser.inserter
 create mode 100644 printer/laser/printer.apple.laserwriter
 create mode 100644 printer/laser/printer.canon.lbp-8
 create mode 100644 printer/laser/printer.epson.sq
 create mode 100644 printer/laser/printer.hp.laserjet
 create mode 100644 printer/laser/printer.kyocera.f-1010
 create mode 100644 printer/laser/printer.nec.lc-08
 create mode 100644 printer/laser/readme
 create mode 100644 prolog/calc
 create mode 100644 prolog/family
 create mode 100644 prolog/permute
 create mode 100644 prolog/prieks
 create mode 100644 prolog/prolog
 create mode 100644 prolog/prolog installation
 create mode 100644 prolog/puzzle
 create mode 100644 prolog/quicksort
 create mode 100644 prolog/standard
 create mode 100644 prolog/sum
 create mode 100644 prolog/thesaurus
 create mode 100644 prolog/topographie
 create mode 100644 prozess/ls-MENUKARTE:Prozess
 create mode 100644 "prozess/ls-Prozess 1 f\303\274r AKTRONIC-Adapter"
 create mode 100644 "prozess/ls-Prozess 1 f\303\274r MUFI als Endger\303\244t"
 create mode 100644 "prozess/ls-Prozess 1 f\303\274r MUFI im Terminalkanal"
 create mode 100644 prozess/ls-Prozess 2
 create mode 100644 prozess/ls-Prozess 3
 create mode 100644 prozess/ls-Prozess 4
 create mode 100644 prozess/ls-Prozess 5
 create mode 100644 prozess/ls-Prozess-gen
 create mode 100644 system/crypt
 create mode 100644 system/eumel printer.5
 create mode 100644 system/eumelmeter
 create mode 100644 system/font convertor 9
 create mode 100644 system/free channel
 create mode 100644 system/port server
 create mode 100644 system/printer server
 create mode 100644 system/purge
 create mode 100644 system/referencer
 create mode 100644 system/reporter
 create mode 100644 system/scheduler
 create mode 100644 system/spool cmd
 create mode 100644 system/spool manager
 create mode 100644 system/std analysator
 create mode 100644 tecal/TeCal
 create mode 100644 tecal/TeCal Auskunft
 create mode 100644 tecal/TeCal.gen
 create mode 100644 warenhaus/ls-MENUKARTE:Warenhaus
 create mode 100644 warenhaus/ls-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter
 create mode 100644 "warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endger\303\244t"
 create mode 100644 warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal
 create mode 100644 warenhaus/ls-Warenhaus 0: ohne Kartenleser
 create mode 100644 warenhaus/ls-Warenhaus 1
 create mode 100644 warenhaus/ls-Warenhaus 2
 create mode 100644 warenhaus/ls-Warenhaus 3
 create mode 100644 warenhaus/ls-Warenhaus 4
 create mode 100644 warenhaus/ls-Warenhaus 5
 create mode 100644 warenhaus/ls-Warenhaus-gen

diff --git a/at/AT Generator b/at/AT Generator
new file mode 100644
index 0000000..d3bfd6d
--- /dev/null
+++ b/at/AT Generator	
@@ -0,0 +1,135 @@
+(*************************************************************************)
+(*** Generiert Für IBM-AT einen neuen SYSUR-Zweig.                     ***)
+(*** Danach wird die eingebaute Hardwareuhr für die Systemzeit benutzt ***)
+(*** und andere Partitionen können mit neuem 'shutup' gebootet werden. ***)
+(***                                                                   ***)
+(*** Autor : W. Sauerwein                             Stand : 15.07.86 ***)
+(*************************************************************************)
+
+LET ack = 0,
+    nak = 1;
+ 
+cl eop (1, 4);
+erzeuge collector;
+erzeuge archive manager;
+erzeuge operator;
+erzeuge configurator;
+loesche collector;
+forget ("AT Generator", quiet);
+break.
+
+loesche collector :
+   end (/"colly");
+   put ("Collector gelöscht.");
+   line (2).
+
+erzeuge collector :
+   put line ("Generating 'Collector'...");
+   begin ("colly", PROC generate collector, t);
+   warte auf meldung;
+   IF answer = nak THEN end (/"colly");
+                        errorstop (meldung)
+   FI.
+   TASK VAR t.
+
+erzeuge archive manager :
+   put line ("Generating 'ARCHIVE'...");
+   end (/"ARCHIVE");
+   begin ("ARCHIVE", PROC archive manager, t).
+
+erzeuge operator :
+   put line ("Generating 'OPERATOR'...");
+   end (/"OPERATOR");
+   begin ("OPERATOR", PROC monitor, t).
+ 
+erzeuge configurator :
+   put line ("Generating 'configurator'...");
+   end (/"configurator");
+   begin ("configurator", PROC generate configurator, t); 
+   warte auf meldung;
+   IF answer = nak THEN errorstop (meldung) FI.
+ 
+warte auf meldung : 
+   DATASPACE VAR ds; INT VAR answer; 
+   wait (ds, answer, t);
+   BOUND TEXT VAR m := ds;
+   TEXT VAR meldung := m;
+   forget (ds).
+ 
+PROC generate collector :
+
+   disable stop;
+   fetch all (/"configurator");
+   DATASPACE VAR ds := nilspace;
+   BOUND TEXT VAR m := ds; m := "";
+   send (father, mess, ds);
+   forget (ds);
+   free global manager.
+ 
+mess : IF is error THEN m := error message;
+                        nak
+                   ELSE ack FI.
+
+END PROC generate collector;
+
+PROC generate configurator :
+
+   disable stop;
+   fetch all (/"colly");
+   DATASPACE VAR ds := nilspace; 
+   BOUND TEXT VAR m := ds; m := "";
+   send (father, mess, ds);
+   forget (ds);
+   enable stop;
+   new configuration;
+   setup;
+   global manager (PROC ( DATASPACE VAR, INT CONST, INT CONST, TASK CONST) 
+                   configuration manager with time).
+
+mess : IF is error THEN m := error message;
+                        nak
+                   ELSE ack FI.
+
+END PROC generate configurator;
+
+TEXT PROC inverse (TEXT CONST t):
+  ""15"" + t + " " + ""14""
+END PROC inverse;
+
+PROC put center (TEXT CONST t):
+   put center (t, 80)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t):
+   put center (zeile, t, 80)
+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; 
+
diff --git a/at/AT Utilities b/at/AT Utilities
new file mode 100644
index 0000000..760e728
--- /dev/null
+++ b/at/AT Utilities	
@@ -0,0 +1,1057 @@
+(*************************************************************************)
+(*** AT-spezifische Software, die zum Lesen der Hardwareuhr und        ***)
+(*** Booten in anderen Partitionen benötigt wird.                      ***)
+(***                                                                   ***)
+(*** Zusammengestellt und geändert : Werner Sauerwein, GMD             ***)
+(***                         Stand : 31.10.86                          ***)
+(*************************************************************************)
+
+PACKET splitting DEFINES  low byte,     (* Copyright (C) 1985       *)
+                          high byte,    (* Martin Schönbeck, Spenge *)
+                          low word,     (* Stand: 13.09.85          *)
+                          high word: 
+ 
+INT PROC high byte (INT CONST value):
+ 
+    TEXT VAR x := "  ";
+    replace (x, 1, value);
+    code (x SUB 2)
+
+END PROC high byte;
+
+INT PROC low byte (INT CONST value):
+ 
+    TEXT VAR x := "  ";
+    replace (x, 1, value);
+    code (x SUB 1)
+
+END PROC low byte; 
+ 
+INT PROC high word (REAL CONST double precission int):
+
+    int (double precission int / 65536.0)
+
+END PROC high word;
+
+INT PROC low word (REAL CONST double precission int): 
+ 
+    string of low bytes ISUB 1.
+
+string of low bytes:
+    code (int (double precission int MOD 256.0)) +
+    code (int ((double precission int MOD 65536.0) / 256.0)). 
+ 
+END PROC low word; 
+
+END PACKET splitting;
+
+
+PACKET basic block io DEFINES
+ 
+  read block,
+  write block:
+
+PROC read block (DATASPACE VAR ds,
+                 INT CONST ds page no, 
+                 INT CONST block no,
+                 INT VAR return code):
+  read block; 
+  retry if read error.
+ 
+read block: 
+  block in (ds, ds page no, 0, block no, return code).
+ 
+retry if read error: 
+  INT VAR retry;
+  FOR retry FROM 1 UPTO 10 WHILE return code = 2 REP 
+    reset to block 0 if fifth try; 
+    read block 
+  PER. 
+ 
+reset to block 0 if fifth try: 
+  IF retry = 5 
+    THEN block in (ds, ds page no, 0, 0, return code) 
+  FI. 
+ 
+END PROC read block;
+ 
+PROC write block (DATASPACE CONST ds,
+                 INT CONST ds page no, 
+                 INT CONST block no,
+                 INT VAR return code):
+  write block; 
+  retry if write error. 
+ 
+write block: 
+  block out (ds, ds page no, 0, block no, return code).
+ 
+retry if write error: 
+  INT VAR retry;
+  FOR retry FROM 1 UPTO 10 WHILE return code = 2 REP 
+    reset to block 0 if fifth try; 
+    write block 
+  PER. 
+ 
+reset to block 0 if fifth try: 
+  IF retry = 5 
+    THEN disable stop;
+         DATASPACE VAR dummy ds := nilspace;
+         block in (dummy ds, 2, 0, 0, return code);
+         forget (dummy ds);
+         enable stop
+  FI. 
+ 
+END PROC write block; 
+
+PROC read block (DATASPACE VAR ds, INT CONST ds page,
+                 REAL CONST archive block):
+
+   enable stop;
+   read block (ds, ds page, archive block, error);
+   INT VAR error;
+   SELECT error OF
+      CASE 0:
+      CASE 1: error stop ("Platte kann nicht gelesen werden");
+      CASE 2: error stop ("Lesefehler bei Block "+ text (archive block));
+      CASE 3: error stop ("Versorgungsfehler Archiv");
+      OTHERWISE error stop ("unbekannter Fehler auf Platte");
+   END SELECT;
+
+END PROC read block;
+
+PROC write block (DATASPACE CONST ds, INT CONST ds page,
+                  REAL CONST archive block):
+
+   enable stop;
+   write block (ds, ds page, archive block, error);
+   INT VAR error;
+   SELECT error OF
+      CASE 0:
+      CASE 1: error stop ("Platte kann nicht geschrieben werden");
+      CASE 2: error stop ("Schreibfehler bei Block "+ text (archive block));
+      CASE 3: error stop ("Versorgungsfehler Archiv");
+      OTHERWISE error stop ("unbekannter Fehler auf Platte");
+   END SELECT;
+
+END PROC write block;
+
+PROC read block (DATASPACE VAR ds,
+                 INT CONST ds page no, 
+                 REAL CONST block no,
+                 INT VAR return code):
+  read block; 
+  retry if read error.
+ 
+read block: 
+  block in (ds, ds page no, high word (block no),
+                             low word (block no), return code).
+ 
+retry if read error: 
+  INT VAR retry;
+  FOR retry FROM 1 UPTO 10 WHILE return code = 2 REP 
+    reset to block 0 if fifth try; 
+    read block 
+  PER. 
+ 
+reset to block 0 if fifth try: 
+  IF retry = 5 
+    THEN block in (ds, ds page no, 0, 0, return code) 
+  FI. 
+ 
+END PROC read block;
+ 
+PROC write block (DATASPACE CONST ds,
+                 INT CONST ds page no, 
+                 REAL CONST block no,
+                 INT VAR return code):
+  write block; 
+  retry if write error. 
+ 
+write block: 
+  block out (ds, ds page no, high word (block no),
+                              low word (block no), return code).
+ 
+retry if write error: 
+  INT VAR retry;
+  FOR retry FROM 1 UPTO 10 WHILE return code = 2 REP 
+    reset to block 0 if fifth try; 
+    write block 
+  PER. 
+ 
+reset to block 0 if fifth try: 
+  IF retry = 5 
+    THEN disable stop;
+         DATASPACE VAR dummy ds := nilspace;
+         block in (dummy ds, 2, 0, 0, return code);
+         forget (dummy ds);
+         enable stop
+  FI. 
+ 
+END PROC write block; 
+
+END PACKET basic block io;
+
+
+PACKET utilities DEFINES getchoice, cleol, cleop, inverse, put center:
+ 
+INT PROC get choice (INT CONST von, bis, TEXT VAR retchar):
+  get choice (von, bis, von, retchar)
+END PROC get choice;
+
+INT PROC get choice (INT CONST von, bis, zusatz, TEXT VAR retchar):
+   LET return  = ""13"",
+       escape  = ""27"",
+       left    = ""8"";
+   TEXT VAR buffer; 
+   INT VAR cx, cy;
+   get cursor (cx, cy); out (" " + left);
+   REP
+      REP 
+         cursor (cx, cy); buffer := incharety;
+      UNTIL input ok OR buffer = escape PER; 
+      IF buffer = escape THEN retchar := escape;
+                              LEAVE get choice WITH 0
+      FI;
+      out (buffer); 
+      leseschleife bis left or ret;
+      IF retchar = left   THEN out (left + " ") FI;
+      IF retchar = escape THEN LEAVE get choice WITH 0 FI
+   UNTIL retchar = return OR retchar = escape PER;
+   int (buffer). 
+ 
+input ok : (buffer >= text (von) AND buffer <= text (bis)) OR buffer = text (zusatz).
+
+leseschleife bis left or ret:
+   REP 
+     inchar (retchar) 
+   UNTIL retchar = return OR retchar = left OR retchar = escape PER.
+
+END PROC get choice;
+
+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 cl eol: 
+  out (""5"") 
+END PROC cl eol;
+
+PROC cl eop: 
+  out (""4"") 
+END PROC cl eop; 
+
+TEXT PROC inverse (TEXT CONST t):
+  ""15"" + t + " " + ""14""
+END PROC inverse; 
+ 
+PROC put center (TEXT CONST t):
+   put center (t, 80)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t):
+   put center (zeile, t, 80)
+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;
+
+END PACKET utilities
+
+
+PACKET part DEFINES activate, show actual partition table:
+                                           (* Copyright (C) 1985       *)
+                                           (* Martin Schönbeck, Spenge *)
+                                           (* Stand      : 02.02.86    *)
+                                           (* Changed by : W.Sauerwein *)
+                                           (*              I.Ley       *)
+                                           (* Stand      : 03.10.86    *) 
+    LET fd channel           = 28;
+
+ROW 256 INT VAR boot block;
+INT VAR boot block session := session - 1;
+
+PROC get boot block:
+    IF boot block session <> session
+       THEN hole aktuellen boot block
+    FI.
+
+hole aktuellen boot block:
+    disable stop;
+    DATASPACE VAR dummy ds := nilspace;
+    BOUND STRUCT (ALIGN dummy, 
+                  ROW 256 INT block) VAR partition table := dummy ds; 
+    get external block (dummy ds, 2, 0, fd channel); 
+    IF NOT is error
+        THEN transfer data to boot block
+    FI; 
+    forget (dummy ds). 
+ 
+transfer data to boot block:
+    IF not valid boot block
+        THEN try to get valid boot block from file
+    FI;
+    boot block := partition table. block;
+    boot block session := session.
+
+not valid boot block:
+    partition table. block [256] <> boot indicator OR
+    it is an old boot block of eumel.
+
+boot indicator: -21931.
+
+it is an old boot block of eumel:
+    partition table. block [1] = 1514.
+
+try to get valid boot block from file:
+    forget (dummy ds);
+    partition table := old ("bootblock");
+    IF is error THEN LEAVE transfer data to boot block FI.
+ 
+END PROC get boot block;
+
+PROC put boot block:
+    IF boot block ist uptodate
+        THEN schreibe block auf platte
+        ELSE errorstop ("boot block nicht uptodate")
+    FI.
+
+boot block ist uptodate:
+    boot block session = session.
+
+schreibe block auf platte:
+    disable stop;
+    DATASPACE VAR dummy ds := nilspace;
+    BOUND STRUCT (ALIGN dummy, 
+                  ROW 256 INT block) VAR partition table := dummy ds; 
+    transfer data to dataspace;
+    put external block (dummy ds, 2, 0, fd channel); 
+    forget (dummy ds). 
+ 
+transfer data to dataspace:
+    partition table. block := boot block.
+
+END PROC put boot block;
+
+INT PROC partition type (INT CONST partition):
+    low byte (boot block [entry (partition) + 2])
+END PROC partition type;
+
+REAL PROC partition start (INT CONST partition):
+    unsigned low word + high word.
+
+unsigned low word:
+    real (low byte (boot block [entry (partition) + 4])) +
+    real (high byte (boot block [entry (partition) + 4])) * 256.0.
+
+high word:
+    real (boot block [entry (partition) + 5]).
+
+END PROC partition start;
+
+INT PROC partition word 0 (INT CONST partition):
+   boot block (entry (partition))
+END PROC partition word 0;
+
+INT PROC first track (INT CONST partition):
+    high byte (boot block [entry (partition) + 1]) 
+    + 4 * (low byte (boot block [entry (partition) + 1]) AND (128 + 64)) 
+END PROC first track;
+
+INT PROC last track (INT CONST partition):
+    high byte (boot block [entry (partition) + 3]) 
+    + 4 * (low byte (boot block [entry (partition) + 3]) AND (128 + 64)) 
+END PROC last track;
+
+BOOL PROC partition activ (INT CONST partition):
+    low byte (boot block [entry (partition)]) = 128
+END PROC partition activ;
+
+REAL PROC partition size (INT CONST partition):
+    unsigned low word + high word.
+
+unsigned low word:
+    real (low byte (boot block [entry (partition) + 6])) +
+    real (high byte (boot block [entry (partition) + 6])) * 256.0.
+
+high word:
+    real (boot block [entry (partition) + 7]).
+
+END PROC partition size;
+
+INT PROC tracks: 
+   get value (-10, fd channel) 
+END PROC tracks; 
+
+PROC activate (INT CONST part type):
+    IF partition type exists AND is possible type
+         THEN deactivate all partitions and
+              activate desired partition
+         ELSE errorstop ("Gewünschte Partitionart gibt es nicht")
+    FI.
+
+is possible type:
+   part type > 0 AND
+   part type < 256.
+
+partition type exists:
+    INT VAR partition;
+    FOR partition FROM 1 UPTO 4 REP
+         IF partition type (partition) = part type 
+             THEN LEAVE partition type exists WITH TRUE
+         FI;
+    PER;
+    FALSE.
+
+deactivate all partitions and activate desired partition:
+    FOR partition FROM 1 UPTO 4 REP
+         deactivate this partition;
+         IF partition type (partition) = part type
+              THEN activate partition
+         FI
+    PER;
+    put boot block.
+
+deactivate this partition:
+    set bit (boot block [entry (partition)], 7);
+    (* first setting needed, because reset bit does xor *)
+    reset bit (boot block [entry (partition)], 7).
+
+activate partition:
+    set bit (boot block [entry (partition)], 7)
+
+END PROC activate;
+
+INT PROC entry (INT CONST partition):
+    get boot block;
+    256 - 5 * 8 + (partition * 8)
+END PROC entry;
+
+INT PROC get value (INT CONST control code, channel for value): 
+    enable stop; 
+    INT VAR old channel := channel;
+    continue (channel for value); 
+    INT VAR value; 
+    control (control code, 0, 0, value); 
+    continue (old channel); 
+    value 
+END PROC get value; 
+ 
+PROC get external block (DATASPACE VAR ds, INT CONST ds page,
+                                             archive block, get channel):
+   INT VAR old channel := channel; 
+   continue (get channel);
+   disable stop;
+   read block (ds, ds page, archive block, error);
+   INT VAR error;
+   SELECT error OF
+      CASE 0:
+      CASE 1: error stop ("Platte kann nicht gelesen werden");
+      CASE 2: error stop ("Lesefehler bei Block "+ text (archive block));
+      CASE 3: error stop ("Versorgungsfehler Archiv");
+      OTHERWISE error stop ("unbekannter Fehler auf Platte");
+   END SELECT;
+   continue (old channel).
+END PROC get external block;
+
+PROC put external block (DATASPACE CONST ds, INT CONST ds page,
+                                             archive block, get channel):
+   INT VAR old channel := channel; 
+   continue (get channel);
+   disable stop;
+   write block (ds, ds page, archive block, error);
+   INT VAR error;
+   SELECT error OF
+      CASE 0:
+      CASE 1: error stop ("Platte kann nicht geschrieben werden");
+      CASE 2: error stop ("Schreibfehler bei Block "+ text (archive block));
+      CASE 3: error stop ("Versorgungsfehler Archiv");
+      OTHERWISE error stop ("unbekannter Fehler auf Platte");
+   END SELECT;
+   continue (old channel).
+END PROC put external block;
+ 
+(**************************************************************************)
+ 
+   LET                           max partitions           =   4;
+   ROW max partitions INT  VAR   part list;
+   ROW max partitions INT  VAR   part type, part active,
+                                 part first track, part last track;
+   ROW max partitions REAL VAR   part start,
+                                 part size;
+                      INT  VAR   zylinder,
+                                 startzeile tabelle      ::   1,
+                                 active partition,
+                                 partitions,
+                                 partition, i, j, help;
+
+                                 
+PROC get actual partition data :
+   get boot block;
+   zylinder := tracks;
+   FOR i FROM 1 UPTO max partitions REP
+      part type        (i) := partition type (i);
+      part first track (i) := first track (i);
+      part last track  (i) := last track (i);
+      part start       (i) := partition start (i);
+      part size        (i) := partition size (i);
+      part active      (i) := partition word 0 (i);
+      IF partition activ (i) THEN active partition := i FI
+   PER;
+   get number of installed partitions;
+   generate part list.
+
+get number of installed partitions :
+   partitions := 0;
+   FOR i FROM 1 UPTO max partitions REP
+     IF part type (i) <> 0 THEN partitions INCR 1 FI
+   PER.
+
+generate part list :
+   FOR i FROM 1 UPTO max partitions REP
+      IF part type (i) <> 0 THEN part list (i) := i
+                            ELSE part list (i) := 0
+      FI;
+   PER;
+   schiebe nullen nach hinten;
+   sort part list.
+
+schiebe nullen nach hinten :
+   i := 1; INT VAR k := 0;
+   REP k INCR 1;
+       IF part list (i) = 0 THEN circle
+                            ELSE i INCR 1
+       FI
+   UNTIL k = max partitions - 1 PER.
+
+circle :
+   FOR j FROM i UPTO max partitions - 1 REP
+      part list (j) := part list (j + 1)
+   PER;
+   part list (max partitions) := 0.
+
+sort part list :
+   FOR i FROM 2 UPTO partitions REP
+      FOR j FROM 1 UPTO i - 1 REP
+          IF part first track (part list (i)) < part first track (part list (j))
+             THEN tausche FI
+      PER
+   PER.
+
+tausche :
+   help := part list (i);
+   part list (i) := part list (j);
+   part list (j) := help.
+
+END PROC get actual partition data;
+
+
+PROC show partition table :
+   headline;
+   devide table;
+   columns;
+   underlines;
+   rows;
+   footlines.
+
+head line :
+   cl eop (1, startzeile tabelle);
+   put center (inverse ("                       "
+                      + "Aktuelle Partitions - Tabelle"
+                      + "                       ")).
+
+devide table :
+   FOR i FROM 1 UPTO 8
+   REP
+      cursor (50, startzeile tabelle + i); out (inverse (""))
+   PER.
+
+columns :
+   cursor ( 1, startzeile tabelle + 2);
+   out (" Nr. System    Typ-Nr. Zustand Größe Start Ende");
+   cursor (54, startzeile tabelle + 2);
+   out ("Plattengröße / Zylinder ").
+
+underlines :
+   cursor ( 1, startzeile tabelle + 3);
+   out ("-------------------------------------------------");
+   cursor (52, startzeile tabelle + 3);
+   out ("--------------------------").
+
+rows :
+   FOR i FROM 1 UPTO max partitions
+   REP cursor (2, startzeile tabelle + 3 + i);
+       put (text (i) + " :")
+   PER.
+
+footlines:
+   cursor (1, startzeile tabelle + 9);
+   put center (inverse (75 * " ")).
+
+END PROC show partition table;
+
+PROC update table :
+   get actual partition data;
+   FOR i FROM 1 UPTO partitions REP update partition PER;
+   FOR i FROM partitions + 1 UPTO max partitions REP rubout partition PER;
+   zeige plattengroesse.
+
+update partition :
+   partition := part list (i);
+   show partition.
+
+rubout partition :
+   cursor (6, startzeile tabelle + 3 + i);
+   out ("                                          ").
+
+show partition :
+   cursor (6, startzeile tabelle + 3 + i);
+   put (name + type + zustand  + groesse + startspur + endspur).
+
+name : subtext (subtext (part name, 1, 9)
+              + "          ", 1, 10).
+
+type : text (part type (partition), 5) + "   ".
+
+zustand   : IF active partition = partition THEN (" aktiv ")
+                                            ELSE ("       ")
+            FI.
+
+startspur : " " + text (part first track (partition), 5).
+endspur   :       text (part last track   (partition), 6).
+groesse   :       text (part groesse, 5).
+
+zeige plattengroesse :
+   put gesamt;
+   put noch freie;
+   put maximaler zwischenraum.
+
+put maximaler zwischenraum :
+   cursor (54, startzeile tabelle + 6);
+   put ("max. zusammenh. : " + text (maximaler zwischenraum, 4)).
+
+put gesamt :
+   cursor (54, startzeile tabelle + 4);
+   put ("insgesamt       : " + text (zylinder, 4)).
+
+put noch freie :
+   cursor (54, startzeile tabelle + 5);
+   put ("davon noch frei : " + text (freie zylinder, 4)).
+
+part groesse :
+   partition groesse (partition).
+
+part name :
+   SELECT part type (partition) OF
+     CASE              1 : "DOS"
+     CASE 69, 70, 71, 72 : "EUMEL"
+     OTHERWISE text (part type (partition))
+   END SELECT.
+
+freie zylinder :
+   zylinder - belegte zylinder.
+
+belegte zylinder :
+   help := 0;
+   FOR i FROM 1 UPTO partitions REP
+      help INCR partition groesse (part list (i))
+   PER;
+   help.
+
+END PROC update table;
+ 
+INT PROC maximaler zwischenraum :
+   IF partitions = 0 THEN zylinder
+                     ELSE max (maximaler platz vor und zwischen den partitionen,
+                               platz hinter letzter partition)
+   FI.
+
+maximaler platz vor und zwischen den partitionen :
+   help := platz vor erster partition;
+   FOR i FROM 1 UPTO partitions - 1
+   REP
+      help := max (help, begin of part i plus 1 - end of part i - 1)
+   PER;
+   help.
+
+platz vor erster partition :
+   part first track (part list (1)).
+
+platz hinter letzter partition :
+   zylinder - part last track (part list (partitions)) - 1.
+
+begin of part i plus 1 :
+   part first track (part list (i + 1)).
+
+end of part i :
+   part last track (part list (i)).
+
+END PROC maximaler zwischenraum;
+
+INT PROC partition groesse (INT CONST part) :
+   part last track (part) - part first track (part) + 1
+END PROC partition groesse;
+
+PROC show actual partition table:
+   show partition table;
+   update table;
+   line (4)
+END PROC show actual partition table;
+
+PROC show actual partition table (ROW max partitions INT VAR typnr):
+   show actual partition table;
+   FOR i FROM 1 UPTO max partitions REP
+      typnr (i) := partition type (part list (i))
+   PER;
+END PROC show actual partition table;
+
+END PACKET part;
+
+
+PACKET hw clock DEFINES hw clock:        (* Copyright (C) 1985       *)
+                                         (* Martin Schönbeck, Spenge *)
+LET clock length  = 7,                   (* Stand: 06.11.85          *)
+    clock command = 4;
+
+BOUND STRUCT (ALIGN dummy,
+              ROW clock length INT clock field) VAR clock data;
+
+REAL PROC hw clock:
+ 
+    disable stop;
+    get clock;
+    hw date + hw time.
+
+get clock:
+    DATASPACE VAR ds := nilspace;
+    clock data := ds;
+    INT VAR return code, actual channel := channel;
+    go to shard channel;
+    blockin (ds, 2, -clock command, 0, return code);
+    IF actual channel = 0 THEN break (quiet)
+                          ELSE continue (actual channel)
+    FI;
+    IF return code <> 0 
+        THEN errorstop ("Keine Hardware Uhr vorhanden");
+    FI;
+    put clock into text;
+    forget (ds).
+
+put clock into text:
+    TEXT VAR clock text := clock length * "  ";
+    INT VAR i;
+    FOR i FROM 1 UPTO clock length REP
+         replace (clock text, i, clock data. clock field [i]);
+    PER.
+
+go to shard channel:
+    INT VAR retry;
+    FOR retry FROM 1 UPTO 20 REP
+        continue (32);
+        IF is error
+            THEN clear error;
+                 pause (30)
+        FI;
+    UNTIL channel = 32 PER.
+
+hw date:
+    date (day + "." + month + "." + year).
+
+day:    subtext (clock text, 7, 8).
+
+month:  subtext (clock text, 5, 6).
+
+year:   subtext (clock text, 1, 4).
+
+hw time:
+    time (hour + ":" + minute + ":" + second).
+
+hour:   subtext (clock text, 9, 10).
+
+minute: subtext (clock text, 11, 12).
+
+second: subtext (clock text, 13, 14).
+
+END PROC hw clock;
+
+END PACKET hw clock
+
+
+PACKET old shutup DEFINES old shutup,       (* Copyright (C) 1985       *)
+                          old save system:  (* Martin Schönbeck, Spenge *)
+                                            (* Stand: 06.11.85          *)
+PROC old shutup : shutup END PROC old shutup;
+
+PROC old save system : save system END PROC old save system;
+
+END PACKET old shutup;
+
+
+PACKET new shutup DEFINES shutup,
+                          shutup dialog,
+                          save system,
+                          generate shutup manager,
+                          generate shutup dialog manager:
+
+LET ack = 0;
+
+PROC shutup:
+ 
+    system down (PROC old shutup)
+
+END PROC shutup;
+
+PROC shutup (INT CONST new system):
+ 
+    IF new system <> 0
+         THEN prepare for new system
+    FI;
+    system down (PROC old shutup).
+
+prepare for new system:
+    activate (new system);
+    prepare for rebooting.
+
+prepare for rebooting:
+    INT VAR old channel := channel;
+    continue (32);
+    INT VAR dummy;
+    control (-5, 0, 0, dummy);
+    break (quiet);
+    continue (old channel).
+
+END PROC shutup;
+
+PROC save system:
+ 
+    IF yes ("Leere Floppy eingelegt")
+       THEN system down (PROC old save system)
+    FI
+
+END PROC save system;
+
+PROC system down (PROC operation):
+
+   BOOL VAR dialogue :: command dialogue;
+   command dialogue (FALSE);
+   operation;
+   command dialogue (dialogue);
+   IF command dialogue
+      THEN wait for configurator;
+           show date;
+   FI.
+
+show date:
+   page;
+   line (2); 
+   put ("      Heute ist der"); putline (date);
+   put ("      Es ist"); put (time of day); putline ("Uhr");
+   line (2).
+
+END PROC system down;
+
+DATASPACE VAR ds := nilspace;
+
+PROC wait for configurator:
+
+   INT VAR i, receipt;
+   FOR i FROM 1 UPTO 20 WHILE configurator exists REP
+      pause (30);
+      forget (ds);
+      ds := nilspace;
+      ping pong (configurator, ack, ds, receipt)
+   UNTIL receipt >= 0 PER.
+
+configurator exists:
+   disable stop;
+   TASK VAR configurator := task ("configurator");
+   clear error;
+   NOT is niltask (configurator).
+
+END PROC wait for configurator;
+
+PROC generate shutup manager:
+ 
+     generate shutup manager ("shutup", 0);
+
+END PROC generate shutup manager;
+
+PROC generate shutup manager (TEXT CONST name, INT CONST new system):
+ 
+     TASK VAR son;
+     shutup question := name;
+     new system for manager := new system;
+     begin (name, PROC shutup manager, son)
+
+END PROC generate shutup manager;
+
+INT VAR new system for manager;
+TEXT VAR shutup question;
+
+PROC shutup manager:
+
+     disable stop;
+     command dialogue (TRUE);
+     REP 
+        break;
+        line ;
+        IF yes (shutup question)
+            THEN clear error;
+                 shutup (new system for manager);
+                 pause (300);
+        FI;
+     PER
+
+END PROC shutup manager;
+
+PROC shutup dialog:
+   init;
+   show actual partition table (typnr);
+   REP
+      enter part number;
+      get cursor (cx, cy);
+      IF NOT escaped CAND yes (shutup question)
+         THEN message;
+              shutup (partition type);
+              LEAVE shutup dialog
+      FI;
+   PER.
+
+shutup question:
+   IF partition null
+      THEN "Shutup ausführen"
+      ELSE "Shutup nach Partition mit Typnummer " + text (typnr (partition)) + " ausführen"
+   FI.
+
+message:
+   cl eol (1, cy);
+   put line ("Bitte auf ENDE - Meldung warten !").
+
+partition type:
+   IF partition = 0
+      THEN 0
+      ELSE typnr (partition)
+   FI.
+
+init:
+   LET  startzeile menu  =  12, 
+        escape           = ""27"",
+        max partitions   =   4;
+
+   ROW max partitions INT VAR typnr;
+   INT VAR partition, cx, cy;
+   TEXT VAR retchar.
+
+partition null:
+   partition = 0 COR typnr (partition) = 0.
+
+enter part number :
+   cl eop (1, startzeile menu);
+   cursor (54, startzeile menu    ); put ("Abbruch mit <ESC>");
+   cursor (54, startzeile menu + 1); put ("Shutup ohne Wechsel mit <0>");
+   cursor ( 1, startzeile menu);
+   put ("Zu welcher Partition wollen Sie wechseln :");
+   get cursor (cx, cy);
+   REP
+      REP cursor (cx, cy);
+          partition := get choice (0, 4, retchar);
+          IF sure escaped THEN LEAVE shutup dialog FI;
+      UNTIL NOT escaped PER;
+      IF partition <> 0 CAND NOT partition exists
+         THEN fehler;
+              put ("Diese Partition gibt es nicht")
+      FI;
+   UNTIL partition = 0 OR partition exists PER;
+   cl eol (54, startzeile menu);
+   cl eol (54, startzeile menu + 1);
+   cl eop (1, cy + 2).
+
+partition exists:
+   typnr (partition) <> 0.
+
+escaped :
+   retchar = escape.
+
+sure escaped :
+   IF escaped THEN cl eop (1, 20); cursor (1, 22);
+                   IF yes ("Shutup-Dialog abbrechen") THEN TRUE
+                                                      ELSE cl eop (1, 20);
+                                                           FALSE
+                   FI
+              ELSE FALSE
+   FI.
+
+fehler :
+   cl eop (1, 20);
+   put (""7"" + inverse ("FEHLER :")); line (2).
+
+END PROC shutup dialog;
+
+PROC generate shutup dialog manager:
+     TASK VAR son;
+     begin ("shutup dialog", PROC shutup dialog manager, son)
+END PROC generate shutup dialog manager;
+
+PROC shutup dialog manager:
+     disable stop;
+     command dialogue (TRUE);
+     REP 
+        break; line;
+        clear error;
+        INT VAR sess := session;
+        shutup dialog;
+        IF sess <> session THEN pause (300) FI;
+     PER;
+END PROC shutup dialog manager;
+
+END PACKET new shutup
+
+
+PACKET config manager with time DEFINES configuration manager ,
+                                        configuration manager with time :
+                                      (* Copyright (C) 1985       *)
+INT VAR old session := 0;             (* Martin Schönbeck, Spenge *)
+                                      (* Stand: 06.11.85          *)
+PROC configuration manager: 
+ 
+   configurate;
+   break;
+   global manager (PROC (DATASPACE VAR, INT CONST, INT CONST, TASK CONST) 
+                      configuration manager with time) 
+ 
+END PROC configuration manager; 
+ 
+PROC configuration manager with time (DATASPACE VAR ds, INT CONST order, 
+                                      phase, TASK CONST order task): 
+ 
+    IF old session <> session
+      THEN
+        disable stop;
+        set clock (hw clock); 
+        set clock (hw clock); (* twice, to avoid all paging delay *) 
+        IF is error THEN IF online THEN put error; clear error; pause (100)
+                                   ELSE clear error
+        FI FI;
+        old session := session;
+        set autonom;
+    FI; 
+    configuration manager (ds, order, phase, order task); 
+
+END PROC configuration manager with time; 
+
+END PACKET config manager with time;
+
diff --git a/at/AT install b/at/AT install
new file mode 100644
index 0000000..11f9b55
--- /dev/null
+++ b/at/AT install	
@@ -0,0 +1,93 @@
+(*************************************************************************)
+(*** Insertiert alle notwendigen Pakete, damit ein AT-System generiert ***)
+(*** werden kann, das die Hardwareuhr lesen und Partitionen bedienen   ***)
+(*** kann. Startet den "AT Generator".                                 ***)
+(***                                                                   ***)
+(*** Autor : W. Sauerwein                             Stand : 15.07.86 ***)
+(*************************************************************************)
+
+erste bildschirmmeldung;
+IF ich bin single THEN putline ("Die AT-spezifische Software ist nur auf Multi-User-Systemen benutzbar !")
+                  ELSE hole dateien vom archiv;
+                       insertiere alle pakete;
+                       put line ("Running ""AT Generator""...");
+                       run ("AT Generator")
+FI;
+forget ("AT install", quiet).
+
+ich bin single : (pcb (9) AND 255) <= 1.
+
+insertiere alle pakete :
+   insert and say ("AT Utilities").
+
+erste bildschirmmeldung :
+   page;
+   put center (" Generator für AT-spezifische Software gestartet."); line;
+   put center ("--------------------------------------------------");
+   line (2).
+
+hole dateien vom archiv :
+   TEXT VAR datei;
+   datei := "AT Utilities";             hole wenn noetig;
+   datei := "AT Generator";             hole wenn noetig;
+   release (archive);
+   line.
+
+hole wenn noetig :
+   IF NOT exists (datei) THEN
+      put line ("Loading """ + datei + """...");
+      fetch (datei, archive)
+   FI.
+
+PROC insert and say (TEXT CONST datei) :
+
+   INT VAR cx, cy;
+   put line ("Inserting """ + datei + """...");
+   get cursor (cx, cy);
+   insert (datei);
+   cl eop (cx, cy); line;
+   forget (datei, quiet).
+
+END PROC insert and say;
+
+TEXT PROC inverse (TEXT CONST t):
+  ""15"" + t + " " + ""14""
+END PROC inverse;
+
+PROC put center (TEXT CONST t):
+   put center (t, 80)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t):
+   put center (zeile, t, 80)
+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; 
+
diff --git a/basic/BASIC.Administration b/basic/BASIC.Administration
new file mode 100644
index 0000000..6df6854
--- /dev/null
+++ b/basic/BASIC.Administration
@@ -0,0 +1,1886 @@
+(***************************************************************************)
+(*                                                                         *)
+(*           Zweite von drei Dateien des EUMEL-BASIC-Systems               *)
+(*                                                                         *)
+(*           Autor: Heiko Indenbirken                                      *)
+(*           Überarbeitet von: Rudolf Ruland und Michael Overdick          *)
+(*                                                                         *)
+(*           Stand: 27.10.1987                                             *)
+(*                                                                         *)
+(***************************************************************************)
+
+PACKET basic errors DEFINES basic error,      (* Autor: Heiko Indenbirken *)
+                            return error,     (* Stand: 26.08.1987/rr/mo  *)
+                            basic warning:
+
+TEXT VAR erste zeile,
+         message;
+LET errorsize = 40;
+LET ERROR = STRUCT (INT no, TEXT msg);
+
+ROW errorsize ERROR CONST error msg :: ROW errorsize ERROR : 
+(ERROR:( 1, "NEXT ohne FOR"),
+ ERROR:( 2, "Syntaxfehler:"),
+ ERROR:( 5, "Fehlerhafter Funktionsaufruf"),
+ ERROR:( 8, "Zeile mit dieser Nummer existiert nicht"),
+ ERROR:(10, "Das Feld ist bereits dimensioniert"),
+ ERROR:(13, "Falscher Typ:"),
+ ERROR:(15, "Text zu lang"),
+ ERROR:(18, "Undefinierte 'user function'"),
+ ERROR:(22, "Ausdruck erwartet"),
+ ERROR:(26, "FOR ohne NEXT"),
+ ERROR:(29, "WHILE ohne WEND"),
+ ERROR:(30, "WEND ohne WHILE"),
+ ERROR:(51, "Interner Fehler"),
+ ERROR:(80, "Fehlerhafte Zeilennummer"),
+ ERROR:(81, "Falsche Reihenfolge der Zeilennummern"),
+ ERROR:(82, "Falscher Typ des Operanden:"),
+ ERROR:(83, "Falscher Typ der Operanden:"),
+ ERROR:(84, "Falsche Felddimension:"),
+ ERROR:(85, "Rekursive Funktionsdefinition"), 
+ ERROR:(86, "Fehlerhafte Laufvariable:"),
+ ERROR:(87, "Fehlerhafte Bereichsangabe:"),
+ ERROR:(88, "Fehlerhafte Dimensionierung:"),
+ ERROR:(89, "Parametervariable kommt mehrmals vor"),
+ ERROR:(90, "AS ohne NAME"),
+ ERROR:(91, "BASE ohne OPTION"),
+ ERROR:(92, "ELSE ohne IF"),
+ ERROR:(93, "STEP ohne FOR"),
+ ERROR:(94, "TAB ohne (L)PRINT"),
+ ERROR:(95, "THEN ohne IF"),
+ ERROR:(96, "TO ohne Zusammenhang"),
+ ERROR:(97, "USING ohne (L)PRINT"),
+ ERROR:(98, "Unbekannte Funktion,"),
+ ERROR:(99, "Unbekannte Prozedur,"),
+ ERROR:(100,"Nicht implementiert"),
+ ERROR:(101,"SUB ohne GO"),
+ ERROR:(102,"GO ohne TO oder SUB"),
+ ERROR:(103,"Accessrecht VAR erwartet, CONST gefunden"),
+ ERROR:(104,"Funktionsaufruf ohne Zusammenhang"),
+ ERROR:(105,"Nach OPTION BASE ist nur 0 oder 1 erlaubt"),
+ ERROR:(106,"Bei SWAP nur gleiche Variablentypen erlaubt"));
+
+TEXT PROC errortext (INT CONST no):
+  INT VAR i;
+  FOR i FROM 1 UPTO errorsize
+  REP IF errormsg [i].no = no
+      THEN LEAVE errortext WITH errormsg [i].msg FI
+  PER;
+  "Unbekannter BASIC-Fehler #" + text (no)  .
+END PROC errortext;
+
+PROC basic error (TEXT CONST packet,
+                  INT CONST error nr,
+                  INT CONST line nr,
+                  INT CONST statement nr,
+                  TEXT CONST position, addition,
+                  BOOL CONST leave statement):
+  erste zeile aufbauen;
+  einfache fehlermeldung aufbauen; 
+  diese auf terminal ausgeben; 
+  diese in sysout datei ausgeben wenn noetig;                    (* F20/rr *)
+  fehlermeldung in fehlerdatei ausgeben;
+  IF leave statement                                             (* DEF/mo *)
+    THEN errorstop (101, packet + "-Fehler")
+  FI.
+
+erste zeile aufbauen:
+  IF line nr = 0 AND statement nr = 0
+  THEN erste zeile := "FEHLER"
+  ELSE erste zeile := "FEHLER (Dateizeile ";
+       erste zeile CAT text (line nr);
+       erste zeile CAT ") in Zeile ";
+       erste zeile CAT text (statement nr);
+  FI;
+ 
+  erste zeile CAT " bei >> ";
+  erste zeile CAT position;
+  erste zeile CAT " << : "  .
+
+einfache fehlermeldung aufbauen:
+  message := "   ";
+  message CAT error text (error nr);
+  message CAT "   "  .
+ 
+diese auf terminal ausgeben:                                     (* F20/rr *)
+  display (""13""10"");
+  display (erste zeile);
+  display (""13""10"");
+  display (message + addition);
+  display (""13""10"") .
+ 
+diese in sysout datei ausgeben wenn noetig :                      (* F20/rr *)
+  IF sysout <> ""
+     THEN putline (erste zeile);
+          putline (message + addition);
+          line;
+  FI .
+
+fehlermeldung in fehlerdatei ausgeben:
+  note (erste zeile);
+  note line;
+  note (message);
+  note (addition);
+  note line .
+ 
+END PROC basic error;
+
+PROC basic warning (INT CONST line nr,                   (* mo *)
+                              statement nr,
+                    TEXT CONST warning text):
+generate warning;
+on screen;
+in sysout file;
+into the notebook.
+
+generate warning:
+  IF line nr = 0 AND statement nr = 0
+  THEN erste zeile := "WARNUNG"
+  ELSE erste zeile := "WARNUNG (Dateizeile ";
+       erste zeile CAT text (line nr);
+       erste zeile CAT ") in Zeile ";
+       erste zeile CAT text (statement nr);
+  FI;
+  erste zeile CAT ": ";
+  erste zeile CAT warning text.
+
+on screen:
+  display (""13""10"");
+  display (erste zeile);
+  display (""13""10"").
+
+in sysout file:
+  IF sysout <> ""
+     THEN putline (erste zeile);
+          line;
+  FI.
+
+into the notebook:
+  IF warnings
+    THEN note (erste zeile);
+         note line
+  FI.
+
+END PROC basic warning;
+
+PROC return error:
+  errorstop (1003, "RETURN ohne GOSUB")
+END PROC return error;
+
+END PACKET basic errors;
+
+PACKET basic types DEFINES symbol of,         (* Autor: Heiko Indenbirken *)
+                           type of,           (* Stand: 07.09.1987/rr/mo  *)
+                           dim of,
+                           shift, deshift,
+                           reserved,
+                           param list,
+                           is bool op:
+
+LET (*                 S y m b o l    T y p e n                          *)
+    any      =  0,    const    =  1,    var     =  2,    array    =  3,
+    expr     =  4,    unused   =  5,    letter  =  6,    param    =  7,
+    res word =  8,    operator =  9,    eos     = 10,    del      = 11,
+    stat no  = 12,    eol      = 13,    eop     = 14,
+    user fn  = 20;  (* DEF/mo *)
+(*                               Operatoren                              *)
+LET less equal = 28,  unequal = 29,  greater equal = 30;
+
+TEXT VAR dummy;
+ 
+TEXT PROC symbol of (INT CONST n) :
+  IF n < 0
+  THEN ""19"" + symbol of (-n)
+  ELSE SELECT n OF
+       CASE less equal    : "<="
+       CASE unequal       : "<>"
+       CASE greater equal : ">="
+
+       CASE eos           : "EOS"
+       CASE eol           : "EOL"
+       CASE eop           : "EOF"
+       OTHERWISE : character END SELECT
+  FI  . 
+
+character :
+  IF n > 32 AND n < 128
+  THEN code (n)
+  ELIF n >= 128 AND n <= 255
+  THEN res word of (n)
+  ELSE "%" + subtext (text (n+1000), 2) + " " FI  .
+
+END PROC symbol of;
+
+TEXT PROC type of (INT CONST n) :
+  SELECT n OF
+  CASE any      : "ANY"
+  CASE const    : "Konstante"
+  CASE var      : "Variable"
+  CASE array    : "Feld"
+  CASE expr     : "Ausdruck"
+  CASE unused   : " -?- "
+  CASE letter   : "Buchstabe" 
+  CASE param    : "Parameter"
+  CASE res word : "reserviertes Wort"
+  CASE operator : "Operator"
+  CASE eos      : "EOS"
+  CASE del      : "Trennzeichen"
+  CASE stat no  : "Zeilennumer"
+  CASE eol      : "EOL"
+  CASE eop      : "EOF"
+  CASE user fn  : "'user function'"                   (* DEF/mo *)
+  OTHERWISE "?TYPE #" + text (n) ENDSELECT.
+END PROC type of;
+
+TEXT PROC dim of (TEXT CONST parameter):
+  IF parameter = ""
+  THEN ""
+  ELSE base limits and size FI  .
+
+base limits and size:
+  INT CONST dimension :: (LENGTH parameter DIV 2) - 2;
+  TEXT VAR result :: text (parameter ISUB dimension+1);
+  INT VAR i;
+  result CAT ": [";
+  FOR i FROM 1 UPTO dimension-1
+  REP result CAT text (parameter ISUB i);
+      result CAT ", "
+  PER;
+  result CAT text (parameter ISUB dimension);
+  result CAT "]  ";
+  result CAT text (parameter ISUB dimension+2);
+  result  .
+
+END PROC dim of;
+
+TEXT PROC param list (INT CONST first, no):
+  IF no < first
+  THEN "keine"
+  ELSE parameter list FI  .
+
+parameter list:
+  INT VAR i;
+  TEXT VAR result :: "(";
+  FOR i FROM first UPTO no
+  REP result CAT dump (dtype (i));
+      IF i = no
+         THEN result CAT ")"
+         ELSE result CAT ", " FI
+  PER;
+  result  .
+
+END PROC param list;
+
+TEXT PROC shift (TEXT CONST word) :
+  INT VAR i;
+  dummy := word;
+  FOR i FROM 1 UPTO length (word)
+  REP shift char PER;
+  dummy  .
+
+shift char:
+  INT VAR local letter :: code (dummy SUB i);
+  IF 97 <= local letter AND local letter <= 122
+  THEN replace (dummy, i, code (local letter - 32)) FI  .
+
+END PROC shift;
+
+TEXT PROC deshift (TEXT CONST word) :
+  INT VAR i;
+  dummy := word;
+  FOR i FROM 1 UPTO length (word)
+  REP deshift char PER;
+  dummy  .
+
+deshift char:
+  INT VAR local letter :: code (dummy SUB i);
+  IF 65 <= local letter AND local letter <= 90
+  THEN replace (dummy, i, code (local letter + 32)) FI;
+
+END PROC deshift;
+
+(*                Verwaltung der Reservierten BASIC-Wörter               *)
+LET first operator = 249,             (* MOD  NOT  AND   OR  XOR  EQV  IMP *)
+    first bool op  = 250;             (* 249  250  251  252  253  254  255 *)
+
+INT VAR index;
+ROW 9 TEXT VAR res words :: ROW 9 TEXT :
+("",
+ ""129"as"163"go"167"if"188"on"217"to"252"or",
+ ""128"abs"130"asc"131"atn"141"cos"142"cvd"143"cvi"145"def"150"dim"152"end"153"eof"154"erl"155"err"157"exp"159"fix"160"for"161"fre"162"get"172"int"175"len"176"let"178"loc"179"log"191"out"192"pos"194"put"202"rnd"197"rem"204"sgn"205"sin"207"spc"208"sqr"214"tab"215"tan"221"val"227"cls"234"usr"235"sub"249"mod"250"not"251"and"253"xor"254"eqv"255"imp",
+ ""132"base"133"call"134"cdbl"136"chr$"137"cint"144"data"151"else"165"goto"166"hex$"173"kill"177"line"181"lset"182"mid$"183"mkd$"184"mki$"185"name"186"next"187"oct$"189"open"196"read"203"rset"209"step"210"stop"211"str$"213"swap"216"then"219"tron"222"wait"223"wend"228"erm$"230"lpos",
+ ""135"chain"138"clear"139"close"156"error"158"field"164"gosub"169"input"171"instr"174"left$"193"print"218"troff"220"using"224"while"225"width"226"write"231"time$"232"date$"233"timer",
+ ""140"common"146"defdbl"147"defint"148"defsng"149"defstr"168"inkey$"170"input$"180"lprint"190"option"199"resume"200"return"201"right$"206"space$"229"csrlin",
+ ""198"restore"212"string$",
+ "",
+ ""195"randomize");
+
+BOOL PROC reserved (TEXT CONST name, INT VAR no, type):
+  IF reserve is not possible COR not found within res words
+  THEN FALSE
+  ELSE no   := code (this words SUB (index-1));
+       type := res word or op;
+       TRUE
+  FI  .
+
+reserve is not possible:
+  INT CONST len :: length (name);
+  len < 2 OR len > 9  .
+
+not found within res words:
+  index := pos (this words, name);
+  index = 0  .
+
+this words:
+  res words [len]  .
+
+res word or op:
+  IF no >= first operator
+  THEN operator
+  ELSE res word FI  .
+
+END PROC reserved;
+
+INT PROC reserved (TEXT CONST name):
+  IF reserve is not possible COR not found within res words
+  THEN 0
+  ELSE code (this words SUB (index-1)) FI  .
+
+reserve is not possible:
+  INT CONST len :: length (name);
+  len < 2 OR len > 9  .
+
+not found within res words:
+  index := pos (this words, name);
+  index = 0  .
+
+this words:
+  res words [len]  .
+
+END PROC reserved;
+
+TEXT PROC res word of (INT CONST no):
+  INT VAR i;
+  FOR i FROM 2 UPTO 9
+  REP index := pos (res words [i], code (no));
+      IF index > 0
+      THEN LEAVE res word of WITH shift (this name) FI
+  PER;
+  ""  .
+
+this name:
+  subtext (res words [i], index+1, next code)  .
+
+next code:
+  INT VAR c := pos (res words [i], ""127"", ""255"", index+1);
+  IF c = 0
+  THEN length (res words [i])
+  ELSE c-1 FI  .
+
+END PROC res word of;
+
+BOOL PROC is bool op (INT CONST no):            (* mo *)
+  no >= first bool op
+END PROC is bool op;
+
+END PACKET basic types;
+
+PACKET basic table handling DEFINES init table, (* Autor: Heiko Indenbirken *)
+                              put name,         (* Stand: 13.08.1987/rr/mo  *)
+                              known, name of,
+                              remember,
+                              recognize,
+                              table entries,
+                              hash table, next table,
+                              scope compulsory:          (* DEF/mo *)
+
+LET hash length = 1024, 
+    hash length minus one = 1023,
+    start of name table = 256,
+    table length = 4500;
+ 
+LET SYMBOL = STRUCT (INT type, ADDRESS adr, DTYPE data, TEXT dim);
+LET TABLE = STRUCT (INT entries,
+                    ROW hash length INT hash table,
+                    ROW table length INT next, 
+                    ROW table length TEXT name table,
+                    ROW table length SYMBOL symbol table);
+ 
+DATASPACE VAR table space;
+BOUND TABLE VAR table;
+INITFLAG VAR tab := FALSE;
+SYMBOL CONST nilsymbol :: SYMBOL:(0, LOC 0, void type, "");
+INT VAR i;
+BOOL VAR compulsory with scope :: TRUE;                     (* DEF/mo *)
+
+PROC init table:
+  IF NOT initialized (tab)
+  THEN table space := nilspace;
+       table := table space;
+  FI;
+  table.entries := start of name table;
+  FOR i FROM 1 UPTO hash length
+  REP table.hash table [i] := 0 PER;
+  compulsory with scope := TRUE;                            (* DEF/mo *)
+
+END PROC init table;
+
+PROC put name (TEXT CONST scope, name, INT VAR pointer):    (* DEF/mo *)
+  IF compulsory with scope
+    THEN put name (scope + name, pointer)
+  ELIF NOT in table
+    THEN put name (name, pointer)
+  FI.
+
+in table:
+  hash (scope + name, pointer);
+  pointer := hash table (pointer);
+  WHILE not end of chain
+  REP IF name is found THEN LEAVE in table WITH TRUE FI;
+      pointer := table. next (pointer);
+  PER;
+  FALSE .
+
+name is found:
+  table.name table [pointer] = scope + name.
+ 
+not end of chain:
+  pointer > 0  .
+
+END PROC put name;
+
+PROC put name (TEXT CONST name, INT VAR pointer):
+  IF no entry in hash table
+  THEN create a new chain
+  ELSE create a new entry in chain FI;
+  insert name in name table  .
+ 
+no entry in hash table:
+  INT VAR hash index;
+  hash (name, hash index); 
+  table.hash table [hash index] = 0  .
+
+create a new chain:
+  table.hash table [hash index] := table.entries  .
+ 
+create a new entry in chain:
+  pointer := table.hash table [hash index];
+  REP IF name is found
+      THEN LEAVE put name
+      ELIF end of chain
+      THEN table.next [pointer] := table.entries;
+           LEAVE create a new entry in chain
+      ELSE pointer := next pointer FI
+  PER  .
+ 
+name is found:
+  table.name table [pointer] = name.
+ 
+end of chain:
+  INT CONST next pointer := table.next [pointer];
+  next pointer = 0  .
+
+insert name in name table:
+  IF table.entries >= table length 
+  THEN errorstop ("volle Namenstabelle") FI;
+
+  pointer := table.entries;
+  table.symbol table [pointer] := nilsymbol;
+  table.name table [pointer] := name; 
+  table.next [pointer] := 0; 
+  table.entries INCR 1  .
+
+END PROC put name; 
+
+PROC hash (TEXT CONST name, INT VAR index) :
+  INT VAR j;
+  index := 0;
+  FOR j FROM 1 UPTO length (name)
+  REP addmult cyclic PER;
+  index INCR 1  .
+ 
+addmult cyclic :
+  index INCR index ;
+  IF index > hash length minus one
+  THEN wrap around FI;
+  index := (index + code (name SUB j)) MOD hash length minus one  .
+
+wrap around:
+  index DECR hash length minus one  .
+
+ENDPROC hash ;
+ 
+INT PROC table entries:
+  table.entries
+END PROC table entries;
+
+INT PROC hash table (INT CONST n):
+  table.hash table [n]
+END PROC hash table;
+
+INT PROC next table (INT CONST n):
+  table.next [n]
+END PROC next table;
+
+TEXT PROC name of (INT CONST index): 
+  IF index < 0
+  THEN errorstop ("PROC name of: negativer Index"); ""
+  ELIF index < start of name table
+  THEN symbol of  (index)
+  ELIF index <= table.entries
+  THEN table.name table (index) 
+  ELSE errorstop ("PROC name of: Index größer als nametable");
+       ""
+  FI
+
+END PROC name of; 
+ 
+PROC recognize (INT CONST symb, type, ADDRESS CONST adr, DTYPE CONST data, TEXT CONST dim):
+  symbol.type  := type;
+  symbol.adr   := adr;
+  symbol.data  := data; 
+  symbol.dim   := dim  .
+
+symbol: table.symboltable [symb]  .
+END PROC recognize;
+
+PROC remember (INT CONST symb, INT VAR type, ADDRESS VAR adr, DTYPE VAR data, TEXT VAR dim):
+  SYMBOL CONST symbol := table.symboltable [symb];
+  type  := symbol.type;
+  adr   := symbol.adr;
+  data  := symbol.data; 
+  dim   := symbol.dim
+END PROC remember;
+
+BOOL PROC known (INT CONST symb) :
+  table.symboltable [symb].type > 0
+END PROC known;
+
+PROC scope compulsory (BOOL CONST new state):       (* DEF/mo *)
+  compulsory with scope := new state
+END PROC scope compulsory;
+
+END PACKET basic table handling;
+
+PACKET basic scanner DEFINES begin scanning,  (* Autor: Heiko Indenbirken *)
+                             next symbol,     (* Stand: 27.10.1987/rr/mo  *)
+                             next data,
+                             next statement,
+                             define chars,
+                             scan line,
+                             scan line no,                       (* F29/rr *)
+                             get data types of input vars,       (* F25/rr *)
+                             basic error,
+                             basic warning,
+                             basic list,
+                             set scope,
+                             scanner scope:
+
+
+LET (*                    S y m b o l    T y p e n                       *)
+    any     = 0,  const   = 1,  var     = 2,  array   = 3,
+    res word= 8,  operator= 9,  eos     = 10, del     =11,
+    stat no = 12, user fn = 20;         (* DEF/mo *)
+
+LET (*                    S y m b o l z e i c h e n                      *)
+    less         = 60,  greater       = 62,
+    less equal   = 28,  unequal       = 29,  greater equal = 30, 
+    point        = 46,  eol           = 13,  eop           = 14,
+    go           = 163, gosub         = 164, goto          = 165,
+    sub          = 235, to            = 217;
+
+LET name chars    = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.0123456789!#$%",
+    quote         = """",       open bracket    = "(",
+    comma         = ",",        close bracket   = ")",
+    colon         = ":",
+    exponent chars= "dDeE";
+
+FILE VAR source file;
+TEXT VAR defint chars, defstr chars, record, letter,
+         scope, new name;     (* DEF/mo *)
+REAL VAR r dummy;
+INT VAR act stat no, record no, rec len, scan pos, i dummy;
+BOOL VAR eol generated, at line begin, listing := FALSE;
+
+PROC define chars (TEXT CONST begin, end, DTYPE CONST data):
+  INT VAR i;
+  FOR i FROM code (begin) UPTO code (end)
+  REP IF data = int type
+        THEN defint chars CAT code (i) 
+      ELIF data = text type
+        THEN defstr chars CAT code (i) 
+      FI
+  PER  .
+
+END PROC define chars;
+
+
+PROC scanline (TEXT VAR line, INT VAR col):
+  line := record;
+  col  := scan pos
+END PROC scanline;
+
+INT PROC scan line no : record no END PROC scan line no;
+
+
+PROC get data types of input vars (ROW 100 DTYPE VAR input var data, (* F25/rr *)
+                                   INT VAR number input vars) :
+
+  TEXT VAR first var char;
+  INT VAR var pos := scan pos;
+  to begin of actual var;
+  REP get next input var;
+      skip brackets if necessary;
+      IF var char <> comma THEN LEAVE get data types of input vars FI;
+      skip comma;
+  PER;
+ 
+  . var char : record SUB var pos
+
+  . to begin of actual var :
+      WHILE pos (name chars, var char) <> 0 REP var pos DECR 1 PER;
+      var pos         INCR 1;
+      number input vars := 0;
+ 
+  . get next input var :
+      first var char := deshift (var char);
+      WHILE pos (name chars, var char) <> 0 REP var pos INCR 1 PER;
+      var pos           DECR 1;
+      number input vars INCR 1;
+      input var data (number input vars) := var datatype (first var char, var char);
+      var pos := pos (record, ""33"", ""255"", var pos + 1);
+
+  . skip brackets if necessary :
+      IF var char =  open bracket
+         THEN INT VAR bracket counter := 1;
+              REP count bracket UNTIL bracket counter = 0 PER;
+              var pos := pos (record, ""33"", ""255"", var pos + 1);
+      FI;
+
+      . count bracket :
+          INT CONST open  := pos (record, open  bracket, var pos + 1),
+                    close := pos (record, close bracket, var pos + 1);
+          IF open > 0
+             THEN IF close > 0
+                     THEN IF open > close
+                             THEN close bracket found
+                             ELSE open  bracket found
+                          FI;
+                     ELSE open bracket found
+                  FI;
+             ELSE IF close > 0
+                     THEN close bracket found
+                     ELSE LEAVE get data types of input vars 
+                  FI;
+          FI;
+
+          . open bracket found :
+               bracket counter INCR 1;
+               var pos := open;
+
+          . close bracket found :
+               bracket counter DECR 1;
+               var pos := close;
+
+  . skip comma :
+      var pos := pos (record, ""33"", ""255"", var pos + 1);
+
+END PROC get data types of input vars;
+
+
+PROC begin scanning (FILE VAR basic file):
+  enable stop;
+  source file := basic file;
+  to first record (source file);
+  col (source file, 1);
+  IF eof (source file) 
+  THEN errorstop ("Datei ist leer") FI; 
+
+  defint chars := "";
+  defstr chars := ""; 
+  scope := "";                              (* DEF/mo *)
+  act stat no := 0;
+  read record (source file, record); 
+  rec len := length (record);
+  scan pos := 0; 
+  record no := 1;
+  eol generated := FALSE;
+  at line begin := TRUE;
+  IF listing
+    THEN line;
+         putline (record);
+         IF sysout <> ""
+           THEN cout (record no)
+         FI
+    ELSE cout (record no)
+  FI.
+
+END PROC begin scanning;
+ 
+PROC next statement:
+  IF eof (source file)
+  THEN errorstop (99, "")
+  ELSE eol generated := FALSE;
+       at line begin := TRUE;
+       down (source file);
+       read record (source file, record); 
+       rec len := length (record);
+       scan pos := 0; 
+       record no INCR 1;
+  FI;
+  IF listing
+    THEN putline (record);
+         IF sysout <> ""
+           THEN cout (record no)
+         FI
+    ELSE cout (record no)
+  FI.
+  
+END PROC next statement;
+
+PROC next symbol (TEXT VAR name, INT VAR no, type, DTYPE VAR data):
+  enable stop;
+  clear symbol;
+  IF eol generated
+  THEN next statement FI;
+
+  IF eol reached
+  THEN generate eol
+  ELIF at line begin CAND stat no found                          (* F15/rr *)
+  THEN generate stat no
+  ELSE generate chars FI  .
+
+clear symbol:
+  name := "";
+  no   := 0;
+  type := any;
+  data := void type  .
+ 
+eol reached:
+  scan pos := pos (record, ""33"", ""255"", scan pos+1); 
+  scan pos = 0  .
+
+generate eol :
+  IF eof (source file)
+  THEN name := "EOF";  no := eop;  type := eos
+  ELSE name := "EOL";  no := eol;  type := eos FI;
+  eol generated := TRUE  .
+
+stat no found:                                                   (* F15/rr *)
+  at line begin := FALSE;
+  pos ("0123456789", act char) <> 0 .
+ 
+generate stat no:                                                (* F15/rr *)
+  INT CONST next scan pos := last number pos;
+  name        := subtext (record, scan pos, next scan pos);
+  act stat no := int (name);
+  scan pos    := next scan pos;
+  no := act stat no;  type := stat no  .
+
+last number pos :                                                (* F15/rr *)
+  INT CONST high := pos (record, ""058"", ""255"", scan pos),
+            low  := pos (record, ""032"", ""047"", scan pos);
+  IF   high > 0
+       THEN IF low > 0
+               THEN min (high, low) - 1
+               ELSE high - 1
+            FI
+  ELIF low > 0
+       THEN low - 1
+       ELSE LENGTH record
+  FI .
+
+generate chars:
+  SELECT code (act char) OF
+  CASE 32: next symbol (name, no, type, data)            (* Space        *) 
+  CASE 34: generate text denoter                         (* "            *) 
+  CASE 39: generate eol                                  (* '            *)
+  CASE 42, 43, 45, 47, 92, 94, 61: generate operator     (* *,+,-,/,\,^,=*)
+  CASE 60: generate less op                              (*<, <=, <>     *) 
+  CASE 62: generate greater op                           (*>, >=         *)
+  CASE 46: treat point                                   (* .            *)
+  CASE 48, 49, 50, 51, 52, 53, 54, 55, 56, 57: 
+           generate numeric const                        (* 0  -  9      *)
+  CASE 58: generate eos                                  (* :            *)
+  CASE 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+       82, 83, 84, 85, 86, 87, 88, 89, 90,  97, 98, 99, 100, 101, 102, 103,
+       104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
+       118, 119, 120, 121, 122,               (* small and large letters *)
+       generate res word or id
+  OTHERWISE generate delimiter END SELECT  .
+
+generate text denoter:
+  get text const (name, data);
+  type := const  .
+
+generate operator:
+  name := act char;  no := code (name);  type := operator  .
+
+generate less op:
+  IF next char = "="
+  THEN name := "<=";  no := less equal; skip char
+  ELIF next char = ">"
+  THEN name := "<>";  no := unequal;    skip char
+  ELSE name := "<";  no := less FI;
+  type := operator  .
+
+generate greater op:
+  IF next char = "="
+  THEN name := ">=";  no := greater equal;  skip char 
+  ELSE name := ">";  no := greater;  FI;
+  type := operator  .
+
+treat point:
+  IF pos ("0123456789", next char) <> 0
+    THEN generate numeric const
+    ELSE name := ".";
+         no := point;
+         type := del
+  FI.
+
+generate numeric const:
+  get numeric const (name, data);
+  type := const  .
+
+last name char:
+  name SUB LENGTH name  .
+
+generate eos:
+  name := ":";  no := eos;  type := eos  .
+
+generate res word or id:
+  get name chars;
+  IF reserved (deshift name, no, type)
+    THEN IF type = res word AND no = go
+           THEN treat go
+         FI
+    ELSE IF function name
+           THEN data := ftn datatype;
+                type := user fn
+           ELSE data := var datatype (deshift (name) SUB 1, last name char);
+                type := var or array
+         FI;
+         put name (scope, deshift name, no)
+  FI.
+
+treat go:
+  next symbol (new name, no, type, data);
+  IF no = to AND type = res word
+    THEN name CAT new name;
+         no := goto
+  ELIF no = sub AND type = res word
+    THEN name CAT new name;
+         no := gosub
+    ELSE scan error (102, name, "")
+  FI.
+
+get name chars:
+  TEXT VAR deshift name :: "";
+  INT VAR begin of name :: scan pos;
+  FOR scan pos FROM scan pos UPTO rec len
+  WHILE name chars found
+  REP deshift name CAT deshifted char PER;
+  scan pos DECR 1;
+  name := subtext (record, begin of name, scan pos).
+
+name chars found:
+  pos (name chars, act char) > 0  .
+
+function name:
+  subtext (deshift name, 1, 2) = "fn"  .
+
+ftn datatype:
+  IF last name char = "$"
+  THEN text type
+  ELIF last name char = "%"
+  THEN int type
+  ELSE real type FI  .
+
+var or array:
+  IF array name
+  THEN name CAT "()";
+       deshift name CAT "()";                                (* F30/rr *)
+       array
+  ELSE var FI  .
+
+array name:
+  next scan char = "("  .
+
+deshifted char:
+  letter := act char;
+  IF letter >= "A" AND letter <= "Z"
+  THEN code (code (letter) + 32)
+  ELSE letter FI  .
+
+generate delimiter:
+  name := act char;  no := code (name);  type := del  .
+
+next scan char: record SUB pos (record, ""33"", ""255"", scan pos+1). 
+next char: (record SUB scan pos + 1)  .
+act char: record SUB scan pos  .
+skip char:  scan pos INCR 1  .
+END PROC next symbol;
+
+DTYPE PROC var datatype (TEXT CONST first name char, last name char) :
+
+  IF last name char = "!" OR last name char = "#"
+  THEN real type
+  ELIF last name char = "$"
+  THEN text type
+  ELIF last name char = "%"
+  THEN int type
+  ELIF pos (defint chars, first name char) > 0
+  THEN int type
+  ELIF pos (defstr chars, first name char) > 0
+  THEN text type
+  ELSE real type FI  .
+
+END PROC var datatype;
+
+BOOL PROC next data (TEXT VAR data text, DTYPE VAR data type) :  (* F17/rr *)
+
+  data type := void type;
+  IF   no more data
+       THEN scan pos  := rec len;
+            data text := "";
+            FALSE
+  ELIF quoted string
+       THEN get quoted string;
+            TRUE
+       ELSE get unquoted string;
+            TRUE
+  FI
+
+  . no more data :
+      scan pos := pos (record, ""33"", ""255"", scan pos+1);
+      scan pos = 0
+
+  . quoted string :
+      (record SUB scan pos) = quote
+
+  . get quoted string :
+      get text const (data text, data type);
+
+  . get unquoted string :
+      INT CONST comma or colon pos 1 := position of comma or colon minus one;
+      data text := compress (subtext (record, scan pos, comma or colon pos 1));
+      scan pos  := comma or colon pos 1;
+
+  . position of comma or colon minus one :
+      INT CONST colon pos := pos (record, colon, scan pos),
+                comma pos := pos (record, comma, scan pos);
+      IF colon pos > 0
+         THEN IF comma pos > 0
+                 THEN min (colon pos, comma pos) - 1
+                 ELSE colon pos - 1
+              FI
+         ELSE IF comma pos > 0
+                 THEN comma pos - 1
+                 ELSE LENGTH record
+              FI
+      FI
+
+END PROC next data;
+
+PROC get numeric const (TEXT VAR value, DTYPE VAR data):
+  get sign;
+  get const;
+  check datatype  .
+
+get sign:
+  IF act char = "-"
+  THEN value := "-";
+       scan pos INCR 1
+  ELIF act char = "+"
+  THEN value := "+";
+       scan pos INCR 1
+  ELSE value := "" FI  .
+
+get const:
+  get digits;
+  get point;
+  get digits;
+  get exponent  .
+
+get digits:
+  FOR scan pos FROM scan pos UPTO rec len
+  WHILE digit found
+  REP value CAT act char PER  .
+
+get point:
+  IF act char = "."
+  THEN value CAT ".";
+       scan pos INCR 1
+  ELIF pos (exponent chars, act char) > 0
+  THEN value CAT ".0"
+  ELSE LEAVE get const FI  .
+
+get exponent:
+  IF pos (exponent chars, act char) > 0                 (* F1/rr *)
+  THEN value CAT "e";
+       scan pos INCR 1;
+       evtl get sign;
+       get digits
+  FI  .
+
+evtl get sign:
+  IF act char = "+" OR act char = "-"
+  THEN value CAT act char;
+       scan pos INCR 1
+  FI  .
+
+digit found:
+  "0" <= act char AND act char <= "9"  .
+
+check datatype:
+  IF act char = "%" 
+  THEN IF integer ok (value)
+       THEN data := int type
+       ELSE scan error (2, value, "INT-Konstante nicht korrekt") FI
+  ELIF act char = "!" OR act char = "#"
+  THEN IF real ok (value)
+       THEN data := real type
+       ELSE scan error (2, value, "REAL-Konstante nicht korrekt") FI
+  ELIF integer ok (value)
+  THEN scan pos DECR 1;  data := int type
+  ELIF real ok (value)
+  THEN scan pos DECR 1;
+       data := real type
+  ELSE scan error (2, value, "Numerische Konstante nicht korrekt") FI  . 
+
+act char: record SUB scan pos  .
+END PROC get numeric const;
+ 
+PROC get text const (TEXT VAR value, DTYPE VAR data):
+  INT CONST quote 1 := scan pos;
+  scan pos := pos (record, """", scan pos+1);
+  IF quote 1 < scan pos
+  THEN value := subtext (record, quote 1+1, scan pos-1);
+       data := text type
+  ELSE scan error (15, subtext (record, quote 1), "("" fehlt)") FI  .
+
+END PROC get text const;
+
+BOOL PROC integer ok (TEXT VAR zahl):
+  disable stop;
+  i dummy := int (zahl);
+  IF is error
+  THEN clear error;
+       FALSE
+  ELIF last conversion ok
+  THEN zahl := ""0""0"";
+       replace (zahl, 1, i dummy);
+       TRUE
+  ELSE FALSE FI  .
+
+END PROC integer ok;
+
+BOOL PROC real ok (TEXT VAR zahl):
+  disable stop;
+  r dummy := real (zahl);
+  IF is error
+  THEN clear error;
+       FALSE
+  ELIF last conversion ok
+  THEN zahl := ""0""0""0""0""0""0""0""0"";
+       replace (zahl, 1, r dummy);
+       TRUE
+  ELSE FALSE FI  .
+
+END PROC real ok;
+
+PROC basic error (INT CONST no, TEXT CONST name, addition):
+  basic error ("Compiler", no, record no, act stat no, name, addition, TRUE)
+END PROC basic error;
+
+PROC basic error (INT CONST no, TEXT CONST name, addition, BOOL CONST leave statement):
+  basic error ("Compiler", no, record no, act stat no, name, addition, leave statement)
+END PROC basic error;
+
+PROC scan error (INT CONST no, TEXT CONST name, addition):
+  basic error ("Scanner", no, record no, act stat no, name, addition, TRUE)
+END PROC scan error;
+
+PROC basic warning (TEXT CONST warning text):               (* mo *)
+  basic warning (record no, act stat no, warning text)
+END PROC basic warning;
+
+PROC basic list (BOOL CONST t):
+  listing := t 
+END PROC basic list;
+
+BOOL PROC basic list:
+  listing
+END PROC basic list;
+
+PROC set scope (TEXT CONST new scope):                          (* DEF/mo *)
+  scope := new scope
+END PROC set scope;
+
+TEXT PROC scanner scope:                                        (* DEF/mo *)
+  scope
+END PROC scanner scope;
+
+END PACKET basic scanner;
+
+
+PACKET basic stat no DEFINES init stat no,    (* Autor: Heiko Indenbirken *)
+                             stat no pos,     (* Stand: 27.10.1987/rr/mo  *)
+                             label pos,
+                             all stat no:
+
+LET nil = "";
+
+TEXT VAR found stat no :: nil;
+INT VAR i, akt stat no :: 0, found no :: 0;
+
+PROC init stat no (FILE VAR f, INT VAR error no):                (* F21/rr *)
+(*Die Datei 'f' muß im 'modify-Mode' sein.                               *)
+  INT VAR line no;
+  akt stat no := -1;                                             (* F28/rr *)
+  found no := 0;
+  found stat no := nil;
+  error no := 0;                                                 (* F21/rr *)
+  to first record (f);
+  col (f, 1);
+  disable stop;
+  FOR line no FROM 1 UPTO 4000
+  REP exec (PROC (TEXT CONST, INT CONST) check, f, line no);
+      IF is error THEN check error FI;
+      IF eof (f)
+      THEN LEAVE init stat no
+      ELSE down (f) FI
+  PER;
+
+. check error :                                                  (* F21/rr *)
+    IF error code = 100
+       THEN clear error;
+            error no INCR 1;
+       ELSE LEAVE init stat no;
+    FI;
+
+END PROC init stat no;
+
+PROC check (TEXT CONST record, INT CONST line no):
+  IF statement no vorhanden
+  THEN remember statement no FI  .
+
+statement no vorhanden:                                          (* F15/rr *)
+   INT CONST first number pos := pos (record, ""048"", ""057"", 1);
+   first number pos > 0 CAND first number pos = first non blank pos .
+
+first non blank pos :                                            (* F15/rr *)
+   pos (record, ""033"", ""255"", 1) .
+
+remember statement no:
+  get statement no;
+  IF neue nummer ist groesser als vorherige
+  THEN akt stat no := neue nummer;
+       cout (neue nummer);
+       found no INCR 1;
+       found stat no CAT mki (neue nummer)
+  ELSE basic error ("Stat no", 81, line no, neue nummer, number,
+                    "Letzte Zeilennummer davor: " + text (akt stat no), TRUE)
+  FI  .
+
+get statement no :                                               (* F15/rr *)
+  disable stop;
+  TEXT CONST number := subtext (record, first number pos, last number pos);
+  INT VAR neue nummer := int (number);
+  IF NOT last conversion ok OR is error
+  THEN clear error;
+       basic error ("Stat no", 80, line no, akt stat no, number,
+                    "Die Zeilennummer muß im Bereich 0-32767 liegen", TRUE)
+  FI;
+  enable stop .
+
+last number pos :                                                (* F15/rr *)
+  INT CONST high := pos (record, ""058"", ""255"", first number pos),
+            low  := pos (record, ""032"", ""047"", first number pos);
+  IF   high > 0
+       THEN IF low > 0
+               THEN min (high, low) - 1
+               ELSE high - 1
+            FI
+  ELIF low > 0
+       THEN low - 1
+       ELSE LENGTH record
+  FI .
+
+neue nummer ist groesser als vorherige:
+  neue nummer > akt stat no  .
+
+END PROC check;
+
+INT PROC stat no pos (INT CONST stat no):
+  FOR i FROM found no DOWNTO 1
+  REP IF (found stat no ISUB i) = stat no
+      THEN LEAVE stat no pos WITH i FI
+  PER;
+  0
+END PROC stat no pos;
+
+INT PROC label pos (INT CONST stat no):
+  FOR i FROM found no DOWNTO 1
+  REP IF (found stat no ISUB i) = stat no
+      THEN LEAVE label pos WITH i FI
+  PER;
+  basic error (8, text (stat no), nil);                         (* F16/rr *)
+  0
+END PROC label pos;
+
+PROC all stat no (TEXT VAR stat no, INT VAR no):
+  stat no := found stat no;
+  no      := found no
+END PROC all stat no;
+
+END PACKET basic stat no;
+
+PACKET basic storage DEFINES init storage,     (* Autor: Heiko Indenbirken *)
+                             next local adr,   (* Stand: 12.06.86          *)
+                             next ref,
+                             local adr,
+                             local storage,
+                             type size,
+                             quiet type:         
+                                              
+                                              
+
+LET ref length = 2;
+
+INT VAR quiet size, quiet align;
+ADDRESS VAR loc adr, free loc adr;
+DTYPE VAR quiet value;
+identify ("QUIET", quiet size, quiet align, quiet value);
+
+PROC init storage:
+  free loc adr := LOC 0;
+  loc adr      := LOC 0;
+
+END PROC init storage;
+
+(*        Verwaltung der lokalen Addressen für Zwischenergebnisse        *)
+ADDRESS PROC next local adr (DTYPE CONST type):
+  INT VAR type len :: type size (type);
+  loc adr := free loc adr;
+  adjust (loc adr, type len);
+  free loc adr := loc adr + type len;
+  loc adr  .
+
+END PROC next local adr;
+
+ADDRESS PROC next ref:
+  loc adr := free loc adr;
+  adjust (loc adr, ref length);
+  free loc adr := loc adr + ref length;
+  loc adr  .
+
+END PROC next ref;
+
+ADDRESS PROC local adr:
+   loc adr
+END PROC local adr;
+
+INT PROC local storage:
+  int (subtext (dump (free loc adr), 6))
+END PROC local storage;
+
+INT PROC type size (DTYPE CONST type):
+   IF type = int type OR type = bool type
+   THEN 1
+   ELIF type = row type
+   THEN 2
+   ELIF type = real type
+   THEN 4
+   ELIF type = text type
+   THEN 8
+   ELIF type = quiet value
+   THEN quiet size
+   ELSE errorstop ("Unbekannter DTYPE: " + dump (type));  0 FI  .
+
+END PROC type size;
+
+DTYPE PROC quiet type:
+  quiet value
+END PROC quiet type;
+
+END PACKET basic storage;
+
+PACKET basic identify DEFINES                 (* Autor: Heiko Indenbirken *)
+                                              (* Stand: 20.08.1987/rr/mo  *)
+                           identify,
+                           convert paramfield,
+                           dump ftn,
+                           is basic function:            (* mo *)
+
+LET nil = "";
+
+LET ENTRY = STRUCT (TEXT param, INT no, next, OPN opn, DTYPE result);
+
+ROW 256 ENTRY VAR ftn table;
+
+clear ftn table;
+init ftn names;
+init int operator;
+init real operator;
+init text operator;
+init predefined funktions;
+
+PROC dump ftn (INT CONST n, TEXT VAR param, INT VAR no, next,
+               OPN VAR opn, DTYPE VAR result):
+ param  := ftn table [n].param;
+ no     := ftn table [n].no;
+ next   := ftn table [n].next;
+ opn    := ftn table [n].opn;
+ result := ftn table [n].result
+
+END PROC dump ftn;
+
+PROC identify (INT CONST ftn no, first, params, OPN VAR operation, BOOL VAR found):
+  TEXT VAR param;
+  INT VAR pos :: min (ftn no, 256);
+  convert paramfield (first, params, param);
+  REP IF param = ftn table [pos].param  AND ftn no = ftn table [pos].no
+      THEN declare (params+1, ftn table [pos].result);
+           declare (params+1, 1);
+           operation := ftn table [pos].opn;
+           found     := TRUE;
+           LEAVE identify
+      ELSE pos := ftn table [pos].next FI
+  UNTIL pos <= 0 PER;                                           (* F14/rr *)
+  operation := nop;
+  found     := FALSE  .
+
+END PROC identify;
+
+PROC next free entry (INT VAR free pos):
+  FOR free pos FROM 1 UPTO 256
+  REP IF ftn table [free pos].next < 0 AND ftn table [free pos].no = 0  (* mo *)
+    THEN LEAVE next free entry FI
+  PER;
+  errorstop ("Überlauf der Funktionstabelle")  .
+
+END PROC next free entry;
+
+PROC convert paramfield (INT CONST first, params, TEXT VAR param):
+  INT VAR i;
+  param := nil;
+  FOR i FROM first UPTO params
+  REP param CAT datatype PER  .
+
+datatype:
+  DTYPE CONST data :: dtype (i);
+  IF data = int type
+  THEN "I"
+  ELIF data = real type
+  THEN "R"
+  ELIF data = text type
+  THEN "T"
+  ELIF data = bool type
+  THEN "b"
+  ELSE errorstop ("Falscher DTYPE: " + dump (data));
+       nil
+  FI  .
+
+END PROC convert paramfield;
+
+PROC convert paramfield (TEXT CONST params, INT CONST first):
+  INT VAR i;
+  FOR i FROM first UPTO first+length (params)-1
+  REP parameter (i, this type, 1, GLOB 0) PER  .
+
+this type:
+  IF (params SUB i) = "I"
+  THEN int type
+  ELIF (params SUB i) = "R"
+  THEN real type
+  ELIF (params SUB i) = "T"
+  THEN text type
+  ELSE errorstop ("Unbekannter Typ: " + params);
+       undefined type
+  FI  .
+
+END PROC convert paramfield;
+
+PROC init op (INT CONST ftn no, TEXT CONST param, ftn name):
+  IF elan opn found
+  THEN insert new opn in chain
+  ELSE errorstop ("PROC " + ftn name + " (" + param + ") nicht gefunden") FI  .
+
+elan opn found:
+  OPN VAR opn;
+  BOOL VAR found;
+  convert paramfield (param, 1);
+  identify (ftn name, 1, length (param), opn, found);
+  found  .
+
+insert new opn in chain:
+  INT VAR ftn pos :: ftn no;
+  REP IF end of chain found
+      THEN cat new entry in chain
+      ELIF free entry in chain found
+      THEN cover this entry
+      ELSE next entry FI
+  UNTIL ftn pos <= 0 PER  .
+
+end of chain found:
+  act entry.next = 0  .
+
+cat new entry in chain:
+  INT VAR free pos;
+  next free entry (free pos);
+  act entry.next := free pos;
+  free entry := ENTRY:(param, ftn no, 0, opn, dtype (LENGTH param+1));
+  LEAVE insert new opn in chain  .
+
+free entry in chain found:
+  act entry.next = -1 .
+
+cover this entry:
+  act entry := ENTRY:(param, ftn no, 0, opn, dtype (LENGTH param+1));
+  LEAVE insert new opn in chain  .
+
+next entry:
+  ftn pos := act entry.next  .
+
+act entry: ftn table [ftn pos]  .
+free entry: ftn table [free pos]  .
+
+END PROC init op;
+
+BOOL PROC is basic function (INT CONST ftn no):         (* mo *)
+
+  pos (ftn names, code (ftn no)) <> 0
+
+END PROC is basic function;
+
+.
+clear ftn table:
+  INT VAR k;
+  FOR k FROM 1 UPTO 256
+  REP ftn table [k] := ENTRY:(nil, 0,-1, nop, undefined type) PER  .
+
+init ftn names:
+  TEXT CONST ftn names :: "+-*/\^<=>"28""29""30""249""251""252""253""254"" +
+                          ""128""130""131""134""136""137""141""143""142"" +
+                          ""153""154""155""157""159""161""166""168""170""171""172"" +
+                          ""174""175""178""179""182""184""183""187""192"" +
+                          ""201""202""204""205""206""207""208""211""212"" +
+                          ""215""221""228""229""230""231""232""233"";
+  FOR k FROM 1 UPTO length (ftn names)
+  REP ftn table [ftn pos] := ENTRY:(nil, ftn pos,-1, nop, void type) PER  .
+
+ftn pos:
+  code (ftn names SUB k)  .
+
+init int operator:
+  init op ( 43, "II", "+");
+  init op ( 45, "II", "-");
+  init op ( 42, "II", "*");
+  init op ( 47, "II", "/");                 (* mo *)
+  init op ( 92, "II", "DIV");               (* mo *)
+  init op ( 94, "II", "^");
+  init op ( 61, "II", "EQU");
+  init op ( 29, "II", "UEQ");
+  init op ( 60, "II", "LES");
+  init op ( 28, "II", "LEQ");
+  init op ( 62, "II", "GRE");
+  init op ( 30, "II", "GEQ");
+  init op (249, "II", "MOD");               (* mo *)
+  init op (251, "II", "AND");
+  init op (252, "II", "OR");
+  init op (253, "II", "XOR");
+  init op (254, "II", "EQV");
+  init op (255, "II", "IMP").
+
+init real operator:
+  init op ( 43, "RR", "+");
+  init op ( 45, "RR", "-");
+  init op ( 42, "RR", "*");
+  init op ( 47, "RR", "/");
+  init op ( 92, "RR", "DIV");              (* mo *)
+  init op ( 94, "RR", "^");
+  init op ( 61, "RR", "EQU");
+  init op ( 29, "RR", "UEQ");
+  init op ( 60, "RR", "LES");
+  init op ( 28, "RR", "LEQ");
+  init op ( 62, "RR", "GRE");
+  init op ( 30, "RR", "GEQ");
+  init op (249, "RR", "realmod").          (* mo *)
+
+init text operator:
+  init op ( 43, "TT", "+");
+  init op ( 61, "TT", "EQU");
+  init op ( 29, "TT", "UEQ");
+  init op ( 60, "TT", "LES");
+  init op ( 28, "TT", "LEQ");
+  init op ( 62, "TT", "GRE");
+  init op ( 30, "TT", "GEQ")  .
+
+init predefined funktions:
+  init op (128, "I", "abs");
+  init op (128, "R", "abs");
+  init op (130, "T", "asc");
+  init op (131, "R", "arctan");
+  init op (131, "I", "arctan");
+  init op (134, "I", "cdbl");
+  init op (134, "R", "cdbl");
+  init op (136, "I", "chr");
+  init op (136, "R", "chr");
+  init op (137, "R", "cint");
+  init op (137, "I", "cint");
+  init op (141, "R", "cos");
+  init op (141, "I", "cos");
+  init op (143, "T", "cvi");
+  init op (142, "T", "cvd");
+# init op (153, "", "eof");#                                     (* File *)
+  init op (154, "", "errorline");
+  init op (155, "", "errorcode");
+  init op (157, "R", "exp");
+  init op (157, "I", "exp");
+  init op (159, "R", "floor");
+  init op (159, "I", "floor");
+  init op (161, "I", "fre");
+  init op (161, "R", "fre");
+  init op (161, "T", "fre");
+  init op (166, "I", "hex");
+  init op (166, "R", "hex");
+  init op (168, "", "incharety");
+  init op (170, "I", "inchars");
+  init op (170, "R", "inchars");
+  init op (171, "TT", "instr");
+  init op (171, "ITT", "instr");
+  init op (171, "RTT", "instr");
+  init op (172, "I", "ent");
+  init op (172, "R", "ent");
+  init op (174, "TI", "left");
+  init op (174, "TR", "left");
+  init op (175, "T", "length");
+# init op (178, "I", "line no");#                                (* File *)
+  init op (179, "R", "ln");
+  init op (179, "I", "ln");
+  init op (182, "TII", "mid");
+  init op (182, "TI", "mid");
+  init op (182, "TRR", "mid");
+  init op (182, "TR", "mid");
+  init op (183, "I", "mkd");
+  init op (183, "R", "mkd");
+  init op (187, "I", "oct");
+  init op (187, "R", "oct");
+  init op (192, "I", "pos");
+  init op (192, "R", "pos");
+  init op (201, "TI", "right");
+  init op (201, "TR", "right");
+  init op (202, "", "rnd");                                      (* F12/rr *)
+  init op (202, "I", "rnd");
+  init op (202, "R", "rnd");
+  init op (204, "I", "sign");
+  init op (204, "R", "sign");
+  init op (205, "R", "sin");
+  init op (205, "I", "sin");
+  init op (206, "I", "space");
+  init op (206, "R", "space");
+  init op (207, "I", "space");
+  init op (207, "R", "space");
+  init op (208, "R", "sqrt");
+  init op (208, "I", "sqrt");
+  init op (211, "I", "basictext");
+  init op (211, "R", "basictext");
+  init op (212, "IT", "string");
+  init op (212, "RT", "string");
+  init op (212, "II", "string");
+  init op (212, "RR", "string");
+  init op (212, "RI", "string");
+  init op (212, "IR", "string");
+  init op (215, "R", "tan");
+  init op (215, "I", "tan");
+  init op (221, "T", "val");                                      (* F18/rr *)
+  init op (228, "", "errormessage");
+  init op (229, "", "csrlin");
+  init op (230, "I", "lpos");
+  init op (230, "R", "lpos");
+  init op (231, "", "time");
+  init op (232, "", "date");
+  init op (233, "", "timer").
+
+END PACKET basic identify;
+
+PACKET basic data handling                          (* Autor: R. Ruland   *)
+                                                    (* Stand: 23.10.87/mo *)
+       DEFINES init data,       
+               data line,       
+               data, read,
+               restore,
+               next int,
+               next real,
+               next text:       
+
+LET (*                     R e s u l t    T y p e n                      *) 
+    stat code = 0,   stat char = ""0"",
+    data code = 1,   data char = ""1"",
+    text code = 2,   text char = ""2"",
+
+    int  overflow  =  4,
+    real overflow  =  6;
+
+INT VAR type;
+TEXT VAR data text :: "", number text;
+
+PROC init data:
+
+   data text := ""
+
+END PROC init data;
+
+
+PROC init data (TEXT VAR data, INT VAR data pos):
+
+  data      := data text;
+  data pos  := 1
+
+END PROC init data;
+
+
+PROC restore (TEXT CONST data, INT VAR data pos, INT CONST line no):
+
+  INT CONST data length :: LENGTH data;
+  data pos := 1;
+  WHILE data pos < data length
+  REP type := code (data SUB data pos);
+      data pos INCR 1;
+      SELECT type OF
+         CASE stat code            : IF int value (data, data pos) >= line no
+                                        THEN LEAVE restore FI
+         CASE data code, text code : data pos INCR int value (data, data pos)
+         OTHERWISE : errorstop (1051, "Fehlerhaften Dateneintrag gefunden: " + text (type))
+      ENDSELECT;
+  PER;
+  errorstop (1004, "RESTORE: Keine DATA-Anweisung in oder nach Zeile " + text (line no)
+                     + " gefunden");
+
+END PROC restore;
+
+ 
+INT PROC next int (TEXT CONST data, INT VAR data pos):
+
+   number text := next text (data, data pos);
+   disable stop;
+   INT VAR result := int (number text);
+   IF   is error
+        THEN IF error code = int overflow THEN handle overflow FI;
+   ELIF NOT last conversion ok CAND number text <> "" 
+        THEN errorstop (1013, "READ: Falscher Datentyp, " + number text + " ist kein INT")
+   FI;
+   result
+
+   . handle overflow :
+       clear error;
+       result := result value;
+       IF cursor x pos <> 1 THEN next line FI;
+       basic out ("WARNUNG : INT-Überlauf bei READ, gefunden: " + number text);
+       next line;
+
+       . result value :
+           IF (number text SUB 1) = "-" THEN minint ELSE maxint FI
+
+END PROC next int;
+
+ 
+REAL PROC next real (TEXT CONST data, INT VAR data pos):
+
+   number text := next text (data, data pos);
+   disable stop;
+   REAL VAR result := val (number text);
+   IF   is error
+        THEN IF error code = real overflow OR error code = int overflow  (* <- wegen Fehler in REAL PROC real (T C) *)
+                THEN handle overflow or underflow
+             FI;
+   ELIF NOT last conversion ok CAND number text <> "" 
+        THEN errorstop (1013, "READ: Falscher Datentyp, " + number text + " ist kein REAL")
+   FI;
+   result
+
+   . handle overflow or underflow :                          (* F23/rr *) 
+       clear error;
+       IF cursor x pos <> 1 THEN next line FI;
+       basic out ("WARNUNG : " + overflow or underflow + " bei READ, gefunden: " + number text);
+       next line;
+
+   . overflow or underflow :
+       IF is overflow                            
+          THEN result := sign * (max real - 0.99999999999994e120); (* <- wegen Fehler in TEXT PROC text (R C) *)
+               "REAL-Überlauf"
+          ELSE result := 0.0;
+               "REAL-Unterlauf"
+       FI
+
+       . sign :
+           IF (number text SUB 1) = "-" THEN -1.0 ELSE 1.0 FI
+
+       . is overflow :
+           INT VAR exponent pos := pos (number text, "E"); 
+           IF exponent pos = 0 THEN exponent pos := pos (number text, "e") FI;
+           IF exponent pos = 0
+              THEN TRUE
+              ELSE (number text SUB (exponent pos + 1)) <> "-"
+           FI
+
+END PROC next real;
+
+
+TEXT PROC next text (TEXT CONST data, INT VAR data pos):
+
+   INT CONST len :: int value (data, data pos);
+   data pos INCR len;
+   subtext (data, data pos-len, data pos-1)
+
+END PROC next text;
+
+
+INT PROC int value (TEXT CONST data, INT VAR data pos):
+
+   data pos INCR 2;
+   subtext (data, data pos-2, data pos-1) ISUB 1
+
+END PROC int value;
+ 
+
+PROC data line (INT CONST line no):
+
+  data text CAT stat char;
+  data text CAT mki (line no)
+
+END PROC data line;
+
+
+PROC data (TEXT CONST string, DTYPE VAR data type) :
+
+  data text CAT data + mki (length (string));
+  data text CAT string;
+
+  . data :
+      IF   data type = void type
+           THEN data char
+      ELIF data type = text type
+           THEN text char
+           ELSE errorstop (1051, "Unbekannter DTYPE: " + dump (data type)); ""
+      FI
+
+END PROC data;
+
+
+PROC read (TEXT CONST data, INT VAR data pos, INT VAR i):
+
+  type := code (data SUB data pos);
+  data pos INCR 1;
+  IF   data pos >= LENGTH data
+       THEN errorstop (1004, "Keine Daten mehr für READ")
+  ELIF type = data code
+       THEN i := next int (data, data pos)
+  ELIF type = stat code
+       THEN data pos INCR 2;
+            read (data, data pos, i)
+       ELSE errorstop (1013, "READ: Falscher Datentyp, " + data string (data,data pos) + " ist kein INT")
+  FI;
+
+END PROC read;
+
+
+PROC read (TEXT CONST data, INT VAR data pos, REAL VAR r):
+
+  type := code (data SUB data pos);
+  data pos INCR 1;
+  IF   data pos >= LENGTH data
+       THEN errorstop (1004, "Keine Daten mehr für READ")
+  ELIF type = data code
+       THEN r := next real (data, data pos)
+  ELIF type = stat code
+       THEN data pos INCR 2;
+            read (data, data pos, r)
+       ELSE errorstop (1013, "READ: Falscher Datentyp, " + data string (data,data pos) + " ist kein REAL")
+  FI;
+
+END PROC read;
+
+
+PROC read (TEXT CONST data, INT VAR data pos, TEXT VAR t):
+
+  type := code (data SUB data pos);
+  data pos INCR 1;
+  IF   data pos >= LENGTH data
+       THEN errorstop (1004, "Keine Daten mehr für READ")
+  ELIF type = data code OR type = text code
+       THEN t := next text (data, data pos)
+  ELIF type = stat code
+       THEN data pos INCR 2;
+            read (data, data pos, t)
+       ELSE errorstop (1013, "READ: Falscher Datentyp, " + data string (data,data pos) + " ist kein TEXT")
+  FI;
+
+END PROC read;
+ 
+
+TEXT PROC data string (TEXT CONST data, INT VAR data pos):
+
+  IF type = text code
+     THEN """" + next text (data, data pos) + """"
+     ELSE "unbekannter DTYPE: " + text (type)
+  FI
+
+END PROC data string;
+
+END PACKET basic data handling;
+
+
+PACKET basic odds and ends DEFINES trace,       (* Autor: Heiko Indenbirken *)
+                                   start basic, (* Stand: 26.10.1987/rr/mo  *)
+                                   end basic,
+                                   loop end,
+                                   basic stop:
+
+(*                            Fehlerbehandlung                           *)
+
+PROC trace (INT CONST stat no):
+  basic out ("[" + text (stat no) + "]")
+
+END PROC trace;
+
+(*Laufzeitprozeduren                                                     *)
+PROC start basic:
+  set line nr (0);
+  initialize random (0.1);                                   (* F26/rr *)
+  init output;
+  init input
+
+END PROC start basic;
+
+PROC end basic:
+  IF is error
+    THEN switch back to old sysout state
+  FI  .
+
+END PROC end basic; 
+
+(*                          Schleifenüberprüfung                         *)
+BOOL PROC loop end (REAL CONST x, max, step) :
+  IF step > 0.0
+  THEN x > max
+  ELSE x < max FI
+
+END PROC loop end;
+
+BOOL PROC loop end (INT CONST x, max, step) :
+  IF step > 0
+  THEN x > max
+  ELSE x < max FI
+
+END PROC loop end;
+
+PROC basic stop (INT CONST stat no):
+  basic out ("STOP beendet das Programm in Zeile " + text (stat no));
+  next line
+
+END PROC basic stop;
+
+END PACKET basic odds and ends
+
diff --git a/basic/BASIC.Compiler b/basic/BASIC.Compiler
new file mode 100644
index 0000000..d4e4c21
--- /dev/null
+++ b/basic/BASIC.Compiler
@@ -0,0 +1,2305 @@
+(***************************************************************************)
+(*                                                                         *)
+(*           Dritte von drei Dateien des EUMEL-BASIC-Systems               *)
+(*                                                                         *)
+(*           Autor: Heiko Indenbirken                                      *)
+(*           Überarbeitet von: Rudolf Ruland und Michael Overdick          *)
+(*                                                                         *)
+(*           Stand: 27.10.1987                                             *)
+(*                                                                         *)
+(***************************************************************************)
+
+PACKET basic compiler DEFINES basic,          (* Autor: Heiko Indenbirken *)
+                              basic version:  (* Stand: 27.10.1987/rr/mo  *)
+
+PROC basic version :
+
+putline (""13" "15"              BASIC - Compiler     Version 1.1   (27.10.1987)              "14"");
+
+END PROC basic version;
+
+LET compiler msg  = "       *******  ENDE DER UEBERSETZUNG  *******",
+    compiler err msg = " Fehler entdeckt";
+
+LET (*                    S y m b o l    T y p e n                       *)
+    any     = 0,  const   = 1,  var     = 2,  array   = 3,  denoter = 5,
+    res word= 8,  operator= 9,  eos     = 10, del     =11,  stat no = 12,
+    result const = 13,                                           (* F3/rr *)
+    user fn = 20;     (* DEF/mo *)
+
+LET (*                    S y m b o l z e i c h e n                      *)
+    plus         = 43,  minus        = 45,  mult          = 42,
+    div          = 47,  backslash    = 92,  exponent      = 94,
+    equal        = 61,  semicolon    = 59,  comma         = 44,
+    numbersign   = 35,  open bracket = 40,  close bracket = 41,
+    eol          = 13,  eop          = 14,  mod op        = 249;
+
+LET  (*                   Reservierte Worte                              *)
+  as s       = 129,  base s     = 132,  call s     = 133,  chain s    = 135,
+  clear s    = 138,  close s    = 139,  common s   = 140,  data s     = 144,
+  def s      = 145,  defdbl s   = 146,  defint s   = 147,  defsng s   = 148,
+  defstr s   = 149,  dim s      = 150,  else s     = 151,  end s      = 152,
+  eof s      = 153,  error s    = 156,  field s    = 158,  for s      = 160,
+  get s      = 162,  gosub s    = 164,  goto s     = 165,  if s       = 167,  (* F2/rr *)
+  input s    = 169,  kill s     = 173,  let s      = 176,  line in s  = 177,
+  lprint s   = 180,  lset s     = 181,  mid s      = 182,  name s     = 185,
+  next s     = 186,  on s       = 188,  open s     = 189,  option s   = 190,
+  print s    = 193,  put s      = 194,  rand s     = 195,  read s     = 196,
+  rem s      = 197,  restore s  = 198,  resume s   = 199,  return s   = 200,
+  rset s     = 203,  step s     = 209,  stop s     = 210,  swap s     = 213,
+  tab s      = 214,  then s     = 216,  to s       = 217,  troff s    = 218,
+  tron s     = 219,  using s    = 220,  wait s     = 222,  wend s     = 223,
+  while s    = 224,  width s    = 225,  write s    = 226,  not        = 250,
+  cls s      = 227,  usr        = 234,  sub        = 235;     (* mo *)
+
+LET nil   = "",
+    intern error = 51;
+
+LET SYMBOL = STRUCT (TEXT name, INT no, type, ADDRESS adr, DTYPE data);
+ADDRESS CONST niladr :: LOC -4;
+SYMBOL CONST nilsymbol :: SYMBOL : (nil, any, any, nil adr, void type);
+SYMBOL VAR symb;
+BOOL VAR found;
+OPN VAR opn;
+
+TEXT OP NAME (SYMBOL CONST val):
+  IF val.type = const
+  THEN constant value
+  ELIF val.type = stat no
+  THEN text (val.no)
+  ELSE val.name FI  .
+
+constant value:
+  IF val.data = int type AND length (val.name) = 2
+  THEN text (val.name ISUB 1)
+  ELIF val.data = real type AND length (val.name) = 8
+  THEN text (val.name RSUB 1)
+  ELSE val.name FI  .
+
+END OP NAME;
+
+PROC careful error (INT CONST no, TEXT CONST name, addition):    (* DEF/mo *)
+  IF at end of statement
+    THEN basic error (no, name, addition)
+    ELSE basic error without leaving statement
+  FI.
+
+at end of statement:
+  symb.type = eos.
+
+basic error without leaving statement:
+  basic error (no, name, addition, FALSE);
+  error no INCR 1.
+
+END PROC careful error;
+
+(*                       P r e c o m p i l e r                           *)
+PROC next symbol:
+  symb.adr := niladr;
+  next symbol (symb.name, symb.no, symb.type, symb.data); 
+
+  IF symb.no = end symbol AND symb.type = res word
+  THEN symb.no   := -symb.no;
+       symb.type := eos;
+  FI
+END PROC next symbol;
+
+PROC skip (INT CONST symbol, type):
+  IF symb.type = type AND symb.no = symbol
+  THEN next symbol
+  ELSE basic error (2, NAME symb, name of (symbol) + " erwartet")  FI  .
+END PROC skip;
+
+PROC get letter (SYMBOL VAR symbol):
+  IF symb.type = var AND (LENGTH symb.name) = 1
+  THEN symbol := symb;
+       next symbol
+  ELSE basic error (2, NAME symb, "Buchstabe erwartet, " + type of (symb.type) + " gefunden") FI  .
+
+END PROC get letter;
+
+PROC get var (SYMBOL VAR symbol):
+  IF symb.type = var
+  THEN variable (symbol)
+  ELIF symb.type = array
+  THEN array var (symbol)
+  ELSE basic error (2, NAME symb, "Variable erwartet, " + type of (symb.type) + " gefunden") FI  .
+
+END PROC get var;
+
+PROC get expr (SYMBOL VAR symbol):
+  get expression (symbol, 0)
+END PROC get expr;
+
+PROC get const (SYMBOL VAR symbol, DTYPE CONST data):
+  IF symb.type = const
+  THEN symbol := symb;
+       declare const (symbol, data);                             (* F3/rr *)
+       next symbol
+  ELSE basic error (2, NAME symb, "Konstante erwartet, " + type of (symb.type) + " gefunden")  FI  .
+ 
+END PROC get const;
+
+PROC get var (SYMBOL VAR symbol, DTYPE CONST data):
+  get var (symbol);
+  convert (symbol, data)
+END PROC get var;
+
+PROC get expr (SYMBOL VAR symbol, DTYPE CONST data):
+  get expression (symbol, 0);
+  convert (symbol, data)
+END PROC get expr;
+
+PROC get expression (SYMBOL VAR result, INT CONST last prio):
+  get single result;
+  WHILE symb.type = operator AND higher priority
+  REP get dyadic operand;
+      gen dyadic operation
+  PER  .
+
+get single result:
+  INT VAR prio;
+  SELECT symb.type OF
+  CASE var:      variable (result)
+  CASE array:    array var (result)
+  CASE const:    get const
+  CASE operator: get monadic operator
+  CASE res word: basic function (result)
+  CASE user fn:  user function (result)                      (* DEF/mo *)
+  OTHERWISE get bracket END SELECT  .
+
+get const:
+  result := symb;
+  declare const (result, result. data);                      (* F3/rr *)
+  next symbol  .
+
+get monadic operator:
+  get operator;
+  prio := monadic op prio;                                  (* mo *)
+  get monadic operand;
+  generate monadic operator  .
+
+monadic op prio:                                            (* mo *)
+  IF op no = not
+    THEN 6
+    ELSE 12
+  FI.
+
+get monadic operand:
+  SYMBOL VAR operand;
+  next symbol;
+  get expression (operand, prio).
+
+generate monadic operator:
+(*                      Mögliche Ops:  +, - und NOT                      *)
+  parameter (1, operand.data, const, operand.adr); 
+  parameter (2, operand.data, var, next local adr (operand.data));
+  parameter (3, void type, const, nil adr);
+
+  IF op no = plus
+  THEN result := operand
+  ELIF op no = minus
+  THEN generate minus op
+  ELIF op no = not
+  THEN generate not op
+  ELSE basic error (2, op name, "Kein monadischer Operator") FI  .
+
+generate minus op:
+  IF operand.data = int type
+  THEN apply (1, 2, int minus)
+  ELIF operand.data = real type
+  THEN apply (1, 2, real minus)
+  ELSE basic error (82, op name, NAME operand + " : " + dump (operand.data)) FI;
+  result := SYMBOL:(op name, 0, result const, local adr, operand.data)  .
+
+generate not op:
+  IF operand.data = int type
+  THEN apply (1, 1, int not opn)
+  ELIF operand.data = real type
+  THEN apply (1, 1, real not opn)
+  ELSE basic error (82, op name, NAME operand + " : " + dump (operand.data)) FI;
+  result := SYMBOL:(op name, 0, result const, local adr, operand.data)  .
+
+get operator:
+  INT CONST op no :: symb.no;
+  TEXT CONST op name :: symb.name  .
+
+higher priority:
+  get operator;
+  prio := dyadic op prio;
+  prio > last prio  .
+
+dyadic op prio:
+  IF is bool op (op no)                 THEN bool op prio
+  ELIF op no = plus OR op no = minus    THEN 8
+  ELIF op no = mod op                   THEN 9
+  ELIF op no = backslash                THEN 10
+  ELIF op no = mult OR op no = div      THEN 11
+  ELIF op no = exponent                 THEN 13
+  ELSE (* relational operator *)             7
+  FI.
+
+bool op prio:
+  256 - op no.
+
+get bracket:
+  IF symb.type = del AND symb.no = open bracket
+  THEN next symbol
+  ELSE basic error (22, NAME symb, "") FI;
+  get expression (result, 0);
+  skip (close bracket, del)  .
+
+get dyadic operand:
+  next symbol;
+  get expression (operand, prio)  .
+
+gen dyadic operation:
+  convert operands;
+  identify dyadic operator;
+  generate dyadic operator  .
+
+convert operands:
+ DTYPE CONST op type :: type of operation;
+ convert (result, op type);
+ convert (operand, op type)  .
+
+type of operation:
+  IF is bool op (op no)
+  THEN int type
+  ELIF result.data = operand.data
+  THEN result.data
+  ELSE real type FI  .
+
+identify dyadic operator:
+  BOOL VAR local found;
+  OPN VAR local opn;
+  DTYPE VAR data;
+  parameter (1, result.data,  const, result.adr); 
+  parameter (2, operand.data, const, operand.adr);
+  identify (op no, 1, 2, local opn, local found);
+  IF NOT local found
+  THEN basic error (83, symbol of (op no),
+                    NAME result + " : " + dump (result.data) + " und " +
+                    NAME operand + " : " + dump (operand.data))
+  ELSE data := dtype (3) FI  .
+
+generate dyadic operator:
+  declare (3, var);
+  define (3, next local adr (data));
+  apply (3, push);
+  apply (1, 2, local opn);
+  result := SYMBOL:(op name, 0, result const, local adr, data)  .
+
+END PROC get expression;
+
+PROC variable (SYMBOL VAR symbol):
+   symbol := symb;
+   next symbol;
+   IF known (symbol.no)
+   THEN get adr from table
+   ELSE declare var (symbol, nil) FI  .
+
+get adr from table:
+  TEXT VAR defined dim;
+  remember (symbol.no, symbol.type, symbol.adr, symbol.data, defined dim)  .
+
+END PROC variable;
+
+PROC array var (SYMBOL VAR symbol field):
+(*           Aufbau der Dimensionsangaben in der Symboltabelle           *)
+(*               limit 1   [limit 2]...   Basis   Elemente               *)
+(*                    jeweils als 2 Byte Integer/Text                    *)
+(*                    Die Dimension ist dann   DIM/2-2                   *)
+  ROW 100 SYMBOL VAR indizes;
+  TEXT VAR limits;
+  INT VAR dim;
+
+  symbol field := symb;  next symbol;
+  get paramfield (indizes, dim, int type);
+
+  IF known (symbol field.no)
+  THEN check field dim and data
+  ELSE declare new field FI;
+  generate field index  .
+
+check field dim and data:
+  INT VAR type;
+  DTYPE VAR data;
+  remember (symbol field.no, type, symbol field.adr, data, limits);
+
+  IF old dim <> dim
+  THEN basic error (84, symbol field.name, "Dimensioniert in " + text (old dim) + " Dimensionen, gefundene Anzahl Indizes: " + text (dim))
+  ELIF NOT (symbol field.data = data)
+  THEN basic error (intern error, symbol field.name, dump (data) + " <=> " + dump (symbol field.data))
+  ELIF NOT (symbol field.type = type)
+  THEN basic error (intern error, symbol field.name, "Feld erwartet, " + type of (type) + " gefunden") FI  .
+
+old dim: (length (limits) DIV 2) - 2  .
+
+declare new field:
+  limits := dim * ""10""0"" + mki (array base) +
+            mki ((10 - array base + 1)**dim);
+  declare var (symbol field, limits)  .
+
+generate field index:
+  init field subscription;
+  FOR j FROM 1 UPTO dim
+  REP increase field index;
+      calc index length and limit;
+      calculate field pointer;
+      symbol field.adr := REF pointer
+  PER  .
+
+init field subscription:
+  ADDRESS VAR pointer :: next local adr (row type),
+              index adr :: next local adr (int type);
+  INT VAR j, elem length :: (limits ISUB (dim+2)) * typesize (symbol field.data),
+             elem limit,
+             elem offset :: 1 - (limits ISUB (dim+1));
+  BOOL CONST base zero := elem offset = 1  .
+
+increase field index:
+   IF base zero
+   THEN parameter (1, int type, const, index.adr);
+        parameter (2, int type, const, one value);
+        parameter (3, int type, var, index adr);
+        parameter (4, void type, const, nil adr);
+        apply (1, 3, int add);
+   ELSE index adr := index.adr FI  .
+
+index: indizes [j]  .
+
+calc index length and limit:
+  elem limit  := (limits ISUB j) + elem offset;
+  elem length := elem length DIV elem limit  .
+
+calculate field pointer:
+  parameter (1, int type, const, symbol field.adr);
+  parameter (2, int type, const, index adr);
+  parameter (3, int type, elem length);
+  parameter (4, int type, elem limit);
+  parameter (5, int type, const, pointer);
+  parameter (6, void type, const, nil adr);
+  apply (1, 5, subscript);
+
+END PROC array var;
+
+PROC get paramfield (ROW 100 SYMBOL VAR params list, INT VAR no):
+  skip (open bracket, del);
+  FOR no FROM 1 UPTO 100
+  REP get expression (params list [no], 0);
+      IF symb.type = del AND symb.no = close bracket
+      THEN next symbol;
+           LEAVE get paramfield
+      ELSE skip (comma, del) FI
+  PER  .
+
+END PROC get paramfield;
+
+PROC get paramfield (ROW 100 SYMBOL VAR params list, INT VAR no, DTYPE CONST data):
+  skip (open bracket, del);
+  FOR no FROM 1 UPTO 100
+  REP get expression (params list [no], 0);
+      convert (params list [no], data);
+      IF symb.type = del AND symb.no = close bracket
+      THEN next symbol;
+           LEAVE get paramfield
+      ELSE skip (comma, del) FI
+  PER  .
+
+END PROC get paramfield;
+
+PROC examine access rights (ROW 100 SYMBOL VAR params list, INT CONST no):
+
+  INT VAR j;
+  FOR j FROM 1 UPTO no REP
+    IF params list [j].type = const OR params list [j].type = result const
+      THEN IF access (j) = 2
+             THEN basic error (103, NAME params list [j], "im " + text (j)
+                                     + ". Eintrag der Parameterliste")
+           FI
+    FI
+  PER
+
+END PROC examine access rights;
+
+PROC basic function (SYMBOL VAR ftn):                  (* Änd. 11.08.87, mo *)
+  init and check function;
+  IF symb.type = del AND symb.no = open bracket
+    THEN get paramfield (params list, number params);
+  FI;
+  apply function  .
+
+init and check function:
+  ROW 100 SYMBOL VAR params list;
+  INT VAR number params :: 0;
+  BOOL CONST is usr :: symb.no = usr;
+  IF is usr
+    THEN check proc name
+  FI;
+  ftn := symb;
+  next symbol   .
+
+check proc name:
+  next symbol;
+  IF symb.type = array
+    THEN symb.name := subtext (symb.name, 1, LENGTH symb.name-2)
+  ELIF symb.type <> var
+    THEN basic error (2, NAME symb, "Prozedurname erwartet")
+  FI.
+
+apply function:
+  OPN VAR ftn local opn;
+  BOOL VAR ftn found;
+  INT CONST result :: number params+1;
+
+  INT VAR j;
+  FOR j FROM 1 UPTO number params
+  REP parameter (j, params list [j].data, const, params list [j].adr) PER;
+  IF is usr
+    THEN identify proc;
+         examine access rights (params list, number params);
+    ELSE identify function
+  FI;
+  
+  ftn.adr := next local adr (ftn.data);
+
+  declare (result, var);
+  define (result, ftn.adr);
+  apply (result, push);
+  apply (1, number params, ftn local opn).
+
+identify proc:
+  identify (deshift (ftn.name), 1, number params, ftn local opn, ftn found);
+  ftn.data := dtype (result);
+  IF NOT ftn found
+    THEN basic error (99, ftn.name, "Parameter angegeben: " + param list (1, number params))
+  ELIF ftn.data = void type
+    THEN basic error (5, ftn.name, "Die Prozedur liefert keinen Wert")
+  ELIF NOT (ftn.data = int type) AND NOT (ftn.data = real type) AND NOT (ftn.data = text type)
+    THEN basic error (5, ftn.name, "Der Typ des Resultats ist nicht erlaubt, gefunden: "
+                                   + dump (dtype (result)))
+  FI.
+
+identify function:
+  identify (ftn.no, 1, number params, ftn local opn, ftn found);
+  IF ftn found
+    THEN ftn.data := dtype (result)
+  ELIF is basic function (ftn.no)
+    THEN basic error (98, ftn.name, "Argument(e) angegeben: " + param list (1, number params))
+    ELSE basic error (22, ftn.name, "Anweisung(sbestandteil) gefunden")
+  FI.
+
+END PROC basic function;
+
+PROC user function (SYMBOL VAR result):                     (* DEF/mo *)
+  check if function defined;
+  get arguments if expected;
+  gosub (user function label);
+  copy result.
+
+check if function defined:
+  TEXT CONST scope :: name of (symb.no) + "?";
+  IF NOT known (symb.no)
+    THEN basic error (18, symb.name, "")
+  ELIF scanner scope = scope
+    THEN basic error (85, symb.name, "")
+  FI.
+
+get arguments if expected:
+  INT VAR param counter;
+  TEXT VAR dim text;
+  result := symb;
+  remember (symb.no, symb.type, result.adr, result.data, dim text);
+  INT VAR number of params :: LENGTH dim text DIV 2 - 1;
+  next symbol;
+  IF number of params > 0
+    THEN get all arguments
+  ELIF symb.no = open bracket AND symb.type = del
+    THEN basic error (5, symb.name, "Kein Argument erwartet")
+  FI.
+
+get all arguments:
+  IF symb.no <> open bracket OR symb.type <> del
+    THEN basic error (5, NAME symb, text (number of params) + " Argument(e) erwartet")
+  FI;
+  next symbol;
+  FOR param counter FROM 2 UPTO number of params REP
+    get one argument;
+    skip comma;
+  PER;
+  get one argument;
+  skip close bracket.
+
+get one argument:
+  SYMBOL VAR ftn param;
+  ftn param.no := dim text ISUB param counter;
+  remember (ftn param.no, ftn param.type, ftn param.adr, ftn param.data, ftn param.name);
+  IF ftn param.type <> var
+    THEN basic error (intern error, name of (ftn param.no), "Parametereintrag fehlerhaft")
+  FI;
+  SYMBOL VAR expr res;
+  get expr (expr res, ftn param.data);
+  apply move (ftn param.adr, expr res.adr, ftn param.data).
+
+skip comma:
+  IF symb.no = close bracket AND symb.type = del
+    THEN basic error (5, symb.name, text (number of params) + " Argumente erwartet")
+  ELIF symb.no <> comma OR symb.type <> del
+    THEN basic error (2, NAME symb, "  , in Argumentenliste erwartet")
+  FI;
+  next symbol.
+
+skip close bracket:
+  IF symb.no = comma AND symb.type = del
+    THEN basic error (5, symb.name, "Nur " + text (number of params) + " Argument(e) erwartet")
+  ELIF symb.no <> close bracket OR symb.type <> del
+    THEN basic error (2, NAME symb, "  ) nach Argumentenliste erwartet")
+  FI;
+  next symbol.
+
+user function label:
+  label list [dim text ISUB 1].
+
+copy result :
+  apply move (next local adr (result.data), result.adr, result.data);
+  result.adr := local adr.
+
+END PROC user function;
+
+PROC apply move (ADDRESS CONST dest adr, source adr, DTYPE CONST datype):
+  parameter (1, datype, var, dest adr);
+  parameter (2, datype, const, source adr);
+  parameter (3, void type, const, nil adr);
+
+  IF datype = int type
+  THEN apply (1, 2, int move)
+  ELIF datype = real type
+  THEN apply (1, 2, real move)
+  ELIF datype = text type
+  THEN apply (1, 2, text move)
+  ELSE basic error (2, "=", "Unbekannter Datentyp: " + dump (datype)) FI  .
+
+END PROC apply move;
+
+PROC convert (SYMBOL VAR symbol, DTYPE CONST to data):           (* F3/rr *)
+  IF   to data = from data
+  THEN
+  ELIF symbol.type = const
+  THEN declare const (symbol, to data)
+  ELIF to data = int type 
+  THEN make int
+  ELIF to data = real type
+  THEN make real
+  ELSE basic error (13, NAME symbol, dump (to data) + " erwartet, " + dump (from data) + " gefunden") FI  .
+
+from data : symbol.data  .
+
+make real :
+  IF   symbol.data = int type
+  THEN parameter (1, symbol.data, const, symbol.adr);
+       parameter (2, real type, var, next local adr (real type));
+       parameter (3, void type, const, nil adr);
+       apply (1, 1, int to real);
+       symbol.adr  := local adr;
+       symbol.data := real type
+  ELSE basic error (13, NAME symbol, dump (to data) + " erwartet, " + dump (from data) + " gefunden") FI  .
+
+make int :
+  IF   symbol.data = real type
+  THEN parameter (1, symbol.data, const, symbol.adr);
+       parameter (2, int type, var, next local adr (int type));
+       parameter (3, void type, const, nil adr);
+       apply (1, 1, real to int);
+       symbol.adr  := local adr;
+       symbol.data := int type
+  ELSE basic error (13, NAME symbol, dump (to data) + " erwartet, " + dump (from data) + " gefunden") FI  .
+
+END PROC convert;
+
+PROC declare const (SYMBOL VAR symbol constant, DTYPE CONST data):
+  convert symb value;
+  IF new constant
+  THEN declare this constant
+  ELSE get table entry FI  .
+
+convert symb value:
+  IF data = symbol constant.data
+  THEN LEAVE convert symb value
+  ELIF data = int type AND symbol constant.data = real type
+  THEN symbol constant.name := mki (symbol constant.name RSUB 1);
+  ELIF data = real type AND symbol constant.data = int type
+  THEN symbol constant.name := mkd (symbol constant.name ISUB 1);
+  ELIF data = text type AND symbol constant.data = int type
+  THEN symbol constant.name := text (symbol constant.name ISUB 1)
+  ELIF data = text type AND symbol constant.data = real type
+  THEN symbol constant.name := text (symbol constant.name RSUB 1)
+  ELSE basic error (13, NAME symbol constant, dump (data) + " erwartet, "
+                          + dump (symbol constant.data) + " gefunden") FI;
+  symbol constant.data := data  .
+
+new constant:
+(*                 Konstanten werden wie folgt abgelegt:                 *)
+(*                           INT:   § HL                                 *)
+(*                           REAL:  § MMMMMMME                           *)
+(*                           TEXT:  § Text                               *)
+  put name ("§ " + symbol constant.name, symbol constant.no);
+  NOT known (symbol constant.no)  .
+
+declare this constant:
+  IF data = int type
+  THEN allocate denoter (symbol constant.adr, symbol constant.name ISUB 1)
+  ELIF data = real type
+  THEN allocate denoter (symbol constant.adr, symbol constant.name RSUB 1)
+  ELIF data = text type
+  THEN allocate denoter (symbol constant.adr, symbol constant.name) FI;
+  recognize (symbol constant.no, const, symbol constant.adr, data, nil)  .
+
+get table entry:
+  INT VAR table type;
+  TEXT VAR table dim;
+  remember (symbol constant.no, table type, symbol constant.adr, symbol constant.data, table dim);
+  IF table dim <> nil
+  THEN basic error (intern error, NAME symbol constant,  "Dimension in Tabelle ungleich niltext")
+  ELIF NOT (symbol constant.data = data)
+  THEN basic error (intern error, NAME symbol constant, "Falscher DTYPE in Tabelle, erw: " + dump (data)
+                        + ", gef: " + dump (symbol constant.data)) FI  .
+
+END PROC declare const;
+
+PROC declare var (SYMBOL VAR symbol var, TEXT CONST dim):               (* F4/rr *)
+  allocate variable;
+  recognize (symbol var.no, symbol var.type, symbol var.adr, symbol var.data, dim) .
+
+allocate variable :
+  symbol var.adr := next local adr (symbol var.data);
+  IF dim <> nil
+     THEN INT VAR index;
+          ADDRESS VAR dummy;
+          FOR index FROM 2 UPTO no of elements
+             REP dummy := next local adr (symbol var.data) PER;
+  FI .
+
+no of elements:
+  (dim ISUB (LENGTH dim DIV 2)) .
+END PROC declare var;
+
+PROC parameter (INT CONST p, DTYPE CONST d type, INT CONST value):
+  declare (p, d type);
+  declare (p, denoter);
+  define (p, value);
+END PROC parameter;
+
+PROC apply  (INT CONST first, number params, TEXT CONST name):
+  identify (name, first, number params, opn, found);
+  IF NOT found
+  THEN errorstop (1051, "PROC " + name + ", Parameter: " + param list (first, number params) + ", nicht gefunden!") FI;
+  apply (first, number params, opn)
+
+END PROC apply;
+
+PROC clear local stack :                                         (* F4/rr *)
+
+  define local variables;
+  clear index;
+  define (rep); index incr one;
+                if local storage less or equal index then goto end;
+                get cell address; 
+                clear cell;
+                apply (rep);
+  define (end);
+  clear cell address;
+
+  . define local variables :
+      LABEL VAR rep, end;
+      ADDRESS VAR index;
+      declare (rep); declare (end);
+      allocate variable (index, type size (int type));
+
+  . clear index :
+      parameter (1, int type, var, index);
+      apply (1, 1, clear);
+
+  . index incr one :
+      parameter (1, int type, var, index);
+      apply (1, 1, incone);
+
+  . if local storage less or equal index then goto end :
+      parameter (1, int type, const, loc storage);
+      parameter (2, int type, const, index);
+      apply (1, 2, lsequ);
+      apply (end, TRUE);
+
+  . get cell address :
+      parameter (1, int type, const, LOC 2);
+      parameter (2, int type, const, index);
+      parameter (3, int type, 1);
+      parameter (4, int type, 16000);
+      parameter (5, int type, const, LOC 0);
+      apply (1, 5, subscript);
+
+  . clear cell :
+      parameter (1, int type, var, REF LOC 0);
+      apply (1, 1, clear);
+
+  . clear cell address :
+      parameter (1, int type, var, LOC 0);
+      apply (1, 1, clear);
+      parameter (1, int type, var, LOC 1);
+      apply (1, 1, clear);
+
+END PROC clear local stack;
+
+(*                                M a i n                                *)
+(* ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃ *)
+(*                         C o m p i l e r                               *)
+(* *****              G l o b a l e   V a r i a b l en             ***** *)
+INT VAR end symbol :: 0,  error no :: 0, act stat no :: 0, array base :: 0;
+BOOL VAR basic trace, was warning;
+ADDRESS VAR data pos, data text;
+
+
+(*            Globale Operationen                                        *)
+OPN VAR basic init, basic frame, basic module, ret, equal op,
+        int minus, real minus, int not opn, real not opn,
+        trace op, ln op, push,
+        int incr, real incr, int add,
+        int move, real move, text move, test,
+        real to int, int to real, subscript,
+        clear, incone, lsequ,                                    (* F4/rr *)
+        basic out text;
+
+(*                             Parameter VOID                            *)
+  init ("RTN", 1, 0, ret);
+
+(*                             Parameter INT                             *)
+  declare (1, int type);
+  init ("intnot", 1, 1, int not opn);         (* mo *)
+  init ("PP",  1, 1, push);
+  init ("LN", 1, 1, ln op);
+  init ("real", 1, 1, int to real);
+  init ("TEST", 1, 1, test);
+  init ("CLEAR", 1, 1, clear); 
+  init ("INCONE", 1, 1, incone); 
+  init ("trace", 1, 1, trace op);
+
+(*                           Parameter INT INT                           *)
+  declare (2, int type);
+  init ("COMPLINT", 1, 2, int minus);
+  init ("MOVE", 1, 2, int move); 
+  init ("INC", 1, 2, int incr);
+  init ("EQU", 1, 2, equal op);
+  init ("LSEQU", 1, 2, lsequ); 
+
+(*                         Parameter INT INT INT                         *)
+  declare (3, int type);
+  init ("ADD", 1, 3, int add);
+
+(*                             Paramter REAL                             *)
+  declare (1, real type);
+  init ("realnot", 1, 1, real not opn);       (* mo *)
+  init ("cint", 1, 1, real to int);
+
+(*                          Parameter REAL REAL                          *)
+  declare (2, real type);
+  init ("COMPLREAL", 1, 2, real minus);
+  init ("FMOVE", 1, 2, real move);
+  init ("INCR", 1, 2, real incr);
+
+(*                             Parameter TEXT                            *)
+  declare (1, text type);
+  init ("basicout", 1, 1, basic out text);
+
+(*                           Paramter TEXT TEXT                          *)
+  declare (2, text type);
+  init ("TMOVE", 1, 2, text move);
+
+(*             Parameter ADDRESS INT DENOTER DENOTER ADDRESS             *)
+  declare (3, denoter);
+  declare (4, denoter);
+  init ("SUBSCRIPT", 1, 5, subscript);
+
+PROC init (TEXT CONST name, INT CONST local from, number params, OPN VAR local opn):
+  identify (name, local from, number params, local opn, found);
+  IF NOT found
+  THEN errorstop (1051, "PROC init (TC, IC, IC, OPN VAR): OPN für """ + name + """ nicht gefunden") FI
+END PROC init;
+
+(*                           Runtime Konstanten                          *)
+  ADDRESS VAR true value, false value, niltext value,
+              zero value, one value, two value, three value,
+              comma value, int one value, real one value,
+              loc storage;                                  (* F4/rr *)
+
+(* +++++                     Globale Variablen                     +++++ *)
+  BOOL VAR proc found;
+  INT VAR deftype, field elems, i, params;
+  ROW 100 SYMBOL VAR param;
+  SYMBOL VAR base size, begin range, end range, expr result, field, filename,
+             from, len, image, label, old name, new name,
+             question, size, tab pos, var result;
+  TEXT VAR constant, field size, proc name;
+
+(*                            Label-Verwaltung                           *)
+LET label list size = 4100;
+BOUND ROW label list size LABEL VAR label list;
+DATASPACE VAR label ds;
+INITFLAG VAR label init :: FALSE;
+INT VAR last label no;
+
+(* *****           I n t e r f a c e     P r o z d u r e n         ***** *)
+PROC basic:
+  basic (last param)
+END PROC basic;
+
+PROC basic (TEXT CONST basic file name):
+  basic (basic file name, nil)
+END PROC basic;
+
+PROC basic (TEXT CONST basic file name, prog name):
+  IF NOT exists (basic file name)
+    THEN errorstop ("""" + basic file name + """ gibt es nicht")
+    ELSE FILE VAR basic file :: sequential file (modify, basic file name); (* F5/rr *)
+         headline (basic file, basic file name);
+         last param (basic file name);
+         basic (basic file, prog name)
+  FI;
+
+END PROC basic;
+
+PROC basic (FILE VAR source file, TEXT CONST prog name):
+  IF prog name <> nil CAND prog name is not a tag                (* F5/rr *)
+     THEN errorstop ("unzulässiger Programmname : """ + prog name + """");
+  FI;
+  modify (source file);                                          (* F5/rr *)
+  disable stop;
+  init label table;
+  store status;
+  coder on (data allocation by coder); 
+  compile (source file, progname);
+  restore status;
+  start basic prog  . 
+
+prog name is not a tag :                                         (* F5/rr *)
+  LET tag = 1;
+  INT  VAR symbol type;
+  TEXT VAR symbol name;
+  scan (prog name);
+  next symbol (symbol name, symbol type);
+  symbol name <> prog name OR symbol type <> tag .
+
+init label table:
+  IF NOT initialized (label init)
+  THEN label ds    := nilspace;
+       label list  := label ds;
+  FI  .
+
+store status:
+  INT CONST source line :: line no (source file), 
+            source col  :: col (source file);
+  BOOL CONST check status :: check;
+  check on  .
+
+restore status:
+  to line (source file, source line);
+  col (source file, source col);
+  IF NOT check status
+  THEN check off FI  .
+
+start basic prog:
+  IF error no > 0 OR is error
+    THEN basic error end
+    ELSE normal end
+  FI;
+  close (source file)  .
+
+basic error end:
+  coder off (FALSE, FALSE, nop);
+  IF is error
+    THEN put error;
+         clear error
+    ELSE display (""13""10""10"");                            (* F20/rr *)
+         display (text (error no) + compiler err msg);
+         display (""13""10""10"");
+         display (compiler msg);
+         display (""13""10"");
+         IF sysout <> ""
+            THEN line (2);
+                 put (text (error no) + compiler err msg);
+                 line (2);
+                 put (compiler msg);
+                 line
+         FI
+  FI;
+  show file and error  .
+
+show file and error:                                             (* F20/rr *)
+  IF anything noted CAND command dialogue
+     THEN noteedit (source file);
+  FI;
+  errorstop (nil) .
+
+normal end:
+  IF prog name = nil
+  THEN run basic proc
+  ELSE insert basic proc FI;
+  IF warnings AND was warning
+    THEN show file and error
+  FI.
+
+run basic proc:
+  coder off (FALSE, TRUE, basic frame); 
+  display (""13""10"") .
+ 
+insert basic proc:
+  coder off (TRUE, TRUE, basic frame);
+  coder on (data allocation by coder);
+  coder off (FALSE, FALSE, basic init);
+  display (""13""10"") .
+
+END PROC basic;
+
+PROC compile (FILE VAR source file, TEXT CONST progname):
+  enable stop;
+  init compiler;
+  init basic prog;
+
+  begin scanning (source file);
+  next symbol;
+  get statement group (eop);
+  end compiling  .
+ 
+init compiler:
+  end symbol  := 0;
+  error no    := 0;
+  act stat no := 0;
+  array base  := 0;
+  basic trace := FALSE;
+  was warning := FALSE;
+
+  init storage;
+  init label;
+  init data;
+  init table .
+ 
+init label:                                                      
+  TEXT VAR local stat no;
+  INT VAR stat nos;
+  init stat no (source file, error no);                          (* F21/rr *)
+  IF error no > 0 THEN LEAVE compile FI;
+  all stat no (local stat no, stat nos);
+  FOR i FROM 1 UPTO stat nos
+  REP declare (label list [i]) PER;
+  last label no := stat nos.                                     (* DEF/mo *)
+
+init basic prog:
+  LIB VAR packet;
+  declare (basic packet name, packet);
+  define (packet);
+  parameter (1, void type, const, nil adr);
+  declare (basic init);
+  IF progname = nil
+  THEN declare (basic frame)
+  ELSE declare (progname, 1, 0, basic frame) FI;
+  declare (basic module);
+  declare runtime const;
+  declare basic init;
+  declare basic frame;
+  declare basic module  .
+
+basic packet name:
+  IF progname <> ""
+    THEN "BASIC." + progname
+    ELSE "BASIC"
+  FI.
+
+declare runtime const:
+  allocate variable (data text, type size (text type));
+  allocate variable (data pos, type size (int type));
+  allocate variable (loc storage, type size (int type));         (* F4/rr *)
+
+  allocate denoter (true value, 0);
+  allocate denoter (false value, -1);
+  allocate denoter (niltext value, nil);
+  allocate denoter (one value, 1);
+  allocate denoter (two value, 2);
+  allocate denoter (three value, 3);
+  allocate denoter (real one value, 1.0);
+  allocate denoter (comma value, ",");
+
+  zero value    := true value;
+  int one value := one value  .
+
+declare basic init:
+  begin module;
+  define (basic init, 4);
+  parameter (1, text type, var, data text); 
+  parameter (2, int type, var, data pos);
+  apply (1, 2, "initdata");
+  parameter (1, void type, const, nil adr);
+  apply (1, 0, ret);
+  end module  .
+
+declare basic frame:
+  begin module;
+  define (basic frame, 4);
+
+  IF prog name = nil
+  THEN parameter (1, void type, const, nil adr);
+       apply (1, 0, basic init);
+  FI;
+ 
+  declare (1, int type);
+  declare (1, const);
+  define (1, 0);
+  parameter (2, void type, const, nil adr);
+  apply (1, 1, ln op);
+
+  apply (1, 0, "disablestop");
+  apply (1, 0, "startbasic");
+
+  parameter (1, int type, var, data pos);
+  parameter (2, int type, const, one value);
+  parameter (3, void type, const, nil adr);
+  apply (1, 2, int move);
+
+  parameter (1, void type, const, nil adr);
+  apply (1, 0, basic module);
+  apply (1, 0, "endbasic");
+  parameter (1, void type, const, nil adr);
+  apply (1, 0, ret);
+  end module  .
+
+declare basic module:
+  LABEL VAR start lab;
+  begin module;
+  define (basic module);
+  declare (start lab);
+  apply (1, 0, "enablestop");
+  gosub (start lab);
+  parameter (1, void type, const, nil adr);
+  apply (1, 0, "returnerror");                                   (* mo *)
+  define (start lab);
+  clear local stack .                                            (* F4/rr *)
+
+end compiling:
+  parameter (1, void type, const, nil adr);
+  apply (1, 0, ret); 
+  define (loc storage, local storage - 1);                       (* F4/rr *)
+  set length of local storage (basic module, max (2, local storage));  (* F4/rr *)
+  IF error no = 0
+  THEN end module FI  .
+
+END PROC compile;
+
+PROC get statement group (INT CONST new symbol): 
+(* 'get statement group' compiliert das ganze Programm bis zum Auftreten *)
+(* von 'end symbol'                                                      *)
+  disable stop;
+  new end symbol;
+  get all basic lines;
+  old end symbol  .
+
+new end symbol:
+  INT CONST old symbol :: end symbol;
+  end symbol := new symbol  .
+
+old end symbol:
+  end symbol := old symbol  .
+
+get all basic lines:
+  REP get basic line;
+ 
+      IF is error
+      THEN error handling
+      ELIF symb.type = eos
+      THEN check this eos FI
+  PER  .
+
+error handling:                                                  (* F20/rr *)
+  IF error in basic program 
+       THEN error no INCR 1
+  ELIF end of source file
+       THEN clear error;
+            LEAVE get all basic lines
+  ELIF halt from terminal
+       THEN LEAVE get statement group
+       ELSE error no INCR 1;
+            handle internal error;
+            LEAVE get statement group
+  FI;
+  clear error;
+  scope compulsory (TRUE);                                      (* DEF/mo *)
+  set scope ("");                                               (* DEF/mo *)
+  next statement;
+  next symbol  .
+
+error in basic program:
+  errorcode = 101.
+
+end of source file:
+  errorcode = 99.
+
+halt from terminal:
+  errorcode = 1.
+
+handle internal error :                                          (* F20/rr *)
+  TEXT VAR error :: "BASIC-Compiler ERROR";
+  IF errorcode <> 0
+  THEN error CAT " #" + text (errorcode) FI;
+  IF errorline > 0
+  THEN error CAT " at " + text (errorline) FI;
+  error CAT "  : ";
+  error CAT errormessage;
+  IF sysout <> "" THEN putline (error) FI;
+  note (error);
+  noteline;
+  clear error;
+  errorstop (error).
+
+check this eos:
+  IF symb.no = eol
+  THEN next symbol
+  ELIF symb.no = -new symbol OR symb.no = eop
+  THEN LEAVE get all basic lines                      (* mo *)
+  ELSE basic error (intern error, NAME symb, "EOL erwartet, " +
+                    type of (symb.type) + " gefunden")
+  FI  .
+
+END PROC get statement group;
+
+PROC get basic line (INT CONST new symbol):
+(*Die Abbruchbedingungen werden neu gesetzt und bei Verlassen der        *)
+(*Prozedur zurückgesetzt.                                                *)
+  disable stop;
+  INT CONST old symbol :: end symbol;
+  end symbol := new symbol; 
+  get basic line;
+  end symbol := old symbol  .
+
+END PROC get basic line;
+
+PROC get basic line:
+(* 'get basic line' behandelt genau eine Zeile mit Zeilennummer.         *)
+  enable stop;
+  IF symb.type = stat no
+  THEN gen stat no (symb.no) FI;
+
+  REP get one basic statement PER  .
+ 
+get one basic statement:
+(* 'get one basic statement' behandelt genau ein Statement.              *)
+  IF symb.type = eos
+  THEN get end of statement
+  ELIF symb.type = res word OR symb.type = var OR symb.type = array
+  THEN get one statement
+  ELSE basic error (2, NAME symb, type of (symb.type) + " ohne Zusammenhang") FI  .
+
+get end of statement:
+  IF symb.no = eos
+  THEN next symbol
+  ELSE LEAVE get basic line FI  .
+
+get one statement:
+  IF symb.type = res word
+    THEN get res word statement
+  ELIF symb.type = var OR symb.type = array
+    THEN let statement
+  FI;
+  skip comma if else expected;
+  IF symb.type <> eos
+    THEN basic error (2, NAME symb, "EOS erwartet, " + type of (symb.type) + " gefunden")
+  FI.
+
+skip comma if else expected:
+  IF end symbol = else s AND symb.type = del AND symb.no = comma
+    THEN next symbol;
+         IF symb.type <> eos OR symb.no <> -else s
+           THEN basic error (2, NAME symb, "ELSE erwartet")
+         FI
+  FI.
+  
+get res word statement:
+  SELECT symb.no OF
+  CASE as s     : basic error (90, symb.name, "") 
+  CASE base s   : basic error (91, symb.name, "")
+  CASE call s,    
+       chain s  : call statement
+  CASE clear s  : not implemented
+  CASE close s  : not implemented
+  CASE cls s    : cls statement                           (* mo *)
+  CASE common s : not implemented
+  CASE data s   : data statement 
+  CASE def s    : def statement                           (* mo *)
+  CASE defint s,
+       defdbl s,
+       defsng s,
+       defstr s : def type statement
+  CASE dim s    : dim statement
+  CASE else s   : basic error (92, symb.name, "")
+  CASE end s    : end statement
+  CASE error s  : error statement
+  CASE field s  : not implemented
+  CASE for s    : for statement
+  CASE get s    : not implemented
+  CASE gosub s  : gosub statement
+  CASE goto s   : goto statement
+  CASE if s     : if statement
+  CASE input s  : input statement
+  CASE kill s   : kill statement
+  CASE let s    : let statement
+  CASE line in s: line statement
+  CASE lprint s : lprint statement                        (* mo *)
+  CASE l set s  : l set statement
+  CASE mid s    : mid statement
+  CASE name s   : name statement
+  CASE next s   : basic error (1, symb.name, "")
+  CASE on s     : on statement
+  CASE open s   : not implemented
+  CASE option s : option statement
+  CASE print s  : print statement
+  CASE put s    : not implemented
+  CASE rand s   : randomize statement
+  CASE read s   : read statement
+  CASE rem s    : rem statement
+  CASE restore s: restore statement 
+  CASE resume s : not implemented
+  CASE return s : return statement
+  CASE r set s  : r set statement
+  CASE step s   : basic error (93, symb.name, "")
+  CASE stop s   : stop statement
+  CASE sub      : basic error (101, symb.name, "")
+  CASE swap s   : swap statement
+  CASE tab s    : basic error (94, symb.name, "")
+  CASE then s   : basic error (95, symb.name, "")
+  CASE to s     : basic error (96, symb.name, "")
+  CASE troff s  : troff statement
+  CASE tron s   : tron statement
+  CASE using s  : basic error (97, symb.name, "")
+  CASE wait s   : not implemented
+  CASE wend s   : basic error (30, symb.name, "")
+  CASE while s  : while statement
+  CASE width s  : width statement
+  CASE write s  : write statement
+  OTHERWISE basic error (104, symb.name, "") END SELECT.
+  
+not implemented:
+  basic error (100, symb.name, "").
+
+call statement:
+(*CALL <proc name> [(<argument list>)]                                   *)
+  next symbol;
+  get proc name;
+  get proc parameter;
+  apply proc  .
+
+get proc name:
+  proc name := symb.name;
+  IF symb.type = array
+  THEN proc name := subtext (proc name, 1, LENGTH proc name-2) FI;
+  next symbol  .
+
+get proc parameter:
+  params := 0;
+  IF symb.type = del AND symb.no = open bracket
+  THEN get paramfield (param, params) FI  .
+
+apply proc:
+  OPN VAR proc opn;
+  FOR i FROM 1 UPTO params
+  REP parameter (i, param [i].data, const, param [i].adr) PER;
+  identify (deshift (proc name), 1, params, proc opn, proc found);
+
+  IF NOT proc found
+    THEN basic error (99, proc name, "Parameter angegeben: " + param list (1, params))
+  ELIF result found
+    THEN basic error (5, proc name, "Kein Resultat erlaubt (gefunden: " + dump (result data) + ")")
+  FI;
+
+  examine access rights (param, params);
+
+  parameter (params+1, void type, const, nil adr);
+  apply (1, params, proc opn)  .
+
+result found:
+  NOT (result data = void type)  .
+
+result data:
+  dtype (params+1)  .
+
+cls statement:
+(*CLS                                                                    *)
+  next symbol;
+  apply (1, 0, "nextpage").
+
+data statement:
+(*DATA <list of constants>                                               *)
+  DTYPE VAR const data;
+  data line (act stat no);
+  REP IF next data (constant, const data)
+      THEN data (constant, const data)
+      ELSE basic error (2, "EOL", "Daten fehlen !") FI;
+
+      next symbol;
+      IF symb.type = eos
+      THEN LEAVE data statement
+      ELIF symb.type <> del OR symb.no <> comma
+      THEN basic error (2, NAME symb, "  , erwartet") FI
+  PER  .
+
+def statement:                         (* DEF/mo *)
+(*DEF FN<name> [(parameter list)] = <function definition>                *)
+  get function name;
+  store label of function;
+  get all params;
+  get function definition.
+
+get function name:
+  next symbol;
+  IF symb.type <> user fn
+    THEN treat wrong function name
+  ELIF LENGTH symb.name <= 2
+    THEN basic error (2, symb.name, "Unerlaubter Funktionsname")
+  ELIF known (symb.no)
+    THEN basic warning ("Die Funktion """ + symb.name + """ wurde bereits definiert");
+         was warning := TRUE
+  FI;
+  SYMBOL VAR function :: symb;
+  function.name := name of (function.no).
+
+treat wrong function name:
+  IF symb.type = var OR symb.type = array
+    THEN basic error (2, symb.name, "Funktionsname muß mit FN beginnen")
+    ELSE basic error (2, NAME symb, "Funktionsname erwartet")
+  FI.
+
+store label of function:
+  IF last label no < label list size
+    THEN last label no INCR 1
+    ELSE errorstop ("Zu viele Label")
+  FI;
+  declare (label list [last label no]);
+  TEXT VAR dim text :: "";
+  dim text CAT last label no;
+  recognize (function.no, user fn, niladr, function.data, dim text).
+
+get all params:
+  set scope (function.name + "?");
+  next symbol;
+  IF symb.type = del AND symb.no = open bracket
+    THEN REP
+           try to get a param;
+           try to get del
+         UNTIL symb.no = close bracket OR
+                    (symb.type <> del AND symb.type <> var) PER;
+         skip close bracket
+  FI.
+
+try to get a param:
+  REP
+    IF symb.type <> var
+      THEN next symbol
+    FI;
+    IF symb.type <> var
+      THEN careful error (2, NAME symb, "Parametervariable erwartet");
+           IF symb.type <> del
+             THEN next symbol
+           FI
+      ELSE treat param
+    FI
+  UNTIL symb.type <> del OR symb.no = close bracket PER.
+
+treat param:
+  IF NOT known (symb.no) 
+    THEN declare var (symb, nil);
+  ELIF already appeared in param list
+    THEN careful error (89, symb.name, "");
+  FI;
+  dim text CAT symb.no.
+
+already appeared in param list:
+  INT VAR param counter;
+  FOR param counter FROM 2 UPTO LENGTH dim text DIV 2 REP
+    IF (dim text ISUB param counter) = symb.no
+      THEN LEAVE already appeared in param list WITH TRUE
+    FI
+  PER;
+  FALSE.
+
+try to get del:
+  IF symb.type = var
+    THEN next symbol
+  FI;
+  IF symb.type = var OR (symb.type = del CAND (symb.no <> comma AND symb.no <> close bracket))
+    THEN careful error (2, symb.name, "  , in Parameterliste erwartet")
+  FI.
+
+skip close bracket:
+  IF symb.type = del AND symb.no = close bracket
+    THEN next symbol
+    ELSE careful error (2, NAME symb, "  ) nach Parameterliste erwartet")
+  FI.
+
+get function definition:
+  scope compulsory (FALSE);
+  skip (equal, operator);
+  generate forward jump;
+  define this label;
+  get expr (expr result, function.data);
+  recognize (function.no, user fn, expr result.adr, function.data, dim text);
+  goret;
+  define (behind);
+  scope compulsory (TRUE);
+  set scope ("").
+
+generate forward jump:
+  LABEL VAR behind;
+  declare (behind);
+  apply (behind).
+
+define this label:
+  define (label list [last label no]).
+
+
+def type statement:
+(*DEFINT/DBL/SNG/STR <range(s) of letters>                              *)
+  deftype := symb.no;
+  next symbol;
+  REP get letter (begin range);
+      IF symb.type = operator AND symb.no = minus
+      THEN next symbol;
+           get letter (end range)
+      ELSE end range := begin range FI; 
+
+      IF name of (begin range.no) > name of (end range.no)
+      THEN basic error (87, begin range.name + "-" + end range.name, "") 
+      ELSE define chars (name of (begin range.no), name of (end range.no), data type) FI;
+
+      IF symb.type = eos
+      THEN LEAVE def type statement
+      ELSE skip (comma, del) FI
+  PER  .
+ 
+data type:
+  SELECT deftype OF
+  CASE defint s: int type
+  CASE defstr s: text type
+  OTHERWISE real type ENDSELECT  .
+
+ dim statement:
+(*DIM <list of subscripted var results>                                    *)
+  next symbol;
+  REP get field var;
+      get field size;
+      declare field;
+
+      IF symb.type = eos
+      THEN LEAVE dim statement
+      ELSE skip (comma, del) FI
+  PER  .
+
+get field var:
+  IF symb.type = array
+    THEN IF known (symb.no)
+           THEN basic error (10, symb.name, "")
+           ELSE field := symb;
+                next symbol
+         FI
+  ELIF symb.type = var
+    THEN basic error (2, symb.name, "Dimensionsangabe fehlt")
+    ELSE basic error (2, NAME symb, "Feldname erwartet")
+  FI.
+
+get field size:
+  field size := "";
+  field elems := 1;
+  skip (open bracket, del);
+
+  REP get const (size, int type);
+      INT CONST field limit :: size.name ISUB 1;
+      IF field limit < array base
+      THEN basic error (88, NAME size, "Die Obergrenze muß >= " +
+                                        text (array base) + " sein")
+      ELSE field size CAT (mki (field limit));
+           field elems := field elems * (field limit + 1 - array base)
+      FI;
+
+      IF symb.type = del AND symb.no = close bracket
+      THEN next symbol;
+           LEAVE get field size
+      ELSE skip (comma, del) FI
+  PER  .
+
+declare field:
+  field size CAT mki (array base);
+  field size CAT mki (field elems);
+  declare var (field, field size)  .
+
+end statement:
+(*END                                                                    *)
+  next symbol;
+  parameter (1, void type, const, nil adr);
+  apply (1, 0, ret)  .
+
+error statement:
+(*ERROR <integer expr result>                                             *)
+  next symbol;
+  get expr (expr result, int type);
+  parameter (1, int type, const, expr result.adr);
+  parameter (2, text type, const, niltext value);
+  apply (1, 2, "errorstop")  .
+
+gosub statement:
+(*GOSUB <line number>                                                    *) 
+  next symbol;
+  get const (label, int type);
+  gosub (this label)  .
+
+goto statement :
+(*GOTO <line number>                                                     *)
+  next symbol;
+  get const (label, int type);
+  apply (this label)  .
+
+this label: label list [label pos (label no)]  .
+label no:  label.name ISUB 1  .
+
+input statement:
+(*INPUT [;]["Anfrage" ;/,] Variable [, Variable]                         *) 
+  ROW 100 DTYPE VAR input var data;
+  INT VAR number input vars;
+  LABEL VAR input lab;
+  next symbol;
+  declare (input lab);
+  define (input lab);
+  get semicolon for cr lf;
+  get question and question mark;
+  apply (1, 3, "readinput");
+  get input eof;
+  get data types of input vars (input var data, number input vars); (* F25/rr *)
+  check data types of input vars;                                (* F8/F25/rr *)
+  apply (1, 0, "inputok");
+  apply (input lab, FALSE);                                      
+  assign list of input var .                                     (* F8/F25/rr *)
+
+get semicolon for cr lf:
+  IF symb.type = del AND symb.no = semicolon
+  THEN next symbol;
+       parameter (1, bool type, const, false value)
+  ELSE parameter (1, bool type, const, true value) FI   .
+
+get question and question mark:
+  IF symb.type = const AND symb.data = text type
+  THEN get const (question, text type);
+       parameter (2, text type, const, question.adr);
+       parameter (3, bool type, const, question mark value);
+       next symbol
+  ELSE parameter (2, text type, const, niltext value);
+       parameter (3, bool type, const, true value);              (* F7/rr *)
+  FI  .
+
+question mark value:
+  IF symb.type = del AND symb.no = semicolon
+  THEN true value
+  ELIF symb.type = del AND symb.no = comma
+  THEN false value
+  ELSE basic error (2, NAME symb, "  ; oder , erwartet"); nil adr FI  .
+
+get input eof:
+ IF symb.type = res word AND symb.no = eof s
+ THEN next symbol;
+      get const (label, int type);
+      apply (1, 0, "inputeof");
+      apply (this label, TRUE)
+ FI .
+ 
+check data types of input vars :                                (* F8/F25/rr *)
+  FOR i FROM 1 UPTO number input vars
+  REP parameter (1, int type, const, input data type);
+      apply (1, 1, "checkinput");
+      apply (input lab, FALSE);
+  PER .
+
+input data type :                                               (* F8/F25/rr *)
+   IF   input var data (i) =  int type THEN one value
+   ELIF input var data (i) = real type THEN two value
+   ELIF input var data (i) = text type THEN three value
+                                       ELSE zero value
+   FI .
+
+assign list of input var :                                       (* F8/F25/rr *)
+  REP get var (var result);
+      parameter (1, var result. data, var, var result. adr);
+      apply (1, 1, "assigninput");
+
+      IF symb.type = del AND symb.no = comma
+      THEN next symbol
+      ELSE LEAVE assign list of input var FI
+  PER .
+
+kill statement:
+(*KILL <filename>                                                        *)
+  next symbol;
+  get expr (filename, text type);
+
+  parameter (1, text type, const, filename.adr);
+  parameter (2, quiet type, const, next local adr (int type));
+  apply (2, 0, "quiet");
+  apply (1, 2, "forget")  .
+
+let statement:
+(*[LET] <var> = <expression>                                             *)
+  IF symb.type = res word AND symb.no = let s
+  THEN next symbol FI;
+  get var (var result);
+  skip (equal, operator);
+  get expr (expr result, var result.data);
+  apply move (var result.adr, expr result.adr, var result.data).
+
+line statement:                                                  (* F9/rr *)
+(*1.  LINE INPUT [;][<"prompt string">;]<string var result>                *)
+  next symbol;
+  skip (input s, res word);
+  get semicolon;
+  get prompt string;
+  apply (1, 3, "readinput");
+  assign string var result  .
+
+get semicolon:
+  IF symb.type = del AND symb.no = semicolon
+  THEN next symbol;
+       parameter (1, bool type, const, false value)
+  ELSE parameter (1, bool type, const, true value) FI   .
+
+get prompt string:
+  IF symb.type = const AND symb.data = text type
+  THEN get const (question, text type);
+       parameter (2, text type, const, question.adr);
+       skip (semicolon, del);
+  ELSE parameter (2, text type, const, niltext value);
+  FI;
+  parameter (3, bool type, const, false value) .
+
+assign string var result :
+  get var (var result, text type);
+  parameter (1, text type, var, var result.adr);
+  apply (1, 1, "assigninputline") .
+
+lprint statement:
+(*LPRINT        (cf. PRINT)                                              *)
+  apply (1, 0, "switchtoprintoutfile");
+  print statement;
+  apply (1, 0, "switchbacktooldsysoutstate").
+
+l set statement:
+(*LSET <string var> = <string expression>                                *) 
+  next symbol;
+  get var (var result, text type);
+  skip (equal, operator);
+  get expr (expr result, text type);
+  parameter (1, text type, var, var result.adr);
+  parameter (2, text type, const, expr result.adr);
+  apply (1, 2, "lset")  .
+
+mid statement:
+(*MID$  (<string var>, from [,len]) = <string expression>                *) 
+  next symbol;
+  skip (open bracket, del);
+  get var (var result, text type);
+  skip (comma, del);
+  get expr (from, int type);
+  IF symb.type = del AND symb.no = comma
+  THEN next symbol;
+       get expr (len, int type)
+  ELSE len := nilsymbol FI;
+  skip (close bracket, del);
+  skip (equal, operator);
+  get expr (expr result, text type);
+
+  parameter (1, text type, var, var result.adr);
+  parameter (2, int type, const, from.adr);
+  parameter (3, text type, const, expr result.adr);
+  IF len.data = int type
+  THEN parameter (4, int type, const, one value);
+       parameter (5, int type, const, len.adr);
+       parameter (6, text type, var, next local adr (text type));
+       apply (3, 3, "subtext");
+       parameter (3, text type, const, local adr);
+  FI;
+  apply (1, 3, "replace")  .
+
+name statement:
+(*NAME <old filename> AS <new filename>                                  *) 
+  next symbol;
+  get expr (old name, text type);
+  skip (as s, res word);
+  get expr (new name, text type);
+  parameter (1, text type, const, old name.adr);
+  parameter (2, text type, const, new name.adr);
+  apply (1, 2, "rename")  .
+
+option statement:
+(*OPTION BASE 0|1                                                        *)
+  next symbol;
+  skip (base s, res word);
+  get const (base size, int type);
+  IF new array base > 1
+    THEN basic error (105, NAME base size, "")
+    ELSE array base := new array base
+  FI.
+
+new array base:
+  base size.name ISUB 1.
+
+randomize statement:
+(*RANDOMIZE [<expression>]                                               *)
+  next symbol;
+  IF symb.type = eos
+  THEN apply (1, 0, "initrnd")
+  ELSE get expr (expr result, real type);
+       parameter (1, real type, const, expr result.adr);
+       apply (1, 1, "initrnd")
+  FI  .
+
+read statement:
+(*READ <list of var>                                                *) 
+  next symbol;
+  REP get var (var result);
+      parameter (1, text type, const, data text);
+      parameter (2, int type, var, data pos);
+      parameter (3, var result.data, var, var result.adr);
+      apply (1, 3, "read");
+
+      IF symb.type = eos
+      THEN LEAVE read statement
+      ELSE skip (comma, del) FI
+  PER  .
+
+rem statement:
+(*REM <remark>                                                           *)
+  next statement;
+  symb := SYMBOL : ("", eol, eos, LOC 0, void type); 
+  LEAVE get basic line  .
+
+restore statement:
+(*RESTORE [<line number>]                                                *) 
+  next symbol;
+  IF symb.type = eos
+  THEN parameter (1, int type, var, data pos);
+       parameter (2, int type, const, one value);
+       parameter (3, void type, const, nil adr);
+       apply (1, 2, int move);
+  ELSE get const (label, int type);
+       parameter (1, text type, const, data text);
+       parameter (2, int type, var, data pos);
+       parameter (3, int type, const, label.adr);
+       apply (1, 3, "restore")
+  FI  .
+
+return statement :
+(*RETURN                                                                 *)
+  next symbol;
+  goret  .
+
+r set statement:
+(*RSET <string var> = <string expression>                           *) 
+  next symbol;
+  get var (var result, text type);
+  skip (equal, operator);
+  get expr (expr result, text type);
+  parameter (1, text type, var, var result.adr);
+  parameter (2, text type, const, expr result.adr);
+  apply (1, 2, "rset")  .
+
+stop statement: 
+(*STOP                                                                   *)
+  next symbol;
+  expr result := SYMBOL: (nil, any, const, nil adr, int type);
+  expr result.name CAT act stat no;
+  declare const (expr result, int type);
+  parameter (1, int type, const, expr result.adr);
+  apply (1, 1, "basicstop");
+  parameter (1, void type, const, nil adr);
+  apply (1, 0, ret)  .
+
+swap statement:
+(*SWAP <var>,<var>                                             *)
+  next symbol;
+  get var (var result);
+  parameter (1, var result.data, var, var result.adr);
+  DTYPE CONST first var result data :: var result.data;
+  skip (comma, del);
+  get var (var result);
+  IF first var result data = var result.data
+    THEN parameter (2, var result.data, var, var result.adr);
+         apply (1, 2, "swap")
+    ELSE basic error (106, var result.name, "gefunden: "
+           + dump (first var result data) + ", " + dump (var result.data))
+  FI.
+
+troff statement:
+(*TROFF                                                                  *)
+  next symbol;
+  basic trace := FALSE  .
+
+tron statement:
+(*TRON                                                                   *)
+  next symbol;
+  basic trace := TRUE  .
+
+width statement:
+(*WIDTH Größe                                                            *)
+  next symbol;
+  get expr (expr result, int type);
+  parameter (1, int type, const, expr result.adr);
+  apply (1, 1, "width")  .
+
+write statement:
+(*WRITE [<list of expr results>]                                          *)
+  next symbol;
+
+  IF symb.type = eos
+  THEN apply (1, 0, "nextline")
+  ELSE write list of expr results FI  .
+
+write list of expr results:
+  REP get expr (expr result);
+      parameter (1, expr result.data, const, expr result.adr);
+      apply (1, 1, "basicwrite");
+
+      IF symb.type = eos
+      THEN apply (1, 0, "nextline");
+           LEAVE write list of expr results
+      ELSE skip (comma, del);
+           parameter (1, text type, const, comma value);
+           apply (1, 1, "basicout") 
+      FI
+  PER  .
+
+END PROC get basic line;
+
+PROC gen stat no (INT CONST local stat no):
+(*               Die Zeilennummer wird als Label definiert               *)
+(*     Die Prozedur 'stat no' wird mit der Statementnummer aufgerufen    *)
+  act stat no := local stat no;
+  define (label list [label pos (act stat no)]);
+
+  declare (1, int type);
+  declare (1, const);
+  define (1, act stat no);
+  parameter (2, void type, const, nil adr);
+  apply (1, 1, ln op);
+
+  IF basic trace
+  THEN expr result := SYMBOL: (nil, any, const, nil adr, int type);
+       expr result.name CAT act stat no;
+       declare const (expr result, int type);
+       parameter (1, int type, const, expr result.adr);
+       apply (1, 1, trace op)
+  FI;
+  next symbol  .
+
+END PROC gen stat no;
+
+PROC for statement:
+(*FOR <var> = x TO y [STEP z]                                       *)
+  SYMBOL VAR local var result, init val, limit val, step val;
+  LABEL VAR start loop, end loop;
+  INT CONST  for stat no      := act stat no,                     (* F29/rr *)
+             for scan line no := scan line no;
+  TEXT CONST for symb name    := symb.name;
+  declare (start loop);
+  declare (end loop);
+
+  next symbol;
+  get loop var;
+  skip (equal, operator);
+  get expr (init val, local var result.data);
+  skip (to s, res word);
+  get expr (limit val, local var result.data);
+  get step val;
+
+  init loop var;
+  define (start loop);
+  gen check of variable;
+  get statement group (next s);
+
+  IF symb.type = eos AND symb.no = -next s
+  THEN next var statement
+  ELSE define (end loop);
+       basic error ("Compiler", 26, for scan line no, for stat no, for symb name, "", TRUE); (* F29/rr *)
+  FI  .
+
+get loop var:
+  get var (local var result);
+  IF NOT (local var result.data = int type OR local var result.data = real type)
+    THEN basic error (2, NAME local var result, "INT oder REAL erwartet, "
+                        + dump (local var result.data) + " gefunden")
+  FI  .
+
+get step val:
+  IF symb.type = res word AND symb.no = step s
+  THEN next symbol;
+       get expr (step val, local var result.data)
+  ELIF local var result.data = int type
+  THEN step val.data := int type;
+       step val.adr  := int one value
+  ELSE step val.data := real type;
+       step val.adr  := real one value
+  FI  .
+
+init loop var:
+  IF local var result.data = int type
+  THEN init int loop
+  ELSE init real loop FI .
+
+init int loop:
+  IF limit val.type = var
+  THEN parameter (1, int type, var, next local adr (int type));
+       parameter (2, int type, const, limit val.adr);
+       parameter (3, void type, const, nil adr);
+       apply (1, 2, int move);
+       limit val.adr := local adr;
+  FI;
+  IF step val.type = var
+  THEN parameter (1, int type, var, next local adr (int type));
+       parameter (2, int type, const, step val.adr);
+       parameter (3, void type, const, nil adr);
+       apply (1, 2, int move);
+       step val.adr := local adr;
+  FI;
+  IF NOT (init val.no = local var result.no)
+  THEN parameter (1, int type, var, local var result.adr);
+       parameter (2, int type, const, init val.adr);
+       parameter (3, void type, const, nil adr);
+       apply (1, 2, int move) 
+  FI  .
+
+init real loop:
+  IF limit val.type = var
+  THEN parameter (1, real type, var, next local adr (real type));
+       parameter (2, real type, const, limit val.adr);
+       parameter (3, void type, const, nil adr);
+       apply (1, 2, real move);
+       limit val.adr := local adr;
+  FI;
+  IF step val.type = var
+  THEN parameter (1, real type, var, next local adr (real type));
+       parameter (2, real type, const, step val.adr);
+       parameter (3, void type, const, nil adr);
+       apply (1, 2, real move);
+       step val.adr := local adr;
+  FI;
+  IF NOT (init val.no = local var result.no)
+  THEN parameter (1, real type, var, local var result.adr);
+       parameter (2, real type, const, init val.adr);
+       parameter (3, void type, const, nil adr);
+       apply (1, 2, real move) 
+  FI  .
+
+gen check of variable:
+  parameter (1, local var result.data, const, local var result.adr);
+  parameter (2, limit val.data,  const, limit val.adr);
+  parameter (3, step val.data, const, step val.adr);
+  parameter (4, bool type, const, nil adr);  apply (4, nop);
+(*    In der nächsten Coder-Version ist eine PUSH-Angabe nop nicht nötig *)
+  apply (1, 3, "loopend");
+  apply (end loop, TRUE)  .
+
+next var statement:
+(*NEXT [<var>][,<var>...]                                  *)
+  next symbol;
+  generate loop end;
+  IF symb.type <> eos
+  THEN check next var result FI  .
+
+check next var result:
+  IF symb.no = local var result.no
+  THEN next symbol;
+       IF symb.type = del AND symb.no = comma
+       THEN next for loop FI
+  ELSE basic error (86, NAME symb, local var result.name + " erwartet") FI  .
+
+next for loop:
+  IF end symbol = next s
+    THEN symb := SYMBOL:("", -next s, eos, nil adr, void type)
+    ELSE basic error (1, symb.name, "")                        (* mo *)
+  FI.
+
+generate loop end:
+  parameter (1, local var result.data, var, local var result.adr);
+  parameter (2, step val.data, const, step val.adr);
+  parameter (3, void type, const, nil adr);
+  IF local var result.data = int type
+  THEN apply (1, 2, int incr)
+  ELSE apply (1, 2, real incr) FI;
+
+  apply (start loop);
+  define (end loop)  .
+
+END PROC for statement;
+
+PROC if statement :                                   (* Änd. 11.08.87, mo *)
+(*  IF <expression> THEN <statement(s)>|<line number>                    *)
+(*                 [ELSE <statement(s)>|<line number>]                   *)
+(*  IF <expression> GOTO <line number>                                   *)
+(*                 [ELSE <statement(s)>|<line number>]                   *)
+  SYMBOL VAR local expr result;
+  next symbol;
+  get expr (local expr result, int type);
+  skip comma if there;
+  IF symb.type = res word AND (symb.no = then s OR symb.no = goto s)
+    THEN test expr result;
+         IF symb.no = goto s
+           THEN next symbol;
+                if goto statement
+         ELIF next symbol is stat no
+           THEN if goto statement
+           ELSE if then statement
+         FI
+  ELSE basic error (2, NAME symb, "THEN oder GOTO erwartet") FI  .
+
+skip comma if there:
+  IF symb.no = comma AND symb.type = del
+    THEN next symbol
+  FI.
+
+test expr result:
+  parameter (1, int type, const, local expr result.adr);
+  parameter (2, bool type, var, nil adr);  apply (2, nop);
+  apply (1, 1, test)  .
+
+next symbol is stat no:
+  next symbol;
+  symb.type = const AND symb.data = int type.
+
+if goto statement:
+  SYMBOL VAR stat label;
+  get const (stat label, int type);
+  expect else if comma found;
+  IF symb.type = res word AND symb.no = else s
+    THEN apply (this label, FALSE);
+         treat else case
+  ELIF symb.type <> eos OR symb.no <> eol
+    THEN declare (else label);
+         apply (this label, FALSE);
+         apply (else label);
+         get basic line (else s);
+         IF symb.type = eos AND symb.no = -else s
+           THEN else statement
+           ELSE define (else label)
+         FI
+    ELSE apply (this label, FALSE)
+  FI.
+
+this label: label list [label pos (label no)]  .
+label no:  stat label.name ISUB 1  .
+
+expect else if comma found:
+  IF symb.type = del AND symb.no = comma
+    THEN next symbol;
+         IF symb.no <> else s OR symb.type <> res word
+           THEN basic error (2, NAME symb, "ELSE erwartet")
+         FI
+  FI.
+
+treat else case:
+  IF next symbol is stat no
+    THEN get const (stat label, int type);
+         apply (this label)
+    ELSE get basic line
+  FI.
+
+if then statement:
+  LABEL VAR fi label;
+  declare (else label);
+  apply (else label, TRUE);
+  get basic line (else s);
+
+  IF symb.type = eos AND symb.no = -else s
+  THEN declare (fi label);
+       apply (fi label);
+       else statement;
+       define (fi label)
+  ELSE define (else label) FI  .
+
+
+else statement:
+  LABEL VAR else label;
+  define (else label); 
+  treat else case.
+
+
+END PROC if statement;
+
+PROC on statement:
+(*2.  ON <expression> GOSUB <list of line numbers>                       *)
+(*3.  ON <expression> GOTO <list of line numbers>                        *)
+  LABEL VAR before case, after case, return case;
+  declare (before case);
+  declare (after case);
+  declare (return case);
+
+  next symbol;
+  IF symb.type = res word AND symb.no = error s
+    THEN basic error (100, symb.name, "")
+  FI;
+  get expr (expr result, int type);
+  IF on gosub statement
+  THEN gosub (before case);
+       apply (after case)
+  ELIF NOT on goto statement
+  THEN basic error (2, symb.name, "GOTO oder GOSUB erwartet") FI;
+
+  get case stat no;
+  define (before case);
+  gen case branches;
+  gen return case;
+  define (after case)  .
+
+on gosub statement:
+  BOOL CONST gosub found := symb.type = res word AND symb.no = gosub s;
+  gosub found  .
+
+on goto statement:
+  symb.type = res word AND symb.no = goto s.
+
+get case stat no:
+  TEXT VAR case stat no :: nil;
+  INT VAR case no :: 0;
+  next symbol;
+  REP get const (label, int type);
+      case no INCR 1;
+      case stat no CAT label.name;
+
+      IF symb.type = eos
+      THEN LEAVE get case stat no
+      ELSE skip (comma, del) FI
+  PER  .
+
+gen case branches:
+  computedbranch (expr result.adr, case no + 1, otherwise lab);  (* F6/rr *)
+  apply (otherwise lab);
+  FOR i FROM 1 UPTO case no
+  REP apply (label i) PER  .
+
+gen return case:
+  IF gosub found
+  THEN define (return case);
+       goret
+  FI  .
+
+otherwise lab:
+  IF gosub found
+  THEN return case
+  ELSE after case FI  .
+
+label i:
+  label list [label pos (case stat no ISUB i)]  .
+
+END PROC on statement;
+
+PROC print statement:
+(*PRINT [<list of expr results>]                                         *)
+(*PRINT USING <string exp>;<list of expression>                          *)
+(*PRINT #<file number>,<list of expr results>                            *) 
+(*PRINT #<file number>, USING <string exp>;<list of expression>          *)
+  next symbol;
+  IF symb.type = del AND symb.no = numbersign
+  THEN print file statement
+  ELSE print display statement FI  .
+
+print file statement:
+  basic error (100, symb.name, "")  .
+
+print display statement:
+  get format string;
+  print list of expr results;
+  reset format string  .
+
+get format string:
+  IF symb.type = res word AND symb.no = using s
+  THEN next symbol;
+       get expr (image, text type);
+       skip (semicolon, del);
+       parameter (1, text type, const, image.adr);
+       apply (1, 1, "using");
+  ELSE image := nilsymbol FI  .
+
+reset format string:
+  IF image.type <> any
+  THEN apply (1, 0, "clearusing") FI  .
+
+print list of expr results:
+  REP IF symb.type = res word AND symb.no = tab s
+      THEN get tabulation
+      ELIF symb.type = del AND symb.no = comma
+      THEN get next zone
+      ELIF symb.type = del AND symb.no = semicolon
+      THEN get next pos
+      ELIF symb.type = eos
+      THEN apply (1, 0, "nextline");
+           LEAVE print list of expr results 
+      ELSE get print expr result FI;
+  PER  .
+
+get tabulation:
+  next symbol;
+  skip (open bracket, del);
+  get expr (tab pos, int type);
+  skip (close bracket, del);
+  parameter (1, int type, const, tab pos.adr);
+  apply (1, 1, "tab")  .
+
+get next zone:
+  next symbol;
+  IF image.type = any
+  THEN apply (1, 0, "nextzone") FI;
+  IF symb.type = eos
+  THEN LEAVE print list of expr results FI  .
+
+get next pos:
+  next symbol;
+  IF symb.type = eos
+  THEN LEAVE print list of expr results FI  .
+
+get print expr result:
+  get expr (expr result);
+  parameter (1, expr result.data, const, expr result.adr);
+  apply (1, 1, "basicout")  .
+
+END PROC print statement;
+
+PROC while statement:
+(*WHILE <expression>                                                     *)
+  LABEL VAR while lab, wend lab;
+  SYMBOL VAR while expr result;
+  INT CONST  while stat no      := act stat no,                   (* F29/rr *)
+             while scan line no := scan line no;
+  TEXT CONST while symb name    := symb.name;
+  next symbol;
+  declare (while lab);
+  declare (wend lab);
+
+  define (while lab);
+  get expr (while expr result, int type);
+  parameter (1, int type, const, while expr result.adr);
+  parameter (2, bool type, const, nil adr);  apply (2, nop);
+  apply (1, 1, test);
+  apply (wend lab, TRUE);              (* 'test' vergleicht mit 0 *)
+
+  get statement group (wend s);
+  IF symb.type = eos AND symb.no = -wend s
+  THEN wend statement
+  ELSE basic error ("Compiler", 29, while scan line no, while stat no, while symb name, "", TRUE) FI. (* F29/rr *)
+
+wend statement:
+(*WEND                                                                   *)
+  apply (while lab);
+  define (wend lab);
+  next symbol  .
+
+END PROC while statement;
+
+END PACKET basic compiler
+
diff --git a/basic/BASIC.Runtime b/basic/BASIC.Runtime
new file mode 100644
index 0000000..854002a
--- /dev/null
+++ b/basic/BASIC.Runtime
@@ -0,0 +1,1571 @@
+(***************************************************************************)
+(*                                                                         *)
+(*           Erste von drei Dateien des EUMEL-BASIC-Systems                *)
+(*                                                                         *)
+(*           Autor: Heiko Indenbirken                                      *)
+(*           Überarbeitet von: Rudolf Ruland und Michael Overdick          *)
+(*                                                                         *)
+(*           Stand: 27.10.1987                                             *)
+(*                                                                         *)
+(***************************************************************************)
+
+PACKET basic std DEFINES EQU, UEQ,            (* Autor: Heiko Indenbirken *)
+                         LES, LEQ,            (* Stand: 23.10.1987/rr/mo  *)
+                         GRE, GEQ,
+                         EQV, IMP,
+                         ^, swap,
+                         val, asc, cdbl, chr,
+                         cint, cvi, cvd, fre,
+                         hex, inchars,
+                         instr, ent, left,
+                         mid, mki, mkd,
+                         oct, right,
+                         rnd, init rnd,
+                         space, string,  
+                         l set, r set,
+                         int not, real not,
+                         /, DIV, real mod,
+                         time, timer,
+                         arctan, cos, sin, tan,
+                         exp, ln, floor,
+                         sqrt:
+
+
+INT CONST true := -1,
+          false := 0;
+
+LET real overflow = 6;
+
+
+(*BASIC-Integervergleiche                                                *)
+INT OP EQU (INT CONST a, b):
+  IF a=b
+  THEN true
+  ELSE false FI
+END OP EQU;
+
+INT OP UEQ (INT CONST a, b):
+  IF a=b
+  THEN false
+  ELSE true FI
+END OP UEQ;
+
+INT OP LES (INT CONST a, b):
+  IF a<b
+  THEN true
+  ELSE false FI
+END OP LES;
+
+INT OP LEQ (INT CONST a, b):
+  IF a<=b
+  THEN true
+  ELSE false FI
+END OP LEQ;
+
+INT OP GRE (INT CONST a, b):
+  IF a>b
+  THEN true
+  ELSE false FI
+END OP GRE;
+
+INT OP GEQ (INT CONST a, b):
+  IF a>=b
+  THEN true
+  ELSE false FI
+END OP GEQ;
+
+(*BASIC-Realvergleiche                                                   *)
+INT OP EQU (REAL CONST a, b):
+  IF a=b
+  THEN true
+  ELSE false FI
+END OP EQU;
+
+INT OP UEQ (REAL CONST a, b):
+  IF a=b
+  THEN false
+  ELSE true FI
+END OP UEQ;
+
+INT OP LES (REAL CONST a, b):
+  IF a<b
+  THEN true
+  ELSE false FI
+END OP LES;
+
+INT OP LEQ (REAL CONST a, b):
+  IF a<=b
+  THEN true
+  ELSE false FI
+END OP LEQ;
+
+INT OP GRE (REAL CONST a, b):
+  IF a>b
+  THEN true
+  ELSE false FI
+END OP GRE;
+
+INT OP GEQ (REAL CONST a, b):
+  IF a>=b
+  THEN true
+  ELSE false FI
+END OP GEQ;
+
+(*BASIC-Tesxtvergleiche                                                  *)
+INT OP EQU (TEXT CONST a, b):
+  IF a=b
+  THEN true
+  ELSE false FI
+END OP EQU;
+
+INT OP UEQ (TEXT CONST a, b):
+  IF a=b
+  THEN false
+  ELSE true FI
+END OP UEQ;
+
+INT OP LES (TEXT CONST a, b):
+  IF a<b
+  THEN true
+  ELSE false FI
+END OP LES;
+
+INT OP LEQ (TEXT CONST a, b):
+  IF a<=b
+  THEN true
+  ELSE false FI
+END OP LEQ;
+
+INT OP GRE (TEXT CONST a, b):
+  IF a>b
+  THEN true
+  ELSE false FI
+END OP GRE;
+
+INT OP GEQ (TEXT CONST a, b):
+  IF a>=b
+  THEN true
+  ELSE false FI
+END OP GEQ;
+
+
+(*BASIC         INTEGER / BOOL Operatoren                                *)
+REAL PROC real not (REAL CONST a):          (* mo *)
+  real (int (a) XOR -1)
+END PROC real not;
+
+INT PROC int not (INT CONST a):             (* mo *)
+  a XOR -1
+END PROC int not;
+
+INT OP EQV (INT CONST l, r):
+  int not (l XOR r)
+END OP EQV;
+
+INT OP IMP (INT CONST l, r):
+  (l EQV r) OR r
+END OP IMP;
+
+LET smallest significant = 5.0e-12;
+REAL OP ^ (REAL CONST x, y):                                  (* F22/rr *)
+  IF   x > 0.0
+       THEN x ** y
+  ELIF x = 0.0
+       THEN IF   y > 0.0
+                 THEN 0.0
+            ELIF y = 0.0
+                 THEN 1.0
+                 ELSE errorstop (real overflow, "");
+                      max real
+            FI
+       ELSE REAL VAR floor y := floor (y + round value);            
+            IF   (abs (y - floor y) > smallest significant)
+                      COR (floor y = 0.0 AND y <> 0.0)
+                 THEN errorstop (1005, "bei " + text (x) +
+                                        " ^ " + text (y, 19) +
+                                        " : neg. Basis, gebr. Exponent");
+                      0.0
+            ELIF (floor y MOD 2.0) = 0.0
+                 THEN     (-x) ** floor y
+                 ELSE - ( (-x) ** floor y )
+            FI
+  FI .
+
+  round value : IF y >= 0.0 THEN 0.5 ELSE -0.5 FI .
+
+END OP ^;
+
+REAL OP ^ (INT CONST x, y):
+  real (x) ** y
+END OP ^;
+
+REAL OP / (INT CONST l, r):                 (* mo *)
+  real (l) / real (r)
+END OP /;
+
+INT OP DIV (REAL CONST l, r):               (* mo *)
+  cint (l) DIV cint (r)
+END OP DIV;
+
+REAL PROC real mod (REAL CONST l, r):       (* mo *)
+  round (l, 0) MOD round (r, 0)
+END PROC real mod;
+
+(*                            Basic Arithmetik                           *)
+REAL VAR r swap;
+PROC swap (REAL VAR left, right):
+  r swap := left;
+  left := right;
+  right := r swap
+END PROC swap;
+
+INT VAR i swap;
+PROC swap (INT VAR left, right):
+  i swap := left;
+  left := right;
+  right := i swap
+END PROC swap;
+
+TEXT VAR t swap;
+PROC swap (TEXT VAR left, right):
+  t swap := left;
+  left := right;
+  right := t swap
+END PROC swap;
+
+(*Internkonvertierungen                                                  *)
+INT PROC cvi (TEXT CONST v):
+  v ISUB 1
+END PROC cvi;
+
+REAL PROC cvd (TEXT CONST v):
+  v RSUB 1
+END PROC cvd;
+
+TEXT VAR i text :: 2*""0"", r text :: 8*""0"";
+TEXT PROC mki (REAL CONST x):
+  mki (cint (x))
+END PROC mki;
+
+TEXT PROC mki (INT CONST i):
+  replace (i text, 1, i);
+  i text
+END PROC mki;
+
+TEXT PROC mkd (INT CONST i):
+  mkd (real (i))
+END PROC mkd;
+
+TEXT PROC mkd (REAL CONST r):
+  replace (r text, 1, r);
+  r text
+END PROC mkd;
+
+(*Textoperationen                                                        *)
+PROC l set (TEXT VAR left, TEXT CONST right):
+  replace (left, 1, right)
+END PROC l set;
+
+PROC r set (TEXT VAR left, TEXT CONST right):
+  replace (left, length (left)-length (right)+1, right)
+END PROC r set;
+
+TEXT PROC left (TEXT CONST string, REAL CONST no):
+  left (string, cint (no))
+END PROC left;
+
+TEXT PROC left (TEXT CONST string, INT CONST no):
+  subtext (string, 1, no)
+END PROC left;
+
+TEXT PROC right (TEXT CONST string, REAL CONST no):
+  right (string, cint (no))
+END PROC right;
+
+TEXT PROC right (TEXT CONST string, INT CONST no):
+  subtext (string, length (string)-no+1)
+END PROC right;
+
+TEXT PROC mid (TEXT CONST source, REAL CONST from):
+  mid (source, cint (from))
+END PROC mid;
+
+TEXT PROC mid (TEXT CONST source, INT CONST from):
+  subtext (source, from)
+END PROC mid;
+
+TEXT PROC mid (TEXT CONST source, REAL CONST from, length):
+  mid (source, cint (from), cint (length))
+END PROC mid;
+
+TEXT PROC mid (TEXT CONST source, INT CONST from, length):
+  subtext (source, from, from+length-1)
+END PROC mid;
+
+TEXT PROC string (REAL CONST x, y):
+  string (cint (x), cint (y))
+END PROC string;
+
+TEXT PROC string (INT CONST x, REAL CONST y):
+  string (x, cint (y))
+END PROC string;
+
+TEXT PROC string (REAL CONST x, INT CONST y):
+  string (cint (x), y)
+END PROC string;
+
+TEXT PROC string (INT CONST i, j):
+  i * code (j)
+END PROC string;
+
+TEXT PROC string (REAL CONST i, TEXT CONST x):
+  string (cint (i), x)
+END PROC string;
+
+TEXT PROC string (INT CONST i, TEXT CONST x):
+  i * (x SUB 1)
+END PROC string;
+
+(*Konvertierungen                                                       *)
+
+REAL PROC val (TEXT CONST text) :                               (* F18/rr *)
+
+  TEXT VAR buffer := text;
+  change (buffer, "d", "e");
+  change (buffer, "D", "e");
+  change (buffer, "E", "e");
+  real (buffer)
+
+END PROC val;
+
+REAL PROC asc (TEXT CONST text):
+  real (code (text SUB 1))
+END PROC asc;
+
+TEXT PROC chr (INT CONST n):
+  code (n)
+END PROC chr;
+
+TEXT PROC chr (REAL CONST n):
+  code (cint (n))
+END PROC chr;
+
+TEXT PROC hex (REAL CONST x):
+  hex (cint (x))
+END PROC hex;
+
+TEXT PROC hex (INT CONST x):
+  TEXT VAR value :: "12";
+  replace (value, 1, x);
+  high byte + low byte  .
+
+low byte:
+  hexdigit (code (value SUB 1) DIV 16) + hexdigit (code (value SUB 1) MOD 16)  .
+
+high byte:
+  IF (value SUB 2) = ""0""
+  THEN ""
+  ELSE hexdigit (code (value SUB 2) DIV 16) +
+       hexdigit (code (value SUB 2) MOD 16) 
+  FI  .
+
+END PROC hex;
+
+TEXT PROC oct (REAL CONST x):
+  oct (cint (x))
+END PROC oct;
+
+TEXT PROC oct (INT CONST x):
+  INT VAR number :: x AND maxint;
+  generate oct number;
+  IF x < 0
+    THEN "1" + oct number
+    ELSE subtext (oct number, pos (oct number, "1", "7", 1))
+  FI.
+
+generate oct number:
+  TEXT VAR oct number :: "";
+  INT VAR digit;
+  FOR digit FROM 1 UPTO 5 REP
+    oct number := hexdigit (number MOD 8) + oct number;
+    number := number DIV 8
+  PER.
+
+END PROC oct;
+
+TEXT PROC hexdigit (INT CONST digit):
+  IF 0 <= digit AND digit <= 9
+  THEN code (digit + 48)
+  ELIF 10 <= digit AND digit <= 15
+  THEN code (digit + 55)
+  ELSE errorstop (1051, "Hexziffer außerhalb des gültigen Bereichs"); "" FI
+END PROC hexdigit;
+
+TEXT PROC inchars (REAL CONST n):
+  inchars (cint (n))
+END PROC inchars;
+
+TEXT PROC inchars (INT CONST n):
+  TEXT VAR buffer :: "", char;
+  INT VAR i;
+  FOR i FROM 1 UPTO n
+  REP inchar (char);
+      buffer CAT char
+  PER;
+  buffer
+
+END PROC inchars;
+
+(*Mathematische Prozeduren                                               *)
+REAL PROC ent (INT CONST r):
+  real (r)
+END PROC ent;
+
+REAL PROC ent (REAL CONST r):
+  IF r >= 0.0 OR frac (r) = 0.0
+  THEN floor (r)
+  ELSE floor (r-1.0) FI
+END PROC ent;
+
+REAL PROC cdbl (INT CONST r):
+  real (r)
+END PROC cdbl;
+
+REAL PROC cdbl (REAL CONST r):
+  r
+END PROC cdbl;
+
+INT PROC cint (INT CONST r):
+  r
+END PROC cint;
+
+INT PROC cint (REAL CONST r):
+  IF r >= 0.0
+  THEN int (r+0.5)
+  ELSE int (r-0.5) FI
+END PROC cint;
+
+REAL VAR last rnd :: rnd (1.0);
+REAL PROC rnd (INT CONST x):
+  rnd (real (x))
+END PROC rnd;
+
+REAL PROC rnd (REAL CONST x):
+  IF x > 0.0
+  THEN last rnd := random;
+       last rnd
+  ELIF x = 0.0
+  THEN last rnd
+  ELSE init rnd (x);
+       last rnd := random;
+       last rnd
+  FI
+
+END PROC rnd;
+
+REAL PROC rnd:
+  rnd (1.0)
+END PROC rnd;
+
+PROC init rnd (REAL CONST init value) :
+
+  REAL VAR init := init value;
+  IF init <= -1.0 OR 1.0 <= init
+     THEN set exp (- decimal exponent (init) - 1, init) FI; 
+  initialize random (init) 
+
+END PROC init rnd;
+
+
+REAL PROC fre (TEXT CONST dummy):
+  INT VAR f, u;
+  collect heap garbage;
+  storage (f, u);
+
+  real (f - u) * 1024.0
+END PROC fre;
+
+REAL PROC fre (REAL CONST dummy):
+  fre ("")
+END PROC fre;
+
+REAL PROC fre (INT CONST dummy):
+  fre ("")
+END PROC fre;
+
+(*Inputroutinenen                                                        *)
+INT PROC instr (TEXT CONST source, pattern):
+  pos (source, pattern)
+END PROC instr;
+
+INT PROC instr (REAL CONST from, TEXT CONST source, pattern):
+  instr (cint (from), source, pattern)
+END PROC instr;
+
+INT PROC instr (INT CONST from, TEXT CONST source, pattern):
+  pos (source, pattern, from)
+END PROC instr;
+
+TEXT PROC space (REAL CONST len):
+  space (cint (len))
+END PROC space;
+
+TEXT PROC space (INT CONST len):
+  len * " "
+END PROC space;
+
+TEXT PROC time:                                        (* mo *)
+  subtext (time (clock (1) MOD day), 1, 8)          (* hh:mm:ss *)
+END PROC time;
+
+REAL PROC timer:
+  clock (0)
+END PROC timer;
+
+REAL PROC arctan (INT CONST x):
+  arctan (real (x))
+END PROC arctan;
+
+REAL PROC cos (INT CONST x):
+  cos (real (x))
+END PROC cos;
+
+REAL PROC sin (INT CONST x):
+  sin (real (x))
+END PROC sin;
+
+REAL PROC tan (INT CONST x):
+  tan (real (x))
+END PROC tan;
+
+REAL PROC exp (INT CONST x):
+  exp (real (x))
+END PROC exp;
+
+REAL PROC ln (INT CONST x):
+  ln (real (x))
+END PROC ln;
+
+REAL PROC floor (INT CONST x):
+  real (x)
+END PROC floor;
+
+REAL PROC sqrt (INT CONST x):
+  sqrt (real (x))
+END PROC sqrt;
+
+END PACKET basic std;
+
+PACKET basic using DEFINES using,             (* Autor: Heiko Indenbirken *)
+                           clear using,       (* Stand: 05.08.1987/rr/mo  *)
+                           basic text:
+
+
+LET exclamation point = "!",
+    backslash         = "\",
+    comercial and     = "&",
+    numbersign        = "#",
+    plus              = "+",
+    minus             = "-",
+    asterisk dollar   = "**$",
+    asterisk          = "**",
+    dollarsign        = "$$",
+    comma             = ",",
+    point             = ".",
+    caret             = "^^^^",
+    underscore        = "_",
+    blank             = " ",
+    nil               = "",
+
+    number format chars = "#+-*$.^",
+    format chars        = "!\&#+-$*.";
+
+TEXT VAR result, using format :: "", pre format :: "";
+INT VAR using pos :: 0;
+BOOL VAR image used :: FALSE;
+
+PROC using (TEXT CONST format):
+  using format := format;
+  using pos := 0;
+  result := "";
+  image used := TRUE
+
+END PROC using;
+
+PROC clear using:
+  using format := "";
+  image used := FALSE
+END PROC clear using;
+
+TEXT PROC next format:
+  pre format := "";
+  IF using pos = 0
+  THEN ""
+  ELSE search rest of format FI  .
+
+search rest of format:
+  WHILE using pos <= length (using format)
+  REP IF at underscore
+      THEN using pos INCR 1;
+           pre format CAT akt char
+      ELIF at format char
+      THEN LEAVE next format WITH pre format
+      ELSE pre format CAT akt char FI;
+      using pos INCR 1
+  PER;
+  using pos := 0;
+  pre format  .
+ 
+at underscore:
+  akt char = underscore  .
+
+at format char:
+  pos (format chars, akt char) > 0 CAND
+  evtl double asterisk CAND
+  evtl point with numbersign  .
+
+evtl double asterisk:
+  akt char <> asterisk COR next char = asterisk  .
+
+evtl point with numbersign:
+  akt char <> point COR next char = numbersign  .
+
+akt char: using format SUB using pos  .
+next char: using format SUB using pos+1  .
+END PROC next format;
+
+PROC init (TEXT VAR l result):
+  IF using pos = 0
+  THEN using pos := 1;
+       l result := next format;
+       IF using pos = 0
+       THEN errorstop (1005, "USING: kein Format gefunden") FI
+  ELSE l result := "" FI
+
+END PROC init;
+
+TEXT PROC basic text (TEXT CONST string):
+  IF image used
+  THEN using text
+  ELSE string FI  .
+
+using text:
+  init (result);
+  result CAT format string;
+  using pos INCR 1;
+  result CAT next format;
+  result  .
+
+format string:
+  IF akt char = exclamation point
+  THEN string SUB 1
+  ELIF akt char = backslash
+  THEN given length string
+  ELIF akt char = comercial and
+  THEN string
+  ELSE errorstop (1005, "USING-Format fehlerhaft: " + using format); ""  FI  .
+
+given length string:
+  INT VAR len :: 2;
+  FOR using pos FROM using pos+1 UPTO length (using format)
+  REP IF akt char = "\"
+      THEN LEAVE given length string WITH text (string, len) FI;
+      len INCR 1
+  UNTIL akt char <> " "PER;
+  errorstop (1005, "USING-Format fehlerhaft: " + using format);
+  ""  .
+
+akt char: using format SUB using pos
+END PROC basic text;
+ 
+TEXT PROC basic text (INT CONST number):
+  IF image used
+  THEN basic text (real (number))
+  ELSE sign + text (number) FI  .
+
+sign:
+  IF number >= 0
+  THEN " "
+  ELSE "" FI  .
+
+END PROC basic text;
+
+TEXT PROC basic text (REAL CONST number):
+  IF image used
+  THEN using text
+  ELSE normal text FI  .
+
+normal text:
+(*   Bei Real Zahlen werden maximal 7 signifikante Stellen ausgegeben,   *)
+(*          führende und nachfolgende Nullen werden unterdrückt,         *)
+(*           der Dezimalpunkt wird im Normalformat unterdrückt           *)
+  calculate sign;
+  REAL VAR mantissa := round (abs (number), 6-decimal exponent (number));
+  INT CONST exp :: decimal exponent (mantissa);
+
+  IF mantissa = 0.0
+  THEN result := " 0"
+  ELIF exp > 6 OR exp < -7 OR (exp < 0 AND more than 7 signifikant digits)
+  THEN scientific notation
+  ELIF exp < 0
+  THEN short negative notation
+  ELSE short positive notation FI;
+  result  .
+
+more than 7 signifikant digits:
+   REAL VAR signifikant := mantissa;
+   set exp (7+exp, signifikant);
+   frac (signifikant) <> 0.0  .
+
+calculate sign:
+  IF number >= 0.0
+  THEN result := " "
+  ELSE result := "-" FI  .
+
+scientific notation:
+  set exp (0, mantissa);
+  result CAT non zero (text (mantissa, 8, 6));
+
+  IF exp < 0
+  THEN result CAT "E-"
+  ELSE result CAT "E+" FI;
+
+  IF abs (exp) > 9
+  THEN result CAT text (abs (exp))
+  ELSE result CAT "0";
+       result CAT text (abs (exp))
+  FI  .
+
+short positive notation:
+  result CAT non zero (text (mantissa, 8, 6-exp));
+  IF (result SUB LENGTH result) = "."
+  THEN delete char (result, LENGTH result) FI  .
+
+short negative notation:
+  result CAT non zero (subtext (text (abs (mantissa), 9, 7), 2)).(* F13/rr *)
+
+using text:
+  init (result);
+  result CAT format number (subformat, number);
+  result CAT next format;
+  result  .
+
+subformat:
+  INT VAR from :: using pos, to :: last format char;
+  subtext (using format, from, to)  .
+
+last format char:
+  FOR using pos FROM using pos+1 UPTO length (using format)
+  REP IF non format char
+      THEN LEAVE last format char WITH using pos-1 FI
+  PER;
+  using pos := 0;
+  length (using format)  .
+
+non format char:
+  IF (using format SUB using pos) = comma
+  THEN (using format SUB (using pos+1)) <> point
+  ELSE pos (numberformat chars, using format SUB using pos) = 0  FI  .
+
+END PROC basic text;
+
+TEXT PROC non zero (TEXT CONST text):
+  INT VAR i;
+  FOR i FROM length (text) DOWNTO 2
+  REP UNTIL (text SUB i) <> "0" PER;
+  subtext (text, 1, i)
+END PROC non zero;
+
+TEXT PROC format number (TEXT CONST format, REAL CONST number):
+  IF no digit char
+  THEN errorstop (1005, "USING-Format fehlerhaft: " + using format);  ""
+  ELIF exponent found
+  THEN exponent format
+  ELSE normal format FI  .
+
+no digit char:
+  pos (format, numbersign) = 0 AND
+  pos (format, asterisk) = 0 AND
+  pos (format, dollarsign) = 0  .
+
+exponent found:
+  INT CONST exponent pos := pos (format, caret);
+  exponent pos > 0  .
+
+exponent format:
+  IF leading plus
+  THEN plus or minus + exponent field (subtext (format, 2), number, exponent pos-1) 
+  ELIF trailing plus
+  THEN exponent field (format, number, exponent pos) + plus or minus 
+  ELIF trailing minus
+  THEN exponent field (format, number, exponent pos) + nil or minus 
+  ELSE blank or minus + exponent field (subtext (format, 2), number, exponent pos-1) FI  .
+
+normal format:
+  IF leading numbersign
+  THEN number field (format, number, "", " ")
+  ELIF leading point
+  THEN number field (format, number, "", " ")
+  ELIF leading plus 
+  THEN number field (format, abs (number), plus or minus, " ")
+  ELIF leading asterisk dollar
+  THEN number field (format, number, "$", "*")
+  ELIF leading asterisk 
+  THEN number field (format, number, "", "*")
+  ELIF leading dollarsign
+  THEN number field (format, number, "$", " ")
+  ELSE errorstop (1005, "USING-Format fehlerhaft: " + using format); "" FI  . 
+ 
+leading numbersign:      (format SUB 1) = numbersign  .
+leading point:           (format SUB 1) = point  .
+leading plus:            (format SUB 1) = plus  .
+leading asterisk dollar: subtext (format, 1, 3) = asterisk dollar  .
+leading asterisk:        subtext (format, 1, 2) = asterisk  .
+leading dollarsign:      subtext (format, 1, 2) = dollarsign  .
+
+trailing minus: (format SUB LENGTH format) = minus   .
+trailing plus:  (format SUB LENGTH format) = plus  .
+
+plus or minus:  IF number < 0.0 THEN minus ELSE plus FI  .
+nil or minus:   IF number < 0.0 THEN minus ELSE nil FI  .
+blank or minus: IF number < 0.0 THEN minus ELSE blank FI .
+
+END PROC format number;
+
+TEXT PROC exponent field (TEXT CONST format, REAL CONST value, INT CONST exponent pos):
+  REAL VAR number := abs (value);
+  INT CONST point pos := pos (format, point);
+  calc leading and trailing;
+  INT CONST new exponent :: decimal exponent (value) - leading + 1;
+  IF abs (new exponent) >= 100
+    THEN "%" + mantissa + "E" + null text (new exponent, 4)
+    ELSE mantissa + exponent
+  FI.
+
+calc leading and trailing:
+  INT VAR leading, trailing;
+  IF point pos = 0
+  THEN leading := exponent pos-1;
+       trailing := 0
+  ELSE leading := point pos-1;
+       trailing := exponent pos-point pos-1
+  FI  .
+
+mantissa:
+  set exp (leading - 1, number);
+  IF point pos = 0
+  THEN subtext (text (number, leading+1, 0), 1, leading)
+  ELSE subtext (text (number, leading+trailing+2, trailing), 2) FI  .
+
+exponent:
+  "E" + null text (new exponent, 3)  .
+
+END PROC exponent field;
+
+TEXT PROC number field (TEXT CONST format, REAL CONST value,
+                        TEXT CONST pretext, lead char):
+  INT CONST point pos :: pos (format, point);
+  calc fraction;
+  calc digits;
+  calc commata if necessary;
+  fill with lead chars and sign  .
+
+calc fraction:
+  INT VAR fraction :: 0, i;
+  FOR i FROM point pos+1 UPTO length (format)
+  WHILE (format SUB i) = numbersign
+  REP fraction INCR 1 PER  .
+
+calc digits:
+  TEXT VAR valuetext;
+  IF point pos = 0
+  THEN valuetext := digits (abs (value), 0, TRUE);
+       delete char (valuetext, length (valuetext))
+  ELSE valuetext := digits (abs (value), fraction, point pos <> 1) FI  .
+
+calc commata if necessary:
+  IF comma before point
+  THEN insert commata FI  .
+
+comma before point:
+  point pos > 0 CAND (format SUB point pos-1) = comma   .
+
+insert commata:
+  i := pos (valuetext, point)-3;
+  WHILE i > 1 CAND (valuetext SUB i) <> " "
+  REP insert char (valuetext, ",", i);
+      i DECR 3
+  PER  .
+
+fill with lead chars and sign:
+  IF trailing minus
+  THEN fillby (pretext + valuetext, length (format)-1, lead char) + nil or minus
+  ELIF trailing plus
+  THEN fillby (pretext + valuetext, length (format)-1, lead char) + plus or minus
+  ELIF value < 0.0
+  THEN fillby (pretext + minus + valuetext, length (format), lead char)
+  ELSE fillby (pretext + valuetext, length (format), lead char) FI  .
+
+
+plus or minus:  IF value < 0.0 THEN minus ELSE plus FI  .
+nil or minus:   IF value < 0.0 THEN minus ELSE nil FI  .
+trailing minus: (format SUB LENGTH format) = minus   .
+trailing plus:  (format SUB LENGTH format) = plus  .
+END PROC numberfield;
+
+TEXT PROC null text (INT CONST n, digits):
+  TEXT VAR l result := text (abs (n), digits);
+  IF n < 0
+  THEN replace (l result, 1, "-")
+  ELSE replace (l result, 1, "+") FI;
+  change all (l result, " ", "0");
+  l result  .
+END PROC null text;
+
+TEXT PROC fillby (TEXT CONST source, INT CONST format, TEXT CONST with):
+  IF differenz >= 0
+  THEN differenz * with + source
+  ELSE "%" + source FI  .
+
+differenz:  format - length (source)  .
+END PROC fillby;
+
+TEXT PROC digits (REAL CONST value, INT CONST frac, BOOL CONST null):
+  IF decimal exponent (value) < 0
+  THEN TEXT VAR l result := text (value, frac+2, frac);
+
+       IF null AND first char <> "0"
+       THEN replace (l result, 1, "0");
+            l result
+       ELIF (NOT null AND first char = "0") OR first char = " "
+       THEN subtext (l result, 2)
+       ELSE l result FI
+  ELSE text (value, decimal exponent (value)+frac+2, frac) FI  .
+
+first char:
+  (l result SUB 1)  .
+
+END PROC digits;
+
+TEXT PROC right (TEXT CONST msg, INT CONST len):
+  IF length (msg) >= len
+  THEN subtext (msg, 1, len)
+  ELSE (len - length (msg)) * " " + msg FI
+
+END PROC right;
+
+END PACKET basic using;
+
+PACKET basic output                          (* Autor: R. Ruland        *)
+                                             (* Stand: 28.08.1987/rr/mo *)
+       DEFINES basic page,
+               width,           
+               init output,     
+               basic out,
+               basic write,
+               tab,
+               next zone,
+               next line,
+               next page,
+               cursor x pos,
+               pos,
+               csrlin,
+               l pos,
+               switch to printout file,
+               switch back to old sysout state:
+
+LET zone width = 16;  (*  sd.ddddddEsdddb  (s = sign, d = digit, b = blank) *)
+LET printfile name = "BASIC LPRINT OUTPUT";
+
+INT VAR screen width, x cursor, y cursor, line no;
+BOOL VAR paging := FALSE, first time,
+         in lprint;     (* mo *)
+TEXT VAR buffer, output line, last sysout file, old sysout, char;
+
+PROC basic page (BOOL CONST status):
+
+  paging := status
+
+END PROC basic page;
+
+BOOL PROC basic page:  paging  END PROC basic page;
+
+
+PROC width (INT CONST max):
+
+  IF   max < 0
+       THEN errorstop (1005, "WIDTH: negatives Angabe: " + text (max))
+  ELIF max = 0
+       THEN screen width := 1
+       ELSE screen width := max
+  FI;
+  last sysout file := "";
+
+END PROC width;
+
+INT PROC width :  screen width  END PROC width;
+
+
+PROC init output:
+
+  clear using;
+  width (max (1, x size));
+  line no      := 1;
+  output line  := "";
+  first time   := TRUE;
+  in lprint := FALSE
+
+END PROC init output;
+
+
+PROC basic out (INT  CONST i):   bas out (basic text (i) + " ")  END PROC basic out;
+ 
+PROC basic out (REAL CONST r):   bas out (basic text (r) + " ")  END PROC basic out;
+ 
+PROC basic out (TEXT CONST t):   bas out (basic text (t))        END PROC basic out;
+
+PROC basic write (INT  CONST i): bas out (basic text (i))  END PROC basic write;
+
+PROC basic write (REAL CONST r): bas out (basic text (r))  END PROC basic write;
+
+PROC basic write (TEXT CONST t): bas out (basic text ("""" + t + """"))  END PROC basic write;
+
+ 
+PROC bas out (TEXT CONST msg):
+
+  get cursor;
+  IF length (msg) > free
+     THEN IF first time
+             THEN first time := FALSE;
+                  next line;
+                  bas out (msg);
+             ELSE buffer := subtext (msg, 1, free);
+                  IF sysout = ""
+                    THEN out (buffer)
+                    ELSE sysout write (buffer)
+                  FI;
+                  next line;
+                  buffer := subtext (msg, free + 1);
+                  bas out (buffer);
+          FI;
+     ELSE first time := TRUE;
+          IF sysout = ""
+            THEN out (msg)
+            ELSE sysout write (msg)
+          FI;
+  FI;
+
+  . free : screen width - x cursor + 1
+
+END PROC bas out;
+
+
+PROC tab (INT CONST n):
+
+  get cursor;
+  IF   n <= 0
+       THEN tab position out of range
+  ELIF n > screen width
+       THEN tab (n MOD screen width);
+  ELIF x cursor > n
+       THEN next line;
+            tab (n);
+  ELIF sysout = ""
+       THEN cursor (n, y cursor);
+       ELSE buffer := (n - x cursor) * " ";
+            sysout write (buffer)
+  FI;
+
+  . tab position out of range :
+      IF x cursor <> 1 THEN next line FI;
+      write ("WARNUNG : TAB-Position <= 0");
+      next line;
+
+END PROC tab;
+
+
+PROC next zone:
+
+  get cursor;
+  IF   x cursor > screen width - zone width
+       THEN next line;
+  ELIF sysout = ""
+       THEN free TIMESOUT " ";
+       ELSE buffer := free * " ";
+            sysout write (buffer)
+  FI;
+
+  . free : ((x cursor - 1) DIV zone width + 1) * zone width - x cursor + 1
+
+END PROC next zone;
+
+
+PROC next line :
+
+  IF sysout = ""
+     THEN next line on screen
+     ELSE line;
+          write ("");              (* generates new record *)
+          output line := "";
+  FI;
+
+  . next line on screen:
+      line no INCR 1;
+      IF paging CAND line no > y size
+        THEN IF in last line
+               THEN warte;
+               ELSE out (""13""10"");
+                    line no := y cursor + 1;
+             FI;
+      ELIF NOT paging
+        THEN char := incharety;
+             IF char <> ""
+               THEN IF char = "+"
+                      THEN paging := TRUE
+                      ELSE type (char)
+                    FI
+             FI;
+             out (""13""10"")
+        ELSE out (""13""10"")
+      FI
+
+  . in last line :
+      get cursor;
+      y cursor = y size
+
+  . warte :
+      cursor (x size - 2, y size);
+      out (">>");
+      inchar (char);
+      IF   char = ""13""
+           THEN next page
+      ELIF char = ""10""
+           THEN out (""8""8"  "13""10"") 
+      ELIF char = ""27""
+           THEN clear editor buffer;
+                errorstop (1, "")
+      ELIF char = "-"
+           THEN out (""8""8"  "13""10"");
+                line no := 1;
+                paging  := FALSE;
+           ELSE out (""8""8"  "13""10"");
+                line no := 1;
+      FI;
+
+      . clear editor buffer:
+          REP UNTIL get charety = "" PER;
+
+END PROC next line;
+
+
+PROC next page:
+
+  IF sysout = ""
+    THEN out (""1""4"")
+    ELSE line
+  FI;
+  clear using;
+  line no     := 1;
+  output line := "";
+
+END PROC next page;
+
+
+INT PROC pos (REAL CONST dummy):           (* mo *)
+
+  cursor x pos
+
+END PROC pos;
+
+
+INT PROC pos (INT CONST dummy):            (* mo *)
+
+  cursor x pos
+
+END PROC pos;
+
+
+INT PROC cursor x pos :
+
+  get cursor;
+  x cursor
+
+END PROC cursor x pos;
+
+
+INT PROC csrlin:                              (* mo *)
+
+  get cursor;
+  y cursor
+
+END PROC csrlin;
+
+
+PROC get cursor :
+
+  IF sysout = ""
+     THEN get cursor (x cursor, y cursor);
+     ELSE x cursor := LENGTH output line + 1;
+  FI;
+
+END PROC get cursor;
+
+
+INT PROC l pos (REAL CONST dummy):                   (* mo *)
+
+  l pos (0)
+
+END PROC l pos;
+
+
+INT PROC l pos (INT CONST dummy):                    (* mo *)
+
+  INT VAR lprint position :: 1;
+  IF exists (printfile name)
+    THEN disable stop;
+         FILE VAR printfile :: sequential file (modify, printfile name);
+         IF lines (printfile) > 0
+           THEN to line (printfile, lines (printfile));
+                lprint position := len (printfile) + 1
+         FI;
+         output (printfile)
+  FI;
+  lprint position
+
+END PROC l pos;
+
+
+PROC switch to printout file:                       (* mo *)
+
+  in lprint := TRUE;
+  old sysout := sysout;
+  careful sysout (printfile name);
+
+END PROC switch to printout file;
+
+
+PROC switch back to old sysout state:               (* mo *)
+
+  IF in lprint
+    THEN careful sysout (old sysout);
+         in lprint := FALSE
+  FI
+
+END PROC switch back to old sysout state;
+
+
+PROC sysout write (TEXT CONST string):
+  check sysout;
+  write (string);
+  output line CAT string.
+
+check sysout:
+  IF sysout <> last sysout file
+    THEN careful sysout (sysout)
+  FI.
+
+END PROC sysout write;
+
+
+PROC careful sysout (TEXT CONST new sysout):                  (* mo *)
+
+IF new sysout <> ""
+  THEN disable stop;
+       FILE VAR outfile :: sequential file (modify, new sysout);
+       max line length (outfile, screen width);
+       last sysout file := sysout;
+       IF lines (outfile) > 0
+         THEN to line (outfile, lines (outfile));
+              read record (outfile, output line);
+              delete record (outfile)
+         ELSE output line := ""
+       FI;
+       sysout (new sysout);
+       write (output line);
+  ELSE sysout ("")
+FI
+
+END PROC careful sysout;
+
+END PACKET basic output;
+
+
+PACKET basic input                              (* Autor: R. Ruland        *)
+                                                (* Stand: 27.10.1987/rr/mo *)
+
+       DEFINES init input,
+               read input,       
+               check input,
+               assign input,
+               assign input line,
+               input ok,
+               input eof:            
+
+
+LET comma             = ",",
+    quote             = """",
+
+    wrong type        = 1,
+    insufficient data = 2,
+    too much data     = 3,
+    overflow          = 4,
+
+    int overflow      = 4,
+    real overflow     = 6;
+
+INT VAR input line pos, input error no;
+BOOL VAR on terminal;
+TEXT VAR input line :: "", previous input line := "", input value;
+
+. first quote found : (input value SUB 1) = quote
+.;
+
+PROC init input :
+
+  input error no      := 0;
+  input line pos      := 0;
+  input line          := "";
+  previous input line := "";
+
+END PROC init input;
+
+
+PROC read input (BOOL CONST cr lf, TEXT CONST msg, BOOL CONST question mark):
+
+  on terminal := sysout <> "" AND sysin = "";
+  check input error;
+  out string (msg);
+  IF question mark THEN out string ("? ") FI;
+  IF sysin <> ""
+     THEN getline (input line);
+     ELSE editget input line;
+  FI;
+  out string (input line);
+  IF crlf THEN out line FI;
+  input line pos := 0;
+  input error no := 0;
+
+  . check input error :
+      IF input error no = 0
+         THEN input line := "";
+         ELSE IF sysin = ""
+                 THEN BOOL CONST old basic page := basic page;
+                      basic page (FALSE);
+                      IF cursor x pos <> 1 THEN next line FI;
+                      basic out ("?Eingabe wiederholen ! (" + error text + ")");
+                      next line;
+                      basic page (old basic page);
+                 ELSE errorstop (1080,"INPUT-Fehler (" + error text +
+                                               ") : >" + input line + "<");
+              FI;
+       FI;
+
+       . error text :
+           SELECT input error no OF
+             CASE wrong type        : "falscher Typ"
+             CASE insufficient data : "zu wenig Daten"
+             CASE too much data     : "zu viele Daten"
+             CASE overflow          : "Überlauf"
+                          OTHERWISE : ""
+           END SELECT
+
+  . editget input line :
+      TEXT VAR exit char;
+      INT VAR x, y;
+      get cursor (x, y);
+      REP IF width - x < 1
+            THEN out (""13""10"");
+                 get cursor (x, y)
+          FI;
+          editget (input line, max text length, width - x, "", "k", exit char);
+          cursor (x, y);
+          IF exit char = ""27"k"
+             THEN input line := previous input line;
+             ELSE previous input line := input line;
+                  LEAVE editget input line;
+          FI;
+      PER;
+      
+END PROC read input;
+
+
+PROC out string (TEXT CONST string) :
+
+  basic out (string);
+  IF on terminal THEN out (string) FI;
+
+END PROC out string;
+
+
+PROC out line :
+
+  next line;
+  IF on terminal THEN out (""13""10"") FI;
+
+END PROC out line;
+
+
+BOOL PROC check input (INT CONST type) :
+
+  get next input value;
+  input value := compress (input value);
+  set conversion (TRUE);
+  SELECT type OF
+    CASE 1 : check int input
+    CASE 2 : check real input
+    CASE 3 : check text input
+  END SELECT;
+  IF NOT last conversion ok THEN input error no := wrong type FI;
+  input error no = 0
+
+  . check int input :
+      IF input value <> ""
+         THEN disable stop;
+              INT VAR help int value;
+              help int value := int (input value);
+              IF is error CAND error code = int overflow
+                 THEN clear error;
+                      input error no := overflow;
+              FI;
+              enable stop;
+      FI;
+
+  . check real input :
+      IF input value <> ""
+         THEN disable stop;
+              REAL VAR help real value;
+              help real value := val (input value);
+              IF is error CAND (error code = real overflow
+                                OR error code = int overflow) (* <-- Aufgrund eines Fehlers in 'real' *)
+                 THEN clear error;
+                      input error no := overflow;
+              FI;
+              enable stop;
+        FI;
+
+  . check text input :
+      (* IF input value = "" THEN input error no := wrong type FI; *)
+      IF NOT is quoted string CAND quote found
+         THEN input error no := wrong type
+      FI; 
+
+      . is quoted string :
+          first quote found CAND last quote found
+
+          . last quote found :
+              (input value SUB LENGTH input value) = quote
+
+      . quote found :
+          pos (input value, quote) > 0
+
+END PROC check input;
+
+
+PROC assign input (INT VAR int value) :
+
+  get next input value;
+  int value := int (input value);
+
+END PROC assign input;
+
+PROC assign input (REAL VAR real value) :
+
+  get next input value;
+  real value := val (input value);
+
+END PROC assign input;
+
+PROC assign input (TEXT VAR string value) :
+
+  get next input value;
+  input value := compress (input value);
+  IF first quote found
+     THEN string value := subtext (input value, 2, LENGTH input value -1)
+     ELSE string value := input value
+  FI;
+
+END PROC assign input;
+
+PROC assign input line (TEXT VAR string line) :
+
+  string line := input line;
+
+END PROC assign input line;
+
+
+PROC get next input value :                                  (* F27/rr *)
+
+  IF input line pos > LENGTH input line 
+     THEN input value    := "";
+          input error no := insufficient data;
+     ELSE IF next non blank char = quote
+             THEN get quoted string
+             ELSE get unquoted string
+          FI;
+  FI;
+
+  . next non blank char :
+      INT CONST next non blank char pos := pos (input line, ""33"", ""255"", input line pos + 1);
+      input line SUB next non blank char pos
+
+  . get quoted string :
+      INT CONST quote pos := pos (input line, quote, next non blank char pos + 1);
+      IF quote pos = 0
+         THEN input value    := subtext (input line, next non blank char pos);
+              input line pos := LENGTH input line + 1;
+              input error no := wrong type;
+         ELSE input value    := subtext (input line, next non blank char pos, quote pos);
+              input line pos := pos (input line, ""33"", ""255"", quote pos + 1);
+              IF   input line pos = 0
+                   THEN input line pos := LENGTH input line + 1;
+              ELIF (input line SUB input line pos) <> comma
+                   THEN input error no := wrong type;
+                        input line pos DECR 1;
+              FI;
+      FI;
+
+  . get unquoted string :
+      INT VAR comma pos := pos (input line, comma, input line pos + 1);
+      IF comma pos = 0
+         THEN input value    := subtext (input line, input line pos + 1);
+              input line pos := LENGTH input line + 1;
+         ELSE input value    := subtext (input line, input line pos + 1, comma pos - 1);
+              input line pos := comma pos;
+      FI;
+
+END PROC get next input value;
+
+
+BOOL PROC input ok:
+
+  IF input line pos <= LENGTH input line
+     THEN input error no := too much data FI;
+  input line pos := 0;
+  input error no = 0
+
+END PROC input ok;
+
+BOOL PROC input eof:  input line = ""  END PROC input eof;
+
+
+END PACKET basic input; 
+
+PACKET basic std using io                         (* Autor: R. Ruland      *)
+                                                  (* Stand: 26.10.87/rr/mo *)
+
+       DEFINES init rnd:
+
+
+PROC init rnd:
+
+  REAL VAR init;
+  REP read input (TRUE, "Startwert des Zufallszahlengenerators ? ", FALSE);
+  UNTIL check input (2) CAND input ok PER;                      (* F24/rr *)
+  assign input (init);
+  init rnd (init);
+
+END PROC init rnd;
+
+
+END PACKET basic std using io;
+
diff --git a/basic/eumel coder 1.8.1 b/basic/eumel coder 1.8.1
new file mode 100644
index 0000000..0047067
--- /dev/null
+++ b/basic/eumel coder 1.8.1	
@@ -0,0 +1,3086 @@
+PACKET eumel coder                                 (* Autor: U. Bartling *) 
+       DEFINES coder on, coder off,
+               declare, define, apply, identify,
+               :=, =,
+               dump,
+ 
+               LIB,
+
+               LABEL,
+               gosub, goret,
+               computed branch,
+               complement condition code,
+
+               ADDRESS ,
+               GLOB, LOC, REF, DEREF,
+               ref length,
+               +, 
+               adjust,
+               get base,
+               is global, is local, is ref,
+ 
+               DTYPE, 
+               type class, type name,
+               void type, int type, real type, text type, bool type, 
+               bool result type, dataspace type, undefined type, 
+               row type, struct type, proc type, end type,
+ 
+               OPN, 
+               set length of local storage, 
+               begin module, end module, 
+               is proc, is eumel 0 instruction,
+               address, operation,
+               nop, 
+               mnemonic, 
+
+               parameter,
+               next param,
+               NEXTPARAM, 
+               access , 
+               dtype , 
+               param address,
+               same type ,
+ 
+               reserve storage, 
+               allocate denoter , 
+               allocate variable, 
+               data allocation by coder ,
+               data allocation by user,
+ 
+               run, run again, 
+               insert,
+               prot, prot off,
+               check, check on, check off,
+
+               help, bulletin, packets,
+
+(**************************************************************************)
+(*                                                                        *) 
+(*                         E U M E L  -  C O D E R                        *) 
+(*                                                                        *) 
+(*                                                                        *) 
+(*   Zur Beschreibung des Coders siehe                                    *) 
+(*         U.Bartling, J. Liedtke: EUMEL-Coder-Interface                  *) 
+(*                                                                        *) 
+(*   Stand der Dokumentation  : 29.10.1986                                *) 
+(*   Stand der Implementation : 03.09.1986                                *) 
+(*                                                                        *) 
+(*                                                                        *) 
+(**************************************************************************) 
+ 
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                  0. Datentyp DINT                          03.09.1987  *) 
+(*                                                                        *) 
+(*   Definition    des Datentyps                                          *) 
+(*                 arithmetischer Operationen                             *) 
+(*            und  Konvertierungsprozeduren                               *) 
+(*                                                                        *) 
+(**************************************************************************) 
+
+
+               DINT,
+               -, *, DIV, MOD, <, <=,
+               AND, OR, XOR,
+               dput, dget, dmov,
+               ddec1, dinc1, dinc, ddec,
+               dadd, dsub,
+               dequ, dlseq,
+               INCR, DECR,
+               put, get, cout,
+               text, real, int, dint,
+               replace, DSUB :
+ 
+ 
+TYPE DINT = STRUCT (INT low, high) ; 
+
+
+REAL VAR   real value ;           (* auch fuer Ausrichtung ! *)
+TEXT VAR convertion buffer ;
+
+DINT CONST dint0 :: dint(0) ;
+DINT VAR result  :: dint 0 ;
+  
+ 
+DINT PROC dint (INT CONST number) : 
+    EXTERNAL 144
+ENDPROC dint ; 
+
+INT PROC int (DINT CONST i) : 
+    EXTERNAL 143
+ENDPROC int;
+
+REAL PROC real (DINT CONST number) : 
+    real value := 65536.0 * real (number.high) ; 
+
+    IF   number.low >= 0 
+    THEN real value INCR real (number.low) 
+    ELSE real value INCR (real (number.low AND maxint) + 32768.0) 
+    FI ; 
+    real value
+ENDPROC real ; 
+
+DINT PROC dint (REAL CONST number) : 
+    real value := abs (number) ;
+    REAL CONST low := real value MOD 65536.0 ; 
+   
+    result.high := int(real value / 65536.0) ; 
+    IF   low < 32768.0 
+    THEN result.low := int (low)
+    ELSE result.low := int (low-32768.0) OR minint
+    FI ;
+    IF number < 0.0 THEN dsub (dint0, result, result) FI ;
+    result
+ENDPROC dint ; 
+
+TEXT PROC text (DINT CONST number) :
+    IF number.high = 0 THEN convert low part only
+                       ELSE convert number 
+    FI ; 
+    convertion buffer .
+ 
+convert low part only : 
+    IF number.low >= 0 THEN convertion buffer := text (number.low) 
+                       ELSE convertion buffer := text (real of low) ;
+                            erase decimal point
+    FI . 
+
+real of low : 
+    real (number.low AND maxint) + 32768.0 .
+
+convert number : 
+    convertion buffer := text (real(number)) ;
+    erase decimal point .
+
+erase decimal point :
+    convertion buffer := subtext (convertion buffer, 1, LENGTH convertion buffer-2)
+ENDPROC text;
+
+DINT PROC dint (TEXT CONST dint txt) :
+    convertion buffer := dint txt ;
+    INT CONST dot pos :: pos (convertion buffer, ".") ; 
+    IF dot pos = 0 THEN convertion buffer CAT ".0" FI ;
+    dint (real(convertion buffer))
+ENDPROC dint ;
+
+PROC get (DINT VAR dest) : 
+    REAL VAR number ;
+    get (number) ;
+    dest := dint (number)
+ENDPROC get ; 
+
+PROC put (DINT CONST number) : 
+    put (text (number));
+ENDPROC put ; 
+
+PROC cout (DINT CONST number) : 
+    EXTERNAL 61
+ENDPROC cout;
+
+OP := (DINT VAR a, DINT CONST b) : 
+#   INLINE ;   #
+    dmov (b, a); 
+ENDOP :=;
+
+OP INCR (DINT VAR a, DINT CONST b) : 
+#   INLINE ;   #
+    dinc (b, a); 
+ENDOP INCR;
+ 
+OP DECR (DINT VAR a, DINT CONST b) : 
+#   INLINE ;   #
+    ddec (b, a); 
+ENDOP DECR;
+
+BOOL OP = (DINT CONST a, b) : 
+    EXTERNAL 137 
+ENDOP =;
+
+BOOL OP <= (DINT CONST a, b) : 
+    EXTERNAL 138 
+ENDOP <=;
+
+BOOL OP < (DINT CONST a, b) :
+#   INLINE ;   #
+    NOT (b <= a)
+ENDOP <;
+
+BOOL PROC dequ (DINT CONST a, b) : 
+    EXTERNAL 137 
+ENDPROC dequ ;
+
+BOOL PROC dlseq (DINT CONST a, b) : 
+    EXTERNAL 138 
+ENDPROC dlseq ;
+
+PROC replace (TEXT VAR text, INT CONST index of dint, DINT CONST value) :
+    INT VAR subscript := index of dint * 2 ;
+    replace (text, subscript - 1,value.low); 
+    replace (text, subscript, value.high); 
+ENDPROC replace;
+
+DINT OP DSUB (TEXT CONST text, INT CONST index of dint) : 
+    INT  VAR subscript := index of dint * 2 ;
+    result.low  := text ISUB subscript - 1; 
+    result.high := text ISUB subscript;
+    result
+ENDOP DSUB;
+
+DINT OP + (DINT CONST a, b) :
+    EXTERNAL 135 
+ENDOP + ;
+ 
+DINT OP - (DINT CONST a, b) :
+    EXTERNAL 136 
+ENDOP - ;
+
+PROC dadd (DINT CONST a, b, DINT VAR res) :
+    EXTERNAL 135 
+ENDPROC dadd ;
+ 
+PROC dsub (DINT CONST a, b, DINT VAR res) :
+    EXTERNAL 136
+ENDPROC dsub ;
+
+PROC dinc (DINT CONST source, DINT VAR dest) : 
+    EXTERNAL 133 
+ENDPROC dinc ; 
+ 
+PROC ddec (DINT CONST source, DINT VAR dest) : 
+    EXTERNAL 134 
+ENDPROC ddec ; 
+ 
+PROC dmov (DINT CONST source, DINT VAR dest) : 
+    EXTERNAL 130 
+ENDPROC dmov; 
+
+DINT OP DIV (DINT CONST a,b) :
+    EXTERNAL 152
+ENDOP DIV ;
+
+DINT OP MOD (DINT CONST a,b) :
+    EXTERNAL 153
+ENDOP MOD ;
+
+DINT OP AND (DINT CONST a,b) :
+    result.low  := a.low  AND b.low ;
+    result.high := a.high AND b.high ;
+    result
+ENDOP AND ;
+
+DINT OP OR (DINT CONST a,b) :
+    result.low  := a.low  OR b.low ;
+    result.high := a.high OR b.high ;
+    result
+ENDOP OR ;
+
+DINT OP XOR (DINT CONST a,b) :
+    result.low  := a.low  XOR b.low ;
+    result.high := a.high XOR b.high ;
+    result
+ENDOP XOR ;
+
+PROC dput (ROW 32000 DINT VAR array, DINT CONST index, value) : 
+    EXTERNAL 139 
+ENDPROC dput ; 
+ 
+PROC dget (ROW 32000 DINT VAR array, DINT CONST index, DINT VAR dest) : 
+    EXTERNAL 140 
+ENDPROC dget ; 
+
+PROC dinc1 (DINT VAR dest) : 
+    EXTERNAL 131 
+ENDPROC dinc1 ; 
+ 
+PROC ddec1 (DINT VAR dest) :
+    EXTERNAL 132 
+ENDPROC ddec1 ; 
+
+DINT OP * (DINT CONST a,b) :
+    EXTERNAL 151
+ENDOP * ; 
+
+#page#
+                   (***** Globale Variable *****) 
+
+TEXT VAR object name;
+ 
+FILE VAR bulletin file; 
+ 
+INT VAR memory management mode, global address offset, packet base,
+        hash table pointer, nt link, permanent pointer, param link,
+        packet link, index, mode, field pointer, word,
+        number of errors := 0 ;
+ 
+BOOL VAR found, end of params;
+ 
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                  1. Interface zum ELAN-Compiler            13.11.1986  *) 
+(*                              1.8.1                                     *) 
+(*                                                                        *) 
+(*   Beschreibung der      Tabellen (-groessen),                          *) 
+(*                         internen Vercodung von Typen                   *) 
+(*                    und  Kennungen .                                    *) 
+(*   Initialisieren und Beenden des Compilers,                            *) 
+(*   Lesen aus und Schreiben in Namens- bzw. Permanent-Tabelle            *) 
+(*                                                                        *) 
+(**************************************************************************) 
+ 
+
+TYPE LIB = STRUCT (TEXT name, INT nt link, pt link, ADDRESS base) ;
+
+LET  begin of hash table         =     0 ,
+     end of hash table           =  1023 ,
+ 
+     begin of permanent table    = 22784 ,
+       before first pt entry     = 22784 ,
+       first permanent entry     = 22785 ,
+     end of permanent table      = 32767 , 
+
+     wordlength                  =     1 ,  (* compile  u n d  run time *)
+     two word length             =     2 ,
+     three word length           =     3 ,
+     four word length            =     4 ,
+ 
+     permanent param const             = 10000 ,
+     permanent param var               = 20000 ,
+     permanent proc op                 = 30000 ,
+     permanent type                    = 30000 ,
+     permanent row                     =    10 ,
+     permanent struct                  =    11 ,
+     permanent param proc              =    12 ,
+     permanent param proc end marker   =     0 ,
+     permanent type field              =     0 ,
+
+     ptt limit                         = 10000 ,
+     begin of pt minus ptt limit       = 12784 ,
+     begin of pt minus ptt limit 1     = 12785 , (* plus wordlength *)
+ 
+     void id                           =     0 ,
+     int id                            =     1 ,
+     real id                           =     2 ,
+     string id                         =     3 ,
+     bool id                           =     5 ,
+     bool result id                    =     6 ,
+     dataspace id                      =     7 ,
+     undefined id                      =     9 ,
+     row id                            =    10 ,
+     struct id                         =    11 ,
+     end id                            =     0 ,
+
+     const                             =     1 , 
+     var                               =     2 ,
+     proc id                           =     3 ,
+(*   denoter                           =     5 , *)
+     bold                              =     2 ,
+ 
+     ins                               = TRUE ,
+     no ins                            = FALSE ,
+     no lst                            = FALSE ,
+     sermon                            = TRUE  ,
+     no sermon                         = FALSE ,
+ 
+     run again mode                    =     0 ,
+     compile file mode                 =     1 ,
+     prep coder mode                   =     5 , 
+
+     warning message                   =     2 , 
+     error message                     =     4 ,
+ 
+     point line                        = "..............." ;
+ 
+INT CONST permanent packet            :=     -2 ,
+          permanent end               :=     -3 ;
+
+BOOL VAR coder active                 := FALSE ; 
+
+INT  VAR run again mod nr             :=     0 ;
+ 
+ 
+                     (***** Start/Ende *****)
+ 
+LET coder not active      = "CODER not active" ,
+    illegal define packet = "illegal define packet" ;
+
+PROC coder on (INT CONST data allocation mode) : 
+    mark coder on ; 
+    init opn section ; 
+    init compiler ;
+    init memory management .
+ 
+mark coder on :
+    coder active := TRUE .
+
+init memory management :
+    memory management mode := data allocation mode .
+ 
+init compiler :
+    no do again ;
+    elan (prep coder mode, bulletin file, "", run again mod nr,
+          no ins, no lst, check option, no sermon)
+
+ENDPROC coder on;
+ 
+PROC coder off (BOOL CONST insert, sermon, OPN CONST start proc) :
+    IF coder active 
+       THEN mark coder off ; 
+            end coder (insert, sermon, start mod nr if no insert)
+       ELSE errorstop (coder not active)
+    FI .
+ 
+start mod nr if no insert :
+    IF insert THEN run again mod nr := 0
+              ELSE run again mod nr := start proc.mod nr
+    FI ;
+    run again mod nr .
+
+mark coder off :
+    reset memory management mode ;
+    init opn section ;
+    coder active := FALSE
+ENDPROC coder off ; 
+ 
+PROC end coder (BOOL CONST insert wanted, sermon wanted, INT CONST mod) :
+    EXTERNAL 10021
+ENDPROC end coder ; 
+
+PROC elan (INT CONST mode, FILE VAR source, TEXT CONST line, 
+           INT VAR start module number, BOOL CONST ins, lst, rtc, ser) :
+  EXTERNAL 256
+ENDPROC elan ;
+
+PROC unsigned arithmetic : 
+    EXTERNAL 92 
+ENDPROC unsigned arithmetic ;
+ 
+
+                   (*****    Paket-Rahmen    *****)
+
+PROC declare (TEXT CONST name, LIB VAR packet) :
+    packet.name := name
+ENDPROC declare ;
+
+PROC define (LIB VAR packet) :
+    check if definition possible ;
+    declare object (packet.name, packet.nt link, packet.pt link) ;
+    open packet (packet.nt link, global address offset, packet base) ;
+    set to actual base (packet) .
+
+check if definition possible :
+    IF NOT coder active THEN errorstop (coder not active) FI ;
+    IF module open      THEN errorstop (illegal define packet) FI
+ENDPROC define ;
+
+PROC open packet (INT CONST nt link of packet name, INT VAR offset, base) :
+    EXTERNAL 10032 
+ENDPROC open packet ;
+
+PROC identify (TEXT CONST name, LIB VAR packet, BOOL VAR packet exists) :
+     to packet (name) ;
+     packet exists := found ;
+     IF found THEN packet.name    := name ;
+                   packet.nt link := nt link ;
+                   packet.pt link := packet link ;
+                   get pbas (packet.base)
+     FI
+ENDPROC identify ;
+
+ 
+                   (***** Hash/Namenstabelle *****) 
+.
+next hash entry :
+     hash table pointer INCR wordlength .
+
+end of hash table reached :
+     hash table pointer > end of hash table .
+
+yet another nt entry :
+     nt link := cdb int (nt link) ;
+     nt link <> 0 . ;
+ 
+PROC declare object (TEXT CONST name, INT VAR nt link, pt pointer) : 
+    EXTERNAL 10031
+ENDPROC declare object ; 
+ 
+PROC to object (TEXT CONST searched object) : 
+     hash ;
+     search nt entry .
+
+hash :
+     hash code := 0 ;
+     FOR index FROM 1 UPTO LENGTH searched object REP
+         addmult cyclic
+     ENDREP .
+
+addmult cyclic :
+     hash code INCR hash code ;
+     IF hash code > end of hash table THEN wrap around FI ;
+     hash code := (hash code + code (searched object SUB index)) MOD 1024 .
+
+wrap around :
+     hash code DECR end of hash table .
+
+hash code : nt link .
+
+search nt entry :
+     found := FALSE ;
+     WHILE yet another nt entry REP
+          read current entry ;
+          IF object name = searched object 
+             THEN found := TRUE ;
+                  LEAVE to object
+          FI
+     PER .
+
+read current entry :
+     permanent pointer := cdb int (nt link + wordlength) ;
+     object name := cdb text (nt link + two word length)
+ENDPROC to object ;
+
+
+                 (***** Permanent Tabelle *****) 
+.
+next procedure :
+     permanent pointer := cdb int (permanent pointer) . ;
+
+PROC next pt param :
+     mode := cdb int (param link) MOD ptt limit ;
+     param link INCR wordlength ;
+     IF   mode = permanent row    THEN skip over permanent row 
+     ELIF mode = permanent struct THEN skip over permanent struct
+     FI ;
+     set end marker if end of list .
+
+skip over permanent row :
+     param link INCR wordlength ;
+     next pt param .
+
+skip over permanent struct :
+     REP
+         mode := cdb int (param link) ;
+         IF mode = permanent type field
+            THEN param link INCR wordlength ;
+                 LEAVE skip over permanent struct
+         FI ;
+         next pt param
+     PER
+ENDPROC next pt param ;
+
+PROC set end marker if end of list :
+     mode := cdb int (param link) ;
+     end of params := mode >= permanent proc op OR mode <= 0 
+ENDPROC set end marker if end of list ;
+
+PROC get type and mode (INT VAR type) : 
+     mode := cdb int (param link) ;
+     IF   mode < 0                    THEN type := 2769 + (32767 + mode) ;
+                                           mode := 0
+     ELIF mode = permanent param proc THEN translate type
+                                      ELSE type := mode MOD ptt limit ;
+                                           mode DECR type ;
+                                           translate type if necessary ;
+                                           translate mode if necessary 
+     FI .
+
+translate type if necessary :
+     IF permanent row or struct THEN translate type FI .
+
+translate type :
+     type := param link - begin of pt minus ptt limit .
+
+translate mode if necessary : 
+    IF   mode = permanent param const THEN mode := const
+    ELIF mode = permanent param var   THEN mode := var
+    FI .
+
+permanent row or struct :
+     type = permanent row OR type = permanent struct
+ENDPROC get type and mode ;
+
+PROC put next permanent (INT CONST permanent value) : 
+    EXTERNAL 10020
+ENDPROC put next permanent ; 
+ 
+
+                 (***** Allgemeine Zugriffsprozeduren *****) 
+
+INT PROC cdb int (INT CONST index) :
+   EXTERNAL 116
+ENDPROC cdb int ;
+
+TEXT PROC cdb text (INT CONST index) :
+   EXTERNAL 117
+ENDPROC cdb text ;
+ 
+
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                  2. Spruenge und Marken                    07.10.1986  *) 
+(*                                                                        *) 
+(*   Definition des Datentyps LABEL                                       *) 
+(*                                                                        *) 
+(*   Deklaration, Definition und Applikation von Marken                   *) 
+(*                                                                        *) 
+(**************************************************************************) 
+
+
+
+TYPE LABEL = INT ; 
+
+BOOL VAR invers :: FALSE ; 
+ 
+PROC declare (LABEL VAR label) : 
+    CONCR (label) := 0
+ENDPROC declare ; 
+ 
+PROC define (LABEL VAR label) : 
+    EXTERNAL 10085
+ENDPROC define ; 
+ 
+PROC complement condition code : 
+    invers := NOT invers
+ENDPROC complement condition code ; 
+ 
+PROC apply (LABEL VAR label) : 
+    EXTERNAL 10151
+ENDPROC apply ; 
+ 
+PROC apply (LABEL VAR label, BOOL CONST condition) : 
+    IF condition xor invers THEN branch true (label) 
+                            ELSE branch false (label)
+    FI ;
+    invers := FALSE .
+
+condition xor invers : 
+    IF condition THEN NOT invers
+                 ELSE invers
+    FI
+ENDPROC apply ; 
+ 
+OP := (LABEL VAR global label, local label) : (* EQUATE ! *)
+    EXTERNAL 10014 
+ENDOP := ; 
+ 
+TEXT PROC dump (LABEL CONST label) : 
+    "LAB " + text (CONCR (label)) 
+ENDPROC dump ; 
+ 
+PROC gosub (LABEL VAR label) : 
+    EXTERNAL 10015 
+ENDPROC gosub ; 
+ 
+PROC goret : 
+    s0 (q goret code) 
+ENDPROC goret ; 
+ 
+PROC branch true (LABEL VAR label) : 
+    EXTERNAL 10028
+ENDPROC branch true ; 
+ 
+PROC branch false (LABEL VAR label) : 
+    EXTERNAL 10029
+ENDPROC branch false ; 
+
+PROC computed branch (ADDRESS CONST switch, INT CONST limit, LABEL VAR out) :
+    s1 (q esc case, REPR switch) ;
+    s0 (limit) ; 
+    branch false (out)
+ENDPROC computed branch ;
+ 
+ 
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                  3. Datenaddressen                         13.11.1986  *) 
+(*                                                                        *) 
+(*   Definition des Datentyps ADDRESS                                     *) 
+(*                                                                        *) 
+(*   Aufbau von Datenaddressen (Vercodung)                                *) 
+(*   Fortschalten und Ausrichten von Adressen                             *) 
+(*   Behandlung von Paketbasis-Adressen                                   *) 
+(*   Bereitstellen der Fehlermeldung "address overflow" (Coder-intern)    *) 
+(*                                                                        *) 
+(**************************************************************************) 
+ 
+ 
+ 
+TYPE ADDRESS = STRUCT (INT kind, value) ; 
+ 
+LET global                 = 0 , 
+    local                  = 1 , 
+    ref mask               = 2 , 
+    global ref             = 2 , 
+    local ref              = 3 , 
+    module nr              = 4 ,
+    immediate value        = 5 ,
+    p base                 = 6 ,
+ 
+    eumel0 stack offset    = 4 ,
+    local address limit    = 16 384 ,
+    global address zero    = 0 ,
+ 
+    illegal ref operation  = "REF not allowed" , 
+    deref on non ref       = "DEREF on non-ref address" ,
+    global ref not allowed = "GLOBAL REF not allowed" , 
+    unknown kind           = "Unknown address kind" , 
+    address overflow       = "Address Overflow" , 
+    illegal plus operation = "+ not allowed" ;
+ 
+ADDRESS VAR result addr;
+ 
+INT CONST ref length :: 2 ;
+
+OP := (ADDRESS VAR l, ADDRESS CONST r) : 
+    CONCR (l) := CONCR (r) 
+ENDOP := ; 
+ 
+ADDRESS OP GLOB (INT CONST address level) : 
+    result addr.kind  := global ; 
+    result addr.value := address level ; 
+    IF memory management mode = data allocation by user
+       THEN result addr.value INCR global address offset
+    FI ;
+    result addr
+ENDOP GLOB ;
+
+ADDRESS OP LOC (INT CONST address level) : 
+    result addr.kind  := local ;
+    result addr.value := address level + eumel0 stack offset ; 
+    result addr
+ENDOP LOC ; 
+ 
+ADDRESS OP REF (ADDRESS CONST addr) : 
+    CONCR (result addr) := CONCR (addr) ;
+    IF   result addr.kind = local  THEN result addr.kind INCR ref mask
+    ELIF result addr.kind = global THEN errorstop (global ref not allowed)
+                                   ELSE errorstop (illegal ref operation)
+    FI ;
+    result addr 
+ENDOP REF ; 
+ 
+ADDRESS OP DEREF (ADDRESS CONST ref address) : 
+    CONCR (result addr) := CONCR (ref address) ;
+    IF is not local ref THEN errorstop (deref on non ref) FI ; 
+    result addr.kind DECR ref mask ; 
+    result addr .
+ 
+is not local ref :
+    result addr.kind <> local ref
+ENDOP DEREF ;
+ 
+INT OP REPR (ADDRESS CONST addr) : 
+    CONCR (result addr) := CONCR (addr) ;
+    SELECT result addr.kind OF 
+        CASE global     :
+        CASE local      : set bit (result addr.value, 15) 
+        CASE global ref : errorstop (global ref not allowed)
+        CASE local ref  : prep local ref 
+        OTHERWISE errorstop (unknown kind)
+    ENDSELECT ; 
+    result addr.value .
+ 
+prep local ref : 
+    IF address limit exceeded THEN errorstop (address overflow) FI ;
+    set bit (result addr.value, 14) ; 
+    set bit (result addr.value, 15) .
+
+address limit exceeded :
+    result addr.value < eumel0 stack offset OR
+    result addr.value > local address limit
+ENDOP REPR ; 
+ 
+PROC get base (LIB CONST packet, ADDRESS VAR base) :
+    CONCR (base) := CONCR (packet.base)
+ENDPROC get base ;
+
+PROC set to actual base (LIB VAR packet) :
+    packet.base.kind  := p base ;
+    packet.base.value := packet base
+ENDPROC set to actual base ;
+
+PROC get pbas (ADDRESS VAR base) :
+    base.kind  := p base ;
+    base.value := cdbint (packet link + 2)
+ENDPROC get pbas ;
+
+BOOL OP = (ADDRESS CONST l,r) :
+    l.kind = r.kind AND l.value = r.value
+ENDOP = ;
+
+BOOL PROC is ref (ADDRESS CONST addr) : 
+    addr.kind = local ref
+ENDPROC is ref ; 
+ 
+BOOL PROC is global (ADDRESS CONST addr) : 
+    addr.kind = global 
+ENDPROC is global ; 
+ 
+BOOL PROC is local (ADDRESS CONST addr) : 
+    addr.kind = local 
+ENDPROC is local ; 
+ 
+ADDRESS OP + (ADDRESS CONST addr, INT CONST offset) : 
+    CONCR (result addr) := CONCR (addr) ; 
+    SELECT result addr.kind OF 
+        CASE global : inc global
+        CASE local  : inc local
+        OTHERWISE     errorstop (illegal plus operation) 
+    ENDSELECT ; 
+    result addr .
+
+inc global : 
+    result addr.value INCR offset ; 
+    IF result addr.value < 0 THEN errorstop (address overflow) FI .
+ 
+inc local : 
+    result addr.value INCR offset ; 
+    IF result addr.value < eumel 0 stack offset OR
+       result addr.value > local address limit
+       THEN errorstop (address overflow)
+    FI
+ENDOP + ; 
+ 
+PROC adjust (ADDRESS VAR addr, INT CONST adjust length) :
+    IF is local or global THEN adjust to length FI . 
+ 
+is local or global :
+    addr.kind <= local .
+
+adjust to length :
+    mode := addr.value MOD adjust length ;
+    IF mode <> 0 THEN addr.value INCR (adjust length-mode) FI
+ENDPROC adjust ;
+
+TEXT PROC dump (ADDRESS CONST addr) : 
+    kind + text (addr.value) . 
+ 
+kind : 
+    SELECT addr.kind OF 
+        CASE global          : "GLOBAL " 
+        CASE local           : "LOCAL " 
+        CASE immediate value : "IMMEDIATE "
+        CASE module nr       : "PARAM PROC "
+        CASE global ref      : "GLOBAL REF " 
+        CASE local ref       : "LOCAL REF " 
+        CASE p base          : "PBAS "
+        OTHERWISE              "undef. Addr: " 
+    ENDSELECT 
+ENDPROC dump; 
+
+
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                  4. Datentypen   Teil I                    08.09.1986  *) 
+(*                                                                        *) 
+(*   Definition des Datentyps DTYPE                                       *) 
+(*                                                                        *) 
+(*   Interne Repraesentation der primitiven Datentypen                    *) 
+(*   Identifikation von DTYPEs                                            *)
+(*                                                                        *) 
+(**************************************************************************) 
+
+
+
+TYPE DTYPE = INT ; 
+ 
+OP := (DTYPE VAR l, DTYPE CONST r) : 
+    CONCR (l) := CONCR (r) 
+ENDOP := ; 
+ 
+BOOL OP = (DTYPE CONST l, r) : 
+    CONCR (l) = CONCR (r)
+ENDOP = ; 
+ 
+DTYPE PROC void type :      DTYPE :(void id)   ENDPROC  void type ; 
+ 
+DTYPE PROC int  type :      DTYPE :(int id)    ENDPROC  int type ; 
+ 
+DTYPE PROC real type :      DTYPE :(real id)   ENDPROC  real type ; 
+ 
+DTYPE PROC text type :      DTYPE :(string id) ENDPROC  text type ; 
+ 
+DTYPE PROC bool type :      DTYPE :(bool id)   ENDPROC  bool type ; 
+ 
+DTYPE PROC bool result type : DTYPE :(bool result id) ENDPROC  bool result type; 
+ 
+DTYPE PROC dataspace type : DTYPE :(dataspace id) ENDPROC dataspace type ; 
+ 
+DTYPE PROC undefined type : DTYPE :(undefined id) ENDPROC undefined type ; 
+ 
+DTYPE PROC row type  :      DTYPE :(row id)    ENDPROC row type ; 
+ 
+DTYPE PROC struct type :    DTYPE :(struct id) ENDPROC struct type ; 
+ 
+DTYPE PROC proc type :   DTYPE :(permanent param proc) ENDPROC proc type ; 
+ 
+DTYPE PROC end type  :      DTYPE :(end id)    ENDPROC end type ; 
+ 
+INT PROC type class (DTYPE CONST type) : 
+    SELECT type id OF 
+        CASE int id, real id, bool id, bool result id, string id,
+             dataspace id, undefined id : 1 
+        CASE void id   : 0 
+        CASE row id    : 3 
+        CASE struct id : 4 
+        CASE permanent param  proc : 5 
+        OTHERWISE     pt type 
+    ENDSELECT . 
+
+pt type :
+    IF type id > ptt limit THEN permanent row or struct
+                           ELSE abstract type
+    FI .
+
+abstract type : 2 .
+
+permanent row or struct :
+    unsigned arithmetic ;
+    mode := cdbint (type link into pt) MOD ptt limit ; 
+    IF   mode = struct id            THEN 4
+    ELIF mode = row id               THEN 3
+    ELIF mode = permanent param proc THEN 5
+                                     ELSE 2
+    FI .
+ 
+type link into pt :
+    type id + begin of pt minus ptt limit .
+
+type id : CONCR (type)
+ENDPROC type class ; 
+ 
+PROC identify (TEXT CONST name,INT VAR size, align, DTYPE VAR type) : 
+    SELECT type pos OF 
+          CASE 1   : size := 0; align := 0; type id := void id
+          CASE 6   : size := 1; align := 1; type id := int id
+          CASE 10  : size := 4; align := 4; type id := real id
+          CASE 15  : size := 8; align := 4; type id := string id
+          CASE 20  : size := 1; align := 1; type id := bool id
+          CASE 25  : size := 1; align := 1; type id := dataspace id
+          OTHERWISE  search for type in permanent table 
+    ENDSELECT . 
+ 
+type pos : 
+    enclose in delimiters ;
+    pos (".VOID.INT.REAL.TEXT.BOOL.DATASPACE.", object name) . 
+ 
+enclose in delimiters :
+    object name := "." ;
+    object name CAT name ;
+    object name CAT "." .
+
+search for type in permanent table : 
+    to object (name) ;
+    IF not found THEN size := 0; align := 0; type id := undefined id
+                 ELSE size := cdbint (permanent pointer + two wordlength) ;
+                      type id := permanent pointer - begin of permanent table ;
+                      IF   size < two wordlength  THEN align := 1
+                      ELIF size < four wordlength THEN align := 2
+                                                  ELSE align := 4
+                      FI
+    FI . 
+ 
+not found :
+    NOT found OR invalid entry .
+
+invalid entry :
+    permanent pointer = 0 OR
+    cdb int (permanent pointer + wordlength) <> permanent type .
+
+type id : CONCR (type)
+ENDPROC identify ; 
+ 
+ 
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                  5. Operationen  Teil I                    30.09.1986  *) 
+(*                                                                        *) 
+(*   Definition des Datentyps OPN                                         *) 
+(*   Primitive Operationen (:=  etc.)                                     *) 
+(*   Initialisieren mit den externen Namen der EUMEL-0-Codes              *) 
+(*   Bereitstellen dee Fehlermeldung 'proc op expected' (coder-intern)    *) 
+(*                                                                        *) 
+(**************************************************************************) 
+
+
+TYPE OPN = STRUCT (INT kind, mod nr, top of stack) ;
+ 
+LET proc op    = 0 ,
+    param proc = 1 ,
+    eumel 0    = 2 , 
+    nil        = 3 , 
+ 
+    param proc at non ref = "PARAM PROC at non-ref address" ,
+    proc op expected      = "PROC expected" ;
+ 
+OPN VAR eumel0 opn;
+eumel0 opn.kind := eumel0 ;
+eumel0 opn.top of stack := 0 ;
+
+eumel0 opn.mod nr := q pp ;
+OPN CONST pp       :: eumel0 opn ,
+          nop code :: OPN :(nil, 0, 0) ;
+
+IF NOT exists ("eumel0 codes")
+    THEN IF yes ("Archive 'eumel coder' eingelegt")
+             THEN archive ("eumel coder") ;
+                  fetch ("eumel0 codes", archive) ;
+                  release (archive)
+             ELSE errorstop ("""eumel0 codes"" gibt es nicht")
+         FI
+FI ;
+BOUND THESAURUS VAR initial opcodes :: old ("eumel0 codes") ;
+THESAURUS VAR eumel 0 opcodes :: initial opcodes ; 
+forget ("eumel0 codes") ;
+ 
+ADDRESS PROC address (OPN CONST opn) :
+    IF opn.kind <> proc op THEN errorstop (proc op expected) FI ;
+    result addr.kind  := module nr ; 
+    result addr.value := opn.mod nr ;
+    result addr
+ENDPROC address ;
+ 
+OPN PROC operation (ADDRESS CONST addr) : 
+    IF addr.kind <> local ref THEN errorstop (param proc at non ref) FI ; 
+    OPN VAR opn ;
+    opn.kind := param proc ; 
+    opn.mod nr :=addr.value ; 
+    opn.top of stack := 0 ; 
+    opn 
+ENDPROC operation ; 
+ 
+TEXT PROC mnemonic (OPN CONST op code) : 
+    name (eumel 0 opcodes, op code.mod nr)
+ENDPROC mnemonic ;
+ 
+OPN PROC nop : 
+    nop code
+ENDPROC nop ; 
+ 
+OP := (OPN VAR r, OPN CONST l) : 
+    CONCR (r) := CONCR (l) 
+ENDOP := ; 
+ 
+BOOL PROC is proc (OPN CONST operation) : 
+    operation.kind = proc op
+ENDPROC is proc ; 
+ 
+BOOL PROC is eumel 0 instruction (TEXT CONST op code name) : 
+    link (eumel 0 opcodes, op code name) <> 0
+ENDPROC is eumel 0 instruction ; 
+
+BOOL PROC is eumel 0 instruction (OPN CONST operation) : 
+    operation.kind = eumel0
+ENDPROC is eumel 0 instruction ; 
+ 
+
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                  6. Parameterfeld                          10.04.1986  *) 
+(*                                                                        *) 
+(*   Bereitstellen des Parameterfeldes                                    *) 
+(*   Schreiben und Lesen von Eintraegen im Parameterfeld                  *) 
+(*   Fortschalten von Zeigern in das Parameterfeld                        *) 
+(*   Bereitstellen der Konstanten 'size of param field' (Coder-intern)    *) 
+(*                                                                        *) 
+(**************************************************************************) 
+
+
+
+LET PARAMDESCRIPTOR = STRUCT (DTYPE type,   INT access, 
+                              ADDRESS addr, OPN push opn) , 
+ 
+    size of param field   = 100 ,
+    param field exceeded  = "Param Field Overflow",
+    param nr out of range = "Illegal Param Number" ;
+ 
+ROW size of param field PARAMDESCRIPTOR VAR param field ;
+ 
+ 
+                      (***** Schreiben *****) 
+ 
+PROC test param pos (INT CONST param nr) : 
+    IF param nr < 1 OR param nr > size of param field
+       THEN errorstop (param nr out of range)
+    FI 
+ENDPROC test param pos ; 
+ 
+PROC declare (INT CONST param nr, DTYPE CONST type) : 
+    test param pos (param nr) ; 
+    enter type . 
+ 
+enter type :
+    CONCR (param field [param nr].type) := CONCR (type) 
+ENDPROC declare ; 
+ 
+PROC declare (INT CONST param nr, access) : 
+    test param pos (param nr) ; 
+    enter access . 
+
+enter access :
+    param field [param nr].access := access 
+ENDPROC declare ; 
+ 
+PROC define (INT CONST param nr, ADDRESS CONST addr) : 
+    test param pos (param nr) ; 
+    enter address . 
+
+enter address :
+    CONCR (param field [param nr].addr) := CONCR (addr) 
+ENDPROC define ; 
+ 
+PROC define (INT CONST param nr, value) : 
+    result addr.kind  := immediate value ;
+    result addr.value := value ;
+    define (param nr, result addr) 
+ENDPROC define ; 
+ 
+PROC apply (INT CONST param nr, OPN CONST opn) : 
+    test param pos (param nr) ; 
+    enter push opn . 
+ 
+enter push opn : 
+    CONCR (param field [param nr].push opn) := CONCR (opn) 
+ENDPROC apply ; 
+ 
+PROC parameter (INT CONST param nr, DTYPE CONST type, 
+                INT CONST access, ADDRESS CONST addr) : 
+    test param pos (param nr) ; 
+    enter type ; 
+    enter access ; 
+    enter address ; 
+    enter pp as default . 
+ 
+enter type : 
+    CONCR (param field [param nr].type) := CONCR (type) .
+
+enter access :
+    param field [param nr].access := access .
+
+enter address :
+    CONCR (param field [param nr].addr) := CONCR (addr) .
+
+enter pp as default :
+    CONCR (param field [param nr].push opn) := CONCR (pp) 
+ENDPROC parameter ; 
+ 
+ 
+                       (***** Lesen *****) 
+ 
+ADDRESS PROC param address (INT CONST param nr) : 
+    test param pos (param nr) ; 
+    param field [param nr].addr 
+ENDPROC param address ; 
+ 
+DTYPE PROC dtype (INT CONST param nr) : 
+    test param pos (param nr) ; 
+    param field [param nr].type 
+ENDPROC dtype ; 
+ 
+INT PROC access (INT CONST param nr) : 
+    test param pos (param nr) ; 
+    param field [param nr].access 
+ENDPROC access ; 
+ 
+ 
+                      (***** Fortschalten *****) 
+ 
+OP NEXTPARAM (INT VAR param nr) : 
+   test param pos (param nr) ; 
+   INT CONST class :: type class (param field [param nr].type) ;
+   param nr INCR 1 ;
+   SELECT class OF
+       CASE 3    : NEXTPARAM param nr
+       CASE 4,5  : read until end 
+    ENDSELECT .
+
+read until end : 
+    WHILE NOT end marker read or end of field REP
+        NEXTPARAM param nr 
+    PER ;
+    param nr INCR 1 .
+ 
+end marker read or end of field :
+    param nr > size of param field OR
+    CONCR (param field [param nr].type) = end id
+ENDOP NEXTPARAM ; 
+ 
+INT PROC next param (INT CONST p) : 
+    INT VAR index := p ; 
+    NEXTPARAM index ; 
+    index
+ENDPROC next param ; 
+ 
+TEXT PROC dump (INT CONST p) : 
+   IF p > 0 AND p <= 100 THEN dump entry (param field (p)) 
+                         ELSE param nr out of range 
+    FI 
+ENDPROC dump ; 
+ 
+TEXT PROC dump entry (PARAMDESCRIPTOR CONST id) : 
+(*  object name :=  dump (id.type) ; *)
+    object name :=  "TYPE " ;           (*  siehe                         *)
+    object name CAT dump (id.type) ;    (*    TEXT PROC dump (DTYPE d)    *)
+    object name CAT text (id.access) ; 
+    object name CAT dump (id.addr) ; 
+    object name CAT dump (id.push opn) ;
+    object name
+ENDPROC dump entry ; 
+
+ 
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                  7. Datentypen   Teil II                   08.09.1986  *) 
+(*                                                                        *) 
+(*   Deklaration neuer Datentypen                                         *) 
+(*   Vergleich von DTYPEs im Parameterfeld und in der Permanent-Tabelle   *) 
+(*                                                                        *) 
+(**************************************************************************) 
+
+
+
+DTYPE VAR pt type ;
+
+PROC declare (TEXT CONST name, INT CONST size, align, DTYPE VAR type) : 
+    entry into name table ; 
+    put next permanent (permanent type) ; 
+    put next permanent (size) ; 
+    put next permanent (nt link) ;
+    mark no offsets of text elements . 
+ 
+entry into name table : 
+    declare object (name, nt link, CONCR (type)) ;
+    CONCR (type) DECR begin of permanent table .
+ 
+mark no offsets of text elements : 
+    put next permanent (0) 
+ENDPROC declare ; 
+ 
+BOOL PROC same type (INT CONST param 1, param 2) : 
+    INT CONST left type :: CONCR (param field [param 1].type) ;
+    IF left type = right type
+       THEN same fine structure if there is one
+       ELSE left type = undefined id OR right type = undefined id
+    FI .
+ 
+right type : CONCR (param field [param 2].type) . 
+ 
+same fine structure if there is one : 
+    IF   left type = row id     THEN compare row 
+    ELIF left is struct or proc THEN compare struct 
+                                ELSE TRUE 
+    FI . 
+ 
+left is struct or proc :
+    left type = struct id OR left type = proc id .
+
+compare row : 
+    equal sizes AND same type (param1 + 1, param2 + 1) . 
+ 
+equal sizes : 
+    param field [param1+1].access = param field [param2+1].access .
+ 
+compare struct : 
+    INT VAR p1 :: param1+1, p2 :: param2+1 ; 
+    WHILE same type (p1, p2) AND NOT end type found REP
+       NEXTPARAM p1 ;
+       NEXTPARAM p2
+    UNTIL end of field PER ;
+    FALSE .
+
+end type found :
+    CONCR (param field [p1].type) = end id .
+
+end of field : 
+    p1 > size of param field OR p2 > size of param field 
+ENDPROC same type ;
+ 
+BOOL PROC same type (INT CONST param nr, DTYPE CONST type) : 
+    field pointer := param nr ;
+    CONCR (pt type) := CONCR (type) ;
+    equal types 
+ENDPROC same type ;
+
+BOOL PROC equal types :
+    identical types OR one type is undefined .
+
+one type is undefined :
+    type of actual field = undefined id OR CONCR(pt type) = undefined id .
+
+identical types :
+    SELECT type class (pt type) OF 
+        CASE 0, 1, 2 : type of actual field = CONCR (pt type)
+        CASE 3       : perhaps equal rows
+        CASE 4       : perhaps equal structs
+        CASE 5       : perhaps equal param procs
+        OTHERWISE      FALSE
+    ENDSELECT .
+
+perhaps equal rows :
+    param link := CONCR (pt type) + begin of pt minus ptt limit ;
+    is row AND equal row sizes AND equal row types . 
+ 
+is row :
+    type of actual field = row id .
+
+perhaps equal structs : 
+    param link := CONCR (pt type) + begin of pt minus ptt limit ;
+    is struct AND same type fields . 
+ 
+is struct :
+    type of actual field = struct id .
+
+equal row sizes :
+    pt row size = row size within param field . 
+
+equal row types :
+    field pointer INCR 1 ;
+    param link INCR 2 ;
+    get type and mode (CONCR(pt type)) ;
+    equal types .
+
+pt row size :
+    cdb int (param link + 1) .
+
+row size within param field :
+    param field [field pointer + 1].access .
+ 
+same type fields :
+    REP
+        field pointer INCR 1 ;
+        param link INCR 1 ;
+        IF type of actual field = end id
+             THEN LEAVE same type fields WITH pt struct end reached
+        FI ; 
+        get type and mode (CONCR(pt type)) ;
+        IF NOT equal types THEN LEAVE same type fields WITH FALSE FI
+    UNTIL end of field PER ;
+    FALSE .
+
+pt struct end reached : 
+    cdbint (param link) = permanent type field . 
+ 
+end of field :
+    field pointer > size of param field .
+
+type of actual field :
+    CONCR (param field [field pointer].type) .
+
+perhaps equal param procs :
+    param link := CONCR (pt type) + begin of pt minus ptt limit ;
+    is proc AND same param list . 
+
+is proc : cdbint (param link) = permanent param proc .
+
+same param list :
+    param link INCR wordlength ;
+    DTYPE VAR proc result type ;
+    get type and mode (CONCR (proc result type)) ;
+    compare param list ;
+    check results .
+
+compare param list :
+    INT VAR last param := field pointer + 1 ;
+    REP
+        field pointer INCR 1 ;
+        param link INCR wordlength ;
+        IF pt param list exhausted THEN LEAVE compare param list FI ; 
+        IF type of actual field = end id 
+           THEN LEAVE equal types WITH FALSE
+        FI ; 
+        get type and mode (CONCR(pt type)) ;
+        last param := field pointer ;
+    UNTIL NOT equal types OR end of field PER .
+
+check results : 
+    pt param list exhausted AND equal result types .
+
+equal result types :
+    save param link ;
+    IF same type (last param, proc result type)
+       THEN restore ;
+            TRUE
+       ELSE FALSE
+    FI .
+
+pt param list exhausted :
+    cdbint (param link) = permanent param proc end marker .
+
+save param link :
+    INT CONST p :: param link .
+
+restore :
+    field pointer INCR 1 ;
+    param link := p
+
+ENDPROC equal types ;
+
+BOOL PROC is not void bool or undefined (DTYPE CONST dtype) :
+    type <> void id AND type <> bool result id AND type <> undefined id .
+
+type : CONCR (dtype)
+ENDPROC is not void bool or undefined ;
+ 
+
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                  8. Operationen  Teil II                   08.09.1986  *) 
+(*                                                                        *) 
+(*   Definition der Opcodes                                               *) 
+(*   Deklaration, Definition, Identifikation und Applikation              *) 
+(*   Eroeffnen und Schliessen eines Moduls                                *)
+(*                                                                        *) 
+(**************************************************************************) 
+ 
+ 
+ 
+LET module not opened  = "Module not opened" , 
+    define missing     = "DEFINE missing" ,
+    wrong nr of params = "Wrong Nr. of Params:" , 
+    illegal kind       = "Opcode expected" ,
+    nested module      = "Nested Modules" ,
+    no mod nr          = "Param Proc expected" ,
+    no immediate value = "Value expected" ,
+    type error         = "Type Error" ,
+ 
+    q ln              =  1 ,
+    q move            =  2 ,    q move code             =  2 048 ,
+    q inc1            =  3 ,    q inc1 code             =  3 072 ,
+    q dec1            =  4 ,    q dec1 code             =  4 096 ,
+    q inc             =  5 ,    q inc code              =  5 120 ,
+    q dec             =  6 ,    q dec code              =  6 144 ,
+    q add             =  7 ,    q add code              =  7 168 ,
+    q sub             =  8 ,    q sub code              =  8 192 ,
+    q clear           =  9 ,    q clear code            =  9 216 ,
+    q test            = 10 , 
+    q equ             = 11 ,    q equ code              = 11 264 , 
+    q lsequ           = 12 ,    q lsequ code            = 12 288 , 
+    q fmove           = 13 ,    q fmove code            = 13 312 , 
+    q fadd            = 14 ,    q fadd code             = 14 336 , 
+    q fsub            = 15 ,    q fsub code             = 15 360 , 
+    q fmult           = 16 ,    q fmult code            = 16 384 , 
+    q fdiv            = 17 ,    q fdiv code             = 17 408 ,
+    q flsequ          = 18 ,    q flsequ code           = 18 432 ,
+    q tmove           = 19 ,    q tmove code            = 19 456 ,
+    q tequ            = 20 ,    q tequ code             = 20 480 , 
+    q accds           = 21 ,    q access ds code        = 22 528 , 
+    q ref             = 22 ,    q ref code              = 23 552 ,
+    q subscript       = 23 ,    q subscript code        = 24 576 , 
+    q select          = 24 ,    q select code           = 25 600 ,
+    q ppv             = 25 ,    q ppv code              = 26 624 ,
+    q pp              = 26 , 
+    q make false      = 27 , (* q make false code       = 65 513 *)
+    q movex           = 28 ,
+(*  q longa subs                q longa subs code       = 65 376 *) 
+    q return          = 29 ,    q return code           = 32 512 ,
+    q true return     = 30 ,    q true return code      = 32 513 ,
+    q false return    = 31 ,    q false return code     = 32 514 ,
+                                q goret code            = 32 519 ,
+    q esc mult        = 32 ,    q esc mult code         = 32 553 ,
+    q esc div         = 33 ,    q esc div code          = 32 554 , 
+    q esc mod         = 34 ,    q esc mod code          = 32 555 , 
+    q pproc           = 35 , 
+    q compl int       = 36 ,    q compl int code        = 32 551 ,
+    q compl real      = 37 ,    q compl real code       = 32 550 ,
+    q alias ds        = 38 ,    q alias ds code         = 32 546 ,
+    q movim           = 39 ,    q esc movim code        = 32 547 ,
+    q fequ            = 40 ,    q fequ code             = 32 548 ,
+    q tlsequ          = 41 ,    q tlsequ code           = 32 549 ,
+(*  q case            = 42 , *) q esc case              = 32 544 ,
+    q plus            = 43 ,
+    q minus           = 44 ,
+    q mult            = 45 ,
+    q int div         = 46 ,
+    q real div        = 47 ,
+    q equal           = 48 ,
+    q lessequal       = 49 ,
+    q ulseq           = 50 ,    q ulseq code            = 21 504 ,
+    q pdadd           = 51 ,    q pdadd code            = 32 653 ,
+    q ppsub           = 52 ,    q ppsub code            = 32 654 ,
+    q dimov           = 53 ,    q dimov code            = 32 655 ,
+    q idmov           = 54 ,    q idmov code            = 32 656 ;
+
+INT CONST q make false code :: - 1 022 , 
+          q longa subs code :: -   159 ,
+          q penter code     :: -   511 ;
+ 
+
+                   (***** Deklaration *****) 
+ 
+PROC declare (OPN VAR operation) : 
+    operation.kind := proc op ;
+    get module nr (operation.mod nr) ; 
+    operation.top of stack := 0 
+ENDPROC declare ; 
+ 
+PROC declare (TEXT CONST name, INT CONST first, params, OPN VAR operation) : 
+    declare (operation) ;
+    entry into name and pt table if necessary ; 
+    enter params ; 
+    enter result ; 
+    enter module number . 
+ 
+entry into name and pt table if necessary : 
+    declare object (name, nt link, permanent pointer) . 
+ 
+enter params : 
+    field pointer := first ;
+    FOR index FROM 1 UPTO params REP
+       enter param (param field [field pointer]) ;
+       NEXTPARAM field pointer 
+    PER .
+ 
+enter result : 
+    enter param (param field[field pointer].type, permanent proc op) .
+ 
+enter module number : 
+    put next permanent (operation.mod nr)
+ENDPROC declare ; 
+ 
+PROC enter param (PARAMDESCRIPTOR CONST param) :
+    IF   param.access = const 
+         THEN enter param (param.type, permanent param const)
+    ELIF param.access = var 
+         THEN enter param (param.type, permanent param var)
+    ELSE errorstop ("Unknown Access")
+    FI
+ENDPROC enter param ;
+
+PROC enter param (DTYPE CONST type, INT CONST permanent mode) :
+    unsigned arithmetic ;
+    SELECT type class (type) OF
+        CASE 0, 1, 2 : put next permanent (CONCR(type) + permanent mode)
+        OTHERWISE      errorstop ("Illegal Type")
+    ENDSELECT
+ENDPROC enter param ;
+
+
+                    (***** Definition *****) 
+ 
+PROC define (OPN VAR opn) : 
+    IF NOT module open THEN errorstop (module not opened)
+                       ELSE proc head (opn.mod nr, opn.top of stack)
+    FI 
+ENDPROC define ; 
+ 
+PROC set length of local storage (OPN VAR opn, INT CONST size) :
+    IF   size < 0 OR size > local address limit
+         THEN errorstop (address overflow)
+    ELIF opn.top of stack = 0
+         THEN errorstop (define missing)
+    ELIF opn.kind <> proc op
+         THEN errorstop (proc op expected)
+    FI ;
+    set length (opn.top of stack, size + eumel0 stack offset)
+ENDPROC set length of local storage ; 
+ 
+PROC define (OPN VAR operation, INT CONST size) : 
+    define (operation) ; 
+    set length of local storage (operation, size)
+ENDPROC define ; 
+ 
+ 
+                 (***** Identifikation *****) 
+ 
+INT VAR counter, result index, result type repr;
+ 
+PROC identify (TEXT CONST name, INT CONST first, params, OPN VAR operation,
+               BOOL VAR object exists) :
+    find result entry ; 
+    to object (name) ;
+    IF found  THEN first fit and leave if found FI ; 
+    IF eumel0 THEN identify eumel0 instruction 
+              ELSE yield undefined operation 
+    FI .
+ 
+find result entry : 
+    result index := first; 
+    counter := 0 ;
+    WHILE counter < params REP 
+        NEXTPARAM result index ; 
+        counter INCR 1
+    PER ;
+    check on param field exceeded .
+
+check on param field exceeded :
+    IF result index > size of param field
+       THEN errorstop (param field exceeded) 
+    FI .
+ 
+yield undefined operation :
+    declare (result index, undefined type) ;
+    apply (result index, nop) ;
+    object exists := FALSE .
+ 
+first fit and leave if found :
+    WHILE yet another procedure exists REP 
+        check one procedure and leave if match ; 
+        next procedure 
+    PER . 
+ 
+yet another procedure exists : 
+    permanent pointer <> 0 . 
+ 
+check one procedure and leave if match: 
+    param link := permanent pointer + wordlength ; 
+    set end marker if end of list ;
+    counter := params ; 
+    field pointer := first ;
+    REP
+       IF   end of params AND counter = 0 
+            THEN procedure found
+       ELIF end of params OR  counter = 0 
+            THEN LEAVE check one procedure and leave if match 
+            ELSE check next param 
+       FI 
+   PER . 
+ 
+check next param : 
+    get type and mode (CONCR(pt type)) ;
+    IF same types THEN set param mode ; 
+                       field pointer INCR 1 ;
+                       param link INCR 1 ;
+                       set end marker if end of list ;
+                       counter DECR 1 ; 
+                  ELSE LEAVE check one procedure and leave if match 
+    FI . 
+ 
+same types : (* inline version ! *)
+    equal types .
+ 
+set param mode : 
+    param field [field pointer].access := mode . 
+ 
+procedure found : 
+    get result ; 
+    operation.kind   := proc op ; 
+    operation.mod nr := module number ; 
+    operation.top of stack := 0 ;
+    object exists := TRUE ;
+    LEAVE identify . 
+ 
+get result : 
+    get type and mode (result type) ; 
+    declare (result index, mode) .
+ 
+module number :
+    cdbint (param link + 1) . 
+
+result type :
+    CONCR (param field [result index].type) .
+ 
+eumel0 : 
+    eumel0 opn.mod nr := link (eumel 0 opcodes, name) ; 
+    eumel0 opn.mod nr <> 0 .
+ 
+identify eumel 0 instruction : 
+    init result type with void ; 
+    CONCR (operation) := CONCR (eumel0 opn) ;
+    object exists := check params and set result ;
+    declare (result index, DTYPE:(result type repr)) ;
+    declare (result index, const) .
+
+init result type with void :
+    result type repr := void id . 
+ 
+check params and set result :
+    SELECT operation.mod nr OF
+       CASE q return, q false return, q true return : no params 
+       CASE q inc1, q dec1          : one int param yielding void 
+       CASE q pproc, q pp, q ln     : one param yielding void
+       CASE q test                  : one param yielding bool
+       CASE q clear, q ppv          : one int or bool param yielding void 
+       CASE q make false            : one bool param yielding void 
+       CASE q move                  : two int or bool params yielding void 
+       CASE q compl int, q inc, q dec : two int params yielding void
+       CASE q compl real, q fmove   : two real params yielding void 
+       CASE q equ, q lsequ, q ulseq : two int params yielding bool 
+       CASE q fequ, q flsequ        : two real params yielding bool 
+       CASE q tequ, q tlsequ        : two text params yielding bool
+       CASE q tmove                 : two text params yielding void
+       CASE q accds, q ref, q movim,
+            q dimov, q idmov        : two params yielding void
+       CASE q add, q sub, q esc mult,
+            q esc div, q esc mod    : three int params yielding void
+       CASE q fadd, q fsub, q fmult, q fdiv : three real params yielding void
+       CASE q select, q movex, q alias ds,
+            q pdadd, q ppsub        : three params 
+       CASE q subscript             : five params 
+       CASE q plus, q mult          : two intreals yielding intreal
+       CASE q minus                 : monadic or dyadic minus
+       CASE q int div               : two int params yielding int 
+       CASE q real div              : two real params yielding real
+       CASE q equal, q lessequal    : two intrealtexts yielding bool
+       OTHERWISE                      FALSE
+    ENDSELECT .
+ 
+no params : 
+    params = 0 . 
+
+one int param yielding void : 
+    p1 void (int type, first, params) .
+
+one param yielding void :
+    params = 1 . 
+
+one param yielding bool :
+    IF params = 1 THEN result type repr := bool id ; 
+                       TRUE 
+                  ELSE FALSE
+    FI .
+ 
+one int or bool param yielding void :
+    p1 void (int type, first, params) OR p1 void (bool type, first, params) . 
+
+one bool param yielding void :
+    p1 void (bool type, first, params) . 
+ 
+two int or bool params yielding void : 
+    p2 (int  type, first, params, void id) OR
+    p2 (bool type, first, params, void id) .
+
+two int params yielding void :
+    p2 (int type, first, params, void id) .
+
+two real params yielding void :
+    p2 (real type, first, params, void id) .
+
+two text params yielding void :
+    p2 (text type, first, params, void id) .
+
+two int params yielding bool :
+    p2 (int type, first, params, bool id) .
+
+two real params yielding bool :
+    p2 (real type, first, params, bool id) .
+
+two text params yielding bool :
+    p2 (text type, first, params, bool id) .
+
+two params yielding void :
+    params = 2 . 
+
+three int params yielding void :
+    p3 void (int type, first, params) .
+
+three real params yielding void :
+    p3 void (real type, first, params) .
+
+three params :
+    params = 3 .
+
+five params : 
+    params = 5 . 
+
+two intreals yielding intreal :
+    two int params yielding int OR two real params yielding real .
+
+monadic or dyadic minus :
+    IF   params = 2 THEN two intreals yielding intreal
+    ELIF params = 1 THEN monadic minus
+                    ELSE FALSE
+    FI .
+
+monadic minus :
+    result type repr := CONCR (param field[first].type) ;
+    result type repr = int id OR result type repr = real id .
+
+two intrealtexts yielding bool :
+    two int params yielding bool OR two real params yielding bool OR
+    two text params yielding bool .
+
+two int params yielding int :
+    p2 (int type, first, params, int id) .
+
+two real params yielding real :
+    p2 (real type, first, params, real id)
+ENDPROC identify ; 
+ 
+BOOL PROC p1 void (DTYPE CONST requested type, INT CONST first, param nr) :
+    param nr = 1 AND param type is requested plain type . 
+ 
+param type is requested plain type :
+    CONCR (param field [first].type) = CONCR (requested type) 
+ 
+ENDPROC p1 void ;
+ 
+BOOL PROC p2 (DTYPE CONST requested type, INT CONST first, param nr,
+              INT CONST result type) :
+    IF param nr = 2 AND param types equal requested plain type
+       THEN result type repr := result type ;
+            TRUE
+       ELSE FALSE
+    FI .
+ 
+param types equal requested plain type :
+    CONCR (param field [first]  .type) = CONCR (requested type) AND 
+    CONCR (param field [first+1].type) = CONCR (requested type)
+
+ENDPROC p2 ;
+ 
+BOOL PROC p3 void (DTYPE CONST requested type, INT CONST first, param nr) :
+    param nr = 3 AND param types ok .
+ 
+param types ok :
+    FOR index FROM first UPTO first+2 REP
+       IF different param types THEN LEAVE p3 void WITH FALSE FI 
+    PER ;
+    TRUE .
+ 
+different param types :
+    CONCR (param field [index].type) <> CONCR (requested type)
+ENDPROC p3 void; 
+
+
+                   (***** Applikation *****) 
+ 
+INT VAR address representation, left repr, right repr, result repr;
+
+PROC apply (INT CONST first, nr of params, OPN CONST opn) : 
+    IF NOT module open THEN errorstop (module not opened) FI ;
+    SELECT opn.kind OF 
+        CASE eumel 0    : generate eumel0 instruction 
+        CASE proc op    : call operation 
+        CASE param proc : call param proc
+        CASE nil        :
+        OTHERWISE         errorstop (illegal kind) 
+    ENDSELECT .
+ 
+call operation :
+    push params if necessary (first, nr of params, opn.mod nr) ; 
+    call (opn.mod nr) .
+ 
+call param proc : 
+    result addr.kind := local ref ;
+    result addr.value := opn.mod nr ;
+    INT CONST module nr := REPR result addr ;
+    push params if necessary (first, nr of params, module nr) ;
+    call param (module nr) .
+
+generate eumel0 instruction : 
+    SELECT real nr of params OF 
+        CASE 0 : p0 instruction 
+        CASE 1 : apply p1 (opn, first addr) 
+        CASE 2 : apply p2 (opn, first addr, second addr)
+        CASE 3 : apply p3 (opn, left type, first addr, second addr, third addr) 
+        CASE 5 : subscript operation
+        OTHERWISE errorstop (wrong nr of params + text (nr of params)) 
+    ENDSELECT . 
+ 
+real nr of params :
+    IF operator denotation THEN nr of params + 1
+                           ELSE nr of params
+    FI .
+
+operator denotation :
+    opn.mod nr >= q plus AND opn.mod nr < q ulseq .
+
+p0 instruction :
+    IF   opn.mod nr = q return       THEN s0 (q return code) 
+    ELIF opn.mod nr = q true return  THEN s0 (q true return code)
+    ELIF opn.mod nr = q false return THEN s0 (q false return code)
+                                     ELSE errorstop (wrong nr of params +
+                                                     mnemonic (opn)) 
+    FI .
+ 
+subscript operation :
+    IF opn.mod nr = q subscript 
+       THEN subscription
+       ELSE errorstop (wrong nr of params + text (nr of params))
+    FI .
+
+subscription :
+    ADDRESS CONST element length :: param field [first+2].addr ,
+                  limit          :: param field [first+3].addr ;
+    check on immediates ;
+    IF element length.value < 1024
+       THEN s0 (q subscript code + element length.value)
+       ELSE s0 (q longa subs code) ;
+            s0 (element length.value)
+    FI ;
+    s3 (limit.value - 1, subs index, base addr, subs result) .
+
+check on immediates :
+    IF element length.kind <> immediate value OR
+       limit.kind <> immediate value
+       THEN errorstop (no immediate value)
+    FI .
+
+subs index  : REPR param field [first+1].addr .
+
+base addr   : REPR param field [first].addr .
+
+subs result : REPR param field [first+4].addr .
+
+first addr : 
+    param field [first].addr .
+ 
+left type :
+    param field [first].type .
+
+second addr : 
+    param field [nextparam (first)].addr .
+ 
+third addr : 
+    param field [nextparam(nextparam(first))].addr
+ENDPROC apply ;
+ 
+PROC push params if necessary (INT CONST first, nr of params, mod nr) : 
+    init param push (mod nr) ;
+    field pointer := first ;
+    IF nr of params > 0 THEN push params FI ;
+    push result if there is one .
+ 
+push params : 
+    FOR index FROM 1 UPTO nr of params REP 
+        apply p1 (push code, param addr) ; 
+        NEXTPARAM field pointer
+    PER . 
+ 
+push code : 
+    param field [field pointer].push opn . 
+ 
+param addr :
+    param field [field pointer].addr . 
+ 
+push result if there is one : 
+    IF push result necessary 
+       THEN push result address (REPR param field [field pointer].addr)
+    FI . 
+
+push result necessary :
+    param field [field pointer].push opn.kind <> nil AND 
+    is not void bool or undefined (param field [field pointer].type) 
+ENDPROC push params if necessary ;
+
+PROC apply p1 (OPN CONST opn, ADDRESS CONST addr) : 
+    IF   opn.mod nr = q ln    THEN generate line number 
+    ELIF opn.mod nr = q pproc THEN push module nr
+                              ELSE gen p1 instruction
+    FI .
+
+gen p1 instruction : 
+    address representation := REPR addr ;
+    SELECT opn.mod nr OF 
+        CASE q inc1  : t1 (q inc1 code, address representation)
+        CASE q dec1  : t1 (q dec1 code, address representation)
+        CASE q clear : t1 (q clear code,address representation)
+        CASE q test  : test bool object (address representation)
+        CASE q pp    : push param (address representation)
+        CASE q ppv   : s1 (q ppv code, address representation)
+        CASE q make false : s1 (q make false code, address representation)
+        OTHERWISE errorstop (wrong nr of params + mnemonic (opn))
+    ENDSELECT .
+
+generate line number :
+    IF addr.kind = immediate value THEN mark line (addr.value)
+                                   ELSE errorstop (no immediate value)
+    FI .
+
+push module nr : 
+    IF addr.kind = module nr THEN push param proc (addr.value)
+                             ELSE errorstop (no mod nr)
+    FI
+ENDPROC apply p1; 
+ 
+PROC apply p2 (OPN CONST opn, ADDRESS CONST left addr, right addr): 
+    left repr := REPR left addr ;
+    IF opn.mod nr = q movim THEN move immediate
+                            ELSE gen p2 instruction 
+    FI . 
+ 
+gen p2 instruction : 
+    right repr := REPR right addr ;
+    SELECT opn.mod nr OF 
+        CASE q move       : t2 (q move code, right repr, left repr)
+        CASE q inc        : t2 (q inc code, right repr, left repr) 
+        CASE q dec        : t2 (q dec code, right repr, left repr) 
+        CASE q equ        : compare (q equ code, left repr, right repr) 
+        CASE q lsequ      : compare (q lsequ code, left repr, right repr) 
+        CASE q ulseq      : compare (q ulseq code, left repr, right repr)
+        CASE q fmove      : t2 (q fmove code, right repr, left repr)
+        CASE q flsequ     : compare (q flsequ code, left repr, right repr) 
+        CASE q tmove      : t2 (q tmove code, right repr, left repr)
+        CASE q tequ       : compare (q tequ code, left repr, right repr) 
+        CASE q compl int  : s2 (q compl int code, left repr, right repr)
+        CASE q compl real : s2 (q compl real code, left repr, right repr)
+        CASE q fequ       : compare (q fequ code, left repr, right repr) 
+        CASE q tlsequ     : compare (q tlsequ code, left repr, right repr) 
+        CASE q accds      : t2 (q access ds code, left repr, right repr)
+        CASE q ref        : t2 (q ref code, left repr, right repr) 
+        CASE q dimov      : s2 (q dimov code, left repr, right repr)
+        CASE q idmov      : s2 (q idmov code, left repr, right repr)
+        OTHERWISE errorstop (wrong nr of params + mnemonic (opn))
+    ENDSELECT .
+ 
+move immediate :
+    IF right addr.kind = immediate value 
+       THEN s0 (q esc movim code) ;
+            s1 (right addr.value, left repr)
+       ELSE errorstop (no immediate value)
+    FI
+ENDPROC apply p2; 
+ 
+PROC apply p3 (OPN CONST opn, DTYPE CONST left dtype, 
+               ADDRESS CONST left addr, right addr, result addr ):
+    result repr := REPR result addr ;
+    IF   opn.mod nr = q pdadd  THEN select with dint; LEAVE apply p3
+    ELIF opn.mod nr = q select THEN gen select instruction; LEAVE apply p3 FI ;
+    left repr   := REPR left addr ; 
+    IF   opn.mod nr = q movex    THEN gen long move
+    ELIF opn.mod nr = q alias ds THEN alias dataspace
+                                 ELSE gen p3 instruction
+    FI .
+
+gen long move :
+    IF right addr.kind = immediate value
+       THEN long move (left repr, result repr, right addr.value)
+       ELSE errorstop (no immediate value)
+    FI .
+
+alias dataspace :
+    IF right addr.value = immediate value
+       THEN s0 (q alias ds code) ;
+            s2 (right addr.value, result repr, left repr)
+       ELSE errorstop (no immediate value)
+    FI .
+
+gen select instruction :
+    IF right addr.kind = immediate value 
+       THEN IF different bases
+               THEN access external (left addr.value, right addr.value)
+               ELSE t1 (q select code, REPR left addr) ;
+                    s1 (right addr.value, result repr)
+            FI
+       ELSE errorstop (no immediate value)
+    FI .
+
+select with dint :
+    right repr := REPR right addr ;
+    IF different bases THEN access external packet
+                       ELSE simple access
+    FI .
+
+different bases :
+    left addr.kind = p base AND left addr.value <> packet base .
+
+simple access :
+    s3 (q pdadd code, REPR left addr, right repr, result repr) .
+
+access external packet :
+    access external (left addr.value, global address zero) ;
+    s3 (q pdadd code, REPR REF result addr, right repr, result repr) .
+
+gen p3 instruction :
+    right repr  := REPR right addr ; 
+    SELECT opn.mod nr OF 
+        CASE q add                : int add
+        CASE q sub                : int sub
+        CASE q fadd               : real add 
+        CASE q fsub               : real sub 
+        CASE q fmult              : real mult 
+        CASE q fdiv, q real div   : real div 
+        CASE q esc mult           : int mult 
+        CASE q esc div, q int div : int div 
+        CASE q esc mod            : int mod 
+        CASE q plus               : int real add
+        CASE q minus              : int real sub
+        CASE q mult               : int real mult
+        CASE q equal, q lessequal : compare (comp code, left repr, right repr)
+        CASE q ppsub              : distance between two objects
+        OTHERWISE errorstop (wrong nr of params + mnemonic (opn))
+    ENDSELECT . 
+ 
+int add   : compute (q add code, left repr, right repr, result repr) . 
+ 
+int sub   : compute (q sub code, left repr, right repr, result repr) . 
+ 
+real add  : compute (q fadd code, left repr, right repr, result repr) . 
+ 
+real sub  : compute (q fsub code, left repr, right repr, result repr) . 
+ 
+real mult : compute (q fmult code, left repr, right repr, result repr) . 
+ 
+real div  : compute (q fdiv code, left repr, right repr, result repr) . 
+ 
+int mult  : s3 (q esc mult code, left repr, right repr, result repr) . 
+ 
+int div   : s3 (q esc div code, left repr, right repr, result repr) . 
+ 
+int mod   : s3 (q esc mod code, left repr, right repr, result repr) .
+ 
+int real add : 
+    IF left type = int id THEN int add
+                          ELSE real add
+    FI . 
+ 
+int real sub :
+    IF left type = int id THEN int sub 
+                           ELSE real sub
+    FI .
+
+int real mult :
+    IF left type = int id THEN int mult
+                          ELSE real mult
+    FI . 
+
+comp code : 
+    SELECT left type OF
+        CASE int id    : IF opn.mod nr = q equal THEN q equ  ELSE q lsequ FI 
+        CASE real id   : IF opn.mod nr = q equal THEN q fequ ELSE q flsequ FI
+        CASE string id : IF opn.mod nr = q equal THEN q tequ ELSE q tlsequ FI
+        OTHERWISE errorstop (type error); q equ
+    ENDSELECT .
+
+left type : CONCR (left dtype) .
+
+distance between two objects :
+    s3 (q ppsub code, left repr, right repr, result repr)
+
+ENDPROC apply p3; 
+ 
+PROC access external (INT CONST old base, offset) :
+    s0 (q penter code + old base) ;
+    t2 (q ref code, offset, result repr) ;
+    s0 (q penter code + packet base)
+ENDPROC access external ;
+
+
+                      (***** Modul *****) 
+ 
+BOOL VAR module open ;
+
+.init opn section : 
+    module open := FALSE .;
+
+PROC begin module : 
+    IF module open THEN errorstop (nested module) 
+                   ELSE begin modul ; 
+                        module open := TRUE 
+    FI 
+ENDPROC begin module ; 
+ 
+PROC end module : 
+    IF NOT module open
+       THEN errorstop (module not opened) 
+       ELSE end modul ;
+            module open := FALSE
+    FI
+ENDPROC end module ; 
+
+TEXT PROC dump (OPN CONST operation) : 
+    IF   operation.kind = proc op THEN " PROC" + text (operation.mod nr, 5) 
+    ELIF operation.kind = eumel 0 THEN " EUMEL0: " + mnemonic (operation)
+                                  ELSE " undef. Opn" 
+    FI 
+ENDPROC dump ; 
+ 
+PROC begin modul :
+    EXTERNAL 10073
+ENDPROC begin modul ; 
+ 
+PROC end modul :
+    EXTERNAL 10011
+ENDPROC end modul ; 
+ 
+PROC proc head (INT VAR mod nr, top of stack) :
+    EXTERNAL 10012
+ENDPROC proc head ; 
+ 
+PROC set length (INT CONST top of stack, size) : 
+    EXTERNAL 10013
+ENDPROC set length ; 
+ 
+PROC get module nr (INT VAR module nr) : 
+    EXTERNAL 10016
+ENDPROC get module nr ; 
+ 
+PROC compute (INT CONST op code, l addr, r addr, result address) :
+    EXTERNAL 10017
+ENDPROC compute ; 
+ 
+PROC compare (INT CONST op code, l addr, r addr) :
+    EXTERNAL 10018
+ENDPROC compare ; 
+ 
+PROC long move (INT CONST to, from, length) :
+    EXTERNAL 10019
+ENDPROC long move ;
+
+PROC call (INT CONST mod nr) : 
+    EXTERNAL 10022
+ENDPROC call ; 
+ 
+PROC call param (INT CONST mod nr) : 
+    EXTERNAL 10023
+ENDPROC call param ; 
+ 
+PROC push param (INT CONST addr) : 
+    EXTERNAL 10024
+ENDPROC push param ; 
+ 
+PROC push param proc (INT CONST mod nr) : 
+    EXTERNAL 10025
+ENDPROC push param proc ; 
+ 
+PROC init param push (INT CONST mod nr) : 
+    EXTERNAL 10026
+ENDPROC init param push ; 
+ 
+PROC push result address (INT CONST addr) : 
+    EXTERNAL 10027
+ENDPROC push result address ; 
+ 
+PROC test bool object (INT CONST addr) : 
+    EXTERNAL 10192
+ENDPROC test bool object ; 
+ 
+PROC mark line (INT CONST line number) : 
+    EXTERNAL 10030
+ENDPROC mark line ; 
+ 
+PROC s0 (INT CONST op code) : 
+    EXTERNAL 10038
+ENDPROC s0 ; 
+ 
+PROC s1 (INT CONST op code, addr) : 
+    EXTERNAL 10039
+ENDPROC s1 ; 
+ 
+PROC s2 (INT CONST op code , addr1, addr2) : 
+    EXTERNAL 10040
+ENDPROC s2 ; 
+ 
+PROC s3 (INT CONST op code, addr1, addr2, addr3) : 
+    EXTERNAL 10041
+ENDPROC s3 ; 
+ 
+PROC t1 (INT CONST op code, addr) : 
+    EXTERNAL 10042
+ENDPROC t1 ; 
+ 
+PROC t2 (INT CONST op code, addr1, addr2) : 
+    EXTERNAL 10043
+ENDPROC t2 ; 
+ 
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                  9. Speicherverwaltung                     03.06.1986  *) 
+(*                                                                        *) 
+(*   Ablage der Paketdaten                                                *) 
+(*                                                                        *) 
+(**************************************************************************) 
+
+
+
+INT VAR address value;
+ 
+INT CONST data allocation by coder  := 1 , 
+          data allocation by user   := 2 ; 
+
+LET not initialized      = 0 ,
+    wrong mm mode        = "Wrong MM Mode" ,
+    define on non global = "Define for GLOB only" ,
+    text too long        = "TEXT too long" ;
+ 
+TEXT VAR const buffer :: point line ;
+
+.reset memory management mode :
+     memory management mode := not initialized . ;
+ 
+PROC reserve storage (INT CONST size) : 
+    IF memory management mode <> data allocation by user 
+       THEN errorstop (wrong mm mode) 
+    FI ; 
+    allocate var (address value, size) ; 
+    memory management mode := not initialized
+ENDPROC reserve storage ; 
+ 
+PROC allocate variable (ADDRESS VAR addr, INT CONST size) : 
+    IF memory management mode <> data allocation by coder 
+       THEN errorstop (wrong mm mode) 
+    FI ; 
+    allocate var (addr.value, size) ;
+    addr.kind := global
+ENDPROC allocate variable ; 
+ 
+PROC allocate denoter (ADDRESS VAR addr, INT CONST value) :
+    IF memory management mode <> data allocation by coder 
+       THEN errorstop (wrong mm mode) 
+    FI ; 
+    allocate int denoter (addr.value) ;
+    put data word (value, addr.value) ;
+    addr.kind := global
+ENDPROC allocate denoter ; 
+
+PROC allocate denoter (ADDRESS VAR addr, REAL CONST value) :
+    IF memory management mode <> data allocation by coder 
+       THEN errorstop (wrong mm mode) 
+    FI ; 
+    allocate real denoter (addr.value) ;
+    addr.kind := global ;
+    define (addr, value)
+ENDPROC allocate denoter ; 
+ 
+PROC allocate denoter (ADDRESS VAR addr, TEXT CONST value) :
+    IF memory management mode <> data allocation by coder 
+       THEN errorstop (wrong mm mode) 
+    FI ; 
+    allocate text denoter (addr.value, (LENGTH value+1) DIV 2 + 2) ; 
+    addr.kind := global ;
+    skip heaplink; 
+    define (addr, value) ; 
+    reset heaplink .
+ 
+skip heaplink : 
+    addr.value INCR 1 .
+
+reset heaplink :
+    addr.value DECR 1
+ENDPROC allocate denoter ; 
+ 
+PROC allocate denoter (ADDRESS VAR addr, DINT CONST value) :
+    IF memory management mode <> data allocation by coder 
+       THEN errorstop (wrong mm mode) 
+    FI ; 
+    allocate dint denoter (addr.value, value) ;
+    addr.kind := global
+ENDPROC allocate denoter ;
+
+PROC allocate dint denoter (INT VAR addr offset, DINT CONST value) :
+    adjust to an even address if necessary ;
+    put data word (value.low, addr offset) ;
+    allocate int denoter (address value) ;
+    put data word (value.high, address value) .
+
+adjust to an even address if necessary :
+    allocate int denoter (addr offset) ;
+    IF (addr offset AND 1) <> 0 THEN allocate int denoter (addr offset) FI
+ENDPROC allocate dint denoter ; 
+
+PROC define (ADDRESS CONST addr, INT CONST value) : 
+    IF addr.kind <> global 
+       THEN errorstop (define on non global) 
+    FI ; 
+    put data word (value, addr.value) 
+ENDPROC define ; 
+ 
+PROC define (ADDRESS CONST addr, DINT CONST value) : 
+    IF addr.kind <> global
+       THEN errorstop (define on non global) 
+    FI ; 
+    put data word (value.low , addr.value);
+    put data word (value.high, addr.value + 1)
+ENDPROC define ;
+
+PROC define (ADDRESS CONST addr, REAL CONST value) : 
+    IF addr.kind <> global 
+       THEN errorstop (define on non global) 
+    FI ; 
+    replace (const buffer, 1, value) ; 
+    address value := addr.value ;
+    FOR index FROM 1 UPTO 4 REP 
+        put data word (const buffer ISUB index, address value) ;
+        address value INCR 1
+    PER 
+ENDPROC define ; 
+ 
+PROC define (ADDRESS CONST addr, TEXT CONST value) : 
+    IF   addr.kind <> global THEN errorstop (define on non global) 
+    ELIF LENGTH value > 255  THEN errorstop (text too long)
+    FI ; 
+    address value := addr.value ;
+    const buffer := code (LENGTH value) ; 
+    const buffer CAT value ; 
+    const buffer CAT ""0"" ;
+    FOR index FROM 1 UPTO LENGTH const buffer DIV 2 REP 
+        put data word (const buffer ISUB index, address value) ;
+        address value INCR 1
+    PER ; 
+    const buffer := point line
+ENDPROC define ; 
+ 
+PROC allocate var (INT VAR addr, INT CONST length) : 
+    EXTERNAL 10033
+ENDPROC allocate var ; 
+ 
+PROC allocate int denoter (INT VAR addr) : 
+    EXTERNAL 10034
+ENDPROC allocate int denoter ;
+ 
+PROC allocate real denoter (INT VAR addr) : 
+    EXTERNAL 10035 
+ENDPROC allocate real denoter ;
+
+PROC allocate text denoter (INT VAR addr, INT CONST length) : 
+    EXTERNAL 10036 
+ENDPROC allocate text denoter ;
+ 
+PROC put data word (INT CONST value, INT CONST addr) :
+    EXTERNAL 10037
+ENDPROC put data word ; 
+ 
+ 
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                 10. Inspector                              28.10.1987  *) 
+(*                                                                        *) 
+(**************************************************************************) 
+
+
+
+INT VAR line number, pattern length, begin of packet,
+        last packet entry, indentation;
+
+TEXT VAR bulletin name, type and mode, pattern, buffer, dummy name;
+ 
+DATASPACE VAR bulletin ds :: nilspace ;
+
+.packet name :
+     cdb text (cdb int(packet link + wordlength) + two word length) .
+
+.packet entry :
+     permanent pointer = 0 OR
+     cdbint (permanent pointer) = permanent packet OR
+     cdbint (permanent pointer + wordlength) = permanent packet .
+
+.within editor :
+    aktueller editor > 0 .  ;
+
+TEXT PROC type name (DTYPE CONST type) : 
+    type and mode := "" ; 
+    IF CONCR (type) = void id THEN type and mode CAT "VOID"
+                              ELSE name of type (CONCR (type)) 
+    FI ;
+    type and mode
+ENDPROC type name ; 
+ 
+TEXT PROC dump (DTYPE CONST type) :
+(*  type and mode := "TYPE " ;
+    name of type (CONCR (type)) ; 
+    type and mode
+*)
+    type name (type)    (* aus Kompatibilitätsgründen zum 1.9.2 Coder / rr *)
+ENDPROC dump ;
+
+PROC name of type (INT CONST type) :
+            SELECT type OF
+     CASE void id                 :
+     CASE int id                  : type and mode CAT "INT"
+     CASE real id                 : type and mode CAT "REAL"
+     CASE string id               : type and mode CAT "TEXT"
+     CASE bool id, bool result id : type and mode CAT "BOOL"
+     CASE dataspace id            : type and mode CAT "DATASPACE"
+     CASE row id                  : type and mode CAT "ROW "
+     CASE struct id               : type and mode CAT "STRUCT"
+     OTHERWISE                    : complex type
+            ENDSELECT .
+
+complex type :
+     unsigned arithmetic ;
+     IF type > ptt limit THEN perhaps permanent struct or row
+                         ELSE get complex type
+     FI .
+
+perhaps permanent struct or row :
+     index := type + begin of pt minus ptt limit ;
+     mode := cdb int (index) MOD ptt limit ;
+     IF   mode = permanent row    THEN get permanent row 
+     ELIF mode = permanent struct THEN get permanent struct
+                                  ELSE type and mode CAT "-"
+     FI .
+
+get complex type :
+     index := type + begin of permanent table ;
+     IF is complex type THEN get name
+                        ELSE type and mode CAT "-"
+     FI .
+
+is complex type :
+     permanent type definition mode = permanent type .
+
+get name :
+     type and mode CAT cdb text (link to type name + two word length) .
+
+link to type name :
+     cdb int (index + three word length) .
+
+permanent type definition mode :
+     cdb int (index + wordlength) .
+
+get permanent row :
+     INT VAR t; 
+     type and mode CAT "ROW " ;
+     type and mode CAT text (cdb int (index + wordlength)) ;
+     type and mode CAT " " ;
+     param link := index + two wordlength ;
+     get type and mode (t) ;
+     name of type (t) .
+ 
+get permanent struct :
+     type and mode CAT "STRUCT ( ... )" 
+ENDPROC name of type ;
+
+PROC help (TEXT CONST proc name) :
+     prep bulletin ;
+     prep help ;
+     scan (object name) ;
+     next symbol (pattern) ;
+     packet link := end of permanent table ;
+     IF function = 0 THEN standard help
+                     ELSE asterisk help
+     FI .
+
+prep help :
+     object name := compress (proc name) ;
+     INT VAR function :: 0 ;
+     INT CONST l :: LENGTH object name ;
+     IF l > 1 AND object name <> "**"
+        THEN IF (object name SUB l) = "*"
+               THEN function INCR 2 ;
+                    delete char (object name, l)
+             FI ;
+             IF (object name SUB 1) = "*"
+               THEN function INCR 1 ;
+                    delete char (object name, 1)
+             FI ;
+             IF another asterisk THEN wrong function FI
+     FI.
+
+another asterisk :
+     pos (object name, "*") <> 0 .
+
+wrong function :
+     errorstop ("unzulaessige Sternfunktion") .
+
+standard help :
+     to object (pattern) ;
+     IF found THEN display
+              ELSE error stop ("unbekannt: " + proc name)
+     FI .
+
+display :
+     IF NOT packet entry
+        THEN WHILE permanent pointer <> 0 REP
+                 put name of packet if necessary ;
+                 put specifications (pattern) ;
+                 next procedure
+             ENDREP ;
+             show bulletin file
+        FI .
+ 
+put name of packet if necessary :
+     IF new packet THEN packet link := permanent pointer ;
+                        find begin of packet ;
+                        writeline (2) ;
+                        write packet name
+     FI .
+
+find begin of packet :
+     REP 
+         packet link DECR wordlength
+     UNTIL begin of packet found PER .
+
+begin of packet found :
+     cdb int (packet link) = permanent packet .
+
+new packet :
+     permanent pointer < packet link .
+
+asterisk help :
+     hash table pointer := begin of hash table ;
+     pattern length := LENGTH pattern - 1 ;
+     REP
+        list all objects in current hash table chain ;
+        next hash entry
+     UNTIL end of hash table reached ENDREP ;
+     show bulletin file .
+
+list all objects in current hash table chain :
+     nt link := hash table pointer ;
+     WHILE yet another nt entry REP
+        permanent pointer := cdb int (nt link + wordlength) ;
+        object name := cdb text (nt link + two word length) ;
+        IF matching THEN into bulletin FI
+     PER .
+
+matching :
+     INT CONST p :: pos (object name, pattern) ;
+     SELECT function OF
+         CASE 1 :   p <> 0 AND p = LENGTH object name - pattern length
+         CASE 2 :   p = 1
+         CASE 3 :   p <> 0
+         OTHERWISE  FALSE
+     ENDSELECT .
+
+into bulletin :
+     object names into bulletin (BOOL PROC not end of chain)
+ENDPROC help ;
+ 
+BOOL PROC not end of chain :
+     permanent pointer <> 0 
+ENDPROC not end of chain ;
+
+PROC write packet name :
+     indentation := 0 ;
+     write line ;
+     write bulletin line ("PACKET ") ;
+     indentation := 7 ;
+     object name := packet name ;
+     write bulletin line (object name) ;
+     write bulletin line (":") ;
+     writeline (2)
+ENDPROC write packet name ;
+
+PROC put specifications (TEXT CONST proc name) :
+     put obj name (proc name) ;
+     to first param ;
+     IF NOT end of params THEN put param list FI ;
+     put result ;
+     writeline .
+  
+to first param :
+     param link := permanent pointer + word length ;
+     set end marker if end of list .
+
+put result :
+     INT VAR type;
+     get type and mode (type) ;
+     IF type <> void id THEN type and mode := "  --> " ;
+                             name of type (type) ;
+                             write bulletin line (type and mode)
+     FI
+ENDPROC put specifications ;
+
+PROC put param list : 
+     write bulletin line (" (") ;
+     REP
+         INT VAR type, param mode;
+         get type and mode (type) ;
+         param mode := mode ;
+         put type and mode ;
+         maybe param proc ;
+         next pt param ;
+         IF end of params THEN write bulletin line (")") ;
+                               LEAVE put param list 
+         FI ;
+         write bulletin line (", ") ;
+     PER .
+
+put type and mode :
+     type and mode := "" ;
+     name of type (type) ;
+     type and mode CAT name of mode ;
+     write bulletin line (type and mode) .
+
+name of mode :
+     IF   param mode = const THEN " CONST"
+     ELIF param mode = var   THEN " VAR"
+                             ELSE " PROC"
+     FI .
+
+maybe param proc :
+     IF mode = permanent param proc THEN put virtual params FI .
+
+put virtual params :
+     skip over result type if complex type ;
+     IF NOT end of virtual params THEN put param list FI.
+
+skip over result type if complex type :
+     next pt param .
+
+end of virtual params :
+    end of params
+ENDPROC put param list ;
+
+PROC to packet (TEXT CONST packet name) :
+     to object ( packet name) ;
+     IF found THEN find start of packet objects FI .
+
+find start of packet objects :
+     last packet entry := 0 ;
+     packet link := before first pt entry ;
+     REP
+         packet link INCR wordlength ;
+         word := cdb int (packet link) ;
+         IF word < 0 THEN IF   word = permanent packet THEN packet found
+                          ELIF word = permanent end    THEN return
+                          FI
+         FI
+     ENDREP .
+
+packet found :
+     IF cdb int (packet link + wordlength) = nt link
+        THEN last packet entry := packet link FI .
+
+return : 
+     IF last packet entry <> 0 THEN found := TRUE ;
+                                    packet link := last packet entry
+                               ELSE found := FALSE
+     FI ;
+     LEAVE to packet
+ENDPROC to packet ;
+
+PROC next packet :
+     REP
+         packet link INCR wordlength ;
+         word := cdb int (packet link) ;
+         IF   word = permanent packet THEN true return
+         ELIF end of permanents       THEN false return
+         FI ;
+     ENDREP .
+
+true return :
+     found := TRUE ;
+     LEAVE next packet .
+
+false return :
+     found := FALSE ;
+     LEAVE next packet .
+
+end of permanents :
+     word = permanent end OR packet link > end of permanent table 
+ENDPROC next packet ;
+
+PROC prep bulletin :
+     forget (bulletin ds) ;
+     bulletin ds := nilspace ;
+     bulletin file := sequential file (output, bulletin ds) ;
+     line number := 0 ;
+     buffer := ""
+ENDPROC prep bulletin ;
+
+PROC show bulletin file :
+     IF within editor THEN ueberschrift neu FI ;
+     DATASPACE VAR local ds :: bulletin ds ;
+     FILE VAR local file :: sequential file (modify, local ds) ;
+     show (local file) ;
+     forget (local ds)
+ENDPROC show bulletin file ;
+
+PROC write bulletin line (TEXT CONST line) :
+     IF LENGTH buffer + LENGTH line > 75 THEN writeline FI ;
+     buffer CAT line
+ENDPROC write bulletin line ;
+
+PROC writeline  :
+     write (bulletin file, buffer) ;
+     line (bulletin file) ;
+     line number INCR 1 ;
+     cout (line number) ;
+     buffer := indentation * " "
+ENDPROC writeline ;
+
+PROC writeline (INT CONST times) :
+     IF LENGTH compress(buffer) <> 0 THEN index := times - 1 ;
+                                          writeline
+                                     ELSE index := times
+     FI ;
+     line (bulletin file, index) ;
+     line number INCR index;
+     indentation := 0 ;
+     cout (line number)
+ENDPROC writeline ;
+ 
+PROC bulletin (TEXT CONST packet name) :
+     prep bulletin ;
+     scan (packet name) ;
+     next symbol (pattern) ;
+     to packet (pattern) ;
+     IF found THEN list packet ;
+                   show bulletin file
+              ELSE error stop (packet name + " ist kein Paketname")
+     FI . 
+ 
+ENDPROC bulletin ;
+ 
+PROC list packet :
+     begin of packet := packet link + word length ;
+     write packet name ; 
+     find end of packet ;
+     run through nametab and list all packet objects .
+ 
+find end of packet :
+     last packet entry := begin of packet ;
+     REP
+         last packet entry INCR wordlength ;
+         word := cdb int (last packet entry) ;
+     UNTIL end of packet entries PER .
+
+end of packet entries :
+     word = permanent packet OR word = permanent end .
+
+run through nametab and list all packet objects :
+     hashtable pointer := begin of hashtable ;
+     REP
+         nt link := hashtable pointer ;
+         list objects of current packet in this chain ;
+         next hash entry
+     UNTIL end of hashtable reached ENDREP .
+
+list objects of current packet in this chain :
+     WHILE yet another nt entry REP 
+         permanent pointer := cdb int (nt link + wordlength) ;
+         put objects of this name
+     PER .
+
+put objects of this name :
+    IF there is an entry THEN into bulletin FI .
+
+there is an entry :
+    NOT packet entry AND
+    there is at least one object of this name in the current packet .
+
+there is at least one object of this name in the current packet :
+     REP
+        IF permanent pointer >= begin of packet AND
+           permanent pointer < last packet entry
+           THEN LEAVE there is at least one object of this name
+                      in the current packet WITH TRUE FI ;
+        next procedure
+     UNTIL permanent pointer = 0 PER ;
+     FALSE .
+
+into bulletin :
+     object name := cdb text (nt link + two word length) ;
+     object names into bulletin (BOOL PROC within packet)
+ENDPROC list packet ;
+
+BOOL PROC within packet :
+     permanent pointer >= begin of packet AND 
+     permanent pointer < last packet entry
+ENDPROC within packet ;
+
+PROC object names into bulletin (BOOL PROC link ok) :
+     scan (object name) ;
+     next symbol (dummy name, mode) ;
+     IF type definition THEN put type definition
+                        ELSE put object definitions
+     FI .
+
+type definition :
+     mode = bold AND no params .
+
+no params :
+     cdb int (permanent pointer + word length) >= permanent type .
+
+put type definition :
+     put obj name (object name) ;
+     write bulletin line ("TYPE ") ;
+     writeline (1) .
+
+put object definitions :
+     WHILE link ok REP
+         put specifications (object name) ;
+         next procedure
+     ENDREP 
+ENDPROC object names into bulletin ;
+ 
+PROC bulletin :
+     prep bulletin ;
+     packet link := first permanent entry ;
+     REP
+         list packet ;
+         write line (4) ;
+         next packet
+     UNTIL NOT found PER ;
+     show bulletin file
+ENDPROC bulletin ;
+
+PROC put obj name (TEXT CONST name) :
+     buffer := "      " ;
+     bulletin name := point line ;
+     change (bulletin name, 1, end of line or name, name) ;
+     buffer CAT bulletin name ;
+     indentation := LENGTH buffer + 1 .
+
+end of line or name :
+     min (LENGTH name, LENGTH bulletin name)
+ENDPROC put obj name ;
+
+PROC packets :
+     prep bulletin ;
+     packet link := first permanent entry ;
+     REP
+         object name := packet name ;
+         put obj name (object name) ;
+         write line ;
+         next packet 
+     UNTIL NOT found PER ;
+     show bulletin file
+ENDPROC packets ;
+ 
+#page#
+(**************************************************************************) 
+(*                                                                        *) 
+(*                 11. ELAN Run-Interface                     04.08.1986  *) 
+(*                                                                        *) 
+(*   Uebersetzen von ELAN-Programmen                                      *) 
+(*   Bereitstellen der Ausgabeprozeduren fuer den ELAN-Compiler           *) 
+(*                                                                        *) 
+(**************************************************************************) 
+ 
+ 
+ 
+BOOL VAR list option     := FALSE ,
+         check option    :=  TRUE ,
+         warning option  := FALSE , 
+         listing enabled := FALSE ;
+
+FILE VAR listing file ;
+
+TEXT VAR listing file name := "" ;
+ 
+ 
+PROC run (TEXT CONST file name) : 
+  enable stop ;
+  IF NOT exists (file name)
+    THEN errorstop ("""" + file name + """ gibt es nicht")
+  FI ;
+  last param (file name) ;
+  run elan (file name, no ins)
+END PROC run;
+ 
+PROC run :
+  run (last param)
+ENDPROC run ;
+ 
+PROC run again :
+  IF run again mod nr <> 0
+    THEN elan (run again mode, bulletin file, "", run again mod nr, 
+               no ins, no lst, check option, no sermon)
+    ELSE errorstop ("'run again' nicht moeglich")
+  FI
+ENDPROC run again ;
+ 
+PROC insert (TEXT CONST file name) : 
+  enable stop ;
+  IF NOT exists (file name)
+    THEN errorstop ("""" + file name + """ gibt es nicht")
+  FI ;
+  last param (file name) ;
+  run elan (file name, ins)
+ENDPROC insert ;
+ 
+PROC insert :
+  insert (last param)
+ENDPROC insert ;
+ 
+PROC run elan (TEXT CONST file name, BOOL CONST insert option) :
+  FILE VAR source := sequential file (modify, file name) ;
+  IF listing enabled
+    THEN open listing file
+  FI ;
+
+  disable stop ;
+  no do again ;
+  elan (compile file mode, source, "" , run again mod nr,
+        insert option, list option, check option, sermon) ;
+ 
+  IF anything noted AND command dialogue
+    THEN ignore halt during compiling ;
+         note edit (source) ;
+         last param (file name) ; 
+         errorstop ("")
+  FI .
+
+ignore halt during compiling :
+  IF is error
+    THEN put error ;
+         clear error ;
+         pause (5)
+  FI .
+
+open listing file :
+  listing file := sequential file (output, listing file name) ;
+  max line length (listing file, 130)
+
+ENDPROC run elan ;
+(*
+PROC out text (TEXT CONST text, INT CONST out type) :
+  INTERNAL 257 ; 
+  IF online
+    THEN out (text)
+  FI ;
+  IF out type = error message OR (warning option AND out type = warning message) 
+    THEN note (text) ; 
+  FI ;
+  IF listing enabled
+    THEN write (listing file, text)
+  FI
+ENDPROC out text ;
+
+PROC out line (INT CONST out type) :
+  INTERNAL 258 ; 
+  IF online
+    THEN out (""13""10"")
+  FI ;
+  IF out type = error message
+       OR (warning option AND out type = warning message)
+    THEN note line
+  ELIF listing enabled
+    THEN line (listing file)
+  FI
+ENDPROC out line ;
+*)
+PROC prot (TEXT CONST file name) :
+  list option := TRUE ;
+  listing file name := file name ;
+  listing enabled := TRUE
+ENDPROC prot ;
+ 
+PROC prot off :
+  list option := FALSE ;
+  listing enabled := FALSE
+ENDPROC prot off ;
+
+BOOL PROC prot :
+  list option
+ENDPROC prot ;
+ 
+PROC check on :
+  check option := TRUE
+ENDPROC check on ;
+ 
+PROC check off :
+  check option := FALSE
+ENDPROC check off ;
+ 
+BOOL PROC check :
+  check option
+ENDPROC check ;
+
+PROC warnings on :                    
+  warning option := TRUE    
+ENDPROC warnings on ;    
+ 
+PROC warnings off : 
+  warning option := FALSE 
+ENDPROC warnings off ; 
+ 
+BOOL PROC warnings : 
+  warning option 
+ENDPROC warnings ; 
+
+ENDPACKET eumel coder ;  
+
+PACKET dint2 DEFINES dint type :
+ 
+INT VAR dummy ;
+DTYPE VAR d ;
+identify ("DINT", dummy, dummy, d) ; 
+ 
+DTYPE CONST dint type := d
+
+ENDPACKET dint2 ;
+
diff --git a/basic/eumel0 codes b/basic/eumel0 codes
new file mode 100644
index 0000000..226014c
Binary files /dev/null and b/basic/eumel0 codes differ
diff --git a/basic/gen.BASIC b/basic/gen.BASIC
new file mode 100644
index 0000000..9690ae6
--- /dev/null
+++ b/basic/gen.BASIC
@@ -0,0 +1,80 @@
+(**************************************************************************)
+(*                                                                        *)
+(*     Generatorprogramm zur Installation des EUMEL-BASIC-Systems         *)
+(*                                                                        *)
+(*     Autor: Heiko Indenbirken                                           *)
+(*     Überarbeitet von: Michael Overdick                                 *)
+(*                                                                        *)
+(*     Stand: 27.08.1987                                                  *)
+(*                                                                        *)
+(**************************************************************************)
+
+LET coder name = "eumel coder 1.8.1";
+
+show headline;
+from archive ("BASIC.1", (coder name & "eumel0 codes") - all);
+from archive ("BASIC.2",
+       ("BASIC.Runtime" & "BASIC.Administration" & "BASIC.Compiler") - all);
+set status;
+insert ("eumel coder 1.8.1");
+insert ("BASIC.Runtime");
+insert ("BASIC.Administration");
+insert ("BASIC.Compiler");
+forget (coder name & "BASIC.Runtime"
+               & "BASIC.Administration" & "BASIC.Compiler" & "gen.BASIC");
+restore status;
+show end .
+
+show headline:
+  page;
+  putline ("                 "15"Einrichten des EUMEL-BASIC-Systems "14"");
+  line  .
+
+set status:
+  BOOL VAR old check := check,
+           old warnings := warnings,
+           old command dialogue := command dialogue;
+  check off;
+  warnings off;
+  command dialogue (FALSE).
+
+restore status:
+  IF old check     THEN do ("check on") ELSE do ("check off") FI;
+  IF old warnings  THEN warnings on                           FI;
+  command dialogue (old command dialogue).
+
+show end:
+  line (2);
+  putline ("                      "15"BASIC-System installiert "14"");
+  line  .
+ 
+PROC from archive (TEXT CONST name, THESAURUS CONST files):
+  IF highest entry (files) > 0
+  THEN ask for archive;
+       archive (name);
+       fetch (files, archive);
+       release (archive);
+       putline ("Archiv abgemeldet !")
+  FI  .
+
+ask for archive:
+  line;
+  IF no ("Archiv """ + name + """ eingelegt")
+  THEN errorstop ("Archive nicht bereit") FI  .
+
+END PROC from archive;
+
+THESAURUS OP & (TEXT CONST left, right):
+  THESAURUS VAR result := empty thesaurus;
+  insert (result, left);
+  insert (result, right);
+  result
+END OP &;
+
+THESAURUS OP & (THESAURUS CONST left, TEXT CONST right):
+  THESAURUS VAR result := left;
+  insert (result, right);
+  result
+END OP &;
+
+
diff --git a/datatype/complex b/datatype/complex
new file mode 100644
index 0000000..e2139d0
--- /dev/null
+++ b/datatype/complex
@@ -0,0 +1,115 @@
+ 
+PACKET complex DEFINES COMPLEX,:=,complex zero,complex one,complex i, 
+                       complex,realpart,imagpart,CONJ,+,-,*,/,=,<>, 
+                       put,get, ABS, sqrt, phi, dphi :
+ 
+TYPE COMPLEX = STRUCT(REAL re,im); 
+COMPLEX PROC complex zero: COMPLEX :(0.0,0.0). END PROC complex zero; 
+COMPLEX PROC complex one : COMPLEX :(1.0,0.0). END PROC complex one; 
+COMPLEX PROC complex i   : COMPLEX :(0.0,1.0). END PROC complex i; 
+ 
+OP := (COMPLEX VAR dest, COMPLEX CONST source) :
+ 
+  CONCR (dest) := CONCR (source)
+ 
+ENDOP := ;
+ 
+COMPLEX PROC complex(REAL CONST re,im): 
+   COMPLEX :(re,im). 
+END PROC complex; 
+ 
+REAL PROC realpart(COMPLEX CONST number): 
+           number.re. 
+END PROC realpart; 
+ 
+REAL PROC imagpart(COMPLEX CONST number): 
+           number.im. 
+END PROC imagpart ;
+ 
+COMPLEX OP CONJ(COMPLEX CONST number): 
+   COMPLEX :( number.re,- number.im). 
+END OP CONJ; 
+ 
+BOOL OP =(COMPLEX CONST a,b): 
+   IF   a.re=b.re 
+   THEN a.im=b.im 
+   ELSE FALSE 
+   FI. 
+END OP =; 
+ 
+BOOL OP <>(COMPLEX CONST a,b): 
+   IF   a.re=b.re 
+   THEN a.im<>b.im 
+   ELSE TRUE 
+   FI. 
+END OP <>; 
+ 
+COMPLEX OP +(COMPLEX CONST a,b): 
+   COMPLEX :(a.re+b.re,a.im+b.im). 
+END OP +; 
+ 
+COMPLEX OP -(COMPLEX CONST a,b): 
+   COMPLEX :(a.re-b.re,a.im-b.im). 
+END OP -; 
+ 
+COMPLEX OP *(COMPLEX CONST a,b): 
+   REAL VAR re of a::a.re,im of a ::a.im, 
+            re of b::b.re,im of b ::b.im; 
+   COMPLEX :(re of a*re of b- im of a *im of b, 
+             re of a*im of b+ im of a*re of b). 
+END OP *; 
+ 
+COMPLEX OP /(COMPLEX CONST a,b): 
+   REAL VAR re of a::a.re,im of a::a.im, 
+            re of b::b.re,im of b::b.im; 
+   REAL VAR sqare sum of re and im ::b.re*b.re+b.im*b.im; 
+   COMPLEX :( (re of a * re of b + im of a * im of b)/sqare sum of re and im,
+              (im of a *re of b - re of a*im of b)/sqare sum of re and im). 
+END OP /; 
+ 
+PROC get(COMPLEX VAR a): 
+   REAL VAR realpart,imagpart; 
+   get(realpart);get(imagpart); 
+   a:= COMPLEX :(realpart,imagpart); 
+END PROC get; 
+ 
+PROC put(COMPLEX CONST a): 
+   put(a.re);put(" ");put(a.im); 
+END PROC put; 
+ 
+REAL PROC dphi(COMPLEX CONST x): 
+ IF   imagpart(x)=0.0 THEN reell
+ ELIF realpart(x)=0.0 THEN imag 
+ ELIF realpart(x)>0.0 THEN realpositiv 
+ ELSE realnegativ 
+ FI. 
+reell: IF sign(realpart(x)) < 0 THEN 180.0 ELSE 0.0 FI. 
+imag: IF imagpart(x)>0.0 THEN 90.0 ELSE 270.0 FI. 
+realpositiv:IF imagpart(x)>0.0 THEN arctand(realpart(x)/imagpart(x)) 
+                               ELSE
+arctand(realpart(x)/imagpart(x))+360.0 FI. 
+realnegativ: arctand(realpart(x)/imagpart(x))+180.0. 
+END PROC dphi; 
+ 
+REAL PROC phi(COMPLEX CONST x): 
+dphi(x)*3.141592653689793/180.0. 
+END PROC phi; 
+ 
+COMPLEX PROC sqrt(COMPLEX CONST x): 
+IF x=complex zero THEN x 
+ELIF realpart(x)<0.0 THEN 
+complex(imagpart(x)/(2.0*real(sign(imagpart(x)))
+        *sqrt((ABSx-realpart(x))/2.0)), 
+        real(sign(imagpart(x)))*sqrt((ABS x-realpart(x))/2.0)) 
+ELSE complex(sqrt((ABS x+realpart(x))/2.0), 
+     imagpart(x)/(2.0*sqrt((ABS x+realpart(x))/2.0)))
+FI. 
+ 
+END PROC sqrt; 
+ 
+REAL OP ABS(COMPLEX CONST x): 
+ sqrt(realpart(x)*realpart(x)+imagpart(x)*imagpart(x)). 
+END OP ABS; 
+ 
+END PACKET complex; 
+
diff --git a/datatype/longint b/datatype/longint
new file mode 100644
index 0000000..e78bb52
--- /dev/null
+++ b/datatype/longint
@@ -0,0 +1,423 @@
+PACKET longint    DEFINES LONGINT,        (* Autoren: S.Baumann,A.Bentrup *)
+                          :=,             (*          T.Sillke *)
+                          <,              (* Stand:   17.03.81 *)
+                          >, 
+                          <=,
+                          >=,
+                          <>,
+                          =,
+                          -,
+                          +,
+                          *,
+                          **,
+                          ABS,
+                          abs,
+                          DECR,
+                          DIV,
+                          get,
+                          INCR,
+                          int,
+                        (*last rest,*)
+                          longint,
+                          max,
+                          max longint,
+                          min,
+                          MOD,
+                          put,
+                          random,
+                          SIGN,
+                          sign,
+                          text,
+                          zero:
+ 
+TYPE LONGINT = TEXT;
+ 
+LONGINT VAR   result,aleft,aright;
+TEXT    VAR   ergebnis,x,y,z,h;
+INT     VAR   v byte,slr,sll;
+INT     CONST snull    :: code("0"), mtl :: 300 ;
+TEXT    CONST negativ  :: code(127),max digit :: code(99),null :: code(0),
+              overflow :: "LONGINT overflow",eins :: code(1); 
+BOOL    VAR   vorl,vorr,vleft,vright;
+
+OP := (LONGINT VAR left, LONGINT CONST right) :
+   CONCR(left) := CONCR(right)
+END OP :=;
+ 
+BOOL OP <  (LONGINT CONST left,right) :
+   slr := sign(right)*length(right);
+   sll := sign(left )*length(left );
+   IF slr <> sll THEN
+      IF slr > sll THEN TRUE ELSE FALSE FI
+   ELSE IF slr>0
+        THEN CONCR(left) < CONCR(right)
+        ELSE CONCR(left) > CONCR(right) FI
+   FI
+END  OP < ;
+ 
+BOOL OP >  (LONGINT CONST left,right) :
+   slr := sign(right)*length(right);
+   sll := sign(left )*length(left );
+   IF slr <> sll THEN
+      IF slr < sll THEN TRUE ELSE FALSE FI
+   ELSE IF slr>0
+        THEN CONCR(left) > CONCR(right)
+        ELSE CONCR(left) < CONCR(right) FI
+   FI
+END  OP > ;
+ 
+BOOL OP <= (LONGINT CONST left,right) :
+   NOT (left > right)
+END  OP <=;
+ 
+BOOL OP >= (LONGINT CONST left,right) :
+   NOT (left < right)
+END  OP >=;
+ 
+BOOL OP <> (LONGINT CONST left,right) :
+   CONCR (left) <> CONCR (right)
+END OP  <>;
+ 
+BOOL OP =  (LONGINT CONST left,right) :
+   CONCR (left) =  CONCR (right)
+END  OP = ;
+ 
+LONGINT OP - (LONGINT CONST arg) : 
+   SELECT  code(CONCR(arg)SUB1)  OF
+     CASE 0  : zero
+     CASE 127: LONGINT : (subtext(CONCR(arg),2))
+     OTHERWISE LONGINT : (negativ + CONCR(arg))
+   END SELECT
+END OP -;
+ 
+LONGINT OP + (LONGINT CONST arg) :   arg  END OP +;
+ 
+LONGINT OP - (LONGINT CONST left,right) :
+   IF   CONCR(left ) = null       THEN LEAVE - WITH -right
+   ELIF CONCR(right) = null       THEN LEAVE - WITH   left
+   ELIF sign(left) <> sign(right) THEN LEAVE - WITH left + (-right) FI;
+   betrag(left,right);
+   BOOL CONST betrag max :: aleft > aright;
+   IF   betrag max
+        THEN result := LONGINT : (CONCR(aleft ) SUB CONCR(aright))
+        ELSE result := LONGINT : (CONCR(aright) SUB CONCR(aleft )) FI;
+        kuerze fuehrende nullen(CONCR(result),null);
+   IF   vleft  XOR  betrag max  THEN -result ELSE result FI
+END OP -;
+ 
+LONGINT OP + (LONGINT CONST left,right) :
+   IF   sign(left) <> sign(right) THEN LEAVE + WITH left - (-right) FI;
+   betrag(left,right);
+   IF aleft > aright
+      THEN result := LONGINT : (CONCR(aleft ) ADD CONCR(aright))
+      ELSE result := LONGINT : (CONCR(aright) ADD CONCR(aleft )) FI;
+   IF vleft THEN result ELSE -result FI
+END OP +;
+ 
+LONGINT OP * (LONGINT CONST left,right) :
+   IF   CONCR(left) = null OR CONCR(right) = null THEN LEAVE * WITH zero
+   ELIF length(left) + length(right) > mtl THEN errorstop (overflow) FI;
+   betrag(left,right);
+   IF   aleft < aright 
+        THEN result := LONGINT : (CONCR(aright) MUL CONCR(aleft ))
+        ELSE result := LONGINT : (CONCR(aleft ) MUL CONCR(aright))  FI;
+   IF   length(CONCR(result)) = mtl  THEN errorstop(overflow) FI;
+   IF   vleft XOR vright THEN -result ELSE result FI
+END OP *;
+ 
+LONGINT OP ** (LONGINT CONST arg,exp) :
+   IF exp > longint(max int) THEN errorstop (overflow) FI;
+   arg ** int(exp)
+END OP **;
+ 
+LONGINT OP ** (LONGINT CONST arg,INT CONST exp) :
+   IF   exp < 0 THEN errorstop ("LONGINT OP ** : negativ exp")
+   ELIF CONCR(arg)=null AND exp=0 THEN errorstop(text(0 ** 0)) FI;
+   IF   exp = 0  THEN one
+   ELIF exp = 1  THEN arg
+   ELIF sign(arg) = -1 AND exp MOD 2 <> 0
+        THEN -LONGINT:(CONCR(abs(arg))EXPexp) 
+        ELSE  LONGINT:(CONCR(abs(arg))EXPexp) FI
+END OP **; 
+ 
+LONGINT OP ABS (LONGINT CONST arg) : abs(arg) END OP ABS;
+ 
+LONGINT PROC abs (LONGINT CONST a) : 
+ IF (CONCR(a)SUB1)=negativ THEN LONGINT:(subtext(CONCR(a),2)) ELSE a FI
+END PROC abs;
+ 
+OP DECR (LONGINT VAR result,LONGINT CONST ab) :
+   result := result - ab;
+END OP DECR;
+ 
+LONGINT OP DIV (LONGINT CONST left,right) :
+   IF CONCR(right) = null THEN error stop("LONGINT OP DIV by zero") FI;
+   betrag(left,right);        h    := CONCR(aright);
+   y := null + CONCR(aleft ); vorl := vleft;
+   z := null + CONCR(aright); vorr := vright;
+   IF aleft < aright THEN y:=CONCR(aleft); LEAVE DIV WITH zero FI;
+   INT  VAR try,i,cr1 :: code(z SUB 2),cr2,cr3,zw;
+   BOOL VAR sh :: length(z) <> 2;
+   IF sh THEN cr3:=code(zSUB3); cr2:=10*cr1+cr3DIV10; cr3:=100*cr1+cr3 FI;
+   CONCR(result) := "";
+   FOR i FROM 0 UPTO length(y)-length(z) REP
+      laufe eine abschaetzung durch; 
+      CONCR (result) CAT code(try)
+   PER;  kuerze fuehrende nullen(y,null);
+   IF(CONCR(result)SUB1)=nullTHEN CONCR(result):=subtext(CONCR(result),2)FI;
+   IF vleft XOR vright THEN -result ELSE result FI.
+ 
+   laufe eine abschaetzung durch :
+      zw := 100*code(y SUB i+1) + code(y SUB i+2);
+      IF zw < 3276 AND sh THEN IF zw < 327
+      THEN try := min((100*zw + code(ySUBi+3))     DIV cr3, 99)
+      ELSE try := min(( 10*zw + code(ySUBi+3)DIV10)DIV cr2, 99) FI
+      ELSE try := min(     zw                      DIV cr1, 99) FI;
+       x := z MUL code(try); 
+      WHILE x > subtext(y,i+1,i+length(x)) REP
+            try DECR 1;   x := x SUB z     PER;
+      replace(y,i + 1,subtext(y,i + 1,i + length(x)) SUB x) 
+END OP DIV;
+ 
+PROC get (LONGINT VAR result) : 
+   get (ergebnis);
+   result := longint(ergebnis);
+END PROC get;
+ 
+PROC get (FILE VAR file,LONGINT VAR result) :
+   get(file,ergebnis);
+   result := longint(ergebnis);
+END PROC get;
+ 
+OP INCR (LONGINT VAR result,LONGINT CONST dazu) : 
+   result := result + dazu;
+END OP INCR;
+ 
+INT PROC int (LONGINT CONST longint) :
+   IF length(longint) > 3 
+      THEN max int + 1
+      ELSE ergebnis := (3-length(longint))*null + CONCR(abs(longint));
+           (code(ergebnis SUB 1)  * 10000 +
+            code(ergebnis SUB 2)  * 100   +
+            code(ergebnis SUB 3)) * sign(longint)
+   FI
+END PROC int;
+ 
+LONGINT PROC longint (INT CONST int) :
+   CONCR(result) :=  code( abs(int)            DIV 10000) +
+                     code((abs(int) MOD 10000) DIV 100)   +
+                     code( abs(int) MOD 100);
+   kuerze fuehrende nullen (CONCR(result),null);
+   IF int < 1 THEN -result ELSE result FI
+END PROC longint;
+ 
+LONGINT PROC longint (TEXT CONST text) :
+   INT  VAR i;
+   ergebnis := compress(text);
+   BOOL VAR minus :: (ergebnisSUB1) = "-"; 
+   IF (ergebnisSUB1)="+" OR minus THEN ergebnis:=subtext(ergebnis,2) FI;
+   kuerze fuehrende nullen(ergebnis,"0");
+   kuerze die unzulaessigen zeichen aus ergebnis;
+   schreibe ergebnis im hundertersystem in result;
+   result mit vorzeichen.
+
+   kuerze die unzulaessigen zeichen aus ergebnis :
+      ergebnis := subtext(ergebnis,1,letztes zulaessiges zeichen).
+   letztes zulaessiges zeichen :
+      FOR i FROM 1 UPTO length(ergebnis) REP 
+      UNTIL pos("0123456789", ergebnis SUB i) = 0 PER;
+      i - 1.
+   schreibe ergebnis im hundertersystem in result :
+      sll := length(ergebnis);
+      IF sll MOD 2 <> 0 THEN ergebnis := "0"+ergebnis; sll INCR 1 FI; 
+      i := 1; CONCR(result) := "";
+      REP schreibe ein zeichen im hundertersystem in result;
+          i INCR 2
+      UNTIL i >= sll PER.
+   schreibe ein zeichen im hundertersystem in result :
+      CONCR(result) CAT code((code(ergebnis SUB i    ) - snull) * 10 +
+                              code(ergebnis SUB i + 1) - snull).
+   result mit vorzeichen : 
+      IF ergebnis="" THEN zero ELIF minus THEN -result ELSE result FI
+END PROC longint;
+ 
+LONGINT PROC max (LONGINT CONST left,right) :
+   IF left > right THEN left ELSE right FI
+END PROC max;
+ 
+LONGINT PROC max longint :
+   LONGINT : ((mtl - 1) * max digit)
+END PROC max longint;
+ 
+LONGINT PROC min (LONGINT CONST left,right) :
+   IF left < right THEN left ELSE right FI
+END PROC min;
+ 
+LONGINT OP MOD (LONGINT CONST left,right) :
+   IF CONCR(right) = null THEN errorstop("LONGINT OP MOD by zero") FI;
+   result := left DIV right; last rest 
+END OP MOD;
+ 
+PROC put (LONGINT CONST longint) :
+   INT  VAR i :: 1,zwei ziffern;
+   IF sign(longint) = -1 THEN out("-"); i:=2 FI;
+   out(text(code(CONCR(longint) SUB i)));
+   FOR i FROM i + 1 UPTO length(CONCR(longint)) REP
+       zwei ziffern := code(CONCR(longint) SUB i);
+       out(code(zwei ziffern DIV 10 + snull));
+       out(code(zwei ziffern MOD 10 + snull));
+   PER;out(" ")
+END PROC put;
+ 
+PROC put (FILE VAR file,LONGINT CONST longint) :
+   put(file,text(longint));
+END PROC put;
+ 
+LONGINT PROC random (LONGINT CONST lower bound,upper bound) :
+   INT VAR i; x := CONCR(upper bound - lower bound - one); y := "";
+   FOR i FROM 1 UPTO length(x) REP y CAT code(random(0,99)) PER;
+   upper bound - (LONGINT : (y) MOD LONGINT : (x)) 
+END PROC random;
+ 
+INT OP SIGN (LONGINT CONST arg) : sign(arg) END OP SIGN;
+ 
+INT PROC sign (LONGINT CONST arg) :
+   SELECT code(CONCR(arg) SUB 1) OF
+      CASE 0   :  0
+      CASE 127 : -1
+      OTHERWISE   1
+   END SELECT
+END PROC sign;
+ 
+TEXT PROC text (LONGINT CONST longint) :
+   INT  VAR i::1,zwei ziffern; ergebnis := "";
+   IF sign(longint) = -1 THEN ergebnis := "-"; i:=2  FI;
+   ergebnis CAT text (code (CONCR (longint) SUB i ) ) ;
+   FOR i FROM i+1 UPTO length(CONCR(longint)) REP
+      zwei ziffern := code(CONCR(longint) SUB i);
+      ergebnis CAT code(zwei ziffern DIV 10 + snull);
+      ergebnis CAT code(zwei ziffern MOD 10 + snull) 
+   PER;   ergebnis
+END PROC text;
+ 
+TEXT PROC text (LONGINT CONST longint,INT CONST length) :
+   x := text(longint); sll := LENGTH x;
+   IF sll > length THEN length * "*" ELSE (length - sll)*" " + x FI
+END PROC text; 
+
+LONGINT PROC last rest :
+  IF y=null THEN LEAVE last rest WITH zero FI; 
+  IF vorl XOR vorr THEN y := h SUB y; kuerze fuehrende nullen(y,null);
+                        vorl := TRUE FI;
+  IF NOTvorr THEN y:=negativ+y; vorr := TRUE FI; LONGINT:(y) 
+END PROC last rest;
+ 
+LONGINT PROC zero :   LONGINT : (null)   END PROC zero;
+LONGINT PROC one  :   LONGINT : (""1"")  END PROC one;
+ 
+ 
+(* ----------------------- INTERNE HILFSPROZEDUREN ----------------------- *)
+ 
+TEXT OP ADD (TEXT CONST left,right) :
+   INT  VAR   carrybit :: 0,i,dif :: length(left) - length(right);
+   ergebnis := left; 
+   FOR i FROM length(left) DOWNTO dif + 1 REP
+      replace(ergebnis,i,das result der addition)
+   PER;
+   IF carrybit = 1 THEN addiere den uebertrag  FI; 
+   ergebnis.
+ 
+   das result der addition :
+      v byte := (code(left SUB i) + code(right SUB i - dif) + carrybit);
+      IF v byte > 99 
+         THEN carrybit := 1; code(v byte - 100)
+         ELSE carrybit := 0; code(v byte)
+      FI. 
+   addiere den uebertrag :
+      FOR i FROM i DOWNTO 1
+          WHILE (ergebnis SUB i) >= max digit REP
+          replace(ergebnis,i,null) 
+      PER;
+      IF (ergebnis SUB 1) = null  OR  dif = 0
+         THEN pruefe auf longint overflow 
+         ELSE replace(ergebnis,i,code(code(ergebnis SUB i) + 1))
+      FI.
+   pruefe auf longint overflow :
+      IF length(ergebnis) = mtl - 1 THEN errorstop(overflow) FI;
+      ergebnis := eins + ergebnis
+END OP ADD;
+ 
+PROC betrag (LONGINT CONST a, b) :
+   vleft := (CONCR(a)SUB1)<>negativ; vright := (CONCR(b)SUB1)<>negativ;
+   IF vleft  THEN aleft :=a ELSE CONCR(aleft ):=subtext(CONCR(a),2) FI;
+   IF vright THEN aright:=b ELSE CONCR(aright):=subtext(CONCR(b),2) FI
+END PROC betrag;
+
+TEXT OP EXP (TEXT CONST arg,INT CONST exp) :
+   INT VAR zaehler :: exp;
+   x := arg; z := eins;
+   REP  IF zaehler MOD 2 = 1 THEN z := z MUL x FI; 
+        zaehler := zaehler DIV 2; x := x MUL x 
+   UNTIL zaehler = 1 PER;
+    x MUL z 
+END OP EXP;
+ 
+PROC kuerze fuehrende nullen ( TEXT VAR text,TEXT CONST snull) :
+   INT VAR i;
+   text := subtext(text,erste nicht snull).
+ 
+   erste nicht snull :
+   FOR i FROM 1 UPTO length (text) - 1 REP
+   UNTIL (text SUB i) <> snull PER;
+   i
+END PROC kuerze fuehrende nullen;
+ 
+INT PROC length (LONGINT CONST a) : 
+  IF (CONCR(a)SUB1)=negativ THEN length(CONCR(a))-1 ELSE length(CONCR(a)) FI
+END PROC length;
+ 
+TEXT OP MUL (TEXT CONST left,right) :
+   INT VAR i,j,carrybit,v,w;
+   ergebnis := (length(left) + length(right) - 1) * null;
+   FOR i FROM length(ergebnis) DOWNTO length(left) REP
+       v := i - length(left); w := length(right) - length(ergebnis) + i;
+       carrybit := 0;
+      FOR j FROM length(left) DOWNTO 1 REP
+            replace(ergebnis,v + j,result der addition)
+      PER;
+       replace(ergebnis,v,code(code(ergebnis SUB v) + carrybit));
+   PER;
+   IF carrybit = 0 THEN ergebnis ELSE code(carrybit) + ergebnis FI.
+
+   result der addition :
+      v byte := code(right    SUB w) * code(left SUB j) + carrybit +
+                code(ergebnis SUB v + j);
+      carrybit := v byte DIV 100;
+      code(v byte MOD 100)
+END OP MUL;
+ 
+TEXT OP SUB (TEXT CONST left,right) : 
+   INT  VAR   carrybit :: 0,i,dif :: length(left) - length(right);
+   ergebnis := left;
+   FOR i FROM length(left) DOWNTO dif + 1 REP 
+       replace(ergebnis,i,das result der subtraktion);
+   PER;
+   IF carrybit = 1 THEN subtrahiere den uebertrag FI;
+   ergebnis.
+ 
+   das result der subtraktion :
+      v byte := (code(left SUB i) - code(right SUB i - dif) - carrybit);
+      IF v byte < 0 
+         THEN carrybit := 1;code(v byte + 100)
+         ELSE carrybit := 0;code(v byte)
+      FI.
+   subtrahiere den uebertrag :
+      FOR i FROM i DOWNTO 2 
+          WHILE (ergebnis SUB i) = null REP
+          replace(ergebnis,i,max digit)
+      PER;
+      replace(ergebnis,i,code(code(ergebnis SUB i) - 1))
+END OP SUB;
+ 
+END PACKET longint;
+
diff --git a/datatype/matrix b/datatype/matrix
new file mode 100644
index 0000000..d9de9fb
--- /dev/null
+++ b/datatype/matrix
@@ -0,0 +1,482 @@
+PACKET matrix DEFINES MATRIX, matrix, idn,  (* Stand : 16.06.86 wk   *)
+                      :=, sub,              (* Autor : H.Indenbirken *)
+                      row, column,
+                      COLUMNS,
+                      ROWS,
+                      DET, 
+                      INV, 
+                      TRANSP, 
+                      transp,
+                      replace row, replace column,
+                      replace element,
+                      get, put,
+                      =, <>,
+                      +, -, * :
+
+TYPE MATRIX = STRUCT (INT rows, columns, VECTOR elems);
+TYPE INITMATRIX = STRUCT (INT rows, columns, REAL value, BOOL idn);
+
+MATRIX VAR a :: idn (1);
+INT VAR i;
+
+(****************************************************************************
+PROC dump (MATRIX CONST m) :
+  put line (text (m.rows) + " Reihen, " + text (m.columns) + " Spalten.");
+  dump (m.elems)  .
+
+END PROC dump;
+****************************************************************************)
+
+OP := (MATRIX VAR l, MATRIX CONST r) :
+  CONCR (l) := CONCR (r);
+END OP :=;
+
+OP := (MATRIX VAR l, INITMATRIX CONST r) :
+  l.rows    := r.rows;
+  l.columns := r.columns;
+  l.elems   := vector (r.rows*r.columns, r.value);
+  IF r.idn
+  THEN idn FI  .
+
+idn :
+  INT VAR i;
+  FOR i FROM 1 UPTO r.rows
+  REP replace (l.elems, calc pos (l.columns, i, i), 1.0) PER
+
+END OP :=;
+ 
+INITMATRIX PROC matrix (INT CONST rows, columns, REAL CONST value) :
+  IF rows <= 0
+  THEN errorstop ("PROC matrix : rows <= 0")
+  ELIF columns <= 0
+  THEN errorstop ("PROC matrix : columns <= 0") FI;
+
+  INITMATRIX : (rows, columns, value, FALSE)
+
+END PROC matrix;
+
+INITMATRIX PROC matrix (INT CONST rows, columns) :
+  matrix (rows, columns, 0.0)
+
+END PROC matrix;
+
+INITMATRIX PROC idn (INT CONST size) :
+  IF size <= 0
+  THEN errorstop ("MATRIX PROC idn : size <= 0") FI;
+
+  INITMATRIX : (size, size, 0.0, TRUE)
+
+END PROC idn;
+
+VECTOR PROC row (MATRIX CONST m, INT CONST i) :
+  VECTOR VAR v :: vector (m.columns);
+  INT VAR j, k :: 1, pos :: (i-1) * m.columns;
+  FOR j FROM pos+1 UPTO pos + m.columns
+  REP replace (v, k, m.elems SUB j);
+      k INCR 1
+  PER;
+  v
+
+END PROC row;
+
+VECTOR PROC column (MATRIX CONST m, INT CONST j) :
+  VECTOR VAR v :: vector (m.rows);
+  INT VAR i, k :: j;
+  FOR i FROM 1 UPTO m.rows
+  REP replace (v, i, m.elems SUB k);
+      k INCR m.columns
+  PER;
+  v
+
+END PROC column;
+
+INT OP COLUMNS (MATRIX CONST m) :
+  m.columns
+
+END OP COLUMNS;
+
+INT OP ROWS (MATRIX CONST m) :
+  m.rows
+
+END OP ROWS;
+
+REAL PROC sub (MATRIX CONST a, INT CONST row, column) :
+  a.elems SUB calc pos (a.columns, row, column)
+
+END PROC sub;
+
+PROC replace row (MATRIX VAR m, INT CONST rowindex, VECTOR CONST rowvalue) :
+  test ("PROC replace row : ", "LENGTH rowvalue", "COLUMNS m",
+        LENGTH rowvalue, m.columns);
+  test ("PROC replace row : row ", rowindex, m.rows);
+
+  INT VAR i, pos :: (rowindex-1) * m.columns;
+  FOR i FROM 1 UPTO m.columns
+  REP replace (m.elems, pos+i, rowvalue SUB i) PER
+
+END PROC replace row;
+
+PROC replace column (MATRIX VAR m, INT CONST columnindex,
+                     VECTOR CONST columnvalue) :
+  test ("PROC replace column : ", "LENGTH columnvalue", "ROWS m",
+        LENGTH columnvalue, m.rows);
+  test ("PROC replace column : column ", columnindex, m.columns);
+
+  INT VAR i;
+  FOR i FROM 1 UPTO m.rows
+  REP replace (m.elems, calc pos (m.columns, i, columnindex),
+               columnvalue SUB i) PER
+
+END PROC replace column;
+
+PROC replace element (MATRIX VAR a, INT CONST row, column, REAL CONST x) :
+  test ("PROC replace element : row ", row, a.rows);
+  test ("PROC replace element : column ", column, a.columns);
+  replace (a.elems, calc pos (a.columns, row, column), x)
+
+END PROC replace element;
+
+BOOL OP = (MATRIX CONST l, r) :
+  IF l.rows <> r.rows
+  THEN FALSE
+  ELIF l.columns <> r.columns
+  THEN FALSE
+  ELSE l.elems = r.elems FI
+
+END OP =;
+
+BOOL OP <> (MATRIX CONST l, r) :
+  IF l.rows <> r.rows
+  THEN TRUE
+  ELIF l.columns <> r.columns
+  THEN TRUE
+  ELSE l.elems <> r.elems FI
+
+END OP <>;
+
+INT PROC calc pos (INT CONST columns, z, s) :
+ (z-1) * columns + s
+END PROC calc pos;
+
+MATRIX OP + (MATRIX CONST m) :
+  m
+
+END OP +;
+
+MATRIX OP + (MATRIX CONST l, r) :
+  test ("MATRIX OP + : ", "ROWS l", "ROWS r", l.rows, r.rows);
+  test ("MATRIX OP + : ", "COLUMNS l", "COLUMNS r", l.columns, r.columns);
+
+  a := l;
+  INT VAR i;
+  FOR i FROM 1 UPTO l.rows * l.columns
+  REP replace (a.elems, i, (l.elems SUB i) + (r.elems SUB i))
+  PER;
+  a
+
+END OP +;
+
+MATRIX OP - (MATRIX CONST m) :
+  a := m;
+  INT VAR i;
+  FOR i FROM 1 UPTO m.rows * m.columns
+  REP replace (a.elems, i, -a.elems SUB i)
+  PER;
+  a
+
+END OP -;
+
+MATRIX OP - (MATRIX CONST l, r) :
+  test ("MATRIX OP - : ", "ROWS l", "ROWS r", l.rows, r.rows);
+  test ("MATRIX OP - : ", "COLUMNS l", "COLUMNS r", l.columns, r.columns);
+
+  a := l;
+  INT VAR i;
+  FOR i FROM 1 UPTO l.rows * l.columns
+  REP replace (a.elems, i, (l.elems SUB i) - (r.elems SUB i))
+  PER;
+  a
+
+END OP -;
+
+MATRIX OP * (REAL CONST x, MATRIX CONST m) :
+ m*x
+
+END OP *;
+
+MATRIX OP * (MATRIX CONST m, REAL CONST x) :
+  a := m;
+  INT VAR i;
+  FOR i FROM 1 UPTO m.rows * m.columns
+  REP replace (a.elems, i, x*m.elems SUB i) PER;
+  a
+
+END OP *;
+
+VECTOR OP * (VECTOR CONST v, MATRIX CONST m) :
+  test ("VECTOR OP * : ", "LENGTH v", "ROWS m", LENGTH v, m.rows);
+  VECTOR VAR result :: vector (m.columns);                       (*wk*)
+  INT VAR i;
+  FOR i FROM 1 UPTO m.columns
+  REP replace (result, i, v * column (m, i)) PER;
+  result  .
+
+END OP *;
+
+VECTOR OP * (MATRIX CONST m, VECTOR CONST v) :
+  test ("VECTOR OP * : ", "COLUMNS m", "LENGTH v", COLUMNS m, LENGTH v);
+  VECTOR VAR result :: vector (m.rows);                          (*wk*)
+  INT VAR i;
+  FOR i FROM 1 UPTO m.rows 
+  REP replace (result, i, row (m, i) * v) PER;
+  result  .
+
+END OP *;
+
+MATRIX OP * (MATRIX CONST l, r) :
+  test ("MATRIX OP * : ","COLUMNS l","ROWS r", l.columns, r.rows);
+
+  a.rows := l.rows;
+  a.columns := r.columns;
+  a.elems := vector (a.rows*a.columns)
+  INT VAR i, j;
+  FOR i FROM 1 UPTO a.rows
+  REP FOR j FROM 1 UPTO a.columns
+      REP VECTOR VAR rl :: row (l, i), cr :: column (r, j);
+          replace (a.elems, calc pos (a.columns, i, j), rl * cr)
+      PER
+  PER;
+  a  .
+
+END OP *;
+
+PROC get (MATRIX VAR a, INT CONST rows, columns) :
+ 
+  a := matrix (rows,columns);
+  INT VAR i, j;
+  VECTOR VAR v;
+  FOR i FROM 1 UPTO rows
+  REP get (v, columns);
+      store row
+  PER  .
+
+store row :
+  FOR j FROM 1 UPTO a.columns
+  REP replace (a.elems, calc pos (a.columns, i, j), v SUB j)
+  PER  .
+
+END PROC get;
+
+PROC put (MATRIX CONST a, INT CONST length, fracs) :
+  INT VAR i, j;
+  FOR i FROM 1 UPTO a.rows
+  REP FOR j FROM 1 UPTO a.columns
+      REP put (text (sub (a, i, j), length, fracs)) PER;
+      line (2);
+  PER
+
+END PROC put;
+
+PROC put (MATRIX CONST a) :
+  INT VAR i, j;
+  FOR i FROM 1 UPTO a.rows
+  REP FOR j FROM 1 UPTO a.columns
+      REP TEXT CONST number :: "                 " + text (sub (a, i, j));
+          put (subtext (number, LENGTH number - 15))
+      PER;
+      line (2);
+  PER
+
+END PROC put;
+
+TEXT VAR error :: "";
+PROC test (TEXT CONST proc, l text, r text, INT CONST left, right) :
+  IF left <> right
+  THEN error := proc;
+       error CAT l text;
+       error CAT " (";
+       error CAT text (left);
+       error CAT ") <> ";
+       error CAT r text;
+       error CAT " (";
+       error CAT text (right);
+       error CAT ")";
+       errorstop (error)
+  FI  .
+
+END PROC test;
+
+PROC test (TEXT CONST proc, INT CONST i, n) :
+  IF i < 1
+  THEN error := proc;
+       error CAT "subscript underflow (";
+       error CAT text (i);
+       error CAT ")";
+       errorstop (error)
+  ELIF i > n
+  THEN error := proc;
+       error CAT "subscript overflow (i=";
+       error CAT text (i);
+       error CAT ", max=";
+       IF n <= 0
+       THEN error CAT "undefined"
+       ELSE error CAT text (n) FI;
+       error CAT ")";
+       errorstop (error)
+  FI
+
+END PROC test;
+
+
+MATRIX OP TRANSP (MATRIX CONST m) :
+  MATRIX VAR a :: m;
+  transp (a);
+  a
+
+END OP TRANSP;
+
+PROC transp (MATRIX VAR m) :
+  INT VAR k :: 1, n :: m.rows*m.columns;
+  a := m;
+  FOR i FROM 2 UPTO n
+  REP replace (m.elems, i, a.elems SUB position) PER;
+  a := idn (1);
+  i := m.rows;
+  m.rows := m.columns;
+  m.columns := i  .
+
+position :
+  k INCR m.columns;
+  IF k > n
+  THEN k DECR (n-1) FI;
+  k  .
+END PROC transp;
+
+MATRIX OP INV (MATRIX CONST m) :
+  a := m;
+  ROW 32 INT VAR pivots;
+  INT VAR i, j, k :: ROWS a, n :: COLUMNS a, pos;
+
+  IF n <> k
+  THEN errorstop ("MATRIX OP INV : no square matrix") FI;
+
+  initialisiere die pivotpositionen;
+
+  FOR j FROM 1 UPTO n
+  REP pivotsuche (a, j, pos);
+      IF sub (a, pos, pos) = 0.0
+      THEN errorstop ("MATRIX OP INV : singular matrix") FI;
+      zeilentausch (a, j, pos);
+      merke dir die vertauschung;
+      transformiere die matrix
+  PER;
+
+  spaltentausch;
+  a  .
+
+initialisiere die pivotpositionen :
+  FOR i FROM 1 UPTO n
+  REP pivots [i] := i PER  .
+
+merke dir die vertauschung :
+  IF pos > j
+  THEN INT VAR hi :: pivots [j];
+       pivots [j] := pivots [pos];
+       pivots [pos] := hi
+  FI  .
+
+transformiere die matrix :
+  REAL VAR h := 1.0/sub (a, j, j);
+
+  FOR k FROM 1 UPTO n
+  REP IF k <> j
+      THEN FOR i FROM 1 UPTO n
+           REP IF i <> j
+               THEN replace element (a, i, k, sub (a, i, k) -
+                                     sub (a, i, j)*sub (a, j, k)*h);
+               FI
+           PER;
+       FI
+  PER;
+
+  FOR k FROM 1 UPTO n
+  REP replace element (a, j, k, -h*sub (a, j, k));
+      replace element (a, k, j,  h*sub (a, k, j))
+  PER;
+  replace element (a, j, j, h)  .
+
+spaltentausch :
+  VECTOR VAR v :: vector (n);
+  FOR i FROM 1 UPTO n
+  REP FOR k FROM 1 UPTO n
+      REP replace (v, pivots [k], sub(a, i, k)) PER; 
+      replace row (a, i, v) 
+  PER  .
+
+END OP INV;
+
+REAL OP DET (MATRIX CONST m) :
+  IF COLUMNS m <> ROWS m
+  THEN errorstop ("REAL OP DET : no square matrix") FI;
+
+  a := m;
+  INT VAR i, j, k, n :: COLUMNS m, pos;
+  REAL VAR merker := 1.0; 
+  FOR j FROM 1 UPTO n
+  REP pivotsuche (a, j, pos);
+      IF j<> pos 
+        THEN zeilentausch (a, j, pos);
+             zeilen tausch merken 
+      FI; 
+      transformiere die matrix
+  PER;
+  produkt der pivotelemente  .
+
+transformiere die matrix : 
+  REAL VAR hp := sub(a,j,j); 
+  IF hp = 0.0 
+    THEN LEAVE DET WITH 0.0 
+    ELSE REAL VAR h := 1.0/hp;
+  FI;
+  FOR i FROM j+1 UPTO n
+  REP FOR k FROM j+1 UPTO n
+      REP replace element (a, i, k, sub (a, i, k) -
+                           sub (a, i, j)*h*sub (a, j, k))
+      PER
+  PER  .
+
+produkt der pivotelemente :
+  REAL VAR produkt :: sub (a, 1, 1);
+  FOR j FROM 2 UPTO n
+  REP produkt := produkt * sub (a, j, j) PER;
+  a := idn (1);
+  produkt * merker.
+
+zeilen tausch merken: 
+  merker := merker * (-1.0). 
+ 
+END OP DET;
+
+PROC pivotsuche (MATRIX CONST a, INT CONST start pos, INT VAR pos) :
+  REAL VAR max :: abs (sub (a, start pos, start pos));
+  INT VAR i;
+  pos := start pos;
+
+  FOR i FROM start pos+1 UPTO COLUMNS a
+  REP IF abs (sub (a, i, start pos)) > max
+      THEN max := abs (sub (a, i, start pos));
+           pos := i
+      FI
+  PER  .
+
+END PROC pivotsuche;
+
+PROC zeilentausch (MATRIX VAR a, INT CONST old pos, pos) :
+  VECTOR VAR v := row (a, pos);
+  replace row (a, pos, row (a, old pos));
+  replace row (a, old pos, v)  .
+
+END PROC zeilentausch;
+
+END PACKET matrix;
+
diff --git a/datatype/vector b/datatype/vector
new file mode 100644
index 0000000..5c9e896
--- /dev/null
+++ b/datatype/vector
@@ -0,0 +1,213 @@
+PACKET vector DEFINES VECTOR, :=, vector,         (* Autor : H.Indenbirken *)
+                      SUB, LENGTH, length, norm,  (* Stand : 21.10.83      *)
+                      nilvector, replace, =, <>,
+                      +, -, *, /,
+                      get, put :
+
+
+TYPE VECTOR = STRUCT (INT lng, TEXT elem);
+TYPE INITVECTOR = STRUCT (INT lng, REAL value);
+
+INT VAR i;
+TEXT VAR t :: "12345678";
+VECTOR VAR v :: nilvector;
+
+(****************************************************************************
+PROC dump (VECTOR CONST v) :
+  put line (text (v.lng) + " Elemente :");
+  FOR i FROM 1 UPTO v.lng
+  REP put line (text (i) + ": " + text (element i)) PER  .
+
+element i :
+  v.elem RSUB i  .
+
+END PROC dump;
+****************************************************************************)
+
+OP := (VECTOR VAR l, VECTOR CONST r) :
+  l.lng := r.lng;
+  l.elem := r.elem
+
+END OP :=;
+
+OP := (VECTOR VAR l, INITVECTOR CONST r) :
+  l.lng := r.lng;
+  replace (t, 1, r.value);
+  l.elem := r.lng * t
+
+END OP :=;
+
+INITVECTOR PROC nilvector :
+   vector (1, 0.0)
+
+END PROC nilvector;
+
+INITVECTOR PROC vector (INT CONST lng, REAL CONST value) :
+  IF lng <= 0
+  THEN errorstop ("PROC vector : lng <= 0") FI;
+  INITVECTOR : (lng, value)
+
+END PROC vector;
+
+INITVECTOR PROC vector (INT CONST lng) :
+  vector (lng, 0.0)
+
+END PROC vector;
+
+REAL OP SUB (VECTOR CONST v, INT CONST i) :
+  test ("REAL OP SUB : ", v, i);
+  v.elem RSUB i
+
+END OP SUB;
+
+INT OP LENGTH (VECTOR CONST v) :
+  v.lng
+
+END OP LENGTH;
+
+INT PROC length (VECTOR CONST v) :
+  v.lng
+
+END PROC length;
+
+REAL PROC norm (VECTOR CONST v) :
+  REAL VAR result :: 0.0;
+  FOR i FROM 1 UPTO v.lng
+  REP result INCR ((v.elem RSUB i)**2) PER;
+  sqrt (result)  .
+
+END PROC norm;
+
+PROC replace (VECTOR VAR v, INT CONST i, REAL CONST r) :
+  test ("PROC replace : ", v, i);
+  replace (v.elem, i, r)
+
+END PROC replace;
+
+BOOL OP = (VECTOR CONST l, r) :
+  l.elem = r.elem
+END OP =;
+
+BOOL OP <> (VECTOR CONST l, r) :
+  l.elem <> r.elem
+END OP <>;
+
+VECTOR OP + (VECTOR CONST v) :
+  v
+END OP +;
+
+VECTOR OP + (VECTOR CONST l, r) :
+  test ("VECTOR OP + : ", l, r);
+  v := l;
+  FOR i FROM 1 UPTO v.lng
+  REP replace (v.elem, i, (l.elem RSUB i) + (r.elem RSUB i)) PER;
+  v
+
+END OP +;
+
+VECTOR OP - (VECTOR CONST a) :
+  v := a;
+  FOR i FROM 1 UPTO v.lng
+  REP replace (v.elem, i, - (a.elem RSUB i)) PER;
+  v
+
+END OP -;
+
+VECTOR OP - (VECTOR CONST l, r) :
+  test ("VECTOR OP - : ", l, r);
+  v := l;
+  FOR i FROM 1 UPTO v.lng
+  REP replace (v.elem, i, (l.elem RSUB i) - (r.elem RSUB i)) PER;
+  v
+END OP -;
+
+REAL OP * (VECTOR CONST l, r) :
+  test ("REAL OP * : ", l, r);
+  REAL VAR x :: 0.0;
+  FOR i FROM 1 UPTO l.lng
+  REP x INCR ((l.elem RSUB i) * (r.elem RSUB i)) PER;
+  x
+
+END OP *;
+
+VECTOR OP * (VECTOR CONST v, REAL CONST r) :
+  r*v
+
+END OP *;
+
+VECTOR OP * (REAL CONST r, VECTOR CONST a) :
+  v := a;
+  FOR i FROM 1 UPTO v.lng
+  REP replace (v.elem, i, r*(a.elem RSUB i)) PER;
+  v
+
+END OP *;
+
+VECTOR OP / (VECTOR CONST a, REAL CONST r) :
+  v := a;
+  FOR i FROM 1 UPTO v.lng
+  REP replace (v.elem, i, (a.elem RSUB i)/r) PER;
+  v
+
+END OP /;
+
+TEXT VAR error :: "";
+PROC test (TEXT CONST proc, VECTOR CONST v, INT CONST i) :
+  IF i > v.lng
+  THEN error := proc;
+       error CAT "subscript overflow (LENGTH v=";
+       error CAT text (v.lng);
+       error CAT ", i=";
+       error CAT text (i);
+       error CAT ")";
+       errorstop (error)
+  ELIF i < 1
+  THEN error := proc;
+       error CAT "subscript underflow (i = ";
+       error CAT text (i);
+       error CAT ")";
+       errorstop (error)
+  FI  .
+
+END PROC test;
+
+PROC test (TEXT CONST proc, VECTOR CONST a, b) :
+  IF a.lng <> b.lng
+  THEN error := proc;
+       error CAT "LENGTH a (";
+       IF a.lng <= 0
+       THEN error CAT "undefined"
+       ELSE error CAT text (a.lng) FI;
+       error CAT ") <> LENGTH b (";
+       error CAT text (b.lng);
+       error CAT ")";
+       errorstop (error)
+  FI
+
+END PROC test;
+
+PROC get (VECTOR VAR v, INT CONST lng) :
+  v.lng := lng;
+  v.elem := lng * "12345678";
+  REAL VAR x;
+  FOR i FROM 1 UPTO lng
+  REP get (x);
+      replace (v.elem, i, x)
+  PER  .
+
+END PROC get;
+
+PROC put (VECTOR CONST v, INT CONST length, fracs) :
+  FOR i FROM 1 UPTO v.lng
+  REP put (text (v.elem RSUB i, length, fracs)) PER
+
+END PROC put;
+
+PROC put (VECTOR CONST v) :
+  FOR i FROM 1 UPTO v.lng
+  REP put (text (v.elem RSUB i)) PER
+
+END PROC put;
+
+END PACKET vector;
+
diff --git a/dialog/ls-DIALOG 1 b/dialog/ls-DIALOG 1
new file mode 100644
index 0000000..974bcda
--- /dev/null
+++ b/dialog/ls-DIALOG 1	
@@ -0,0 +1,60 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                     ls-DIALOG 1                     ** 
+          **                                                     ** 
+          **                     Version 1.2                     ** 
+          **                                                     ** 
+          **                  (Stand: 04.11.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+PACKET ls dialog 1  DEFINES                  
+       ecke oben  links,  balken oben,{}       ecke oben  rechts, balken rechts,{}       ecke unten links,  balken links,{}       ecke unten rechts, balken unten,{}       waagerecht, senkrecht, kreuz,{}       cursor on, cursor off,{}       clear buffer, clear buffer and count,{}       center, invers, page, page up,{}       out frame, out menuframe, erase frame,{}       std graphic char, ft20 graphic char,{}       ibm graphic char, AREA, :=, fill,{}       areax, areay, areaxsize, areaysize,{}       cursor, get cursor, out, out invers,{}
+       out with beam, out invers with beam,{}       erase, erase invers, erase with beam:{}TYPE AREA = STRUCT (INT x, y, xsize, ysize);{}LET blank     =     " ",{}    mark ein  =  ""15"",{}    mark aus  =  ""14"",{}    cleol     =   ""5"";{}TEXT CONST fehlermeldung :: "Unzulässige Größen!";{}TEXT VAR eol  := "+", eor  := "+", eul  := "+", eur  := "+",{}         bo   := "+", br   := "+", bl   := "+", bu   := "+",{}         waa  := "-", sen  := "|", kr   := "+",{}         cursor sichtbar     :=  "", cursor unsichtbar   :=  "";{}
+TEXT PROC ecke oben  links : eol END PROC ecke oben  links  ;{}TEXT PROC ecke oben  rechts: eor END PROC ecke oben  rechts ;{}TEXT PROC ecke unten links : eul END PROC ecke unten links  ;{}TEXT PROC ecke unten rechts: eur END PROC ecke unten rechts ;{}TEXT PROC balken oben      : bo  END PROC balken oben       ;{}TEXT PROC balken links     : bl  END PROC balken links      ;{}TEXT PROC balken rechts    : br  END PROC balken rechts     ;{}TEXT PROC balken unten     : bu  END PROC balken unten      ;{}
+TEXT PROC waagerecht       : waa END PROC waagerecht        ;{}TEXT PROC senkrecht        : sen END PROC senkrecht         ;{}TEXT PROC kreuz            : kr  END PROC kreuz             ;{}PROC ecke oben  links  (TEXT CONST t): eol := t END PROC ecke oben  links  ;{}PROC ecke oben  rechts (TEXT CONST t): eor := t END PROC ecke oben  rechts ;{}PROC ecke unten links  (TEXT CONST t): eul := t END PROC ecke unten links  ;{}PROC ecke unten rechts (TEXT CONST t): eur := t END PROC ecke unten rechts ;{}
+PROC balken oben       (TEXT CONST t): bo  := t END PROC balken oben       ;{}PROC balken links      (TEXT CONST t): bl  := t END PROC balken links      ;{}PROC balken rechts     (TEXT CONST t): br  := t END PROC balken rechts     ;{}PROC balken unten      (TEXT CONST t): bu  := t END PROC balken unten      ;{}PROC waagerecht        (TEXT CONST t): waa := t END PROC waagerecht        ;{}PROC senkrecht         (TEXT CONST t): sen := t END PROC senkrecht         ;{}PROC kreuz             (TEXT CONST t): kr  := t END PROC kreuz             ;{}
+PROC std graphic char:{}  ecke oben  links  ("+"); ecke oben  rechts ("+");{}  ecke unten links  ("+"); ecke unten rechts ("+");{}  balken oben       ("+"); balken rechts     ("+");{}  balken links      ("+"); balken unten      ("+");{}  waagerecht        ("-"); senkrecht         ("|");{}  kreuz             ("+");{}  cursor sichtbar   := ""; cursor unsichtbar := ""{}END PROC std graphic char;{}PROC ft20 graphic char:{}  ecke oben  links (""27"R�"27"S"); ecke oben  rechts (""27"RD"27"S");{}  ecke unten links (""27"RH"27"S"); ecke unten rechts (""27"RL"27"S");{}
+  balken oben      (""27"RP"27"S"); balken rechts     (""27"RT"27"S");{}  balken links     (""27"RX"27"S"); balken unten      (""27"R\"27"S");{}  waagerecht       (""27"R`"27"S"); senkrecht         (""27"Rd"27"S");{}  kreuz            (""27"Rh"27"S");{}  cursor sichtbar  := ""27"-1"    ; cursor unsichtbar := ""27"-0"    ;{}  ft20 statuszeilen aus{}END PROC ft20 graphic char;{}PROC ft 20 statuszeilen aus: out (""27".A") END PROC ft 20 statuszeilen aus;{}PROC ft 20 statuszeilen an : out (""27".�") END PROC ft 20 statuszeilen an ;{}
+PROC ibm graphic char:{}  ecke oben  links (""201"");  ecke oben  rechts (""187"");{}  ecke unten links (""200"");  ecke unten rechts (""188"");{}  balken oben      (""203"");  balken rechts     (""185"");{}  balken links     (""204"");  balken unten      (""202"");{}  waagerecht       (""205"");  senkrecht         (""186"");{}  kreuz            (""206"");{}  cursor sichtbar  := ""    ;  cursor unsichtbar := ""{}END PROC ibm graphic char;{}PROC cursor on                : out (cursor sichtbar  ) END PROC cursor on ;{}
+PROC cursor off               : out (cursor unsichtbar) END PROC cursor off;{}PROC cursor on  (TEXT CONST t): cursor sichtbar   := t  END PROC cursor on ;{}PROC cursor off (TEXT CONST t): cursor unsichtbar := t  END PROC cursor off;{}PROC clear buffer:{}  REP UNTIL incharety = "" PER{}END PROC clear buffer;{}INT PROC clear buffer and count (TEXT CONST zeichen):{}  INT  VAR zaehler :: 0;{}  TEXT VAR zeichenkette :: "", ch;{}  IF zeichen = "" THEN clear buffer; LEAVE clear buffer and count WITH 0 FI;{}
+  ermittle die zeichenkette;{}  untersuche auf vorhandene zeichen;{}  zaehler.{}  ermittle die zeichenkette:{}    REP{}      ch := incharety (1);{}      zeichenkette CAT ch{}    UNTIL ch = "" PER.{}  untersuche auf vorhandene zeichen:{}    INT VAR i;{}    FOR i FROM 1 UPTO length (zeichenkette) REP{}      IF pos (subtext (zeichenkette, i), zeichen) = 1{}         THEN zaehler INCR 1{}      FI{}    PER.{}END PROC clear buffer and count;{}TEXT PROC center (INT CONST xsize, TEXT CONST t):{}  TEXT VAR zeile :: compress (t);{}
+  zeile := ((xsize  - length (zeile)) DIV 2) * blank + zeile;{}  zeile CAT (xsize - length (zeile)) * blank;{}  zeile{}END PROC center;{}TEXT PROC center (TEXT CONST t):{}  center (79, t){}END PROC center;{}TEXT PROC invers (TEXT CONST t):{}  TEXT VAR neu :: mark ein; neu CAT t; neu CAT " "; neu CAT mark aus;{}  neu{}END PROC invers;{}PROC page (INT CONST x, y, xsize, ysize):{}    INT VAR zeiger;{}    IF x + xsize = 80{}       THEN in einem streich{}       ELSE putze vorsichtig{}    FI;{}    cursor (x, y).{}
+    in einem streich:{}      FOR zeiger FROM y UPTO y + ysize - 1 REP{}        cursor (x, zeiger); out (cleol){}      PER.{}    putze vorsichtig:{}      FOR zeiger FROM y UPTO y + ysize - 1  REP{}        cursor (x, zeiger); xsize TIMESOUT blank{}      PER.{}END PROC page;{}PROC page (AREA CONST a):{}  page (a.x, a.y, a.xsize, a.ysize){}END PROC page;{}PROC page up (INT CONST x, y, xsize, ysize):{}    INT VAR zeiger;{}    IF x + xsize = 80{}       THEN in einem streich{}       ELSE putze vorsichtig{}
+    FI.{}    in einem streich:{}      FOR zeiger FROM y + ysize - 1 DOWNTO y REP{}        cursor (x, zeiger); out (cleol){}      PER.{}    putze vorsichtig:{}      FOR zeiger FROM y + ysize - 1  DOWNTO y REP{}        cursor (x, zeiger); xsize TIMESOUT blank{}      PER.{}END PROC page up;{}PROC page up (AREA CONST a):{}  page up (a.x, a.y, a.xsize, a.ysize){}END PROC page up;{}PROC out frame (INT CONST x, y, xsize, ysize):{}  INT VAR zeiger;{}  IF x < 1 COR y < 1 COR xsize < 8 COR ysize < 3 COR{}     x + xsize > 80  COR y + ysize > 25{}
+     THEN LEAVE out frame{}  FI;{}  male oben;{}  male seiten;{}  male unten.{}  male oben:{}    cursor (x, y);{}    out (ecke oben links);{}    (xsize - 2) TIMESOUT waagerecht;{}    out (ecke oben rechts).{}  male seiten:{}    FOR zeiger FROM 1 UPTO ysize - 2 REP{}      cursor (x,             y + zeiger); out (senkrecht);{}      cursor (x + xsize - 1, y + zeiger); out (senkrecht){}    PER.{}  male unten:{}    cursor (x, y + ysize - 1);{}    out (ecke unten links);{}    (xsize - 2) TIMESOUT waagerecht;{}
+    out (ecke unten rechts){}END PROC out frame;{}PROC out frame (AREA CONST a):{}  IF    a.x - 1     <  1  OR a.y - 1     <  1{}     OR a.xsize + 2 > 79 OR a.ysize + 2 > 24{}     OR a.x + a.xsize + 1 > 80{}     OR a.y + a.ysize + 1 > 25{}     THEN LEAVE out frame{}  FI;{}  out frame (a.x - 1, a.y - 1, a.xsize + 2, a.ysize + 2){}END PROC out frame;{}PROC out menuframe (INT CONST x, y, xsize, ysize):{}  INT VAR i;{}  untersuche angaben;{}  schreibe rahmen.{}  untersuche angaben:{}    IF x < 0 COR y < 0 COR x + xsize > 81 COR y + ysize > 26{}
+       THEN LEAVE out menuframe{}    FI.{}  schreibe rahmen:{}    IF x = 0 COR y = 0 COR xsize = 81 COR ysize = 26{}       THEN zeichne reduzierten rahmen{}       ELSE zeichne vollen rahmen{}    FI.{}  zeichne reduzierten rahmen:{}    zeichne oberlinie;{}    zeichne unterlinie.{}  zeichne oberlinie:{}    cursor (1, 2);{}    79 TIMESOUT waagerecht.{}  zeichne unterlinie:{}    cursor (1, 23);{}    79 TIMESOUT waagerecht.{}  zeichne vollen rahmen:{}    schreibe kopf; schreibe rumpf; schreibe fuss;{}
+    schreibe kopfleiste; schreibe fussleiste.{}  schreibe kopf:{}    cursor (x, y);{}    out (ecke oben links);{}    (xsize - 2) TIMESOUT waagerecht;{}    out (ecke oben rechts).{}  schreibe rumpf:{}    FOR i FROM y + 1 UPTO y + ysize - 2 REP{}      cursor (x,             i); out (senkrecht);{}      cursor (x + xsize - 1, i); out (senkrecht){}    PER.{}  schreibe fuss:{}    cursor (x, y + ysize - 1);{}    out (ecke unten links);{}    (xsize - 2) TIMESOUT waagerecht;{}    out (ecke unten rechts).{}
+  schreibe kopfleiste:{}    cursor (x, y + 2        ); schreibe balkenlinie.{}  schreibe fussleiste:{}    cursor (x, y + ysize - 3); schreibe balkenlinie.{}  schreibe balkenlinie:{}    out (balken links); (xsize - 2) TIMESOUT waagerecht; out (balken rechts).{}END PROC out menuframe;{}PROC out menuframe (AREA CONST a):{} out menuframe (a.x - 1, a.y - 1, a.xsize + 2, a.ysize + 2){}END PROC out menuframe;{}PROC erase frame (INT CONST x, y, xsize, ysize):{}  INT VAR zeiger;{}  loesche oben; loesche seiten; loesche unten.{}
+  loesche oben:{}    cursor (x, y); xsize TIMESOUT blank.{}  loesche seiten:{}    FOR zeiger FROM 1 UPTO ysize - 2 REP{}      cursor (x, y + zeiger); out (blank);{}      cursor (x + xsize - 1, y + zeiger); out (blank){}    PER.{}  loesche unten:{}    cursor (x, y + ysize - 1); xsize TIMESOUT blank.{}END PROC erase frame;{}OP := (AREA VAR ziel, AREA CONST quelle):{}  CONCR (ziel) := CONCR (quelle){}END OP :=;{}PROC fill (AREA VAR ziel, INT CONST a, b, c, d):{}  IF a < 1 COR b < 1 COR a > 79 COR b > 24 COR c < 8 COR d < 3{}
+     COR c > 79 COR d > 24 COR a + c > 80 COR b + d > 25{}     THEN errorstop (fehlermeldung){}  FI;{}  ziel.x := a; ziel.y := b; ziel.xsize := c; ziel.ysize := d{}END PROC fill;{}INT PROC areax     (AREA CONST a): a.x      END PROC areax;{}INT PROC areay     (AREA CONST a): a.y      END PROC areay;{}INT PROC areaxsize (AREA CONST a): a.xsize  END PROC areaxsize;{}INT PROC areaysize (AREA CONST a): a.ysize  END PROC areaysize;{}PROC out (TEXT CONST t, INT CONST breite):{}  outtext (t, 1, breite){}
+END PROC out;{}PROC erase (INT CONST breite):{}  breite TIMESOUT blank{}END PROC erase;{}PROC cursor (AREA CONST a, INT CONST spa, zei):{}  cursor (a.x + spa - 1, a.y + zei - 1){}END PROC cursor;{}PROC get cursor (AREA CONST a, INT VAR spalte, zeile):{}  INT VAR x, y;{}  get cursor (x, y);{}  spalte := x - a.x + 1; zeile  := y - a.y + 1{}END PROC get cursor;{}PROC out (AREA CONST a, INT CONST spa, zei, TEXT CONST t):{}  ueberpruefe cursorangaben; positioniere cursor;{}  IF text ist zu lang{}     THEN verkuerzte ausgabe{}
+     ELSE out (t){}  FI.{}  ueberpruefe cursorangaben:{}    IF spa > xsize COR zei > a.ysize COR spa < 1 COR zei < 1{}       THEN LEAVE out{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 1, a.y + zei - 1).{}  text ist zu lang:{}    length (t) > a.xsize - spa + 1.{}  verkuerzte ausgabe:{}    outsubtext (t, 1, a.xsize - spa + 1){}END PROC out;{}PROC out (AREA CONST a, INT CONST spa, zei, TEXT CONST t, INT CONST laenge):{}  ueberpruefe cursorangaben; positioniere cursor;{}  IF laenge ist zu gross{}
+     THEN verkuerzte ausgabe{}     ELSE outtext (t, 1, laenge){}  FI.{}  ueberpruefe cursorangaben:{}    IF spa > a.xsize COR zei > a.ysize COR spa < 1 COR zei < 1{}       THEN LEAVE out{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 1, a.y + zei - 1).{}  laenge ist zu gross:{}    laenge > a.xsize - spa + 1.{}  verkuerzte ausgabe:{}    outtext (t, 1, a.xsize - spa + 1){}END PROC out;{}PROC erase (AREA CONST a, INT CONST spa, zei, INT CONST laenge):{}  ueberpruefe cursorangaben; positioniere cursor;{}
+  IF laenge ist zu gross{}     THEN verkuerzte ausgabe{}     ELSE erase (laenge){}  FI.{}  ueberpruefe cursorangaben:{}    IF spa > a.xsize COR zei > a.ysize COR spa < 1 COR zei < 1{}       THEN LEAVE erase{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 1, a.y + zei - 1).{}  laenge ist zu gross:{}    laenge > a.xsize - spa + 1.{}  verkuerzte ausgabe:{}    erase (a.xsize - spa + 1){}END PROC erase;{}PROC out invers (AREA CONST a, INT CONST spa, zei, TEXT CONST t):{}  ueberpruefe cursorangaben; positioniere cursor;{}
+  IF text ist zu lang{}     THEN verkuerzte ausgabe{}     ELSE out (mark ein); out (t); out (blank); out (mark aus){}  FI.{}  ueberpruefe cursorangaben:{}    IF spa > (xsize - 4) COR zei > ysize COR spa < 2 COR zei < 1{}       THEN LEAVE out invers{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 2, a.y + zei - 1).{}  text ist zu lang:{}    length (t) > a.xsize - spa - 1.{}  verkuerzte ausgabe:{}    out (mark ein); outsubtext (t, 1, a.xsize - spa - 1);{}    out (blank); out (mark aus){}END PROC out invers;{}
+PROC out invers (AREA CONST a, INT CONST spa, zei,{}                 TEXT CONST t, INT CONST laenge):{}  ueberpruefe cursorangaben; positioniere cursor;{}  IF laenge ist zu gross{}     THEN verkuerzte ausgabe{}     ELSE out (mark ein); outtext (t, 1, laenge); out (blank); out (mark aus){}  FI.{}  ueberpruefe cursorangaben:{}    IF spa > (a.xsize - 4) COR zei > a.ysize COR spa < 2 COR zei < 1{}       THEN LEAVE out invers{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 2, a.y + zei - 1).{}
+  laenge ist zu gross:{}    laenge > a.xsize - spa - 1.{}  verkuerzte ausgabe:{}    out (mark ein); outsubtext (t, 1, a.xsize - spa - 1);{}    out (blank); out (mark aus){}END PROC out invers;{}PROC erase invers (AREA CONST a, INT CONST spa, zei, INT CONST laenge):{}  ueberpruefe cursorangaben; positioniere cursor;{}  IF laenge ist zu gross{}     THEN verkuerzte ausgabe{}     ELSE erase (laenge + 3){}  FI.{}  ueberpruefe cursorangaben:{}    IF spa > (a.xsize - 4) COR zei > a.ysize COR spa < 2 COR zei < 1{}
+       THEN LEAVE erase invers{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 2, a.y + zei - 1).{}  laenge ist zu gross:{}    laenge > a.xsize - spa - 1.{}  verkuerzte ausgabe:{}    erase ( a.xsize - spa + 2).{}END PROC erase invers;{}PROC out with beam (AREA CONST a, INT CONST spa, zei, TEXT CONST t):{}  ueberpruefe cursorangaben; positioniere cursor;{}  IF text ist zu lang{}     THEN verkuerzte ausgabe{}     ELSE out (senkrecht); out (blank); out (blank);{}          out (t);{}          out (blank); out (blank); out (senkrecht){}
+  FI.{}  ueberpruefe cursorangaben:{}    IF spa > a.xsize - 7 COR zei > a.ysize COR spa < 4 COR zei < 1{}       THEN LEAVE out with beam{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 4, a.y + zei - 1).{}  text ist zu lang:{}    length (t) > a.xsize - spa - 2.{}  verkuerzte ausgabe:{}    out (senkrecht); out (blank); out (blank);{}    outsubtext (t, 1, a.xsize - spa - 2);{}    out (blank); out (blank); out (senkrecht){}END PROC out with beam;{}PROC out with beam (AREA CONST a, INT CONST spa, zei,{}
+                    TEXT CONST t, INT CONST laenge):{}  ueberpruefe cursorangaben; positioniere cursor;{}  IF laenge ist zu gross{}     THEN verkuerzte ausgabe{}     ELSE out (senkrecht); out (blank); out (blank);{}          outtext (t, 1,laenge);{}          out (blank); out (blank); out (senkrecht){}  FI.{}  ueberpruefe cursorangaben:{}    IF spa > a.xsize - 7 COR zei > a.ysize COR spa < 4 COR zei < 1{}       THEN LEAVE out with beam{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 4, a.y + zei - 1).{}
+  laenge ist zu gross:{}    laenge > a.xsize - spa - 2.{}  verkuerzte ausgabe:{}    out (senkrecht); out (blank); out (blank);{}    outsubtext (t, 1, a.xsize - spa - 2);{}    out (blank); out (blank); out (senkrecht){}END PROC out with beam;{}PROC erase with beam (AREA CONST a, INT CONST spa, zei, INT CONST laenge):{}  ueberpruefe cursorangaben; positioniere cursor;{}  IF laenge ist zu gross{}     THEN verkuerzte ausgabe{}     ELSE erase (laenge + 6){}  FI.{}  ueberpruefe cursorangaben:{}    IF spa > a.xsize - 7 COR zei > a.ysize COR spa < 4 COR zei < 1{}
+       THEN LEAVE erase with beam{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 4, a.y + zei - 1).{}  laenge ist zu gross:{}    laenge > a.xsize - spa - 2.{}  verkuerzte ausgabe:{}    erase (a.xsize - spa + 4).{}END PROC erase with beam;{}PROC out invers with beam (AREA CONST a, INT CONST spa, zei, TEXT CONST t):{}  ueberpruefe cursorangaben; positioniere cursor;{}  IF text ist zu lang{}     THEN verkuerzte ausgabe{}     ELSE out (senkrecht); out (blank); out (mark ein);{}          out (t);{}
+          out (blank); out (mark aus); out (senkrecht){}  FI.{}  ueberpruefe cursorangaben:{}    IF spa > a.xsize - 7 COR zei > a.ysize COR spa < 4 COR zei < 1{}       THEN LEAVE out invers with beam{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 4, a.y + zei - 1).{}  text ist zu lang:{}    length (t) > a.xsize - spa - 2.{}  verkuerzte ausgabe:{}    out (senkrecht); out (blank); out (mark ein);{}    outsubtext (t, 1, a.xsize - spa - 2);{}    out (blank); out (mark aus); out (senkrecht){}
+END PROC out invers with beam;{}PROC out invers with beam (AREA CONST a, INT CONST spa, zei,{}                           TEXT CONST t, INT CONST laenge):{}  ueberpruefe cursorangaben; positioniere cursor;{}  IF laenge ist zu gross{}     THEN verkuerzte ausgabe{}     ELSE out (senkrecht); out (blank); out (mark ein);{}          outtext (t, 1, laenge);{}          out (blank); out (mark aus); out (senkrecht){}  FI.{}  ueberpruefe cursorangaben:{}    IF spa > a.xsize - 7 COR zei > a.ysize COR spa < 4 COR zei < 1{}
+       THEN LEAVE out invers with beam{}    FI.{}  positioniere cursor:{}    cursor (a.x + spa - 4, a.y + zei - 1).{}  laenge ist zu gross:{}    laenge > a.xsize - spa - 2.{}  verkuerzte ausgabe:{}    out (senkrecht); out (blank); out (mark ein);{}    outsubtext (t, 1, a.xsize - spa - 2);{}    out (blank); out (mark aus); out (senkrecht){}END PROC out invers with beam;{}END PACKET ls dialog 1;{}
+
diff --git a/dialog/ls-DIALOG 2 b/dialog/ls-DIALOG 2
new file mode 100644
index 0000000..1750162
--- /dev/null
+++ b/dialog/ls-DIALOG 2	
@@ -0,0 +1,77 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                     ls-DIALOG 2                     ** 
+          **                                                     ** 
+          **                     Version 1.2                     ** 
+          **                                                     ** 
+          **                  (Stand: 04.11.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+PACKET ls dialog 2  DEFINES                  
+       some,{}       one,{}       infix namen,{}       ohne praefix,{}       not empty:{}LET maxentries           = 200;{}LET zeichenstring                           =  ""1""27""3""10""13""12"xo?",{}    oben unten return rubout kreuz kringel  =  ""3""10""13""12"xo",{}    q eins neun h                           =  "q19h";{}LET zurueck    =   ""8"",{}    piep       =   ""7"";{}LET hop        =  1,{}    esc        =  2,{}    oben       =  3,{}    unten      =  4,{}    return     =  5,{}    rubout     =  6,{}
+    kreuz      =  7,{}    kringel    =  8,{}    frage      =  9;{}LET punkt      =  ".",{}    gleich     =  "=",{}    blank      =  " ";{}INT  VAR x,{}         y,{}         xsize,{}         ysize,{}         maxeintraege,{}         anzahl,{}         erste auswahlzeile,{}         virtueller cursor,{}         reeller cursor;{}TEXT VAR kennzeile 1,{}         kennzeile 2,{}         registrierkette :: "";{}BOOL VAR abbruch,{}         auswahlende;{}BOUND ROW max entries TEXT VAR eintrag;{}ROW 2 TEXT CONST fehlermeldung :: ROW 2 TEXT : ({}
+  "Unzulässige Cursorwerte bei der Auswahl",{}  "Fenster für Auswahl zu klein (x < 56 / y < 15)");{}ROW 24 TEXT CONST hinweis :: ROW 24 TEXT : ({}  " Bitte warten... Ich sortiere und räume auf!",{}  " Info: <?>  Fertig: <ESC><q>  Abbrechen: <ESC><h>",{}  " Zum Weitermachen bitte irgendeine Taste tippen!",{}  "Weitere Dateien!",{}  "INFORMATIONEN: Auswahl  mehrerer  Dateien",{}  "INFORMATIONEN: Auswahl  einer Datei",{}  "                       "15"Positionierungen: "14"",{}  "  hoch               : zum vorausgehenden Namen",{}
+  "  runter             : zum folgenden   Namen",{}  "  HOP hoch           : auf den ersten  Namen der Seite",  (***********){}  "  HOP runter         : auf den letzten Namen der Seite",  (*  bitte  *){}  "  ESC 1              : auf den ersten  Namen der Liste",  (*  diese  *){}  "  ESC 9              : auf den letzten Namen der Liste",  (*  Länge  *){}  "                       "15"Auswahl treffen: "14"",        (*  nicht  *){}  "  RETURN     / x     : diesen Namen ankreuzen ",          (*  über-  *){}
+  "  RUBOUT     / o     : Kreuz vor dem Namen loeschen",     (*  schrei-*){}  "  HOP RETURN / HOP x : alle folgende Namen ankreuzen",    (*  ten!   *){}  "  HOP RUBOUT / HOP o : alle folgende Kreuze loeschen",    (***********){}  "                       "15"Auswahl verlassen: "14"",{}  "  ESC q              : Auswahl verlassen",{}  "  ESC h              : Auswahl abbrechen",{}  "  Auswahl   m e h r e r e r   Dateien durch Ankreuzen",{}  "  Auswahl   e i n e r   Datei durch Ankreuzen",{}  " Bitte warten... Ich breche die Auswahl ab!"{}
+  );{}THESAURUS PROC auswahl (THESAURUS CONST t,{}                        BOOL CONST mehrere moeglich,{}                        TEXT CONST t1, t2):{}  werte initialisieren;{}  namen besorgen;{}  bildschirm aufbauen;{}  auswaehlen lassen;{}  abgang vorbereiten.{}  werte initialisieren:{}    THESAURUS VAR ausgabe :: empty thesaurus;{}    DATASPACE VAR ds      := nilspace;{}    eintrag               := ds;{}    kennzeile 1           := t1;{}    kennzeile 2           := t2;{}    abbruch               := FALSE;{}
+    erste auswahlzeile    := y + 7;{}    anzahl                := 0;{}    maxeintraege          := ysize - 11;{}    virtueller cursor     := 1;{}    reeller cursor        := 1.{}  namen besorgen:{}    fische die namen aus dem thesaurus;{}    IF kein eintrag vorhanden{}       THEN LEAVE auswahl WITH ausgabe{}    FI.{}  bildschirm aufbauen:{}    schreibe kopfzeile;{}    gib hinweis aus (kennzeile 1, kennzeile 2);{}    gib erklaerungszeile aus (mehrere moeglich);{}    baue bildschirm auf (1);{}    footnote (x, y, xsize, ysize, hinweis [2]);{}
+    schreibe fusszeile;{}    reellen cursor setzen .{}  schreibe kopfzeile:{}    cursor (x, y);{}    out(ecke oben links);{}    (xsize - 2) TIMESOUT waagerecht;{}    out(ecke oben rechts).{}  schreibe fusszeile:{}    cursor (x, y + ysize - 1);{}    out (ecke unten links);{}    (xsize - 2) TIMESOUT waagerecht;{}    out (ecke unten rechts).{}  auswaehlen lassen:{}    kreuze an (mehrere moeglich).{}  abgang vorbereiten:{}    IF abbruch{}       THEN change footnote (x, y, xsize, ysize, hinweis [24]){}
+       ELSE change footnote (x, y, xsize, ysize, hinweis [ 1]){}    FI;{}    cursor (x + 1, y + ysize - 1);{}    ausgabe erzeugen;{}    forget (ds);{}    ausgabe.{}  fische die namen aus dem thesaurus:{}    INT VAR zeiger;{}    FOR zeiger FROM 1 UPTO highest entry (t) REP{}      IF name (t, zeiger) <> ""{}         THEN anzahl INCR 1;{}              eintrag [anzahl] := name (t, zeiger){}      FI{}    PER.{}  kein eintrag vorhanden:{}    anzahl = 0.{}  ausgabe erzeugen:{}    TEXT VAR nummer;{}    WHILE registrierkette <> "" REP{}
+      nummer          := subtext (registrierkette, 1, 3);{}      registrierkette := subtext (registrierkette, 5);{}      insert (ausgabe, eintrag [ int (nummer)]){}    PER.{}END PROC auswahl;{}PROC reellen cursor setzen:{}  cursor (x + 1, erste auswahlzeile + reeller cursor - 1);{}  out (marke (virtueller cursor, TRUE) + (8 * zurueck)){}END PROC reellen cursor setzen;{}PROC baue bildschirm auf (INT CONST anfang):{}  gib kopfzeile aus;{}  gib namenstabelle aus;{}  gib fusszeile aus;{}  loesche ggf restbereich.{}
+  gib kopfzeile aus:{}    cursor (x, erste auswahlzeile - 1); out (senkrecht);{}    IF reeller cursor = virtueller cursor{}       THEN (xsize - 2) TIMESOUT punkt{}       ELSE (xsize - length (hinweis [4]) - 5) TIMESOUT punkt;{}            out (invers (hinweis [4])){}    FI;{}    out (senkrecht);{}    line.{}  gib namenstabelle aus:{}    INT VAR zeiger, zaehler :: -1;{}    FOR zeiger FROM anfang UPTO grenze REP{}      zaehler INCR 1;{}      cursor (x, erste auswahlzeile + zaehler);{}      out (senkrecht); out (marke (zeiger, FALSE));{}
+      outtext (subtext (eintrag [zeiger], 1, xsize - 10), 1, xsize - 10);{}      out (senkrecht);{}    PER.{}  gib fusszeile aus:{}    cursor (x, erste auswahlzeile + zaehler + 1);{}    out (senkrecht);{}    IF NOT ((virtueller cursor + maxeintraege - reeller cursor) < anzahl){}       THEN (xsize - 2) TIMESOUT punkt{}       ELSE (xsize - length (hinweis [4]) - 5) TIMESOUT punkt;{}            out (invers (hinweis [4])){}    FI;{}    out (senkrecht).{}  loesche ggf restbereich:{}    IF zaehler + 1 < maxeintraege{}
+       THEN loesche bildschirmrest{}    FI.{}  loesche bildschirmrest:{}    FOR zeiger FROM restanfang UPTO restende REP{}      cursor (x, zeiger); out (senkrecht);{}                          (xsize - 2) TIMESOUT blank;{}                          out (senkrecht){}    PER.{}  restanfang:{}    erste auswahlzeile + zaehler + 2.{}  restende:{}    erste auswahlzeile + maxeintraege.{}  grenze:{}    min (anzahl, anfang + max eintraege - 1).{}END PROC baue bildschirm auf;{}TEXT PROC marke (INT CONST zeiger, BOOL CONST mit cursor):{}
+  INT VAR platz := nr (zeiger);{}  IF platz = 0{}     THEN leer{}     ELSE mit zahl{}  FI.{}  mit zahl:{}    IF mit cursor{}       THEN "==>" + (3 - length (text (platz))) * blank + text (platz) + "x "{}       ELSE "   " + (3 - length (text (platz))) * blank + text (platz) + "x "{}    FI.{}  leer:{}    IF mit cursor{}       THEN "==>   o "{}       ELSE "      o "{}    FI.{}END PROC marke;{}INT PROC nr (INT CONST zeiger):{}  IF pos (registrierkette, textstring (zeiger)) = 0{}     THEN 0{}     ELSE (pos (registrierkette, textstring (zeiger)) DIV 4) + 1{}
+  FI{}END PROC nr;{}TEXT PROC textstring (INT CONST nr):{}  text (nr, 3) + "!"{}END PROC textstring;{}PROC info (BOOL CONST mehrere):{}  notiere hinweisueberschrift;{}  notiere positionierhinweise;{}  IF noch platz vorhanden{}     THEN  notiere auswahlmoeglichkeiten auf alter seite{}     ELSE  wechsle auf naechste seite;{}           notiere hinweisueberschrift;{}           notiere auswahlmoeglichtkeiten auf neuer seite{}  FI;{}  stelle alten bildschirmzustand wieder her.{}  notiere hinweisueberschrift:{}
+    cursor (x + 1, y +  1);{}    IF mehrere{}       THEN out (center(xsize - 2, invers (hinweis [5]))){}       ELSE out (center(xsize - 2, invers (hinweis [6]))){}    FI;{}    cursor (x + 1, y +  2); out ("", xsize - 2).{}  notiere positionierhinweise:{}    cursor (x + 1, y +  3); out (hinweis [ 7], xsize - 2);{}    cursor (x + 1, y +  4); out (hinweis [ 8], xsize - 2);{}    cursor (x + 1, y +  5); out (hinweis [ 9], xsize - 2);{}    cursor (x + 1, y +  6); out (hinweis [10], xsize - 2);{}    cursor (x + 1, y +  7); out (hinweis [11], xsize - 2);{}
+    cursor (x + 1, y +  8); out (hinweis [12], xsize - 2);{}    cursor (x + 1, y +  9); out (hinweis [13], xsize - 2).{}  notiere auswahlmoeglichkeiten auf alter seite:{}    cursor (x + 1, y + 10); out ("", xsize - 2);{}    cursor (x + 1, y + 11); out (hinweis [14], xsize - 2);{}    cursor (x + 1, y + 12); out (hinweis [15], xsize - 2);{}    IF mehrere{}       THEN  gib alle auswahlmoeglichkeiten auf der alten seite an{}       ELSE  gib eine auswahlmoeglichkeit   auf der alten seite an{}    FI;{}
+    notiere verlassmoeglichkeiten auf der alten seite;{}    loesche die restlichen zeilen;{}    change footnote (x, y, xsize, ysize, hinweis [3]);{}    cursor in ruhestellung;{}    clear buffer.{}  gib alle auswahlmoeglichkeiten auf der alten seite an:{}    cursor (x + 1, y + 13); out (hinweis [16], xsize - 2);{}    cursor (x + 1, y + 14); out (hinweis [17], xsize - 2);{}    cursor (x + 1, y + 15); out (hinweis [18], xsize - 2).{}  gib eine auswahlmoeglichkeit auf der alten seite an:{}    cursor (x + 1, y + 13); out ("", xsize - 2);{}
+    cursor (x + 1, y + 14); out ("", xsize - 2);{}    cursor (x + 1, y + 15); out ("", xsize - 2).{}  notiere verlassmoeglichkeiten auf der alten seite:{}    cursor (x + 1, y + 16); out ("", xsize - 2);{}    cursor (x + 1, y + 17); out (hinweis [19], xsize - 2);{}    cursor (x + 1, y + 18); out (hinweis [20], xsize - 2);{}    cursor (x + 1, y + 19); out (hinweis [21], xsize - 2).{}  loesche die restlichen zeilen:{}    IF ysize = 24{}       THEN cursor (x + 1, y + 20); out ("", xsize - 2){}    FI.{}
+  wechsle auf naechste seite:{}    loesche seitenrest;{}    change footnote (x, y, xsize, ysize, hinweis [3]);{}    cursor in ruhestellung;{}    clear buffer;{}    pause.{}  loesche seitenrest:{}    INT VAR zaehler;{}    FOR zaehler FROM 10 UPTO ysize - 4 REP{}      cursor (x + 1, y + zaehler); out ("", xsize - 2){}    PER.{}  notiere auswahlmoeglichtkeiten auf neuer seite:{}    cursor (x + 1, y +  3); out (hinweis [14], xsize - 2);{}    cursor (x + 1, y +  4); out (hinweis [15], xsize - 2);{}    IF mehrere{}
+       THEN  gib alle auswahlmoeglichkeiten auf der neuen seite an{}       ELSE  gib eine auswahlmoeglichkeit   auf der neuen seite an{}    FI;{}    notiere verlassmoeglichkeiten auf der neuen seite.{}  gib alle auswahlmoeglichkeiten auf der neuen seite an:{}    cursor (x + 1, y +  5); out (hinweis [16], xsize - 2);{}    cursor (x + 1, y +  6); out (hinweis [17], xsize - 2);{}    cursor (x + 1, y +  7); out (hinweis [18], xsize - 2).{}  gib eine auswahlmoeglichkeit auf der neuen seite an:{}    cursor (x + 1, y +  5); out ("", xsize - 2);{}
+    cursor (x + 1, y +  6); out ("", xsize - 2);{}    cursor (x + 1, y +  7); out ("", xsize - 2).{}  notiere verlassmoeglichkeiten auf der neuen seite:{}    cursor (x + 1, y +  8); out ("", xsize - 2);{}    cursor (x + 1, y +  9); out (hinweis [19], xsize - 2);{}    cursor (x + 1, y + 10); out (hinweis [20], xsize - 2);{}    cursor (x + 1, y + 11); out (hinweis [21], xsize - 2);{}    cursor in ruhestellung.{}  cursor in ruhestellung:{}    cursor (x + 1, y + ysize - 2).{}  stelle alten bildschirmzustand wieder her:{}
+    clear buffer;{}    pause;{}    gib hinweis aus (kennzeile 1, kennzeile 2);{}    gib erklaerungszeile aus (mehrere);{}    virtueller cursor := 1;{}    reeller    cursor := 1;{}    baue bildschirm auf (1);{}    change footnote (x, y, xsize, ysize, hinweis [2]);{}    reellen cursor setzen.{}  noch platz vorhanden:{}    (ysize - 4) > 18.{}END PROC info;{}PROC kreuze an (BOOL CONST mehrere):{}  auswahlende := FALSE;{}  REP{}    zeichen lesen; zeichen interpretieren{}  UNTIL auswahlende PER.{}  zeichen lesen:{}
+    TEXT VAR zeichen;{}    getchar (zeichen).{}  zeichen interpretieren:{}    SELECT pos (zeichenstring, zeichen) OF{}      CASE hop      : hop kommando verarbeiten (mehrere){}      CASE esc      : esc kommando verarbeiten{}      CASE oben     : nach oben{}      CASE unten    : nach unten{}      CASE kreuz    : ankreuzen; evtl aufhoeren{}      CASE return   : ankreuzen weiter; evtl aufhoeren{}      CASE rubout   : auskreuzen weiter{}      CASE kringel  : auskreuzen{}      CASE frage    : info (mehrere){}
+      OTHERWISE       out (piep){}    END SELECT.{}  evtl aufhoeren:{}    IF NOT mehrere{}      THEN LEAVE kreuze an{}    FI.{}END PROC kreuze an;{}PROC hop kommando verarbeiten (BOOL CONST mehrere):{}  zweites zeichen lesen;{}  zeichen interpretieren.{}  zweites zeichen lesen:{}    TEXT VAR zweites zeichen;{}    getchar(zweites zeichen).{}  zeichen interpretieren:{}    SELECT pos (oben unten return rubout kreuz kringel, zweites zeichen) OF{}      CASE 1    : hop nach oben{}      CASE 2    : hop nach unten{}
+      CASE 3, 5 : IF mehrere THEN alle darunter ankreuzen FI{}      CASE 4, 6 : IF mehrere THEN alle darunter loeschen  FI{}      OTHERWISE   out (piep){}    END SELECT.{}  alle darunter ankreuzen:{}    INT VAR i;{}    FOR i FROM virtueller cursor UPTO anzahl REP{}      IF nr (i) = 0{}         THEN ankreuzen{}      FI{}    PER;{}    bild aktualisieren ;{}    reellen cursor setzen .{}  ankreuzen:{}    registrierkette CAT textstring (i).{}  alle darunter loeschen:{}    INT VAR j, position;{}    FOR j FROM virtueller cursor UPTO anzahl REP{}
+      position := nr (j);{}      IF position > 0{}         THEN rausschmeissen;{}      FI{}    PER;{}    bild aktualisieren;{}    reellen cursor setzen.{}  rausschmeissen:{}   registrierkette := subtext (registrierkette, 1, (4 * position) - 4) +{}                      subtext (registrierkette, (4 * position) + 1).{}  hop nach oben:{}    IF   ganz oben{}         THEN out (piep){}    ELIF oben auf der seite{}         THEN raufblaettern{}         ELSE top of page{}    FI.{}  ganz oben:{}    virtueller cursor = 1.{}
+  oben auf der seite:{}    reeller cursor = 1.{}  raufblaettern:{}    virtueller cursor DECR max eintraege;{}    virtueller cursor := max (virtueller cursor, 1);{}    baue bildschirm auf (virtueller cursor);{}    reellen cursor setzen.{}  top of page:{}    loesche marke;{}    virtueller cursor DECR (reeller cursor - 1);{}    reeller cursor := 1;{}    reellen cursor setzen.{}  hop nach unten:{}    IF   ganz unten{}         THEN out (piep){}    ELIF unten auf der seite{}         THEN runterblaettern{}
+         ELSE bottom of page{}    FI.{}  ganz unten:{}    virtueller cursor = anzahl.{}  unten auf der seite:{}    reeller cursor > max eintraege - 1.{}  runterblaettern:{}    INT VAR alter virtueller cursor :: virtueller cursor;{}    virtueller cursor INCR max eintraege;{}    virtueller cursor := min (virtueller cursor, anzahl);{}    reeller cursor    := virtueller cursor - alter virtueller cursor;{}    baue bildschirm auf (alter virtueller cursor + 1);{}    reellen cursor setzen.{}  bottom of page:{}
+    loesche marke;{}    alter virtueller cursor := virtueller cursor;{}    virtueller cursor INCR (max eintraege - reeller cursor);{}    virtueller cursor := min (anzahl, virtueller cursor);{}    reeller cursor INCR (virtueller cursor - alter virtueller cursor);{}    reellen cursor setzen.{}END PROC hop kommando verarbeiten;{}PROC esc kommando verarbeiten:{}  TEXT VAR zweites zeichen;{}  getchar (zweites zeichen);{}  SELECT pos (q eins neun h, zweites zeichen) OF{}    CASE 1 :  auswahlende     := TRUE{}
+    CASE 2 :  zeige anfang{}    CASE 3 :  zeige ende{}    CASE 4 :  abbruch         := TRUE;{}              auswahlende     := TRUE;{}              registrierkette := ""{}    OTHERWISE out (piep){}  END SELECT.{}  zeige anfang:{}    IF   virtueller cursor = 1{}         THEN out (piep){}    ELIF virtueller cursor = reeller cursor{}         THEN loesche marke;{}              virtueller cursor := 1;{}              reeller cursor    := 1;{}              reellen cursor setzen{}         ELSE virtueller cursor := 1;{}
+              reeller cursor    := 1;{}              baue bildschirm auf (1);{}              reellen cursor setzen{}    FI.{}  zeige ende:{}    IF   virtueller cursor = anzahl{}         THEN out (piep){}    ELIF ende auf bildschirm{}         THEN loesche marke;{}              reeller cursor INCR (anzahl - virtueller cursor);{}              virtueller cursor := anzahl;{}              reellen cursor setzen{}         ELSE virtueller cursor := anzahl;{}              reeller cursor    := max eintraege;{}
+              baue bildschirm auf (anzahl - (max eintraege - 1));{}              reellen cursor setzen{}    FI.{}  ende auf bildschirm:{}    (reeller cursor + anzahl - virtueller cursor) < max eintraege + 1.{}END PROC esc kommando verarbeiten;{}PROC ankreuzen:{}  INT VAR platz :: nr (virtueller cursor);{}  IF platz <> 0{}     THEN out (piep);{}          LEAVE ankreuzen{}  FI;{}  registrierkette CAT textstring (virtueller cursor);{}  reellen cursor setzen{}END PROC ankreuzen;{}PROC ankreuzen weiter:{}
+  INT VAR platz :: nr (virtueller cursor);{}  IF platz <> 0{}     THEN out (piep);{}          LEAVE ankreuzen weiter{}  FI;{}  registrierkette CAT textstring (virtueller cursor);{}  IF virtueller cursor < anzahl{}     THEN nach unten{}  FI;{}  IF virtueller cursor = anzahl{}    THEN reellen cursor setzen{}  FI{}END PROC ankreuzen weiter;{}PROC auskreuzen weiter:{}  INT VAR position :: nr (virtueller cursor);{}  IF position = 0{}    THEN out (piep);{}         LEAVE auskreuzen weiter{}  FI;{}  rausschmeissen;{}
+  IF virtueller cursor < anzahl{}     THEN nach unten{}     ELSE loesche marke{}  FI;{}  bild aktualisieren;{}  reellen cursor setzen.{}  rausschmeissen:{}    registrierkette := subtext (registrierkette, 1, 4 * position - 4) +{}                       subtext (registrierkette, 4 * position + 1).{}END PROC auskreuzen weiter;{}PROC auskreuzen:{}  INT VAR position :: nr (virtueller cursor);{}  IF position = 0{}    THEN out (piep);{}         LEAVE auskreuzen{}  FI;{}  rausschmeissen;{}  loesche marke;{}
+  bild aktualisieren;{}  reellen cursor setzen.{}  rausschmeissen:{}    registrierkette := subtext (registrierkette, 1, 4 * position - 4) +{}                       subtext (registrierkette, 4 * position + 1).{}END PROC auskreuzen;{}PROC bild aktualisieren:{}  INT VAR ob, un, i, zaehler :: -1;{}  ob := virtueller cursor - reeller cursor + 1;{}  un := min (ob + max eintraege - 1, anzahl);{}  FOR i FROM ob UPTO un REP{}  zaehler INCR 1;{}  cursor (x + 1, erste auswahlzeile + zaehler);{}  out (marke (i,FALSE)) PER{}
+END PROC bild aktualisieren;{}PROC nach oben:{}  IF noch nicht oben       (*virtuell*){}     THEN gehe nach oben{}     ELSE out (piep){}  FI.{}  noch nicht oben:{}    virtueller cursor > 1.{}  gehe nach oben:{}    IF reeller cursor = 1 THEN scroll down ELSE cursor up FI.{}  scroll down:{}    virtueller cursor DECR 1;{}    baue bildschirm auf (virtueller cursor);{}    reellen cursor setzen.{}  cursor up:{}    loesche marke;{}    virtueller cursor DECR 1;{}    reeller cursor DECR 1;{}    reellen cursor setzen{}
+END PROC nach oben;{}PROC nach unten:{}  IF noch nicht unten      (*virtuell*){}     THEN gehe nach unten{}     ELSE out (piep){}  FI.{}  noch nicht unten:{}    virtueller cursor < anzahl.{}  gehe nach unten:{}    IF reeller cursor > max eintraege - 1 THEN scroll up ELSE cursor down FI.{}  scroll up:{}    virtueller cursor INCR 1;{}    baue bildschirm auf (virtueller cursor - (max eintraege - 1));{}    reellen cursor setzen.{}  cursor down:{}    loesche marke;{}    virtueller cursor INCR 1;{}    reeller cursor INCR 1;{}
+    reellen cursor setzen{}END PROC nach unten;{}PROC loesche marke:{}  out (marke (virtueller cursor, FALSE)){}END PROC loesche marke;{}PROC footnote (INT CONST x, y, xsize, ysize, TEXT CONST text):{}  cursor (x, y + ysize - 3);{}  out (balken links); (xsize - 2) TIMESOUT waagerecht; out (balken rechts);{}  change footnote (x, y, xsize, ysize, text){}END PROC footnote;{}PROC change footnote (INT CONST x, y, xsize, ysize, TEXT CONST text):{}  cursor (x, y + ysize - 2);{}  out (senkrecht); outtext (text, 1, xsize - 2); out (senkrecht){}
+END PROC change footnote;{}PROC gib hinweis aus (TEXT CONST t1, t2):{}  cursor (x, y + 1); out (senkrecht);{}                     out (center (xsize - 2, invers (t1)));{}                     out (senkrecht);{}  cursor (x, y + 2); out (senkrecht);{}                     out ("", xsize - 2);{}                     out (senkrecht);{}  cursor (x, y + 3); out (senkrecht);{}                     out (center (xsize - 2, t2));{}                     out (senkrecht){}END PROC gib hinweis aus;{}PROC gib erklaerungszeile aus (BOOL CONST mehrere):{}
+  cursor (x, y + 4); out (senkrecht);{}                     out ((xsize - 2) * gleich);{}                     out (senkrecht);{}  cursor (x, y + 5); out (senkrecht);{}                     IF mehrere{}                        THEN out (erklaerungszeile mehrere){}                        ELSE out (erklaerungszeile eine){}                     FI;{}                     out (senkrecht).{}  erklaerungszeile mehrere:{}    invers (text 1 + (rest1 * blank)).{}  erklaerungszeile eine:{}    invers (text 2 + (rest2 * blank)).{}
+  text1:{}    hinweis [22].{}  text2:{}    hinweis [23].{}  rest1:                                  (***************************){}    xsize - length (text1) - 5.           (* durch 'invers' wird ein *){}                                          (* Blank angehängt und zu- *){}  rest2:                                  (* sätzlich noch durch     *){}    xsize - length (text2) - 5.           (* 'relativcenter' - außer-*){}END PROC gib erklaerungszeile aus;        (* dem nimmt die Markierung*){}                                          (* selbst eine Position ein*){}
+                                          (***************************){}THESAURUS PROC infix namen (THESAURUS CONST t, TEXT CONST infix):{}  THESAURUS VAR tt :: empty thesaurus;{}  INT VAR i;{}  FOR i FROM 1 UPTO highest entry (t) REP{}    TEXT VAR eintrag :: name (t,i);{}    IF eintrag enthaelt infix{}       THEN insert (tt, eintrag){}    FI{}  PER;{}  tt.{}  eintrag enthaelt infix:{}    pos (eintrag, infix) <> 0{}END PROC infix namen;{}THESAURUS PROC infix namen (THESAURUS CONST t, INT CONST dateityp):{}
+  THESAURUS VAR tt :: empty thesaurus;{}  INT VAR i;{}  FOR i FROM 1 UPTO highest entry (t) REP{}    TEXT VAR eintrag :: name (t,i);{}    IF eintrag enthaelt infix{}       THEN insert (tt, eintrag){}    FI{}  PER;{}  tt.{}  eintrag enthaelt infix:{}    type (old (eintrag)) = dateityp.{}END PROC infix namen;{}THESAURUS PROC  infix namen (THESAURUS CONST t,{}                             TEXT CONST infix 1, INT CONST dateityp):{}  THESAURUS VAR tt :: empty thesaurus;{}  INT VAR i;{}  FOR i FROM 1 UPTO highest entry (t) REP{}
+    TEXT VAR eintrag :: name (t,i);{}    IF eintrag enthaelt infix{}       THEN insert (tt, eintrag){}    FI{}  PER;{}  tt.{}  eintrag enthaelt infix:{}   (pos (eintrag, infix 1) <> 0) AND (type (old (eintrag)) = dateityp).{}END PROC infix namen;{}THESAURUS PROC  infix namen (THESAURUS CONST t,{}                             TEXT CONST infix 1, infix 2):{}  THESAURUS VAR tt :: empty thesaurus;{}  INT VAR i;{}  FOR i FROM 1 UPTO highest entry (t) REP{}    TEXT VAR eintrag :: name (t,i);{}    IF eintrag enthaelt infix{}
+       THEN insert (tt, eintrag){}    FI{}  PER;{}  tt.{}  eintrag enthaelt infix:{}   (pos (eintrag, infix 1) <> 0) OR (pos (eintrag, infix 2) <> 0){}END PROC infix namen;{}THESAURUS PROC infix namen (TEXT CONST infix):{}  infix namen (ALL myself, infix){}END PROC infix namen;{}THESAURUS PROC infix namen (TEXT CONST infix 1, infix 2):{}  infix namen (ALL myself, infix 1, infix 2){}END PROC infix namen;{}THESAURUS PROC ohne praefix (THESAURUS CONST thesaurus, TEXT CONST praefix):{}  THESAURUS VAR t :: empty thesaurus;{}
+  INT VAR zaehler;{}  FOR zaehler FROM 1 UPTO highest entry (thesaurus) REP{}    IF name (thesaurus, zaehler) <> ""{}       AND pos (name (thesaurus, zaehler), praefix) = 1{}       THEN insert (t, subtext (name (thesaurus, zaehler),{}                                  length (praefix) + 1)){}    FI;{}  PER;{}  t{}END PROC ohne praefix;{}BOOL PROC not empty (THESAURUS CONST t):{}  INT VAR i;{}  FOR i FROM 1 UPTO highest entry (t) REP{}    IF name (t, i) <> ""{}       THEN LEAVE not empty WITH TRUE{}
+    FI{}  PER;{}  FALSE{}END PROC not empty;{}PROC untersuche bildschirmmasszahlen (TEXT CONST t1, t2):{}  IF   unzulaessige cursorwerte{}       THEN errorstop (fehlermeldung [1]){}  ELIF fenster ist zu klein{}       THEN errorstop (fehlermeldung [2]){}  FI.{}  unzulaessige cursorwerte:{}    (x + xsize) > 80 COR (y + ysize) > 25 COR x < 1 COR y < 1{}    COR xsize > 79 COR ysize > 24.{}  fenster ist zu klein:{}   (xsize) < 56 COR (ysize) < 15{}   COR length (t1) > (xsize - 5) COR length (t2) > (xsize - 5).{}
+END PROC untersuche bildschirmmasszahlen;{}TEXT PROC ggf gekuerzter text (TEXT CONST text):{}   IF length (text) > (xsize - 5){}      THEN subtext (text, 1, xsize - 7) + ".."{}      ELSE text{}   FI{}END PROC ggf gekuerzter text;{}THESAURUS PROC some (INT CONST spa, zei, breite, hoehe,{}                     THESAURUS CONST t,{}                     TEXT CONST t1, t2):{}  TEXT VAR text 1, text 2;{}  x := spa;{}  y := zei;{}  xsize := breite;{}  ysize := hoehe;{}  text 1 := ggf gekuerzter text (t1);{}
+  text 2 := ggf gekuerzter text (t2);{}  untersuche bildschirmmasszahlen (text 1, text 2);{}  auswahl (t, TRUE, text 1, text 2){}END PROC some;{}THESAURUS PROC some (INT CONST spa, zei,{}                     THESAURUS CONST t,{}                     TEXT CONST t1, t2):{}  some (spa, zei, 79 - spa + 1, 24 - zei + 1, t, t1, t2){}END PROC some;{}THESAURUS PROC some (THESAURUS CONST t,{}                     TEXT CONST t1, t2):{}  some (1, 1, 79, 24, t, t1, t2){}END PROC some;{}TEXT PROC one (INT CONST spa, zei, breite, hoehe,{}
+               THESAURUS CONST t,{}               TEXT CONST t1, t2):{}  TEXT VAR text 1, text 2;{}  x := spa;{}  y := zei;{}  xsize := breite;{}  ysize := hoehe;{}  text 1 := ggf gekuerzter text (t1);{}  text 2 := ggf gekuerzter text (t2);{}  untersuche bildschirmmasszahlen (text 1, text 2);{}  name (auswahl (t, FALSE, text 1, text 2), 1){}END PROC one;{}TEXT PROC one (INT CONST spa, zei,{}               THESAURUS CONST t,{}               TEXT CONST t1, t2):{}  one (spa, zei, 79 - spa + 1, 24 - zei + 1, t, t1, t2){}
+END PROC one;{}TEXT PROC one  (THESAURUS CONST t, TEXT CONST t1, t2):{}  one (1, 1, 79, 24, t, t1, t2){}END PROC one;{}END PACKET ls dialog 2;{}
+
diff --git a/dialog/ls-DIALOG 3 b/dialog/ls-DIALOG 3
new file mode 100644
index 0000000..dce6507
--- /dev/null
+++ b/dialog/ls-DIALOG 3	
@@ -0,0 +1,48 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                     ls-DIALOG 3                     ** 
+          **                                                     ** 
+          **                     Version 1.2                     ** 
+          **                                                     ** 
+          **                  (Stand: 04.11.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET ls dialog 3  DEFINES{}       WINDOW, :=, window,{}       show, page, erase,{}       line, remaining lines,{}       cursor, get cursor,{}       out frame, out menuframe,{}       out, put, putline, editget,{}       get, getline, yes, no,{}       edit, center, stop,{}       area, areax, areay,{}       areaxsize, areaysize:{}LET piep          =      ""7"",{}    cr            =     ""13"";{}LET janeinkette   =   "jJyYnN",{}    blank         =        " ",{}    niltext       =         "";{}TYPE WINDOW = STRUCT (AREA fenster,{}
+                      INT cspalte, czeile, belegbare zeilen,{}                      BOOL fensterende erreicht);{}ROW 3 TEXT CONST aussage :: ROW 3 TEXT : ({}  " 'Window' ungültig!",{}  " (j/n) ?",{}  " Zum Weitermachen bitte irgendeine Taste tippen!"{}  );{}TEXT VAR number word, exit char;{}OP := (WINDOW VAR links, WINDOW CONST rechts):{}  CONCR (links) := CONCR (rechts){}END OP :=;{}WINDOW PROC window (INT CONST x, y, xsize, ysize):{}  WINDOW VAR w;{}  fill (w.fenster, x, y, xsize, ysize);{}  IF fenster ungueltig (w){}
+     THEN errorstop (aussage [1]){}  FI;{}  initialize (w);{}  w{}END PROC window;{}PROC initialize (WINDOW VAR w):{}  w.czeile               := 1;{}  w.cspalte              := 1;{}  w.fensterende erreicht := FALSE;{}  w.belegbare zeilen     := areaysize (w.fenster){}END PROC initialize;{}BOOL PROC fenster ungueltig (WINDOW CONST w):{}  IF     areax     (w.fenster) <  1  COR areax     (w.fenster) > 79{}     COR areay     (w.fenster) <  1  COR areay     (w.fenster) > 24{}     COR areaxsize (w.fenster) <  6  COR areaysize (w.fenster) <  3{}
+     COR areax (w.fenster) + areaxsize (w.fenster) > 80{}     COR areay (w.fenster) + areaysize (w.fenster) > 25{}     THEN TRUE{}     ELSE FALSE{}  FI.{}END PROC fenster ungueltig;{}PROC show (WINDOW VAR w):{}  zeige rahmen;{}  fenster putzen.{}  zeige rahmen:{}    out frame (w.fenster).{}  fenster putzen:{}    page (w).{}END PROC show;{}PROC page (WINDOW VAR w):{}  initialize (w);{}  page (w, FALSE){}END PROC page;{}PROC page (WINDOW CONST w, BOOL CONST mit rahmen ):{}  IF areax     (w) = 1  AND areay     (w) =  1 AND{}
+     areaxsize (w) = 79 AND areaysize (w) = 24{}     THEN page;{}     ELSE loesche bereich{}  FI.{}  loesche bereich:{}    IF mit rahmen{}       THEN page (areax     (w) - 1, areay     (w) - 1,{}                  areaxsize (w) + 2, areaysize (w) + 2){}       ELSE page (area (w)){}    FI{}END PROC page;{}PROC erase (WINDOW VAR w):{}  page (w, TRUE){}END PROC erase;{}PROC line (WINDOW VAR w):{}  w.cspalte := 1;{}  IF w.czeile < w.belegbare zeilen{}     THEN w.czeile INCR 1;{}     ELSE w.czeile  :=  1;{}
+          w.fensterende erreicht := TRUE{}  FI;{}  cursor (w, w.cspalte, w.czeile){}END PROC line;{}PROC line (WINDOW VAR w, INT CONST anzahl):{}  INT VAR i; FOR i FROM 1 UPTO anzahl REP line (w) PER{}END PROC line;{}INT PROC remaining lines (WINDOW CONST w):{}  INT VAR spalte, zeile;{}  get cursor (w, spalte, zeile);{}  IF spalte = 0 OR zeile = 0{}     THEN 0{}     ELSE w.belegbare zeilen - w.czeile{}  FI{}END PROC remaining lines;{}PROC cursor (WINDOW VAR w, INT CONST spalte, zeile):{}  IF spalte < 1 OR zeile < 1 OR spalte > areaxsize (w) OR zeile > areaysize (w){}
+     THEN page (w);{}     ELSE w.cspalte := spalte; w.czeile  := zeile;{}  FI;{}  cursor (w.fenster, w.cspalte, w.czeile){}END PROC cursor;{}PROC get cursor (WINDOW CONST w, INT VAR spalte, zeile):{}  IF (w.cspalte < 1) OR (w.cspalte > areaxsize (w.fenster)){}                          OR{}     (w.czeile  < 1) OR (w.czeile  > areaysize (w.fenster)){}     THEN spalte := 0;         zeile := 0{}     ELSE spalte := w.cspalte; zeile := w.czeile{}  FI{}END PROC get cursor;{}PROC out (WINDOW VAR w, TEXT CONST text):{}
+  INT VAR restlaenge;{}  IF (w.cspalte >= 1) AND (w.cspalte <= areaxsize (w.fenster)){}                           AND{}     (w.czeile  >= 1) AND (w.czeile  <= w.belegbare zeilen){}     THEN putze ggf fenster;{}          cursor (w.fenster, w.cspalte, w.czeile);{}          outtext (text, 1, textende);{}          setze fenstercursor neu;{}          setze ausgabe ggf in naechster zeile fort{}  FI.{}  putze ggf fenster:{}    IF w.fensterende erreicht{}       THEN page (w);{}            w.fensterende erreicht := FALSE{}
+    FI.{}  textende:{}    restlaenge := areaxsize (w.fenster) - w.cspalte + 1;{}    min (length (text), restlaenge).{}  setze fenstercursor neu:{}    IF length (text) >= restlaenge{}       THEN w.cspalte  := 1;{}            w.czeile INCR 1;{}            schlage ggf neue seite auf{}       ELSE w.cspalte INCR length (text){}    FI.{}  schlage ggf neue seite auf:{}    IF w.czeile > w.belegbare zeilen{}       THEN page (w);{}            w.czeile := 1{}    FI.{}  setze ausgabe ggf in naechster zeile fort:{}
+    IF length (text) > restlaenge{}       THEN out (w, subtext (text, restlaenge + 1)){}    FI.{}END PROC out;{}PROC out frame (WINDOW VAR w):{}  out frame (area (w)){}END PROC out frame;{}PROC out menuframe (WINDOW VAR w):{}  out menu frame (area (w)){}END PROC out menuframe;{}PROC put (WINDOW VAR w, TEXT CONST word):{}  out (w, word); out (w, blank){}END PROC put;{}PROC put (WINDOW VAR w, INT CONST number):{}  put (w, text (number)){}END PROC put;{}PROC put (WINDOW VAR w, REAL VAR number):{}  put (w, text (number)){}
+END PROC put;{}PROC putline (WINDOW VAR w, TEXT CONST textline):{}  out (w, textline); line (w){}END PROC putline;{}PROC editget (WINDOW VAR w, TEXT VAR ausgabe,{}              INT CONST max laenge, scroll,{}              TEXT CONST sep, res, TEXT VAR exit char):{}  INT VAR spalte, zeile;{}  ggf zur naechsten zeile;{}  get cursor (spalte, zeile); cursor on; cursor (spalte, zeile);{}  editget (ausgabe, max laenge, min (scroll, restlaenge),{}           sep, res, exitchar);{}  get cursor (spalte, zeile); cursor off; cursor (spalte, zeile).{}
+  ggf zur naechsten zeile:{}    IF restlaenge < 5 THEN line (w) FI.{}  restlaenge:{}    areaxsize (w.fenster) - w.cspalte - 1.{}END PROC editget;{}PROC editget (WINDOW VAR w, TEXT VAR ausgabe):{}   TEXT VAR dummy;{}   editget (w, ausgabe, 79, 79, "", "", dummy){}END PROC editget;{}PROC get (WINDOW VAR w, TEXT VAR word):{}  INT VAR spa, zei;{}  ggf zur naechsten zeile;{}  get cursor (spa, zei); cursor on; cursor (spa, zei);{}  REP{}    word := "";{}    editget (word, maxtextlength, restlaenge, " ", "", exit char);{}
+    out (w, subtext (word, 1, restlaenge));{}    IF compress (word) <> ""{}       THEN echoe exit char (w){}    FI{}  UNTIL word <> niltext AND word <> blank PER;{}  get cursor (spa, zei); cursor off; cursor (spa, zei);{}  delete leading blanks.{}  ggf zur naechsten zeile:{}    IF restlaenge < 5 THEN line (w) FI.{}  restlaenge:{}    areaxsize (w.fenster) - w.cspalte - 1.{}  delete leading blanks:{}    WHILE (word SUB 1) = blank REP word := subtext (word, 2) PER.{}END PROC get;{}PROC get (WINDOW VAR w, TEXT VAR word, TEXT CONST separator):{}
+  INT VAR spa, zei;{}  ggf zur naechsten zeile;{}  get cursor (spa, zei); cursor on; cursor (spa, zei);{}  REP{}    word := "";{}    editget (word, maxtextlength, restlaenge, separator, "", exit char);{}    out (w, subtext (word, 1, restlaenge));{}    echoe exit char (w);{}  UNTIL word <> niltext AND word <> blank PER;{}  get cursor (spa, zei); cursor off; cursor (spa, zei).{}  ggf zur naechsten zeile:{}    IF restlaenge < 5 THEN line (w) FI.{}  restlaenge:{}    areaxsize (w.fenster) - w.cspalte - 1.{}
+END PROC get;{}PROC get (WINDOW VAR w, TEXT VAR word, INT CONST length):{}  INT VAR spa, zei;{}  ggf zur naechsten zeile;{}  get cursor (spa, zei); cursor on; cursor (spa, zei);{}  REP{}    word := "";{}    editget (word, maxtextlength, laenge, "", "", exit char);{}    out (w, subtext (word, 1, laenge));{}    echoe exit char (w){}  UNTIL word <> niltext AND word <> blank PER;{}  get cursor (spa, zei); cursor off; cursor (spa, zei).{}  ggf zur naechsten zeile:{}    IF restlaenge < 5 THEN line (w) FI.{}
+  restlaenge:{}    areaxsize (w.fenster) - w.cspalte - 1.{}  laenge:{}    min (length, restlaenge).{}END PROC get;{}PROC get (WINDOW VAR w, INT VAR number):{}  get (w, number word);{}  number := int (number word){}END PROC get;{}PROC get (WINDOW VAR w, REAL VAR number):{}  get  (w, number word);{}  number := real (number word){}END PROC get;{}PROC getline (WINDOW VAR w, TEXT VAR textline):{}  INT VAR spa, zei;{}  ggf zur naechsten zeile;{}  get cursor (spa, zei); cursor on; cursor (spa, zei);{}  REP{}
+    textline := "";{}    editget (textline, maxtextlength, restlaenge, "", "", exit char);{}    out (w, subtext (word, 1, restlaenge));{}    echoe exit char (w);{}  UNTIL textline <> niltext AND textline <> blank PER;{}  get cursor (spa, zei); cursor off; cursor (spa, zei).{}  ggf zur naechsten zeile:{}    IF restlaenge < 5 THEN line (w) FI.{}  restlaenge:{}    areaxsize (w.fenster) - w.cspalte - 1.{}END PROC getline;{}PROC echoe exit char (WINDOW VAR fenster):{}  IF exit char = cr{}     THEN line (fenster){}
+     ELSE out (fenster, exit char){}  FI{}END PROC echoe exit char;{}TEXT PROC center (WINDOW CONST w, TEXT CONST text):{}  IF length (text) >= areaxsize (w.fenster){}     THEN subtext (text, 1, areaxsize (w.fenster)){}     ELSE center  (areaxsize (w.fenster), text){}  FI{}END PROC center;{}BOOL PROC yes (WINDOW VAR w, TEXT CONST frage):{}  TEXT VAR   zeichen, interne frage :: frage;{}  interne frage CAT aussage [2];{}  wechsel ggf auf neue seite;{}  out (w, interne frage);{}  hole eingabezeichen;{}
+  werte zeichen aus.{}  wechsel ggf auf neue seite:{}    IF remaining lines (w) < 1{}       THEN page (w){}    FI.{}  hole eingabezeichen:{}    cursor on; clear buffer;{}    REP{}      inchar (zeichen);{}      piepse ggf{}    UNTIL pos (janeinkette, zeichen) > 0 PER;{}    out (w, blank + zeichen);{}    cursor off; line (w).{}  piepse ggf:{}    IF pos (janeinkette, zeichen) = 0 THEN out (piep) FI.{}  werte zeichen aus:{}    IF pos (janeinkette, zeichen) < 5{}       THEN TRUE{}       ELSE FALSE{}    FI.{}
+END PROC yes;{}PROC edit (WINDOW VAR w, FILE VAR f):{}  out frame (w.fenster);{}  loesche rechte spalten (w);{}  cursor on;{}  edit (f, areax     (w.fenster),     areay     (w.fenster),{}           areaxsize (w.fenster) - 1, areaysize (w.fenster));{}  cursor off{}END PROC edit;{}PROC edit (WINDOW VAR w, TEXT CONST dateiname):{}  FILE VAR f :: sequential file (modify, dateiname);{}  to line (f, 1);{}  edit (w, f){}END PROC edit;{}PROC show (WINDOW VAR w, FILE VAR f):{}  out frame (w.fenster);{}  loesche rechte spalten (w);{}
+  open editor (groesster editor + 1, f, FALSE,{}               areax     (w.fenster),     areay     (w.fenster),{}               areaxsize (w.fenster) - 1, areaysize (w.fenster));{}  cursor on;{}  edit (groesster editor, "eqvw19dpgn"9"",{}                          PROC (TEXT CONST) std kommando interpreter);{}  cursor off{}END PROC show;{}PROC show (WINDOW VAR w, TEXT CONST dateiname):{}  FILE VAR f :: sequential file (modify, dateiname);{}  to line (f, 1);{}  show (w, f){}END PROC show;{}PROC loesche rechte spalten (WINDOW VAR w):{}
+  INT VAR i;{}  FOR i FROM 1 UPTO areaysize (w.fenster) REP{}    cursor (w, areaxsize (w.fenster) - 2, i); out (3 * blank){}  PER{}END PROC loesche rechte spalten;{}BOOL PROC no (WINDOW VAR w, TEXT CONST frage):{}  NOT yes (w, frage){}END PROC no;{}PROC stop (WINDOW VAR w):{}  stop (w, 2){}END PROC stop;{}PROC stop (WINDOW VAR w, INT CONST zeilenzahl):{}  INT VAR i; FOR i FROM 1 UPTO zeilenzahl REP line (w) PER;{}  out (w, aussage [3]);{}  pause{}END PROC stop;{}AREA PROC area (WINDOW CONST w):{}
+  w.fenster{}END PROC area;{}INT PROC areax (WINDOW CONST w):{}  areax (w.fenster){}END PROC areax;{}INT PROC areay (WINDOW CONST w):{}  areay (w.fenster){}END PROC areay;{}INT PROC areaxsize (WINDOW CONST w):{}  areaxsize (w.fenster){}END PROC areaxsize;{}INT PROC areaysize (WINDOW CONST w):{}  areaysize (w.fenster){}END PROC areaysize;{}END PACKET ls dialog 3;{}
+
diff --git a/dialog/ls-DIALOG 4 b/dialog/ls-DIALOG 4
new file mode 100644
index 0000000..7c9d9c4
--- /dev/null
+++ b/dialog/ls-DIALOG 4	
@@ -0,0 +1,71 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                     ls-DIALOG 4                     ** 
+          **                                                     ** 
+          **                     Version 1.2                     ** 
+          **                                                     ** 
+          **                  (Stand: 04.11.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET  ls dialog 4  DEFINES{}       boxinfo,{}       boxnotice,{}       boxalternative,{}       boxyes,{}       boxno,{}       boxanswer,{}       boxone,{}       boxanswerone,{}       boxsome,{}       boxanswersome,{}       out footnote,{}       erase footnote:{}LET mark ein                 =           ""15"",{}    mark aus                 =           ""14"",{}    delimiter                =           ""13"",{}    piep                     =            ""7"",{}    rechts links esc  return = ""2""8""27""13"",{}
+    rechts links null return = ""2""8""0""13"" ,{}    blank                    =              " ",{}    niltext                  =               "",{}    janeintasten             =         "jJyYnN";{}ROW 8 TEXT CONST aussage :: ROW 8 TEXT : ({}" Zum Weitermachen bitte irgendeine Taste tippen!",{}" Ändern: <Pfeile>  Bestätigen: <RETURN>  Abbruch: <ESC> <h>",{}" Ändern: <Pfeile>  Bestätigen: <RETURN>  Ja: <j>  Nein: <n>",{}" Ändern: <Pfeile>  Bestätigen: <RETURN>",{}" Fertig: <RETURN>  Zeigen: <ESC><z>  Abbruch: <ESC><h>",{}
+" Fertig: <RETURN>  Abbruch: <ESC><h>",{}"Ja"13"Nein",{}" Eingabe: "{});{}PROC boxinfo (WINDOW VAR w, TEXT CONST t,{}              INT CONST position, timelimit,{}              INT VAR x, y, xsize, ysize):{}  INT VAR spa, zei;{}  get cursor (w, spa, zei);{}  schreibe box (w, t, position, timelimit, x, y, xsize, ysize);{}  cursor (w, spa, zei);{}END PROC boxinfo;{}PROC boxinfo (WINDOW VAR w, TEXT CONST t, INT CONST position,{}                            timelimit, BOOL CONST trennlinie weg):{}  INT VAR x, y, xsize, ysize, spa, zei;{}
+  get cursor (w, spa, zei);{}  schreibe box (w, t, position, timelimit, x, y, xsize, ysize);{}  page up (x, y, xsize, ysize);{}  IF trennlinie weg{}     THEN erase footnote (w, TRUE){}     ELSE erase footnote (w, FALSE){}  FI;{}  cursor (w, spa, zei){}END PROC boxinfo;{}PROC boxinfo (WINDOW VAR w, TEXT CONST t, INT CONST position, timelimit):{}  boxinfo (w, t, position, timelimit, TRUE){}END PROC boxinfo;{}PROC boxinfo (WINDOW VAR w, TEXT CONST t):{}  boxinfo (w, t, 5, maxint, TRUE){}END PROC boxinfo;{}
+PROC boxnotice (WINDOW VAR w, TEXT CONST t, INT CONST position,{}                              INT VAR x, y, xsize, ysize):{}  INT VAR spa, zei;{}  get cursor (w, spa, zei);{}  schreibe notiz (w, t, position, x, y, xsize, ysize);{}  cursor (w, spa, zei){}END PROC boxnotice;{}INT PROC boxalternative (WINDOW VAR w, TEXT CONST t,{}                         auswahlliste, zusatztasten,{}                         INT CONST position, BOOL CONST mit abbruch,{}                         INT VAR x, y, xsize, ysize):{}
+  INT VAR ergebnis, spa, zei;{}  get cursor (w, spa, zei);{}  schreibe alternativen (w, t, auswahlliste, zusatztasten, position,{}                         mit abbruch, x, y, xsize, ysize, ergebnis);{}  cursor (w, spa, zei);{}  ergebnis{}END PROC boxalternative;{}INT PROC boxalternative (WINDOW VAR w, TEXT CONST t, auswahlliste,{}                         zusatztasten, INT CONST position,{}                         BOOL CONST mit abbruch, trennlinie weg):{}  INT VAR x, y, xsize, ysize, ergebnis, spa, zei;{}
+  get cursor (w, spa, zei);{}  ergebnis := boxalternative (w, t, auswahlliste, zusatztasten, position,{}                                 mit abbruch, x, y, xsize, ysize);{}  page up (x, y, xsize, ysize);{}  IF trennlinie weg{}     THEN erase footnote (w, TRUE){}     ELSE erase footnote (w, FALSE){}  FI;{}  cursor (w, spa, zei);{}  ergebnis{}END PROC boxalternative;{}INT PROC boxalternative (WINDOW VAR w, TEXT CONST t,{}                         auswahlliste, zusatztasten,{}                         INT CONST position, BOOL CONST mit abbruch):{}
+  boxalternative (w, t, auswahlliste, zusatztasten,{}                        position, mit abbruch, TRUE){}END PROC boxalternative;{}BOOL PROC boxyes (WINDOW VAR w, TEXT CONST t, INT CONST position,{}                                INT VAR x, y, xsize, ysize):{}   INT VAR spa, zei;{}   get cursor (w, spa, zei);{}   BOOL CONST wert :: ja (w, t, position, x, y, xsize, ysize);{}   cursor (w, spa, zei);{}   wert{}END PROC boxyes;{}BOOL PROC boxyes (WINDOW VAR w, TEXT CONST t,{}                  INT CONST position, BOOL CONST trennlinie weg):{}
+  INT VAR x, y, xsize, ysize, spa, zei;{}  get cursor (w, spa, zei);{}  BOOL VAR wert :: ja (w, t, position, x, y, xsize, ysize);{}  page up (x, y, xsize, ysize);{}  IF trennlinie weg{}     THEN erase footnote (w, TRUE){}     ELSE erase footnote (w, FALSE);{}  FI;{}  cursor (w, spa, zei);{}  wert{}END PROC boxyes;{}BOOL PROC boxyes (WINDOW VAR w, TEXT CONST t, INT CONST position):{}  boxyes (w, t, position, TRUE){}END PROC boxyes;{}BOOL PROC boxno (WINDOW VAR w, TEXT CONST t, INT CONST position,{}
+                               INT VAR x, y, xsize, ysize):{}   NOT boxyes (w, t, position, x, y, xsize, ysize){}END PROC boxno;{}BOOL PROC boxno (WINDOW VAR w, TEXT CONST t,{}                 INT CONST position, BOOL CONST trennlinie weg):{}  NOT boxyes (w, t, position, trennlinie weg){}END PROC boxno;{}BOOL PROC boxno (WINDOW VAR w, TEXT CONST t, INT CONST position):{}  boxno (w, t, position){}END PROC boxno;{}TEXT PROC boxanswer (WINDOW VAR w, TEXT CONST t, vorgabe,{}                     INT CONST position, INT VAR x, y, xsize, ysize):{}
+  INT VAR spa, zei;{}  TEXT VAR wert;{}  get cursor (w, spa, zei);{}  wert := hole antwort (w, t, vorgabe, position, FALSE, x, y, xsize, ysize);{}  cursor (spa, zei);{}  wert{}END PROC boxanswer;{}TEXT PROC boxanswer (WINDOW VAR w, TEXT CONST t, vorgabe,{}                     INT CONST position, BOOL CONST trennlinie weg):{}  INT VAR x, y, xsize, ysize, spa, zei;{}  get cursor (w, spa, zei);{}  TEXT VAR wert := hole antwort (w, t, vorgabe, position, FALSE,{}                                 x, y, xsize, ysize);{}
+  page up (x, y, xsize, ysize);{}  IF trennlinie weg{}     THEN erase footnote (w, TRUE){}     ELSE erase footnote (w, FALSE){}  FI;{}  cursor (w, spa, zei);{}  wert{}END PROC boxanswer;{}TEXT PROC boxanswer (WINDOW VAR w, TEXT CONST t, vorgabe,{}                                   INT CONST position):{}  boxanswer (w, t, vorgabe, position, TRUE){}END PROC boxanswer;{}TEXT PROC boxone (WINDOW VAR w, THESAURUS CONST thesaurus,{}                  TEXT CONST text1, text2, BOOL CONST mit reinigung):{}
+  INT VAR spa, zei;{}  get cursor (w, spa, zei);{}  TEXT VAR wert :: one (areax     (w) + 2, areay     (w) + 2,{}                        areaxsize (w) - 4, areaysize (w) - 2,{}                        thesaurus, text1, text2);{}  IF mit reinigung{}     THEN page up (areax     (w) + 2, areay     (w) + 2,{}                   areaxsize (w) - 4, areaysize (w) - 2);{}          erase footnote (w){}  FI;{}  cursor (w, spa, zei);{}  wert{}END PROC boxone;{}TEXT PROC boxanswerone  (WINDOW VAR w, TEXT CONST text, vorgabe,{}
+                         THESAURUS CONST thesaurus, TEXT CONST t1, t2,{}                         BOOL CONST mit reinigung, trennlinie weg):{}  INT VAR x,y, xsize, ysize, spa, zei;{}  get cursor (w, spa, zei);{}  TEXT VAR wert := hole antwort (w, text, vorgabe, 5, TRUE,{}                                 x, y, xsize, ysize);{}  IF wert = ""27"z"{}     THEN lasse auswaehlen{}     ELSE uebernimm den wert{}  FI;{}  cursor (w, spa, zei);{}  wert.{}  lasse auswaehlen:{}    IF mit reinigung{}       THEN wert := boxone (w, thesaurus, t1, t2, TRUE ){}
+       ELSE wert := boxone (w, thesaurus, t1, t2, FALSE){}    FI.{}  uebernimm den wert:{}    IF mit reinigung{}       THEN page up (x, y, xsize, ysize);{}            entferne ggf die trennlinie{}    FI.{}  entferne ggf die trennlinie:{}    IF trennlinie weg{}       THEN erase footnote (w, TRUE){}       ELSE erase footnote (w, FALSE){}    FI.{}END PROC boxanswer one;{}TEXT PROC boxanswerone  (WINDOW VAR w, TEXT CONST text, vorgabe,{}                         THESAURUS CONST thesaurus, TEXT CONST t1, t2,{}
+                         BOOL CONST mit reinigung):{}  boxanswerone (w, text, vorgabe, thesaurus, t1, t2, mit reinigung, TRUE){}END PROC boxanswer one;{}THESAURUS PROC boxsome (WINDOW VAR w, THESAURUS CONST thesaurus,{}                        TEXT CONST text1, text2,{}                        BOOL CONST mit reinigung):{}  INT VAR spa, zei;{}  get cursor (w, spa, zei);{}  THESAURUS VAR wert :: some (areax     (w) + 2, areay     (w) + 2,{}                              areaxsize (w) - 4, areaysize (w) - 2,{}
+                              thesaurus, text1, text2);{}  IF mit reinigung{}     THEN page up (areax     (w) + 2, areay     (w) + 2,{}                   areaxsize (w) - 4, areaysize (w) - 2);{}          erase footnote (w){}  FI;{}  cursor (w, spa, zei);{}  wert{}END PROC boxsome;{}THESAURUS PROC boxanswersome  (WINDOW VAR w, TEXT CONST text, vorgabe,{}                               THESAURUS CONST thesaurus,{}                               TEXT CONST t1, t2,{}                               BOOL CONST mit reinigung, trennlinie weg):{}
+  THESAURUS VAR ergebnis :: empty thesaurus;{}  INT VAR x, y, xsize, ysize, spa, zei;{}  get cursor (w, spa, zei);{}  TEXT VAR wert := hole antwort (w, text, vorgabe, 5, TRUE,{}                                 x, y, xsize, ysize);{}  IF wert = ""27"z"{}     THEN lasse auswaehlen{}     ELSE uebernimm den wert{}  FI;{}  cursor (w, spa, zei);{}  ergebnis.{}  lasse auswaehlen:{}    IF mit reinigung{}       THEN ergebnis := boxsome (w, thesaurus, t1, t2, TRUE ){}       ELSE ergebnis := boxsome (w, thesaurus, t1, t2, FALSE){}
+    FI.{}  uebernimm den wert:{}    IF wert <> niltext{}       THEN insert (ergebnis, wert){}    FI;{}    IF mit reinigung{}       THEN page up (x, y, xsize, ysize);{}            entferne ggf die trennlinie{}    FI.{}  entferne ggf die trennlinie:{}    IF trennlinie weg{}       THEN erase footnote (w, TRUE){}       ELSE erase footnote (w, FALSE){}    FI.{}END PROC boxanswer some;{}THESAURUS PROC boxanswersome  (WINDOW VAR w, TEXT CONST text, vorgabe,{}                               THESAURUS CONST thesaurus,{}
+                               TEXT CONST t1, t2,{}                               BOOL CONST mit reinigung):{}  boxanswersome (w, text, vorgabe, thesaurus, t1, t2, mit reinigung, TRUE){}END PROC boxanswersome;{}PROC out footnote (WINDOW VAR w, BOOL CONST mit trennlinie, TEXT CONST text):{}  INT VAR spa, zei;{}  get cursor (w, spa, zei);{}  IF mit trennlinie{}     THEN cursor (w, 1,  areaysize (w) - 1);{}          areaxsize (w) TIMESOUT waagerecht{}  FI;{}  cursor (w, 1,  areaysize (w));{}  outtext (text, 1, areaxsize (w));{}
+  cursor (w, spa, zei){}END PROC out footnote;{}PROC out footnote (WINDOW VAR w, TEXT CONST t):{}  out footnote (w, TRUE, t){}END PROC out footnote;{}PROC erase footnote (WINDOW VAR w, BOOL CONST auch trennlinie):{}  INT VAR spa, zei;{}  get cursor (w, spa, zei);{}  IF auch trennlinie{}     THEN cursor (w, 1, areaysize (w) - 1);{}          outtext ("", 1, areaxsize (w)){}  FI;{}  cursor (w, 1, areaysize (w));{}  outtext ("", 1, areaxsize (w));{}  cursor (w, spa, zei){}END PROC erase footnote;{}PROC erase footnote (WINDOW VAR w):{}
+  erase footnote (w, TRUE){}END PROC erase footnote;{}PROC schreibe boxtext (WINDOW VAR w, TEXT CONST t,{}                       INT CONST position, zusatzlaenge,{}                                 mindestbreite, mindesthoehe,{}                       INT VAR x, y, xsize, ysize):{}  ermittle boxbreite und boxhoehe;{}  ermittle rahmenwerte;{}  schreibe boxkopf;{}  schreibe boxrumpf.{}  ermittle boxbreite und boxhoehe:{}    TEXT VAR intern :: t + delimiter;{}    entferne fuehrende delimiter;{}    INT VAR  anfang :: 1,{}
+             ende   :: pos (intern, delimiter, anfang) - 1;{}    xsize := 0;{}    ysize := 0;{}    WHILE ende > 0 REP{}      ysize INCR 1;{}      lege ggf boxbreite fest;{}      bestimme neue positionen{}    PER.{}  entferne fuehrende delimiter:{}    WHILE (intern SUB 1) = delimiter REP{}      intern := subtext (intern, 2){}    PER.{}  lege ggf boxbreite fest:{}    IF length (subtext (intern, anfang, ende)) > xsize{}       THEN xsize := length (subtext (intern, anfang, ende)){}    FI.{}  bestimme neue positionen:{}
+    anfang := ende + 2;{}    ende   := pos (intern, delimiter, anfang) - 1.{}  ermittle rahmenwerte:{}    schlage notwendige groessen auf;{}    kill ueberlaengen;{}    lege bildschirmpositionen fest.{}  schlage notwendige groessen auf:{}    IF xsize < mindestbreite{}       THEN xsize := mindestbreite{}    FI;{}    IF ysize < mindesthoehe{}       THEN ysize := mindesthoehe{}    FI;{}    ysize INCR zusatzlaenge;{}    ysize INCR 2;  (* Für den Rahmen *){}    xsize INCR 2.  (* Für den Rahmen *){}  kill ueberlaengen:{}
+    IF ysize > (areaysize (w) - 4){}       THEN ysize := areaysize (w) - 4{}    FI;{}    IF xsize > (areaxsize (w) - 4){}       THEN xsize := areaxsize (w) - 4{}    FI.{}  lege bildschirmpositionen fest:{}    SELECT position OF{}      CASE 1: plazierung links  oben{}      CASE 2: plazierung rechts oben{}      CASE 3: plazierung links  unten{}      CASE 4: plazierung rechts unten{}      OTHERWISE plazierung im zentrum{}    END SELECT.{}  plazierung links oben:{}    x := areax (w) + 2;{}    y := areay (w) + 2.{}
+  plazierung rechts oben:{}    x := areax (w) + areaxsize (w) - xsize - 2;{}    y := areay (w) + 2.{}  plazierung links unten:{}    x := areax (w) + 2;{}    y := areay (w) + areaysize (w) - ysize - 2.{}  plazierung rechts unten:{}    x := areax (w) + areaxsize (w) - xsize - 2;{}    y := areay (w) + areaysize (w) - ysize - 2.{}  plazierung im zentrum:{}    x := areax (w) + ((areaxsize (w) - (xsize + 2)) DIV 2) + 1;{}    y := areay (w) + ((areaysize (w) - ysize)       DIV 2).{}  schreibe boxkopf:{}
+    cursor (x, y);{}    out (ecke oben links);{}    (xsize - 2) TIMESOUT waagerecht;{}    out (ecke oben rechts).{}  schreibe boxrumpf:{}    INT VAR i;{}    intern := t + delimiter;{}    entferne fuehrende delimiter;{}    anfang := 1;{}    ende   := pos (intern, delimiter, anfang) - 1;{}    FOR i FROM y + 1 UPTO y + ysize - zusatzlaenge - 2 REP{}      cursor (x, i);{}      out (senkrecht);{}      outtext (subtext (intern, anfang, ende), 1, xsize - 2);{}      out (senkrecht);{}      anfang := ende + 2;{}
+      ende   := pos (intern, delimiter, anfang) - 1{}    PER{}END PROC schreibe boxtext;{}PROC schreibe boxfuss (WINDOW VAR w,{}                       INT CONST x, y, xsize, ysize, limit):{}  schreibe abschlusszeile;{}  out footnote (w, aussage [1]);{}  cursor in position und warten.{}  schreibe abschlusszeile:{}    cursor (x, y + ysize - 1);{}    out (ecke unten links);{}    (xsize - 2) TIMESOUT waagerecht;{}    out (ecke unten  rechts).{}  cursor in position und warten:{}    cursor parken (w);{}
+    clear buffer;{}    pause (limit){}END PROC schreibe boxfuss;{}PROC cursor parken (WINDOW VAR w):{}  cursor (w, 1, 2){}END PROC cursor parken;{}PROC schreibe box (WINDOW VAR w, TEXT CONST t,{}                   INT CONST position, timelimit,{}                   INT VAR x, y, xsize, ysize):{}  schreibe boxtext (w, t, position, 0, 0, 0, x, y, xsize, ysize);{}  schreibe boxfuss (w, x, y, xsize, ysize, timelimit){}END PROC schreibe box;{}PROC schreibe notizfuss (WINDOW VAR w, INT CONST x, y, xsize, ysize):{}
+  schreibe abschlusszeile;{}  cursor parken (w).{}  schreibe abschlusszeile:{}    cursor (x, y + ysize - 1);{}    out (ecke unten links);{}    (xsize - 2) TIMESOUT waagerecht;{}    out (ecke unten rechts).{}END PROC schreibe notizfuss;{}PROC schreibe notiz (WINDOW VAR w, TEXT CONST t, INT CONST position,{}                     INT VAR x, y, xsize, ysize):{}  schreibe boxtext   (w, t, position, 0, 0, 0, x, y, xsize, ysize);{}  schreibe notizfuss (w, x, y, xsize, ysize){}END PROC schreibe notiz;{}PROC schreibe alternativen (WINDOW VAR w, TEXT CONST t, altzeile, sonst,{}
+                            INT CONST position, BOOL CONST mit abbruch,{}                            INT VAR x, y, xsize, ysize, ergebnis):{}  ROW 10 STRUCT (TEXT alternat, INT anfang, laenge) VAR altliste;{}  normiere alternativen;{}  untersuche alternativen;{}  schreibe boxtext (w, textintern, position, 2, altbreite,{}                    0, x, y, xsize, ysize);{}  schreibe alternativenfuss;{}  lasse auswaehlen;{}  liefere ergebnis.{}  textintern:{}    IF sonst = janeintasten{}       THEN TEXT VAR zwischen;{}
+            zwischen := t;{}            kuerze um folgende blanks;{}            zwischen + "? "{}       ELSE t{}    FI.{}  kuerze um folgende blanks:{}    WHILE (zwischen SUB (length (zwischen))) = blank REP{}      zwischen := subtext (zwischen , 1, length (zwischen) - 1){}    PER.{}  normiere alternativen:{}    TEXT VAR altintern :: altzeile;{}    altintern CAT delimiter.{}  untersuche alternativen:{}    INT VAR altanzahl :: 1, altbreite, first :: - 2, anfang :: 1,{}            ende :: pos (altintern, delimiter, anfang) - 1;{}
+    WHILE ende > 0 AND altanzahl <= 10 REP{}      trage alternative ein;{}      trage alternativenanfang ein;{}      trage alternativenlaenge ein;{}      setze neue positionen fest{}    PER;{}    ermittle gesamtalternativenbreite.{}  trage alternative ein:{}    altliste [altanzahl].alternat :={}                               compress (subtext (altintern, anfang, ende)).{}  trage alternativenanfang ein:{}    first INCR 3;{}    altliste [altanzahl].anfang   := first.{}  trage alternativenlaenge ein:{}
+    altliste [altanzahl].laenge   := length (altliste [altanzahl].alternat);{}    first INCR altliste [altanzahl].laenge.{}  setze neue positionen fest:{}    anfang := ende + 2;{}    ende   := pos (altintern, delimiter, anfang) - 1;{}    altanzahl INCR 1.{}  ermittle gesamtalternativenbreite:{}    altanzahl DECR 1;{}    altbreite :=    altliste [altanzahl].anfang;{}    altbreite INCR (altliste [altanzahl].laenge + 3);{}    IF altbreite > areaxsize (w) - 6{}       THEN LEAVE schreibe alternativen{}
+    FI.{}  schreibe alternativenfuss:{}    schreibe leerzeile;{}    schreibe antwortmoeglichkeiten;{}    schreibe abschlusszeile;{}    IF mit abbruch{}       THEN out footnote (w, aussage [2]){}       ELSE beruecksichtige ja nein hinweis{}    FI.{}  schreibe leerzeile:{}    cursor (x, y + ysize - 3);{}    out (senkrecht);{}    (xsize - 2) TIMESOUT blank;{}    out (senkrecht).{}  schreibe antwortmoeglichkeiten:{}    cursor (x, y + ysize - 2);{}    out (senkrecht);{}    einrueckbreite TIMESOUT blank;{}
+    out (antwortleiste);{}    rest TIMESOUT blank;{}    out (senkrecht).{}  einrueckbreite:{}    (xsize - 2 - length (antwortleiste)) DIV 2.{}  antwortleiste:{}    INT VAR zeiger; TEXT VAR ausgabe :: "";{}    FOR zeiger FROM 1 UPTO altanzahl REP{}      ausgabe CAT altliste [zeiger].alternat;{}      ausgabe CAT "   "{}    PER;{}    compress (ausgabe).{}  rest:{}    xsize - 2 - einrueckbreite - length (antwortleiste).{}  schreibe abschlusszeile:{}    cursor (x, y + ysize - 1);{}    out (ecke unten links);{}
+    (xsize - 2) TIMESOUT waagerecht;{}    out (ecke unten rechts).{}  beruecksichtige ja nein hinweis:{}     IF sonst = janeintasten{}        THEN out footnote (w, aussage [3]){}        ELSE out footnote (w, aussage [4]){}     FI.{}  lasse auswaehlen:{}    INT VAR altzeiger :: 1;{}    stelle erste alternative invers dar;{}    REP{}      hole eingabe;{}      werte eingabe aus und reagiere{}    UNTIL alternative gefunden PER.{}  stelle erste alternative invers dar:{}    cursor (x + einrueckbreite, y + ysize - 2);{}
+    out (mark ein);{}    out (altliste [altzeiger].alternat); out (blank);{}    out (mark aus);{}    cursor (x + einrueckbreite, y + ysize - 2).{}  hole eingabe:{}    TEXT VAR moegliche, eingabe;{}    IF mit abbruch{}       THEN moegliche := rechts links esc  return + sonst{}       ELSE moegliche := rechts links null return + sonst{}    FI;{}    clear buffer;{}    REP{}      inchar (eingabe);{}      piepse bei unzulaessiger eingabe{}    UNTIL pos (moegliche, eingabe) > 0 PER.{}  piepse bei unzulaessiger eingabe:{}
+    IF pos (moegliche, eingabe) = 0 THEN out (piep) FI.{}  werte eingabe aus und reagiere:{}    SELECT pos (moegliche, eingabe) OF{}      CASE 1: zur naechsten alternative{}      CASE 2: zur vorausgehenden alternative{}      CASE 3: esc kommando verarbeiten{}    END SELECT.{}  zur naechsten alternative:{}    loesche aktuelle alternative;{}    ermittle rechte alternative;{}    stelle neue alternative invers dar.{}  zur vorausgehenden alternative:{}    loesche aktuelle alternative;{}    ermittle linke alternative;{}
+    stelle neue alternative invers dar.{}  loesche aktuelle alternative:{}    cursor (alternativenanfang - 1, y + ysize - 2);{}    out (blank);{}    out (altliste [altzeiger].alternat);{}    out (2 * blank).{}  alternativenanfang:{}    x + einrueckbreite + altliste [altzeiger].anfang.{}  ermittle rechte alternative:{}    IF altzeiger = altanzahl{}       THEN altzeiger :=   1{}       ELSE altzeiger INCR 1{}    FI.{}  ermittle linke alternative:{}    IF altzeiger = 1{}       THEN altzeiger := altanzahl{}
+       ELSE altzeiger DECR 1{}    FI.{}  stelle neue alternative invers dar:{}    cursor (alternativenanfang - 1, y + ysize - 2);{}    out (mark ein);{}    out (altliste [altzeiger].alternat); out (blank);{}    out (mark aus);{}    cursor (alternativenanfang - 1, y + ysize - 2).{}  esc kommando verarbeiten:{}    inchar (eingabe);{}    IF eingabe = "h"{}       THEN ergebnis := 0;{}            LEAVE schreibe alternativen{}       ELSE out (piep); eingabe := ""{}    FI.{}  alternative gefunden:{}    pos (moegliche, eingabe) > 3.{}
+  liefere ergebnis:{}    IF pos (moegliche, eingabe) = 4{}       THEN ergebnis := altzeiger{}       ELSE ergebnis := 100 + pos (sonst, eingabe){}    FI.{}END PROC schreibe alternativen;{}BOOL PROC ja (WINDOW VAR w, TEXT CONST t, INT CONST position,{}               INT VAR x, y, xsize, ysize):{}  INT VAR ergebnis;{}  schreibe alternativen (w, t, aussage [7], janeintasten, position,{}                         FALSE, x, y, xsize, ysize, ergebnis);{}  SELECT ergebnis OF{}    CASE 2, 105, 106: FALSE{}    OTHERWISE TRUE{}
+  END SELECT.{}END PROC ja;{}TEXT PROC hole antwort (WINDOW VAR w, TEXT CONST t, vorgabe,{}                        INT CONST position, BOOL CONST mit auswahl,{}                        INT VAR x, y, xsize, ysize):{}  TEXT VAR eingabe :: compress (vorgabe);{}  schreibe boxtext (w, t, position, 2, length (aussage [8]) + 12, 2,{}                    x, y, xsize, ysize);{}  schreibe antwortfuss;{}  clear buffer;{}  REP{}    IF eingabe = "break"{}       THEN eingabe := ""{}    FI;{}    lasse eintragen{}
+  UNTIL eingabe <> "break" PER;{}  liefere ergebnis.{}  schreibe antwortfuss:{}    schreibe leerzeile;{}    schreibe eingabezeile;{}    schreibe abschlusszeile;{}    IF mit auswahl{}       THEN out footnote (w, aussage [5]){}       ELSE out footnote (w, aussage [6]){}    FI.{}  schreibe leerzeile:{}    cursor (x, y + ysize - 3);{}    out (senkrecht);{}    (xsize - 2) TIMESOUT blank;{}    out (senkrecht).{}  schreibe eingabezeile:{}    cursor (x, y + ysize - 2);{}    out (senkrecht);{}    out (aussage [8]);{}
+    (xsize - 2 - length (aussage [8])) TIMESOUT blank;{}    out (senkrecht).{}  schreibe abschlusszeile:{}    cursor (x, y + ysize - 1);{}    out (ecke unten links);{}    (xsize - 2) TIMESOUT waagerecht;{}    out (ecke unten rechts).{}  lasse eintragen:{}    TEXT VAR exit :: "";{}    cursor on;{}    cursor (x + length (aussage [8]) + 1, y + ysize - 2);{}    IF mit auswahl{}       THEN editget (eingabe, maxtextlength, textlaenge, "", "hz", exit){}       ELSE editget (eingabe, maxtextlength, textlaenge, "", "h",  exit){}
+    FI;{}    cursor off;{}    IF exit = ""27"h"{}       THEN eingabe := ""{}    ELIF mit auswahl AND (exit = ""27"z"){}       THEN eingabe := ""27"z"{}    ELSE eingabe := compress (eingabe){}    FI.{}  textlaenge:{}    xsize - 2 - length (aussage [8]).{}  liefere ergebnis:{}    eingabe.{}END PROC hole antwort;{}END PACKET ls dialog 4;{}
+
diff --git a/dialog/ls-DIALOG 5 b/dialog/ls-DIALOG 5
new file mode 100644
index 0000000..1772b99
--- /dev/null
+++ b/dialog/ls-DIALOG 5	
@@ -0,0 +1,118 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                     ls-DIALOG 5                     ** 
+          **                                                     ** 
+          **                     Version 1.2                     ** 
+          **                                                     ** 
+          **                  (Stand: 04.11.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET  ls dialog 5 DEFINES{}       menufootnote, old menufootnote,{}       menuinfo,menualternative,{}       menuyes, menuno, menuone,{}       menusome,menuanswer,{}       menuanswerone, menuanswersome,{}       install menu, handle menu,{}       refresh submenu, deactivate,{}       regenerate menuscreen, activate,{}       write menunotice, erase menunotice,{}       menubasistext, anwendungstext,{}       show menuwindow, menuwindowpage,{}       menuwindowout, menuwindowget,{}       menuwindoweditget, menuwindowedit,{}
+       menuwindowshow, menuwindowline,{}       menuwindowyes, menuwindowno,{}       menuwindowcursor, get menuwindowcursor,{}       remaining menuwindowlines,{}       menuwindowcenter, menuwindowstop,{}       editorinformationen,stdinfoedit,{}       menukartenname, current menuwindow,{}       reset dialog, only intern, ausstieg,{}       direktstart:{}LET systemkuerzel         =  "ls-DIALOG",{}    menutafeltaskname     =  "ls-MENUKARTEN",{}    menutafeltype         =   1954,{}    menutafelpraefix      =  "ls-MENUKARTE:",{}
+    stdmenukartenname     =  "ls-MENUKARTE:Archiv",{}    versionsnummer        =  "1.1",{}    copyright1            =  " (C) 1987/88 Eva Latta-Weber",{}    copyright2            =  " (C) 1988 ERGOS GmbH";{}LET maxmenus              =      6,{}    maxmenutexte          =    300,{}    maxinfotexte          =   2000,{}    maxhauptmenupunkte    =     10,{}    maxuntermenupunkte    =     15,{}    erste untermenuzeile  =      3;{}LET blank                 =    " ",{}    piep                  =  ""7"",{}
+    cleol                 =  ""5"",{}    cleop                 =  ""4"",{}    trennzeilensymbol     =  "###",{}    bleibt leer symbol    =  "***",{}    hauptmenuluecke       =   "  ";{}LET auswahlstring1        =  ""8""2""10""3""13""27"?";{}TYPE MENUPUNKT   = STRUCT (TEXT punktkuerzel,{}                                punktname,{}                                procname,{}                                boxtext,{}                           BOOL aktiv,{}                                angewaehlt),{}
+     EINZELMENU  = STRUCT (INT  belegt,{}                           TEXT ueberschrift,{}                           INT  anfangsposition,{}                                maxlaenge,{}                           ROW  maxuntermenupunkte MENUPUNKT menupunkt,{}                           INT  aktueller untermenupunkt,{}                           TEXT startprozedurname,{}                                leaveprozedurname),{}     MENU        = STRUCT (TEXT menuname,{}                           INT  anzahl hauptmenupunkte,{}
+                           ROW  maxhauptmenupunkte EINZELMENU einzelmenu,{}                           TEXT menueingangsprozedur,{}                                menuausgangsprozedur,{}                                menuinfo,{}                                lizenznummer,{}                                versionsnummer,{}                           INT  hauptmenuzeiger,{}                                untermenuanfang,{}                                untermenuzeiger),{}     INFOTEXT    = STRUCT (INT anzahl infotexte,{}
+                           ROW maxinfotexte TEXT stelle),{}     MENUTEXT    = STRUCT (INT anzahl menutexte,{}                           ROW maxmenutexte TEXT platz),{}     MENULEISTE  = STRUCT (INT belegt, zeigeraktuell, zeigerhintergrund,{}                           ROW maxmenus MENU menu,{}                           MENUTEXT   menutext,{}                           INFOTEXT   infotext);{}BOUND MENULEISTE VAR menuleiste;{}DATASPACE VAR ds;{}WINDOW VAR menuwindow, schreibfenster, editorinfofenster;{}
+INITFLAG VAR in this task       ::         FALSE;{}INT VAR anzahl offener menus    ::             0;{}INT VAR menunotizx, menunotizxsize,{}        menunotizy, menunotizysize,{}        menunotizposition;{}TEXT VAR angekoppelte menutafel ::            "",{}         permanent footnote     ::            "",{}         menunotiztext;{}BOOL VAR menunotiz ist gesetzt  ::         FALSE,{}         nur interne verwendung ::         FALSE,{}         mit ausstieg          ::          FALSE;{}REAL VAR zeitpunkt              ::     clock (1);{}
+ROW 13 TEXT CONST fehlermeldung  :: ROW 13 TEXT : ({}"Die Task '" + menutafeltaskname + "' existiert nicht!",{}"Die Menukarte '",{}"' existiert nicht in der Task '" + menutafeltaskname + "'!",{}"' hat falschen Typ/Bezeichnung (keine 'MENUKARTE')!",{}"Das Menu '",{}"' ist nicht in der angekoppelten Menukarte!",{}"Zu viele geoeffnete Menus ( > 2 )!",{}"Kein Menu geoeffnet!",{}"Menu enthaelt keine Menupunkte!",{}"Menupunkt ist nicht im Menu enthalten!",{}"Kein Text vorhanden!",{}"Zugriff unmöglich!",{}
+"Einschränkung unzulässig!"{});{}ROW 1 TEXT CONST vergleichstext :: ROW 1 TEXT : ({}"gibt es nicht"{});{}ROW 3 TEXT CONST hinweis :: ROW 3 TEXT : ({}"Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q>",{}" Zum Weitermachen bitte irgendeine Taste tippen!",{}"Bitte warten ...  Ich räume auf!"{});{}ROW 3 TEXT CONST infotext :: ROW 3 TEXT : ({}" Für diesen Menupunkt ist (noch) keine "13""13"        Funktion eingetragen!",{}" Möchten Sie dieses Menu tatsächlich verlassen",{}" Leider ist zu diesem Menupunkt "13""13"  kein Info - Text eingetragen!"{}
+ );{}PROC install menu (TEXT CONST menutafelname):{}  installmenu (menutafelname, TRUE){}END PROC install menu;{}PROC install menu (TEXT CONST menutafelname, BOOL CONST mit kennung):{}  TEXT VAR letzter parameter;{}  IF mit kennung{}     THEN zeige menukennung{}  FI;{}  initialisiere menu ggf;{}  IF menutafel noch nicht angekoppelt{}     THEN letzter parameter := std;{}          hole menutafel;{}          kopple menutafel an;{}          last param (letzter parameter){}  FI.{}  initialisiere menu ggf:{}
+    IF NOT initialized (in this task){}       THEN angekoppelte menutafel :=    "";{}            anzahl offener menus   :=     0;{}            menunotiz ist gesetzt  := FALSE;{}            nur interne verwendung := FALSE{}    FI.{}  menutafel noch nicht angekoppelt:{}    menutafelname <> angekoppelte menutafel.{}  hole menutafel:{}    IF NOT exists task (menutafeltaskname){}       THEN bereinige situation; cursor on;{}            errorstop (fehlermeldung [1]){}    FI;{}    disable stop;{}    fetch (menutafelname, /menutafeltaskname);{}
+    IF   is error AND pos (errormessage, vergleichstext [1]) > 0{}         THEN clear error; enable stop;{}              bereinige situation; cursor on;{}              errorstop (fehlermeldung [2] + menutafelname +{}                         fehlermeldung [3]){}    ELIF is error{}         THEN clear error; enable stop;{}              bereinige situation; cursor on;{}              errorstop (errormessage){}   ELSE enable stop{}    FI.{}  kopple menutafel an:{}    IF type (old (menutafelname)) = menutafeltype{}
+       AND pos (menutafelname,menutafelpraefix) = 1{}       THEN forget (ds);{}            ds                     := old (menutafelname);{}            menuleiste             := ds;{}            angekoppelte menutafel := menutafelname;{}            forget (menutafelname, quiet){}       ELSE bereinige situation; cursor on;{}            errorstop ("'" + menutafelname + fehlermeldung [4]){}    FI.{}END PROC install menu;{}PROC only intern (BOOL CONST wert):{}  nur interne verwendung := wert{}END PROC only intern;{}
+PROC ausstieg (BOOL CONST wert):{}  mit ausstieg := wert{}END PROC ausstieg;{}TEXT PROC menukartenname:{}  IF NOT initialized (in this task){}     THEN   angekoppelte menutafel :=    "";{}            anzahl offener menus   :=     0;{}            menunotiz ist gesetzt  := FALSE;{}  FI;{}  angekoppelte menutafel{}END PROC menukartenname;{}PROC handle menu (TEXT CONST menuname):{}  nur interne verwendung := FALSE;{}  mit ausstieg           :=  TRUE;{}  handle menu (menuname, ""){}END PROC handle menu;{}
+PROC handle menu (TEXT CONST menuname, ausstiegsproc):{}  cursor off;{}  IF nur interne verwendung{}     THEN oeffne menu (menuname){}     ELSE biete menu an{}  FI;{}  lasse menupunkte auswaehlen;{}  IF nur interne verwendung{}     THEN do (ausstiegsproc);{}          anzahl offener menus DECR 1;{}          IF anzahl offener menus < 1 THEN erase menunotice FI;{}          menuleiste.zeigeraktuell := menuleiste.zeigerhintergrund;{}          menuwindow := window (1,1,79, 24);{}          nur interne verwendung := FALSE;{}
+          mit ausstieg           := TRUE;{}          cursor on{}     ELSE schliesse menu;{}          leere ggf den bildschirm{}  FI.{}  biete menu an:{}    REAL VAR zwischenzeit :: clock (1) - zeitpunkt;{}    IF zwischenzeit < 2.0{}       THEN pause (20 - int (10.0 * zwischenzeit)){}    FI;{}    oeffne menu (menuname).{}  leere ggf den bildschirm:{}    IF anzahl offener menus < 1{}       THEN erase menunotice;{}            page; cursor on{}    FI.{}  lasse menupunkte auswaehlen:{}    TEXT VAR kuerzelkette :: "";{}
+    starte aktuelle untermenuoperationen;{}    REP{}      cursor in warteposition;{}      ermittle aktuelle kuerzelkette;{}      nimm zeichen auf;{}      interpretiere zeichen;{}    UNTIL menu verlassen gewuenscht PER.{}  nimm zeichen auf:{}    TEXT CONST erlaubte zeichen ::auswahlstring1 + kuerzelkette;{}    TEXT VAR eingabezeichen;{}    INT  VAR zeichenposition;{}    REP{}      inchar (eingabezeichen);{}      zeichenposition := pos (erlaubte zeichen, eingabezeichen);{}      piepse ggf{}    UNTIL zeichenposition > 0 PER.{}
+  piepse ggf:{}    IF zeichenposition = 0 THEN out (piep) FI.{}  menu verlassen gewuenscht:{}    zeichenposition = 6 AND (zweites zeichen = "q").{}  interpretiere zeichen:{}    SELECT zeichenposition OF{}      CASE 1: gehe einen hauptmenupunkt nach links{}      CASE 2: gehe einen hauptmenupunkt nach rechts{}      CASE 3: gehe einen untermenupunkt nach unten{}      CASE 4: gehe einen untermenupunkt nach oben{}      CASE 5: fuehre aktuellen menupunkt aus{}      CASE 6: hole esc sequenz{}      CASE 7: zeige erklaerungstext im menu an{}
+      OTHERWISE werte kuerzeleingabe aus{}    END SELECT.{}  gehe einen hauptmenupunkt nach links:{}    INT VAR anzahl schritte :: 1;{}    beende aktuelle untermenuoperationen;{}    loesche aktuelles untermenu auf bildschirm;{}    loesche alte hauptmenumarkierung;{}    anzahl schritte INCR clear buffer and count (""8"");{}    ermittle linke menuposition;{}    stelle aktuellen hauptmenupunkt invers dar;{}    starte aktuelle untermenuoperationen;{}    schreibe aktuelles untermenu auf bildschirm.{}  gehe einen hauptmenupunkt nach rechts:{}
+    anzahl schritte := 1;{}    beende aktuelle untermenuoperationen;{}    loesche aktuelles untermenu auf bildschirm;{}    loesche alte hauptmenumarkierung;{}    anzahl schritte INCR clear buffer and count (""2"");{}    ermittle rechte menuposition;{}    stelle aktuellen hauptmenupunkt invers dar;{}    starte aktuelle untermenuoperationen;{}    schreibe aktuelles untermenu auf bildschirm.{}  loesche alte hauptmenumarkierung:{}    erase invers (area (menuwindow), startpos, 1, ueberschriftlaenge);{}
+    out          (area (menuwindow), startpos, 1, ueberschrifttext).{}  startpos:{}    aktuelles untermenu.anfangsposition.{}  ueberschriftlaenge:{}    length (ueberschrifttext).{}  ueberschrifttext:{}    aktuelles untermenu.ueberschrift.{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}  ermittle linke menuposition:{}    INT VAR positionszaehler;{}    FOR positionszaehler FROM 1 UPTO anzahl schritte REP{}
+      drehe die menuposition um einen wert runter{}    PER.{}  ermittle rechte menuposition:{}    FOR positionszaehler FROM 1 UPTO anzahl schritte REP{}      drehe die menuposition um einen wert hoch{}    PER.{}  drehe die menuposition um einen wert runter:{}    IF aktuelles menu.hauptmenuzeiger > 1{}       THEN aktuelles menu.hauptmenuzeiger DECR 1{}       ELSE aktuelles menu.hauptmenuzeiger{}                     := aktuelles menu.anzahl hauptmenupunkte{}    FI.{}  drehe die menuposition um einen wert hoch:{}
+    IF aktuelles menu.hauptmenuzeiger{}         < aktuelles menu.anzahl hauptmenupunkte{}       THEN aktuelles menu.hauptmenuzeiger INCR 1{}       ELSE aktuelles menu.hauptmenuzeiger := 1{}    FI.{}  gehe einen untermenupunkt nach unten:{}    INT VAR naechster aktiver := folgender aktiver untermenupunkt;{}    nimm ummarkierung vor.{}  gehe einen untermenupunkt nach oben:{}    naechster aktiver := vorausgehender aktiver untermenupunkt;{}    nimm ummarkierung vor.{}  nimm ummarkierung vor:{}    IF ueberhaupt aktive menupunkte vorhanden{}
+       THEN demarkiere aktuellen untermenupunkt;{}            gehe zum folgenden untermenupunkt;{}            markiere aktuellen untermenupunkt{}    FI.{}  ueberhaupt aktive menupunkte vorhanden:{}    (aktuelles untermenu.belegt > 0) CAND (naechster aktiver > 0).{}  gehe zum folgenden untermenupunkt:{}    aktuelles menu.untermenuzeiger := naechster aktiver.{}  stelle aktuellen hauptmenupunkt invers dar:{}    out invers (area (menuwindow), startpos, 1, ueberschrifttext).{}  fuehre aktuellen menupunkt aus:{}
+    IF nur interne verwendung AND mit ausstieg{}       THEN kennzeichne als angetickt;{}            disable stop;{}            do (ausstiegsproc);{}            do (menuanweisung);{}            aktueller menupunkt.angewaehlt := FALSE;{}            IF is error THEN put error; clear error FI;{}            enable stop;{}            anzahl offener menus DECR 1;{}            menuleiste.zeigeraktuell := menuleiste.zeigerhintergrund;{}            menuwindow := window (1,1,79, 24);{}            nur interne verwendung := FALSE;{}
+            cursor on;{}            LEAVE handle menu{}       ELSE kennzeichne als angetickt;{}            fuehre operation aus (menuanweisung);{}            nimm kennzeichnung zurueck{}    FI.{}  kennzeichne als angetickt:{}    aktueller menupunkt.angewaehlt := TRUE;{}    markiere aktuellen untermenupunkt.{}  nimm kennzeichnung zurueck:{}    aktueller menupunkt.angewaehlt := FALSE;{}    markiere aktuellen untermenupunkt.{}  menuanweisung:{}   compress (aktueller menupunkt.procname).{}  aktueller menupunkt:{}
+    aktuelles untermenu.menupunkt [aktuelles menu.untermenuzeiger].{}  hole esc sequenz:{}    TEXT VAR zweites zeichen;{}    inchar (zweites zeichen);{}    SELECT pos ("q?$", zweites zeichen) OF{}      CASE 1: erfrage abbruch{}      CASE 2: zeige menubedienhinweise{}      CASE 3: gib info aus{}      OTHERWISE out (piep){}    END SELECT.{}  erfrage abbruch:{}    IF menuno (infotext [2], 5){}       THEN zweites zeichen := "n"  (* gleichgültig, nur nicht 'q'  *){}    FI.{}  zeige menubedienhinweise:{}
+    INT VAR gewaehlt;{}    REP{}      gewaehlt := menualternative ( alttext, altwahl, altzusatz, 5, FALSE);{}      erfuelle den wunsch{}    UNTIL ausstieg aus bedienhinweisen gewuenscht PER.{}  alttext:{}    menuleiste.menutext.platz [1].{}  altwahl:{}    menuleiste.menutext.platz [2].{}  altzusatz:{}    menuleiste.menutext.platz [3].{}  erfuelle den wunsch:{}    SELECT gewaehlt OF{}      CASE 1,101,106: menuinfo (menuleiste.menutext.platz [4], 5, maxint){}      CASE 2,102,107: menuinfo (menuleiste.menutext.platz [5], 5, maxint){}
+      CASE 3,103,108: menuinfo (menuleiste.menutext.platz [6], 5, maxint){}      CASE 4,104,109: menuinfo (menuleiste.menutext.platz [7], 5, maxint){}    END SELECT.{}  ausstieg aus bedienhinweisen gewuenscht:{}    gewaehlt = 5 OR gewaehlt = 105 OR gewaehlt = 110.{}  gib info aus:{}    menuinfo (menuleiste.menutext.platz [20]).{}  zeige erklaerungstext im menu an:{}    IF compress (erklaerungstext) = ""{}       THEN menuinfo (infotext [3]){}       ELSE menuinfo (erklaerungstext){}    FI.{}  erklaerungstext:{}
+    aktueller menupunkt.boxtext.{}  werte kuerzeleingabe aus:{}    naechster aktiver := pos (kuerzelkette, eingabezeichen);{}    nimm ummarkierung vor;{}    fuehre aktuellen menupunkt aus.{}  starte aktuelle untermenuoperationen:{}    ermittle aktuelle kuerzelkette;{}    IF startoperation <> ""{}       THEN fuehre operation aus (startoperation){}    FI.{}  startoperation:{}    compress (aktuelles untermenu.startprozedurname).{}  ermittle aktuelle kuerzelkette:{}    kuerzelkette := "";{}    INT VAR kuerzelzeiger;{}
+    FOR kuerzelzeiger FROM 1 UPTO aktuelles untermenu.belegt REP{}      IF compress (aktuelles punktkuerzel) = ""{}         THEN kuerzelkette CAT ""0""  { beliebiger Code der Länge 1 }{}         ELSE haenge ggf kuerzel an{}      FI{}    PER.{}  aktuelles punktkuerzel:{}    aktuelles untermenu.menupunkt [kuerzelzeiger].punktkuerzel.{}  haenge ggf kuerzel an:{}    IF betrachteter punkt ist aktiv{}       THEN kuerzelkette CAT aktuelles punktkuerzel{}       ELSE kuerzelkette CAT ""0""{}    FI.{}  betrachteter punkt ist aktiv:{}
+    aktuelles untermenu.menupunkt [kuerzelzeiger].aktiv.{}  beende aktuelle untermenuoperationen:{}    kuerzelkette := "".{}END PROC handle menu;{}PROC oeffne menu (TEXT CONST menuname):{}  cursor off;{}  suche eingestelltes menu;{}  IF menu existiert nicht{}     THEN cursor on;{}          page;{}          errorstop (fehlermeldung [5] + menuname + fehlermeldung [6]){}  FI;{}  anzahl offener menus INCR 1;{}  ggf neue seite aufschlagen;{}  ueberpruefe anzahl offener menus;{}  lege ggf aktuelles menu auf eis;{}
+  initialisiere den menubildschirm;{}  IF NOT nur interne verwendung{}     THEN aktuelles menu.hauptmenuzeiger     := 1;{}          aktuelles menu.untermenuzeiger     := 0;{}          aktuelles menu.untermenuanfang     := 0;{}  FI;{}  show menu;{}  fuehre ggf menueingangsprozedur aus;{}  zeige ggf menukenndaten an.{}  suche eingestelltes menu:{}    INT VAR i, suchzeiger;{}    BOOL VAR gefunden :: FALSE;{}    FOR i FROM 1 UPTO menuleiste.belegt REP{}      IF menuleiste.menu [i].menuname = menuname{}
+         THEN gefunden   := TRUE;{}              suchzeiger := i;{}      FI{}    UNTIL menuleiste.menu [i].menuname = menuname PER.{}  menu existiert nicht:{}    NOT gefunden.{}  ueberpruefe anzahl offener menus:{}    IF anzahl offener menus > 2{}       THEN anzahl offener menus := 0; cursor on;{}            errorstop (fehlermeldung [7]){}    FI.{}  lege ggf aktuelles menu auf eis:{}    IF anzahl offener menus = 2{}       THEN menuleiste.zeigerhintergrund := menuleiste.zeigeraktuell{}    FI;{}    menuleiste.zeigeraktuell := suchzeiger.{}
+  initialisiere den menubildschirm:{}    IF anzahl offener menus = 2{}       THEN menuwindow := window (6, 4, 73, 20){}       ELSE menuwindow := window (1, 1, 79, 24);{}    FI.{}  fuehre ggf menueingangsprozedur aus:{}    IF aktuelles menu.menueingangsprozedur <> ""{}       THEN fuehre operation aus (aktuelles menu.menueingangsprozedur){}    FI.{}  ggf neue seite aufschlagen:{}    IF anzahl offener menus = 1 THEN page FI.{}  zeige ggf menukenndaten an:{}    IF anzahl offener menus = 1  AND aktuelles menu.menuinfo <> bleibt leer symbol{}
+       THEN write menunotice (vollstaendiger infotext, 4);{}            pause (100);{}            erase menunotice{}    FI.{}  vollstaendiger infotext:{}    aktuelles menu.menuinfo +{}    aktuelles menu.lizenznummer +{}    aktuelles menu.versionsnummer.{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}END PROC oeffne menu;{}PROC show menu:{}  ueberpruefe menudaten;{}  stelle hauptmenuleiste zusammen;{}  zeige hauptmenu an;{}  stelle aktuellen hauptmenupunkt invers dar;{}  schreibe aktuelles untermenu auf bildschirm;{}
+  zeige informationszeile an.{}  ueberpruefe menudaten:{}    IF   anzahl offener menus = 0{}         THEN errorstop (fehlermeldung [8]){}    ELIF aktuelles menu.anzahl hauptmenupunkte < 1{}         THEN errorstop (fehlermeldung [9]){}    FI.{}  stelle hauptmenuleiste zusammen:{}    TEXT VAR hauptmenuzeile :: "";{}    INT VAR zeiger;{}    hauptmenuzeile CAT aktuelles menu.menuname;{}    hauptmenuzeile CAT ":";{}    FOR zeiger FROM 1 UPTO aktuelles menu.anzahl hauptmenupunkte REP{}      haenge hauptmenupunkt an{}
+    PER.{}  haenge hauptmenupunkt an:{}    hauptmenuzeile CAT hauptmenuluecke;{}    hauptmenuzeile CAT hauptmenupunktname.{}  hauptmenupunktname:{}    aktuelles menu.einzelmenu [zeiger].ueberschrift.{}  zeige hauptmenu an:{}    page (menuwindow, TRUE);{}    out menuframe (area (menuwindow));{}    cursor (menuwindow, 1, 1);{}    out (menuwindow, hauptmenuzeile).{}  stelle aktuellen hauptmenupunkt invers dar:{}    cursor (menuwindow, startposition, 1);{}    out (menuwindow, invers (ueberschrifttext)).{}
+  startposition:{}    aktuelles untermenu.anfangsposition - 1.{}  ueberschrifttext:{}    aktuelles untermenu.ueberschrift.{}  zeige informationszeile an:{}    write permanent footnote (hinweis [1]).{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC show menu;{}PROC schreibe aktuelles untermenu auf bildschirm:{}  ermittle linke obere ecke des untermenukastens;{}  wirf untermenu aus;{}
+  show menunotice;{}  cursor in warteposition.{}  ermittle linke obere ecke des untermenukastens:{}    aktuelles menu.untermenuanfang := menumitte - halbe menubreite;{}    achte auf randextrema.{}  menumitte:{}    startposition + (length (ueberschrifttext) DIV 2) - 1.{}  startposition:{}    aktuelles untermenu.anfangsposition.{}  ueberschrifttext:{}    aktuelles untermenu.ueberschrift.{}  halbe menubreite:{}    aktuelles untermenu.maxlaenge DIV 2.{}  achte auf randextrema:{}    gleiche ggf linken  rand aus;{}
+    gleiche ggf rechten rand aus.{}  gleiche ggf linken rand aus:{}    IF aktuelles menu.untermenuanfang < 4{}       THEN aktuelles menu.untermenuanfang := 4{}    FI.{}  gleiche ggf rechten rand aus:{}    IF (aktuelles menu.untermenuanfang + aktuelles untermenu.maxlaenge) >{}       (areaxsize (menuwindow) - 3){}       THEN aktuelles menu.untermenuanfang{}               := areaxsize (menuwindow) - aktuelles untermenu.maxlaenge - 3{}    FI.{} wirf untermenu aus:{}    IF aktuelles menu.untermenuzeiger = 0{}
+       THEN aktuelles menu.untermenuzeiger := folgender aktiver untermenupunkt{}    FI;{}    wirf untermenukopfzeile aus;{}    wirf untermenurumpf aus;{}    wirf untermenufusszeile aus;{}    markiere aktuellen untermenupunkt.{}  wirf untermenukopfzeile aus:{}    cursor (menuwindow, spalte, anfangszeile);{}    out (balken oben); striche; out (balken oben).{}  wirf untermenufusszeile aus:{}    cursor (menuwindow, spalte, endezeile);{}    out (ecke unten links); striche; out (ecke unten rechts).{}  spalte:{}
+    aktuelles menu.untermenuanfang - 3.{}  anfangszeile:{}    erste untermenuzeile - 1.{}  endezeile:{}    erste untermenuzeile + aktuelles untermenu.belegt.{}  striche:{}    (aktuelles untermenu.maxlaenge + 5) TIMESOUT waagerecht.{}  wirf untermenurumpf aus:{}    INT VAR laufvar;{}    INT CONST aktuelle punktlaenge :: aktuelles untermenu.maxlaenge + 1;{}    FOR laufvar FROM 1 UPTO aktuelles untermenu.belegt REP{}      wirf eine einzelne menuzeile aus{}    PER.{}  wirf eine einzelne menuzeile aus:{}
+    out with beam (area (menuwindow), menuspalte, menuzeile,{}                   aktueller punktname, laenge).{}  menuspalte:{}    aktuelles menu.untermenuanfang.{}  menuzeile:{}    erste untermenuzeile + laufvar - 1.{}  aktueller punktname:{}    untermenubezeichnung (laufvar).{}  laenge:{}    aktuelle punktlaenge.{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC schreibe aktuelles untermenu auf bildschirm;{}
+PROC loesche aktuelles untermenu auf bildschirm:{}  beende aktuelle untermenuoperationen;{}  loesche untermenu auf bildschirm;{}  schreibe balken wieder hin;{}  aktuelles menu.untermenuzeiger := 1.{}  beende aktuelle untermenuoperationen:{}    IF leaveoperation <> ""{}       THEN fuehre operation aus (leaveoperation){}    FI.{}  leaveoperation:{}    compress (aktuelles untermenu.leaveprozedurname).{}  loesche untermenu auf bildschirm:{}    INT VAR laufvar;{}    FOR laufvar FROM aktuelles untermenu.belegt + 1 DOWNTO 1 REP{}
+      loesche eine einzelne menuzeile{}    PER.{}  loesche eine einzelne menuzeile:{}    erase with beam (area (menuwindow), menuspalte, menuzeile, laenge).{}  menuspalte:{}    aktuelles menu.untermenuanfang.{}  menuzeile:{}    erste untermenuzeile + laufvar - 1.{}  laenge:{}    aktuelles untermenu.maxlaenge + 1.{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}  schreibe balken wieder hin:{}
+    cursor (menuwindow, spalte, anfangszeile);{}    (aktuelles untermenu.maxlaenge + 7) TIMESOUT waagerecht.{}  spalte:{}    aktuelles menu.untermenuanfang - 3.{}  anfangszeile:{}    erste untermenuzeile - 1.{}END PROC loesche aktuelles untermenu auf bildschirm;{}PROC markiere aktuellen untermenupunkt:{}  IF aktuelles menu.untermenuzeiger <> 0{}     THEN laufe ggf zum naechsten aktiven menupunkt;{}          out invers with beam (area (menuwindow), menuspalte, menuzeile,{}                                aktueller punktname, laenge){}
+  FI.{}  laufe ggf zum naechsten aktiven menupunkt:{}    IF NOT aktuelles untermenu.menupunkt [aktuelles menu.untermenuzeiger].aktiv{}       THEN aktuelles menu.untermenuzeiger := folgender aktiver untermenupunkt{}    FI.{}  menuspalte:{}    aktuelles menu.untermenuanfang.{}  menuzeile:{}    erste untermenuzeile - 1 + aktuelles menu.untermenuzeiger.{}  aktueller punktname:{}    untermenubezeichnung (aktuelles menu.untermenuzeiger).{}  laenge:{}    aktuelles untermenu.maxlaenge + 1.{}  aktuelles menu:{}
+    menuleiste.menu [menuleiste.zeigeraktuell].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC markiere aktuellen untermenupunkt;{}PROC demarkiere aktuellen untermenupunkt:{}  IF aktuelles menu.untermenuzeiger <> 0{}     THEN erase invers (area (menuwindow), menuspalte, menuzeile, laenge);{}          out (area (menuwindow), menuspalte, menuzeile,{}                                  aktueller punktname, laenge){}  FI.{}  menuspalte:{}    aktuelles menu.untermenuanfang.{}
+  menuzeile:{}    erste untermenuzeile - 1 + aktuelles menu.untermenuzeiger.{}  aktueller punktname:{}    untermenubezeichnung (aktuelles menu.untermenuzeiger).{}  laenge:{}    aktuelles untermenu.maxlaenge + 1.{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC demarkiere aktuellen untermenupunkt;{}INT PROC folgender aktiver untermenupunkt:{}  INT VAR anzahl aktiver menupunkte :: 0;{}
+  untersuche anzahl aktiver menupunkte;{}  IF   kein aktiver menupunkt vorhanden{}       THEN 0{}  ELIF nur ein aktiver menupunkt vorhanden{}       THEN liefere einzigen aktiven menupunkt{}  ELSE liefere naechsten aktiven menupunkt{}  FI.{}  untersuche anzahl aktiver menupunkte:{}    INT VAR zaehler, position;{}    FOR zaehler FROM 1 UPTO aktuelles untermenu.belegt REP{}      IF aktuelles untermenu.menupunkt [zaehler].aktiv{}         THEN anzahl aktiver menupunkte INCR 1;{}              position := zaehler{}
+      FI{}    UNTIL anzahl aktiver menupunkte > 1 PER.{}  kein aktiver menupunkt vorhanden:{}    anzahl aktiver menupunkte = 0.{}  nur ein aktiver menupunkt vorhanden:{}    anzahl aktiver menupunkte = 1.{}  liefere einzigen aktiven menupunkt:{}    position.{}  liefere naechsten aktiven menupunkt:{}    INT VAR interner zeiger;{}    stelle internen zeiger auf den naechsten menupunkt;{}    WHILE NOT punkt ist aktiv REP{}      untersuche naechsten menupunkt{}    PER;{}    ergebnis.{}    stelle internen zeiger auf den naechsten menupunkt:{}
+      IF aktuelles menu.untermenuzeiger = letzter untermenupunkt{}         THEN interner zeiger := 1{}         ELSE interner zeiger := aktuelles menu.untermenuzeiger + 1{}      FI.{}    letzter untermenupunkt:{}      aktuelles untermenu.belegt.{}    punkt ist aktiv:{}      aktuelles untermenu.menupunkt [interner zeiger].aktiv.{}    untersuche naechsten menupunkt:{}      IF interner zeiger = letzter untermenupunkt{}         THEN interner zeiger := 1{}         ELSE interner zeiger INCR 1{}      FI.{}
+    ergebnis:{}      interner zeiger.{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC folgender aktiver untermenupunkt;{}INT PROC vorausgehender aktiver untermenupunkt:{}  INT VAR anzahl aktiver menupunkte :: 0;{}  untersuche anzahl aktiver menupunkte;{}  IF   kein aktiver menupunkt vorhanden{}       THEN 0{}  ELIF nur ein aktiver menupunkt vorhanden{}       THEN liefere einzigen aktiven menupunkt{}
+  ELSE liefere vorausgehenden aktiven menupunkt{}  FI.{}  untersuche anzahl aktiver menupunkte:{}    INT VAR zaehler, position;{}    FOR zaehler FROM 1 UPTO aktuelles untermenu.belegt REP{}      IF aktuelles untermenu.menupunkt [zaehler].aktiv{}         THEN anzahl aktiver menupunkte INCR 1;{}              position := zaehler{}      FI{}    UNTIL anzahl aktiver menupunkte > 1 PER.{}  kein aktiver menupunkt vorhanden:{}    anzahl aktiver menupunkte = 0.{}  nur ein aktiver menupunkt vorhanden:{}    anzahl aktiver menupunkte = 1.{}
+  liefere einzigen aktiven menupunkt:{}    position.{}  liefere vorausgehenden aktiven menupunkt:{}    INT VAR interner zeiger;{}    stelle internen zeiger auf vorausgehenden menupunkt;{}    WHILE NOT punkt ist aktiv REP{}      untersuche vorausgehenden menupunkt{}    PER;{}    ergebnis.{}  stelle internen zeiger auf vorausgehenden menupunkt:{}    IF aktuelles menu.untermenuzeiger <= 1{}       THEN interner zeiger := letzter untermenupunkt{}       ELSE interner zeiger := aktuelles menu.untermenuzeiger - 1{}
+    FI.{}  letzter untermenupunkt:{}    aktuelles untermenu.belegt.{}  punkt ist aktiv:{}    aktuelles untermenu.menupunkt [interner zeiger].aktiv.{}  untersuche vorausgehenden menupunkt:{}    IF interner zeiger = 1{}       THEN interner zeiger := letzter untermenupunkt{}       ELSE interner zeiger DECR 1{}    FI.{}  ergebnis:{}    interner zeiger.{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}
+END PROC vorausgehender aktiver untermenupunkt;{}PROC cursor in warteposition:{}  cursor (areax (menuwindow), areay (menuwindow) + 1){}END PROC cursor in warteposition;{}TEXT PROC untermenubezeichnung (INT CONST position):{}  TEXT VAR bezeichnung :: "";{}  bezeichnung CAT kennzeichnung;{}  bezeichnung CAT punktkennung;{}  bezeichnung.{}  kennzeichnung:{}    IF        aktueller menupunkt.aktiv{}         AND  aktueller menupunkt.angewaehlt{}              THEN "*"{}    ELIF      aktueller menupunkt.aktiv{}
+         AND  aktueller menupunkt.punktkuerzel <> ""{}              THEN aktueller menupunkt.punktkuerzel{}    ELIF      aktueller menupunkt.aktiv{}         AND  aktueller menupunkt.punktkuerzel = ""{}              THEN blank{}    ELSE      "-"{}    FI.{}    punktkennung:{}      IF menupunkt ist trennzeile{}         THEN strichellinie{}         ELSE aktueller menupunkt.punktname{}      FI.{}    menupunkt ist trennzeile:{}      aktueller menupunkt.punktname = (blank + trennzeilensymbol).{}    strichellinie:{}
+      (aktuelles untermenu.maxlaenge + 1) * "-".{}    aktueller menupunkt:{}      aktuelles untermenu.menupunkt [position].{}    aktuelles menu:{}      menuleiste.menu [menuleiste.zeigeraktuell].{}    aktuelles untermenu:{}      aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC untermenubezeichnung;{}PROC fuehre operation aus (TEXT CONST operation):{}  disable stop;{}  IF operation = ""{}     THEN menuinfo (infotext [1]);{}          LEAVE fuehre operation aus{}  FI;{}  do (operation);{}
+  IF is error{}     THEN menuinfo (errormessage, 5);{}          clear error{}  FI;{}  old menufootnote;{}  enable stop;{}  cursor off{}END PROC fuehre operation aus;{}PROC veraendere aktivierung (TEXT CONST unterpunkt, BOOL CONST eintrag):{}  INT VAR unterpunktposition :: 0, zeiger;{}  suche unterpunkt;{}  aendere aktivierung.{}  suche unterpunkt:{}    FOR zeiger FROM 1 UPTO untermenuende REP{}      IF untermenupunkt = blank + compress (unterpunkt){}         THEN unterpunktposition := zeiger;{}              LEAVE suche unterpunkt{}
+      FI{}    PER;{}    LEAVE veraendere aktivierung.{}  untermenuende:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].belegt.{}  untermenupunkt:{}    aktuelles untermenu.menupunkt [zeiger].punktname.{}  aendere aktivierung:{}    aktuelles untermenu.menupunkt [unterpunktposition].aktiv := eintrag.{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC veraendere aktivierung;{}
+PROC veraendere aktivierung (INT CONST punktnummer, BOOL CONST eintrag):{}  IF punktnummer >= 1 AND punktnummer <= untermenuende{}     THEN aktuelles untermenu.menupunkt [punktnummer].aktiv := eintrag{}  FI.{}  untermenuende:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].belegt.{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC veraendere aktivierung;{}PROC veraendere anwahl (TEXT CONST unterpunkt, BOOL CONST eintrag):{}
+  INT VAR unterpunktposition :: 0, zeiger;{}  suche unterpunkt;{}  aendere anwahl.{}  suche unterpunkt:{}    FOR zeiger FROM 1 UPTO untermenuende REP{}      IF untermenupunkt = blank + compress (unterpunkt){}         THEN unterpunktposition := zeiger;{}              LEAVE suche unterpunkt{}      FI{}    PER;{}    enable stop;{}    errorstop (fehlermeldung [10]).{}  untermenuende:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].belegt.{}  untermenupunkt:{}    aktuelles untermenu.menupunkt [zeiger].punktname.{}
+  aendere anwahl:{}    aktuelles untermenu.menupunkt [unterpunktposition].angewaehlt := eintrag.{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [aktuelles menu.hauptmenuzeiger].{}END PROC veraendere anwahl;{}PROC activate (TEXT CONST unterpunkt):{}  enable stop;{}  veraendere aktivierung (unterpunkt, TRUE){}END PROC activate;{}PROC activate (INT CONST punktnummer):{}  enable stop;{}  veraendere aktivierung (punktnummer, TRUE){}
+END PROC activate;{}PROC deactivate (TEXT CONST unterpunkt):{}  enable stop;{}  veraendere aktivierung (unterpunkt, FALSE){}END PROC deactivate;{}PROC deactivate (INT CONST punktnummer):{}  enable stop;{}  veraendere aktivierung (punktnummer, FALSE){}END PROC deactivate;{}PROC select (TEXT CONST unterpunkt):{}  enable stop;{}  veraendere anwahl (unterpunkt, TRUE){}END PROC select;{}PROC deselect (TEXT CONST unterpunkt):{}  enable stop;{}  veraendere anwahl (unterpunkt, FALSE){}END PROC deselect;{}
+PROC schliesse menu:{}  IF aktuelles menu.menuausgangsprozedur <> ""{}     THEN menufootnote (hinweis [3]);{}          fuehre operation aus (aktuelles menu.menuausgangsprozedur){}  FI;{}  anzahl offener menus DECR 1;{}  IF anzahl offener menus = 1{}     THEN aktiviere das auf eis gelegte menu{}  FI.{}  aktiviere das auf eis gelegte menu:{}    menuleiste.zeigeraktuell := menuleiste.zeigerhintergrund;{}    menuwindow := window (1, 1, 79, 24);{}    show menu.{}  aktuelles menu:{}    menuleiste.menu [menuleiste.zeigeraktuell].{}
+END PROC schliesse menu;{}PROC refresh submenu:{}  schreibe aktuelles untermenu auf bildschirm;{}  show menunotice;{}END PROC refresh submenu;{}PROC regenerate menuscreen:{}  IF   anzahl offener menus = 0{}       THEN errorstop (fehlermeldung [8]){}  ELIF anzahl offener menus = 1{}       THEN page;{}            show menu;{}            show menunotice{}  ELSE zeige erstes menu an;{}       zeige zweites menu an;{}       show menunotice{}  FI.{}  zeige erstes menu an:{}    INT VAR menuzeiger :: menuleiste.zeigeraktuell;{}
+    menuleiste.zeigeraktuell := menuleiste.zeigerhintergrund;{}    menuwindow := window (1, 1, 79, 24);{}    anzahl offener menus := 1;{}    show menu.{}  zeige zweites menu an:{}    menuleiste.zeigeraktuell := menuzeiger;{}    menuwindow := window (6, 4, 73, 20);{}    anzahl offener menus := 2;{}    show menu.{}END PROC regenerate menuscreen;{}PROC menuinfo (TEXT CONST t, INT CONST position, timelimit):{}  boxinfo (menuwindow, t, position, timelimit, FALSE);{}  schreibe aktuelles untermenu auf bildschirm;{}
+  old menufootnote{}END PROC menuinfo;{}PROC menuinfo (TEXT CONST t, INT CONST position):{}  menuinfo (t, position, maxint){}END PROC menuinfo;{}PROC menuinfo (TEXT CONST t):{}  menuinfo (t, 5, maxint){}END PROC menuinfo;{}INT PROC menualternative (TEXT CONST t, auswahlliste, zusatztasten,{}                          INT CONST position, BOOL CONST mit abbruch):{}  INT VAR ergebnis :=  boxalternative (menuwindow, t, auswahlliste,{}                       zusatztasten, position, mit abbruch, FALSE);{}
+  schreibe aktuelles untermenu auf bildschirm;{}  old menufootnote;{}  ergebnis{}END PROC menualternative;{}BOOL PROC menuyes (TEXT CONST frage, INT CONST position):{}  BOOL VAR wert := boxyes (menuwindow, frage, position, FALSE);{}  schreibe aktuelles untermenu auf bildschirm;{}  old menufootnote;{}  wert{}END PROC menuyes;{}BOOL PROC menuno (TEXT CONST frage, INT CONST position):{}  NOT menuyes (frage, position){}END PROC menuno;{}TEXT PROC menuone (THESAURUS CONST thes, TEXT CONST t1, t2,{}                   BOOL CONST mit reinigung):{}
+  TEXT CONST wert :: boxone (menuwindow, thes, t1, t2, mit reinigung);{}  IF mit reinigung{}     THEN schreibe aktuelles untermenu auf bildschirm;{}          old menufootnote{}  FI;{}  wert{}END PROC menuone;{}THESAURUS PROC menusome (THESAURUS CONST thes, TEXT CONST t1, t2,{}                         BOOL CONST mit reinigung):{}  THESAURUS CONST thesaurus :: boxsome (menuwindow, thes, t1, t2,{}                                        mit reinigung);{}  IF mit reinigung{}     THEN schreibe aktuelles untermenu auf bildschirm;{}
+          old menufootnote{}  FI;{}  thesaurus{}END PROC menusome;{}TEXT PROC menuanswer (TEXT CONST t, vorgabe, INT CONST position):{}  TEXT VAR wert :: boxanswer (menuwindow, t, vorgabe, position, FALSE);{}  schreibe aktuelles untermenu auf bildschirm;{}  old menufootnote;{}  wert{}END PROC menuanswer;{}TEXT PROC menuanswerone (TEXT CONST t, vorgabe, THESAURUS CONST thes,{}                          TEXT CONST t1, t2, BOOL CONST mit reinigung):{}  TEXT VAR wert :: boxanswerone (menuwindow, t, vorgabe, thes, t1, t2,{}
+                                             mit reinigung, FALSE){}  IF mit reinigung{}     THEN schreibe aktuelles untermenu auf bildschirm;{}          old menufootnote{}  FI;{}  wert{}END PROC menuanswer one;{}THESAURUS PROC menuanswersome (TEXT CONST t, vorgabe, THESAURUS CONST thes,{}                               TEXT CONST t1, t2, BOOL CONST mit reinigung):{}  THESAURUS VAR wert :: boxanswersome (menuwindow, t, vorgabe,{}                                       thes, t1, t2, mit reinigung, FALSE){}
+  IF mit reinigung{}     THEN schreibe aktuelles untermenu auf bildschirm;{}          old menufootnote{}  FI;{}  wert{}END PROC menuanswersome;{}PROC menufootnote (TEXT CONST t):{}  cursor (menuwindow, 1, areaysize (menuwindow) - 1);{}  areaxsize (menuwindow) TIMESOUT waagerecht;{}  cursor (menuwindow, 1, areaysize (menuwindow));{}  outtext (t, 1, areaxsize (menuwindow)){}END PROC menufootnote;{}PROC old menufootnote:{}  menufootnote (permanent footnote){}END PROC old menufootnote;{}TEXT PROC menubasistext (INT CONST nummer):{}
+  IF   nummer <= 20{}       THEN fehlermeldung [12]{}  ELIF nummer > menuleiste.menutext.anzahl menutexte{}       THEN fehlermeldung [11]{}  ELSE menuleiste.menutext.platz [nummer]{}  FI{}END PROC menubasistext;{}TEXT PROC anwendungstext (INT CONST nummer):{}  IF nummer > menuleiste.infotext.anzahl infotexte{}     THEN fehlermeldung [11]{}     ELSE menuleiste.infotext.stelle [nummer]{}  FI{}END PROC anwendungstext;{}PROC zeige menukennung:{}  IF anzahl offener menus = 0{}     THEN zeige angaben und emblem;{}
+  FI.{}  zeige angaben und emblem:{}    ROW 5 WINDOW VAR w;{}    w [ 1] := window (40,  3, 30, 9);{}    w [ 2] := window (36,  5, 30, 9);{}    w [ 3] := window (30,  7, 30, 9);{}    w [ 4] := window (22,  9, 30, 9);{}    w [ 5] := window (12, 11, 30, 9);{}    page;{}    show (w [1]); out (w [1], center (w [1], invers (systemkuerzel)));{}    show (w [2]); out (w [2], " Version " + versionsnummer);{}    show (w [3]); out (w [3], copyright1);{}    show (w [4]); out (w [4], copyright2);{}    show (w [5]);{}
+    cursor (w [5], 1, 2);out (w [5], "    lll        sssssssss  ");{}    cursor (w [5], 1, 3);out (w [5], "    lll       sss     sss ");{}    cursor (w [5], 1, 4);out (w [5], "    lll       sss         ");{}    cursor (w [5], 1, 5);out (w [5], "    lll        sssssssss  ");{}    cursor (w [5], 1, 6);out (w [5], "    lll               sss ");{}    cursor (w [5], 1, 7);out (w [5], "    lll latta soft    sss ");{}    cursor (w [5], 1, 8);out (w [5], "     lllllllll sssssssss  ");{}    cursor (79, 24);{}
+    zeitpunkt := clock (1);{}END PROC zeige menukennung;{}PROC reset dialog:{} angekoppelte menutafel := "";{} anzahl offener menus   :=  0{}END PROC reset dialog;{}PROC write permanent footnote (TEXT CONST t):{}  permanent footnote := t;{}  cursor (menuwindow, 1, areaysize (menuwindow));{}  outtext (t, 1, areaxsize (menuwindow)){}END PROC write permanent footnote;{}PROC write menunotice (TEXT CONST t, INT CONST position):{}  erase menunotice;{}  boxnotice (menuwindow, t, position, menunotizx,     menunotizy,{}
+                                      menunotizxsize, menunotizysize);{}  menunotiztext         := t;{}  menunotizposition     := position;{}  menunotiz ist gesetzt := TRUE{}END PROC write menunotice;{}PROC show menunotice:{}  IF menunotiz ist gesetzt{}     THEN boxnotice (menuwindow, menunotiztext, menunotizposition,{}                     menunotizx, menunotizy, menunotizxsize, menunotizysize);{}  FI{}END PROC show menunotice;{}PROC erase menunotice:{}  INT VAR spa, zei;{}  get cursor (spa, zei);{}
+  IF menunotiz ist gesetzt{}     THEN page up (menunotizx, menunotizy, menunotizxsize, menunotizysize);{}          menunotiz ist gesetzt := FALSE;{}          cursor (spa, zei){}  FI{}END PROC erase menunotice;{}PROC initialize menuwindow:{}  schreibfenster := window (areax     (menuwindow) + 1,{}                            areay     (menuwindow) + 3,{}                            areaxsize (menuwindow) - 2,{}                            areaysize (menuwindow) - 4){}END PROC initialize menuwindow;{}
+PROC show menuwindow:{}  initialize menuwindow;{}  show (schreibfenster);{}END PROC show menuwindow;{}PROC menuwindow page:{}  initialize menuwindow;{}  page (schreibfenster){}END PROC menuwindow page;{}PROC menuwindowout (TEXT CONST text):{}  out (schreibfenster, text){}END PROC menuwindow out;{}PROC menuwindowget (TEXT VAR text):{}  get (schreibfenster, text){}END PROC menuwindowget;{}PROC menuwindoweditget (TEXT VAR text):{}  editget (schreibfenster, text){}END PROC menuwindoweditget;{}PROC menuwindowedit (TEXT CONST dateiname):{}
+  initialize menuwindow;{}  edit (schreibfenster, dateiname){}END PROC menuwindowedit;{}PROC menuwindowedit (FILE VAR f):{}  initialize menuwindow;{}  edit (schreibfenster, f){}END PROC menuwindowedit;{}PROC menuwindowshow (TEXT CONST dateiname):{}  initialize menuwindow;{}  show (schreibfenster, dateiname){}END PROC menuwindowshow;{}PROC menuwindowshow (FILE VAR f):{}  initialize menuwindow;{}  show (schreibfenster, f){}END PROC menuwindowshow;{}BOOL PROC menuwindowyes (TEXT CONST frage):{}  yes (schreibfenster, frage){}
+END PROC menuwindowyes;{}BOOL PROC menuwindowno (TEXT CONST frage):{}  no (schreibfenster, frage){}END PROC menuwindowno;{}PROC menuwindowline:{}  menuwindowline (1){}END PROC menuwindowline;{}PROC menuwindowline (INT CONST anzahl):{}  line (schreibfenster, anzahl){}END PROC menuwindowline;{}PROC menuwindowcursor (INT CONST spa, zei):{}  cursor (schreibfenster, spa, zei){}END PROC menuwindowcursor;{}PROC get menuwindowcursor (INT VAR spa, zei):{}  get cursor (schreibfenster, spa, zei){}END PROC get menuwindowcursor;{}
+INT PROC remaining menuwindowlines:{}  remaining lines (schreibfenster){}END PROC remaining menuwindowlines;{}TEXT PROC menuwindowcenter (TEXT CONST t):{}  center (schreibfenster, t){}END PROC menuwindowcenter;{}PROC menuwindowstop:{}  menuwindowstop (2){}END PROC menuwindowstop;{}PROC menuwindowstop (INT CONST anzahl):{}  stop (schreibfenster, anzahl){}END PROC menuwindowstop;{}WINDOW PROC current menuwindow:{}  initialize menuwindow;{}  schreibfenster{}END PROC current menuwindow;{}PROC stdinfoedit (FILE VAR f, INT CONST oberste zeile):{}
+  IF oberste zeile < 1 OR oberste zeile > 3{}     THEN errorstop (fehlermeldung [13]);{}  FI;{}  garantiere menukarte;{}  cursor (1, oberste zeile); out (cleop);{}  cursor (1, 23); out(79 * waagerecht);{}  cursor (1, 24); outtext (menubasistext (141), 1, 79);{}  editorinfofenster := window (1, oberste zeile + 1, 79, 24 - oberste zeile);{}  kommando auf taste legen ("?", "editorinformationen");{}  command dialogue (FALSE);{}  cursor on; edit (f, 1, oberste zeile, 79, 23 - oberste zeile);{}  command dialogue (TRUE);{}
+  kommando auf taste legen ("?", "").{}  garantiere menukarte:{}    TEXT VAR name := compress (menukartenname);{}    IF name = ""{}       THEN install menu (stdmenukartenname, FALSE){}    FI.{}END PROC stdinfoedit;{}PROC stdinfoedit (FILE VAR f):{}  stdinfoedit (f, 1){}END PROC stdinfoedit;{}PROC stdinfoedit (TEXT CONST dateiname, INT CONST oberste zeile):{}  FILE VAR f :: sequential file (modify, dateiname);{}  stdinfoedit (f, oberste zeile);{}END PROC stdinfoedit;{}PROC stdinfoedit (TEXT CONST dateiname):{}
+  stdinfoedit (dateiname, 1){}END PROC stdinfoedit;{}PROC editorinformationen:{}  BOOL VAR ende gewuenscht :: FALSE; INT VAR z;{}  FOR z FROM startwert UPTO 22 REP{}    cursor (1, z); out (cleol);{}  PER;{}  REP{}    INT VAR erg := boxalternative (editorinfofenster,{}                                   menubasistext (149),{}                                   menubasistext (150),{}                                   menubasistext (151),{}                                   5, FALSE, FALSE);{}    erfuelle den wunsch{}
+  UNTIL ende gewuenscht PER;{}  cursor (2, 23); 77 TIMESOUT waagerecht;{}  cursor (1, 24); outtext (menubasistext (141), 1, 79).{}  startwert:{}    areay (editorinfofenster) + 1.{}  erfuelle den wunsch:{}    SELECT erg OF{}      CASE 1, 101, 109: boxinfo (editorinfofenster, menubasistext (142), 5, maxint, FALSE){}      CASE 2, 102, 110: boxinfo (editorinfofenster, menubasistext (143), 5, maxint, FALSE){}      CASE 3, 103, 111: boxinfo (editorinfofenster, menubasistext (144), 5, maxint, FALSE){}      CASE 4, 104, 112: boxinfo (editorinfofenster, menubasistext (145), 5, maxint, FALSE){}
+      CASE 5, 105, 113: boxinfo (editorinfofenster, menubasistext (146), 5, maxint, FALSE){}      CASE 6, 106, 114: boxinfo (editorinfofenster, menubasistext (147), 5, maxint, FALSE){}      CASE 7, 107, 115: boxinfo (editorinfofenster, menubasistext (148), 5, maxint, FALSE){}      CASE 8, 108, 116: ende gewuenscht := TRUE{}      OTHERWISE   (*tue nichts*){}    END SELECT{}END PROC editorinformationen;{}PROC bereinige situation:{}  page;{}  forget (ds);{}  reset dialog{}END PROC bereinige situation;{}
+PROC direktstart (TEXT CONST procname, BOOL CONST autoloeschen):{}  TEXT VAR datname := "Selbststartergenerierungsdatei", letzter := std;{}  kopple archivmenukarte an;{}  schreibe programm;{}  insertiere programm;{}  abkoppeln.{}  kopple archivmenukarte an:{}    install menu (stdmenukartenname, FALSE).{}  schreibe programm:{}    forget (datname, quiet);{}    FILE VAR f :: sequential file (output, datname);{}    putline (f, menubasistext (191));{}    putline (f, "do (""reset dialog; erase menunotice; " + procname + """);");{}
+    putline (f, menubasistext (192));{}    IF autoloeschen{}       THEN putline (f, menubasistext (193)){}       ELSE putline (f, menubasistext (194)){}    FI;{}    putline (f, menubasistext (195));{}    putline (f, menubasistext (196)).{}  insertiere programm:{}     TEXT VAR t := "insert (""" + datname + """)"; do (t).{}  abkoppeln:{}    forget (datname, quiet); last param (letzter);{}    reset dialog;{}    global manager.{}END PROC direktstart;{}END PACKET ls dialog 5;{}
+
diff --git a/dialog/ls-DIALOG 6 b/dialog/ls-DIALOG 6
new file mode 100644
index 0000000..b27eae2
--- /dev/null
+++ b/dialog/ls-DIALOG 6	
@@ -0,0 +1,102 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                     ls-DIALOG 6                     ** 
+          **                 Archiv-/Taskhandling                ** 
+          **                     Version 1.2                     ** 
+          **                                                     ** 
+          **                  (Stand: 04.11.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET  ls dialog 6  DEFINES{}       menu archiv notizort setzen,{}       menu archiv grundeinstellung,{}       menu archiv zieltask einstellen,{}       menu archiv zieltask aendern,{}       menu archiv reservieren,{}       menu archiv neue diskette,{}       menu archiv schreiben,{}       menu archiv checken,{}       menu archiv schreibcheck,{}       menu archiv holen,{}       menu archiv loeschen,{}       menu archiv verzeichnis,{}       menu archiv verzeichnis drucken,{}       menu archiv initialisieren,{}
+       menu archiv reservierung aufgeben,{}       archiv:{}LET menukartenname  =  "ls-MENUKARTE:Archiv";{}LET ack             =   0,{}    schreiben       =   1,{}    checken         =   2,{}    schreibcheck    =   3,{}    holen           =   4,{}    loeschen        =   5,{}    list code       =  15,{}    reserve code    =  19;{}BOOL VAR zieltask ist archivmanager   :: TRUE,{}         archiv gehoert mir           :: FALSE,{}         fehlerfall                   :: FALSE,{}         kontakt mit zieltask erfolgt :: FALSE;{}
+TEXT VAR zieltaskname                 :: "ARCHIVE",{}         aktueller archivname         :: "";{}INT VAR stationsnummer                :: station (myself),{}        letzte funktion               :: 11,{}        notizort                      :: 3;{}PROC archiv:{}  install menu (menukartenname, FALSE);{}  handle  menu ("ARCHIV"){}END PROC archiv;{}PROC melde zieltaskerror (TEXT CONST meldung):{}  IF   meldung = menubasistext (47){}       THEN menuinfo (menubasistext (123)){}  ELIF meldung = menubasistext (46){}
+       THEN menuinfo (menubasistext (124)){}  ELIF pos (meldung, "inkonsistent") > 0{}       THEN menuinfo (menubasistext (125)){}  ELIF     pos (meldung, "Lesen unmoeglich") > 0{}       COR pos (meldung, "Schreiben unmoeglich") > 0{}       THEN menuinfo (menubasistext (126)){}  ELIF pos (meldung, "Archiv heisst") > 0 AND pos (meldung, "?????") > 0{}       THEN menuinfo (menubasistext (127)){}  ELIF pos (meldung, "Archiv heisst") > 0{}       THEN menuinfo (menubasistext (128)){}  ELIF pos (meldung, "Schreibfehler") > 0 CAND pos (meldung, "Archiv") > 0{}
+       THEN menuinfo (menubasistext (129)){}  ELIF pos (meldung, "Lesefehler") > 0{}       THEN menuinfo (menubasistext (130)){}  ELIF pos (meldung, "Kommando") > 0 AND pos (meldung, "unbekannt") > 0{}       THEN menuinfo (menubasistext (131)){}  ELIF pos (meldung, "falscher Auftrag fuer Task") > 0{}       THEN menuinfo (menubasistext (132)){}  ELIF meldung = menubasistext (41){}       THEN menuinfo (menubasistext (133)){}  ELIF meldung = menubasistext (42){}       THEN menuinfo (menubasistext (134)){}
+  ELIF pos (meldung, "Collector") > 0 AND pos(meldung, "fehlt") > 0{}       THEN menuinfo (menubasistext (135)){}  ELIF pos (meldung, "kein Zugriffsrecht auf Task") > 0{}       THEN menuinfo (menubasistext (132)){}  ELIF pos (meldung, "nicht initialisiert") > 0{}       THEN menuinfo (menubasistext (136)){}  ELIF pos (meldung, "ungueltiger Format-Code") > 0{}       THEN menuinfo (menubasistext (137)){}  ELSE menuinfo (invers (meldung)){}  FI{}END PROC melde zieltaskerror;{}PROC menu archiv notizort setzen (INT CONST wert):{}
+   SELECT wert OF{}     CASE 1,2,3,4,5 : notizort := wert{}     OTHERWISE        notizort := 3{}   END SELECT{}END PROC menu archiv notizort setzen;{}PROC menu archiv grundeinstellung (INT CONST ort):{}  menu archiv zieltask aendern ("ARCHIVE", station (myself), TRUE);{}  menu archiv notizort setzen (ort);{}  zieltask anzeigen{}END PROC menu archiv grundeinstellung;{}PROC menu archiv zieltask einstellen:{}  TEXT VAR taskname :: "";{}  INT  VAR stationsnr, auswahl;{}  BOOL VAR ist amanager;{}  erfrage daten;{}
+  kontrolliere daten;{}  menu archiv zieltask aendern (taskname, stationsnr, ist amanager);{}  refresh submenu;{}  zieltask anzeigen.{}  erfrage daten:{}    auswahl := menualternative (menubasistext (51), menubasistext (52),{}                                menubasistext (53), 5, TRUE);{}    SELECT auswahl OF{}      CASE 1, 101 : menu archiv zieltask aendern{}                    ("ARCHIVE",     station (myself), TRUE );{}                    ausstieg{}      CASE 2, 102 : menu archiv zieltask aendern{}
+                    (name (father), station (myself), FALSE);{}                    ausstieg{}      CASE 3, 103 : menu archiv zieltask aendern{}                    ("PUBLIC",      station (myself), FALSE);{}                    ausstieg{}      CASE 4, 104 : handeinstellung{}      OTHERWISE ausstieg{}    END SELECT.{}  ausstieg:{}    refresh submenu;{}    zieltask anzeigen;{}    LEAVE menu archiv zieltask einstellen.{}  handeinstellung:{}    taskname     := menuanswer (menubasistext (81), zieltaskname, 5);{}
+    stationsnr   := int (menuanswer (menubasistext (82),{}                         text (station (myself)), 5));{}    ist amanager := menuyes (menubasistext (83), 5).{}  kontrolliere daten:{}    IF   compress (taskname) = ""{}      OR compress (taskname) = "-"{}      OR taskname = name (myself){}       THEN menuinfo (menubasistext (64));{}            LEAVE menu archiv zieltask einstellen{}    FI.{}END PROC menu archiv zieltask einstellen;{}PROC menu archiv zieltask aendern (TEXT CONST taskname,{}
+                                   INT  CONST stationsnr,{}                                   BOOL CONST ist archivmanager):{}  menufootnote (menubasistext (21) + menubasistext (23));{}  gib ggf archiv frei;{}  IF ist archivmanager{}     THEN archivmanager einstellen{}     ELSE sonstige task einstellen{}  FI;{}  aktiviere gueltige archivmenupunkte.{}  gib ggf archiv frei:{}    IF archiv gehoert mir{}       THEN archivreservierung aufgeben{}    FI.{}  archivmanager einstellen:{}    zieltask ist archivmanager   := TRUE;{}
+    zieltaskname                 := taskname;{}    stationsnummer               := stationsnr;{}    kontakt mit zieltask erfolgt := FALSE;{}    aktueller archivname         := "";{}    archiv gehoert mir           := FALSE;{}    letzte funktion              := 11.{}  sonstige task einstellen:{}    zieltask ist archivmanager := FALSE;{}    zieltaskname               := taskname;{}    stationsnummer             := stationsnr;{}    aktueller archivname       := "";{}    archiv gehoert mir         := FALSE;{}
+    letzte funktion            := 6.{}END PROC menu archiv zieltask aendern;{}PROC menu archiv reservieren:{}  TEXT VAR archivname :: "", meldung :: "";{}  kontrolliere einstellung;{}  menufootnote (menubasistext (21) + menubasistext (24));{}  versuche archiv zu reservieren (meldung);{}  werte meldung aus;{}  archiv anmelden (archivname, meldung, TRUE);{}  IF archivname = ""{}     THEN behandle archivfehler{}     ELSE aktueller archivname := archivname{}  FI;{}  aktiviere gueltige archivmenupunkte;{}
+  refresh submenu;{}  zieltask anzeigen.{}  kontrolliere einstellung:{}    IF   NOT zieltask ist archivmanager{}         THEN aktiviere gueltige archivmenupunkte;{}              refresh submenu;{}              LEAVE menu archiv reservieren{}    ELIF NOT kontakt mit zieltask erfolgt{}         THEN versuche kontakt herzustellen{}    FI.{}  versuche kontakt herzustellen:{}    TEXT VAR fehler :: "";{}    IF NOT task ist kommunikativ (fehler){}       THEN melde zieltaskerror (fehler);{}            melde rigoros ab;{}
+            LEAVE menu archiv reservieren{}       ELSE kontakt mit zieltask erfolgt := TRUE{}    FI.{}  werte meldung aus:{}    IF meldung <> ""{}       THEN melde zieltaskerror (meldung);{}            melde rigoros ab;{}            LEAVE menu archiv reservieren{}    FI.{}  behandle archivfehler:{}    melde zieltaskerror (meldung);{}    archivreservierung aufgeben;{}    melde rigoros ab{}END PROC menu archiv reservieren;{}PROC melde rigoros ab:{}  aktueller archivname         := "";{}  archiv gehoert mir           := FALSE;{}
+  kontakt mit zieltask erfolgt := FALSE{}END PROC melde rigoros ab;{}PROC versuche archiv zu reservieren (TEXT VAR fehler):{}  IF NOT kontakt mit zieltask erfolgt{}     THEN fehler := menubasistext (44);{}          archiv gehoert mir := FALSE;{}          LEAVE versuche archiv zu reservieren{}  FI;{}  disable stop;{}  IF eigene station{}     THEN reserve ("beknackter archivename",/zieltaskname ){}     ELSE reserve ("beknackter archivename", stationsnummer/zieltaskname){}  FI;{}  IF is error{}     THEN fehler := errormessage;{}
+          melde rigoros ab;{}          clear error{}     ELSE archiv gehoert mir := TRUE;{}          fehler             := "";{}  FI;{}  enable stop{}END PROC versuche archiv zu reservieren;{}PROC archiv anmelden (TEXT VAR archivname, fehler, BOOL CONST mit anfrage):{}  ueberpruefe archivbesitz;{}  fuehre archivanmeldung aus.{}  ueberpruefe archivbesitz:{}    IF NOT archiv gehoert mir OR NOT kontakt mit zieltask erfolgt{}       THEN fehler := menubasistext (45);{}            melde rigoros ab;{}            LEAVE archiv anmelden{}
+    FI.{}  fuehre archivanmeldung aus:{}    IF mit anfrage{}       THEN frage nach eingelegter diskette und melde an{}       ELSE melde archiv unter richtigem namen an{}    FI.{}  frage nach eingelegter diskette und melde an:{}    IF menuyes (menubasistext (84), 5){}       THEN menufootnote (menubasistext (21) + menubasistext (25));{}            melde archiv unter richtigem namen an{}       ELSE fehler := menubasistext (46);{}            aktueller archivname := "";{}            LEAVE archiv anmelden{}
+    FI.{}  melde archiv unter richtigem namen an:{}    disable stop;{}    IF eigene station{}       THEN reserve ("beknackter archivename",/zieltaskname);{}            list (/zieltaskname);{}       ELSE reserve ("beknackter archivename", stationsnummer/zieltaskname);{}            list (stationsnummer/zieltaskname){}    FI;{}    IF is error{}       THEN fehler := errormessage;{}            behandle die fehlermeldung{}       ELSE archivname := "beknackter archivename";{}            fehler     := "";{}            enable stop{}
+   FI.{} behandle die fehlermeldung:{}   IF   subtext (fehler, 1, 14) = menubasistext (61){}          CAND subtext (fehler, 16, 20) <> menubasistext (62){}        THEN clear error; enable stop;{}             archivname := subtext (fehler, 16, length (fehler) - 1);{}             melde archiv nun wirklich richtig an;{}             fehler := "";{}             enable stop{}   ELIF subtext (fehler, 1, 14) = menubasistext (61){}          CAND subtext (fehler, 16, 20) = menubasistext (62){}        THEN clear error; enable stop;{}
+             archivname := "";{}             fehler     := menubasistext (62){}   ELSE clear error; enable stop;{}        archivname := ""{}   FI.{}  melde archiv nun wirklich richtig an:{}    IF eigene station{}       THEN reserve (archivname,/zieltaskname);{}       ELSE reserve (archivname, stationsnummer/zieltaskname){}    FI.{}END PROC archiv anmelden;{}PROC menu archiv neue diskette:{}  ueberpruefe reservierung;{}  melde neue diskette an.{}  ueberpruefe reservierung:{}    IF NOT (archiv gehoert mir AND kontakt mit zieltask erfolgt){}
+       THEN melde zieltaskerror (menubasistext (47));{}            LEAVE menu archiv neue diskette{}    FI.{}  melde neue diskette an:{}    TEXT VAR archivname :: "", meldung :: "";{}    menufootnote (menubasistext (21) + menubasistext (26));{}    archiv anmelden (archivname, meldung, FALSE);{}    IF archivname = ""{}       THEN behandle archivfehler{}       ELSE aktueller archivname := archivname{}    FI;{}    zieltask anzeigen.{}  behandle archivfehler:{}    melde zieltaskerror (meldung);{}    aktueller archivname := "".{}
+END PROC menu archiv neue diskette;{}PROC menu archiv schreiben:{}  dateioperation  mit zieltask (schreiben);{}  regenerate menuscreen{}END PROC menu archiv schreiben;{}PROC menu archiv checken:{}  dateioperation mit zieltask (checken);{}  regenerate menuscreen{}END PROC menu archiv checken;{}PROC menu archiv schreibcheck:{}  dateioperation mit zieltask (schreibcheck);{}  regenerate menuscreen{}END PROC menu archiv schreibcheck;{}PROC menu archiv holen:{}  dateioperation mit zieltask (holen);{}  regenerate menuscreen{}
+END PROC menu archiv holen;{}PROC menu archiv loeschen:{}  dateioperation mit zieltask (loeschen);{}  regenerate menuscreen{}END PROC menu archiv loeschen;{}PROC dateioperation mit zieltask (INT CONST wahl):{}  ueberpruefe kommunikationsbasis und sinnhaftigkeit;{}  lasse dateien auswaehlen;{}  operiere mit ausgewaehlten dateien.{}  ueberpruefe kommunikationsbasis und sinnhaftigkeit:{}    IF   unzulaessiger zieltaskname{}         THEN LEAVE dateioperation mit zieltask{}    ELIF zieltaskname = name (myself){}
+         THEN melde zieltaskerror (menubasistext (48));{}              LEAVE dateioperation mit zieltask{}    ELIF zieltask ist archivmanager AND NOT archiv gehoert mir{}         THEN melde zieltaskerror (menubasistext (47));{}              LEAVE dateioperation mit zieltask{}    ELIF NOT zieltask ist archivmanager{}         AND (wahl = checken OR wahl = schreibcheck){}         THEN gib hinweis auf unmoeglich;{}              LEAVE dateioperation mit zieltask{}    ELIF NOT zieltask ist archivmanager{}
+         THEN stelle kontakt mit zieltask her{}    ELIF wahl < schreiben OR wahl > loeschen{}         THEN LEAVE dateioperation mit zieltask{}    FI.{}  stelle kontakt mit zieltask her:{}    TEXT VAR fehler :: "";{}    IF task ist kommunikativ (fehler){}       THEN kontakt mit zieltask erfolgt := TRUE{}       ELSE melde zieltaskerror (fehler);{}            LEAVE dateioperation mit zieltask{}    FI.{}  gib hinweis auf unmoeglich:{}    menuinfo (menubasistext (121) + taskname + menubasistext (122)).{}
+  taskname:{}    IF eigene station{}       THEN zieltaskname{}       ELSE text (stationsnummer) + "/" + zieltaskname{}    FI.{}  lasse dateien auswaehlen:{}    THESAURUS VAR angekreuzte;{}    disable stop;{}    IF wahl = schreiben  OR wahl = schreibcheck{}       THEN angekreuzte := menusome (ALL myself, operationshinweis,{}                                     ankreuzhinweis, FALSE){}       ELSE angekreuzte := menusome (zieltaskthesaurus, operationshinweis,{}                                     ankreuzhinweis, FALSE){}
+    FI;{}    fehlerbehandlung.{}  zieltaskthesaurus:{}    IF eigene station{}       THEN ALL /zieltaskname{}       ELSE ALL (stationsnummer/zieltaskname){}    FI.{}  ankreuzhinweis:{}    menubasistext (91) + operationskennzeichnung (wahl) + menubasistext (92).{}  operationshinweis:{}    operationsbezeichnung (wahl) + zieltaskhinweis.{}  operiere mit ausgewaehlten dateien:{}    bereite bildschirm vor;{}    steige ggf bei leerem thesaurus aus;{}    IF wahl = schreiben OR wahl = schreibcheck{}       THEN zuerst loeschen{}
+    FI;{}    IF wahl = schreibcheck{}       THEN fehlerfall := FALSE;{}            dateioperation ausfuehren (angekreuzte, schreiben, FALSE);{}            IF NOT fehlerfall{}               THEN dateioperation ausfuehren (angekreuzte, checken, TRUE){}            FI{}       ELSE dateioperation ausfuehren (angekreuzte, wahl, TRUE){}    FI.{}  bereite bildschirm vor:{}    show menuwindow.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (angekreuzte){}       THEN menuwindowline (2);{}            menuwindowout (menubasistext (94));{}
+            menuwindowstop;{}            LEAVE dateioperation mit zieltask{}    FI.{}  zuerst loeschen:{}    menuwindowout (menuwindowcenter (menubasistext (21) + menubasistext (31)));{}    menuwindowline;{}    IF not empty (angekreuzte){}       THEN disable stop;{}            THESAURUS CONST zu loeschende ::{}                            angekreuzte / zieltaskthesaurus;{}            fehlerbehandlung;{}            biete ggf dateien zum loeschen an{}       ELSE menuwindowpage{}    FI.{}  biete ggf dateien zum loeschen an:{}
+    IF not empty (zu loeschende){}       THEN menuwindowout (menuwindowcenter (invers (menubasistext (108))));{}            menuwindowline;{}            menuwindowout (menuwindowcenter (menubasistext (109)));{}            menuwindowline (2);{}            dateien rausschmeissen{}       ELSE menuwindowpage{}    FI.{}  dateien rausschmeissen:{}    command dialogue (FALSE);{}    biete dateien einzeln zum loeschen an;{}    menuwindowpage;{}    command dialogue (TRUE).{}  biete dateien einzeln zum loeschen an:{}
+    INT VAR z, index;{}    FOR z FROM 1 UPTO highest entry (zu loeschende) REP{}      disable stop;{}      IF name (zu loeschende, z) <> ""{}         THEN stelle frage und fuehre aus{}      FI;{}      fehlerbehandlung{}    PER.{}  stelle frage und fuehre aus:{}    IF menuwindowyes ("'" + name (zu loeschende, z) + "' "{}                          + menubasistext (111)){}       THEN erase (name (zu loeschende, z), task (zieltaskname)){}       ELSE menuwindowout (menubasistext (110));{}            menuwindowline;{}
+            delete (angekreuzte, name (zu loeschende, z), index);{}            pause (20){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            melde zieltaskerror (errormessage);{}            clear error; enable stop;{}            LEAVE dateioperation mit zieltask{}    FI.{}END PROC dateioperation mit zieltask;{}PROC dateioperation ausfuehren (THESAURUS CONST angekreuzte,{}                                INT CONST wahl,{}                                BOOL CONST mit schlussbemerkung):{}
+  INT VAR spalte :: 1, zeile :: 3, k, anzahl :: 0;{}  menuwindowout (menuwindowcenter (invers (operationsbezeichnung (wahl){}                                        + zieltaskhinweis)));{}  command dialogue (FALSE);{}  fuehre einzelne operationen aus;{}  command dialogue (TRUE);{}  IF mit schlussbemerkung{}     THEN schreibe schlussbemerkung{}     ELSE menuwindowpage{}  FI.{}  fuehre einzelne operationen aus:{}    FOR k FROM 1 UPTO highest entry (angekreuzte) REP{}      IF name (angekreuzte, k) <> ""{}
+         THEN disable stop;{}              bildschirmausgabe;{}              operation ausfuehren;{}              anzahl INCR 1;{}              fehlerbehandlung{}      FI{}    PER.{}  bildschirmausgabe:{}    spalte := 1;{}    IF remaining menuwindowlines < 2{}       THEN menuwindowpage; zeile := 1{}       ELSE zeile INCR 1{}    FI;{}    menuwindowcursor (spalte, zeile);{}    ergaenzter dateiname.{}  ergaenzter dateiname:{}    INT VAR windowcolumn, windowrow;{}    SELECT wahl OF{}      CASE schreiben : menuwindowout (menubasistext (105) + dateiname){}
+      CASE checken   : get menuwindowcursor (windowcolumn, windowrow);{}                       menuwindowout (dateiname + menubasistext (106));{}                       menuwindowcursor (windowcolumn, windowrow);{}      CASE holen     : menuwindowout (menubasistext (107) + dateiname){}    END SELECT.{}  dateiname:{}    " """ + name (angekreuzte, k) + """ ".{}  operation ausfuehren:{}    IF eigene station{}       THEN fuehre eigenstationoperation aus{}       ELSE fuehre fremdstationoperation aus{}    FI.{}
+  fuehre eigenstationoperation aus:{}    SELECT wahl OF{}      CASE schreiben : save  (name (angekreuzte, k), /zieltaskname){}      CASE checken   : check (name (angekreuzte, k), /zieltaskname);{}                       bestaetige{}      CASE holen     : ueberschreiben erfragen eigene station{}      CASE loeschen  : loeschen erfragen eigene station{}    END SELECT.{}  ueberschreiben erfragen eigene station:{}    IF exists (name (angekreuzte, k)){}       THEN menuwindowline;{}            IF menuwindowyes (dateiname + menubasistext (112)){}
+               THEN zeile INCR 2;{}                    menuwindowline;{}                    forget (name (angekreuzte, k), quiet);{}                    fetch  (name (angekreuzte, k), /zieltaskname){}            FI{}       ELSE fetch (name (angekreuzte, k), /zieltaskname){}    FI.{}  loeschen erfragen eigene station:{}    IF menuwindowyes (dateiname + menubasistext (111)){}       THEN erase (name (angekreuzte, k), /zieltaskname){}    FI.{}  fuehre fremdstationoperation aus:{}    SELECT wahl OF{}      CASE schreiben : save  (name (angekreuzte, k), ziel){}
+      CASE checken   : check (name (angekreuzte, k), ziel); bestaetige{}      CASE holen     : ueberschreiben erfragen fremde station{}      CASE loeschen  : loeschen erfragen fremde station{}    END SELECT.{}  ueberschreiben erfragen fremde station:{}    IF exists (name (angekreuzte, k)){}       THEN menuwindowline;{}            IF menuwindowyes (dateiname + menubasistext (112)){}               THEN zeile INCR 2;{}                    menuwindowline;{}                    forget (name (angekreuzte, k), quiet);{}
+                    fetch  (name (angekreuzte, k), ziel){}            FI{}       ELSE fetch (name (angekreuzte, k), ziel){}    FI.{}  loeschen erfragen fremde station:{}    IF menuwindowyes (dateiname + menubasistext (111)){}       THEN erase (name (angekreuzte, k), ziel){}    FI.{}  ziel:{}    stationsnummer/zieltaskname.{}  bestaetige:{}    IF NOT is error{}       THEN menuwindowout (dateiname + menubasistext (114)){}    FI.{}  schreibe schlussbemerkung:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}
+       ELSE menuwindowline (2){}    FI;{}    IF anzahl > 0{}       THEN menuwindowout (menubasistext (93) +{}                           operationskennzeichnung (wahl)){}       ELSE menuwindowout (menubasistext (94)){}    FI;{}    menuwindowstop.{}  fehlerbehandlung:{}    IF is error{}       THEN fehlerfall := TRUE;{}            regenerate menuscreen;{}            melde zieltaskerror (errormessage);{}            clear error; enable stop;{}            LEAVE dateioperation ausfuehren{}    FI.{}END PROC dateioperation ausfuehren;{}
+TEXT PROC operationsbezeichnung (INT CONST nr):{}  SELECT nr OF{}    CASE schreiben    : menubasistext (95){}    CASE checken      : menubasistext (97){}    CASE schreibcheck : menubasistext (99){}    CASE holen        : menubasistext (101){}    CASE loeschen     : menubasistext (103){}    OTHERWISE ""{}  END SELECT{}END PROC operationsbezeichnung;{}TEXT PROC operationskennzeichnung (INT CONST nr):{}  SELECT nr OF{}    CASE schreiben    : menubasistext (96){}    CASE checken      : menubasistext (98){}
+    CASE schreibcheck : menubasistext (100){}    CASE holen        : menubasistext (102){}    CASE loeschen     : menubasistext (104){}    OTHERWISE ""{}  END SELECT{}END PROC operationskennzeichnung;{}BOOL PROC not empty (THESAURUS CONST t):{}  INT VAR i;{}  FOR i FROM 1 UPTO highest entry (t) REP{}    IF name (t, i) <> ""{}       THEN LEAVE not empty WITH TRUE{}    FI{}  PER;{}  FALSE{}END PROC not empty;{}TEXT PROC zieltaskhinweis:{}  IF   zieltaskname = "ARCHIVE"{}       THEN "(" + menubasistext (78) + ")"{}
+  ELIF zieltaskname = name (father){}       THEN "(" + menubasistext (79) + ")"{}  ELSE menubasistext (80) + zieltaskname + ")"{}  FI{}END PROC zieltaskhinweis;{}PROC menu archiv verzeichnis:{}  forget("Interne Dateiliste bei Archivoperation", quiet);{}  ueberpruefe kommunikationsbasis;{}  liste dateien der zieltask auf;{}  regenerate menuscreen.{}  ueberpruefe kommunikationsbasis:{}    IF   unzulaessiger zieltaskname{}         THEN LEAVE menu archiv verzeichnis{}    ELIF zieltaskname = name (myself){}
+         THEN LEAVE ueberpruefe kommunikationsbasis{}    ELIF zieltask ist archivmanager AND NOT archiv gehoert mir{}         THEN melde zieltaskerror (menubasistext (47));{}             LEAVE menu archiv verzeichnis{}    ELIF NOT zieltask ist archivmanager{}         THEN stelle kontakt mit zieltask her{}    FI.{}  stelle kontakt mit zieltask her:{}    TEXT VAR fehler :: "";{}    IF task ist kommunikativ (fehler){}       THEN kontakt mit zieltask erfolgt := TRUE{}       ELSE melde zieltaskerror (fehler);{}
+            LEAVE menu archiv verzeichnis{}    FI.{}  liste dateien der zieltask auf:{}    erstelle liste;{}    gib liste aus;{}    forget ("Interne Dateiliste bei Archivoperation", quiet).{}  erstelle liste:{}    menufootnote (menubasistext (21) + menubasistext (28));{}    FILE VAR f :: sequential file (output, "Interne Dateiliste bei Archivoperation");{}    disable stop;{}    IF eigene station{}       THEN list (f, /zieltaskname){}       ELSE list (f, stationsnummer/zieltaskname){}    FI;{}    IF is error{}
+       THEN melde zieltaskerror (errormessage);{}            forget ("Interne Dateiliste bei Archivoperation", quiet);{}            clear error; enable stop;{}            LEAVE menu archiv verzeichnis{}    FI;{}    enable stop.{}  gib liste aus:{}    modify (f);{}    IF NOT (zieltaskname = name (myself)){}       THEN to line (f, 1);{}            insert record (f);{}            notiere kopfzeile;{}            headline (f, menubasistext (43));{}       ELSE entferne eigenen namen aus der liste{}    FI;{}
+    to line (f, 1);{}    cursor on; menuwindowshow (f); cursor off.{}  notiere kopfzeile:{}    IF zieltask ist archivmanager{}       THEN write record (f, headline (f));{}       ELSE write record (f, zieltaskbezeichnung){}    FI.{}  entferne eigenen namen aus der liste:{}    TEXT VAR zeile :: ""; INT VAR i;{}    FOR i FROM lines (f) DOWNTO 1 REP{}      to line (f, i);{}      read record (f, zeile);{}      IF pos (zeile, "Interne Dateiliste bei Archivoperation") > 0{}         THEN delete record (f);{}
+              LEAVE entferne eigenen namen aus der liste{}      FI{}    PER{}END PROC menu archiv verzeichnis;{}PROC menu archiv verzeichnis drucken:{}  forget ("Interne Dateiliste bei Archivoperation", quiet);{}  ueberpruefe kommunikationsbasis;{}  erstelle listing;{}  drucke listing aus.{}  ueberpruefe kommunikationsbasis:{}    IF   unzulaessiger zieltaskname{}         THEN LEAVE menu archiv verzeichnis drucken{}    ELIF zieltaskname = name (myself){}         THEN LEAVE ueberpruefe kommunikationsbasis{}
+    ELIF zieltask ist archivmanager AND NOT archiv gehoert mir{}         THEN melde zieltaskerror (menubasistext (47));{}             LEAVE menu archiv verzeichnis drucken{}    ELIF NOT zieltask ist archivmanager{}         THEN stelle kontakt mit zieltask her{}    FI.{}  stelle kontakt mit zieltask her:{}    TEXT VAR fehler :: "";{}    IF task ist kommunikativ (fehler){}       THEN kontakt mit zieltask erfolgt := TRUE{}       ELSE melde zieltaskerror (fehler);{}            LEAVE menu archiv verzeichnis drucken{}
+    FI.{}  erstelle listing:{}    LET dummy name pos = 18;{}    FILE VAR listfile; INT VAR i; TEXT VAR record :: "";{}    TEXT CONST head :: 70 * "=", end :: 70 * "-";{}    IF menuno (menubasistext (90), 5){}       THEN LEAVE menu archiv verzeichnis drucken{}    FI;{}    menufootnote (menubasistext (21) + menubasistext (29));{}    disable stop;{}    listfile := sequential file (output, "Interne Dateiliste bei Archivoperation");{}    IF eigene station{}       THEN list (listfile, /zieltaskname){}       ELSE list (listfile, stationsnummer/zieltaskname){}
+    FI;{}    IF is error{}       THEN melde zieltaskerror (errormessage);{}            forget ("Interne Dateiliste bei Archivoperation", quiet);{}            clear error; enable stop;{}            LEAVE menu archiv verzeichnis drucken{}    FI;{}    enable stop.{}  drucke listing aus:{}    schreibe dateikopf;{}    loesche dummy names;{}    schreibe fuss;{}    drucke und loesche listing.{}  schreibe dateikopf:{}    modify (listfile);{}    to line (listfile, 1);{}    FOR i FROM 1 UPTO 6 REP insert record (listfile) PER;{}
+    to line (listfile, 1);{}    write record (listfile, "#type (""elanlist"")#"); down (listfile);{}    write record (listfile, "#start (2.5,0.0)##limit (20,5)#"{}                            + "#pagelength (26.0)#"); down (listfile);{}    write record (listfile, head); down (listfile);{}    schreibe erkennungszeile; down (listfile);{}    write record (listfile, "        Listing vom " + date + ",  "{}                            + time of day + " Uhr"); down (listfile);{}    write record (listfile, head).{}
+  schreibe erkennungszeile:{}    IF zieltask ist archivmanager{}       THEN write record (listfile, "Archiv: " + headline (listfile)){}       ELSE write record (listfile, "Task  : " + taskbezeichnung){}    FI.{}  taskbezeichnung:{}    IF eigene station{}       THEN zieltaskname{}       ELSE text (stationsnummer) + "/" + zieltaskname{}    FI.{}  loesche dummy names:{}    to line (listfile, 8);{}    WHILE NOT eof (listfile) REP{}      read record (listfile, record);{}      IF (record SUB dummy name pos) = "-"{}
+         OR pos (record, "Interne Dateiliste bei Archivoperation") > 0{}         THEN delete record (listfile){}         ELSE down (listfile){}      FI{}    PER.{}  schreibe fuss:{}    output (listfile);{}    putline (listfile, end).{}  drucke und loesche listing:{}    menufootnote (menubasistext (21) + menubasistext (30));{}    disable stop;{}    print ("Interne Dateiliste bei Archivoperation");{}    IF is error{}       THEN melde zieltaskerror (errormessage);{}            clear error; enable stop;{}
+            forget ("Interne Dateiliste bei Archivoperation", quiet);{}            LEAVE menu archiv verzeichnis drucken{}    FI;{}    enable stop;{}    forget ("Interne Dateiliste bei Archivoperation", quiet){}END PROC menu archiv verzeichnis drucken;{}TEXT PROC zieltaskbezeichnung:{}  IF eigene station{}     THEN menubasistext (77) + taskbezeichnung{}     ELSE menubasistext (76) + text (stationsnummer) + "   " +{}          menubasistext (77) + zieltaskname{}  FI.{}  taskbezeichnung:{}    IF   zieltaskname = "ARCHIVE"{}
+         THEN menubasistext (78){}    ELIF zieltaskname = name (father){}         THEN menubasistext (79) + " (" + zieltaskname + ")"{}         ELSE zieltaskname{}    FI{}END PROC zieltaskbezeichnung;{}BOOL PROC unzulaessiger zieltaskname:{}  IF compress (zieltaskname) = "" OR compress (zieltaskname) = "-"{}     THEN TRUE{}     ELSE FALSE{}  FI{}END PROC unzulaessiger zieltaskname;{}PROC menu archiv initialisieren:{}  TEXT VAR archivname :: "", meldung :: "";{}  klaere zieltaskart;{}  formatiere ggf;{}
+  initialisiere ggf.{}  klaere zieltaskart:{}    IF NOT zieltask ist archivmanager{}       THEN menuinfo (menubasistext (121) + zieltaskname +{}                      menubasistext (122));{}            LEAVE menu archiv initialisieren{}    FI.{}  formatiere ggf:{}    IF menuyes (menubasistext (85), 5){}       THEN nimm archiv in beschlag;{}            fuehre formatierung aus{}    FI.{}  nimm archiv in beschlag:{}    stelle archivbesitz sicher;{}    IF aktueller archivname <> ""{}       THEN archivname := aktueller archivname{}
+       ELSE archivname := menubasistext (75){}    FI;{}    IF eigene station{}       THEN reserve (archivname,/zieltaskname){}       ELSE reserve (archivname, stationsnummer/zieltaskname){}    FI;{}    aktueller archivname := archivname;{}    archiv gehoert mir   := TRUE;{}    zieltask anzeigen.{}  stelle archivbesitz sicher:{}    IF NOT archiv gehoert mir OR NOT kontakt mit zieltask erfolgt{}           THEN versuche kommunikation;{}                versuche archiv zu reservieren (meldung);{}                werte meldung aus{}
+    FI.{}  versuche kommunikation:{}    TEXT VAR fehler :: "";{}    IF NOT task ist kommunikativ (fehler){}       THEN melde zieltaskerror (fehler);{}            melde rigoros ab;{}            LEAVE menu archiv initialisieren{}       ELSE kontakt mit zieltask erfolgt := TRUE{}    FI.{}  werte meldung aus:{}    IF meldung <> ""{}       THEN melde zieltaskerror (meldung);{}            aktueller archivname := "";{}            zieltask anzeigen;{}            LEAVE menu archiv initialisieren{}    FI.{}
+  fuehre formatierung aus:{}    INT VAR auswahl :: menualternative (menubasistext (54),{}                                        menubasistext (55),{}                                        menubasistext (56), 5, TRUE);{}    IF auswahl = 0{}       THEN LEAVE fuehre formatierung aus{}    FI;{}    IF auswahl > 100{}       THEN auswahl DECR 100{}    FI;{}    command dialogue (FALSE);{}    disable stop;{}    menufootnote (menubasistext (21) + menubasistext (27));{}    IF eigene station{}       THEN formatiere auf eigener station{}
+       ELSE formatiere auf fremder station{}    FI;{}    IF is error{}       THEN melde zieltaskerror (errormessage);{}            clear error; enable stop;{}            command dialogue (TRUE);{}            LEAVE formatiere ggf{}       ELSE enable stop;{}            command dialogue (TRUE);{}            aktiviere gueltige archivmenupunkte;{}            refresh submenu;{}            zieltask anzeigen{}    FI.{}  formatiere auf eigener station:{}    IF auswahl < 5{}       THEN format (auswahl, /zieltaskname){}
+       ELSE format (/zieltaskname){}    FI.{}  formatiere auf fremder station:{}     IF auswahl < 5{}       THEN format (auswahl, stationsnummer/zieltaskname){}       ELSE format (stationsnummer/zieltaskname){}    FI.{}  initialisiere ggf:{}    stelle archivbesitz sicher;{}    archiv anmelden (archivname, meldung, FALSE);{}    IF   archivname <> ""{}         THEN aktueller archivname := archivname;{}              archiv gehoert mir   := TRUE;{}              aktiviere gueltige archivmenupunkte;{}              refresh submenu;{}
+              zieltask anzeigen;{}              frage nach ueberschreiben{}    ELIF meldung = menubasistext (63) OR meldung = menubasistext (62){}         THEN frage nach initialisieren{}    ELSE melde zieltaskerror (meldung);{}         aktueller archivname := "";{}         zieltask anzeigen;{}         LEAVE menu archiv initialisieren{}    FI.{}  frage nach ueberschreiben:{}    IF menuyes (menubasistext (86) + archivname + menubasistext (87), 5){}       THEN erfrage neuen namen und initialisiere{}
+       ELSE LEAVE menu archiv initialisieren{}    FI.{}  frage nach initialisieren:{}    IF menuyes (menubasistext (88), 5){}       THEN erfrage neuen namen und initialisiere{}       ELSE LEAVE menu archiv initialisieren{}    FI.{}  erfrage neuen namen und initialisiere:{}    TEXT VAR neuer name := compress(menuanswer (menubasistext (89),{}                                                aktueller archivname, 5));{}    IF   neuer name <> ""{}         THEN archivname := neuer name{}    ELIF neuer name = "" AND archivname = ""{}
+         THEN archivname := menubasistext (75){}    FI;{}    command dialogue (FALSE);{}    disable stop;{}    IF eigene station{}       THEN reserve (archivname, /zieltaskname);{}            clear (/zieltaskname){}       ELSE reserve (archivname, stationsnummer/zieltaskname);{}            clear (stationsnummer/zieltaskname){}    FI;{}    IF is error{}       THEN melde zieltaskerror (errormessage);{}            clear error; enable stop;{}            command dialogue (TRUE);{}            melde rigoros ab;{}
+            archivreservierung aufgeben;{}            aktiviere gueltige archivmenupunkte;{}            refresh submenu;{}            zieltask anzeigen;{}            LEAVE menu archiv initialisieren{}       ELSE enable stop; command dialogue (TRUE);{}            aktueller archivname := archivname;{}            archiv gehoert mir   := TRUE;{}            aktiviere gueltige archivmenupunkte;{}            refresh submenu;{}            zieltask anzeigen{}    FI{}END PROC menu archiv initialisieren;{}PROC archive (TEXT CONST archive name,task, INT CONST station):{}
+  call (reserve code, archive name, station/task){}END PROC archive;{}PROC menu archiv reservierung aufgeben:{}  IF archiv gehoert mir{}     THEN menufootnote (menubasistext (21) + menubasistext (22));{}          archivreservierung aufgeben;{}  FI;{}  erase menunotice;{}  old menufootnote{}END PROC menu archiv reservierung aufgeben;{}PROC archivreservierung aufgeben:{}  command dialogue (FALSE);{}  disable stop;{}  IF eigene station{}     THEN release (/zieltaskname){}     ELSE release (stationsnummer/zieltaskname);{}
+  FI;{}  IF is error{}     THEN clear error{}  FI;{}  enable stop;{}  command dialogue (TRUE);{}  archiv gehoert mir   := FALSE;{}  aktueller archivname := ""{}END PROC archivreservierung aufgeben;{}BOOL PROC eigene station:{}  IF stationsnummer = 0 OR stationsnummer = station (myself){}     THEN TRUE{}     ELSE FALSE{}  FI{}END PROC eigene station;{}PROC aktiviere gueltige archivmenupunkte:{}  IF   zieltask ist archivmanager AND NOT archiv gehoert mir{}       THEN aktiviere nur grundfunktionen{}
+  ELSE aktiviere alle momentan gueltigen punkte{}  FI.{}  aktiviere alle momentan gueltigen punkte:{}    IF letzte funktion = 11{}       THEN activate (1); activate (2);{}            activate (4); activate (5); activate (6); activate (7); activate (8);{}            activate (10); activate (11);{}            activate (13); activate (14);{}    ELIF letzte funktion = 6{}       THEN deactivate (1); deactivate (2);{}            activate (4); deactivate (5); deactivate (6); activate (7); activate (8);{}
+            activate (10); activate (11);{}            deactivate (13); activate (14);{}    FI.{}  aktiviere nur grundfunktionen:{}     activate (1); deactivate (2);{}     deactivate (4); deactivate (5); deactivate (6); deactivate (7); deactivate (8);{}     deactivate (10); deactivate (11);{}     activate (13); activate (14).{}END PROC aktiviere gueltige archivmenupunkte;{}PROC zieltask anzeigen:{}  IF zieltask ist archivmanager{}     THEN schreibe taskname und archivname{}     ELSE schreibe taskname{}
+  FI.{}  schreibe taskname:{}    write menunotice (menubasistext (59) + ""13"" + name der task, notizort).{}  schreibe taskname und archivname:{}    write menunotice (menubasistext (59) + ""13"" + name der task +{}                      ""13"" + menubasistext (60) + ""13"" + archivname,{}                      notizort).{}  name der task:{}    IF   zieltaskname = "ARCHIVE" AND eigene station{}         THEN " " + menubasistext (71){}    ELIF zieltaskname = "PUBLIC"  AND eigene station{}         THEN " " + menubasistext (72){}
+    ELIF zieltaskname = name (father){}         THEN " " + menubasistext (73){}    ELSE " " + ggf gekuerzter zieltaskname{}    FI.{}  ggf gekuerzter zieltaskname:{}    TEXT VAR interner name;{}    IF eigene station{}       THEN interner name := zieltaskname;{}       ELSE interner name := text (stationsnummer) + "/" + zieltaskname{}    FI;{}    IF length (interner name) < 20{}       THEN ""15"" + interner name + " "14""{}       ELSE ""15"" + subtext (interner name, 1 , 18) + ".." + " "14""{}    FI.{}
+  archivname:{}    IF NOT archiv gehoert mir OR aktueller archivname = ""{}       THEN " " + menubasistext (74){}       ELSE " "15"" + ggf gekuerzter archivname + " "14""{}    FI.{}  ggf gekuerzter archivname:{}    IF   eigene station AND length (aktueller archivname) > 20{}         THEN subtext (aktueller archivname, 1, 18) + ".."{}    ELIF NOT eigene station AND length (aktueller archivname) > 17{}         THEN subtext (aktueller archivname, 1, 15) + ".."{}    ELSE aktueller archivname{}    FI.{}
+END PROC zieltask anzeigen;{}BOOL PROC task ist kommunikativ (TEXT VAR  fehler):{}  INT VAR antwort;{}  DATASPACE VAR dummy space := nilspace;{}    IF zieltask ist archivmanager{}       THEN schicke reservierungscode{}       ELSE schicke listcode{}    FI.{}  schicke reservierungscode:{}    disable stop;{}    IF eigene station{}       THEN pingpong (/zieltaskname, reserve code, dummy space, antwort);{}       ELSE pingpong (stationsnummer/zieltaskname, reserve code,{}                      dummy space, antwort){}
+    FI;{}    werte antwort aus.{}  schicke listcode:{}    disable stop;{}    IF eigene station{}       THEN pingpong (/zieltaskname, list code, dummy space, antwort);{}       ELSE pingpong (stationsnummer/zieltaskname, list code,{}                      dummy space, antwort){}    FI;{}    werte antwort aus.{}  werte antwort aus:{}    IF is error{}       THEN clear error{}    FI;{}    BOUND TEXT VAR inhalt := dummy space;{}    enable stop;{}    IF   antwort  =   0 THEN fehler := ""{}    ELIF antwort  =  -1 THEN fehler := menubasistext (41){}
+    ELIF antwort  =  -2 THEN fehler := menubasistext (42){}    ELSE fehler  := inhalt{}    FI;{}    forget (dummy space);{}    IF antwort = ack{}       THEN kontakt mit zieltask erfolgt := TRUE;  TRUE{}       ELSE kontakt mit zieltask erfolgt := FALSE; FALSE{}    FI{}END PROC task ist kommunikativ;{}END PACKET ls dialog 6;{}
+
diff --git a/dialog/ls-DIALOG 7 b/dialog/ls-DIALOG 7
new file mode 100644
index 0000000..467f531
--- /dev/null
+++ b/dialog/ls-DIALOG 7	
@@ -0,0 +1,54 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                     ls-DIALOG 7                     ** 
+          **                    Dateihandling                    ** 
+          **                     Version 1.2                     ** 
+          **                                                     ** 
+          **                  (Stand: 04.11.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET  ls dialog 7  DEFINES{}        menu dateien verzeichnis,{}        menu dateien loeschen,{}        menu dateien drucken,{}        menu dateien kopieren,{}        menu dateien umbenennen,{}        menu dateien speicherplatz,{}        menu dateien aufraeumen:{}LET filetype  = 1003,{}    maxlaenge =   60,{}    breite    =   40,{}    niltext   =   "";{}TEXT CONST dateibez :: "Dateiliste bei internen Operationen";{}PROC menu dateien verzeichnis:{}  forget (dateibez, quiet);{}  liste dateien auf;{}
+  regenerate menuscreen.{}  liste dateien auf:{}    erstelle liste;{}    gib liste aus;{}    forget (dateibez, quiet).{}  erstelle liste:{}    menufootnote (menubasistext (21) + menubasistext (28));{}    FILE VAR f :: sequential file (output, dateibez);{}    list (f); modify (f);{}    headline (f, menubasistext (43));{}    to line (f, 1); insert record (f);{}    write record (f, menubasistext (161));{}    entferne eigenen namen aus der liste.{}  entferne eigenen namen aus der liste:{}    TEXT VAR zeile :: ""; INT VAR i;{}
+    FOR i FROM lines (f) DOWNTO 1 REP{}      to line (f, i); read record (f, zeile);{}      IF pos (zeile, dateibez) > 0{}         THEN delete record (f);{}              LEAVE entferne eigenen namen aus der liste{}      FI{}    PER.{}  gib liste aus:{}    to line (f, 1); cursor on; menuwindowshow (f); cursor off{}END PROC menu dateien verzeichnis;{}PROC menu dateien loeschen:{}  lasse dateien auswaehlen;{}  loesche ausgewaehlte dateien;{}  regenerate menuscreen.{}  lasse dateien auswaehlen:{}    IF NOT not empty (ALL myself){}
+       THEN noch keine datei;{}            LEAVE menu dateien loeschen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    THESAURUS VAR angekreuzte :={}    menuanswersome ( center (breite, invers (menubasistext(162))) +{}                     menubasistext (163), "", ALL myself,{}                     menubasistext (162), menubasistext (91) +{}                     menubasistext (104) + menubasistext (92), FALSE).{}  loesche ausgewaehlte dateien:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}
+    menuwindowout (menuwindowcenter (invers (menubasistext (162))));{}    menuwindowline (2);{}    command dialogue (FALSE);{}    fuehre einzelne operation aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (menubasistext (93) + menubasistext (104));{}    menuwindowstop.{}  fuehre einzelne operation aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (angekreuzte) REP{}      IF   name (angekreuzte, k) = niltext{}           THEN LEAVE fuehre einzelne operation aus{}
+      ELIF NOT exists (name (angekreuzte, k)){}           THEN menuwindowout (" """ + name (angekreuzte, k) + """");{}                menuwindowline;{}                menuwindowout (menubasistext (188)); menuwindowline;{}                LEAVE fuehre einzelne operation aus{}      ELSE disable stop;{}           IF menuwindowyes (" """ + name (angekreuzte, k) + """ "{}                                   + menubasistext (111)){}              THEN forget (name (angekreuzte, k), quiet){}           FI;{}
+           fehlerbehandlung{}      FI{}    PER.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (angekreuzte){}       THEN menuwindowline (2);{}            menuwindowout (menubasistext (94));{}            menuwindowstop;{}            regenerate menuscreen;{}            LEAVE menu dateien loeschen{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}
+       THEN regenerate menuscreen;{}            menuinfo  (invers (errormessage));{}            clear error; enable stop;{}            LEAVE menu dateien loeschen{}    FI{}END PROC menu dateien loeschen;{}PROC menu dateien drucken:{}  lasse programme auswaehlen;{}  drucke programme;{}  regenerate menuscreen.{}  lasse programme auswaehlen:{}    IF NOT not empty (ALL myself){}       THEN noch keine datei;{}            LEAVE menu dateien drucken{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}
+    THESAURUS VAR angekreuzte :={}    menuanswersome ( center (breite, invers (menubasistext(164))) +{}                     menubasistext (163), "", ALL myself,{}                     menubasistext (164), menubasistext (91) +{}                     menubasistext (165) + menubasistext (92), FALSE).{}  drucke programme:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers (menubasistext (164))));{}    menuwindowline (2);{}    command dialogue (FALSE);{}
+    fuehre einzelne operation aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (menubasistext (93) + menubasistext (165));{}    menuwindowstop.{}  fuehre einzelne operation aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (angekreuzte) REP{}      IF   name (angekreuzte, k) = niltext{}           THEN LEAVE fuehre einzelne operation aus{}      ELIF NOT exists (name (angekreuzte, k)){}           THEN menuwindowout (" """ + name (angekreuzte, k) + """");{}
+                menuwindowline;{}                menuwindowout (menubasistext (188)); menuwindowline;{}                LEAVE fuehre einzelne operation aus{}      ELSE disable stop;{}           menuwindowout ( " """ + name (angekreuzte, k) + """ "{}                                 + menubasistext (166));{}           menuwindowline;{}           print (name (angekreuzte, k));{}           fehlerbehandlung{}      FI{}    PER.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (angekreuzte){}
+       THEN menuwindowline (2);{}            menuwindowout (menubasistext (94));{}            menuwindowstop;{}            regenerate menuscreen;{}            LEAVE menu dateien drucken{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            menuinfo  (invers (errormessage));{}            clear error; enable stop;{}
+            LEAVE menu dateien drucken{}    FI.{}END PROC menu dateien drucken;{}PROC menu dateien kopieren:{}  ermittle alten dateinamen;{}  erfrage neuen dateinamen;{}  kopiere ggf die datei.{}  ermittle alten dateinamen:{}    IF NOT not empty (ALL myself){}       THEN noch keine datei;{}            LEAVE menu dateien kopieren{}       ELSE hole den namen{}    FI.{}  hole den namen:{}    TEXT VAR alter name :={}    menuanswerone ( center (breite, invers (menubasistext(167))) +{}                    menubasistext (163), "", ALL myself,{}
+                    menubasistext (167), menubasistext (168) +{}                    menubasistext (169) + menubasistext (170), TRUE);{}    IF   alter name = niltext{}         THEN LEAVE menu dateien kopieren{}    ELIF NOT exists (alter name){}         THEN menuinfo (menubasistext (188));{}              LEAVE menu dateien kopieren{}    FI.{}  erfrage neuen dateinamen:{}    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}     ueberschrift + menubasistext (171) + bisheriger name{}
+                  + menubasistext (172).{}  ueberschrift:{}    center (maxlaenge, invers (menubasistext (167))) + ""13""13"".{}  bisheriger name:{}    ""13""13" " + invers (alter name) + ""13""13"".{}  kopiere ggf die datei:{}    IF   neuer name = niltext{}         THEN menuinfo (invers (menubasistext (173)));{}              LEAVE menu dateien kopieren{}    ELIF exists (neuer name){}         THEN mache vorwurf;{}              LEAVE menu dateien kopieren{}       ELSE copy (alter name, neuer name){}
+    FI.{}  mache vorwurf:{}    menuinfo (menubasistext (174)).{}END PROC menu dateien kopieren;{}PROC menu dateien umbenennen:{}  ermittle alten dateinamen;{}  erfrage neuen dateinamen;{}  benenne ggf die datei um.{}  ermittle alten dateinamen:{}    IF NOT not empty (ALL myself){}       THEN noch keine datei;{}            LEAVE menu dateien umbenennen{}       ELSE hole den namen{}    FI.{}  hole den namen:{}    TEXT VAR alter name :={}    menuanswerone ( center (breite, invers (menubasistext(175))) +{}
+                    menubasistext (163), "", ALL myself,{}                    menubasistext (175), menubasistext (168) +{}                    menubasistext (176) + menubasistext (170), TRUE);{}    IF   alter name = niltext{}         THEN LEAVE menu dateien umbenennen{}    ELIF NOT exists (alter name){}         THEN menuinfo (menubasistext (188));{}              LEAVE menu dateien umbenennen{}    FI.{}  erfrage neuen dateinamen:{}    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}
+     ueberschrift + menubasistext (171) + bisheriger name{}                  + menubasistext (177).{}  ueberschrift:{}    center (maxlaenge, invers (menubasistext (175))) + ""13""13"".{}  bisheriger name:{}    ""13""13" " + invers (alter name) + ""13""13"".{}  benenne ggf die datei um:{}    IF   neuer name = niltext{}         THEN menuinfo (invers (menubasistext (173)));{}              LEAVE menu dateien umbenennen{}    ELIF exists (neuer name){}         THEN mache vorwurf;{}              LEAVE menu dateien umbenennen{}
+       ELSE rename (alter name, neuer name){}    FI.{}  mache vorwurf:{}    menuinfo (menubasistext (174)).{}END PROC menu dateien umbenennen;{}PROC menu dateien speicherplatz:{}  lasse dateinamen auswaehlen;{}  ermittle den speicherplatz;{}  regenerate menuscreen.{}  lasse dateinamen auswaehlen:{}    IF NOT not empty (ALL myself){}       THEN noch keine datei;{}            LEAVE menu dateien speicherplatz{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    THESAURUS VAR angekreuzte :={}
+    menuanswersome ( center (breite, invers (menubasistext(178))) +{}                     menubasistext (163), "", ALL myself,{}                     menubasistext (178), menubasistext (179), FALSE).{}  ermittle den speicherplatz:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers (menubasistext (178))));{}    menuwindowline (2);{}    command dialogue (FALSE);{}    fuehre einzelne operation aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}
+    menuwindowout (menubasistext (180));{}    menuwindowstop.{}  fuehre einzelne operation aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (angekreuzte) REP{}      IF   name (angekreuzte, k) = niltext{}           THEN LEAVE fuehre einzelne operation aus{}      ELIF NOT exists (name (angekreuzte, k)){}           THEN menuwindowout (" """ + name (angekreuzte, k) + """");{}                menuwindowline;{}                menuwindowout (menubasistext (188)); menuwindowline;{}                LEAVE fuehre einzelne operation aus{}
+      ELSE disable stop;{}           menuwindowout ( " """ + name (angekreuzte, k) + """ "{}                                 + menubasistext (181){}                                 + speicherplatz (name (angekreuzte, k)));{}           menuwindowline;{}           fehlerbehandlung{}      FI{}    PER.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (angekreuzte){}       THEN menuwindowline (2);{}            menuwindowout (menubasistext (94));{}            menuwindowstop;{}            regenerate menuscreen;{}
+            LEAVE menu dateien speicherplatz{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            menuinfo  (invers (errormessage));{}            clear error; enable stop;{}            LEAVE menu dateien speicherplatz{}    FI.{}END PROC menu dateien speicherplatz;{}TEXT PROC speicherplatz (TEXT CONST dateiname):{}
+  DATASPACE VAR ds :: old (dateiname);{}  INT CONST platz    :: storage (ds);{}  forget (ds);{}  " " + text (platz) + menubasistext (182){}END PROC speicherplatz;{}PROC menu dateien aufraeumen:{}  lasse dateinamen auswaehlen;{}  raeume die dateien auf;{}  regenerate menuscreen.{}  lasse dateinamen auswaehlen:{}    IF NOT not empty (ALL myself){}       THEN noch keine datei;{}            LEAVE menu dateien aufraeumen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    THESAURUS VAR angekreuzte :={}
+    menuanswersome ( center (breite, invers (menubasistext(183))) +{}                     menubasistext (163), "", ALL myself,{}                     menubasistext (183), menubasistext (91) +{}                     menubasistext (184) + menubasistext (92), FALSE).{}  raeume die dateien auf:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers (menubasistext (183))));{}    menuwindowline (2);{}    command dialogue (FALSE);{}    fuehre einzelne operation aus;{}
+    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (menubasistext (93) + menubasistext (184));{}    menuwindowstop.{}  fuehre einzelne operation aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (angekreuzte) REP{}      IF   name (angekreuzte, k) = niltext{}           THEN LEAVE fuehre einzelne operation aus{}      ELIF NOT exists (name (angekreuzte, k)){}           THEN menuwindowout (" """ + name (angekreuzte, k) + """");{}                menuwindowline;{}                menuwindowout (menubasistext (188)); menuwindowline;{}
+                LEAVE fuehre einzelne operation aus{}      ELIF dateityp ist ok{}           THEN disable stop;{}                menuwindowline;{}                menuwindowout ( " """ + name (angekreuzte, k) + """ "{}                                      + menubasistext (185) );{}                menuwindowline; menuwindowout ("   ");{}                reorganize (name (angekreuzte, k));{}                fehlerbehandlung{}      ELSE menuwindowout ( " """ + name (angekreuzte, k) + """ "{}                                 + menubasistext (186)){}
+      FI{}    PER.{}  dateityp ist ok:{}   type (old (name (angekreuzte, k))) = filetype.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (angekreuzte){}       THEN menuwindowline (2);{}            menuwindowout (menubasistext (94));{}            menuwindowstop;{}            regenerate menuscreen;{}            LEAVE menu dateien aufraeumen{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}
+    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            menuinfo  (invers (errormessage));{}            clear error; enable stop;{}            LEAVE menu dateien aufraeumen{}    FI.{}END PROC menu dateien aufraeumen;{}PROC noch keine datei:{}  menuinfo (menubasistext ( 187)){}END PROC noch keine datei;{}END PACKET ls dialog 7;{}
+
diff --git a/dialog/ls-DIALOG MENUKARTEN MANAGER b/dialog/ls-DIALOG MENUKARTEN MANAGER
new file mode 100644
index 0000000..67799ea
--- /dev/null
+++ b/dialog/ls-DIALOG MENUKARTEN MANAGER	
@@ -0,0 +1,28 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                      ls-DIALOG                      ** 
+          **                  MENUKARTEN-MANAGER                 ** 
+          **                     Version 1.2                     ** 
+          **                                                     ** 
+          **                  (Stand: 04.11.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET  ls dialog manager DEFINES{}     ls dialog manager:{}LET  fetch    code  =  11,{}     save     code  =  12,{}     exists   code  =  13,{}     list     code  =  15,{}     continue code  = 100;{}LET mm taskname   = "ls-MENUKARTEN",{}    gibt es schon  = "Die Task 'ls-MENUKARTEN' existiert schon!",{}    verweis        = "Unzulässiger Zugriff auf die Task 'ls-MENUKARTEN'!";{}PROC ls dialog manager:{}  stelle richtigen tasknamen ein;{}  global manager{}  (PROC (DATASPACE VAR, INT CONST, INT CONST, TASK CONST) ls dialog manager){}
+END PROC ls dialog manager;{}PROC stelle richtigen tasknamen ein:{}  IF name (myself) <> mm taskname{}     THEN nimm umbenennung vor{}  FI.{}  nimm umbenennung vor:{}    IF NOT exists task (mm taskname){}       THEN rename myself (mm taskname){}       ELSE errorstop (gibt es schon){}    FI.{}END PROC stelle richtigen tasknamen ein;{}PROC ls dialog manager (DATASPACE VAR ds, INT CONST order, phase,{}                        TASK CONST order task):{}  IF   order task = supervisor{}    OR order      = fetch    code{}
+    OR order      = save     code{}    OR order      = exists   code{}    OR order      = list     code{}    OR order      = continue code{}    THEN free manager (ds, order, phase, order task){}    ELSE errorstop (verweis){}  FI{}END PROC ls dialog manager;{}END PACKET ls dialog manager;{}
+
diff --git a/dialog/ls-DIALOG MM-gen b/dialog/ls-DIALOG MM-gen
new file mode 100644
index 0000000..ef05853
--- /dev/null
+++ b/dialog/ls-DIALOG MM-gen	
@@ -0,0 +1,27 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                     ls-DIALOG                       ** 
+          **                 MENUKARTEN MANAGER                  ** 
+          **                 Generator-Programm                  ** 
+          **                    Version 1.2                      ** 
+          **                                                     ** 
+          **                 (Stand: 04.11.88)                   ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+LET dateiname  = "ls-DIALOG MENUKARTEN MANAGER",{}    archivname = "gs-dialog";{}gib bildschirmhinweis;{}hole generatordatei vom archiv;{}insertiere die datei;{}do ("ls dialog manager").{}gib bildschirmhinweis:{}  page;{}  putline ("              "15"ls-DIALOG MENUKARTEN MANAGER - Generierung "14"").{}hole generatordatei vom archiv:{}  IF NOT exists (dateiname){}     THEN cursor (1, 5); out (""4"");{}          putline ("Bitte warten... Ich hole eine Datei von der Diskette!");{}          archive (archivname);{}
+          fetch (dateiname, archive);{}          release (archive){}  FI.{}insertiere die datei:{}  cursor (1, 5); out (""4"");{}  putline ("Bitte warten... Ich insertiere!");{}  check off; insert (dateiname); check on;{}  forget ("ls-DIALOG MM/gen", quiet);{}  forget (dateiname, quiet).{}
+
diff --git a/dialog/ls-DIALOG decompress b/dialog/ls-DIALOG decompress
new file mode 100644
index 0000000..96d9340
--- /dev/null
+++ b/dialog/ls-DIALOG decompress	
@@ -0,0 +1,150 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **               ls-DIALOG - DECOMPRESS                ** 
+          **                                                     ** 
+          **                    Version 1.2                      ** 
+          **                                                     ** 
+          **                 (Stand: 04.11.88)                   ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+PACKET ls dialog decompress DEFINES 
+ 
+       komprimiere, 
+       dekomprimiere: 
+ 
+LET verweis      = "Angegebene Datei existiert nicht!", 
+    falscher typ = "Angegebenen Datei hat falschen Typ!", 
+    filetype     = 1003; 
+ 
+PROC komprimiere (TEXT CONST dateiname):   
+  INT VAR zeiger; 
+  ueberpruefe existenz; 
+  ueberpruefe dateityp; 
+  initialisiere; 
+  FOR zeiger FROM 1 UPTO 24 REP 
+    getline (ein, eingabezeile); 
+    putline (aus, eingabezeile); 
+  PER; 
+  WHILE NOT eof (ein) REP 
+    getline (ein, eingabezeile); 
+    zaehler INCR 1; cout (zaehler); 
+    zwischenzeile := abgeschnitten (eingabezeile); 
+    haenge zeilentrenner an; 
+    haenge zwischenzeile an ausgabezeile; 
+    schreibe ausgabezeile ggf weg 
+  PER; 
+  schreibe ausgabezeile weg; 
+  mache ausgabedatei zur eingabedatei. 
+ 
+  ueberpruefe existenz: 
+    IF NOT exists (dateiname) 
+       THEN errorstop (verweis); 
+    FI. 
+ 
+  ueberpruefe dateityp: 
+    IF type (old (dateiname)) <> filetype 
+       THEN errorstop (falscher typ) 
+    FI. 
+ 
+  initialisiere: 
+    FILE VAR ein := sequential file (input, dateiname); 
+    FILE VAR aus := sequential file (output, "KOMPRIM"); 
+    maxlinelength (aus, 600); 
+    INT VAR zaehler :: 1; 
+    TEXT VAR eingabezeile :: "", zwischenzeile :: "", ausgabezeile :: "". 
+ 
+  haenge zeilentrenner an: 
+    IF zwischenzeile <> "" 
+       THEN zwischenzeile CAT "{}" 
+    FI. 
+ 
+  haenge zwischenzeile an ausgabezeile: 
+    ausgabezeile CAT zwischenzeile. 
+ 
+  schreibe ausgabezeile ggf weg: 
+    IF length (ausgabezeile) > 500 
+       THEN schreibe ausgabezeile weg 
+    FI. 
+ 
+  schreibe ausgabezeile weg: 
+    IF ausgabezeile <> "" 
+       THEN putline (aus, ausgabezeile); 
+            ausgabezeile := "" 
+    FI. 
+ 
+mache ausgabedatei zur eingabedatei: 
+  forget (dateiname, quiet); 
+  rename ("KOMPRIM", dateiname). 
+END PROC komprimiere; 
+ 
+TEXT PROC abgeschnitten (TEXT CONST zeile): 
+  TEXT VAR t :: zeile; 
+  WHILE (t SUB length (t)) = " " REP 
+    t := subtext (t, 1, length (t) - 1) 
+  PER; 
+  t 
+END PROC abgeschnitten; 
+ 
+PROC dekomprimiere (TEXT CONST dateiname): 
+  INT VAR zeiger; 
+  ueberpruefe existenz; 
+  ueberpruefe dateityp; 
+  initialisiere; 
+  FOR zeiger FROM 1 UPTO 24 REP 
+    getline (ein, eingabezeile); 
+    putline (aus, eingabezeile); 
+  PER; 
+  WHILE NOT eof (ein) REP 
+    getline (ein, eingabezeile); 
+    zerlege zeile 
+  PER; 
+  forget (dateiname, quiet); 
+  rename ("DEKOMPRIM", dateiname). 
+ 
+  ueberpruefe existenz: 
+    IF NOT exists (dateiname) 
+       THEN errorstop (verweis) 
+    FI. 
+ 
+  ueberpruefe dateityp: 
+    IF type (old (dateiname)) <> filetype 
+       THEN errorstop (falscher typ) 
+    FI. 
+ 
+  initialisiere: 
+    FILE VAR ein := sequential file (input, dateiname); 
+    FILE VAR aus := sequential file (output, "DEKOMPRIM"); 
+    INT VAR zaehler :: 1; 
+    TEXT VAR eingabezeile :: "",  ausgabezeile :: "". 
+ 
+  zerlege zeile: 
+    WHILE eingabezeile <> "" REP 
+      nimm das erste stueck und schreibe es weg; 
+      entferne den zeilentrenner 
+    PER. 
+ 
+  nimm das erste stueck und schreibe es weg: 
+    ausgabezeile := subtext (eingabezeile, 1, pos (eingabezeile, "{}") - 1); 
+    putline (aus, ausgabezeile); 
+    zaehler INCR 1; 
+    cout (zaehler). 
+ 
+  entferne den zeilentrenner: 
+    eingabezeile := subtext (eingabezeile, pos (eingabezeile, "{}") + 2). 
+END PROC dekomprimiere; 
+END PACKET ls dialog decompress; 
+
diff --git a/dialog/ls-DIALOG-gen b/dialog/ls-DIALOG-gen
new file mode 100644
index 0000000..e085616
--- /dev/null
+++ b/dialog/ls-DIALOG-gen
@@ -0,0 +1,34 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                      ls-DIALOG                      ** 
+          **                  GENERATORPROGRAMM                  ** 
+          **                     Version 1.2                     ** 
+          **                                                     ** 
+          **                  (Stand: 04.11.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+LET mm taskname = "ls-MENUKARTEN",{}    datei 1     = "ls-DIALOG 1",{}    datei 2     = "ls-DIALOG 2",{}    datei 3     = "ls-DIALOG 3",{}    datei 4     = "ls-DIALOG 4",{}    datei 5     = "ls-DIALOG 5",{}    datei 6     = "ls-DIALOG 6",{}    datei 7     = "ls-DIALOG 7",{}    menukarte   = "ls-MENUKARTE:Archiv";{}PROC stelle existenz des mm sicher:{}  cursor (1, 5); out (""4"");{}  IF NOT exists (task (mm taskname)){}     THEN errorstop ("Unbedingt erst den 'MENUKARTEN-MANAGER' generieren!");{}  FI{}
+END PROC stelle existenz des mm sicher;{}PROC vom archiv (TEXT CONST datei):{}  cursor (1,5); out (""4"");{}  out ("  """); out (datei); putline (""" wird geholt.");{}  fetch (datei, archive){}END PROC vom archiv;{}PROC hole (TEXT CONST datei):{}  IF NOT exists (datei) THEN vom archiv (datei) FI{}END PROC hole;{}PROC in (TEXT CONST datei):{}  hole (datei);{}  cursor (1, 5); out (""4"");{}  out ("  """); out (datei); out (""" wird übersetzt: ");{}  insert (datei);{}  forget (datei, quiet);{}END PROC in;{}
+PROC schicke (TEXT CONST datei):{}  cursor (1, 5); out (""4"");{}  out ("  """); out(datei);{}  out (""" wird zum MENUKARTEN-MANAGER geschickt!");{}  command dialogue (FALSE);{}  save (datei, task (mm taskname));{}  command dialogue (TRUE);{}  forget (datei, quiet){}END PROC schicke;{}INT VAR size, used;{}BOOL VAR einzeln;{}storage (size, used);{}einzeln := size - used < 500;{}forget ("ls-DIALOG/gen", quiet);{}wirf kopfzeile aus;{}stelle existenz des mm sicher;{}hole die dateien;{}insertiere die dateien;{}
+mache global manager aus der task.{}wirf kopfzeile aus:{}  page;{}  putline ("                      "15"ls-DIALOG - Automatische Generierung "14"").{}hole die dateien:{}  IF     NOT exists (datei 1) COR NOT exists (datei 2){}     COR NOT exists (datei 3) COR NOT exists (datei 4){}     COR NOT exists (datei 5) COR NOT exists (datei 6){}     COR NOT exists (datei 7) COR NOT exists (menukarte){}     THEN hole dateien vom archiv{}  FI.{}hole dateien vom archiv:{}  cursor (1,3);{}  IF yes ("Ist das Archiv angemeldet und die 'ls-DIALOG' - Diskette eingelegt"){}
+     THEN lese ein{}     ELSE line (2);{}          errorstop ("Ohne die Diskette kann ich das System nicht generieren!"){}  FI.{}lese ein:{}  cursor (1, 3); out (""4"");{}  out ("                      "15"Bitte die Diskette eingelegt lassen! "14"");{}  IF NOT einzeln{}     THEN hole (datei 1);{}          hole (datei 2);{}          hole (datei 3);{}          hole (datei 4);{}          hole (datei 5);{}          hole (datei 6);{}          hole (datei 7);{}          hole (menukarte);{}          cursor (1, 3); out(""4"");{}
+          out ("                     "15"Die Diskette wird nicht mehr benötigt! "14"");{}          release (archive){}  FI.{}insertiere die dateien:{}  check off;{}  in (datei 1);{}  in (datei 2);{}  in (datei 3);{}  in (datei 4);{}  in (datei 5);{}  in (datei 6);{}  in (datei 7);{}  schicke (menukarte);{}  IF einzeln THEN release (archive) FI;{}  check on.{}mache global manager aus der task:{}  global manager.{}
+
+
+
+
diff --git a/dialog/ls-MENUKARTE:Archiv b/dialog/ls-MENUKARTE:Archiv
new file mode 100644
index 0000000..c859d22
Binary files /dev/null and b/dialog/ls-MENUKARTE:Archiv differ
diff --git a/doc/basic/basic handbuch.1 b/doc/basic/basic handbuch.1
new file mode 100644
index 0000000..2e604cb
--- /dev/null
+++ b/doc/basic/basic handbuch.1	
@@ -0,0 +1,1075 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#Basic 
+ 
+ 
+ 
+ 
+#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# 
+#page nr ("%", 1)# 
+#head# 
+EUMEL-BASIC-Compiler         Inhalt                          % 
+#end# 
+ 
+Inhalt 
+ 
+1  Einleitung                                                3 
+ 
+2  Installation des BASIC-Compilers                          4 
+ 
+3  Aufruf und Steuerung des BASIC-Compilers                  5 
+ 
+4  Umgang mit dem BASIC-Compiler                             7 
+4.1  Erläuterungen zur Syntax                                7 
+4.2  Datentypen und Konstanten                               10 
+4.3  Variablen und Felder                                    12 
+4.4  Operatoren                                              14 
+4.5  Funktionen                                              19 
+4.6  Typanpassung                                            22 
+4.7  Aufruf von EUMEL-Prozeduren in BASIC-Programmen         23 
+ 
+5  Steuerung der Bildschirmausgaben                          25 
+ 
+6  Grenzen des Compilers                                     26 
+ 
+7  Fehlerbehandlung                                          28 
+7.1  Fehler zur Übersetzungszeit                             28 
+7.2  Fehler zur Laufzeit                                     30 
+ 
+8  Übersicht über die Anweisungen und Funktionen             31 
+ 
+9  Anpassung von Programmen an den EUMEL-BASIC-Compiler      96 
+9.1  Unterschiede zwischen BASIC-Interpretern 
+     und dem EUMEL-BASIC-Compiler                            96 
+9.2  Abweichungen von ISO 6373-1984 (Minimal-BASIC)          97 
+9.3  Anpassung von Microsoft-BASIC Programmen 
+     an den EUMEL-BASIC-Compiler                             98 
+ 
+Anhang A: Reservierte Wörter                                100 
+Anhang B: Vom Scanner erkannte Symboltypen                  103 
+Anhang C: Übersicht über die Fehlermeldungen                106 
+Anhang D: ELAN-Prozeduren des Compilers                     113 
+#page# 
+ 
+ 
+#page nr ("%", 3)# 
+#head# 
+EUMEL-BASIC-Compiler                1. Einleitung              % 
+ 
+#end# 
+ 
+1. Einleitung 
+ 
+ 
+BASIC entspricht heute nicht mehr den Vorstellungen von einer modernen Program­
+miersprache. Dennoch wurde für das EUMEL-Betriebssystem ein Compiler für BASIC
+entwickelt. Er soll vor allem dazu dienen, schon bestehende BASIC-Programme -
+gegebenenfalls nach entsprechender Anpassung -  auch unter EUMEL verfügbar zu
+machen. 
+Der Compiler ist weitgehend an die ISO-Norm 6373 für Minimal-BASIC angelehnt.
+Die Syntax und Bedeutung der Anweisungen orientiert sich in den meisten Fällen an
+Microsoft-BASIC. Anweichungen treten insbesondere an den Stellen auf, an denen
+Prinzipien des Betriebssystems EUMEL verletzt würden. 
+Verglichen mit dem ELAN-Compiler des EUMEL-Systems ist der BASIC-Compiler
+beim Übersetzen recht langsam. Auch aus diesem Grund scheint es nicht sinnvoll,
+den BASIC-Compiler zur Neuentwicklung größerer Programme einzusetzen. 
+ 
+Sinn dieses Handbuchs ist es vor allem, Kenntnisse über den Umgang mit dem
+EUMEL-BASIC-Compiler zu vermitteln. Das Handbuch ist auf keinen Fall als Ein­
+führung in die Programmiersprache BASIC gedacht, sondern es soll dem Benutzer mit
+BASIC-Erfahrung die Arbeit mit dem EUMEL-BASIC-Compiler ermöglichen und
+erleichtern. Neben Erfahrung in BASIC setzt dieses Buch an einigen Stellen auch
+Grundkenntnisse über das EUMEL-System voraus. 
+ 
+ 
+ 
+Zur #ib(4)#Notation#ie(4)# in dieser Beschreibung 
+ 
+Bei der Beschreibung der Anweisungen und Funktionen und auch an anderen Stellen
+werden in dieser Beschreibung Syntaxregeln für BASIC-Programme oder Teile davon
+angegeben. Dabei werden folgende Zeichen mit besonderer Bedeutung verwendet: 
+ 
+[ ]       optionale Angabe 
+[...]     beliebig häufige Wiederholung der letzten optionalen Angabe 
+|         alternative Angabe, d.h. entweder die letzte links stehende Angabe oder
+          die nächste rechts stehende Angabe, aber nicht beide 
+< >       in spitzen Klammern stehende Begriffe sind entweder definiert (z.B. <Va­
+          riable>) oder werden hinter der Syntaxregel erläutert 
+ 
+Die Notation der exportierten ELAN-Prozeduren des Compilers (besonders in An­
+hangD) entspricht der in den EUMEL-Handbüchern üblichen Prozedurkopf-
+Schreibweise. 
+#page# 
+#head# 
+EUMEL-BASIC-Compiler      2. Installation des BASIC-Compilers       % 
+ 
+#end#
+ 
+2. #ib(3)#Installation des BASIC-Compilers#ie(3)# 
+ 
+ 
+Der EUMEL-BASIC-Compiler wird auf zwei Disketten mit jeweils 360 KByte
+Speicherkapazität ausgeliefert. 
+Auf der Diskette "BASIC.1" befindet sich das #ib(3)#Generatorprogramm#ie(3)#("gen.BASIC") zur 
+Installation des EUMEL-BASIC-Systems. 
+Legen Sie diese Diskette in das Laufwerk ihres Rechners ein und geben Sie in der
+Task, in der das BASIC-System installiert werden soll, folgende Zeile nach 'gib
+kommando :' (oder 'maintenance :') ein: 
+ 
+archive ("BASIC.1"); fetch ("gen.BASIC", archive); run 
+ 
+Lassen Sie die Diskette 'BASIC.1' im Laufwerk und antworten Sie auf die Frage
+"Archiv "BASIC.1" eingelegt(j/n)?" mit "j". Das Generatorprogramm holt nun einige
+Dateien von der Diskette. Nach Zugriff auf das Archiv erscheint die Meldung "Archiv
+abgemeldet!" und die Frage "Archiv 'BASIC.2' eingelegt(j/n)?". Legen Sie nun statt
+des Archivs 'BASIC.1' das Archiv 'BASIC.2' in das Laufwerk ein und drücken Sie bitte
+wiederum "j". Nach weiteren Archivoperationen erscheint dann wieder die Meldung
+"Archiv abgemeldet". Sie können nun die Diskette "BASIC.2" aus dem Laufwerk
+entnehmen. 
+Das Generatorprogramm insertiert nun alle Programme des BASIC-Systems in der
+Task. Dieser Vorgang nimmt einige Zeit in Anspruch. Zum Abschluß erscheint die
+Meldung "BASIC-System installiert". 
+Der EUMEL-BASIC-Compiler steht Ihnen nun in der Task (und in nachfolgend
+eingerichteten Söhnen) zur Verfügung. 
+#page# 
+#head# 
+EUMEL-BASIC-Compiler     3. Aufruf und Steuerung des BASIC-Compilers   % 
+ 
+#end# 
+ 
+3. #ib(4)#Aufruf und #ib(3)#Steuerung des BASIC-Compilers#ie(3)##ie(4)# 
+    
+ 
+ 
+ 
+Übersetzen von BASIC-Programmen 
+ 
+Ein BASIC-Programm, das vom Compiler übersetzt werden soll, muß sich dazu in
+einer EUMEL-Textdatei befinden (Syntax vgl. Kap. 4.). Steht das BASIC-Programm
+zum Beispiel in der Datei "Programm.17+4", so wird der Compiler mit 
+ 
+    #ib(3)#basic#ie(3)# ("Programm.17+4") 
+ 
+zum Übersetzen dieses Programms aufgerufen. 
+In einem Vordurchlauf werden die Zeilennummern des Programms auf Richtigkeit
+überprüft. Beim eigentlichen Compilerdurchlauf wird das BASIC-Programm dann mit
+Hilfe des EUMEL-Coders in einen von der EUMEL-0-Maschine ausführbaren Code
+übersetzt. 
+ 
+Das Programm wird mit 'check on' (Zeilennummergenerierung) übersetzt. 
+Ein 'runagain' wie bei ELAN-Programmen ist bei BASIC-Programmen zur Zeit
+leider nicht möglich. 
+ 
+ 
+ 
+Insertieren von BASIC-Programmen 
+ 
+Der BASIC-Compiler kann BASIC-Programme auch insertieren. Das ganze Pro­
+gramm bildet dabei eine Prozedur, die nach dem Insertieren wie eine 'normale'
+ELAN-Prozedur aufgerufen werden kann. 
+Zum Insertieren wird der Compiler mit einem zusätzlichen Text-Parameter aufge­
+rufen: 
+ 
+    #ib(3)#basic#ie(3)# ("Programm.17+4", "blackjack") 
+ 
+Das Programm wird übersetzt und, falls keine Fehler gefunden wurden, fest einge­
+tragen ('insertiert'). Gestartet wird das Programm aber nicht. 
+"blackjack" ist nun der Prozedurname, unter dem das BASIC-Programm nach erfolg­
+reichem Insertieren aufgerufen werden kann. 
+Bei 'packets' erscheint jetzt der Eintrag 'BASIC.blackjack' in der Liste der insertierten
+Pakete, und ein 'help ("blackjack")' zeigt, daß eine Prozedur 'blackjack' nun tatsäch­
+lich in der Task bekannt ist. Die Prozedur 'bulletin' funktioniert für insertierte
+BASIC-Programme nicht. Sie ist aber auch nicht nötig, da das 'Paket' mit dem
+BASIC-Programm ohnehin nur eine Prozedur enthält und ihr Name ja schon aus
+dem Namen des Paketes hervorgeht. 
+ 
+#on ("b")# 
+Beachten Sie: 
+  - Der Prozedurname muß der Syntax für ELAN-Prozedurnamen entsprechen, darf
+    aber #on ("b")#keine Leerzeichen enthalten. 
+  - Die BASIC-Programme können über den Prozedurnamen nur aufgerufen wer­
+    den; die Übergabe von Parametern ist ebenso wie Wertlieferung nicht möglich. 
+  - Jedes Insertieren belegt Speicherplatz im Codebereich der Task. Weil der Coder
+    und der Compiler ebenfalls recht viel Code belegen, kann es (vor allem, wenn
+    die BASIC-Programme lang sind) schnell zu einem Code-Überlauf kommen
+    (Compiler Error 305). Es sollten daher nur die Programme insertiert werden, für
+    die dies wirklich nötig ist. 
+  - Achten Sie bei der Wahl des Namens für die gelieferte Prozedur darauf, daß sie
+    nicht ungewollt Prozeduren des Betriebssystems überdecken. (Der Aufruf 'ba­
+    sic("tadellos","help")' wäre z.B. gar nicht tadellos, denn 'help' wäre nach dem
+    Insertieren überdeckt). 
+  - Auch beim Insertieren werden die BASIC-Programme mit 'check on' übersetzt. 
+#off ("b")#  
+ 
+ 
+Ausgabe der übersetzten Zeilen während des
+Compilierens 
+Mit '#ib(3)#basic list#ie(3)# (TRUE)' wird der Compiler so eingestellt, daß beim Übersetzen die
+aktuelle Programmzeile ausgegeben wird. Diese Ausgabe kann auch mit '#ib(3)#sysout#ie(3)#'
+umgeleitet werden. Zum Beispiel: 
+ 
+   sysout ("Fehlerprotokoll"); basic ("Programm.17+4") 
+ 
+Dies kann beim #ib(3)#Debugging#ie(3)# von BASIC-Programmen eine wertvolle Hilfe sein, da in
+der Ausgabedatei die Fehler sofort hinter der betreffenden Programmzeile vermerkt
+werden. Das 'sysout' muß in Monitortasks ('gib kommando:') direkt vor dem Aufruf
+des Compilers gegeben werden, weil der Monitor 'sysout' sonst wieder zurücksetzt. 
+ 
+Mit 'basic list (FALSE)' kann die Ausgabe der Programmzeilen beim Übersetzen
+wieder ausgeschaltet werden. 
+ 
+#page# 
+#head# 
+EUMEL-BASIC-Compiler       4. Umgang mit dem BASIC-Compiler       % 
+ 
+#end# 
+ 
+4. Umgang mit dem BASIC-Compiler 
+ 
+ 
+ 
+4.1. Erläuterungen zur #ib(3)#Syntax#ie(3)# 
+ 
+ 
+Ein zu übersetzendes Programm muß dem BASIC-Compiler in Form einer
+#ib(3)#EUMEL-Textdatei#ie(3)# übergeben werden. (Es gelten somit auch die für EUMEL-Text­
+dateien üblichen Begrenzungen, z.B. höchstens 32000 Zeichen pro Zeile und höch­
+stens 4075 Dateizeilen pro Datei.) 
+BASIC-Programme setzen sich aus Programmzeilen zusammen; jede Dateizeile der
+#ib(3)#Programmdatei#ie(3)# bildet eine BASIC-Programmzeile. Die Syntax für ein Programm sieht
+damit so aus: 
+ 
+ 
+<Programmzeile>[<Programmzeile>][...]EOF 
+ 
+Dabei bedeutet #ib(3)#EOF (end of file)#ie(3)# das Ende der Programmdatei. 
+ 
+Eine #ib(3)#Programmzeile#ie(3)# hat folgende Syntax: 
+ 
+ 
+[<Zeilennummer>][<Anweisung>][:<Anweisung>][...][:]EOL 
+ 
+Die #ib(3)#Zeilennummer#ie(3)# dient unter anderem als Sprungadresse an den Anfang der Pro­
+grammzeile während der Laufzeit des Programms (vgl. 'GOTO' und 'GOSUB'). Sie ist
+fakultativ (d.h. sie muß nicht geschrieben werden). Durch sparsame Verwendung von
+Zeilennummern (nämlich nur da, wo sie benötigt werden) kann eine gewisse Steige­
+rung der #ib(3)#Übersichtlichkeit von BASIC-Programmen#ie(3)# erreicht werden. Hat eine Pro­
+grammzeile keine Zeilennummer, so wird bei Fehlermeldungen (sowohl während der
+Übersetzung als auch zur Laufzeit des Programms) die letzte Zeilennummer mit
+angegeben, die davor auftrat. 
+Zeilennummern dürfen im Bereich von 1 bis 32767 liegen und müssen unbedingt in
+aufsteigender Reihenfolge vergeben werden. Zeilennummern dürfen keine Leerzeichen
+enthalten und müssen mit einem Leerzeichen abgeschlossen werden. Um spätere
+Ergänzungen zu ermöglichen, ist eine Numerierung im Abstand zehn empfehlenswert. 
+ 
+Hier ein Beispiel, wie ein BASIC-Programm in einer EUMEL-Datei aussehen
+könnte: 
+ 
+ 
+...........................Einmaleins............................ 
+10 CLS: PRINT "Kleines Einmaleins" 
+   FOR zahl% = 1 TO 10 
+     PRINT 
+     'Erzeugung einer Zeile 
+     FOR faktor% = 1 TO 10 
+       PRINT TAB (faktor% * 5); 
+       PRINT USING "\#\#\#"; faktor% * zahl%; 
+     NEXT faktor% 
+   NEXT zahl% 
+ 
+ 
+ 
+ 
+Die Syntax der Anweisungen, die vom EUMEL-BASIC-Compiler übersetzt werden
+können, ist ausführlich im Kapitel 8 beschrieben. 
+ 
+Der #ib(3)#Doppelpunkt#ie(3)# dient als Trennzeichen zwischen Anweisungen. Ihm muß nicht
+unbedingt eine Anweisung folgen. Er kann somit als explizites "Ende der
+Anweisung"-Symbol aufgefaßt werden (#ib(3)#EOS, "end of statement"#ie(3)#). 
+ 
+#ib(3)#EOL (end of line)#ie(3)# ist das Ende einer Dateizeile. (Dieses "Zeichen" ist ebenso wie
+EOF beim Editieren der Datei nicht sichtbar.) 
+Das #ib(3)#Hochkomma#ie(3)# ("'", Code 39) wird vom Compiler ebenfalls als EOL interpretiert.
+Alle dem Hochkomma in der Dateizeile folgenden Zeichen werden überlesen. Dies
+ermöglicht das Schreiben von Kommentaren ohne Verwendung der
+'REM'-Anweisung. 
+ 
+Es sei hier bereits bemerkt, daß sich durch die Realisierung des Übersetzers als
+#on ("b")#Compiler gewisse Unterschiede gegenüber Interpretern #off ("b")#ergeben (siehe hierzu Kap. 9).
+Der wesentliche Unterschied ist, daß der Interpreter dem Programmtext analog zum
+Programmablauf folgt, der Compiler das Programm aber von vorne bis hinten Zeile für
+Zeile übersetzt. Dies hat zur Folge, daß z.B. die Dimensionierungen von Feldvariablen
+#on ("b")#textuell vor der Verwendung der Variablen stattfinden müssen#off ("b")# und nicht, wie bei
+Interpretern, nur im Ablauf des Programms vorher ausgeführt werden müssen. 
+ 
+ 
+ 
+Weitere Schreibregeln 
+ 
+#on ("b")# 
+1. #ib(3)#Groß-/Kleinschreibung#ie(3)##off ("b")# 
+Für den BASIC-Compiler bestehen zwischen kleinen und großen Buchstaben keiner­
+lei Unterschiede, es sei denn es handelt sich um Textdenoter (Textkonstanten). 
+Daher können alle #ib(3)#Schlüsselwörter#ie(3)# und #ib(3)#Variablennamen#ie(3)# mit kleinen oder großen
+Buchstaben geschrieben werden. Aus der Tatsache, daß zwischen großen und kleinen
+Buchstaben nicht unterschieden wird, folgt aber bespielsweise auch, daß die Variab­
+lennamen (vgl. 4.3.) 'hallo' und 'HALLO' ein und dieselbe Variable bezeichnen. 
+ 
+#on ("b")# 
+2. #ib(3)#Reservierte Wörter#ie(3)##off ("b")# 
+Der BASIC-Compiler erkennt eine ganze Reihe #on("i")#reservierter Wörter#off("i")#. Es handelt sich
+hierbei im wesentlichen um die Namen der Anweisungen und Funktionen. Sie sollten
+im eigenen Interesse darauf achten, daß sich sowohl vor als auch hinter reservier­ 
+ten Wörtern stets mindestens ein #on ("b")##ib(3)#Leerzeichen#ie(3)##off ("b")# (Blank) befindet. Der #ib(3)#Scanner#ie(3)# (ver­
+gleiche AnhangB) erkennt zwar manchmal die reservierten Wörter auch ohne Leer­
+zeichen, aber unter bestimmten Umständen kann es auch zu erkannten oder - noch
+schlimmer -  vom Compiler unerkannten Fehlern kommen. 
+Hierzu zwei Beispiele: 
+Die Anweisung 'IF a > b THENPRINT "größer"' führt beim Compilieren zur Fehler­
+meldung "Syntaxfehler:   THEN oder GOTO erwartet". 
+Wesentlich gefährlicher ist da schon die Programmzeile 
+     "LEThallo = 3 : PRINT hallo", 
+denn die unerwartete Wirkung ist die Ausgabe von "0" auf dem Bildschirm. Der Wert
+"3" wurde nämlich nicht der Variablen mit dem Namen "hallo" zugewiesen, sondern
+einer Variablen namens "LEThallo". 
+ 
+#on ("b")# 
+3. Bedeutung der #ib(3)#Leerstelle#ie(3)# ("Blank") für den Compiler#off("b")# 
+Wie schon aus dem vorhergehenden Punkt ersichtlich kann das Fehlen von trennen­
+den Leerstellen unschöne Effekte haben, denn der #ib(3)#Scanner#ie(3)# (vgl. AnhangB) des
+BASIC-Compilers erkennt anhand der Leerstelle (Code 32) beim Durchlauf durch das
+Programm, daß ein #ib(3)#Symbol#ie(3)# zu Ende ist. 
+Es kommt somit immer dann zu Fehlern, wenn zwei Symbole (z.B. reservierte Wörter,
+Konstanten, Variablen etc.) nicht durch Leerzeichen getrennt sind, und der Scanner
+sie als ein Symbol "versteht". 
+Beispiel: 
+     "a = 3 : b = 4 : PRINT a b"   erzeugt die Ausgabe "34". 
+     "a = 3 : b = 4 : PRINT ab"    erzeugt hingegen die Ausgabe "0", denn der
+Compiler sieht "ab" als #on ("b")#einen Variablennamen an. #off ("b")# 
+ 
+ 
+ 
+4.2. #ib(3)#Datentypen#ie(3)# und #ib(3)#Konstanten#ie(3)# 
+ 
+ 
+Der EUMEL-BASIC-Compiler unterscheidet grundsätzlich zwischen zwei Daten­
+typen, nämlich zwischen #ib(3)#Texte#ie(3)#n und #ib(3)#Zahlen#ie(3)#. 
+ 
+#on ("b")# 
+#ib(3)#Datentyp TEXT#ie(3)# #off ("b")# 
+Texte dürfen alle Zeichen enthalten (Codes 0 bis 255) und bis zu 32000 Zeichen lang
+sein. 
+Die zugehörigen Konstanten werden von #ib(3)#Anführungszeichen#ie(3)# begrenzt, z.B.: 
+  "Anzahl Einträge: " 
+  "2.32 DM" 
+  "General-Musik-Direktor" 
+Anführungszeichen (Code 34) dürfen #on("i")#innerhalb#off("i")# von Text-Konstanten nicht vor­
+kommen. 
+ 
+Bei Zahlen unterscheidet der Compiler noch zwischen #ib(3)#INTs#ie(3)# (#ib(3)#Ganzzahlen#ie(3)#) und REALs
+(#ib(3)#Gleitkommazahlen#ie(3)#). Diese entsprechen im Hinblick auf den Wertebereich genau den
+in ELAN bekannten INTs und REALs. 
+ 
+#on ("b")# 
+#ib(3)#Datentyp INT#ie(3)# #off ("b")# 
+INT-Werte dürfen zwischen -32768 und 32767 liegen. INT-Konstanten dürfen aber
+#on("i")#nur#off("i")# aus Ziffern und einem optionalen '%'-Zeichen am Ende bestehen. Das bedeutet,
+daß die INT-Konstanten im Bereich von 0 bis 32767 liegen können. 
+Ein nachgestelltes '%'-Zeichen kennzeichnet eine Konstante nochmals explizit als
+INT. (Diese Option wurde aus Kompatibilitätsgründen implementiert.) 
+ 
+#on ("b")# 
+#ib(3)#Datentyp REAL#ie(3)# #off ("b")# 
+REALs können Werte zwischen -9.999999999999*10#u#126#e# und 
+9.999999999999*10#u#126#e# annehmen. 
+Die kleinste positive von Null verschiedene Zahl ist 9.999999999999*10#u#-126#e#. 
+Der kleinste REAL-Wert mit x + 1.0 > 1.0 ist gleich 10#u#-12#e#. 
+REAL-Konstanten werden gebildet aus Vorkommastellen, Dezimalpunkt, Nachkom­
+mastellen, Zeichen "E" oder "D" (jeweils auch klein) für den #ib(3)#Exponent#ie(3)#en gefolgt vom
+Vorzeichen und den Ziffern des Exponenten. 
+Dabei müssen nicht für jede REAL-Konstante alle diese Elemente benutzt werden.
+Unverzichtbar sind #on("i")#entweder#off("i")# der Dezimalpunkt #on("i")#oder#off("i")# der Exponent. Ebenso müssen
+zumindest entweder Vor- oder Nachkommastellen vorhanden sein. 
+ 
+Beispiele für gültige REAL-Konstanten sind: 
+  0. 
+  .01 
+  1E-17 
+  2.9979D8 
+  .3e-102 
+  100.e+7 
+ 
+Nicht erlaubt sind dagegen folgende Schreibweisen für REAL-Konstanten: 
+  e12         (#ib(3)#Mantisse#ie(3)# fehlt) 
+  100         (ist INT-Konstante) 
+  .           (weder Vor- noch Nachkommastellen) 
+  .E-12       (dito) 
+  1exp-3      ('exp' nicht erlaubt) 
+  -1.99e30    (Mantisse hat Vorzeichen) 
+ 
+Das letzte Beispiel zeigt, daß auch vor REAL-Konstanten keine #ib(3)#Vorzeichen#ie(3)# erlaubt
+sind. Da normalerweise keine REAL-Konstanten, sondern vielmehr numerische
+Ausdrücke verlangt werden, können durch Voranstellen des Operators '-' (vgl. 4.4.)
+auch #ib(3)#negative Zahlenwerte#ie(3)# leicht erzeugt werden. 
+ 
+An REAL-Konstanten darf eines der Zeichen "!" und "\#" angehängt werden. Diese
+Option wurde aus Kompatibilitätsgründen eingebaut. Wird ein "!" oder "\#" an eine
+INT-Konstante angehängt, so verwandelt es diese in eine REAL-Konstante. 
+Beispiel: 10000! oder 10000\# entspricht 10000. oder 1E4 
+ 
+ 
+#page# 
+ 
+4.3. Variablen und Felder 
+ 
+ 
+Variablen 
+ 
+Der BASIC-Compiler stellt für die in 4.2. vorgestellten Datentypen TEXT, INT und
+REAL auch Variablen zur Verfügung. 
+Die #ib(3)#Variablennamen#ie(3)# müssen folgenden Bedingungen genügen: 
+- Ein Variablenname muß mit einem Buchstaben beginnen. 
+- Variablennamen dürfen ab der zweiten Stelle außer Buchstaben auch Ziffern, Dezi­
+  malpunkte sowie die Zeichen "!", "\#", "$" und "%" enthalten. Leerzeichen dürfen
+  in Variablennamen dagegen nicht vorkommen. 
+- Variablennamen dürfen nicht mit FN beginnen (vgl. 4.5. benutzer-definierte Funk­
+  tionen). 
+- #ib(3)#Reservierte Wörter#ie(3)# (siehe Anhang A) dürfen kein Variablenname sein. Als Teiltexte
+  dürfen reservierte Wörter aber in Variablennamen enthalten sein (auch am Anfang). 
+ 
+Variablennamen dürfen beliebig lang sein, und alle Zeichen eines Variablennamens
+sind signifikant. 
+ 
+Welchen Typ eine Variable hat, entscheidet der Compiler nach folgenden #ib(3)#Kriterien#ie(3, " für den Typ einer Variablen")# (in
+der Reihenfolge ihrer Beachtung): 
+- Ist das letzte Zeichen des Namens ein "!" oder "\#", so bezeichnet er eine
+  REAL-Variable. 
+- Ist das letzte Zeichen ein "%", so handelt es sich um eine INT-Variable. 
+- Ist das letzte Zeichen des Namens ein "$", so ist die Variable vom Typ TEXT. 
+- Liegt das erste Zeichen des Namens im Bereich der mit einer #ib(3)#DEFINT#ie(3)#-Anweisung
+  (vgl. Kap. 8) festgelegten Buchstaben, so ist die Variable eine INT-Variable. 
+- Liegt das erste Zeichen im Bereich der mit einer #ib(3)#DEFSTR#ie(3)#-Anweisung (vgl. Kap. 8)
+  festgelegten Buchstaben, so handelt es sich um eine TEXT-Variable. 
+- Wenn keine der obigen Bedingungen erfüllt ist, dann bezeichnet der Name eine
+  Variable des Datentyps REAL. 
+ 
+Variablen, denen noch kein Wert zugewiesen wurde, haben den Inhalt null (bei INT
+und REAL) beziehungsweise Leertext (bei TEXT). 
+ 
+ 
+ 
+Felder (#ib(4)#Arrays#ie(4)#) 
+ 
+Ein Feld (Array) ist eine Ansammlung von mehreren Variablen gleichen Typs. Jedes
+Feld hat einen Namen. Für die #ib(3)#Feldnamen#ie(3)# gelten die gleichen Regeln wie für die
+Namen von normalen Variablen. Auch die Datentypen werden nach den gleichen
+Kriterien bestimmt wie bei einfachen Variablen. 
+In einem Feld können die Elemente in bis zu 100 #ib(3)#Dimensionen#ie(3)# abgelegt werden. Auf
+ein Element eines Feldes wird über den Feldnamen und den Index / die #ib(3)#Indizes#ie(3)# des
+Elements zugegriffen. Beim Zugriff auf das Element müssen so viele Indizes ange­
+geben werden, wie das Feld Dimensionen hat. 
+Beispiel: 
+Das Feld 'tabelle' habe zwei Dimensionen. Mit 'tabelle (3, 5)' wird auf das Element
+mit dem Index 3 in der ersten Dimension und dem Index 5 in der zweiten Dimension
+zugegriffen. 
+ 
+Beim ersten Zugriff auf ein Element eines Feldes wird anhand der Zahl der Indizes
+die Anzahl der Dimensionen festgestellt und das Feld so eingerichtet, daß in jeder
+Dimension der größte Index zehn ist. 
+Soll ein Feld mit anderen größten Indizes eingerichtet werden, so muß hierzu die
+#ib(3)#DIM#ie(3)#-Anweisung verwendet werden (siehe Kapitel 8). 
+ 
+Der kleinste Index ist voreingestellt auf null, kann aber mit der #ib(3)#OPTION BASE#ie(3)#-
+Anweisung (vgl. Kap. 8) auch auf eins eingestellt werden. 
+ 
+Die Elemente eines Feldes sind, wie auch die einfachen Variablen, mit den Werten
+null (INT und REAL) beziehungsweise Leertext (TEXT) vorbesetzt, sofern ihnen noch
+nichts zugewiesen wurde. 
+ 
+#page# 
+ 
+4.4. Operatoren 
+ 
+Nachfolgend sind alle Operatoren aufgelistet, die vom EUMEL-BASIC-Compiler
+übersetzt werden. 
+ 
+ 
+Arithmetische #ib(4)#Operatoren#ie(4, ", arithmetische")# 
+ 
+#ib(3)##ie(3, "+")##ib(3)##ie(3, "-")##ib(3)##ie(3, "*")##ib(3)##ie(3, "/")# 
+#ib(3)##ie(3, "\")##ib(3)##ie(3, "MOD")##ib(3)##ie(3, "^")# 
+ 
+      Operand(en)    Zweck                            Ergebnistyp 
+ 
+ +    INT            positives Vorzeichen             INT 
+      REAL           positives Vorzeichen             REAL 
+ 
+      INT, INT       INT-Addition                     INT 
+      REAL, REAL     REAL-Addition                    REAL 
+ 
+ -    INT            negatives Vorzeichen             INT 
+      REAL           negatives Vorzeichen             REAL 
+ 
+      INT, INT       INT-Subtraktion                  INT 
+      REAL, REAL     REAL-Subtraktion                 REAL 
+ 
+ *    INT, INT       INT-Multiplikation               INT 
+      REAL, REAL     REAL-Multiplikation              REAL 
+ 
+ /    (INT, INT)   #linefeed (0.5)# 
+                     REAL-Division                    REAL 
+      REAL, REAL   #linefeed (1.0)# 
+ 
+ \    INT, INT     #linefeed (0.5)# 
+                     INT-Division                     INT 
+      (REAL, REAL) #linefeed (1.0)# 
+ 
+MOD   INT, INT       INT-Divisionsrest                INT 
+      REAL, REAL     Divisionsrest nach               REAL 
+                     Runden auf Ganzzahl (nicht INT) 
+ 
+ ^    (INT, INT)   #linefeed (0.5)# 
+                     Potenzierung                     REAL 
+      REAL, REAL   #linefeed (1.0)# 
+ 
+ 
+#on ("b")# 
+Hinweis: #off ("b")# 
+Wird ein Operator mit numerischen Operanden unterschiedlichen Typs (also INT und
+REAL) aufgerufen, so wird der INT-Operand nach REAL konvertiert und der Operator
+mit den beiden REAL-Operanden aufgerufen. 
+Sind die Operandtypen in Klammern angegeben, so werden vor Ausführung der Ope­
+ration die Operanden zu den nicht eingeklammerten Typen konvertiert. 
+Da jede #ib(3)#Konvertierung#ie(3)# Zeit benötigt, sollte der Benutzer darauf achten, daß möglichst
+wenig konvertiert werden muß. 
+Hierzu ein (etwas extremes, aber nicht seltenes) Beispiel: 
+Der Aufruf a%\b bewirkt zunächst eine Konvertierung von a% nach REAL:
+CDBL(a%)\b. Intern wird die Berechnung dann aber wieder mit INTs ausgeführt:
+CINT(CDBL(a%))\CINT(b). Das Ergebnis wird also erst nach drei Konvertierungen
+geliefert. Schreibt man dagegen sofort a%\CINT(b), dann reicht eine Konvertierung
+aus. 
+ 
+Es muß außerdem bei den Operatoren +, - und * für INTs darauf geachtet werden,
+daß das Ergebnis innerhalb des INT-Wertebereichs liegen muß, da es sonst zu
+einem #ib(3)#INT-Überlauf#ie(3)# kommt. 
+ 
+ 
+ 
+Text-Operator #ib(4)#+#ie(4)# 
+ 
+#ib(3)##ie(3, "Operatoren, Text-")# 
+Für Text-Manipulationen wird der Operator '+' mit zwei TEXT-Operanden zur
+Verfügung gestellt. Mit '+' werden zwei Texte aneinandergehängt (konkateniert). 
+ 
+ 
+ 
+Vergleichsoperatoren#ib(4)##ie(4, "Operatoren, Vergleichs-")# 
+ 
+Im EUMEL-BASIC gibt es folgende Vergleichsoperatoren: 
+ 
+#ib(3)#=#ie(3)#     gleich 
+#ib(3)#<>#ie(3)#    ungleich 
+#ib(3)#<#ie(3)#     kleiner 
+#ib(3)#>#ie(3)#     größer 
+#ib(3)#<=#ie(3)#    kleiner oder gleich 
+#ib(3)#>=#ie(3)#    größer oder gleich 
+ 
+Bei den numerischen Datentypen werden mit den Vergleichsoperatoren die Zahlen­
+werte verglichen. 
+Sollen ein INT und ein REAL verglichen werden, dann wird der INT vorher nach
+REAL konvertiert und ein REAL-Vergleich vorgenommen. 
+ 
+Bei Texten dienen die Vergleichsoperatoren zum Vergleich der Zeichencodes. Dies
+ermöglicht zum Beispiel ein alphabetisches Sortieren von Wörtern, mit der Einschrän­
+kung, daß Groß- und Kleinbuchstaben unterschiedliche Zeichencodes haben (ver­
+gleiche EUMEL-Zeichensatz-Tabelle im Benutzerhandbuch) und somit verschieden
+eingeordnet werden. 
+Es gilt a$ < b$, wenn die Zeichenkette in a$ codemäßig vor der Zeichenkette in b$
+           steht:     "a" < "b"  (TRUE) "aa"< "a"  (FALSE) 
+ 
+ 
+Die Vergleichsoperatoren liefern, je nachdem ob die Aussage wahr oder falsch ist, die
+INT-Werte 0 (falsch) oder -1 (wahr). 
+Anhand des Ergebnisses einer Vergleichsoperation kann zum Beispiel der Programm­
+ablauf gesteuert werden (siehe Kapitel 8, IF-Anweisung). 
+ 
+ 
+ 
+Logische Operatoren 
+ 
+#ib(3)##ie(3, "Operatoren, logische")# 
+Die logischen Operatoren haben zwei Aufgaben: 
+1. logische (Boolsche) Verknüpfung von #ib(3)#Wahrheitswerte#ie(3)#n, die zum Beispiel von
+   Vergleichsoperationen geliefert werden und 
+2. bitweise Ausführung von logischen Verknüpfungen auf den internen (Zweierkom­
+   plement-) Darstellungen von INT-Werten. 
+ 
+Da für beide Aufgaben die gleichen Operatoren benutzt werden, wurden für die Wahr­
+heitswerte die INT-Werte 0 für falsch (Bitmuster: 0000000000000000) und -1 für
+wahr (Bitmuster: 1111111111111111) gewählt. 
+ 
+      Operand(en)       Zweck                       insbesondere gilt 
+ 
+#ib(3)#NOT#ie(3)#   INT       #linefeed (0.5)#                                        NOT0->-1 
+                        #ib(3)#Negation#ie(3)# 
+      (REAL)    #linefeed (1.0)#                                        NOT-1->0 
+ 
+#ib(3)#AND#ie(3)#   INT, INT          #ib(3)#UND-Verknüpfung#ie(3)#              0AND0->0 
+                                                     0AND-1->0 
+                                                     -1AND0->0 
+                                                     -1AND-1->-1 
+ 
+ #ib(3)#OR#ie(3)#   INT, INT          #ib(3)#ODER-Verknüpfung#ie(3)#             0OR0->0 
+                                                     0OR-1->-1 
+                                                     -1OR0->-1 
+                                                     -1OR-1->-1 
+ 
+#ib(3)#XOR#ie(3)#   INT, INT          #ib(3)#Exklusiv-ODER-Verknüpfung#ie(3)#    0XOR0->0 
+                                                     0XOR-1->-1 
+                                                     -1XOR0->-1 
+                                                     -1XOR-1->0 
+ 
+#ib(3)#EQV#ie(3)#   INT, INT          #ib(3)#Äquivalenz-Verknüpfung#ie(3)#       0EQV0->-1 
+                                                     0EQV-1->0 
+                                                     -1EQV0->0 
+                                                     -1EQV-1->-1 
+ 
+#ib(3)#IMP#ie(3)#   INT, INT          #ib(3)#Implikations-Verknüpfung#ie(3)#     0IMP0->-1 
+                                                     0IMP-1->-1 
+                                                     -1IMP0->0 
+                                                     -1IMP-1->-1 
+ 
+ 
+ 
+Prioritäten der Operanden 
+ 
+ 
+Hier die Übersicht über alle Operatoren in der Reihenfolge ihrer Ausführung 
+ 
+ 
+  Operator                                           Priorität 
+ 
+     ^           Potenzierung                           13 
+     +, -        positives/negatives Vorzeichen         12 
+     *, /        Multiplikation, REAL-Division          11 
+     \           INT-Division                           10 
+     MOD         Divisionsrest- (MOD-) Operation         9 
+     +, -        Addition, Subtraktion                   8 
+     =, <>, <, >, <=, >=       Vergleichsoperatoren      7 
+     NOT         Negation                                6 
+     AND         UND-Verknüpfung                         5 
+     OR          ODER-Verknüpfung                        4 
+     XOR         Exklusiv-ODER-Verknüpfung               3 
+     EQV         Äquivalenz-Verknüpfung                  2 
+     IMP         Implikations-Verknüpfung                1 
+ 
+ 
+Die Reihenfolge der Auswertung von Ausdrücken kann durch Klammern geändert
+werden. 
+ 
+Beachten Sie, daß der Operator '=' in BASIC die Funktion eines Vergleichsoperators
+und des #ib(3)#Zuweisungsoperators#ie(3)##ib(3)##ie(3, "Operator, Zuweisungs-")# (siehe Kapitel 8, LET-Anweisung) hat. 
+ 
+#page# 
+ 
+4.5. #ib(3)#Funktionen#ie(3)# 
+ 
+ 
+ 
+Standard-Funktionen 
+ 
+Der EUMEL-BASIC-Compiler unterstützt eine ganze Reihe von Funktionen. Diese
+Funktionen liefern Werte und können in Ausdrücken zusammen mit Konstanten,
+Variablen und Operatoren verwendet werden. 
+Viele der eingebauten Funktionen arbeiten mit Argumenten, das heißt es werden den
+Funktionen Werte übergeben. 
+In Kapitel 8 dieses Handbuches sind alle Funktionen ausführlich beschrieben. 
+Beispiele für #ib(3)#Funktionsaufrufe#ie(3)#: 
+  SQR (17)             Dieser Ausdruck liefert die Wurzel von 17 als REAL. 
+  RIGHT$ (text$, 5)    Dieser Ausdruck liefert die letzten fünf Textzeichen 
+#right#aus 'text$' als TEXT. 
+ 
+ 
+ 
+Benutzer-definierte Funktionen 
+ 
+Neben der Verwendung der standardmäßig verfügbaren Funktionen besteht für den
+Benutzer die Möglichkeit, selbst Funktionen innerhalb eines Programms zu definieren. 
+ 
+#on ("b")# 
+#ib(3)#Definition benutzer-definierter Funktionen#ie(3)# #off ("b")# 
+Hierzu dient die #ib(3)#DEF FN#ie(3)#-Anweisung (vergleiche Kapitel 8). 
+Die Syntax der DEF FN-Anweisung lautet: 
+ 
+DEFFN<Name>[(<Parameter>[,<Parameter>][...])]= 
+#right#<Funktionsdefinition> 
+ 
+<Name>:                   Zeichenfolge, die der Syntax für Variablennamen ent­
+                          sprechen muß. 
+                          FN<Name> bilden zusammen den Namen der neuen
+                          Funktion. 
+<#ib(3)#Parameter#ie(3)#>:              Zeichenfolge, die der Syntax für Variablennamen ent­
+                          sprechen muß. 
+<Funktionsdefinition>:    Ausdruck, der Konstanten, Variablen, die Parameter der
+                          Funktion und Aufrufe anderer Funktionen enthalten
+                          darf. 
+ 
+- Die benutzer-definierten Funktionen ("user functions") liefern, genau wie die
+  Standard-Funktionen, Werte. 
+- Das letzte Zeichen des Funktionsnamens gibt den Typ des Wertes an, den die
+  Funktion liefert. Soll die Funktion einen TEXT liefern, so muß der Name mit "$"
+  enden. Soll ein INT geliefert werden, muß der Name mit "%" enden. Für alle
+  anderen Endungen wird eine REAL-liefernde Funktion eingetragen. 
+- Die Syntax der Parameternamen entspricht der Syntax für die Namen von einfachen
+  Variablen. 
+- Die Parameter haben nur bei der Definition Gültigkeit. Hierbei 'überdecken' sie (für
+  diese Zeile) eventuell im BASIC-Programm vorhandene gleichnamige Variablen. 
+- Jeder Parameter darf in der Parameterliste nur einmal vorkommen. 
+- Bezeichnet der Funktionsname eine TEXT-liefernde Funktion, so muß auch die
+  Funktionsdefinition ein Ergebnis vom Typ TEXT liefern. Zwischen INTs und REALs
+  findet eine Typanpassung statt. 
+- Eine Funktion darf nicht in ihrer eigenen Definition erscheinen. 
+- Eine Funktion ist allein durch ihren Namen gekennzeichnet. Generische Funktionen
+  (gleicher Name, aber unterschiedliche Parameter) können somit nicht definiert wer­
+  den. 
+ 
+Beispiele für gültige Funktionsdefinitionen: 
+  DEF FNPI = 3.1415927 
+  DEF FNumfang (radius) = 2.0 * FNPI * radius    (Enthält Aufruf von FNPI) 
+  DEF FNhallo$ (dummy$) = "Hallo " + name$       (name$ kommt im 
+  #right#BASIC-Programm vor) 
+  DEF FNheavyside% (x) = ABS (SGN (x) = 1) 
+ 
+Beispiele für ungültige Funktionsdefinitionen: 
+  DEF FNfunct (a, b, a) = a ^ 2 + b  (a kommt zweimal als Parameter vor) 
+  DEF FNfr (x) = x * FNfr (x - 1)    (rekursive Definition) 
+ 
+ 
+#on ("b")# 
+#ib(3)#Aufruf benutzer-definierter Funktionen#ie(3)# #off ("b")# 
+ 
+FN<Name> [ ( <Argument> [, <Argument>] [...] ) ] 
+ 
+<#ib(3)#Argument#ie(3)#>  : Ausdruck, der für den entsprechenden Parameter bei der Evaluation
+              (Auswertung) der Funktion eingesetzt werden soll 
+ 
+- Beim Funktionsaufruf werden die Argumente in der Reihenfolge ihres Auftretens für
+  die Parameter eingesetzt. Für TEXT-Parameter müssen die Argumente ebenfalls
+  TEXTe liefern. Zwischen INTs und REALs findet eine Typanpassung statt. 
+- Die Anzahl der Argumente muß genau mit der Anzahl der Parameter übereinstim­
+  men. 
+- Für in der Funktionsdefinition vorkommende Variablen wird der zum Zeitpunkt des
+  Funktionsaufruf gültige Wert eingesetzt. 
+- Die Definition der Funktion muß dem ersten Aufruf der Funktion textuell voraus­
+  gehen. 
+- Eine Definition gilt für alle textuell folgenden Aufrufe, bis die Funktion wieder neu
+  definiert wird. 
+ 
+Beispiele für korrekte Funktionsaufrufe (bezogen auf obige Beispiel-Definitionen): 
+  PRINT FNPI / 2.0                              (Ausgabe: 1.570796) 
+  PRINT FNumfang (20)                           (Ausgabe: 125.6637) 
+  LET name$ = "Purzelbär":PRINT FNhallo$ ("")   (Ausgabe: Hallo Purzelbär) 
+  PRINT heavyside% (-17.3)                      (Ausgabe: 0) 
+ 
+Beispiele für falsche Funktionsaufrufe (bezogen auf obige Beispiel-Definitionen): 
+  PRINT FNPI (10)                    (kein Argument erwartet) 
+  PRINT FNumfang                     (Argument erwartet) 
+  PRINT FNhallo$ (zahl%)             (Falscher Typ des Arguments) 
+  PRINT FNheavyside (17.4, -12.3)    (Zu viele Argumente) 
+ 
+ 
+#page# 
+ 
+4.6. #ib(3)#Typanpassung#ie(3)# 
+ 
+ 
+In BASIC wird, im Gegensatz zu ELAN, nicht sehr streng zwischen den numerischen
+Datentypen unterschieden, sondern es finden häufig automatische Typanpassungen
+statt. Zu solchen Typanpassungen kommt es vor allem bei der Zuweisung, bei Opera­
+toren und bei Funktionen, aber auch bei einigen Anweisungen. 
+Die automatische Typanpassung hat zwei Nachteile: 
+1. Die Typkonvertierung von INT nach REAL und umgekehrt kostet Zeit während der
+   Programmausführung. 
+2. Es kann zu sehr unangenehmen Laufzeitfehlern kommen, wenn eine REAL-
+   INT-#ib(3)#Konvertierung#ie(3)# mit Fehler abbricht, weil der REAL-Wert außerhalb des
+   INT-Wertebereichs liegt. 
+ 
+Allgemein gilt also, daß sich der Programmierer auch in BASIC über die Typen der
+verwendeten Objekte im klaren sein sollte. Außerdem ist zu beachten, daß bei Konver­
+tierungen von REAL nach INT immer gerundet wird. 
+ 
+Genaueres zur Typanpassung bei der Zuweisung finden Sie in Kapitel 8 bei der
+LET-Anweisung. 
+Über Typkonvertierung bei Operatoren informiert Kapitel 4.4. 
+Informationen über die Funktionen betreffenden Typkonvertierungen befinden sich am
+Anfang von Kapitel 8 und direkt bei der Beschreibung der jeweiligen Funktionen
+(ebenfalls in Kapitel 8). 
+ 
+#page# 
+ 
+4.7. Aufruf von EUMEL-Prozeduren in
+     BASIC-Programmen
+      
+ 
+ 
+Der EUMEL-BASIC-Compiler bietet die Möglichkeit, insertierte ELAN-Prozeduren
+(und auch insertierte BASIC-Programme) in BASIC-Programmen aufzurufen. Hierzu
+werden die beiden Anweisungen #ib(3)#CALL#ie(3)# und #ib(3)#CHAIN#ie(3)# (identisch) sowie die Funktion
+#ib(3)#USR#ie(3)# zur Verfügung gestellt. 
+Mit der CALL-Anweisung (siehe auch Kapitel 8) können Prozeduren aufgerufen
+werden, die keinen Wert liefern und nur die BASIC-Datentypen INT, REAL und/oder
+TEXT als Parameter benötigen. 
+Beispiele: 
+  CALL list 
+  CALL taskstatus ("PUBLIC") 
+  CALL cursor (10, 21) 
+  CALL getcursor (x%, y%) 
+ 
+Das letzte Beispiel zeigt, daß auch #ib(3)#VAR-Parameter#ie(3)# im ELAN-Sinne übergeben
+werden können. 
+ 
+Die Funktion USR dient im Gegensatz zu CALL zum Aufruf von #ib(3)#wertliefernden Pro­
+zeduren#ie(3)#. Die Prozeduren dürfen allerdings nur einen der BASIC-Datentypen INT,
+REAL oder TEXT liefern. Es gilt auch bei USR, wie bei CALL, daß die aufgerufenen
+Prozeduren nur Parameter der Typen INT, REAL oder TEXT haben dürfen. 
+Beispiele: 
+  PRINT USR e                            (Ausgabe: 2.718282) 
+  PRINT USR compress ("   EUMEL   ")     (Ausgabe: EUMEL) 
+ 
+#on ("b")# 
+Wichtige Hinweise zu CALL, CHAIN und USR: #off ("b")# 
+1. Bei den Parametern finden keinerlei Typkonvertierungen statt (ELAN-
+   Prozeduren werden ja gerade anhand der Typen ihrer Parameter eindeutig identifi­
+   ziert). 
+2. Die Prozedurnamen nach CALL, CHAIN und USR dürfen keine Leerzeichen ent­
+   halten, weil die Prozedur sonst nicht identifiziert werden kann. 
+   Beispiel:  CALLlernsequenzauftastelegen(...)  statt
+              CALLlernsequenzauftastelegen(...) 
+3. Die Prozedurnamen können (nach BASIC-Konvention) auch Großbuchstaben
+   enthalten. 
+   Beispiel:  CALLcursor(17,4) ist äquivalent zu 
+              CALLCURSOR(17,4) 
+ 
+ 
+Wie in Kapitel 3 erläutert kann ein BASIC-Programm auch insertiert werden. Somit
+können mit der CALL-Anweisung auch andere (vorher insertierte) BASIC-
+Programme aufgerufen werden. 
+Beispiel: 
+CALL blackjack      ('blackjack' sei der Prozedurname, unter dem ein BASIC-
+                    Programm zuvor insertiert wurde.) 
+ 
+Die sonst in einigen BASIC-Dialekten vorhandene Möglichkeit, Programme oder
+#ib(3)#Programmsegmente#ie(3)# nachzuladen, kann so durch Aufrufe von insertierten Programmen
+nachgebildet werden. 
+#page# 
+#head# 
+EUMEL-BASIC-Compiler       5. Steuerung der Bildschirmausgaben      % 
+ 
+#end# 
+ 
+5. #ib(4)#Steuerung der #ib(3)#Bildschirmausgaben#ie(3)##ie(4)# 
+ 
+ 
+ 
+Die Ausgaben von BASIC-Programmen ('PRINT' und 'WRITE') werden im Paket
+'basic output' behandelt. Dieses Paket ermöglicht unter anderem, daß die Ausgabe
+auf das Terminal mit der Prozedur 
+ 
+         PROC #ib(3)#basic page#ie(3)# (BOOL CONST status) 
+ 
+gesteuert werden können. Wird dabei 'TRUE' eingestellt, so wartet die Ausgabe bei
+Erreichen der letzten Terminalzeile auf die Eingabe eines Zeichens, bevor sie fortfährt.
+Das Eingabezeichen wird nach Ausgabe von ">>" in der rechten unteren Ecke des
+Bildschirms erwartet und wie folgt interpretiert: 
+ 
+#linefeed (1.5)# 
+          Löschen des Bildschirms und Ausgabe der nächsten Bildschirmseite 
+         Ausgabe der nächsten Zeile 
+         Abbruch des Programms mit der Fehlermeldung "'halt' vom Terminal" 
+           'basic page' wird auf 'FALSE' gesetzt #linefeed (1.0)#und mit der normalen Ausgabe
+            weitergemacht 
+ 
+Alle anderen Tasten bewirken eine Ausgabe der nächste Bildschirmseite (#ib(3)#Scrolling#ie(3)#). 
+ 
+Ist 'basic page' auf 'FALSE' gesetzt, so kann durch Eingabe von  vor einem Zei­
+lenwechsel 'basic page' auf 'TRUE' gesetzt werden. 
+#page# 
+#head# 
+EUMEL-BASIC-Compiler          6. Grenzen des Compilers             % 
+ 
+#end# 
+ 
+6. #ib(3)#Grenzen des Compilers#ie(3)# 
+ 
+ 
+Es gibt verschiedene Grenzen, die bei der Benutzung des BASIC-Compilers erreicht
+werden können. 
+ 
+#on ("b")# 
+Grenzen des #ib(3)#EUMEL-Coder#ie(3)#s #off ("b")# 
+Da ein BASIC-Programm vom Compiler als eine Prozedur im Coder eingetragen
+wird, darf der Code für ein BASIC-Programm die #ib(3)#Modulgrenze#ie(3)# von 7500 Byte Code
+nicht überschreiten. 
+Sollte dies doch einmal der Fall sein (#ib(3)#Compiler Error 308#ie(3)#), so gibt es folgende
+Abhilfe-Möglichkeiten: 
+- Zerlegen des BASIC-Programms in mehrere BASIC-Programme, wobei ein
+  Programm das andere während der Ausführung aufrufen kann (vgl.4.7.). 
+  Bei dieser Methode können die Teilprogramme aber nicht mit gemeinsamen Variab­
+  len arbeiten. 
+- Auslagerung von Programmteilen (z.B. Unterprogrammen) in ELAN-Prozeduren,
+  die insertiert und vom BASIC-Programm aufgerufen werden können (vgl.4.7.). 
+  Dieses Verfahren bietet die Möglichkeit, Variablen zwischen BASIC-Programm und
+  ELAN-Prozedur über die Prozedurschnittstelle auszutauschen. 
+ 
+Neben der Begrenzung des Codes ist auch die Größe des Datenspeicherbereichs pro
+BASIC-Programm begrenzt. Insgesamt dürfen die Datenobjekte eines BASIC-
+Programms nicht mehr als 32 KByte Speicherplatz belegen. Andernfalls kommt es
+zum #ib(3)#Compiler Error 307#ie(3)#. 
+ 
+Eine weitere Grenze des EUMEL-Coders stellt die maximal zulässige Anzahl der
+#ib(3)#Labels#ie(3)# (interne Sprungadressen) dar. Es können nur höchstens 2000 Labels vom
+Coder verwaltet werden. Der BASIC-Compiler vergibt für jede gefundene Zeile mit
+Zeilennummer ein Label und benötigt auch bei Schleifen (FOR-NEXT, WHILE-
+WEND), Fallunterscheidungen (IF-Anweisung), Unterprogramm-Aufrufen (GOSUB)
+und bei der Definition von benutzer-definierten Funktionen (DEF) Labels. 
+Beim Auftreten des #ib(3)#Compiler Errors 304#ie(3)# (zu viele Label) ist Abhilfe relativ leicht
+dadurch möglich, daß Zeilennummern nur den Zeilen vergeben werden, die tatsächlich
+angesprungen werden (d.h. zu denen es GOTOs oder GOSUBs gibt). 
+ 
+#on ("b")# 
+Grenzen des BASIC-Compilers #off ("b")# 
+Die interne #ib(3)#Namenstabelle#ie(3)# des BASIC-Compilers kann etwa 4240 Einträge aufneh­
+men. Ein Eintrag in dieser Tabelle wird für jede Variable, für jedes Feld, für jede
+benutzer-definierte Funktion und für jeden Parameter einer benutzer-definierten
+Funktion sowie für jede Konstante erzeugt. Numerische Konstanten erhalten, sofern
+sie konvertiert werden müssen, sogar zwei Einträge in der Namenstabelle. 
+Bei Auftreten des seltenen Fehlers "volle Namenstabelle" kann durch eine Aufteilung
+des BASIC-Programms in Teilprogramme oder eine Auslagerung von Unterprogram­
+men in ELAN-Prozeduren Abhilfe geschaffen werden. 
+ 
+#on ("b")# 
+Sonstige EUMEL-Grenzen #off ("b")# 
+Außer den bisher genannten Begrenzungen sei nochmals auf die Begrenzung des
+#ib(3)#Codebereichs pro Task#ie(3)# hingewiesen (maximal 256 KByte Code). 
+Da der EUMEL-Coder und der BASIC-Compiler recht viel Code belegen, sollte
+"vorsichtig" insertiert werden, also nur das, was wirklich benötigt wird. 
+Auch die übrigen Grenzen des EUMEL-Systems sind zu beachten (vergleiche hierzu
+die Aufstellung der möglichen Compiler Errors im EUMEL-Benutzerhandbuch)! 
+ 
+#page# 
+#head# 
+EUMEL-BASIC-Compiler            7. Fehlerbehandlung              % 
+ 
+#end# 
+ 
+7. #ib(3)#Fehlerbehandlung#ie(3)# 
+ 
+ 
+7.1. #ib(3)#Fehler zur Übersetzungszeit#ie(3)# 
+ 
+Endeckt der BASIC-Compiler bei der Übersetzung eines BASIC-Programms Fehler,
+so werden diese auf dem Bildschirm angezeigt und ins #ib(3)#Notebook#ie(3)# eingetragen. 
+Nur (syntaktisch) fehlerfreie Programme werden zur Ausführung gebracht beziehungs­
+weise insertiert. 
+Im #ib(3)#Vordurchlauf#ie(3)# werden die Zeilennummern auf Richtigkeit überprüft. Falls bereits
+hiebei Fehler festgestellt werden, bricht der Compiler die Übersetzung nach dem
+Vordurchlauf ab. 
+Im #ib(3)#Hauptdurchlauf#ie(3)# wird das Programm Zeile für Zeile auf syntaktische Richtigkeit
+überprüft und gleichzeitig übersetzt. Wird dabei in einer Programmzeile ein Fehler
+entdeckt, so wird er angezeigt und die Übersetzung des Programms #on("i")#in der nächsten
+Programmzeile#off("i")# fortgesetzt. Eine Ausnahme von dieser Regel bildet nur die #ib(3)#DEF FN#ie(3)#-
+Anweisung, bei der bei gewissen Fehlern die Übersetzung fortgesetzt wird. (Der
+Grund hierfür liegt darin, daß die Folgefehlerzahl besonders bei der DEF FN-
+Anweisung sehr groß wäre, wenn beim Auftreten eines Fehlers die Übersetzung der
+Zeile sofort abgebrochen würde. Die Parameter würden dann nämlich nicht oder
+falsch abgelegt, und bei jedem Aufruf der Funktion würde ein Fehler gemeldet.) 
+ 
+Eine Übersicht über alle verwendeten Fehlermeldungen zur Übersetzungszeit befindet
+sich im AnhangC. 
+ 
+ 
+ 
+Interne Compilerfehler 
+ 
+Neben den "normalen" Fehlern (siehe oben) kann es in seltenen Fällen möglicher­
+weise auch zu internen Fehlern kommen. 
+Es gibt zwei verschiedene Sorten von internen Fehlern: 
+1. interne Fehler, die das Compilerprogramm selbst feststellt. 
+   Solche Fehler bewirken die Meldung "Interner Fehler !" (meist mit näherer Erläu­
+   terung) und die Fortsetzung der Übersetzung in der nächsten Programmzeile. 
+2. Fehler, die in anderen Paketen des BASIC-Systems oder des EUMELs (z.B. im
+   EUMEL-Coder) während der Übersetzungszeit ausgelöst werden (siehe auch
+   Kapitel 6: "Grenzen des Compilers"). 
+   Solche Fehler werden mit "#ib(3)#BASIC-Compiler ERROR#ie(3)#" und eventuell näheren
+   Angaben gemeldet. Beim Auftreten eines solchen Fehlers wird die Übersetzung
+   des gesamten Programms abgebrochen. 
+ 
+Sollten bei Ihrer Arbeit mit dem EUMEL-BASIC-Compiler interne Fehler auftreten,
+die nicht auf das Überschreiten von Compilergrenzen zurückzuführen sind, dann
+wären wir Ihnen für eine Meldung der Fehler dankbar. Bitte senden Sie eine Fehler­
+beschreibung an: 
+ 
+  Gesellschaft für Mathematik und Datenverarbeitung 
+  Schloß Birlinghoven 
+  Postfach 1240 
+  5205 Sankt Augustin 1 
+ 
+Die Fehlerbeschreibung sollte nach Möglichkeit folgende Informationen enthalten: 
+- verwendete Hardware 
+- Urlader-Version 
+- EUMEL-Version 
+- Programmtext des Programms, das den Fehler auftreten ließ 
+- genaue Angabe der ausgegebenen Fehlermeldung 
+ 
+ 
+#page# 
+ 
+7.2. #ib(3)#Fehler zur Laufzeit#ie(3)# 
+ 
+Treten während der Laufzeit eines BASIC-Programms Fehler auf, so wird die Ausfüh­
+rung des Programms mit einer entsprechenden Fehlermeldung abgebrochen. 
+Da die meisten Laufzeit-Fehlermeldungen durch Prozeduren des EUMEL-Systems
+(und nicht des BASIC-Systems) erzeugt werden, entsprechen sie oft nicht der
+BASIC-Terminologie. (Beispielsweise führt ein zu großer Feldindex zu der Fehlermel­
+dung "Ueberlauf bei Subskription".) 
+ 
+Die bei Laufzeitfehlern gemeldete #ib(3)#Fehlerzeile#ie(3)# bezieht sich nicht (wie bei ELAN-Pro­
+grammen) auf die Nummer der Dateizeile, sondern auf die letzte der Programmzeile
+vorangegangene BASIC-Zeilennummer. 
+ 
+Fast alle ausgelösten Laufzeitfehler erzeugen auch #ib(3)#Fehlercodes#ie(3)#. Dabei liefern Fehler
+aus EUMEL-Betriebssystem-Prozeduren die EUMEL-Standard-Fehlercodes (vgl.
+Systemhandbuch), zum Beispiel wird beim Fehler "INT-Ueberlauf" der Fehlercode 4
+geliefert. 
+Laufzeitfehler, die in Prozeduren des BASIC-Systems ausgelöst werden, liefern dage­
+gen den in Microsoft-BASIC üblichen Fehlercode plus 1000. So liefert die Meldung
+"Keine Daten mehr für READ" den Fehlercode 1004 (MS-BASIC: "Out of data",
+Fehlercode 4). 
+Es läßt sich so anhand des gelieferten Fehlercodes ermitteln, ob der Fehler im
+BASIC-System oder an einer anderen Stelle des EUMEL-Systems ausgelöst wurde. 
+ 
+Eine Übersicht über die innerhalb des BASIC-Systems erzeugten Fehlermeldungen
+enthält Anhang C. 
+
diff --git a/doc/basic/basic handbuch.2 b/doc/basic/basic handbuch.2
new file mode 100644
index 0000000..1379e9e
--- /dev/null
+++ b/doc/basic/basic handbuch.2	
@@ -0,0 +1,2441 @@
+#page nr ("%", 31)# 
+#head# 
+EUMEL-BASIC-Compiler    8. Übersicht über die Befehle und Funktionen    % 
+ 
+#end# 
+ 
+8. Übersicht über die Anweisungen und Funktionen 
+    
+ 
+ 
+In diesem Kapitel sind alle Anweisungen und Funktionen des vom Compiler übersetz­
+baren BASIC-Sprachumfangs in alphabetischer Reihenfolge aufgeführt. 
+Auch die Anweisungsbestandteile (z.B. ELSE und TO) sind mit einem Hinweis auf die
+zugehörige Anweisung eingeordnet. 
+Sind bei Funktionen INT- oder REAL-Ausdrücke als Argumente angegeben, so ist
+dies als Hinweis auf den Sinn der Funktion zu verstehen. Es können auch Ausdrücke
+des jeweils anderen Datentyps eingesetzt werden. Wird statt eines INT-Ausdrucks
+ein REAL-Ausdruck angegeben, so darf dessen Wert aber nur innerhalb des
+Wertebereichs für INTs liegen, da der REAL-Wert bei der Ausführung der Funktion
+in einen INT-Wert konvertiert wird. 
+ 
+ 
+ 
+Funktion : ABS 
+ 
+Zweck :        Berechnung des Betrages (Absolutwertes) einer Zahl 
+ 
+Syntax :       ABS (<num. Ausdruck>) 
+ 
+Erklärung :   Liefert den Betrag des numerischen Ausdrucks. 
+              Das Ergebnis ist vom gleichen Typ wie das Argument. 
+ 
+ 
+Beispiel :      10 a = -12.74 
+                20 PRINT ABS (a) 
+                Ausgabe: 12.74 
+ 
+Vergleiche :  SGN-Funktion 
+ 
+ 
+ 
+Operator :  AND 
+ 
+Siehe Kapitel 4.4. (Operatoren) 
+ 
+ 
+ 
+Anweisungsbestandteil : AS 
+ 
+Siehe NAME-Anweisung 
+ 
+ 
+ 
+Funktion : ASC 
+ 
+Zweck :        Ermittlung des ASCII-Codes eines Textzeichens 
+ 
+Syntax :       ASC (<TEXT-Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert den ASCII-Code des ersten Zeichens des
+              TEXT-Ausdrucks. 
+              Der Code wird als INT geliefert. 
+ 
+ 
+Beispiel :      10 a$ = "Guten Tag !" 
+                20 PRINT ASC (a$) 
+                Ausgabe:  71 
+ 
+Vergleiche :  CHR$-Funktion (Komplementärfunktion) 
+ 
+ 
+ 
+Funktion : ATN 
+ 
+Zweck :        Berechnung des Arcustangens 
+ 
+Syntax :       ATN (<num. Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert den Arcustangens des 
+              numerischen Ausdrucks in Radiant. 
+ 
+ 
+Beispiel :      10 LET x = 4 
+                20 PRINT ATN (x) 
+                Ausgabe: 1.325818 
+ 
+Vergleiche :  TAN-Funktion (Komplementärfunktion), SIN, COS 
+ 
+ 
+ 
+Anweisungsbestandteil : BASE 
+ 
+Siehe OPTION BASE-Anweisung 
+ 
+ 
+ 
+Anweisung : CALL 
+ 
+Zweck :        Aufruf einer insertierten Prozedur 
+ 
+Syntax :       CALL <Prozedurname> #right#[ (<Parameter> [, <Parameter>] [...] ) ] 
+ 
+Erklärung :   <Prozedurname>: Folge aus Zeichen, die für Prozeduren im
+              EUMEL-System zugelassen sind (also Buchstaben und  - ab der
+              zweiten Stelle -  Zahlen), aber keine Leerzeichen. 
+ 
+              <Parameter>: <CONST-Parameter> | <VAR-Parameter> 
+ 
+              <CONST-Parameter>:   Ausdruck (genau des von der Prozedur
+                                   benötigten Typs) 
+              <VAR-Parameter>:     Variable (genau des von der Prozedur benö­
+                                   tigten Typs) 
+ 
+              Die Prozedur mit dem angegebenen <Prozedurnamen> wird mit den
+              angegebenen Parametern aufgerufen. 
+              Die aufgerufene Prozedur darf keinen Wert liefern (vgl. USR-Funk­
+              tion). 
+ 
+              Mögliche Fehlerfälle: 
+              - Eine Prozedur mit dem Namen <Prozedurnamen> und den an­
+                gegebenen Parametern gibt es nicht. 
+              - Die Prozedur liefert einen Wert. 
+              - Die Prozedur benötigt Parametertypen, die in BASIC nicht bekannt
+                sind (z.B. BOOL, FILE, TASK, QUIET). 
+              - Ein Parameter ist CONST, es wird aber ein VAR-Parameter ver­
+                langt. 
+ 
+              Weitere Informationen finden Sie in Kapitel 4.7. 
+ 
+Hinweis :     1.  Bei den Parametern wird keine Typkonvertierung vorgenommen. 
+              2. Der Prozedurname muß (entgegen der ELAN-Gewohnheit) ohne
+                 Leerzeichen angegeben werden. 
+              3. Statt des Anweisungswortes CALL kann auch CHAIN geschrieben
+                 werden. CALL und CHAIN werden im EUMEL-BASIC nicht wie
+                 in Microsoft-BASIC benutzt. 
+ 
+ 
+Beispiel :      10 CALL sysout ("Meine Datei") 
+                20 PRINT "Dieser Text geht nun in die Datei" 
+                30 CALL sysout ("") 
+                40 PRINT "Wieder auf den Bildschirm" 
+                 
+ 
+Vergleiche :  USR-Funktion 
+ 
+ 
+ 
+Funktion : CDBL 
+ 
+Zweck :        Konvertierung in den Datentyp REAL 
+ 
+Syntax :       CDBL (<num. Ausdruck>) 
+ 
+Erklärung :   Das Ergebnis des numerischen Ausdrucks wird als REAL geliefert. 
+ 
+ 
+Beispiel :      10 LET a! = 17 
+                20 PRINT USR max (CDBL (a!), 152.3) 
+                30 REM max benötigt zwei REALs als Parameter 
+ 
+ 
+Vergleiche :  CINT-Funktion 
+ 
+ 
+ 
+Anweisung : CHAIN 
+ 
+Vollkommen identisch mit der CALL-Anweisung (Erklärung siehe dort !) 
+ 
+ 
+ 
+Funktion : CHR$ 
+ 
+Zweck :        Erzeugung eines Textzeichens mit einem bestimmten ASCII-Code 
+ 
+Syntax :       CHR$ (<INT-Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert das Zeichen mit dem ASCII-Code, den der
+              INT-Ausdruck angibt. 
+              Das Zeichen wird als TEXT geliefert. 
+              Die Leistung der Funktion ist nur für Werte im Bereich 0 bis 255
+              definiert. 
+ 
+ 
+Beispiel :      10 PRINT CHR$ (61) 
+                Ausgabe:  = 
+ 
+Vergleiche :  ASC-Funktion (Komplementärfunktion) 
+ 
+ 
+ 
+Funktion : CINT 
+ 
+Zweck :        Konvertierung in den Datentyp INT 
+ 
+Syntax :       CINT (<num. Ausdruck>) 
+ 
+Erklärung :   Das Ergebnis des numerischen Ausdrucks wird als INT geliefert.
+              REALs werden gerundet. Werte außerhalb des INT-Bereichs führen
+              zu einem INT-Überlauf. 
+ 
+ 
+Beispiel :      10 LET a = 17.625 
+                20 PRINT CINT (a); CINT (-a) 
+                Ausgabe:  18  -18 
+ 
+Vergleiche :  CDBL-, FIX-, INT-Funktionen 
+ 
+ 
+ 
+Anweisung : CLS 
+ 
+Zweck :        Löschen des Bildschirms 
+ 
+Syntax :       CLS 
+ 
+Erklärung :   Löscht den Bildschirm und positioniert den Cursor in die linke obere
+              Bildschirmecke (Position 1, 1). 
+ 
+ 
+Beispiel :      10 CLS 
+                20 PRINT "PROGRAMMBEGINN" 
+ 
+ 
+ 
+ 
+Funktion : COS 
+ 
+Zweck :        Berechnung des Cosinus eines Radiantwertes 
+ 
+Syntax :       COS (<Winkel>) 
+ 
+Erklärung :   <Winkel>: REAL-Ausdruck, der den Winkel in Radiant angibt. 
+              Die Funktion liefert den Cosinus des Winkels als REAL. 
+ 
+ 
+Beispiel :      10 PI = 3.141593 
+                20 PRINT COS (PI/4) 
+                Ausgabe:  .7071067 
+ 
+Vergleiche :  SIN-, TAN-Funktionen 
+ 
+ 
+ 
+Funktion : CSRLIN 
+ 
+Zweck :        Ermittlung der aktuellen Cursorzeile 
+ 
+Syntax :       CSRLIN 
+ 
+Erklärung :   Geliefert wird die Nummer der Zeile (als INT), in der sich der Cursor
+              auf dem Bildschirm befindet. Die oberste Zeile hat die Nummer 1. 
+ 
+ 
+Beispiel :      10 CLS 
+                20 PRINT 
+                30 PRINT CSRLIN 
+                Ausgabe:  2 
+ 
+Vergleiche :  POS-Funktion 
+ 
+ 
+ 
+Funktion : CVD, CVI 
+ 
+Zweck :        Decodierung von in Texten verschlüsselten Zahlenwerten 
+ 
+Syntax :       CVD (<TEXT-Ausdruck>) 
+              CVI (<TEXT-Ausdruck>) 
+ 
+Erklärung :   INTs und REALs können (mit MKI$ und MKD$) zu Texten codiert
+              werden. 
+              CVD decodiert einen in 8 TEXT-Zeichen codierten REAL-Wert. 
+              CVI decodiert einen in 2 TEXT-Zeichen codierten INT-Wert. 
+              Es wird beim ersten Zeichen des TEXT-Ausdrucks mit der Dekodie­
+              rung begonnen. 
+              Ist der TEXT zu kurz, so wird mit der Meldung "Ueberlauf bei Subs­
+              kription" abgebrochen. 
+ 
+ 
+Beispiel :      10 zahl$ = MKD$ (3.1415) 
+                20 PRINT CVD (zahl$) 
+                Ausgabe:  3.1415 
+ 
+Vergleiche :  MKD$-, MKI$- Funktionen (Komplementärfunktionen) 
+ 
+ 
+ 
+Anweisung : DATA 
+ 
+Zweck :        Ablegen von Konstanten 
+ 
+Syntax :       DATA [<string>] [, [<string>]] [...] 
+ 
+Erklärung :   <string>         : <quoted string> | <unquoted string> 
+              <quoted string>  : von Anführungszeichen umschlossene Zeichen­
+                                 folge, die alle Zeichen außer Anführungs­
+                                 zeichen enthalten darf 
+              <unquoted string>: Zeichenfolge, die alle Zeichen außer Komma
+                                 und Doppelpunkt enthalten darf 
+ 
+              Eine DATA-Anweisung stellt einen Datenspeicher dar, der mit READ
+              (s.d.) ausgelesen werden kann. 
+              In der DATA-Anweisung können "quoted strings" oder "unquo­
+              ted strings" angegeben werden. "quoted strings" können später nur
+              noch als Texte ausgelesen werden. 
+              Bei "unquoted strings" wird der Datentyp in der DATA-Anweisung
+              dagegen nicht festgelegt. Sie können also als INTs, REALs oder
+              TEXTe ausgelesen werden. Sollen "unquoted strings" Zahlenwerte
+              darstellen, so müssen sie den in BASIC üblichen Schreibregeln für
+              die numerischen Konstanten des jeweiligen Typs genügen. Es sind
+              allerdings zusätzlich noch Vorzeichen erlaubt. 
+              Wenn die <strings> nicht angegeben sind, so wird ein "nil-Datum"
+              abgelegt. Dieses bewirkt bei einem READ mit numerischer Variable
+              die Lieferung des Wertes null und bei einem READ mit TEXT-Vari­
+              able die Lieferung eines Leertextes. 
+ 
+              Die DATA-Anweisungen können an beliebiger Stelle im Programm
+              (vor oder hinter den zugehörigen READ-Anweisungen) stehen. 
+ 
+              Alle DATA-Anweisungen eines Programms bilden zusammen einen
+              großen sequentiellen Speicher, auf den mit READ der Reihe nach
+              zugegriffen wird. Intern wird ein sogenannter READ-DATA-Zeiger
+              geführt, der immer auf das nächste auszulesende Element zeigt. 
+              Die RESTORE-Anweisung (s.d.) ermöglicht es, den READ-
+              DATA-Zeiger auf das erste Element einer bestimmten DATA-Zeile
+              zu setzen. 
+ 
+ 
+Beispiel :      2020 PRINT "Stadt", "Land", "Fluß" 
+                2030 READ stadt$, land$, fluß$ 
+                2040 PRINT stadt$, land$, fluß$ 
+                . 
+                5000 DATA Paris, Frankreich, Seine 
+ 
+ 
+Vergleiche :  READ-, RESTORE-Anweisungen 
+ 
+ 
+ 
+Funktion : DATE$ 
+ 
+Zweck :        Abrufen des aktuellen Tagesdatums 
+ 
+Syntax :       DATE$ 
+ 
+Erklärung :   Das Tagesdatum wird als Text in der Form TT.MM.JJ geliefert. 
+ 
+ 
+Beispiel :      10 PRINT "Heute ist der " + DATE$ 
+                Ausgabe (z.B.):  Heute ist der 28.08.87 
+ 
+Vergleiche :  TIME$-Funktion 
+ 
+ 
+ 
+Anweisung : DEFDBL, DEFINT, DEFSNG, DEFSTR 
+ 
+Zweck :        Definition von Anfangsbuchstaben zur Kennzeichnung bestimmter
+              Variablentypen 
+ 
+Syntax :       DEFDBL <Buchstabe1> [ - <Buchstabe2>] 
+              #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...] 
+              DEFINT <Buchstabe1> [ - <Buchstabe2>] 
+              #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...] 
+              DEFSNG <Buchstabe1> [ - <Buchstabe2>] 
+              #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...] 
+              DEFSTR <Buchstabe1> [ - <Buchstabe2>] 
+              #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...] 
+ 
+ 
+Erklärung :   Mit den aufgeführten Anweisungen ist es möglich, bestimmte Buch­
+              staben festzulegen, die, wenn sie als Anfangsbuchstaben eines
+              Variablennamens verwendet werden, der Variablen einen bestimmten
+              Typ zuordnen. 
+ 
+              Die Typfestlegung durch Kennzeichnung mit den Zeichen '!', '\#', '%'
+              oder '$' hat jedoch Vorrang vor den festgelegten Anfangsbuchstaben.
+              Eine genaue Erläuterung, nach welchen Kriterien der BASIC-Compi­
+              ler den Typ einer Variablen feststellt, befindet sich in Kapitel 4.3. 
+ 
+              Die DEFINT-Anweisung legt Anfangsbuchstaben für INT-Variablen
+              fest. 
+              Mit der DEFSTR-Anweisung werden Anfangsbuchstaben von
+              TEXT-Variablen festgelegt. 
+              Die Anweisungen DEFDBL- und DEFSNG- wurden nur aus Kom­
+              patibilitätsgründen implementiert. Sie werden zwar auf syntaktische
+              Richtigkeit überprüft, aber ansonsten vom Compiler nicht beachtet. 
+ 
+              Werden bei den Anweisungen ganze Buchstabenbereiche angegeben,
+              so muß der Buchstabe vor dem Bindestrich auch im Alphabet vor
+              dem Buchstaben hinter dem Bindestrich stehen. 
+ 
+Hinweis :     1.  Die oben beschriebenen Anweisungen gelten stets erst für die im
+                 weiteren Text neu benutzten (also neu eingerichteten) Variablen. 
+              2. Die beschriebenen Anweisungen dürfen auch mehr als einmal in
+                 einem Programm vorkommen. Die Buchstaben, die in der zweiten
+                 und in den folgenden Anweisungen festgelegt werden, werden
+                 #on("izusätzlich#off("i zu den in der ersten Anweisung festgelegten Buchsta­
+                 ben als Kennzeichen für den betreffenden Datentyp vom Compiler
+                 vermerkt. 
+              3. Der Compiler überprüft nicht, ob gleiche Buchstaben als Kennzei­
+                 chen für mehr als einen Variablentyp angegeben werden (siehe
+                 Kapitel 4.3.). Der Benutzer ist also selbst dafür verantwortlich, daß
+                 solche Überschneidungen nicht vorkommen. 
+ 
+ 
+Beispiel :      10 DEFSTR s - z 
+                20 DEFINT a - h, n 
+                30 DIM tabelle (17) 'TEXT-Feld 
+                40 LET c = 4        'INT-Variable 
+                50 LET nummer = 17  'INT-Variable 
+                60 LET ueberschrift = "Willkommen" 'TEXT-Variable 
+                70 LET reellezahl = 19.563 'REAL-Variable 
+                80 LET aha\# = -1.36E17     'REAL-Variable 
+                 
+ 
+ 
+ 
+Anweisung : DEF FN 
+ 
+Zweck :        Definition einer benutzer-definierten Funktion 
+ 
+Syntax :       DEF FN<Name> [ ( <Parameter> [, <Parameter>] #right# [...] ) ] = <Funktionsdefinition> 
+ 
+Erklärung :   <Name>     :  Zeichenfolge, die der Syntax für Variablennamen
+                            entsprechen muß 
+                            FN<Name> bilden zusammen den Namen der
+                            neuen Funktion 
+              <Parameter>:  Zeichenfolge, die der Syntax für Variablennamen
+                            entsprechen muß 
+              <Funktionsdefinition>:  Ausdruck, der Konstanten, Variablen, die
+                                      Parameter der Funktion und Aufrufe
+                                      anderer Funktionen enthalten darf 
+ 
+              Mit der DEF FN-Anweisung wird eine benutzer-definierte Funktion
+              ("user function") mit dem Funktionsnamen FN<Name> definiert
+              (vergleiche hierzu auch Kapitel 4.5.). 
+              Die benutzer-definierte Funktion liefert, genau wie die standard­
+              mäßig eingebauten Funktionen, einen Wert, der sich aus der Auswer­
+              tung des unter <Funktionsdefinition> angegebenen Ausdrucks
+              ergibt. 
+              Das letzte Zeichen des Funktionsnamens gibt den Typ des Wertes
+              an, den die Funktion liefert. Soll die Funktion einen TEXT liefern, so
+              muß der Name mit "$" enden. Soll ein INT geliefert werden, muß der
+              Name mit "%" enden. Für alle anderen Endungen wird eine REAL-
+              liefernde Funktion eingetragen. 
+              Bezeichnet der Funktionsname eine TEXT-liefernde Funktion, so
+              muß auch die Funktionsdefinition ein Ergebnis vom Typ TEXT liefern.
+              Zwischen INTs und REALs findet eine Typanpassung statt. 
+ 
+              Die Parameter stehen für die beim Aufruf der Funktion übergebenen
+              Argumente. 
+              Sie haben nur bei der Definition Gültigkeit. Hierbei 'überdecken' sie
+              (für diese Zeile) eventuell im BASIC-Programm vorhandene gleich­
+              namige Variablen. 
+              Die Syntax der Parameternamen entspricht der Syntax der Namen
+              von einfachen Variablen. 
+              Jeder Parameter darf in der Parameterliste nur einmal vorkommen. 
+ 
+              In der Definition dürfen auch Aufrufe von zuvor definierten anderen
+              "user functions" erscheinen, nicht aber die zu definierende Funktion
+              selbst (rekursive Definition). 
+ 
+              Die Funktionen sind allein durch ihre Namen gekennzeichnet. Gene­
+              rische Funktionen (gleicher Name, aber unterschiedliche Parameter)
+              können somit nicht definiert werden. 
+ 
+Hinweis :     1.  Die Definition einer "user function" muß ihrem ersten Aufruf
+                 immer textuell vorausgehen. 
+              2. "user functions" können auch mehrfach definiert werden. Der
+                 Compiler gibt in einem solchen Fall aber eine Warnung aus, da
+                 die neue Definition nur für die textuell folgenden Aufrufe gültig ist. 
+ 
+ 
+Beispiel :      10 LET pi = 3.1415927 
+                20 DEF FNkreisflaeche (radius) 
+                #right#= 4.0 * pi * radius * radius 
+                1010 PRINT FNkreisflaeche (1.75) 
+                Ausgabe:  38.48451 
+ 
+ 
+ 
+Anweisung : DIM 
+ 
+Zweck :        Dimensionierung eines Feldes 
+ 
+Syntax :       DIM <Felddeklaration> [, <Felddeklaration>] [...] 
+ 
+Erklärung :   <Felddeklaration>: <Feldvariable> (<INT-Konstante> 
+                                 #right#[, <INT-Konstante>] [...] ) 
+              <Feldvariable>: Name des Feldes (Syntax wie Name von einfachen
+                              Variablen, vgl. 4.3.) 
+ 
+              Mit der DIM-Anweisung wird ein Feld dimensioniert, das heißt die
+              Anzahl seiner Dimensionen sowie der kleinste und größte Index in
+              jeder Dimension werden festgelegt und der Speicherplatz für seine
+              Elemente (siehe 4.3.) wird reserviert. 
+ 
+              Der kleinste Index in allen Dimensionen richtet sich nach der letzten
+              vorausgegangenen OPTION BASE-Anweisung. 
+              Geht der Dimensionierung die Anweisung OPTION BASE 0 textuell
+              voraus oder ist keine OPTION BASE-Anweisung vor der Dimensio­
+              nierung vorhanden, so ist der kleinste Index in allen Dimensionen
+              null. 
+              Wenn der Dimensionierung aber eine OPTION BASE 1-Anweisung
+              vorausgeht, dann ist der kleinste Index in allen Dimensionen eins. 
+ 
+              Der größte Feldindex wird für jede Dimension durch die in Klammern
+              stehenden INT-Konstanten angegeben. Die Anzahl dieser INT-Kon­
+              stanten bestimmt auch, wie viele Dimensionen das dimensionierte
+              Feld hat. 
+ 
+              Wird auf ein Element einer Feldvariablen zugegriffen, ohne daß die
+              Feldvariable vorher dimensioniert wurde, dann wird das Feld automa­
+              tisch dimensioniert, wobei die Anzahl der Dimensionen anhand der
+              Anzahl der Indizes beim Aufruf ermittelt wird. Der größte Feldindex
+              wird bei dieser automatischen Dimensionierung in jeder Dimension
+              auf zehn gesetzt. Der kleinste Index richtet sich nach den vorausge­
+              gangenen OPTION BASE-Anweisungen (siehe oben). 
+ 
+              Fehlerfälle bei der Dimensionierung: 
+              - "Das Feld ist bereits dimensioniert": 
+                Das Feld wurde bereits explizit, oder automatisch durch den Zugriff
+                auf ein Feldelement dimensioniert . 
+              - "Die Obergrenze muß >= 1 sein": 
+                Es wurde versucht, 0 als größten Index in einer Dimension festzu­
+                legen, obwohl mit OPTION BASE der kleinste Index auf eins fest­
+                gelegt wurde. 
+ 
+              Fehlerfälle beim Zugriff auf ein Feldelement: 
+              - "Dimensioniert in ... Dimensionen, gefundene Anzahl Indizes ...": 
+                Beim Zugriff wurde eine Anzahl von Indizes gefunden, die nicht mit
+                der Anzahl der Dimensionen übereinstimmt (Fehler zur Über­
+                setzungszeit). 
+              - "Ueberlauf bei Subskription" oder "Unterlauf bei Subskription": 
+                Der Index ist zu groß beziehungsweise zu klein (Fehler zur Lauf­
+                zeit). 
+ 
+ 
+Beispiel :      10 DIM a% (20, 10), text$ (30, 40) 
+                20 DIM tabelle (5, 7, 25) 
+                30 LET element = matrix (1, 7) 
+ 
+              Zeile 30 führt eine automatische Dimensionierung durch, die einem
+              DIM matrix (10, 10) entspricht. 
+ 
+ 
+ 
+Anweisungsbestandteil : ELSE 
+ 
+Siehe IF-Anweisung 
+ 
+ 
+ 
+Anweisung : END 
+ 
+Zweck :        Beenden der Programmausführung eines BASIC-Programms 
+ 
+Syntax :       END 
+ 
+Erklärung :   END beendet die Programmausführung des BASIC-Programms ohne
+              eine Meldung (im Gegensatz zu STOP, s.d.). 
+              END-Anweisungen dürfen im Programm an beliebiger Stelle stehen,
+              und es darf auch mehr als eine END-Anweisung in einem
+              Programm vorkommen. 
+              Der Compiler übersetzt ein Programm auch nach Erreichen einer
+              END-Anweisung weiter. 
+              Nach der letzten Anweisung eines Programms muß kein END stehen. 
+ 
+ 
+Beispiel :      2020 PRINT "Das war's !" 
+                2030 REM Hiernach hört's auf 
+                2040 END 
+ 
+ 
+Vergleiche :  STOP-Anweisung 
+ 
+ 
+ 
+Anweisungsbestandteil : EOF 
+ 
+Siehe INPUT-Anweisung 
+ 
+ 
+ 
+ 
+Operator : EQV 
+ 
+Siehe Kapitel 4.4. (Operatoren) 
+ 
+ 
+ 
+Funktion : ERL 
+ 
+Zweck :        Ermittlung der letzten Fehlerzeile 
+ 
+Syntax :       ERL 
+ 
+Erklärung :   Die Nummer der Zeile, in der der letzte Fehler auftrat, wird als INT
+              geliefert. 
+ 
+Hinweis :     ERL ist realisiert durch Aufruf der Prozedur 'errorline' des Betriebs­
+              systems. 
+              Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü­
+              gung steht, ist diese Funktion nicht im üblichen BASIC-Sinne
+              brauchbar. 
+ 
+Vergleiche :  ERM$, ERR-Funktionen, ERROR-Anweisung 
+ 
+ 
+ 
+Funktion : ERM$ 
+ 
+Zweck :        Ermittlung der letzten Fehlermeldung 
+ 
+Syntax :       ERM$ 
+ 
+Erklärung :   Die letzte Fehlermeldung wird als TEXT geliefert. 
+ 
+Hinweis :     ERM$ ist realisiert durch Aufruf der Prozedur 'errormessage' des
+              Betriebssystems. 
+              Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü­
+              gung steht, ist diese Funktion nicht im üblichen BASIC-Sinne
+              brauchbar. 
+ 
+Vergleiche :  ERL-, ERR-Funktionen, ERROR-Anweisung 
+ 
+ 
+ 
+Funktion : ERR 
+ 
+Zweck :        Ermittlung des letzten Fehlercodes 
+ 
+Syntax :       ERR 
+ 
+Erklärung :   Der Code des letzten aufgetretenen Fehlers wird als INT geliefert. 
+ 
+Hinweis :     ERR ist realisiert durch Aufruf der Prozedur 'errorcode' des Betriebs­
+              systems. 
+              Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü­
+              gung steht, ist diese Funktion nicht im üblichen BASIC-Sinne
+              brauchbar. 
+ 
+Vergleiche :  ERL-, ERM$-Funktionen, ERROR-Anweisung 
+ 
+ 
+ 
+Anweisung : ERROR 
+ 
+Zweck :        Auslösen eines Fehlers mit bestimmtem Fehlercode 
+ 
+Syntax :       ERROR <INT-Ausdruck> 
+ 
+Erklärung :   Es wird ein Fehler mit dem durch den INT-Ausdruck bestimmten
+              Fehlercode ausgelöst. 
+ 
+Hinweis :     ERROR ist realisiert durch Aufruf der Prozedur 'errorstop' des Be­
+              triebssystems. 
+              Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü­
+              gung steht, ist diese Anweisung nicht im üblichen BASIC-Sinne
+              brauchbar. 
+ 
+Vergleiche :  ERL-, ERM$-, ERR-Funktionen 
+ 
+ 
+ 
+Funktion : EXP 
+ 
+Zweck :        Berechnung einer Potenz der Eulerschen Zahl 
+ 
+Syntax :       EXP (<REAL-Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert e (die Basis des natürlichen Logarithmus) poten­
+              ziert mit dem Wert des REAL-Ausdrucks. 
+              Bei zu großen Werten kommt es zum Fehler 'REAL-Ueberlauf'. 
+              Das Ergebnis der Funktion wird als REAL geliefert. 
+ 
+ 
+Beispiel :      10 PRINT EXP (10.0) 
+                Ausgabe:  22026.47 
+ 
+Vergleiche :  LOG-Funktion (Komplementärfunktion) 
+ 
+ 
+ 
+Funktion : FIX 
+ 
+Zweck :        Ermittlung der Vorkommastellen einer REAL-Zahl 
+ 
+Syntax :       FIX (<REAL-Ausdruck>) 
+ 
+Erklärung :   Die Funktion schneidet die Nachkommastellen ab und liefert nur die
+              Vorkommastellen des REAL-Ausdrucks. 
+              Die Vorkommastellen werden ebenfalls als REALs geliefert. 
+ 
+ 
+Beispiel :      10 zahl = 1.2345E2 
+                20 PRINT FIX (zahl) 
+                Ausgabe:  123 
+ 
+Vergleiche :  CINT-, INT-Funktionen 
+ 
+ 
+ 
+Anweisung : FOR 
+ 
+Zweck :        Beginn einer Zählschleife 
+ 
+Syntax :       FOR <num. Variable> = <Anfangswert> #ib(3)#TO#ie(3)# <Endwert> 
+              #right#[ #ib(3)#STEP#ie(3)# <Schrittweite> ] 
+              <Schleifenrumpf> 
+ 
+ 
+Erklärung :   <num. Variable> : INT- oder REAL-Variable 
+              <Anfangswert>   : numerischer Ausdruck 
+              <Endwert>       : numerischer Ausdruck 
+              <Schrittweite>  : numerischer Ausdruck 
+              <Schleifenrumpf>: Folge von Programmzeilen 
+ 
+              Die FOR-Anweisung erlaubt die komfortable Programmierung von
+              automatischen Zählschleifen (sogenannten FOR-NEXT-Schleifen).
+              Gelangt das Programm während der Ausführung an eine FOR-An­
+              weisung, so werden zunächst die Ausdrücke <Anfangswert>,
+              <Endwert> sowie gegebenenfalls <Schrittweite> ausgewertet. Der
+              Anfangswert wird dann der Variablen zugewiesen. 
+              Wenn der Wert der Variablen größer ist als der Endwert (bzw. kleiner
+              als der Endwert bei negativer Schrittweite), dann wird das Programm
+              mit der nach dem korrespondierenden NEXT (s.d.) folgenden
+              Anweisung fortgesetzt. 
+              Ist dies jedoch nicht der Fall, werden die Anweisungen des <Schlei­
+              fenrumpfs> ausgeführt. Erreicht das Programm nun die zum FOR
+              gehörige NEXT-Anweisung (gleiche Variable), so wird der Wert der
+              Variablen um die Schrittweite erhöht beziehungsweise erniedrigt (je
+              nach Vorzeichen), und wieder an den Anfang der Schleife verzweigt.
+              Hier findet dann wieder der Vergleich des Variableninhalts mit dem
+              Endwert statt (siehe oben). 
+ 
+              Die Laufvariable darf innerhalb der Schleife in Ausdrücken vorkom­
+              men. Sie darf sogar verändert werden (, was aber zu unübersichtli­
+              chen Effekten führen kann). Auch eine Schachtelung mehrerer
+              Schleifen mit der gleichen Laufvariable ist syntaktisch möglich, sollte
+              aber #on("iunter allen Umständen#off("i vermieden werden. 
+ 
+              FOR-NEXT-Schleifen dürfen (auch mit WHILE-WEND-Schleifen,
+              s.d.) geschachtelt werden. Überschneidungen von FOR-NEXT-
+              Schleifen und WHILE-WEND-Schleifen sind aber nicht zulässig. 
+ 
+ 
+Beispiel :      10 DIM name$ (5) 
+                20 FOR i = 1 TO 5 
+                30 PRINT "Bitte geben Sie den " + STR$ (i) 
+                #right#+ ". Namen ein:"; 
+                40 INPUT name$ (i) 
+                50 NEXT i 
+ 
+ 
+              Es werden die fünf Elemente des Feldes 'name$' eingelesen. 
+ 
+Vergleiche :  NEXT-, WHILE-, IF-Anweisungen 
+ 
+ 
+ 
+Funktion : FRE 
+ 
+Zweck :        Ermittlung des verfügbaren Speicherplatzes 
+ 
+Syntax :       FRE (<num. Ausdruck>) 
+              FRE (<TEXT-Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert die Anzahl der freien Bytes. 
+              FRE veranlaßt außerdem ein 'collect heap garbage' (EUMEL-
+              Systemprozedur). 
+ 
+              Das Ergebnis der Funktion wird als REAL geliefert. 
+              Der Argument-Ausdruck ist ein Dummy-Argument (hat keinen
+              Einfluß auf den gelieferten Wert). 
+ 
+Hinweis :     Bei der EUMEL M+ Version wird ein korrektes Ergebnis geliefert
+              (vgl.'storage info'). 
+ 
+ 
+Beispiel :      10 PRINT FRE (0) 
+                Ausgabe (z.B.):  5324800 
+ 
+ 
+ 
+Anweisungsbestandteil : GO 
+ 
+Siehe GOSUB und GOTO 
+ 
+ 
+ 
+Anweisung : GOSUB 
+ 
+Zweck :        Unterprogramm-Aufruf 
+ 
+Syntax :       GOSUB <Zeilennummer> 
+ 
+Erklärung :   <Zeilennummer>: INT-Konstante 
+              Statt GOSUB darf auch GO #ib(3)#SUB#ie(3)# geschrieben werden. 
+ 
+              Die Programmausführung wird in der Zeile mit der angegebenen
+              Zeilennummer fortgesetzt. Die Zeile mit der Zeilennummer muß im
+              Programm existieren. 
+              Wird im weiteren Programmablauf die Anweisung RETURN gefunden,
+              so wird hinter dem letzten abgearbeiteten GOSUB die Programm­
+              ausführung fortgesetzt. 
+              GOSUB dient zum Aufruf von #on("iUnterprogrammen#off("i, die von mehr als
+              einer Stelle im Programm (und auch in anderen Unterprogrammen)
+              aufgerufen werden können. 
+ 
+Hinweis :     Es wird empfohlen, Unterprogramme im Programm deutlich als solche
+              zu kennzeichnen und (durch END, STOP oder GOTO) sicherzustel­
+              len, daß nur mit GOSUB zu ihnen verzweigt wird, da es sonst leicht
+              zu der (Laufzeit-) Fehlermeldung "RETURN ohne GOSUB" kommen
+              kann. 
+ 
+ 
+Beispiel :      140 GOSUB 10000  'Zeige Uhrzeit 
+                . 
+                . 
+                370 GOSUB 10000  'Zeige Uhrzeit 
+                9990 END 
+                10000 REM Unterprogramm Zeige Uhrzeit 
+                10010 PRINT "Es ist " + TIME$ + " Uhr" 
+                10020 RETURN 
+ 
+ 
+Vergleiche :  RETURN-, ON-, GOTO- Anweisungen 
+ 
+ 
+ 
+Anweisung : GOTO 
+ 
+Zweck :        Sprung zu einer angegebenen Zeile 
+ 
+Syntax :       GOTO <Zeilennummer> 
+ 
+Erklärung :   <Zeilennummer>: INT-Konstante 
+              Statt GOTO darf auch GO #ib(3)#TO#ie(3)# geschrieben werden. 
+ 
+              Die Programmausführung wird in der Zeile mit der angegebenen
+              Zeilennummer fortgesetzt. Die Zeile mit der Zeilennummer muß im
+              Programm existieren. 
+ 
+ 
+Beispiel :      10 INPUT "Monat (1-12)", monat% 
+                20 IF monat% < 1 OR monat% > 12 THEN GOTO 10 
+ 
+ 
+Vergleiche :  ON-, IF-, GOSUB- Anweisungen 
+ 
+ 
+ 
+Funktion : HEX$ 
+ 
+Zweck :        Erzeugung der hexadezimalen Darstellung einer Zahl als Text 
+ 
+Syntax :       HEX$ (<INT-Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert die hexadezimale (Zweierkomplement-) Darstel­
+              lung der Zahl, die sich aus dem INT-Ausdruck ergibt. 
+ 
+ 
+Beispiel :      10 PRINT HEX$ (10000) 
+                Ausgabe:  2710 
+ 
+Vergleiche :  OCT$-Funktion 
+ 
+ 
+ 
+Anweisung : IF 
+ 
+Zweck :        Sprung zu einer angegebenen Zeile 
+ 
+Syntax :       IF <Bedingung> 
+              #right#[,] #ib(3)#THEN#ie(3)# <Anweisung(en)>|<Zeilennummer> 
+              #right#[ [,] #ib(3)#ELSE#ie(3)# <Anweisung(en)>|<Zeilennummer>] 
+              IF <Bedingung> [,] GOTO <Zeilennummer> 
+              #right#[ [,] ELSE <Anweisung(en)>|<Zeilennummer>] 
+ 
+Erklärung :   <Bedingung>    : numerischer Ausdruck 
+              <Anweisung(en)>: Eine oder mehrere BASIC-Anweisungen, wobei
+                               mehrere wie gewohnt durch ':' zu trennen sind 
+              <Zeilennummer> : INT-Konstante 
+              Statt GOTO darf auch GO TO geschrieben werden. 
+ 
+              Anhand der Bedingung wird entschieden, ob die Abarbeitung des
+              Programms mit dem THEN- oder ELSE-Zweig fortgesetzt werden
+              soll. Mit dem THEN-Zweig wird das Programm fortgesetzt, wenn die
+              Bedingung erfüllt ist (, d.h. der numerische Ausdruck ungleich null
+              ist). Im anderen Fall (Bedingung nicht erfüllt, numerischer Ausdruck
+              gleich null) wird das Programm mit dem ELSE-Teil fortgesetzt. Ist
+              kein ELSE-Teil angegeben, so wird die Abarbeitung des
+              Programmes in der folgenden #on("iZeile#off("i (nicht nach ':') fortgesetzt. 
+ 
+              Sind statt Anweisungen Zeilennummern nach THEN oder ELSE
+              angegeben, so entspricht dies einem GOTO (s.d.) zu diesen Zeilen­
+              nummern. 
+ 
+ 
+Hinweis :     Auch eine IF-Anweisung muß in #on("ieiner#off("i Programmzeile stehen. 
+ 
+ 
+Beispiel :      10 IF a >= b THEN IF a > b THEN 
+                #right#PRINT "a größer b" ELSE PRINT "a gleich b" 
+                #right#ELSE PRINT "a kleiner b" 
+ 
+ 
+              Das Beispiel zeigt, daß bei geschachtelten IF-Anweisungen die
+              ELSE-Teile immer auf das letzte vorhergehende IF bezogen werden,
+              für das noch kein ELSE-Teil gefunden wurde. 
+ 
+ 
+ 
+Vergleiche :  GOTO-, GOSUB-, ON-Anweisungen 
+ 
+ 
+ 
+Operator : IMP 
+ 
+Siehe Kapitel 4.4. (Operatoren) 
+ 
+ 
+ 
+Funktion : INKEY$ 
+ 
+Zweck :        Holen eines Zeichens von der Tastatur 
+ 
+Syntax :       INKEY$ 
+ 
+Erklärung :   Die Funktion liefert ein Textzeichen aus dem Tastaturzeichenpuffer.
+              Wurde kein Zeichen eingegeben, so wird ein Leertext (niltext) gelie­
+              fert. 
+              Die gelieferten Zeichen erscheinen nicht auf dem Bildschirm. 
+ 
+ 
+Beispiel :      10 REM Schreibmaschine 
+                20 LET a$ = INKEY$ 
+                30 IF ASC (a$) = 27 THEN STOP 
+                40 PRINT a$; 
+                50 GOTO 20 
+ 
+ 
+              Die eingegebenen Zeichen werden ausgegeben. Abbruch mit ESC. 
+ 
+Vergleiche :  INPUT$-Funktion, INPUT-Anweisung 
+ 
+ 
+ 
+Anweisung : INPUT 
+ 
+Zweck :        Einlesen von Daten von der Tastatur 
+ 
+Syntax :       INPUT [;] [<Eingabeaufforderung> ,|; ][ #ib(3)#EOF#ie(3)#
+        <Zeilennummer>] 
+              #right#<Variable> [, <Variable> ] [...]  
+ 
+Erklärung :   <Eingabeaufforderung>:  TEXT-Konstante 
+              <Zeilennummer>:         INT-Konstante 
+              <Variable>:             Variable, der der eingelesene Werte
+                                      zugewiesen werden soll 
+ 
+              Mit der INPUT-Anweisung werden Daten zur Laufzeit des
+              Programms von der Tastatur in Variablen eingelesen. 
+ 
+              Folgt dem INPUT-Statement ein Semikolon, so wird nach
+              Beendigung der Eingabe kein Zeilenwechsel vorgenommen. 
+ 
+              Fehlt die <Eingabeaufforderung>, so wird "? " als Eingabe­
+              aufforderung ausgegeben. 
+              Folgt der  ein Semikolon, so wird "? " noch zusätzlich ausge­
+              geben. Bei einem Komma wird dieser Standard-Prompt unter­
+              drückt. 
+ 
+              Folgt der <Eingabeaufforderung> die Zeichenfolge 'EOF', so wird
+              bei Eingabe eines Leertextes zu der nach 'EOF' angegebenen
+              Zeilennumer verzweigt. 
+ 
+              Sollen mehrere Variablen eingelesen werden, so muß der Benutzer
+              auch entsprechend viele Daten (durch Kommata getrennt) zur Verfü­
+              gung stellen. 
+ 
+              Wird nichts eingegeben beziehungsweise nur die richtige Anzahl von
+              Kommata, so wird den entsprechenden Variablen 0, 0.0 bzw. 'niltext'
+              zugewiesen. 
+ 
+              Bei der Eingabe für eine Textvariable können alle Zeichen (außer
+              Steuerzeichen) eingegeben werden. Beginnt eine Eingabe mit dem
+              Anführungszeichen oder endet sie damit, dann muß sie auch damit
+              enden beziehungsweise beginnen. Diese beiden Anführungszeichen
+              werden nicht mit zugewiesen. Innerhalb dieser Texteingabe dürfen
+              Anführungszeichen stehen, aber keine Kommata. 
+ 
+              Eingaben für numerische Variablen müssen in der für Konstanten
+              üblichen Schreibweise erfolgen. Vorzeichen sind allerdings zusätzlich
+              erlaubt. 
+ 
+              Vor Zuweisung der eingegebenen Werte an die Variablen werden
+              Anzahl und Typ(en)  und die Anzahl überprüft. 
+              Dabei können folgende Fehlerfälle auftreten: 
+              - "falscher Typ": 
+                Es wurde ein Text statt einer Zahl eingegeben, es wurde ein REAL
+                statt eines INTs eingegeben oder eine Texteingabe ist fehlerhaft. 
+              - "zu wenig Daten" 
+              - "zu viele Daten" 
+              - "Überlauf": 
+                Es wurde eine zu große (oder zu kleine) Zahl eingegeben. 
+ 
+              Kommt es zu einem Fehler, dann wird nach der Meldung "?Eingabe
+              wiederholen !  (<Fehlerbeschreibung>)" die Eingabe zum Editieren
+              angeboten. 
+ 
+Hinweis :     Bei Eingabe von 'ESC k' kann die letzte Eingabezeile zum Editieren
+              zurückgeholt werden. 
+ 
+              Die Eingabe kann mit der Systemprozedur 'sysin' aus einer Datei
+              erfolgen. Aus der Eingabedatei wird für jedes INPUT-Statement eine
+              Zeile eingelesen. Die Ausgabe der Eingabeaufforderung und der
+              Zeilenwechsel nach der Eingabe werden unterdrückt. Sind die
+              Eingabedaten fehlerhaft, so wird das Programm mit 'errorstop'
+              abgebrochen. 
+ 
+              Wird die Ausgabe mit 'sysout' umgeleitet, so werden die Eingabe­
+              aufforderung, die Eingabezeichenfolge und der Zeilenwechsel nach
+              der Eingabe auf den Bildschirm und in die Ausgabedatei ausgegeben,
+              auch dann, wenn der Text der Eingabe aus einer Datei eingelesen
+              wurde. 
+ 
+ 
+Beispiel :      1990 INPUT "Name, Vorname, Alter"; 
+                #right#name$, vorname$, alter% 
+ 
+ 
+Vergleiche :  INKEY$-, INPUT$-Funktionen 
+ 
+ 
+ 
+Funktion : INPUT$ 
+ 
+Zweck :        Holen einer Zeichenfolge von der Tastatur 
+ 
+Syntax :       INPUT$ (<Anzahl Zeichen>) 
+ 
+Erklärung :   <Anzahl Zeichen>: INT-Ausdruck 
+ 
+              Die Funktion liefert eine Folge von <Anzahl Zeichen> Textzeichen
+              aus dem Tastaturzeichenpuffer. Enthält der Puffer nicht alle ge­
+              wünschten Zeichen, so wird auf weitere Zeichen von der Tastatur
+              gewartet. 
+              Die gelieferten Zeichen erscheinen nicht auf dem Bildschirm. 
+ 
+ 
+Beispiel :      10 PRINT "Bitte drei Zeichen eingeben !" 
+                20 LET a$ = INPUT$ (3) 
+                30 PRINT "Danke schön !" 
+ 
+ 
+Vergleiche :  INKEY$-Funktion, INPUT-Anweisung 
+ 
+ 
+ 
+Funktion : INSTR 
+ 
+Zweck :        Suchen einer Zeichenfolge in einer anderen 
+ 
+Syntax :       INSTR ( [<Startposition>,] <TEXT-Ausdruck1>, 
+              #right#<TEXT-Ausdruck 2>) 
+ 
+Erklärung :   <Startposition>: INT-Ausdruck 
+ 
+              Die Funktion liefert die Position, ab der der TEXT-Ausdruck 2 das
+              erste Mal im TEXT-Ausdruck 1 vorkommt. 
+              Die Position wird als INT geliefert. 
+ 
+ 
+Beispiel :      10 LET a$ = "hallihallo" 
+                20 LET b$ = "all" 
+                30 PRINT INSTR (a$, b$); INSTR (5, a$, b$) 
+                Ausgabe:   2  7 
+ 
+ 
+ 
+Funktion : INT 
+ 
+Zweck :        Ermittlung der nächstkleineren ganzen Zahl 
+ 
+Syntax :       INT (<REAL-Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert die größte ganze Zahl, für die gilt: 
+              n kleiner gleich <REAL-Ausdruck>. 
+              Bei positiven Werten bedeutet das, daß die Nachkommastellen abge­
+              schnitten werden. 
+              Das Ergebnis wird als REAL geliefert. 
+ 
+ 
+Beispiel :      10 PRINT INT (11.74); INT (-11.74) 
+                Ausgabe:  11  -12 
+ 
+Vergleiche :  CINT-, FIX-Funktionen 
+ 
+ 
+ 
+Anweisung : KILL 
+ 
+Zweck :        Löschen einer Datei in der Task 
+ 
+Syntax :       KILL <Dateiname> 
+ 
+Erklärung :   <Dateiname>: TEXT-Ausdruck 
+              Die Datei <Dateiname> wird (ohne Nachfrage) gelöscht. 
+ 
+ 
+Beispiel :      2110 KILL "Scratchdatei" 
+ 
+ 
+ 
+ 
+Funktion : LEFT$ 
+ 
+Zweck :        Erzeugung eines Teiltextes aus einem anderen Text 
+ 
+Syntax :       LEFT$ (<TEXT-Ausdruck>, <Anzahl Zeichen>) 
+ 
+Erklärung :   <Anzahl Zeichen>: INT-Ausdruck 
+ 
+              Die Funktion liefert die ersten <Anzahl Zeichen> Textzeichen des
+              TEXT-Ausdrucks. 
+ 
+ 
+Beispiel :      10 LET a$ = "hallihallo" 
+                20 PRINT LEFT$ (a$, 4) 
+                Ausgabe:   hall 
+ 
+Vergleiche :  MID$-, RIGHT$-Funktionen, LSET-, MID$-, RSET-
+              Anweisungen 
+ 
+ 
+ 
+Funktion : LEN 
+ 
+Zweck :        Ermittlung der Länge eines Textes 
+ 
+Syntax :       LEN (<TEXT-Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert die Anzahl der im TEXT-Ausdruck enthaltenen
+              Zeichen (also die Länge des Textes). Die Länge wird als INT
+              geliefert. 
+              Ein Leertext (niltext, "") hat die Länge null. 
+ 
+ 
+Beispiel :      10 LET a$ = "hallihallo" 
+                20 PRINT LEN (a$) 
+                Ausgabe:   10 
+ 
+ 
+ 
+Anweisung : LET 
+ 
+Zweck :        Zuweisung eines Wertes an eine Variable 
+ 
+Syntax :       [LET] <Variable> = <Ausdruck> 
+ 
+Erklärung :   Die LET-Anweisung ermöglicht das Zuweisen von Werten an Variab­
+              len (dazu gehören auch die Elemente von Feldern). 
+ 
+              Das Schlüsselwort LET ist optional, d.h. eine Zuweisung wird auch
+              ohne dieses Schlüsselwort erkannt. 
+ 
+              #on("iZuweisung an TEXT-Variablen:#off("i 
+                LET <TEXT-Variable> = <TEXT-Ausdruck> oder <num.
+                Konstante> 
+              Die numerische Konstante wird automatisch in einen TEXT umge­
+              wandelt (vgl. STR$-Funktion) 
+ 
+              #on("iZuweisung an INT-Variablen:#off("i 
+                LET <INT-Variable> = <num. Ausdruck> 
+              Ist der numerische Ausdruck ein REAL-Ausdruck, so wird automa­
+              tisch nach INT konvertiert (vgl. CINT-Funktion). 
+ 
+              #on("iZuweisung an REAL-Variablen:#off("i 
+                LET <REAL-Variable> = <num. Ausdruck> 
+              Ist der numerische Ausdruck ein INT-Ausdruck, so wird automatisch
+              nach REAL konvertiert (vgl. CDBL-Funktion). 
+ 
+ 
+Beispiel :      10 LET t$ = "murmel marmel" 
+                20 LET t$ = 1245.3 'wie "1245.3" 
+                30 LET i% = 852 
+                40 LET i% = 12.73  'aufgerundet: 13 
+                50 LET r = 564     'wie 564. 
+                60 LET r = 157.36 
+ 
+ 
+ 
+ 
+Anweisung : LINE INPUT 
+ 
+Zweck :        Einlesen einer Eingabe von der Tastatur in eine TEXT-Variable 
+ 
+Syntax :       LINE INPUT [;] [<Eingabeaufforderung>;] 
+              #right#<TEXT-Variable> 
+ 
+Erklärung :   Die LINE INPUT-Anweisung ermöglicht das Einlesen von Eingaben
+              in TEXT-Variablen, aber im Gegensatz zu INPUT ohne Beachtung
+              von Trennzeichen (z.B. ","). 
+ 
+              Steht direkt nach LINE INPUT ein Semikolon, so wird nach Beendi­
+              gung der Eingabe der Zeilenwechsel unterdrückt. 
+ 
+              Der eingegebene Text wird (bis auf das CR-Zeichen) der TEXT-
+              Variablen zugewiesen. 
+ 
+ 
+Beispiel :      2110 LINE INPUT "Name: ";name$ 
+ 
+ 
+              Der Benutzer könnte nun auch folgendes eingeben: 
+              Neumann, Alfred E. 
+ 
+Vergleiche :  INPUT-Anweisung 
+ 
+ 
+ 
+Funktion : LOG 
+ 
+Zweck :        Berechnung des natürlichen Logarithmus einer Zahl 
+ 
+Syntax :       LOG (<REAL-Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert den natürlichen Logarithmus des Wertes des
+              REAL-Ausdrucks. 
+              Bei nicht-positiven Werten kommt es zu einem Fehler in der
+              EUMEL-Prozedur 'log2'. 
+              Das Ergebnis der Funktion wird als REAL geliefert. 
+ 
+ 
+Beispiel :      10 PRINT LOG (10.0) 
+                Ausgabe:  2.302585 
+ 
+Vergleiche :  EXP-Funktion (Komplementärfunktion) 
+ 
+ 
+ 
+Funktion : LPOS 
+ 
+Zweck :        Ermittlung der aktuellen Druckspalte 
+ 
+Syntax :       LPOS (<num. Ausdruck>) 
+ 
+Erklärung :   Geliefert wird die Nummer der Spalte (als INT), in die das nächste
+              nächste Zeichen mit LPRINT ausgegeben wird. Die Spalte ganz links
+              hat die Nummer 1. 
+              Der Argument-Ausdruck ist ein Dummy-Argument (hat keinen
+              Einfluß auf den gelieferten Wert). 
+ 
+ 
+Beispiel :      3010 IF LPOS (0) > 65 THEN LPRINT 
+                3020 LPRINT name$ 
+ 
+ 
+              Falls die Druckposition hinter Spalte 65 liegt, wird eine neue Druck­
+              zeile begonnen. 
+ 
+Vergleiche :  LPRINT-Anweisung, TAB-, POS-Funktion 
+ 
+ 
+ 
+Anweisung : LPRINT 
+ 
+Zweck :        Ausgabe in eine Druckdatei 
+ 
+Syntax :       LPRINT [#ib(3)#USING#ie(3)# <Format> ;] 
+              #right#[ #ib(3)#TAB#ie(3)# (<Spalte>) | , | ; | <Ausdruck> ] [...] 
+ 
+Erklärung :   <Format>  : TEXT-Ausdruck für USING (vgl. PRINT) 
+              <Spalte>  : INT-Ausdruck (vgl. PRINT) 
+              <Ausdruck>: TEXT-Ausdruck oder numerischer Ausdruck 
+ 
+              Die LPRINT-Anweisung arbeitet wie PRINT (siehe dort), mit dem
+              Unterschied, daß LPRINT die Zeichen nicht auf den Bildschirm, son­
+              dern in eine Datei mit dem Namen "BASIC LPRINT OUTPUT"
+              ausgibt. Diese Datei wird automatisch eingerichtet, falls sie noch
+              nicht existiert. Ist sie schon vorhanden, so werden die auszugeben­
+              den Zeichen am Ende der Datei angefügt. 
+              Nach oder bei Ablauf des Programms kann die Datei (evtl. nach
+              vorheriger Aufbereitung durch Textverarbeitungsprogramme) mit
+              'print', wie im EUMEL-System üblich, an den Drucker geschickt
+              werden. Der Benutzer ist selbst dafür verantwortlich, daß er die
+              Druckdatei, sofern die Daten nicht mehr benötigt werden, vor einem
+              neuen Programmlauf leert oder löscht. Versäumt er dies, so bleiben
+              die alten Daten in der Druckdatei, und die neuen Ausgaben werden
+              hinten angefügt. Das Löschen der Druckdatei kann zum Beispiel
+              durch das BASIC-Programm mit der KILL-Anweisung erreicht
+              werden. 
+ 
+              Die Art der Ausgabe und die Syntax ist sonst analog zur PRINT-
+              Anweisung (siehe Erläuterungen dort). 
+ 
+ 
+Beispiel :      2110 LPRINT "Dieser Text geht in die Druckdatei" 
+                2120 LPRINT TAB (12); "Datum: " DATE$ 
+                2130 LPRINT 1, 2, 3 
+ 
+ 
+Vergleiche :  PRINT-Anweisung, LPOS-Funktion 
+ 
+ 
+ 
+Anweisung : LSET 
+ 
+Zweck :        Ersetzen von Zeichen eines Textes von links her 
+ 
+Syntax :       LSET <TEXT-Variable> = <TEXT-Ausdruck> 
+ 
+Erklärung :   Das Ergebnis des TEXT-Ausdrucks wird, links beginnend, in der
+              TEXT-Variablen eingesetzt. Es werden höchstens so viele Zeichen
+              ersetzt, wie bisher schon in der Variablen vorhanden waren, das heißt
+              die Länge des Textes in der Variablen ändert sich nicht. 
+ 
+ 
+Beispiel :      210 LET a$ = "12345" 
+                220 LSET a$ = "ABCDEFG" 
+                230 PRINT a$, 
+                240 LSET a$ = "abc" 
+                250 PRINT a$ 
+                Ausgabe:    ABCDE         abcDE 
+ 
+Vergleiche :  MID$-, RSET-Anweisungen, LEFT$-, MID$-, RIGHT$-Funk­
+              tionen 
+ 
+ 
+ 
+Anweisung : MID$ 
+ 
+Zweck :        Ersetzen von Zeichen innnerhalb eines Textes 
+ 
+Syntax :       MID$ (<TEXT-Variable>, <Startposition> 
+              #right#[, <Anzahl Zeichen>] ) = <TEXT-Ausdruck> 
+ 
+Erklärung :   <Startposition> : INT-Ausdruck 
+              <Anzahl Zeichen>: INT-Ausdruck 
+ 
+              Das Ergebnis des TEXT-Ausdrucks wird, bei <Startposition>
+              beginnend, in der TEXT-Variablen eingesetzt. Es werden höch­
+              stens LEN <TEXT-Variable> Textzeichen ersetzt. Ist keine
+              <Anzahl Zeichen> angegeben, so werden so viele Zeichen des
+              TEXT-Ausdrucks wie möglich in der TEXT-Variablen eingetragen. 
+              Außerdem gilt: Es wird nicht über das bisherige Ende des Variablen­
+              inhalts ersetzt, das heißt die Länge des Textes in der Variablen
+              ändert sich nicht. 
+ 
+ 
+Beispiel :      210 LET a$ = "12345" 
+                220 MID$ (a$, 3) = "ABCDEFG" 
+                230 PRINT a$, 
+                240 MID$ (a$, 2, 1) = "abc" 
+                250 PRINT a$ 
+                Ausgabe:    12ABC           1aABC 
+ 
+Vergleiche :  LEFT$-, MID$-, RIGHT$-Funktionen, LSET-, RSET-
+              Anweisungen 
+ 
+ 
+ 
+Funktion : MID$ 
+ 
+Zweck :        Erzeugung eines Teiltextes aus einem anderen Text 
+ 
+Syntax :       MID$ (<TEXT-Ausdruck>, 
+              #right#<Startposition> [, <Anzahl Zeichen>]) 
+ 
+Erklärung :   <Startposition> : INT-Ausdruck 
+              <Anzahl Zeichen>: INT-Ausdruck 
+ 
+              Die Funktion liefert höchstens <Anzahl Zeichen> Textzeichen des
+              TEXT-Ausdrucks von Position <Startposition> an. 
+              Wird <Anzahl Zeichen> nicht angegeben, so werden alle Zeichen
+              ab Startposition geliefert. 
+              Werden rechts von <Startposition> keine Zeichen mehr gefunden
+              oder ist <Anzahl Zeichen> gleich null, so wird ein Leertext geliefert. 
+ 
+ 
+Beispiel :      10 LET a$ = "hallihallo" 
+                20 PRINT MID$ (a$, 4, 4), 
+                30 PRINT MID$ (a$, 6) 
+                Ausgabe:   liha           hallo 
+ 
+Vergleiche :  LEFT$-, RIGHT$-Funktionen, LSET-, MID$-, RSET-
+              Anweisungen 
+ 
+ 
+ 
+Funktion : MKD$, MKI$ 
+ 
+Zweck :        Codierung von Zahlenwerten in Texte 
+ 
+Syntax :       MKD$ (<REAL-Ausdruck>) 
+              MKI$ (<INT-Ausdruck>) 
+ 
+Erklärung :   Mit MKD$ und MKI$ können INTs und REALs zu Texten codiert
+              werden. 
+ 
+              Die Funktion MKD$ liefert einen 8 Zeichen langen TEXT, der den
+              Wert des REAL-Ausdrucks codiert enthält. 
+              Vergleichbar arbeitet MKI$, das einen 2 Zeichen langen TEXT liefert,
+              der den Wert des INT-Ausdrucks darstellt. 
+ 
+              Mit MKD$ und MKI$ codierte Werte können mit CVD und CVI (s.d.)
+              wieder decodiert werden. 
+ 
+ 
+Beispiel :      10 zahl$ = MKD$ (3.1415) 
+                20 PRINT CVD (zahl$) 
+                Ausgabe:  3.1415 
+ 
+Vergleiche :  CVD-, CVI-Funktionen 
+ 
+ 
+ 
+Operator : MOD 
+ 
+Siehe Kapitel 4.4. (Operatoren) 
+ 
+ 
+ 
+Anweisung : NAME 
+ 
+Zweck :        Umbenennen einer Datei 
+ 
+Syntax :       NAME <alter Name> AS <neuer Name> 
+ 
+Erklärung :   <alter Name>: TEXT-Ausdruck 
+              <alter Name>: TEXT-Ausdruck 
+ 
+              NAME benennt die Datei <alter Name> in <neuer Name> um. 
+ 
+ 
+Beispiel :      10 NAME "Käufer" AS "Kunden" 
+ 
+ 
+ 
+ 
+Anweisung : NEXT 
+ 
+Zweck :        Markierung des Endes einer FOR-Schleife 
+ 
+Syntax :       NEXT [<num. Variable>] [, <num. Variable>] [...] 
+ 
+Erklärung :   NEXT markiert das Ende einer FOR-Schleife (vergleiche FOR-
+              Anweisung). 
+ 
+              Wird keine Variable angegeben, so bezieht sich das NEXT auf das
+              letzte textuell vorhergehende FOR. 
+              Wird eine Laufvariable angegeben, so muß sie mit der im letzten
+              FOR verwendeten Laufvariable übereinstimmen. 
+              Werden mehrere Variablen angegeben, so werden durch die
+              NEXT-Anweisung mehrere FOR-Schleifen abgeschlossen. 
+              Beachten Sie, daß FOR-Schleifen sich nicht überschneiden dürfen,
+              sondern nur Schachtelungen zulässig sind. Es kommt daher auf die
+              Reihenfolge der Variablen bei den NEXT-Anweisungen an. Die
+              letzte (innerste) FOR-Schleife muß als erste wieder mit dem zuge­
+              hörigen NEXT abgeschlossen werden. 
+ 
+Vergleiche :  FOR-, WHILE-Anweisungen 
+ 
+ 
+ 
+Operator : NOT 
+ 
+Siehe Kapitel 4.4. (Operatoren) 
+ 
+ 
+ 
+Funktion : OCT$ 
+ 
+Zweck :        Erzeugung der oktalen Darstellung einer Zahl als Text 
+ 
+Syntax :       OCT$ (<INT-Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert die oktale (Zweierkomplement-) Darstellung der
+              Zahl, die sich aus dem INT-Ausdruck ergibt. 
+ 
+ 
+Beispiel :      10 PRINT OCT$ (10000) 
+                Ausgabe:  23420 
+ 
+Vergleiche :  OCT$-Funktion 
+ 
+ 
+ 
+Anweisung : ON 
+ 
+Zweck :        Ausführung eines "berechneten" Sprungs oder Unterprogramm-
+              Aufrufs 
+ 
+Syntax :       ON <Sprungziel Nr.> GOTO | GOSUB 
+              #right#<Zeilennummer> [, <Zeilennummer>] [...] 
+ 
+Erklärung :   <Sprungziel Nr.>: INT-Ausdruck 
+              <Zeilennummer>   : INT-Konstante 
+ 
+              ON ermöglicht die Verzweigung des Programms an eine von mehre­
+              ren Stellen abhängig vom Ergebnis eines INT-Ausdrucks. 
+              Gelangt das Programm an eine ON-Anweisung, dann wird zunächst
+              der Wert des INT-Ausdrucks berechnet. Dieses Ergebnis bildet dann
+              die Nummer n des Sprungziels. Danach wird zur n-ten Zeilen­
+              nummer, die nach GOTO beziehungsweise GOSUB steht, verzweigt. 
+              Die maximale Anzahl von Zeilennummern, die nach GOTO oder
+              GOSUB angegeben werden dürfen, ist 512. 
+              Nimmt <Sprungziel Nr.> einen Wert an, zu dem keine Zeile in der
+              Liste gefunden wird (z.B. Werte kleiner gleich null oder Werte größer
+              als die Anzahl der angegebenen Zeilennummern), so wird das Pro­
+              gramm mit der der ON-Anweisung folgenden Programmzeile fortge­
+              setzt. 
+ 
+              Statt GOTO und GOSUB darf auch GO TO beziehungsweise
+              GO SUB geschrieben werden. 
+ 
+Hinweis :     Die ON-Anweisung muß in #on("ieiner#off("i Programmzeile stehen. 
+ 
+ 
+Beispiel :      260 INPUT "Menüpunkt 1, 2 oder 3", a 
+                270 ON VAL (a) GOTO 300, 400, 500 
+                280 GOTO 260 
+                300 PRINT "Menüpunkt 1" 
+                . 
+                . 
+                400 PRINT "Menüpunkt 2" 
+                . 
+                . 
+                500 PRINT "Menüpunkt 3" 
+ 
+ 
+              Entsprechend der Eingabe wird nach 300, 400 oder 500 verzweigt.
+              Bei Fehleingaben wird Zeile 280 ausgeführt. 
+ 
+Vergleiche :  GOSUB-, GOTO-, IF-Anweisungen 
+ 
+ 
+ 
+Anweisung : OPTION BASE 
+ 
+Zweck :        Festlegung des kleinsten Wertes für Feldindizes 
+ 
+Syntax :       OPTION BASE 0|1 
+ 
+Erklärung :   OPTION BASE legt fest, ob die nachfolgend dimensionierten Felder
+              Elemente mit dem Index 0 erhalten, oder ob der niedrigste Index 1
+              ist. Voreingestellt ist OPTION BASE 0. 
+ 
+Hinweis :     Der niedrigste Feldindex kann für jedes Feld individuell eingestellt
+              werden. Die OPTION BASE-Anweisung gilt für alle Felder, deren
+              Dimensionierung ihr textuell nachfolgen. Eine erneute OPTION
+              BASE-Anweisung kann dann die Untergrenze für die #on("iihr#off("i folgenden
+              Dimensionierungen festlegen. 
+ 
+ 
+Beispiel :      10 DIM a (100)       'Indizes 0-100 
+                20 OPTION BASE 1 
+                30 b$ (3) = "hallo"  'Indizes 1-10 
+                40 DIM a% (5)        'Indizes 1-5 
+                50 OPTION BASE 0 
+                60 DIM c% (9)        'Indizes 0-9 
+                70 LET d (4) = 12.3  'Indizes 0-10 
+ 
+ 
+Vergleiche :  DIM-Anweisung 
+ 
+ 
+ 
+Operator : OR 
+ 
+Siehe Kapitel 4.4. (Operatoren) 
+ 
+ 
+ 
+Funktion : POS 
+ 
+Zweck :        Ermittlung der aktuellen Cursorspalte 
+ 
+Syntax :       POS (<num. Ausdruck>) 
+ 
+Erklärung :   Geliefert wird die Nummer der Spalte (als INT), in der sich der Cursor
+              auf dem Bildschirm befindet. Die Spalte ganz links hat die Num­
+              mer 1. 
+              Der Argument-Ausdruck ist ein Dummy-Argument (hat keinen
+              Einfluß auf den gelieferten Wert). 
+ 
+ 
+Beispiel :      10 CLS 
+                20 PRINT "testtext"; 
+                30 PRINT POS (0) 
+                Ausgabe:  testtext 9 
+ 
+ 
+Vergleiche :  CSRLIN-, LPOS-Funktionen 
+ 
+ 
+ 
+Anweisung : PRINT 
+ 
+Zweck :        Ausgabe auf den Bildschirm 
+ 
+Syntax :       PRINT [#ib(3)#USING#ie(3)# <Format> ;] 
+              #right#[ #ib(3)#TAB#ie(3)# (<Spalte>) | , | ; | <Ausdruck> ] [...] 
+ 
+Erklärung :   <Format>  : TEXT-Ausdruck für USING (s. u.) 
+              <Spalte>  : INT-Ausdruck (s. u.) 
+              <Ausdruck>: TEXT-Ausdruck oder numerischer Ausdruck, der
+                          ausgegeben werden soll. 
+ 
+               PRINT dient der Ausgabe von Zeichen auf dem Bildschirm. 
+               Numerische Werte werden mit sieben signifikanten Ziffer ausgege­
+               ben. Bei Exponentendarstellung werden für den Exponent maximal 3
+               Ziffern ausgegeben. Hinter allen numerischen Werten und vor posi­
+               tiven numerischen Werten wird jeweils ein Leerzeichen ausgegeben. 
+ 
+               TAB bewirkt eine Positionierung des Cursors auf die angegebene
+               Spalte (die Spalte ganz links hat die Nummer 1). Ist die Spaltenzahl
+               größer als die mit WIDTH eingestellte Ausgabebreite, so wird auf die
+               Spalte mit der Nummer Spalte MODULO Ausgabebreite positioniert.
+               Eine Spaltennummer kleiner gleich null bewirkt eine entsprechende
+               Warnung. 
+               Ist die Spalte mit der angegebenen Nummer in der aktuellen Zeile
+               bereits überschritten, dann wird auf die nächste Zeile positioniert. 
+ 
+               Ein Semikolon bewirkt, daß der Cursor an der gerade erreichten
+               Position bleibt. 
+ 
+               Ein Komma bewirkt die Positionierung auf die nächste gültige Spal­
+               te, für deren Nummer gilt: Nummer MODULO 16 ist 1. 
+               Das Komma dient also der Ausgabe in 16 Zeichen breiten Zonen. 
+ 
+               Endet die PRINT-Anweisung mit TAB (<Spalte>), einem Komma
+               oder einem Semikolon, dann wird kein Zeilenvorschub ausgelöst. 
+ 
+               #onbold#USING 
+               Der EUMEL-BASIC-Compiler unterstützt auch die PRINT
+               USING-Anweisung für formatierte Ausgaben. 
+               Der nach dem Wort USING angegebene TEXT-Ausdruck spezifi­
+               ziert das Ausgabeformat für eine PRINT USING-Anweisung. 
+ 
+               Formatierung von Texten: 
+               "!": Nur das erste Zeichen einer Zeichenfolge wird ausgegeben 
+               "\n Leerzeichen\": Es werden die 2 + n ersten Zeichen einer
+                    Zeichenfolge ausgegeben 
+               "&": Alle Zeichen einer Zeichenfolge werden ausgegeben 
+ 
+               Formatierung von Zahlen: 
+               "\#": bezeichnet eine Ziffernposition 
+               ".": Position des Dezimalpunkts 
+               "+": (vor oder nach Zahlen) Ausgabe des Vorzeichens 
+               "-": (nach Zahlen) gegebenenfalls Ausgabe von "-" hinter der
+                    Zahl 
+               "**": Führende Leerstellen werden mit Sternchen aufgefüllt; wirkt
+                     außerdem wie "\#\#". 
+               "$$": Es wird ein Dollarzeichen links vor der formatierten Zahl ausgegeben;
+                     wirkt außerdem wie "\#\#". 
+               "**$": Führende Leerstellen werden mit Sternchen ausgefüllt und direkt vor
+                      der formatierten Zahl wird ein Dollarzeichen ausgegeben; wirkt
+                      außerdem wie "\#\#\#". 
+               ",": (vor Dezimalpunkt) Unterteilung der Vorkommastellen in Dreier­
+                    gruppen mittels Komma 
+               "^^^^": Position des Exponenten 
+               "_": Ein Zeichen, das einem Unterstreichungsstrich folgt, wird unverändert
+                    ausgegeben 
+ 
+               Ist der Format-Ausdruck fehlerhaft, so kommt es zum Fehler "USING-
+               Format fehlerhaft". 
+               Überschreitet eine auszugebende Zahl in irgendeiner Hinsicht die im
+               Format-Ausdruck für sie vorgesehene Stellenzahl, so wird das Zeichen "%"
+               ausgegeben, um den Fehler anzuzeigen. 
+ 
+ 
+Hinweis :      1.  PRINT (und PRINT USING) richtet sich bei allen Ausgaben nach
+                  der mit WIDTH eingestellten Ausgabebreite. 
+               2. Alle Ausgaben von PRINT können mit der Systemprozedur
+                  'sysout' in eine Datei umgeleitet werden. Dann wird nichts auf
+                  das Terminal ausgegeben. 
+               3. Das Verhalten beim Erreichen der letzten Bildschirmzeile kann
+                  mit der Prozedur 'basic page' gesteuert werden. Vergleiche
+                  hierzu Kapitel 5, "Steuerung der Bildschirmausgabe". 
+ 
+ 
+Beispiel :      10 PRINT "hallo", 2 ^ 32 TAB (33) "Ende"; 
+ 
+               Ausgabe:  hallo            4.294967E+09   Ende 
+               Position: 1234567890123456789012345678901234567890 
+ 
+ 
+Vergleiche :   WRITE-, LPRINT-Anweisungen, POS-, CSRLIN-, SPC-
+               Funktionen 
+ 
+ 
+ 
+Anweisung : RANDOMIZE 
+ 
+Zweck :        Festlegung eines Anfangswertes für den Zufallszahlengenerator 
+ 
+Syntax :       RANDOMIZE [<num. Ausdruck>] 
+ 
+Erklärung :   Mit RANDOMIZE erhält der Zufallszahlengenerator einen bestimmten
+              Startwert. 
+              Ist kein numerischer Ausdruck angegeben, so wird während des
+              Programmlaufs die Meldung "Startwert des Zufallszahlen­
+              generators ?" ausgegeben und ein Startwert eingelesen. 
+ 
+              Wird der Zufallszahlengenerator immer mit dem gleichen Wert gestar­
+              tet, so liefert er auch immer die gleichen Zufallszahlen. Soll er immer
+              verschiedene Werte liefern, so kann er zum Beispiel mit der System­
+              uhr auf zufällige Startwerte gesetzt werden (RANDOMIZE TIMER). 
+ 
+ 
+Beispiel :      10 RANDOMIZE 4711 
+                20 FOR i = 1 TO 5 
+                30 PRINT INT (RND * 10); 
+                40 NEXT i 
+                Ausgabe:   5  6  2  9  6 
+ 
+Vergleiche :  RND-Funktion 
+ 
+ 
+ 
+Anweisung : READ 
+ 
+Zweck :        Auslesen von Daten aus DATA-Anweisungen 
+ 
+Syntax :       READ <Variable> [, <Variable>] [...] 
+ 
+Erklärung :   <Variable>: numerische Variable oder TEXT-Variable 
+ 
+              Die READ-Anweisung liest die nächsten Elemente aus der aktuellen
+              DATA-Anweisung (s.d.) in die angegebenen Variablen ein. 
+ 
+              In TEXT-Variablen können sowohl "quoted strings" als auch "un­
+              quoted strings" (vgl. DATA-Anweisung) eingelesen werden. 
+              In numerische Variablen können dagegen nur "unquoted strings"
+              eingelesen werden. Außerdem müssen die Zeichen des "unquoted
+              string" eine gültige Darstellung einer numerischen Konstanten (even­
+              tuell mit Vorzeichen) sein. Sind diese Bedingungen nicht erfüllt, so
+              kommt es bei der Ausführung des Programms zu entsprechenden
+              Fehlern. 
+ 
+              Eine READ-Anweisung kann Daten aus vorangehenden und nach­
+              folgenden DATA-Anweisungen lesen. 
+              Alle DATA-Anweisungen eines Programms bilden zusammen einen
+              großen sequentiellen Speicher, auf den mit READ der Reihe nach
+              zugegriffen wird. Intern wird ein sogenannter READ-DATA-Zeiger
+              geführt, der immer auf das nächste auszulesende Element zeigt. 
+ 
+              Die RESTORE-Anweisung (s.d.) ermöglicht es, den READ-DATA-
+              Zeiger auf das erste Element einer bestimmten DATA-Zeile zu
+              setzen. 
+ 
+              Sind keine Daten mehr für READ vorhanden, so wird die Ausführung
+              des Programms mit der Fehlermeldung "Keine Daten mehr für
+              READ" abgebrochen. 
+ 
+ 
+Beispiel :      2020 PRINT "Stadt", "Land", "Fluß" 
+                2030 READ stadt$, land$, fluß$ 
+                2040 PRINT stadt$, land$, fluß$ 
+                . 
+                5000 DATA Köln, Bundesrepublik Deutschland, Rhein 
+ 
+ 
+Vergleiche :  DATA-, RESTORE-Anweisungen 
+ 
+ 
+ 
+Anweisung : REM 
+ 
+Zweck :        Ermöglicht das Einfügen von Kommentaren in ein Programm 
+ 
+Syntax :       REM <Zeichenfolge> 
+ 
+Erklärung :   <Zeichenfolge>: Beliebige Folge von Zeichen 
+ 
+              Wird eine REM-Anweisung gefunden, so wird der Rest der Pro­
+              grammzeile nicht weiter beachtet. Die Compilierung wird in der fol­
+              genden Zeile fortgesetzt. 
+              Es empfielt sich, von Kommentarzeilen möglichst oft Gebrauch zu
+              machen, weil sie den Programmtext dokumentieren und strukturieren. 
+ 
+Hinweis :     Nach REM können keine weiteren Anweisungen mehr in einer Pro­
+              grammzeile stehen, da sie nicht übersetzt werden. Auch der Doppel­
+              punkt wird nach REM nicht beachtet. 
+ 
+ 
+Beispiel :      1000 REM Ausgabe des Feldes 
+                1010 FOR i = 1 TO feldgroesse% 
+                1020 PRINT "Eintrag"; i; feld (i) 
+                1030 NEXT i 
+ 
+ 
+ 
+Anweisung : RESTORE 
+ 
+Zweck :        Setzen des READ-DATA-Zeigers auf den Anfang einer angegebe­
+              nen Zeile 
+ 
+Syntax :       RESTORE [<Zeilennummer>] 
+ 
+Erklärung :   <Zeilennummer>: INT-Konstante 
+ 
+              Der READ-DATA-Zeiger (vgl. DATA-Anweisung) wird auf die Zeile
+              <Zeilennummer> gesetzt. 
+              Wird keine Zeilennummer angegeben, so wird für <Zeilennummer>
+              1 eingesetzt. 
+ 
+              Existiert die Programmzeile <Zeilennummer> nicht oder ist in ihr
+              keine DATA-Anweisung vorhanden, so wird der Zeiger auf die
+              nächste textuell folgende DATA-Anweisung gesetzt. 
+              Folgt der angegebenen Zeilennummer im Programm keine DATA-
+              Anweisung mehr, kommt es zu der Fehlermeldung "RESTORE: Keine
+              DATA-Anweisung in oder nach Zeile <Zeilennummer> gefunden !" 
+ 
+ 
+Beispiel :      10 READ a, b, c 
+                20 RESTORE 
+                30 READ d, e, f 
+                40 DATA 2, 3, 5 
+                50 PRINT a; b; c; d; e; f 
+                Ausgabe:   2  3  5  2  3  5 
+ 
+Vergleiche :  DATA-, READ-Anweisungen 
+ 
+ 
+ 
+Anweisung : RETURN 
+ 
+Zweck :        Rücksprung aus einem Unterprogramm 
+ 
+Syntax :       RETURN 
+ 
+Erklärung :   RETURN bewirkt einen Rücksprung aus dem Unterprogramm hinter
+              die aufrufende GOSUB-Anweisung. 
+ 
+              Es dürfen auch mehrere RETURN-Anweisungen in einem Unterpro­
+              gramm vorkommen, um es an verschiedenen Stellen zu verlassen. 
+ 
+              Wird ein RETURN gefunden, ohne daß ein GOSUB durchlaufen
+              wurde, so wird mit der Fehlermeldung "RETURN ohne GOSUB"
+              abgebrochen. 
+ 
+ 
+Beispiel :      140 GOSUB 10000  'Zeige Uhrzeit 
+                . 
+                . 
+                370 GOSUB 10000  'Zeige Uhrzeit 
+                9990 END 
+                10000 REM Unterprogramm Zeige Uhrzeit 
+                10010 PRINT "Es ist " + TIME$ + " Uhr" 
+                10020 RETURN 
+ 
+ 
+Vergleiche :  GOSUB-, ON-Anweisungen 
+ 
+ 
+ 
+Funktion : RIGHT$ 
+ 
+Zweck :        Erzeugung eines Teiltextes aus einem anderen Text 
+ 
+Syntax :       RIGHT$ (<TEXT-Ausdruck>, <Anzahl Zeichen>) 
+Erklärung :   <Anzahl Zeichen>: INT-Ausdruck 
+ 
+              Die Funktion liefert die letzten <Anzahl Zeichen> Textzeichen des
+              TEXT-Ausdrucks. 
+              Ist <Anzahl Zeichen> größer gleich der Länge des TEXT-
+              Ausdrucks, so wird der gesamte Ausdruck geliefert. 
+ 
+ 
+Beispiel :      10 LET a$ = "hallihallo" 
+                20 PRINT RIGHT$ (a$, 5) 
+                Ausgabe:   hallo 
+ 
+Vergleiche :  LEFT$-, MID$-Funktionen, LSET-, MID$-, RSET-Anweisungen 
+ 
+ 
+ 
+Funktion : RND 
+ 
+Zweck :        Erzeugung von Zufallszahlen 
+ 
+Syntax :       RND [<num. Ausdruck>] 
+ 
+Erklärung :   Wird kein Argument angegeben, so wird ein Wert größer null für den
+              Ausdruck angenommen. 
+ 
+              RND (x) liefert 
+ 
+              für x > 0: 
+              eine neue Zufallszahl. Es gilt immer: 0 <= RND < 1. Der Betrag
+              des Arguments hat keinen Einfluß auf das Ergebnis. 
+ 
+              für x = 0: 
+              die letzte gelieferte Zufallszahl noch einmal. 
+ 
+              für x < 0: 
+              eine neue Zufallszahl. Vorher wird aber RANDOMIZE x (s.d.) ausge­
+              führt. 
+ 
+              Die Zufallszahlen werden als REALs geliefert. 
+              Der Zufallszahlengenerator kann mit der RANDOMIZE-Anweisung
+              auf bestimmte Startwerte eingestellt werden. 
+ 
+ 
+Beispiel :      10 FOR i = 1 TO 5 
+                20 PRINT INT (RND * 10) 
+                30 NEXT i 
+                Ausgabe (z.B.):   7  9  9  5  0 
+ 
+Vergleiche :  RANDOMIZE-Anweisung 
+ 
+ 
+ 
+Anweisung : RSET 
+ 
+Zweck :        Ersetzen von Zeichen eines Textes von rechts her 
+ 
+Syntax :       RSET <TEXT-Variable> = <TEXT-Ausdruck> 
+ 
+Erklärung :   Das Ergebnis des TEXT-Ausdrucks wird, rechts beginnend, in der
+              TEXT-Variablen eingesetzt. Es werden höchstens so viele Zeichen
+              ersetzt, wie bisher schon in der Variablen vorhanden waren, das heißt
+              die Länge des Textes in der Variablen ändert sich nicht. 
+              Soll ein Text eingesetzt werden, der länger ist als der Text in der
+              Variablen, so wird die Variable nicht verändert. 
+ 
+ 
+Beispiel :      210 LET a$ = "ABCDEFG" 
+                220 RSET a$ = "12345" 
+                230 PRINT a$, 
+                240 RSET a$ = "abc" 
+                250 PRINT a$ 
+                Ausgabe:    AB12345           AB12abc 
+ 
+Vergleiche :  LSET-, MID$-Anweisungen, LEFT$-, MID$-, RIGHT$-Funk­
+              tionen 
+ 
+ 
+ 
+Funktion : SGN 
+ 
+Zweck :        Ermittlung des Vorzeichens einer Zahl 
+ 
+Syntax :       SGN (<num. Ausdruck>) 
+ 
+Erklärung :   SGN (x) liefert 
+              für x > 0:   1 
+              für x = 0:   0 
+              für x < 0:  -1 . 
+ 
+ 
+Beispiel :      10 a = -12.74 
+                20 PRINT SGN (a); SGN (-a); SGN (0 * a) 
+                Ausgabe:  -1  1  0 
+ 
+Vergleiche :  ABS-Funktion 
+ 
+ 
+ 
+Funktion : SIN 
+ 
+Zweck :        Berechnung des Sinus eines Radiantwertes 
+ 
+Syntax :       SIN (<Winkel>) 
+ 
+Erklärung :   <Winkel>: REAL-Ausdruck, der den Winkel in Radiant angibt. 
+              Die Funktion liefert den Sinus des Winkels als REAL. 
+ 
+ 
+Beispiel :      10 PI = 3.141593 
+                20 PRINT SIN (PI/4) 
+                Ausgabe:  .7071068 
+ 
+Vergleiche :  COS-, TAN-Funktionen 
+ 
+ 
+ 
+Funktion : SPACE$ 
+ 
+Zweck :        Erzeugung einer bestimmten Anzahl von Leerzeichen 
+ 
+Syntax :       SPACE$ (<INT-Ausdruck>) 
+ 
+Erklärung :   Die SPACE$-Funktion liefert einen TEXT, der aus so vielen Leerzei­
+              chen (Code 32) besteht, wie der Wert des INT-Ausdrucks angibt. 
+ 
+ 
+Beispiel :      10 PRINT "123456789" 
+                20 PRINT "^" + SPACE$ (7) + "^" 
+ 
+              Ausgabe:  123456789 
+                        ^       ^ 
+ 
+ 
+Vergleiche :  STRING$-Funktion 
+ 
+ 
+ 
+Funktion : SPC 
+ 
+Diese Funktion entspricht exakt der SPACE$-Funktion und wurde nur aus Kompatibi­
+litätsgründen implementiert. 
+ 
+ 
+ 
+Funktion : SQR 
+ 
+Zweck :        Berechnung der Quadratwurzel einer Zahl 
+ 
+Syntax :       SQR (<num. Ausdruck>) 
+ 
+Erklärung :   SQR (x) liefert die Quadratwurzel des durch den numerischen Aus­
+              druck angegebenen Wertes. 
+              Das Ergebnis wird als REAL geliefert. 
+ 
+ 
+Beispiel :      10 PRINT SQR (100); 
+                20 PRINT SQR (2); 
+                30 PRINT SQR (17.453) 
+                Ausgabe:  10  1.414214  4.177679 
+ 
+ 
+ 
+Anweisungsbestandteil : STEP 
+ 
+Siehe FOR-Anweisung 
+ 
+ 
+ 
+Anweisung : STOP 
+ 
+Zweck :        Beenden der Programmausführung eines BASIC-Programms mit
+              Meldung 
+ 
+Syntax :       STOP 
+ 
+Erklärung :   STOP beendet die Programmausführung des BASIC-Programms. 
+              Im Gegensatz zu END (s.d.) erzeugt STOP dabei die Meldung "STOP
+              beendet das Programm in Zeile ...". 
+ 
+              STOP-Anweisungen dürfen im Programm an beliebiger Stelle
+              stehen, und es darf auch mehr als eine STOP-Anweisung in einem
+              Programm vorkommen. 
+              Der Compiler übersetzt ein Programm auch nach Erreichen einer
+              STOP-Anweisung weiter. 
+ 
+ 
+Beispiel :      3220 IF eingabe$ = "Ende" THEN STOP 
+ 
+ 
+Vergleiche :  END-Anweisung 
+ 
+ 
+ 
+Funktion : STR$ 
+ 
+Zweck :        Konvertierung einer Zahl in einen Text 
+ 
+Syntax :       STR$ (<num. Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert die Darstellung des Wertes des numerischen
+              Ausdrucks als TEXT. 
+              Die Zahlen werden so als Text geliefert, wie sie bei einer PRINT-
+              Anweisung auf dem Bildschirm erscheinen würden. 
+ 
+ 
+Beispiel :      10 LET zahl$ = STR$ (1e6) 
+                20 PRINT zahl$; LEN (zahl$) 
+                Ausgabe:   1000000  7 
+ 
+Vergleiche :  VAL-Funktion (Komplementärfunktion) 
+ 
+ 
+ 
+Funktion : STRING$ 
+ 
+Zweck :        Erzeugung eines Textes mit mehreren gleichen Zeichen 
+ 
+Syntax :       STRING$ (<Anzahl>, <Code>|<TEXT-Ausdruck>) 
+ 
+Erklärung :   <Anzahl>: INT-Ausdruck 
+              <Code>  : INT-Ausdruck  (Wert im Bereich 0 bis 255) 
+ 
+              Die Funktion liefert <Anzahl> mal das Zeichen, 
+              - das den ASCII-Code <Code> hat oder 
+              - das am Anfang vom Ergebnis des TEXT-Ausdrucks steht. 
+ 
+ 
+Beispiel :      10 LET pfeil$ = STRING$ (10, "=") + ">" 
+                20 PRINT pfeil$;" ";STRING$ (5, 35) '35 entspr. \# 
+                Ausgabe:   ==========> \#\#\#\#\# 
+ 
+Vergleiche :  SPACE$-Funktion 
+ 
+ 
+ 
+Anweisungsbestandteil : SUB 
+ 
+Siehe GOSUB-Anweisung 
+ 
+ 
+ 
+Anweisung : SWAP 
+ 
+Zweck :        Tauschen der Inhalte zweier Variablen 
+ 
+Syntax :       SWAP <Variable1>, <Variable2> 
+ 
+Erklärung :   SWAP tauscht die Inhalte der beiden Variablen. 
+ 
+              Die beiden Variablen müssen vom gleichen Typ sein. 
+ 
+ 
+Beispiel :      3220 LET a = 10 
+                3230 LET b = 20 
+                3240 SWAP a, b 
+                3250 PRINT a; b 
+                Ausgabe:  20  10 
+ 
+ 
+ 
+Anweisungsbestandteil : TAB 
+ 
+Siehe PRINT- und LPRINT-Anweisung 
+ 
+ 
+ 
+Funktion : TAN 
+ 
+Zweck :        Berechnung des Tangens eines Radiantwertes 
+ 
+Syntax :       TAN (<Winkel>) 
+ 
+Erklärung :   <Winkel>: REAL-Ausdruck, der den Winkel in Radiant angibt. 
+              Die Funktion liefert den Tangens des Winkels als REAL. 
+ 
+ 
+Beispiel :      10 PI = 3.141593 
+                20 PRINT TAN (PI/4) 
+                Ausgabe:  1 
+ 
+Vergleiche :  COS-, SIN-Funktionen 
+ 
+ 
+ 
+Anweisungsbestandteil : THEN 
+ 
+Siehe IF-Anweisung 
+ 
+ 
+ 
+Funktion : TIMER 
+ 
+Zweck :        Lesen der Systemuhr (CPU-Zeit der Task) 
+ 
+Syntax :       TIMER 
+ 
+Erklärung :   Die bisher von der Task verbrauchte CPU-Zeit (in Sekunden) wird
+              als REAL geliefert. 
+ 
+              TIMER eignet sich auch zum Starten des Zufallszahlengenerators
+              (vgl. RANDOMIZE-Anweisung). 
+ 
+ 
+Beispiel :      2010 LET starttime = TIMER 
+                . 
+                . 
+                2620 PRINT "Verbrauchte CPU-Zeit:"; 
+                2630 PRINT TIMER - starttime; "Sekunden" 
+ 
+ 
+Vergleiche :  TIME$-Funktion 
+ 
+ 
+ 
+Funktion : TIME$ 
+ 
+Zweck :        Abrufen der aktuellen Tageszeit 
+ 
+Syntax :       TIME$ 
+ 
+Erklärung :   Die Tageszeit wird als Text in der Form HH.MM.SS geliefert. 
+ 
+ 
+Beispiel :      10 PRINT "Es ist jetzt "; TIME$; " Uhr" 
+                Ausgabe (z.B.):  Es ist jetzt 10:51:17 Uhr 
+ 
+Vergleiche :  DATE$-, TIMER-Funktionen 
+ 
+ 
+ 
+Anweisungsbestandteil : TO 
+ 
+Siehe FOR- und GOTO-Anweisungen 
+ 
+ 
+ 
+Anweisung : TRON / TROFF 
+ 
+Zweck :        Ein- und Ausschalten der TRACE-Funktion 
+ 
+Syntax :       TRON 
+              TROFF 
+ 
+Erklärung :   Der TRACE-Modus dient der Suche nach logischen Fehlern bei der
+              Entwicklung von BASIC-Programmen. 
+ 
+              TRON schaltet den TRACE-Modus für die nachfolgend übersetzten
+              Programmzeilen ein. 
+ 
+              Ist der TRACE-Modus eingeschaltet, so wird für jede gefundene
+              Zeilennummer die Ausgabe dieser Zeilennummer in eckigen
+              Klammern mit in den erzeugten Code aufgenommen. Dies hat dann
+              während des Laufens den Effekt, daß immer bei Abarbeitung der im
+              TRACE-Modus übersetzten Zeilen die aktuelle Zeilennummer aus­
+              gegeben wird. Es ist so leicht zu verfolgen, in welcher Reihenfolge
+              die Zeilen des Programms ausgeführt werden. 
+ 
+              TROFF schaltet den TRACE-Modus für die textuell folgenden Pro­
+              grammzeilen wieder aus. 
+ 
+ 
+Beispiel :      5220 TRON 
+                5230 REM hier beginnt die kritische 
+                5240 REM Programmstelle 
+                . 
+                . 
+                . 
+                5970 TROFF 
+ 
+ 
+              Die Zeilen 5230 bis 5970 werden im TRACE-Modus übersetzt. 
+ 
+ 
+ 
+Anweisungsbestandteil : USING 
+ 
+Siehe PRINT-Anweisung 
+ 
+ 
+ 
+Funktion : USR 
+ 
+Zweck :        Aufruf einer wertliefernden insertierten Prozedur 
+ 
+Syntax :       USR <Prozedurname> 
+              #right#[ (<Parameter> [, <Parameter>] [...] ) ] 
+ 
+Erklärung :   <Prozedurname>: Folge aus Zeichen, die für Prozeduren im
+              EUMEL-System zugelassen sind (also Buchstaben und  - ab der
+              zweiten Stelle -  Zahlen), jedoch keine Leerzeichen. 
+ 
+              <Parameter>: <CONST-Parameter> | <VAR-Parameter> 
+ 
+              <CONST-Parameter>:   Ausdruck (genau des von der Prozedur
+                                   benötigten Typs) 
+              <VAR-Parameter>:     Variable (genau des von der Prozedur benö­
+                                   tigten Typs) 
+ 
+              Die Prozedur mit dem angegebenen <Prozedurnamen> und den
+              angegebenen Parametern wird aufgerufen. 
+              Die USR-Funktion liefert nach Ausführung der Prozedur das von der
+              Prozedur übergebene Ergebnis (Typ INT, REAL oder TEXT). 
+ 
+              Mögliche Fehlerfälle: 
+              - Eine Prozedur mit dem Namen <Prozedurnamen> und den ange­
+                gebenen Parametern gibt es nicht. 
+              - Die Prozedur liefert keinen Wert. 
+              - Die Prozedur liefert einen Typ, der in BASIC unbekannt ist (zum
+                Beispiel BOOL). 
+              - Die Prozedur benötigt Parametertypen, die in BASIC nicht bekannt
+                sind (z.B. BOOL, FILE, TASK, QUIET). 
+              - Ein Parameter ist CONST, es wird aber ein VAR-Parameter ver­
+                langt. 
+ 
+              Weitere Informationen finden Sie in Kapitel 4.7. 
+ 
+Hinweis :     1.  Bei den Parametern wird keine Typkonvertierung vorgenommen. 
+              2. Der Prozedurname muß (entgegen der ELAN-Gewohnheit) ohne
+                 Leerzeichen angegeben werden. 
+              3. USR ist die einzige Funktion, bei der das Argument (nämlich der
+                 Prozeduraufruf) nicht in Klammern stehen darf. 
+ 
+ 
+Beispiel :      10 LET euler = USR e 
+                20 PRINT euler 
+                Ausgabe:  2.718282 
+ 
+Vergleiche :  CALL-, CHAIN-Anweisungen 
+ 
+ 
+ 
+Funktion : VAL 
+ 
+Zweck :        Konvertierung eines Texts in eine Zahl 
+ 
+Syntax :       VAL (<TEXT-Ausdruck>) 
+ 
+Erklärung :   Die Funktion liefert den Wert der Zahl, deren Darstellung in dem
+              übergebenen TEXT-Ausdruck enthalten ist. Führende Leerstellen
+              werden dabei überlesen. 
+              Sobald ein nicht wandelbares Zeichen festgestellt wird, wird der bis
+              dahin ermittelte Wert (am Anfang null) geliefert. 
+ 
+ 
+Beispiel :      10 LET zahl$ = "-1.256E-63" 
+                20 PRINT VAL (zahl$) 
+                Ausgabe:   -1.256E-63 
+ 
+Vergleiche :  STR$-Funktion (Komplementärfunktion) 
+ 
+ 
+ 
+Anweisung : WEND 
+ 
+Zweck :        Markierung des Endes einer WHILE-Schleife 
+ 
+Syntax :       WEND 
+ 
+Erklärung :   WEND markiert das Ende einer WHILE-Schleife (vergleiche
+              WHILE-Anweisung). 
+ 
+Vergleiche :  WHILE-, FOR-Anweisungen 
+ 
+ 
+ 
+Anweisung : WHILE 
+ 
+Zweck :        Beginn einer abweisenden Schleife 
+ 
+Syntax :       WHILE <Bedingung> 
+              <Schleifenrumpf> 
+ 
+Erklärung :   <Bedingung>     : numerischer Ausdruck 
+              <Schleifenrumpf>: Folge von Programmzeilen 
+ 
+              Die WHILE-Anweisung erlaubt die komfortable Programmierung von
+              abweisenden Schleifen (sogenannten WHILE-WEND-Schleifen) in
+              BASIC. 
+              Gelangt das Programm während der Ausführung an eine WHILE-
+              Anweisung, so wird zunächst der Bedingungs-Ausdruck ausge­
+              wertet. Ist die Bedingung nicht erfüllt (falsch, Wert gleich null), so
+              wird das Programm mit der nächsten Anweisung hinter der korres­
+              pondierenden WEND-Anweisung fortgesetzt. 
+              Ist die Bedingung dagegen erfüllt (wahr, Wert ungleich null), so
+              werden die Anweisungen des Schleifenrumpfs abgearbeitet. Beim
+              Erreichen der WEND-Anweisung springt das Programm wieder zur
+              WHILE-Anweisung zurück, die Bedingung wird erneut überprüft und,
+              je nach Ergebnis, wird der Schleifenrumpf oder die Anweisung nach
+              WEND ausgeführt. 
+ 
+              WHILE-WEND-Schleifen dürfen (auch mit FOR-NEXT-Schleifen,
+              s.d.) geschachtelt werden. Überschneidungen von WHILE-WEND-
+              Schleifen und FOR-NEXT-Schleifen sind jedoch nicht zulässig. 
+ 
+ 
+Beispiel :      10 LET weiter$ = "j" 
+                20 WHILE LEFT$ (weiter$, 1) = "j" 
+                30 REM Hier beginnt das eigentliche Programm 
+                . 
+                . 
+                1650 INPUT "Weiter ? (j/n)", weiter$ 
+                1660 WEND 
+ 
+ 
+              Das eigentliche Programm wird so lange ausgeführt, bis der Benutzer
+              etwas anderes als "j" an der ersten Stelle von 'weiter$' eingibt. 
+ 
+Vergleiche :  FOR-, IF-Anweisungen 
+ 
+ 
+ 
+Anweisung : WIDTH 
+ 
+Zweck :        Einstellung der Bildschirmbreite 
+ 
+Syntax :       WIDTH <Zeichen pro Zeile> 
+ 
+Erklärung :   <Zeichen pro Zeile>     : INT-Ausdruck 
+ 
+              Mit der WIDTH-Anweisung wird festgelegt, wie viele Zeichen pro
+              Zeile bei Ausgaben auf den Bildschirm oder in Dateien pro Zeile
+              ausgegeben werden sollen. 
+              Soll für die Druckdatei eine andere Anzahl von Zeichen pro Zeile
+              gelten als für den Bildschirm, dann muß vor jeder Sequenz von
+              LPRINT-Anweisungen die gewünschte Anzahl mit WIDTH einge­
+              stellt werden. 
+              WIDTH gilt auch für Ausgaben in 'sysout'-Dateien. 
+              Insbesondere bei der Ausgabe in Dateien kann ein Wert von mehr als
+              80 Zeichen pro Zeile sinnvoll sein. 
+ 
+ 
+Beispiel :      10 REM es sollen nur 45 Zeichen pro Zeile 
+                20 REM ausgegeben werden 
+                30 WIDTH 45 
+                 
+ 
+Vergleiche :  PRINT-, LPRINT-, WRITE-Anweisungen 
+ 
+ 
+ 
+Anweisung : WRITE 
+ 
+Zweck :        Ausgabe von Zahlen und Texten auf dem Bildschirm 
+ 
+Syntax :       WRITE [<Ausdruck>] [, <Ausdruck>] [...] 
+ 
+Erklärung :   <Ausdruck>: numerischer Ausdruck oder TEXT-Ausdruck 
+ 
+              Die WRITE-Anweisung erlaubt die Ausgabe von Daten auf dem
+              Bildschirm. Die angegebenen Ausdrücke werden ausgewertet und
+              ausgegeben. Dabei werden numerische Werte im gleichen Format
+              wie bei der PRINT-Anweisung (s.d.) ausgegeben, mit der Einschrän­
+              kung, daß den Zahlen keine Leerstelle folgt. 
+              Die Ergebnisse von Text-Ausdrücken werden von Anführungszei­
+              chen umschlossen ausgegeben. 
+              Alle Einzelausgaben werden durch Kommata voneinander getrennt. 
+ 
+              Nach Ausgabe aller angegebenen Ausdrücke wird der Cursor an den
+              Anfang der nächsten Zeile positioniert. 
+ 
+ 
+Beispiel :      10 LET a = 10.7: b = 20 
+                20 LET c$ = "Testtext" 
+                30 WRITE a, b, c$ 
+                Ausgabe:  10.7, 20,"Testtext" 
+ 
+Vergleiche :  PRINT-, LPRINT-, WIDTH-Anweisungen 
+ 
+ 
+ 
+Operator : XOR 
+ 
+Siehe Kapitel 4.4. (Operatoren) 
+
diff --git a/doc/basic/basic handbuch.3 b/doc/basic/basic handbuch.3
new file mode 100644
index 0000000..14cb499
--- /dev/null
+++ b/doc/basic/basic handbuch.3	
@@ -0,0 +1,698 @@
+#page nr ("%",97)# 
+#head# 
+EUMEL-BASIC-Compiler    9. Anpassung von Programmen an den EUMEL-BASIC-Compiler    % 
+ 
+#end# 
+ 
+9. Anpassung von Programmen an den EUMEL-BASIC-Compiler 
+   
+ 
+9.1. Unterschiede zwischen BASIC-Inter­
+     pretern und dem EUMEL-BASIC-
+     Compiler 
+ 
+Bei der Anpassung von Programmen für BASIC-Interpreter an den EUMEL-
+BASIC-Compiler gibt es einige Besonderheiten zu beachten, die auf den unterschied­
+lichen Arbeitsweisen von Compilern gegenüber Interpretern beruhen. 
+Bei Interpretern fällt die Übersetzung und Ausführung des Quellprogramms zeitlich
+zusammen (genau genommen gibt es ja gar keine Übersetzung, sondern das Quell­
+programm wird #on("i")#interpretiert#off("i")#). Dies hat zur Folge, daß auch nicht zur Ausführung
+bestimmte Anweisungen (z.B. Dimensionierungen, Typfestlegungen etc.) erst während
+der Ausführung des Programms erkannt und ausgewertet werden. 
+Bei Compilern hingegen muß deutlich zwischen der Übersetzungszeit (Compiletime)
+und der Laufzeit (Runtime) eines Programms unterschieden werden. 
+Der wesentliche Unterschied zwischen Compilern und Interpretern liegt nun in der
+Reihenfolge der Kenntnisnahme von den Anweisungen. Während der Interpreter von
+den Anweisungen in der Reihenfolge ihres Auftretens entlang des Programmablaufs
+Kenntnis nimmt, werden die Anweisungen vom Compiler in der Reihenfolge ihres
+textuellen Auftretens zur Kenntnis genommen. 
+Da es sich bei dem EUMEL-BASIC-Compiler um einen One-Pass-Compiler
+handelt, ist es zwingend notwendig, daß 
+- DIM-Anweisungen vor dem ersten Zugriff auf das zu dimensionierende Feld
+  stehen. 
+- OPTION BASE-Anweisungen vor den betreffenden Dimensionierungen stehen. 
+- DEF FN-Anweisungen vor dem ersten Aufruf der zu definierenden Funktion ste­
+  hen. 
+- DEFINT- beziehungsweise DEFSTR-Anweisungen vor der ersten Verwendung der
+  betreffenden Variablen erscheinen. 
+ 
+Einige Interpreter lassen sogar den Abschluß von FOR-NEXT- und WHILE-
+WEND-Schleifen an mehreren Stellen im Programm zu (z.B. mehrere NEXT-
+Anweisungen zu einer FOR-Anweisung). Auch solche "Kunstgriffe" gestattet der
+EUMEL-BASIC-Compiler (aus den oben geschilderten Gründen) nicht. 
+ 
+ 
+ 
+ 
+9.2. Abweichungen von ISO 6373-1984
+     (Minimal-BASIC)
+     
+ 
+ 
+Der EUMEL-BASIC-Compiler weicht in folgenden Punkten von der ISO-Norm
+6373-1984 für Minimal-BASIC ab: 
+- Treten bei der Auswertung von numerischen Ausdrücken Überläufe auf, so wird
+  nicht, wie im Standard vorgesehen, eine Warnung ausgegeben und mit bestimmten
+  Höchstwerten weitergerechnet, sondern die Ausführung des BASIC-Programms
+  wird mit einer entsprechenden Fehlermeldung abgebrochen. 
+- Nimmt die Sprungziel-Nummer bei der ON-Anweisung einen fehlerhaften Wert an
+  (Nummer < 1 oder Nummer > Anzahl Sprungziele), dann wird nicht, wie im
+  Standard empfohlen, mit einer Fehlermeldung abgebrochen, sondern es wird (wie
+  auch in Microsoft-BASIC üblich) das Programm mit der der ON-Anweisung fol­
+  genden Anweisung fortgesetzt. 
+- Bei der DATA-Anweisung müssen nicht unbedingt Zeichenfolgen angegeben
+  werden. Werden sie weggelassen, dann wird bei Ausführung der READ-
+  Anweisung null beziehungsweise Leertext geliefert (vergleiche Kapitel 8, DATA-
+  Anweisung). 
+- Bei den Eingaben für eine INPUT-Anweisung können ebenfalls die Daten wegge­
+  lassen werden. Auch hier wird null beziehungsweise Leertext geliefert (vergleiche
+  Kapitel 8, INPUT-Anweisung) 
+ 
+ 
+Die Erweiterungen gegenüber ISO 6373 sollen hier nicht im einzelnen aufgeführt
+werden. Bitte vergleichen Sie in Zweifelsfällen die Normungsschrift mit dieser Doku­
+mentation! 
+ 
+ 
+ 
+ 
+9.3. Anpassung von Microsoft-BASIC Pro­
+     grammen an den EUMEL-BASIC-
+     Compiler
+     
+ 
+ 
+Bei der Entwicklung des EUMEL-BASIC-Compilers wurde zwar auf Übereinstim­
+mung mit Microsoft-BASIC Wert gelegt, von einer echten Kompatibilität kann aber
+aufgrund einer ganzen Reihe fehlender Anweisungen und Funktionen nicht gespro­
+chen werden. 
+Gegenüber Microsoft-BASIC fehlen vor allem: 
+- alle "Direkt-Kommandos" (RUN, LIST, LOAD, SAVE, MERGE usw.). Die Aufgaben
+  dieser Anweisungen werden von den Prozeduren des EUMEL-Systems über­
+  nommen. 
+- im weiteren Sinne "hardware-nahe" oder an Maschinensprache orientierte Anwei­
+  sungen und Funktionen (CALL, PEEK, POKE, USR, WAIT usw.) 
+- die ERROR-Handling Anweisungen (ON ERROR, RESUME) 
+- die Dateiverarbeitungs-Anweisungen und -Funktion (INPUT\#, PRINT\# u.a.; die 
+  INPUT- und PRINT-Anweisungen wurden aber auf Zusammenarbeit mit 'sysin'
+  und 'sysout' abgestimmt.) 
+- die Single-Precision-Variablen (Single- und Double-Precision-Variablen wer­
+  den beide auf den Datentyp REAL abgebildet.) 
+- die hexadezimalen und oktalen Konstanten 
+ 
+Anweisungen und Funktionen, die sich abweichend vom Microsoft-Standard verhal­
+ten, sind vor allem: 
+- CALL, CHAIN, USR 
+- ERROR, ERR, ERL 
+- LSET, RSET 
+ 
+Wichtige Erweiterungen gegenüber Microsoft-BASIC sind: 
+- Möglichkeit des Aufrufs von ELAN-Prozeduren 
+- Maximale Anzahl von Zeichen pro Zeile: 32000 
+- Maximale Anzahl von Zeichen pro TEXT-Objekt: 32000 
+- OPTION BASE wirkt auf einzelne Felder (und nicht unbedingt auf ein ganzes
+  Programm) 
+ 
+#on ("b")# 
+Hinweis zur Verwendung von MS-BASIC-Programmen im EUMEL-System#off ("b")# 
+Sollen Microsoft-BASIC-Programme in das EUMEL-Systemm übernommen wer­
+den, so ist dabei so vorzugehen: 
+1. Speichern Sie das Programm von MS-BASIC aus mit der ASCII-SAVE-Option
+   ab. 
+   Beispiel: SAVE "PROGRAMM.BAS",A 
+2. Lesen Sie das Programm mittels "DOSDAT" (Programm zum Lesen von MS-
+   DOS-Dateien) im "file ascii"-Modus ein: 
+ 
+   reserve ("file ascii", /"DOS"); fetch ("PROGRAMM.BAS", /"DOS") 
+ 
+Danach steht ihnen das BASIC-Program in der EUMEL-Textdatei
+"PROGRAMM.BAS" zur Verfügung. 
+ 
+#page# 
+#head# 
+EUMEL-BASIC-Compiler        Anhang A: Reservierte Wörter          % 
+ 
+#end# 
+ 
+Anhang A: #ib(4)#Reservierte Wörter#ie(4)# 
+Dieser Anhang enthält eine Übersicht über alle vom EUMEL-BASIC-Compiler
+erkannten reservierten Wörter. 
+ 
+ABS                Funktion 
+AND                Operator 
+AS                 Anweisungsbestandteil 
+ASC                Funktion 
+ATN                Funktion 
+BASE               Anweisungsbestandteil 
+CALL               Anweisung 
+CDBL               Funktion 
+CHAIN              Anweisung 
+CHR$               Funktion 
+CINT               Funktion 
+CLEAR              nicht implementiert 
+CLOSE              nicht implementiert 
+CLS                Anweisung 
+COMMON             nicht implementiert 
+FIELD              nicht implementiert 
+COS                Funktion 
+CSRLIN             Funktion 
+CVD                Funktion 
+CVI                Funktion 
+DATA               Anweisung 
+DATE$              Funktion 
+DEF                Anweisung 
+DEFDBL             Anweisung 
+DEFINT             Anweisung 
+DEFSNG             Anweisung 
+DEFSTR             Anweisung 
+DIM                Anweisung 
+ELSE               Anweisungsbestandteil 
+END                Anweisung 
+EOF                Anweisungsbestandteil 
+EQV                Operator 
+ERL                Funktion 
+ERM$               Funktion 
+ERR                Funktion 
+ERROR              Anweisung 
+EXP                Funktion 
+FIX                Funktion 
+FOR                Anweisung 
+FRE                Funktion 
+GET                nicht implementiert 
+GO                 Anweisungsbestandteil 
+GOSUB              Anweisung 
+GOTO               Anweisung 
+HEX$               Funktion 
+IF                 Anweisung 
+IMP                Operator 
+INKEY$             Funktion 
+INPUT              Anweisung 
+INPUT$             Funktion 
+INSTR              Funktion 
+INT                Funktion 
+KILL               Anweisung 
+LEFT$              Funktion 
+LEN                Funktion 
+LET                Anweisung 
+LINE               Anweisungsbestandteil 
+LOC                nicht implementiert 
+LOG                Funktion 
+LPOS               Funktion 
+LPRINT             Anweisung 
+LSET               Anweisung 
+MID$               Anweisung/Funktion 
+MKD$               Funktion 
+MKI$               Funktion 
+MOD                Operator 
+NAME               Anweisung 
+NEXT               Anweisung 
+NOT                Operator 
+OCT$               Funktion 
+ON                 Anweisung 
+OPEN               nicht implementiert 
+OPTION             Anweisung 
+OR                 Operator 
+OUT                nicht implementiert 
+POS                Funktion 
+PRINT              Anweisung 
+PUT                nicht implementiert 
+RANDOMIZE          Anweisung 
+READ               Anweisung 
+REM                Anweisung 
+RESTORE            Anweisung 
+RESUME             nicht implementiert 
+RETURN             Anweisung 
+RIGHT$             Funktion 
+RND                Funktion 
+RSET               Anweisung 
+SGN                Funktion 
+SIN                Funktion 
+SPACE$             Funktion 
+SPC                Funktion 
+SQR                Funktion 
+STEP               Anweisungsbestandteil 
+STOP               Anweisung 
+STR$               Funktion 
+STRING$            Funktion 
+SUB                Anweisungsbestandteil 
+SWAP               Anweisung 
+TAB                Anweisungsbestandteil 
+TAN                Funktion 
+THEN               Anweisungsbestandteil 
+TIME$              Funktion 
+TIMER              Funktion 
+TO                 Anweisungsbestandteil 
+TROFF              Anweisung 
+TRON               Anweisung 
+USING              Anweisungsbestandteil 
+USR                Funktion 
+VAL                Funktion 
+WAIT               nicht implementiert 
+WEND               Anweisung 
+WHILE              Anweisung 
+WIDTH              Anweisung 
+WRITE              Anweisung 
+XOR                Operator 
+#page# 
+#head# 
+EUMEL-BASIC-Compiler       Anhang B: Vom Scanner erkannte Symboltypen    % 
+ 
+#end# 
+ 
+Anhang B: Vom #ib(3)#Scanner#ie(3)# erkannte #ib(3)#Symbol­
+typen#ie(3)#
+ 
+ Der Scanner (ein Paket des EUMEL-BASIC-Systems) hat die Aufgabe, den Pro­
+grammtext Zeichen für Zeichen durchzugehen und auszulesen ('scannen'). Dabei
+werden die Zeichen immer zu logischen Gruppen, sogenannten #on("i")#Symbolen#off("i")# zusammen­
+gefaßt. Diese Symbole werden dann dem eigentlichen Compilerprogramm geliefert. 
+Der Scanner entscheidet nach recht komplizierten Regeln, welche Zeichen aus der
+Quelldatei zu einem Symbol zusammengefaßt werden. Dennoch soll in diesem An­
+hang der Begriff des Symbols etwas näher erklärt werden, da der Anwender (vor allem
+bei den Fehlermeldungen) mit Symboltypen konfrontiert wird. 
+ 
+ 
+ 
+Reservierte Wörter 
+#on ("b")# 
+Anfangszeichen:#off ("b")#  Buchstaben 
+#on ("b")# 
+Folgezeichen:#off ("b")#    Buchstaben 
+#on ("b")# 
+Beispiele:#off ("b")#       PRINT, VAL, TAB, SUB, TO 
+#on ("b")# 
+Vergleiche:#off ("b")#      Anhang A 
+ 
+ 
+ 
+Operatoren 
++  -  *  /  \  ^  MOD 
+NOT  AND  OR  XOR  EQV  IMP 
+<  >  =   <=   >=   <> 
+ 
+#on ("b")# 
+Vergleiche:#off ("b")#      Kapitel 4.4. 
+ 
+ 
+ 
+numerische Konstanten 
+#on ("b")# 
+Anfangszeichen:#off ("b")#  Ziffern 0 bis 9, Dezimalpunkt '.' 
+#on ("b")# 
+Folgezeichen:#off ("b")#    zusätzlich: 'd', 'D', 'e' oder 'E', am Schluß auch '%', '!' oder '\#' 
+#on ("b")# 
+Beispiele:#off ("b")#       1.0, 1.256d123, 12! 
+#on ("b")# 
+Vergleiche:#off ("b")#      Kapitel 4.2. 
+ 
+ 
+ 
+TEXT-Konstanten 
+#on ("b")# 
+Anfangszeichen:#off ("b")#  Anführungszeichen 
+#on ("b")# 
+Folgezeichen:#off ("b")#    Alle Zeichen, sogar Doppelpunkte, Apostrophe und Steuerzei­
+                             chen. Anführungszeichen dürfen #on("i")#innerhalb#off("i")# von
+                             TEXT-Konstanten nicht vorkommen. Eine
+                             TEXT-Konstante #on("i")#muß#off("i")# aber mit einem Anfüh­
+                             rungszeichen enden. 
+#on ("b")# 
+Beispiele:#off ("b")#       "tadellos", "!?': alles mögliche" 
+#on ("b")# 
+Vergleiche:#off ("b")#      Kapitel 4.2. 
+ 
+ 
+ 
+Variablen 
+#on ("b")# 
+Anfangszeichen:#off ("b")#  Buchstaben 
+#on ("b")# 
+Folgezeichen:#off ("b")#    zusätzlich: Punkt '.', Ziffern 0 bis 9, Zeichen '$', '%', '!' und '\#' 
+#on ("b")# 
+Beispiele:#off ("b")#       zeiger, A$, Zahl!, n%, var\#4.3% 
+#on ("b")# 
+Vergleiche:#off ("b")#      Kapitel 4.3. 
+ 
+ 
+ 
+Felder/Feldelemente 
+wie Variablen, jedoch gefolgt von '(', den Indexangaben und ')' 
+#on ("b")# 
+Beispiele:#off ("b")#       zeiger (3), A$ (pointer), Zahl! (7), n%  (a, b, c + d) 
+#on ("b")# 
+Vergleiche:#off ("b")#      Kapitel 4.3. 
+ 
+ 
+ 
+Benutzer-definierte Funktionen 
+#on ("b")# 
+Anfangszeichen:#off ("b")#  FN 
+#on ("b")# 
+Folgezeichen:#off ("b")#    Buchstaben, Punkt '.', Ziffern 0 bis 9, 
+                             Zeichen '$', '%', '!' und '\#' 
+#on ("b")# 
+Beispiele:#off ("b")#       FNfunct, FNgauss%, FNf!4.5.6d\# 
+#on ("b")# 
+Vergleiche:#off ("b")#      Kapitel 4.5. 
+ 
+ 
+ 
+EOS (End of Statement, Anweisungsende) 
+Doppelpunkt ':' 
+ 
+#on ("b")# 
+Vergleiche:#off ("b")#      Kapitel 4.1. 
+ 
+ 
+ 
+EOL (End of Line, Zeilenende) 
+Apostrophzeichen ' oder Ende der Dateizeile 
+EOL bedeutet gleichzeitig auch EOS 
+ 
+#on ("b")# 
+Vergleiche:#off ("b")#      Kapitel 4.1. 
+ 
+ 
+ 
+EOF (End of File, Dateiende) 
+Ende der Quelldatei 
+EOF bedeutet gleichzeitig auch EOL (und somit auch EOS) 
+ 
+#on ("b")# 
+Vergleiche:#off ("b")#      Kapitel 4.1. 
+ 
+ 
+ 
+Trennzeichen 
+Alle bisher nicht genannten Zeichen werden vom Scanner als Trennzeichen behan­
+delt. In BASIC benötigte Trennzeichen sind das Komma (','), das Semikolon (';') sowie
+die beiden runden Klammern '(' und ')'. 
+Zeichen mit Codes kleiner als 32 (Steuerzeichen) werden vom Scanner überlesen. 
+#page# 
+#head# 
+EUMEL-BASIC-Compiler     Anhang C: Übersicht über die Fehlermeldungen     % 
+ 
+#end# 
+ 
+Anhang C: Übersicht über die Fehlermeldungen 
+ 
+ 
+Übersicht über die verwendeten Fehlermeldungen zur
+Übersetzungszeit
+Diese Übersicht enthält alle zur Übersetzungszeit möglichen Fehler, mit Ausnahme
+der internen Fehler. 
+Die Erläuterungen geben die üblichen Ursachen für die Fehlermeldung an. Es wird
+empfohlen, sich im Falle eines Fehlers außerdem in Kapitel 8 über die genaue Syntax
+der betreffenden Anweisung beziehungsweise Funktion zu informieren. 
+ 
+ 
+#on ("b")#AS ohne NAME#off ("b")# 
+AS darf nur in NAME-Anweisungen vorkommen. 
+ 
+#on ("b")#Accessrecht VAR erwartet, CONST gefunden#off ("b")# 
+Beim Aufruf einer ELAN-Prozedur (CALL, CHAIN oder USR) wurde ein VAR-Para­
+meter verlangt. Angegeben wurde aber ein CONST-Parameter (zum Beispiel ein
+Ausdruck). 
+ 
+#on ("b")#Ausdruck erwartet#off ("b")# 
+Es wurde ein numerischer oder TEXT-Ausdruck erwartet. Diese Fehlermeldung
+erscheint zum Beispiel, wenn nach einem Operator kein Ausdruck mehr gefunden
+wird. 
+ 
+#on ("b")#BASE ohne OPTION#off ("b")# 
+BASE darf nur in OPTION BASE-Anweisungen vorkommen. 
+ 
+#on ("b")#Bei SWAP nur gleiche Variablentypen erlaubt#off ("b")# 
+Mit SWAP können nur Variablen von genau dem gleichen Typ bearbeitet werden. 
+ 
+#on ("b")#Das Feld ist bereits dimensioniert#off ("b")# 
+Diese Fehlermeldung erscheint bei DIM-Anweisungen, wenn das Feld vorher schon
+explizit oder automatisch dimensioniert wurde. 
+ 
+#on ("b")#ELSE ohne IF#off ("b")# 
+ELSE darf nur in IF-Anweisungen vorkommen. ELSE muß in der gleichen Zeile
+stehen wie die zugehörige IF-Anweisung. 
+ 
+#on ("b")#Falsche Felddimension: 
+Dimensioniert in ... Dimensionen, gefundene Anzahl Indizes: ...#off ("b")# 
+Beim Zugriff auf ein Feldelement wurden zu viele oder zu wenig Indizes angegeben. 
+ 
+#on ("b")#FOR ohne NEXT#off ("b")# 
+Diese Fehlermeldung erscheint, wenn am Programmende für eine FOR-Anweisung
+kein korrespondierendes NEXT gefunden wurde. 
+ 
+#on ("b")#Falsche Reihenfolge der Zeilennummern#off ("b")# 
+Die Zeilennummern wurden nicht in aufsteigender Reihenfolge angegeben. 
+ 
+#on ("b")#Falscher Typ#off ("b")# 
+Es wurde ein anderer Datentyp erwartet als angegeben, und es konnte keine automa­
+tische Konvertierung vorgenommen werden. 
+ 
+#on ("b")#Falscher Typ der Operanden#off ("b")# 
+Bei einem dyadischen Operator wurden Operanden angegeben, für deren Typen
+dieser Operator nicht definiert ist (vergleiche Kapitel 4.4.). 
+ 
+#on ("b")#Falscher Typ des Operanden#off ("b")# 
+Bei einem monadischen Operator wurde ein Operand angegeben, für dessen Typ
+dieser Operator nicht definiert ist (vergleiche Kapitel 4.4.). 
+ 
+#on ("b")#Fehlerhafte Bereichsangabe#off ("b")# 
+Diese Fehlermeldung kann bei den Anweisungen DEFDBL, DEFINT, DEFSNG und
+DEFSTR auftreten, wenn bei einer Bereichsangabe der Buchstabe vor dem Binde­
+strich im Alphabet nach dem Buchstaben hinter dem Bindestrich steht. 
+ 
+#on ("b")#Fehlerhafte Dimensionierung:   Die Obergrenze muß >= 1 sein#off ("b")# 
+Es wurde versucht, ein Feld mit dem größten Index null in einer Dimension zu
+dimensionieren, obwohl die Index-Untergrenze mit OPTION BASE auf eins einge­
+stellt war. 
+ 
+#on ("b")#Fehlerhafte Laufvariable#off ("b")# 
+Nach einer NEXT-Anweisung wurde eine Laufvariable gefunden, die nicht zur letzten
+anhängigen FOR-Anweisung gehört. Der Fehler tritt auf, wenn Schleifen geschachtelt
+wurden. 
+ 
+#on ("b")#Fehlerhafte Zeilennummer#off ("b")# 
+Die Zeilennumer entspricht nicht der Syntax für Zeilennumern. 
+ 
+#on ("b")#Fehlerhafter Funktionsaufruf#off ("b")# 
+- Die Prozedur liefert keinen Wert 
+  Es wurde versucht, eine Prozedur mit USR aufzurufen, die keinen Wert liefert. 
+- Der Typ des Resultats ist nicht erlaubt, gefunden: ... 
+  Es wurde versucht, eine Prozedur mit USR aufzurufen, die ein Objekt liefert,
+  dessen Datentyp in BASIC nicht bekannt ist. 
+- Kein Argument erwartet 
+  Es wurde versucht, eine benutzer-definierte Funktion, die ohne Parameter definiert
+  wurde, mit Argument(en) aufzurufen. 
+- ... Argument(e) erwartet 
+  Die Anzahl der angegebenen Argumente ist kleiner als die Anzahl der bei der
+  Funktionsdefinition angegebenen Parameter. 
+- Nur ... Argument(e) erwartet 
+  Die Anzahl der angegebenen Argumente ist größer als die Anzahl der bei der Funk­
+  tionsdefinition angegebenen Parameter. 
+- Kein Resultat erlaubt  (gefunden: ...) 
+  Bei CALL oder CHAIN wurde versucht, eine wertliefernde Prozedur aufzurufen. 
+ 
+#on ("b")#Funktionsaufruf ohne Zusammenhang#off ("b")# 
+Es wurde ein Funktionsaufruf angegeben, wo eine Anweisung erwartet wurde. 
+ 
+#on ("b")#GO ohne TO oder SUB#off ("b")# 
+Das reservierte Wort GO kann nur in GO SUB oder GO TO auftreten. 
+ 
+#on ("b")#Interner Fehler#off ("b")# 
+Bei der Übersetzung wurde innerhalb des Compilerprogramms ein interner Fehler
+ausgelöst. (vergleiche Kapitel 7.1.) 
+ 
+#on ("b")#Nach OPTION BASE ist nur 0 oder 1 erlaubt#off ("b")# 
+Es wurde versucht, eine Zahl > 1 nach OPTION BASE anzugeben. 
+ 
+#on ("b")#NEXT ohne FOR#off ("b")# 
+Es wurde eine NEXT-Anweisung gefunden, die keiner FOR-Anweisung zuzuordnen
+ist, da keine "offenen" FOR-Schleifen mehr anhängig sind. 
+ 
+#on ("b")#Nicht implementiert#off ("b")# 
+Einige reservierte Wörter werden vom BASIC-Compiler erkannt, obwohl die zugehö­
+rigen Anweisungen oder Funktionen nicht implementiert sind (vgl. Anhang A). 
+ 
+#on ("b")#Parametervariable kommt mehrmals vor#off ("b")# 
+Bei der Definition einer "user function" kommt ein Parameter in der Parameterliste
+mehr als einmal vor. 
+ 
+#on ("b")#Rekursive Funktionsdefinition#off ("b")# 
+Es wurde versucht, in der Definition einer "user function" die zu definierende Funk­
+tion aufzurufen. 
+ 
+#on ("b")#STEP ohne FOR#off ("b")# 
+STEP darf nur in FOR-Anweisungen vorkommen. 
+ 
+#on ("b")#SUB ohne GO#off ("b")# 
+SUB darf nur in GOSUB vorkommen. 
+ 
+#on ("b")#Syntaxfehler:    <nähere Fehlerangabe>#off ("b")# 
+Wenn dieser Fehler erscheint, wurde vom Compiler eine Angabe gefunden, die nach
+den Syntaxregeln dort nicht erwartet wurde oder fehlerhaft ist. 
+ 
+#on ("b")#TAB ohne (L)PRINT#off ("b")# 
+TAB darf nur in PRINT- und LPRINT-Anweisungen vorkommen. 
+ 
+#on ("b")#THEN ohne IF#off ("b")# 
+THEN darf nur in IF-Anweisungen vorkommen. THEN muß in der gleichen Zeile
+stehen wie die zugehörige IF-Anweisung. 
+ 
+#on ("b")#TO ohne Zusammenhang#off ("b")# 
+TO darf nur in FOR-Anweisungen oder in GO TO vorkommen. 
+ 
+#on ("b")#Text zu lang#off ("b")# 
+Dieser Fehler erscheint, wenn ein Anführungszeichen fehlt beziehungsweise ein
+Anführungszeichen zu viel gefunden wird. 
+ 
+#on ("b")#Unbekannte Funktion, Argument(e) angegeben: ...#off ("b")# 
+Es wurde versucht, eine Funktion mit einem Argument aufzurufen, für dessen Typ die
+Funktion nicht definiert ist. 
+ 
+#on ("b")#Unbekannte Prozedur, Parameter angegeben: ...#off ("b")# 
+Die angegebene Prozedur konnte mit den angegebenen Parametertypen nicht gefun­
+den werden. 
+ 
+#on ("b")#Undefinierte 'user function'#off ("b")# 
+Es wurde versucht, eine benutzer-definierte Funktion aufzurufen, die (noch) nicht
+definiert wurde. 
+ 
+#on ("b")#USING ohne (L)PRINT#off ("b")# 
+USING darf nur in PRINT- und LPRINT-Anweisungen vorkommen. 
+ 
+#on ("b")#WEND ohne WHILE#off ("b")# 
+Es wurde eine WEND-Anweisung gefunden, die keiner WHILE-Anweisung zuzuord­
+nen ist, da keine "offenen" WHILE-Schleifen mehr anhängig sind. 
+ 
+#on ("b")#WHILE ohne WEND#off ("b")# 
+Diese Fehlermeldung erscheint, wenn am Programmende für eine WHILE-Anweisung
+kein korrespondierendes WEND gefunden wurde. 
+ 
+#on ("b")#Zeile mit dieser Nummer existiert nicht#off ("b")# 
+Es wurde versucht, mit GOTO oder GOSUB zu einer Zeilennumer zu verzweigen, die
+im Programm nicht angegeben wurde. 
+ 
+ 
+ 
+ 
+Übersicht über die innerhalb des BASIC-Systems
+ausgelösten Laufzeitfehler
+Die meisten Laufzeitfehler werden auch bei BASIC-Programmen im EUMEL-System
+erzeugt (vergleiche Kapitel 7.2.). Einige werden aber innerhalb des BASIC-Systems
+erzeugt. Die nachfolgende Übersicht enthält die innerhalb des BASIC-Systems aus­
+gelösten Fehler mit Angabe des gelieferten Fehlercodes und der Fehlermeldung. 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1003 
+#on ("b")#Fehlermeldung:#off ("b")#  RETURN ohne GOSUB 
+Eine RETURN-Anweisung wurde gefunden, obwohl keine GOSUB-Anweisung mehr
+anhängig war. 
+ 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1004 
+#on ("b")#Fehlermeldung:#off ("b")#  RESTORE: Keine DATA-Anweisung in oder nach 
+#right#Zeile ... gefunden 
+Eine RESTORE-Anweisung konnte nicht ausgeführt werden, weil in oder nach der in
+der Anweisung angegebenen Zeilennummer keine DATA-Anweisung mehr steht. 
+ 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1005 
+#on ("b")#Fehlermeldung:#off ("b")#  bei ^: negative Basis, gebrochener Exponent: ... 
+Es wurde versucht, eine negative Zahl mit einer gebrochenen Zahl zu potenzieren. 
+ 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1005 
+#on ("b")#Fehlermeldung:#off ("b")#  USING: kein Format gefunden 
+Bei einer PRINT USING-Anweisung wurde kein Format für die Ausgabe angegeben
+oder die Formatzeichenkette enthält keine Formatzeichen. 
+ 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1005 
+#on ("b")#Fehlermeldung:#off ("b")#  USING-Format fehlerhaft: ... 
+Bei einer PRINT USING-Anweisung wurde ein fehlerhaftes Format angegeben. 
+ 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1004 
+#on ("b")#Fehlermeldung:#off ("b")#  Keine Daten mehr für READ 
+Es stehen keine Daten mehr für die READ-Anweisung zur Verfügung; der READ-
+DATA-Zeiger zeigt hinter das Ende der letzten DATA-Anweisung. 
+ 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1005 
+#on ("b")#Fehlermeldung:#off ("b")#  WIDTH: negative Angabe: ... 
+Nach WIDTH wurde eine negative Zahl gefunden. 
+ 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1013 
+#on ("b")#Fehlermeldung:#off ("b")#  READ: Falscher Datentyp, ... ist kein INT 
+Einer INT-Variablen konnte kein Wert zugewiesen werden, da das aktuelle Objekt
+aus der DATA-Liste keine gültige Darstellung eines INT-Wertes war oder ein
+"quoted string" gefunden wurde. 
+ 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1013 
+#on ("b")#Fehlermeldung:#off ("b")#  READ: Falscher Datentyp, ... ist kein REAL 
+Einer REAL-Variablen konnte kein Wert zugewiesen werden, da das aktuelle Objekt
+aus der DATA-Liste keine gültige Darstellung eines REAL-Wertes war oder ein
+"quoted string" gefunden wurde. 
+ 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1051 (interner Fehler) 
+#on ("b")#Fehlermeldung:#off ("b")#  variierend 
+Bei der Ausführung des Programms trat in einer Prozedur des BASIC-Systems ein
+interner Fehler auf. (Vergleiche Kapitel 7.) 
+ 
+ 
+#on ("b")#Fehlercode:#off ("b")#     1080 
+#on ("b")#Fehlermeldung:#off ("b")#  INPUT-Fehler ( Fehlerart ) : > Eingabezeile < 
+Bei einer INPUT-Anweisung, die auf eine mit 'sysin' eingestellte Datei wirken sollte,
+kam es zu einem Fehler der angegebenen Fehlerart. Nach dem Doppelpunkt wird die
+Eingabezeile aus der Eingabedatei ausgegeben. 
+#page# 
+#head# 
+EUMEL-BASIC-Compiler      Anhang D: ELAN-Prozeduren des Compilers       % 
+ 
+#end# 
+ 
+Anhang D: ELAN-Prozeduren des Compilers 
+ 
+   #on ("b")#PROC #ib(3)#basic#ie(3)# (TEXT CONST dateiname)#off ("b")# 
+   Das in der Datei 'dateiname' enthaltene BASIC-Programm wird dem BASIC-
+   Compiler zur Übersetzung übergeben. Werden keine Fehler gefunden, so wird das
+   Programm direkt nach der Übersetzung ausgeführt. 
+   Beispiel: 
+ 
+       basic ("Mein liebstes BASIC-Programm")#off ("b")# 
+ 
+ 
+   #on ("b")#PROC basic (TEXT CONST dateiname, prozedurname)#off ("b")# 
+   Das in der Datei 'dateiname' enthaltene BASIC-Programm wird dem BASIC-
+   Compiler zur Übersetzung übergeben. Werden keine Fehler gefunden, dann wird
+   das Programm unter dem Namen 'prozedurname' dauerhaft eingetragen (inser­
+   tiert). 
+   Das Programm wird nicht ausgeführt. Beachten Sie, daß der Prozedurname den
+   Vorschriften für ELAN-Prozedurnamen entsprechen muß und außerdem #on ("b")#keine
+   Leerzeichen#off ("b")# enthalten darf. (Zur Namenswahl siehe auch Kapitel 3.) 
+   Beispiel: 
+ 
+       basic ("Mein liebstes BASIC-Programm", "liebstesprogramm")#off ("b")# 
+ 
+ 
+ 
+   #on ("b")#PROC #ib(3)#basic list#ie(3)# (BOOL CONST status)#off ("b")# 
+   Mit der Prozedur 'basic list' kann eingestellt werden, ob die gerade vom Compiler
+   übersetzten Programmzeilen angezeigt werden sollen oder nicht (vergleiche Kapitel
+   3.). 
+ 
+   basic list (TRUE)#off ("b")#:  Die übersetzten Zeile werden angezeigt 
+   basic list (FALSE)#off ("b")#: Die übersetzten Zeile werden nicht angezeigt 
+ 
+ 
+   #on ("b")#PROC #ib(3)#basic page#ie(3)# (BOOL CONST status)#off ("b")# 
+   Mit der Prozedur 'basic page' kann eingestellt werden, wie die Ausgaben von
+   BASIC-Programmen behandelt werden, wenn der Bildschirm voll ist (vergleiche
+   Kapitel 5, Steuerung der Bildschirmausgaben). 
+ 
+   basic page (TRUE):  Beim Erreichen des Bildschirmendes wird auf einen
+                                           Tastendruck gewartet (vgl. Kap. 5.) 
+   basic page (FALSE): Beim Erreichen des Bildschirmendes wird 'gescrollt'. 
+
diff --git a/doc/basic/basic handbuch.index b/doc/basic/basic handbuch.index
new file mode 100644
index 0000000..4ac7e16
--- /dev/null
+++ b/doc/basic/basic handbuch.index	
@@ -0,0 +1,232 @@
+#page nr ("%",115)# 
+#head# 
+EUMEL-BASIC-Compiler             Stichwortverzeichnis       % 
+ 
+#end# 
+ 
+Stichwortverzeichnis 
+ 
+>=                                                  15 
+\                                                   14 
+-                                                   14 
++                                                   14 
++                                                   15 
+<=                                                  15 
+*                                                   14 
+/                                                   14 
+=                                                   15 
+>                                                   15 
+<                                                   15 
+<>                                                  15 
+^                                                   14 
+ABS                                                 31 
+AND                                                 16 
+Anführungszeichen                                   10 
+Argument                                            21 
+Arithmetische Operatoren                            14 
+Arrays                                              13 
+ASC                                                 32 
+ATN                                                 32 
+Äquivalenz-Verknüpfung                              17 
+Aufruf benutzer-definierter Funktionen              21 
+Aufruf und Steuerung des BASIC-Compilers            5 
+basic                                               5, 113 
+BASIC-Compiler ERROR                                28 
+basic list                                          6, 113 
+basic page                                          25, 114 
+benutzer-definierte Funktionen                      19, 104 
+Bildschirmausgaben                                  25 
+CALL                                                23, 33 
+CDBL                                                35 
+CHAIN                                               23, 35 
+CHR$                                                35 
+CINT                                                36 
+CLS                                                 36 
+Codebereichs pro Task                               27 
+Compiler Error 304                                  26 
+Compiler Error 307                                  26 
+Compiler Error 308                                  26 
+COS                                                 37 
+CSRLIN                                              37 
+CVD, CVI                                            38 
+DATA                                                38 
+DATE$                                               40 
+Datentypen                                          10 
+Datentyp INT                                        10 
+Datentyp REAL                                       10 
+Datentyp TEXT                                       10 
+Debugging                                           6 
+DEFDBL, DEFINT, DEFSNG, DEFSTR                      40 
+DEF FN                                              19, 28, 42 
+Definition benutzer-definierter Funktionen          19 
+DEFINT                                              12 
+DEFSTR                                              12 
+DIM                                                 13, 43 
+Dimensionen                                         13 
+Doppelpunkt                                         8 
+ELSE                                                54 
+END                                                 45 
+EOF                                                 56 
+EOF (End of File, Dateiende)                        7, 105 
+EOL (End of Line, Zeilenende)                       8, 105 
+EOS (End of Statement, Anweisungsende)              8, 105 
+EQV                                                 17 
+ERL                                                 46 
+ERM$                                                47 
+ERR                                                 47 
+ERROR                                               48 
+EUMEL-Coder                                         26 
+EUMEL-Textdatei                                     7 
+Exklusiv-ODER-Verknüpfung                           17 
+EXP                                                 49 
+Exponent                                            10 
+Fehlerbehandlung                                    28 
+Fehlercodes                                         30 
+Fehlerzeile                                         30 
+Fehler zur Laufzeit                                 30, 111 
+Fehler zur Übersetzungszeit                         28, 106 
+Felder (Arrays)                                     13 
+Felder/Feldelemente                                 104 
+Feldnamen                                           13 
+FIX                                                 49 
+FOR                                                 50 
+FRE                                                 51 
+Funktionen                                          19 
+Funktionsaufrufe                                    19 
+Ganzzahlen                                          10 
+Generatorprogramm                                   4 
+Gleitkommazahlen                                    10 
+GOSUB                                               52 
+GOTO                                                53 
+Grenzen des Compilers                               26 
+Groß-/Kleinschreibung                               9 
+Hauptdurchlauf                                      28 
+HEX$                                                54 
+Hochkomma                                           8 
+IF                                                  54 
+IMP                                                 17 
+Implikations-Verknüpfung                            17 
+Indizes                                             13 
+INKEY$                                              56 
+INPUT$                                              58 
+INPUT                                               56 
+Insertieren von BASIC-Programmen                    5 
+Installation des BASIC-Compilers                    4 
+INSTR                                               59 
+INT                                                 59 
+Interne Compilerfehler                              28 
+INTs                                                10 
+INT-Überlauf                                        15 
+KILL                                                60 
+Konstanten                                          10 
+Konvertierung                                       15, 22 
+Kriterien für den Typ einer Variablen               12 
+Labels                                              26 
+Leerzeichen                                         9 
+LEFT$                                               60 
+LEN                                                 61 
+LET                                                 61 
+LINE INPUT                                          62 
+LOG                                                 63 
+Logische Operatoren                                 16 
+LPOS                                                63 
+LPRINT                                              64 
+LSET                                                65 
+Mantisse                                            11 
+MID$                                                65, 66 
+MKD$, MKI$                                          67 
+MOD                                                 14 
+Modulgrenze                                         26 
+NAME                                                68 
+Namenstabelle                                       27 
+Negation                                            16 
+negative Zahlenwerte                                11 
+NEXT                                                50, 68 
+NOT                                                 16 
+Notation                                            3 
+Notebook                                            28 
+numerische Konstanten                               103 
+OCT$                                                69 
+ODER-Verknüpfung                                    17 
+ON                                                  69 
+Operatoren                                          103 
+Operatoren, arithmetische                           14 
+Operatoren, logische                                16 
+Operatoren, Text-                                   15 
+Operatoren, Vergleichs-                             15 
+Operator, Zuweisungs-                               18 
+OPTION BASE                                         13, 71 
+OR                                                  17 
+Parameter                                           19 
+POS                                                 72 
+PRINT                                               72 
+Prioritäten der Operanden                           18 
+Programmdatei                                       7 
+Programmsegmente                                    24 
+Programmzeile                                       7 
+RANDOMIZE                                           75 
+READ                                                75 
+REM                                                 77 
+Reservierte Wörter                                  9, 12, 100, 103 
+RESTORE                                             77 
+RETURN                                              78 
+RIGHT$                                              79 
+RND                                                 80 
+RSET                                                81 
+Scanner                                             9, 103 
+Schlüsselwörter                                     9 
+Scrolling                                           25 
+SGN                                                 81 
+SIN                                                 82 
+SPACE$                                              82 
+SPC                                                 83 
+SQR                                                 83 
+Standard-Funktionen                                 19 
+STEP                                                50 
+Steuerung der Bildschirmausgaben                    25 
+Steuerung des BASIC-Compilers                       5 
+STOP                                                84 
+STR$                                                84 
+STRING$                                             85 
+SUB                                                 52 
+SWAP                                                86 
+Symbol                                              9 
+Symboltypen                                         103 
+Syntax                                              7 
+sysout                                              6 
+TAB                                                 64, 72 
+TAN                                                 86 
+Texte                                               10 
+TEXT-Konstanten                                     104 
+Text-Operator +                                     15 
+THEN                                                54 
+TIME$                                               88 
+TIMER                                               87 
+TO                                                  50, 53 
+Trennzeichen                                        105 
+TRON / TROFF                                        88 
+Typanpassung                                        22 
+UND-Verknüpfung                                     16 
+USING                                               64, 72 
+USR                                                 23, 90 
+Übersetzen von BASIC-Programmen                     5 
+Übersichtlichkeit von BASIC-Programmen              7 
+VAL                                                 91 
+Variablen                                           12, 104 
+Variablennamen                                      9, 12 
+VAR-Parameter                                       23 
+Vergleichsoperatoren                                15 
+Vordurchlauf                                        28 
+Vorzeichen                                          11 
+Wahrheitswerte                                      16 
+Weitere Schreibregeln                               9 
+WEND                                                92 
+wertliefernden Prozeduren                           23 
+WHILE                                               92 
+WIDTH                                               93 
+WRITE                                               94 
+XOR                                                 17 
+Zahlen                                              10 
+Zeilennummer                                        7 
+Zuweisungsoperator                                  18 
+
diff --git a/doc/dialog/gs-dialog handbuch.impressum b/doc/dialog/gs-dialog handbuch.impressum
new file mode 100644
index 0000000..b470fe4
--- /dev/null
+++ b/doc/dialog/gs-dialog handbuch.impressum	
@@ -0,0 +1,89 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#gs-Dialog
+ 
+ 
+ 
+ 
+#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# 
+ 
+#free (4.0)##on("b")# 
+#center#gs-Dialog
+ 
+ 
+#center#Benutzerhandbuch 
+ 
+ 
+#center#Version 1.0 
+ 
+ 
+#off("b")##center#copyright 
+#center#Eva Latta-Weber 
+#center#Software- und Hardware-Systeme, 1988 
+#center#ERGOS GmbH, 1990 
+#page# 
+#block# 
+#center#____________________________________________________________________________ 
+ 
+ 
+Copyright:  ERGOS GmbH   März 1990 
+ 
+                     Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+                     maschinenlesbare Form sowie das Speichern in Informations­
+                     systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+                     der ERGOS GmbH gestattet. 
+ 
+ 
+#center#____________________________________________________________________________ 
+ 
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender. 
+ 
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden. 
+ 
+Texterstellung   :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+                   erstellt und aufbereitet und auf einem Kyocera Laser­
+                   drucker gedruckt. 
+ 
+ 
+ 
+ 
+#center#___________________________________________________________________________ 
+ 
+ 
+ 
+Ergonomic Office Software GmbH 
+ 
+Bergstr. 7              Telefon: (02241) 63075 
+5200 Siegburg           Teletex: 2627-2241413=ERGOS 
+                        Telefax: (02241) 63078 
+ 
+ 
+#center#____________________________________________________________________________ 
+
+
diff --git a/doc/dialog/gs-dialog-1 b/doc/dialog/gs-dialog-1
new file mode 100644
index 0000000..59b98c3
--- /dev/null
+++ b/doc/dialog/gs-dialog-1
@@ -0,0 +1,107 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (3)# 
+#headodd# 
+#center#gs-DIALOG#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-DIALOG 
+ 
+#end# 
+ 
+#center#1 
+ 
+#center#Was kann gs-DIALOG? 
+ 
+ 
+ 
+   In diesem Kapitel wollen wir Ihnen erläutern, was
+#on("b")#gs-DIALOG#off("b")# Ihnen für Vorteile bringen soll. Sie haben
+sicher schon mit einem Computer gearbeitet und sich
+mehrfach darüber geärgert, daß Sie mit jedem neuen Pro­
+gramm auch eine neue Bedienung erlernen müssen. Zwar
+sind Sie als EUMEL-Anwender schon sehr verwöhnt, da das
+System sehr homogen ist und bestimmte Systemelemente,
+wie z.B. der Editor, mit immer gleicher Bedienung immer
+wieder auftauchen. Für die jeweiligen Anwendungspro­
+gramme aber gibt es eine Reihe von Kommandos und Tasten­
+folgen, die Sie sich für die Bedienung merken müssen.
+Brauchen Sie Informationen zu den einzelnen Programm­
+teilen, so müssen Sie zumeist in (den gerade nicht griff­
+bereiten) Handbüchern nachschlagen. 
+  Und der Anfänger? Er ist am härtesten betroffen! Er
+muß sich nicht nur mit der neuen Maschine auseinander­
+setzen, die technische Handhabung erlernen - von ihm
+erwartet man, daß er sich innerhalb kurzer Zeit eine Rei­
+he von Kommandos einprägt, die für die Bedienung des
+Grundsystems notwendig sind - und darüber hinaus noch
+die Kommandos für die verschiedenen Anwendungsprogram­
+me. Viele resignieren nach den ersten Gehversuchen. 
+   Und der Programmierer? Viele Anwender haben keine
+Vorstellung davon, welche Arbeit in einem Programm
+steckt. Einen großen Teil seiner Arbeit verwendet der
+Programmierer darauf, die Benutzerschnittstelle zu ge­
+stalten - den Teil des Programms, mit dem der Anwender in
+Kontakt kommt, über den er mit dem Programm kommuni­
+ziert, einen Dialog führt. Die Gestaltung und Pflege der
+Benutzerschnittstelle kann dabei bis zu 50% der Gesamt­
+arbeit an einem Programm ausmachen. 
+ 
+   #on("b")#gs-DIALOG#off("b")# ist entwickelt worden, um diese Nachteile zu
+beheben bzw. zumindest zu verringern. Grundelemente von
+#on("b")#gs-DIALOG#off("b")#  sind die Pull-Down-Menus (Klappmenus), in de­
+nen die zur Verfügung stehenden Funktionen übersicht­
+lich zur Auswahl angeboten werden. So ist es möglich, daß
+eine Vielzahl von Funktionen verwaltet werden - ohne
+daß der Anwender den Überblick verliert. Dabei können zu
+jeder angebotenen Funktion noch Informationen abge­
+rufen werden, so daß ein Blättern in Handbüchern sich
+zumeist erübrigt. 
+   Zunächst einmal ist #on("b")#gs-DIALOG#off("b")# gar kein eigenständiges
+Programm. Es ist vielmehr ein Baukastensystem, auf das
+andere Programme zugreifen können. Davon können sowohl
+der Programmierer und erst recht der Anwender profi­
+tieren: 
+   Der Programmierer wird bei seiner Arbeit - insbeson­
+dere bei der Gestaltung der Benutzerschnittstelle we­
+sentlich entlastet, da er auf vorgefertigte Komponenten
+zurückgreifen kann. Er kann sich mehr auf die inhalt­
+liche Ausgestaltung seiner Programme konzentrieren. 
+   Sie als Anwender profitieren von der #on("u")#einfachen#off("u")# und
+#on("u")#immer einheitlichen Bedienung#off("u")# solcher Programme. Aus
+den Menupunkten können Sie auf einfache Weise auswählen
+und den gewünschten Teil des Programms zur Ausführung
+bringen. Durch diese Bedienung wird der Aufwand, sich in
+ein neues Programmsystem einzuarbeiten, erheblich redu­
+ziert. Die zur Verfügung stehenden Programmfunktionen
+können effektiver ausgenutzt werden, da sie jederzeit
+offensichtlich sind. Informationen zu den einzelnen Pro­
+grammpunkten können Sie jederzeit abrufen, d.h. zumeist
+können Sie auf ein Nachschlagen in den Handbüchern ver­
+zichten. 
+   #on("b")#gs-DIALOG#off("b")# ist aber nicht nur ein Baukastensystem, auf
+das andere Programme zugreifen können. Bei nahezu jeder
+Anwendung ist es notwendig, Dateien auf das Archiv zu
+schreiben oder von dort zu holen. Aus diesem Grunde ist
+eine leistungsfähige, komfortable Archivbehandlung in
+das Programmsystem integriert. 
+   Ein Austausch von Dateien ist aber nicht nur mit dem
+Archiv möglich. Sie können auch mit anderen Tasks inner­
+halb Ihres Systems (z.B. mit der Vatertask) oder sogar -
+sofern installiert - mit einer Task irgendwo innerhalb
+des EUMEL-Netzes Dateien austauschen. Daneben werden
+noch Funktionen angeboten, die den Umgang mit den Da­
+teien vereinfachen (Verzeichnis, Umbenennen, Kopieren,
+Löschen, Aufräumen etc.). 
+   Diese Funktionen stehen Ihnen unabhängig von ande­
+ren Programmen zu Verfügung, sobald Sie #on("b")#gs-DIALOG#off("b")# in­
+stalliert haben. Andererseits finden Sie diese Funktionen
+in immer gleicher Form auch in den meisten Programmen,
+die auf der Basis von #on("b")#gs-DIALOG#off("b")# entwickelt worden sind
+und entwickelt werden. 
+ 
+
+
+
+
diff --git a/doc/dialog/gs-dialog-2 b/doc/dialog/gs-dialog-2
new file mode 100644
index 0000000..a25d35d
--- /dev/null
+++ b/doc/dialog/gs-dialog-2
@@ -0,0 +1,215 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (6)# 
+#headodd# 
+#center#gs-DIALOG#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-DIALOG 
+ 
+#end# 
+ 
+#center#2 
+ 
+#center#Installation von gs-DIALOG 
+ 
+ 
+ 
+   Bevor Sie #on("b")#gs-DIALOG#off("b")# auf Ihrem System benutzen kön­
+nen, müssen Sie das Programm zunächst installieren. Wenn
+#on("b")#gs-DIALOG#off("b")# auf Ihrem System schon zur Verfügung steht,
+können Sie dieses Kapitel ruhig überspringen. 
+ 
+ 
+2.1  Voraussetzungen: 
+ 
+   Um #on("b")#gs-DIALOG#off("b")# auf Ihrem Computer betreiben zu können,
+muß das EUMEL-Betriebssystem installiert sein. #on("b")#gs-DIALOG#off("b")#
+setzt die Multi-User-Version voraus und ist lauffähig ab
+Version 1.7.5. 
+ 
+ 
+2.2  Lieferumfang 
+ 
+   #on("b")#gs-DIALOG#off("b")# wird auf einer Diskette geliefert, die alle
+notwendigen Programme enthält. Um den Inhalt der Dis­
+kette feststellen zu können, starten Sie Ihr System und
+bringen es dazu, daß 'gib kommando:' erscheint. Dann legen
+Sie die Diskette ein und geben das Kommando: 
+ 
+   archive ("gs-DIALOG"); list (archive); 
+   release (archive) <RETURN> 
+ 
+   Anschließend erscheint eine Übersicht der auf dem
+Archiv vorhandenen Programme. Folgende Programme soll­
+ten sich in der Übersicht befinden: 
+ 
+   "gs-DIALOG MENUKARTEN MANAGER" 
+   "gs-DIALOG MM/gen" 
+   "gs-DIALOG 1" 
+   "gs-DIALOG 2" 
+   "gs-DIALOG 3" 
+   "gs-DIALOG 4" 
+   "gs-DIALOG 5" 
+   "gs-DIALOG 6" 
+   "gs-DIALOG 7" 
+   "gs-MENUKARTE:Archiv" 
+   "gs-DIALOG/gen" 
+ 
+   Eventuell können noch weitere Namen auf der Diskette
+vorhanden sein. Wenn Sie den Inhalt der Diskette kon­
+trolliert haben und diese Programme auf der Diskette
+vorhanden sind, können Sie #on("b")#gs-DIALOG#off("b")# installieren. 
+   Sollten Sie statt der Übersicht eine Fehlermeldung
+erhalten, überprüfen Sie bitte, ob die Diskette das rich­
+tige Format besitzt oder ob ihr Diskettenlaufwerk Pro­
+bleme macht. Sollten dagegen Programme fehlen, so rekla­
+mieren Sie die Diskette. 
+ 
+ 
+2.3  Installation 
+ 
+Die Installation erfolgt in #on("u")#zwei Schritten#off("u")#: 
+   #on("u")#Zunächst#off("u")# muß eine Task eingerichtet werden, in der
+später alle Menukarten aufbewahrt werden. Diese Menu­
+karten enthalten alle Informationen, die #on("b")#gs-DIALOG#off("b")# für
+den Aufbau und den Umgang mit den Menus benötigt. #on("u")#Der
+Name dieser Task ist vorgegeben#off("u")# ('gs-MENUKARTEN'), da
+#on("b")#gs-DIALOG#off("b")# später auf diese Task zugreift. Sollten Sie
+hier einen anderen Namen wählen, so wird die Task vom
+Generierungsprogramm automatisch umbenannt, um die
+Funktionsfähigkeit von #on("b")#gs-DIALOG#off("b")# zu garantieren! 
+   #on("u")#Anschließend#off("u")# kann das Programmsystem selbst in einer
+anderen Task installiert werden. Wie nehmen hier an, daß
+die Task den Namen 'MENU' erhalten soll. (Sie können für
+diese Task auch einen beliebigen anderen Namen wählen.) 
+ 
+ 
+1)  #on("u")#Einrichten der 'Menukarten - Task'#off("u")# 
+ 
+#on("b")# 
+           <SV>           (Supervisor - Taste) 
+#off("b")# 
+ 
+   -->     gib supervisor kommando: 
+ 
+#on("b")# 
+           begin ("gs-MENUKARTEN") <RETURN> 
+#off("b")# 
+ 
+   -->     gib kommando: 
+ 
+ 
+   (Arbeiten mehrere Personen mit dem Computer, dann ist
+es sinnvoll, diese Task vor unbefugtem Zugriff durch ein
+Passwort zu schützen. Wie das gemacht wird, können Sie in
+Ihrem EUMEL-Benutzerhandbuch erfahren.) 
+   Legen Sie dann die Archivdiskette ein, auf der sich
+#on("b")#gs-DIALOG#off("b")# befindet, und geben Sie die folgenden Komman­
+dos: 
+ 
+#on("b")# 
+   archive("gs-DIALOG") <RETURN> 
+ 
+   fetch("gs-DIALOG MM/gen",archive) <RETURN> 
+ 
+   run <RETURN> 
+#off("b")# 
+ 
+   Sie haben damit das Generatorprogramm gestartet; die
+Installation wird automatisch durchgeführt. Lassen Sie
+während des gesamten Vorgangs die Archivdiskette einge­
+legt. Die Generierung ist beendet, wenn der EUMEL-
+Eingangsbildschirm erscheint. 
+ 
+2)  #on("u")#Installation des Programmsystems#off("u")# 
+ 
+ 
+#on("b")# 
+           <SV>           (Supervisor - Taste) 
+#off("b")# 
+ 
+   -->     gib supervisor kommando: 
+ 
+#on("b")# 
+           begin ("MENU") <RETURN> 
+#off("b")# 
+ 
+   -->     gib kommando: 
+ 
+ 
+   (Sichern Sie, wenn gewünscht, auch diese Task durch
+ein Passwort vor unbefugtem Zugriff.) 
+   Legen Sie die #on("b")#gs-DIALOG#off("b")#-Archivdiskette ein und geben
+Sie die folgenden Kommandos: 
+ 
+#on("b")# 
+   archive("gs-DIALOG") <RETURN> 
+ 
+   fetch("gs-DIALOG/gen",archive) <RETURN> 
+ 
+   run <RETURN> 
+#off("b")# 
+ 
+   Sie haben damit das Generatorprogramm gestartet. Die
+Generierung benötigt jetzt aber wesentlich mehr Zeit als
+die zuvor! Lassen Sie während des gesamten Vorgangs die
+Archivdiskette eingelegt. Die Generierung ist beendet,
+wenn der EUMEL-Eingangsbildschirm erscheint. Die Task,
+in der die Generierung stattfindet, wird automatisch zur
+Managertask, das heißt, daß Söhne von ihr eingerichtet
+werden können. Damit ist die Installation von #on("b")#gs-DIALOG#off("b")#
+abgeschlossen - in allen Sohn- und Enkeltasks können
+Sie nun mit dem Kommando: 
+ 
+#on("b")# 
+   archiv <RETURN> 
+#off("b")# 
+ 
+die Archivverwaltung aufrufen. 
+ 
+ 
+2.4  Nutzung der 'Semi-Graphik-Zeichen' 
+ 
+   #on("b")#gs-DIALOG#off("b")# verwendet beim Aufbau der Rahmen inner­
+halb der Menus nur solche Zeichen, die auf jedem Computer
+zur Verfügung stehen. Die meisten Computer/Terminals
+verfügen aber über einen Zeichensatz, der es erlaubt,
+solche Rahmen "schöner" darzustellen. #on("b")#gs-DIALOG#off("b")# ist dar­
+auf vorbereitet, diese Eigenschaften auszunutzen. 
+   Allerdings ist der Aufruf dieser Graphikzeichen nicht
+einheitlich festgelegt. Verfügen Sie über einen Computer,
+der 'IBM - kompatibel' ist, oder über ein Terminal 'Beehive
+FT20', dann können Sie die Graphikzeichen ganz einfach
+nutzen, denn dafür sind im Programm bereits Befehle vor­
+bereitet. 
+ 
+ibm  graphic char <RETURN>  -  Mit diesem Befehl stel­
+                               len Sie für #on("b")#gs-DIALOG#off("b")#
+                               den 'IBM - Graphikzei­
+                               chensatz' ein. 
+ 
+ft20 graphic char <RETURN>  -  Mit diesem Befehl stel­
+                               len Sie für #on("b")#gs-DIALOG#off("b")#
+                               den 'Beehive FT20 -
+                               Graphikzeichensatz'
+                               ein. 
+ 
+std  graphic char <RETURN>  -  Mit diesem Befehl stel­
+                               len Sie wieder den
+                               'Standard - Graphik­
+                               zeichensatz' ein. 
+ 
+   Nehmen Sie eine solche Einstellung in einer Task vor,
+so erben alle Sohn- und Enkeltasks diese Einstellung. Sie
+können auch in verschiedenen Task unterschiedliche Ein­
+stellungen wählen. 
+ 
+   Verfügen Sie über andere Computer- oder Terminalty­
+pen, die Grapikzeichen darstellen können, so können Sie
+diese ebenfalls nutzen. Sie müßten sich allerdings ein
+kleines ELAN-Programm schreiben. Aber auch das ist ganz
+einfach, da #on("b")#gs-DIALOG#off("b")# auch darauf vorbereitet ist. Wie
+das gemacht wird, wird aber erst in Kapitel 5 erläutert. 
+
diff --git a/doc/dialog/gs-dialog-3 b/doc/dialog/gs-dialog-3
new file mode 100644
index 0000000..044720b
--- /dev/null
+++ b/doc/dialog/gs-dialog-3
@@ -0,0 +1,683 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (12)# 
+#headodd# 
+#center#gs-DIALOG#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-DIALOG 
+ 
+#end# 
+ 
+#center#3 
+ 
+#center#Umgang mit den Menus 
+ 
+ 
+#center#Eine Beispielsitzung 
+ 
+ 
+   Wie schon oben erwähnt, ist in #on("b")#gs-DIALOG#off("b")# eine Archiv­
+verwaltung integriert. Anhand dieses Programms möchten
+wir den Umgang mit und die Arbeitsweise von #on("b")#gs-DIALOG#off("b")#
+vorstellen. Als Beispiel wollen wir eine Datei von einer
+Ihrer Archivdisketten ins System holen. 
+  Zunächst zu den Begriffen: Die Disketten, die Sie in den
+Rechner einlegen können, um z.B. Dateien (und Programme)
+von anderen Computern übernehmen zu können, bezeichnet
+man als #on("u")#Archiv#off("u")#. Das Archiv (die Diskette) wird benutzt, um
+Daten und Programme vor Beschädigung und Verlust zu
+sichern. Es ist sehr wichtig, daß Sie Ihre Programme und
+Daten auf Archivdisketten sichern, denn ein einziger
+Hardwarefehler könnte die Arbeit von vielen Stunden
+zunichte machen. 
+   Da man diese Operationen, d.h. Programme und Daten
+auf Disketten zu sichern und wieder von dort zu holen,
+sehr häufig benötigt, ist die Archivbehandlung fest in
+das #on("b")#gs-DIALOG#off("b")#-Programmsystem integriert und Bestandteil
+nahezu jeden Programms, das unter #on("b")#gs-DIALOG#off("b")# entwickelt
+wird. Unabhängig von anderen Programmen kann die
+Archivbehandlung aber auch benutzt werden, sobald
+#on("b")#gs-DIALOG#off("b")# installiert ist. Das wollen wir jetzt auspro­
+bieren. 
+ 
+ 
+3.1  Aufruf der Archivverwaltung: 
+ 
+   Richten Sie eine Task als Sohn der Task ein, in der Sie
+#on("b")#gs-DIALOG#off("b")# installiert haben. Nehmen wir hier an, die neue
+Task soll den Namen 'TEST' erhalten - die Task, in der
+#on("b")#gs-DIALOG#off("b")# installiert ist, habe den Namen 'MENU'. 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+#off("b")# 
+  -->     gib supervisor kommando: 
+#on("b")# 
+          begin ("TEST","MENU") <RETURN> 
+#off("b")# 
+ 
+  -->     gib kommando: 
+#on("b")# 
+          archiv <RETURN> 
+#off("b")# 
+ 
+  Mit dem Befehl 'archiv' können Sie jederzeit die Archiv­
+behandlung aufrufen - es erscheint dann folgendes Menu: 
+ 
+ 
+#on("b")# 
+ARCHIV:  Dateien  Archiv 
+-+-------------------+---------------------------------------------------- 
+ |  v Verzeichnis    | 
+ |  ---------------  | 
+ |  l Löschen        | 
+ |  d Drucken        | 
+ |  ---------------  | 
+ |  k Kopieren       | 
+ |  u Umbenennen     | 
+ |  ---------------  | 
+ |  s Speicherplatz  | 
+ |  a Aufräumen      | 
+ +-------------------+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+ 
+3.2    Bedienung des Menusystems 
+ 
+-  Aufbau der Menus  (Bildschirmaufbau) 
+ 
+   Ein Menu ist ein Angebot von Funktionen, die ein Pro­
+gramm ausführen kann. Aus diesem Angebot kann der Pro­
+grammbenutzer auswählen. In diesem Sinne ist ein solches
+Menu durchaus vergleichbar mit einer Speisenkarte in
+einem Restaurant. 
+   Jedes Menu unter #on("b")#gs-DIALOG#off("b")# besitzt eine 'Kopfzeile'
+und eine 'Fußzeile'. In der Kopfzeile ist ganz links der
+Name des Programms angegeben, mit dem Sie gerade arbei­
+ten. Daneben enthält die Kopfzeile die 'Oberbegriffe', mit
+denen die einzelnen Untermenus angesprochen werden
+können. Maximal können hier zehn Oberbegriffe auftau­
+chen - in unserem Beispiel sind es nur zwei. 
+   Besondere Bedeutung für die Bedienung der Menus
+kommt der Fußzeile zu. Einerseits wird hier jeweils ange­
+zeigt, welche Tasten Sie zum jeweiligen Zeitpunkt benut­
+zen können, andererseits erhalten Sie über diese Fußzeile
+auch Informationen, wenn #on("b")#gs-DIALOG#off("b")# "mit sich selbst be­
+schäftigt ist", d.h. Operationen ausführt. Wissen Sie also
+nicht mehr weiter, so schauen Sie zuerst auf die Fußzeile
+und beachten Sie die hier stehenden Informationen. 
+   Im Bereich zwischen der Kopf- und Fußzeile werden die
+Untermenus ausgegeben. Dieser Bereich wird auch dazu
+benutzt, um Informationen an den Benutzer einzublenden,
+Fragen an ihn zu richten, ihn aus einem Angebot (z.B. von
+Dateien) auswählen zu lassen und vieles mehr. 
+   Treiben wir den Vergleich mit der Speisenkarte in ei­
+nem Restaurant noch ein wenig weiter. Bei einem großen
+Angebot kann eine Speisenkarte recht umfangreich wer­
+den. Denken Sie beispielsweise an eine Speisenkarte in
+einem chinesischen Restaurant. Dazu sind neben den an­
+gebotenen Gerichten oft noch Zusatzinformationen (Zube­
+reitungsart, Zutaten etc.) angegeben. Um dem Gast die Aus­
+wahl zu erleichtern, ist die Speisenkarte aber zumeist
+untergliedert; man findet Suppen, warme Vorspeisen, kalte
+Vorspeisen, Gerichte mit Schweinefleisch, mit Rindfleisch,
+mit Geflügel, mit Fisch etc. 
+   Ein Computerprogramm kann, ebenso wie ein Restau­
+rant, dem Benutzer ein großes Angebot (an Programmfunk­
+tionen) machen. Von großem Nachteil ist allerdings, daß
+ein Computerbildschirm - im Gegensatz zu einer umfang­
+reichen Speisenkarte - viel zu klein ist, um alle Angebote
+und Informationen gleichzeitig darstellen zu können.
+Außerdem würde ein nahezu vollständig beschriebener
+Bildschirm sehr unübersichtlich sein. 
+   Aus diesem Grunde haben wir uns entschlossen, immer
+nur einen Teil des vorhandenen Angebotes an Funktionen
+und der vorhandenen Informationen anzuzeigen - immer
+nur soviel, daß Sie sich auf dem Bildschirm orientieren
+können und den Überblick nicht verlieren. Dazu haben Sie
+die Möglichkeit, jeweils zu bestimmen, auf welche Infor­
+mationen Sie Ihre Aufmerksamkeit richten wollen, was Sie
+angezeigt bekommen möchten. 
+ 
+ 
+-  Auswahl der Menupunkte 
+ 
+   Zu jedem Oberbegriff in der Kopfzeile gehört eine
+Liste von Funktionen, die das Programm dazu zur Auswahl
+anbietet. Allerdings ist immer nur eine Liste (ein Unter­
+menu) sichtbar. Das sichtbare Untermenu gehört immer zu
+dem Oberbegriff in der Kopfzeile, der invers dargestellt
+ist. Wir wollen uns zunächst das Untermenu zum zweiten
+Oberbegriff ('Archiv') anzeigen lassen. Zum Wechsel zwi­
+schen den Oberbegriffen in der Kopfzeile benutzt man die
+Pfeiltasten <links> oder <rechts>. Probieren Sie es einmal
+aus. Es erscheint das folgende Bild auf dem Bildschirm: 
+ 
+ 
+#on("b")# 
+ARCHIV:  Dateien  Archiv 
+-------+-------------------------+---------------------------------------- 
+       |  r Reservieren          | 
+       |  - Neue Diskette        | 
+       |  ---------------------  | 
+       |  - Schreiben            | 
+       |  - Checken              | 
+       |  - Kombination          | 
+       |  - Holen/Lesen          | 
+       |  - Löschen              | 
+       |  ---------------------  | 
+       |  - Verzeichnis          | 
+       |  - Drucken              | 
+       |  ---------------------  | 
+       |  i Initialisieren       | 
+       |  z Zieltask einstellen  | 
+       +-------------------------+                +---------------------+ 
+                                                  | Dateiaustausch mit: | 
+                                                  |  Archiv             | 
+                                                  | Archivname:         | 
+                                                  |  ---                | 
+                                                  +---------------------+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+ 
+   Sie können jetzt sehen, daß ein anderer Oberbegriff in
+der Kopfzeile aktiviert, d.h. invers dargestellt ist. Dane­
+ben wurde noch das sichtbare Untermenu "eingeklappt"
+und ein anderes "ausgeklappt". Man könnte die Unterme­
+nus deshalb auch als 'Klappmenus' bezeichnen - gebräuch­
+lich ist allerdings die Bezeichnung 'Pull-Down-Menus', an
+die wir uns auch halten wollen. 
+ 
+   Sicher haben Sie bemerkt, daß es einen Augenblick
+gedauert hat, bis das Pull-Down-Menu unter dem Menu­
+punkt 'Archiv' erschien. Das hat auch seine Ursache, denn
+#on("b")#gs-DIALOG#off("b")# muß einige Einstellungen vornehmen, die etwas
+Zeit in Anspruch nehmen. Neben dem Pull-Down-Menu ist
+unten rechts auf dem Bildschirm noch ein 'Kasten' sicht­
+bar geworden. Er dient Ihnen zur Information. Da
+#on("b")#gs-DIALOG#off("b")# nicht nur den Austausch von Dateien mit dem
+Archiv, sondern auch mit anderen Tasks ermöglicht, wird
+hier immer angezeigt, mit welcher Task der Dateiaus­
+tausch zur Zeit erfolgt. Ist das Archiv eingestellt, so
+wird auch noch der Name der Diskette angezeigt - aber
+erst wenn das Archiv angemeldet worden ist, was ja mo­
+mentan noch nicht der Fall ist. Deshalb werden nur drei
+Striche ausgegeben. 
+   Sicher ist Ihnen das Grundprinzip der Menubehand­
+lung schon klar geworden: Sie müssen sich zuerst inner­
+halb der Kopfzeile für einen Oberbegriff entscheiden.
+Zum gewählten Oberbegriff wird dann jeweils das Angebot
+an zugehörigen Programmfunktionen im darunterstehen­
+den Pull-Down-Menu angezeigt. Dieses Vorgehen hat den
+Vorteil, daß man den kleinen Bildschirm im Prinzip "mehr­
+fach nutzen kann". Die Pull-Down-Menus können sich ja
+ruhig überlappen. Sie merken es gar nicht, da ja nicht
+alle gleichzeitig angezeigt werden. 
+   Noch ein Vorteil ist da, Sie können sich auf den Teil
+konzentrieren, für den Sie sich gerade interessieren und
+werden nicht durch andere Informationen abgelenkt. An­
+dererseits können Sie jederzeit auch an die Funktionen
+und Informationen gelangen, die gerade nicht sichtbar
+sind. 
+   Sie haben sicher bemerkt, daß nicht nur innerhalb der
+Kopfzeile ein Begriff invers dargestellt ist, sondern
+auch einer innerhalb jedes Pull-Down-Menus. Nachdem man
+sich für einen Oberbegriff entschieden hat, kann man
+nämlich noch zwischen den Funktionen innerhalb des
+Pull-Down-Menus wählen. 
+   Da das Pull-Down-Menu zum Oberbegriff 'Archiv' noch
+einige Besonderheiten aufweist, wollen wir uns die Funk­
+tionsweise zuerst am Pull-Down-Menu unter dem Oberbe­
+griff 'Dateien' verdeutlichen. Bitte wechseln Sie deshalb
+durch Betätigung der Pfeiltaste <links> oder <rechts> zum
+ersten Pull-Down-Menu zurück. 
+   Ähnlich wie in der Kopfzeile, können Sie auch inner­
+halb des Pull-Down-Menus zu einem anderen Punkt wech­
+seln. Das geschieht durch die Pfeiltasten <hoch> und
+<runter>. Dabei werden 'Trennlinien' innerhalb des Pull-
+Down-Menus, die nur der Untergliederung dienen, über­
+sprungen. Vom obersten Menupunkt gelangt man direkt
+zum untersten und umgekehrt. Probieren Sie es einmal
+aus. 
+ 
+ 
+-  Informationen zu einem Menupunkt. 
+ 
+   Zu jedem Punkt eines Pull-Down-Menus können Sie In­
+formationen abrufen. Das ist  ganz einfach, denn Sie
+brauchen sich nur auf den gewünschten Menupunkt zu
+begeben (die Pfeiltasten so betätigen, bis der betreffende
+Menupunkt im Pull-Down-Menu invers dargestellt wird).
+Anschließend betätigen Sie die Fragezeichentaste (<?>). 
+   Auf dem Bildschirm erscheint ein Kasten in den die
+Informationen zum Menupunkt eingetragen sind. Zwar wird
+dadurch ein Teil des Bildschirms überschrieben, doch kei­
+ne Angst - sobald Sie auf irgendeine Taste tippen, wird
+der alte Bildschirmzustand wieder hergestellt! Ebenso wie
+die Pull-Down-Menus sind diese Informationen normaler­
+weise verborgen. Auf Anforderung werden sie aber sicht­
+bar - ja es wäre gar nicht möglich alle vorhandenen In­
+formationen gleichzeitig auf dem Bildschirm darzustel­
+len. Es wäre auch unsinnig, denn man benötigt diese In­
+formationen zumeist nur, wenn man sich in das Programm
+einarbeitet. Später, wenn Ihnen der Umgang mit dem Pro­
+gramm vertraut ist, sind diese Informationen überflüssig
+und würden, wenn sie immer sichtbar wären, nur stören. 
+ 
+ 
+-  Informationen zur Bedienung des Menus 
+ 
+   Alles das, was hier ausführlich beschrieben ist, kön­
+nen Sie auch in Kurzform auf dem Bildschirm erfahren,
+denn auch die Informationen, wie das Menu bedient wird,
+sind jeweils im Menu vorhanden. Möchten Sie diese Infor­
+mationen auf dem Bildschirm sehen, so tippen Sie die
+Tastenfolge <ESC><?>, d.h. erst die Taste 'ESC' und dann die
+Fragezeichentaste. Danach erscheint folgender Kasten
+auf dem Bildschirm: 
+ 
+#on("b")# 
+           +---------------------------------------+ 
+           |              gs-DIALOG                | 
+           |                                       | 
+           |   e ... Erläuterungen (allgemein)     | 
+           |   w ... Wahl eines Menupunktes        | 
+           |   a ... Aktivieren des Menupunktes    | 
+           |   b ... Besondere Tasten / Menuende   | 
+           |                                       | 
+           |   z ... Zurück in das Menu            | 
+           |                                       | 
+           |          e   w   a   b   z            | 
+           +---------------------------------------+ 
+#off("b")# 
+ 
+   Wenngleich die Informationen kurz gefaßt sind, so
+haben sie doch nicht alle gleichzeitig auf dem Bildschirm
+Platz. Aus diesem Grunde werden Sie aufgefordert, sich
+weiter zu entscheiden, welche Informationen Sie haben
+möchten. Sie können zwischen mehreren Alternativen wäh­
+len. Die Reihenfolge spielt keine Rolle; Sie können auch
+Informationen mehrmals aufrufen. 
+   Der Aufruf kann auf zweierlei Weise erfolgen: Entwe­
+der Sie bewegen mit den Pfeiltasten <links> oder <rechts>
+die Markierung in der letzten Zeile des Kastens auf den
+Buchstaben, der vor dem von Ihnen gewünschten Punkt
+steht und tippen anschließend auf die <RETURN>-Taste
+oder Sie tippen direkt die entsprechende Buchstabentaste
+(z.B. <e>). Beide Vorgehensweisen sind zulässig und haben
+die gleiche Wirkung. 
+   Daraufhin werden die gewünschten Informationen
+sichtbar. Durch Tippen irgendeiner Taste verschwinden
+die Informationen wieder vom Bildschirm und sichtbar
+wird wieder der oben abgebildete 'Verteiler'. Erst wenn
+man den Punkt 'z ... Zurück in das Menu' wählt, verschwin­
+det auch dieser Kasten und man gelangt zurück in das
+Menu. 
+ 
+ 
+-  Aktivierbare und nicht aktivierbare Menupunkte 
+ 
+   Wir wollen jetzt endlich unserer Absicht nachgehen,
+eine Datei vom Archiv zu holen. Dazu wechseln wir zuerst
+wieder zum Oberbegriff 'Archiv' in der Kopfzeile. Nach
+kurzer Zeit erscheint das Ihnen schon bekannte Pull-
+Down-Menu. Wenn Sie hier versuchen, die einzelnen Menu­
+punkte innerhalb des Pull-Down-Menus anzusteuern, so
+werden Sie feststellen, daß das nicht möglich ist. Alle
+Menupunkte, die ein Minuszeichen ('-') vor der Bezeichnung
+haben, können nicht angewählt werden. Diese Menupunkte
+sind zur Zeit nicht aktivierbar. Solche Menupunkte kön­
+nen in Menus häufiger auftreten. 
+   Das kann mehrere Ursachen haben: Einerseits könnte
+auf diese Weise ein Programmierer ein komplettes Menu
+entwerfen, das schon alle Funktionen zeigt, wenn auch die
+zugehörigen Programme dazu noch nicht fertig sind. Das
+ist aber in unserem Falle nicht so. Hier ist die Ursache
+eine andere: Bevor man im EUMEL-System auf das Archiv­
+laufwerk zugreifen kann, muß man es erst für sich re­
+servieren. Dadurch wird sichergestellt, daß nicht gleich­
+zeitig mehrere Benutzer auf eine Archivdiskette zugrei­
+fen und ggf. Dateien unbeabsichtigt zerstören. Erst wenn
+das Laufwerk reserviert worden ist, kann man auf die
+Diskette zugreifen. Das wird im Menu durch die nicht ak­
+tivierbaren Punkte zum Ausdruck gebracht. 
+ 
+ 
+-  Aktivieren von Menupunkten 
+ 
+   Wir müssen also zuerst das Archiv reservieren. Auch
+hier gibt es (zumeist) zwei Möglichkeiten, den gewünsch­
+ten Menupunkt zu aktivieren. Entweder Sie sorgen durch
+Bedienung der Pfeiltasten dafür, daß der gewünschte
+Menupunkt invers dargestellt wird und betätigen an­
+schließend die <RETURN>-Taste oder - sofern vor dem Me­
+nupunkt ein einzelner Buchstabe oder eine Ziffer aufge­
+listet ist - tippen Sie einfach auf die zugehörige Buch­
+staben- oder Zifferntaste. Tippen Sie hier die Taste <r>. 
+   Warten Sie einen Moment, denn es wird überprüft, ob
+das Laufwerk von einer anderen Task benutzt wird. Ist
+dies der Fall, erhalten Sie darüber auf dem Bildschirm
+eine Meldung. Ansonsten wird an Sie die Frage gerichtet,
+ob die Diskette eingelegt ist. Wenn diese Frage erscheint,
+befindet sich das Laufwerk schon "in Ihrem Besitz". Erst
+jetzt ist es sinnvoll, wenn auch andere auf das Laufwerk
+zugreifen können, die Diskette in das Laufwerk zu legen.
+Erst wenn die Frage auf dem Bildschirm erscheint, können
+Sie sicher sein, daß keine andere Task mehr auf das Lauf­
+werk zugreifen kann. Legen Sie also beim Erscheinen der
+Frage eine Ihrer EUMEL-Archivdisketten in das Laufwerk
+und bejahen Sie anschließend die gestellte Frage, indem
+Sie die Taste <j> tippen. (Sie können aber auch - wie schon
+in vorausgehenden Situationen - die Inversdarstellung
+innerhalb des Kastens, in dem die Frage auf dem Bild­
+schirm dargestellt wird, auf das 'Ja' positionieren und
+anschließend die <RETURN>-Taste tippen.) 
+   #on("b")#gs-DIALOG#off("b")# ermittelt jetzt den Namen der eingelegten
+Diskette und zeigt diesen im Kasten rechts unten auf dem
+Bildschirm an. Außerdem werden die zuvor nicht aktiver­
+baren Punkte aktivierbar gemacht. Das kann man daran
+erkennen, daß auf dem Bildschirm die Minuszeichen vor
+den betreffenden Menupunkten verschwinden (und Buch­
+staben sichtbar werden). 
+   Lassen Sie sich zunächst ein Inhaltsverzeichnis der
+Diskette anzeigen. Dazu brauchen Sie nur den Menupunkt
+'v Verzeichnis' wählen. Wie das gemacht wird wissen Sie ja
+schon. Sie können dabei beobachten, daß vor dem Menu­
+punkt das bisherige Zeichen verschwindet und ein Stern
+(*) sichtbar wird. Daran kann man erkennen, daß #on("b")#gs-DIALOG#off("b")#
+den Auftrag bereits ausführt. 
+   Es dauert einen Moment, bis das Verzeichnis erstellt
+ist - anschließend wird es auf dem Bildschirm ausgegeben.
+Paßt das Verzeichnis nicht vollständig auf den Bild­
+schirm, so können Sie sich darin bewegen, blättern etc.,
+wie Sie es aus dem Editor gewohnt sind. Ebenso wird das
+Verzeichnis auch wie der Editor verlassen - durch die
+Tastenfolge <ESC><q> (das wird übrigens auch auf dem
+Bildschirm angezeigt!). 
+ 
+ 
+-  Dateiauswahl 
+ 
+   Sie sollen jetzt eine Datei von der Archivdiskette in
+das System holen, d.h. genauer gesagt von der Diskette
+kopieren. Aktivieren Sie also auf gewohnte Weise den
+Menupunkt 'h Holen/Lesen'. Warten Sie anschließend einen
+Moment, denn #on("b")#gs-DIALOG#off("b")# erstellt eine Liste aller vorhan­
+denen Dateien auf der Diskette und bietet Sie Ihnen an­
+schließend so an, daß Sie komfortabel eine Auswahl tref­
+fen können. 
+   Haben Sie die #on("b")#gs-DIALOG#off("b")#-Archivdiskette eingelegt, so
+zeigt sich etwa der folgende Bildschirm: 
+ 
+ 
+#on("b")# 
+ARCHIV:  Dateien  Archiv 
+-------+-------------------------+-------------------------------------- 
+  +--------------------------------------------------------------------+ 
+  |                      Dateien holen/lesen (Archiv)                  | 
+  |                                                                    | 
+  |     Bitte alle Dateien ankreuzen, die 'geholt' werden sollen!      | 
+  |====================================================================| 
+  |   Auswahl   m e h r e r e r   Dateien durch Ankreuzen              | 
+  |....................................................................| 
+  |==>   o gs-DIALOG MENUKARTEN MANAGER"                               | 
+  |      o gs-DIALOG MM/gen                                            | 
+  |      o gs-DIALOG 1                                                 | 
+  |      o gs-DIALOG 2                                                 | 
+  |      o gs-DIALOG 3                                                 | 
+  |      o gs-DIALOG 4                                                 | 
+  |      o gs-DIALOG 5                                                 | 
+  |      o gs-DIALOG 6                                                 | 
+  |      o gs-DIALOG 7                                                 | 
+  |      o gs-MENUKARTE:Archiv                                         | 
+  |..................................................Weitere Dateien!..| 
+  +--------------------------------------------------------------------+ 
+--|Info: <?>  Fertig: <ESC><q>  Abbrechen: <ESC><h>                    | 
+In+--------------------------------------------------------------------+ 
+#off("b")# 
+ 
+ 
+   Auf dem Archiv sind mehrere Dateien vorhanden. Alle
+werden Ihnen zur Auswahl angeboten. In der obersten
+Zeile wird zur Kontrolle die Funktion angezeigt, die Sie
+gerade gewählt haben. Sie können jetzt die Dateien, auf
+die sich die Operation beziehen sollen, in beliebiger Rei­
+henfolge ankreuzen. Wenn Sie abschließend die Auswahl
+verlassen, werden die Dateien in der Ankreuzreihenfolge
+bearbeitet (hier in die Task geholt). 
+   Die Handhabung der Dateiauswahl ist ganz einfach. Der
+Pfeil gibt jeweils an, welche Datei aktuell behandelt
+wird. Zunächst wird vor den Namen jeweils nur ein 'o' aus­
+gegeben. Mit den Pfeiltasten <hoch> und <runter> können
+Sie nun mit dem Pfeil vor den Namen fahren, den Sie an­
+kreuzen möchten. Tippen Sie dann die Taste <x> oder
+<RETURN>, so erscheint in der Anzeige ein 'x' vor dem Na­
+men und eine Zahl, die angibt, die wievielte Datei Sie an­
+gekreuzt haben. Haben Sie sich versehen, so können Sie
+das Kreuz auch wieder löschen. Dazu fahren Sie einfach
+erneut vor den betreffenden Namen, wo ja jetzt ein 'x'
+steht, und tippen die Taste <o> (kleines 'o') oder <RUBOUT>.
+Dadurch wird das Kreuz entfernt und gegebenenfalls eine
+Umnumerierung der schon angekreuzten Dateinamen vor­
+genommen. Verlassen Sie jetzt die Auswahl mit der Tasten­
+folge <ESC><q>, so werden die Dateien nacheinander in der
+von Ihnen angekreuzten Reihenfolge in die Task kopiert. 
+   Neben dieser Auswahl, in der #on("u")#m e h r e r e#off("u")# Dateien an­
+gekreuzt (ausgewählt) werden können, gibt es auch eine
+Auswahl, in der nur jeweils #on("u")#e i n e#off("u")# Datei angekreuzt wer­
+den darf. Das ist durch die entsprechende Beschriftung
+auf dem Bildschirm kenntlich gemacht. In einem solchen
+Fall wird die Auswahl nach Ankreuzen eines Namens #on("u")#auto­
+matisch#off("u")# verlassen, d.h. man braucht nicht <ESC><q> zu tip­
+pen!. 
+   In einer Dateiauswahl können bis zu 200 Dateien ver­
+waltet werden. Da aber nicht alle Namen gleichzeitig auf
+dem Bildschirm angezeigt werden können, wird jeweils in
+der gepunkteten Zeile angezeigt, ob noch #on("u")#weitere Dateien#off("u")#
+in der Liste vorausgehen oder folgen. In unserem Beispiel
+geht als keine Datei voraus, es folgen aber noch weitere
+Dateien hinter der zuletzt angezeigten Datei. 
+   Damit Sie noch komfortabler mit dieser Dateiauswahl
+arbeiten können, gibt es weitere Tastenfolgen die nütz­
+lich sein können. Wenn Sie die Fragezeichentaste (<?>) tip­
+pen, werden Sie auf dem Bildschirm angezeigt. Durch Tip­
+pen irgendeiner weiteren Taste können Sie weiterblättern
+bzw. in die Auswahl zurückgelangen. Folgende Tastenkom­
+mandos stehen Ihnen zur Verfügung: 
+ 
+ 
+                     Positionierungen: 
+ 
+ hoch            : zum vorausgehenden Namen 
+ runter          : zum folgenden Namen 
+ HOP hoch        : auf den ersten Namen der Seite 
+ HOP runter      : auf den letzten Namen der Seite 
+ ESC 1           : auf den ersten Namen der Liste 
+ ESC 9           : auf den letzten Namen der Liste 
+ 
+ 
+                     Auswahl treffen: 
+ 
+ RETURN / x      : diesen Namen ankreuzen 
+(RUBOUT / o      : Kreuz vor dem Namen löschen   ) 
+(HOP RETURN/HOP x: alle folgenden Namen ankreuzen) 
+(HOP RUBOUT/HOP o: alle folgenden Namen löschen  ) 
+ 
+ 
+                     Auswahl verlassen: 
+ 
+ ESC q           : Auswahl verlassen 
+ ESC h           : Auswahl abbrechen 
+ 
+ 
+ 
+   Die in Klammern gesetzten Tastenfunktionen kann man
+nur verwenden, wenn die Auswahl #on("u")#mehrerer#off("u")# Dateien zuge­
+lassen ist. 
+   Wie Sie sehen, orientiert sich die Bedienung an den
+Tastenfunktionen, die Ihnen schon aus dem Editor be­
+kannt sind. Haben Sie aus Versehen einen Menupunkt ge­
+wählt, so daß Ihnen eine solche Auswahl angeboten wird,
+so können Sie die Auswahl durch <ESC><h> (für 'halt') ab­
+brechen. 
+ 
+ 
+-  Ja/Nein - Fragen 
+ 
+   An verschiedenen Stellen werden Fragen an Sie ge­
+richtet, die Sie mit 'ja' oder 'nein' beantworten müssen.
+Tippen Sie dazu entsprechend je nach Entscheidung die
+Taste <j> (für 'ja') bzw. <n> (für 'nein'). 
+ 
+ 
+-  Eingaben 
+ 
+   An einigen Stellen werden Sie aufgefordert, eine Ein­
+gabe zu machen (z.B. einen Dateinamen einzugeben). Sofern
+möglich wird Ihnen auch ein Vorschlag für die Eingabe
+gemacht (z.B. wenn Sie Dateien kopieren oder umbenennen
+wollen). Wenn Sie den gemachten Vorschlag akzeptieren,
+dann brauchen Sie zur Bestätigung nur die <RETURN>-
+Taste zu tippen. 
+   Gefällt Ihnen der Vorschlag nicht oder wird Ihnen
+kein Vorschlag gemacht, so machen Sie bitte die ge­
+wünschte Angabe. Zum Schreiben stehen Ihnen alle aus dem
+Editor bekannten Funktionen zur Verfügung. Mit der
+Taste <RUBOUT> können Sie Buchstaben löschen, mit
+<RUBIN> einfügen. Die Eingabe wird durch Tippen der
+<RETURN>-Taste abgeschlossen. 
+   Ist der von Ihnen gewünschte Name schon in Ihrer Task
+vorhanden und steht in der Fußzeile der Hinweis 'Zeigen:
+<ESC><z>', dann können Sie sich auch alle vorhandenen
+Namen zur Auswahl anbieten lassen und durch Ankreuzen
+den beabsichtigten Namen auswählen. 
+ 
+ 
+-  Alternativen 
+ 
+   Ihnen können auch mehrere Alternativen angeboten
+werden, zwischen denen Sie wählen müssen. In der unter­
+sten Zeile eines solchen Kastens, in denen Ihnen die Al­
+ternativen auf dem Bildschirm eingeblendet werden, sind
+die Möglichkeiten aufgeführt, die darüber beschreiben
+sind. Mit den Pfeiltasten können sie die Markierung auf
+die gewünschte Alternative positionieren und dann durch
+die <RETURN>-Taste zur Ausführung bringen. (Manchmal
+ist das auch durch Tippen der den Alternativen vorange­
+stellten Buchstaben oder Ziffern möglich). 
+ 
+ 
+-  Verlassen des Menus 
+ 
+   Das Menu kann insgesamt mit der Tastenfolge <ESC><q>
+verlassen werden. Damit das nicht versehentlich ge­
+schieht, wird zur Sicherheit die Frage gestellt, ob Sie das
+Menu tatsächlich verlassen wollen. Verneinen Sie die
+Frage, verbleiben Sie im Menu, ansonsten gelangen Sie
+zurück in die 'gib kommando:' - Ebene. 
+ 
+   Mit dieser Beispielsitzung haben Sie jetzt schon fast
+alle Arten des Umgangs mit #on("b")#gs-DIALOG#off("b")# kennengelernt.
+Sicher ist dies beim ersten Mal sehr verwirrend. Mit den
+folgenden vier grundsätzlichen Regeln können Sie
+#on("b")#gs-DIALOG#off("b")# aber immer bedienen: 
+ 
+  1.  Achten Sie darauf, welche Tastenkombinationen in
+      der Fußzeile angegeben sind. Halten Sie sich daran! 
+ 
+  2.  Rufen Sie - sofern vorhanden - die Hilfsfunktio­
+      nen mit <?> oder <ESC><?> auf. Damit erhalten Sie
+      weitere Informationen. 
+ 
+  3.  Funktioniert eine Tastenkombination nicht (geben
+      Sie dem Rechner eine kurze Zeit zum Reagieren),
+      versuchen Sie die Tastenkombination <ESC><q> (Ver­
+      lassen) oder <ESC><h> (Abbruch). Falls sich darauf­
+      hin etwas ändert, verfahren Sie wie unter 1). 
+ 
+  4.  Erfolgt noch immer keine Reaktion, tippen Sie die
+      <SV>-Taste und versuchen Sie das Programm mit
+      'halt' zu stoppen. Führt auch das nicht zum Erfolg,
+      hat sich der Rechner "aufgehängt". Wenn Sie keine
+      Erfahrungen mit einer solchen Situation haben,
+      wenden Sie sich an Ihren Systembetreuer. 
+ 
+ 
+3.3  Zusammenfassung/Kurzbeschreibung 
+ 
+Menu:          Sie können jede (aktive) Funktion inner­
+               halb eines Pull-Down-Menus mit den
+               Pfeiltasten anwählen und durch Tippen
+               der <RETURN>-Taste zur Ausführung
+               bringen. (Ersatzweise kann - sofern vor
+               dem Menupunkt ein Buchstabe oder eine
+               Ziffer angegeben ist - die Funktion
+               durch Tippen der entsprechenden Taste
+               direkt zur Ausführung gebracht werden.)
+               Zu jeder Funktion kann durch Tippen der
+               Fragezeichentaste eine Hilfestellung
+               angefordert werden. Gibt man die Tasten­
+               folge <ESC><?>, so wird die Bedienung des
+               Menus auf dem Bildschirm kurz erläutert.
+               Mit der Tastenfolge <ESC><q> wird das
+               Menu (nach einer Sicherheitsabfrage)
+               verlassen. 
+ 
+Dateiauswahl:  Hier können Sie die gewünschten Namen
+               mit <x> ankreuzen und das Kreuz mit <o>
+               wieder entfernen. Die Auswahl - sofern
+               mehrere Dateien ausgewählt werden kön­
+               nen - wird durch die Tastenfolge
+               <ESC><q> verlassen. Alle Möglichkeiten
+               der Bedienung werden angezeigt, wenn die
+               Fragezeichentaste getippt wird. Die Aus­
+               wahl wird abgebrochen (ohne Kreuze!),
+               wenn die Tastenfolge <ESC><h> eingege­
+               ben wird. 
+ 
+Eingabe:       Hier können Sie eine Zeile eingeben oder
+               eine Vorgabe ändern (wie im Editor). Ein­
+               fügen und Löschen mit RUBIN und RUBOUT.
+               Ist in der Fußzeile die Tastenfolge
+               '<ESC><z>: Zeigen' angegeben, so können
+               Sie darüber auch eine Auswahl anfor­
+               dern, in der Sie bereits vorhandene Na­
+               men nur anzukreuzen brauchen. Zumeist
+               ist auch ein Abbruch der Eingabe durch
+               die Tastenfolge <ESC><h> möglich. 
+ 
+Frage:         Beantworten Sie die an Sie gerichtete
+               Frage mit <j> oder <n>. Sie können auch
+               auf dem Bildschirm die Markierung auf
+               die gewünschte Antwort setzten und an­
+               schließend die <RETURN>-Taste tippen. 
+ 
+Alternativen:  Aus den angegebenen Möglichkeiten kön­
+               nen Sie eine auswählen, indem Sie entwe­
+               der die der Alternative vorangestellte
+               Taste tippen oder in der letzten Zeile des
+               Kastens die Markierung auf die ge­
+               wünschte Kennzeichnung positionieren
+               und anschließend die <RETURN>-Taste
+               tippen. 
+ 
+Fehler:        Die Meldung muß durch Tippen einer be­
+               liebigen Taste quittiert werden. 
+ 
+Bitte warten:  Der Rechner ist beschäftigt - keine
+               Taste tippen! 
+ 
+
diff --git a/doc/dialog/gs-dialog-4 b/doc/dialog/gs-dialog-4
new file mode 100644
index 0000000..03d8dc4
--- /dev/null
+++ b/doc/dialog/gs-dialog-4
@@ -0,0 +1,672 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (30)# 
+#headodd# 
+#center#gs-DIALOG#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-DIALOG 
+ 
+#end# 
+#center#4 
+ 
+#center#Beschreibung der Menufunktionen 
+ 
+ 
+4.1  Menufunktionen zum Oberbegriff  'Dateien' 
+ 
+   In diesem Kapitel werden alle die Menufunktionen be­
+schrieben, die Ihnen unter dem Obergeriff 'Dateien' im
+Menu angeboten werden. 
+ 
+#on("u")##on("b")#v Verzeichnis#off("b")##off("u")# 
+      Mit dieser Funktion können Sie sich einen Über­
+   blick über die in Ihrer Task vorhandenen Dateien ver­
+   schaffen. 
+      Nach Aufruf dieser Funktion wird eine Liste der
+   Dateien auf dem Bildschirm ausgegeben, die sich in
+   Ihrer Task befinden. Da die Liste selbst eine Datei ist,
+   kann sie mit der Tastenkombination <ESC><q> verlassen
+   werden - hierauf wird auch in der Kopfzeile der Datei
+   hingewiesen. Falls nicht alle Dateien auf den Bild­
+   schirm passen, können Sie das Fenster mit <HOP><hoch>
+   bzw. <HOP><runter> rollen. 
+ 
+#on("u")##on("b")#l Löschen#off("b")##off("u")# 
+      Mit dieser Funktion können Sie Dateien, die Sie
+   nicht mehr benötigen, die unnötig Platz belegen, lö­
+   schen. Aber Vorsicht! Die Dateien verschwinden durch
+   diese Funktion unwiederbringlich! 
+      Zunächst wird der Dateiname der Datei erfragt, die
+   gelöscht werden soll. Hier können Sie direkt den be­
+   treffenden Namen eingeben und die Eingabe mit
+   <RETURN> abschließen. Sie können sich aber auch durch
+   die Tastenfolge <ESC><z> (für 'zeigen') alle in der Task
+   vorhandenen Dateien zur Auswahl anbieten lassen und
+   dort einfach einen Namen ankreuzen. 
+     Für jede einzelne Datei wird noch einmal zur
+   Sicherheit angefragt, ob diese auch tatsächlich ge­
+   löscht werden soll. Zur Bestätigung tippen Sie bitte
+   die Taste <j> ('ja') - zur Verhinderung die Taste <n>
+   ('nein'). 
+ 
+   Fehlerfälle: 
+   -  Eine Datei mit dem angegebenen Namen existiert
+      nicht. 
+ 
+#on("u")##on("b")#d Drucken#off("b")##off("u")# 
+     Mit dieser Funktion können Sie Dateien über einen
+   angeschlossenen Drucker ausdrucken lassen. 
+     Zunächst wird der Dateiname der Datei erfragt, die
+   gedruckt werden soll. Hier können Sie direkt den be­
+   treffenden Namen eingeben und die Eingabe mit
+   <RETURN> abschließen. Sie können sich aber auch durch
+   die Tastenfolge <ESC><z> (für 'zeigen') alle in der Task
+   vorhandenen Dateien zur Auswahl anbieten lassen und
+   dort einfach einen Namen ankreuzen. 
+     Die Datei(en) wird/werden anschließend zum Drucker
+   geschickt. Der Vorgang wird auf dem Bildschirm proto­
+   kolliert. 
+ 
+   Fehlerfälle: 
+   -  Eine Datei mit dem angegebenen Namen existiert
+      nicht. 
+   -  Die Druckdatei hat einen falschen Typ zum Drucken
+      (ist nicht editierbar). 
+   -  Der Drucker ist nicht funktionsbereit. 
+   -  Der Drucker wird nicht über die Task 'PRINTER' be­
+      trieben. 
+   -  Auf Ihrem System werden die Druckkosten abge­
+      rechnet. Sie müssen sich mit einer Codenummer
+      identifizieren. 
+ 
+#on("u")##on("b")#k Kopieren#off("b")##off("u")# 
+      Mit dieser Funktion können Sie sich eine (logische)
+   Kopie einer bereits im System vorhandenen Datei anle­
+   gen. Das ist z.B. dann sinnvoll, wenn Sie sich einen
+   bestimmten Stand einer Datei aufbewahren wollen. 
+      Zunächst wird der Dateiname der Datei erfragt, die
+   kopiert werden soll. Hier können Sie direkt den be­
+   treffenden Namen eingeben und die Eingabe mit
+   <RETURN> abschließen. Sie können sich aber auch durch
+   die Tastenfolge <ESC><z> (für 'zeigen') alle in der Task
+   vorhandenen Dateien zur Auswahl anbieten lassen und
+   dort einfach einen Namen ankreuzen. 
+      Anschließend wird dieser Name angezeigt und der
+   Name für die Kopie erfragt. Es muß ein Name eingetra­
+   gen werden, der in dieser Task noch nicht für eine
+   Datei vergeben wurde; ansonsten erfolgt ein Hinweis
+   darauf und es wird nicht kopiert! 
+      Da man aber oft für die Kopie einen ähnlichen Na­
+   men wie für das Original wählt, wird der 'alte' Name
+   vorgeschlagen. Aus genannten Gründen muß er aber
+   verändert werden. Sie können diesen Namen mit den
+   üblichen Editierfunktionen verändern oder mit
+   <HOP><RUBOUT> löschen und ganz neu eingeben. Auf
+   diese Weise sparen Sie aber eine Menge Tipparbeit,
+   wenn Sie einen langen Namen nur an einer Stelle än­
+   dern wollen. 
+ 
+   Fehlerfälle: 
+   -  Eine Datei mit dem angegebenen Namen existiert
+      nicht. 
+   -  Eine Datei mit dem gewünschten Namen existiert
+      bereits in der Task. 
+ 
+#on("u")##on("b")#u Umbenennen#off("b")##off("u")# 
+      Mit dieser Funktion können Sie einer bereits vor­
+   handenen Datei einen neuen Namen geben. 
+      Zunächst wird der Dateiname der Datei erfragt, die
+   umbenannt werden soll. Hier können Sie direkt den
+   betreffenden Namen eingeben und die Eingabe mit
+   <RETURN> abschließen. Sie können sich aber auch durch
+   die Tastenfolge <ESC><z> (für 'zeigen') alle in der Task
+   vorhandenen Dateien zur Auswahl anbieten lassen und
+   dort einfach einen Namen ankreuzen. 
+      Anschließend wird dieser Name angezeigt und der
+   zukünftige Name für die Datei erfragt. Es muß ein
+   Name eingetragen werden, der in dieser Task noch
+   nicht für eine Datei vergeben wurde; ansonsten er­
+   folgt ein Hinweis darauf und die Datei wird nicht
+   umbenannt! 
+      Da man aber oft den 'neuen' Namen in Anlehnung an
+   den 'alten' Namen wählt, wird der 'alte' Name vorge­
+   schlagen. Aus genannten Gründen muß er aber verän­
+   dert werden. Sie können diesen Namen mit den üblichen
+   Editierfunktionen verändern oder mit <HOP><RUBOUT>
+   löschen und ganz neu eingeben. Auf diese Weise sparen
+   Sie aber eine Menge Tipparbeit, wenn Sie einen langen
+   Namen nur an einer Stelle ändern wollen. 
+ 
+   Fehlerfälle: 
+   -  Eine Datei mit dem angegebenen Namen existiert
+      nicht. 
+   -  Eine Datei mit dem gewünschten Namen existiert
+      bereits in der Task. 
+ 
+#on("u")##on("b")#s Speicherplatz#off("b")##off("u")# 
+      Mit dieser Funktionen können Sie sich zu Ihrer
+   Information den Speicherbedarf anzeigen lassen, den
+   eine Datei auf dem Speichermedium einnimmt. 
+      Zunächst wird der Dateiname der Datei erfragt,
+   deren Speicherplatz ermittelt werden soll. Hier kön­
+   nen Sie direkt den betreffenden Namen eingeben und
+   die Eingabe mit <RETURN> abschließen. Sie können sich
+   aber auch durch die Tastenfolge <ESC><z> (für 'zeigen')
+   alle in der Task vorhandenen Dateien zur Auswahl
+   anbieten lassen und dort einfach einen Namen ankreu­
+   zen. 
+      Anschließend wird der belegte Speicherplatz der
+   ausgewählten Datei(en) auf dem Bildschirm angezeigt.
+   Die Größe wird in KB (Kilobyte) angegeben. Ein KB ent­
+   spricht etwa 1000 Zeichen, also einer halb vollge­
+   schriebenen Bildschirmseite. 
+ 
+   Fehlerfälle: 
+   -  Eine Datei mit dem angegebenen Namen existiert
+      nicht. 
+ 
+#on("u")##on("b")#a Aufräumen#off("b")##off("u")# 
+      Wenn in einer Datei viel geändert wurde, wird der
+   Platzbedarf dieser Datei erheblich vergrößert ("Text­
+   leichen"). Dies tritt vor allem dann auf, wenn sehr
+   häufig eingefügt wurde. Da der Platzbedarf der Datei
+   zunimmt, sind mehr Speicherzugriffe notwendig, als es
+   dem Inhalt entspricht. Zudem führt die interne Orga­
+   nisation einer solchen Datei zu Einbußen bei der Bear­
+   beitungsgeschwindigkeit. 
+      Mit dieser Funktion wird die Datei in eine "fri­
+   sche" Datei gewandelt. Diesen Vorgang nennt man 'Re­
+   organisieren' (Aufräumen). Anschließend belegt die
+   Datei zumeist (erheblich) weniger Speicherplatz als
+   zuvor. 
+      Diese Funktion ist allerdings nur mit einer Ein­
+   schränkung nutzbar. Sie läßt sich nur auf Textdateien
+   anwenden, nicht auf andere Dateitypen. Das System
+   nimmt aber die Unterscheidung in Dateitypen automa­
+   tisch vor - allerdings kann es vorkommen, daß Sie den
+   Hinweis erhalten: "... kann nicht aufgeräumt werden!". 
+      Zunächst wird der Dateiname der Datei erfragt, die
+   aufgeräumt (reorganisiert werden soll. Hier können
+   Sie direkt den betreffenden Namen eingeben und die
+   Eingabe mit <RETURN> abschließen. Sie können sich
+   aber auch durch die Tastenfolge <ESC><z> (für 'zeigen')
+   alle in der Task vorhandenen Dateien zur Auswahl
+   anbieten lassen und dort einfach einen Namen ankreu­
+   zen. 
+      Anschließend wird/werden die ausgewählte(n) Da­
+   tei(en) aufgeräumt (reorganisert). #on("u")#Achtung! Die Funk­
+   tion ist zeitaufwendig!#off("u")# 
+ 
+   Fehlerfälle: 
+   -  Eine Datei mit dem angegebenen Namen existiert
+      nicht. 
+#page# 
+4.2  Menufunktionen zum Oberbegriff  'Archiv' 
+ 
+   In diesem Kapitel werden alle die Menufunktionen be­
+schrieben, die Ihnen unter dem Oberbegriff 'Archiv' im
+Menu angeboten werden. Mit den Funktionen in diesem
+Menu können Sie aber nicht nur Dateien auf dem Archiv
+behandeln, sondern auch in anderen Tasks im Multi-
+User-System oder über das EUMEL-Netz sogar auf anderen
+Rechnern! 
+   Wenn Sie das Pull-Down-Menu (siehe Seite 12) gerade
+aufgeschlagen haben, sind nicht alle Funktionen akti­
+vierbar! Um weitere Funktionen zu aktivieren, muß erst
+einer der aktivierbaren Menupunkte ausgeführt werden. 
+ 
+#on("u")##on("b")#r Reservieren#off("b")##off("u")# (des Archivlaufwerks) 
+      Im EUMEL-Multi-User-System haben normalerweise
+   mehrere Personen das Zugriffsrecht auf das Archiv­
+   laufwerk. Allerdings muß der Zugriff so geregelt wer­
+   den, daß sich die Beteiligten dabei nicht gegenseitig
+   "in die Quere kommen". Ein Zugriff auf das Archiv­
+   laufwerk erfordert zunächst eine Anmeldung. Ist diese
+   Anmeldung erfolgt, kann von den anderen Beteiligten
+   nicht mehr auf das Laufwerk zugegriffen werden - bis
+   es wieder freigegeben worden ist. 
+      Diese Anmeldung des Archivlaufwerkes erfolgt
+   über die Menufunktion 'r Reservieren'. Greift bereits
+   eine andere Task auf das Laufwerk zu, so erhalten Sie
+   darüber einen Hinweis auf dem Bildschirm. Ansonsten
+   wird an Sie die Frage gestellt, ob die Diskette einge­
+   legt und das Laufwerk geschlossen ist. 
+      Erst zu diesem Zeitpunkt ist sichergestellt, daß Sie
+   den alleinigen Zugriff auf das Laufwerk haben. Des­
+   halb sollten Sie, wenn Sie mit mehreren Personen am
+   Computer arbeiten, erst zum Zeitpunkt der Fragestel­
+   lung die Diskette ins Laufwerk einlegen. 
+      Nachdem Sie die Diskette eingelegt und die Frage
+   bejaht haben, ermittelt das System selbständig den
+   Namen der eingelegten Diskette, zeigt den Namen auf
+   dem Bildschirm (im kleinen Kasten rechts unten) an und
+   aktiviert die anderen Menupunkte des Pull-Down-
+   Menus. 
+      #on("u")#Beim Verlassen des Pull-Down-Menus, wenn eine
+   andere Zieltask eingestellt wird oder wenn das Menu
+   gänzlich verlassen wird, wird die Reservierung auto­
+   matisch aufgehoben!#off("u")# 
+ 
+   Fehlerfälle: 
+   -  Das Laufwerk ist von einer anderen Task belegt. 
+   -  Die Diskette ist falsch eingelegt oder das Lauf­
+      werk ist nicht richtig geschlossen. 
+   -  Die Diskette ist nicht formatiert bzw. initiali­
+      siert. 
+   -  Die Diskette kann nicht gelesen werden (keine
+      EUMEL-Diskette, Diskette hat ein falsches Format,
+      Diskette ist verschmutzt...). 
+ 
+#on("u")##on("b")#n Neue Diskette#off("b")##off("u")# (anmelden) 
+      Der Dateiaustausch mit einer Diskette ist nur dann
+   möglich, wenn der im System eingestellte Diskettenna­
+   me (auf dem Bildschirm im kleinen Kasten unten rechts
+   sichtbar) mit dem tatsächlichen Namen der Diskette
+   übereinstimmt. Nach einem Diskettenwechsel ist das
+   aber in der Regel nicht mehr der Fall. Greift man dann
+   auf die neu eingelegte Diskette zu, so erscheint die
+   Fehlermeldung: 'Falscher Archivname! Bitte neue Dis­
+   kette anmelden!'. 
+      Das Anmelden einer neuen Diskette - ohne einen
+   neuen Reserviervorgang - wird durch diese Menufunk­
+   tion ermöglicht. Nach Aktivieren dieses Menupunktes
+   wird der Name der eingelegten Diskette ermittelt, im
+   System eingestellt und auf dem Bildschirm angezeigt. 
+      Im Gegensatz zur Menufunktion 'r Reservieren'
+   greift #on("b")#gs-DIALOG#off("b")# ohne Anfrage an den Benutzer auf
+   das Archivlaufwerk zu (die Reservierung bleibt ja
+   bestehen). Ist das Archivlaufwerk reserviert, so ist
+   die Neuanmeldung einer Diskette über diese Menufunk­
+   tion weniger zeitaufwendig. 
+ 
+   Fehlerfälle: 
+   -  wie unter 'r Reservieren' 
+ 
+#on("u")##on("b")#s Schreiben#off("b")##off("u")# (Kopieren) 
+      Alle Dateien der eigenen Task werden zur Auswahl
+   angeboten. Wenn Sie die Auswahl durch die Tastenfolge
+   <ESC><q> verlassen, überprüft #on("b")#gs-DIALOG#off("b")# zunächst, ob
+   die Dateien in der eingestellten Zietask schon vor­
+   handen sind. Ist das der Fall, erfragt #on("b")#gs-DIALOG#off("b")#, ob
+   die dort vorhandenen Dateien überschrieben, d.h. ge­
+   löscht werden dürfen (s.u.). Anschließend werden alle
+   angekreuzten Dateien in der Reihenfolge, in der Sie
+   sie angekreuzt haben, in die eingestellte Zieltask
+   kopiert. Der Vorgang wird auf dem Bildschirm proto­
+   kolliert. Die Originaldateien in der eigenen Task
+   bleiben dabei erhalten. 
+      Wenn in der Zieltask schon eine Datei existiert, die
+   den gleichen Namen hat wie eine Datei, die Sie dorthin
+   kopieren möchten, so wird angefragt, ob die vorher
+   schon existierende Datei überschrieben (gelöscht!)
+   werden soll. Bejahen Sie diese Frage, so wird die be­
+   reits in der Zieltask existierende Datei (unwieder­
+   bringlich) gelöscht und die gewünschte Datei dorthin
+   transportiert. Ein Überschreiben aus Versehen ist
+   nicht möglich, wenn Sie die an Sie gestellte Frage
+   sorgfältig beantworten. 
+      Verneinen Sie die Frage, so wird die Datei auch
+   nicht hinübertransportiert! Sie können die Datei aber
+   umbenennen (Menufunktion 'u Umbenennen' unter dem
+   Oberbegriff 'Dateien') und anschließend mit anderem
+   Namen hinüberschreiben. 
+      Beachten Sie, daß beim Überschreiben einer Datei
+   auf einer Archivdiskette der Speicherplatz der alten
+   (überschriebenen) Version im allgemeinen nicht wie­
+   derverwendet werden kann. In einem solchen Fall
+   könnte die Diskette voll geschrieben werden, obwohl
+   eigentlich genügend Platz vorhanden wäre. Zur Opti­
+   mierung überprüft #on("b")#gs-DIALOG#off("b")# deshalb zuerst, ob die
+   angekreuzten Dateien schon in der Zieltask vorhanden
+   sind und löscht diese, wenn Sie Ihr Einverständnis
+   geben. Erst anschließend werden die Dateien insgesamt
+   kopiert. 
+      Normalerweise ist als Zieltask das Archivlaufwerk
+   der eigenen Station eingestellt. Mit der Menufunktion
+   'z Zieltask einstellen' kann diese Einstellung aber
+   verändert werden. 
+ 
+   Fehlerfälle: 
+   -  Die Diskette ist falsch eingelegt oder beschädigt. 
+   -  Die Diskette kann nicht beschrieben werden
+      (Schreibfehler) 
+   -  Die Diskette ist voll. 
+   -  Sehen Sie auch unter  'r Reservieren' 
+                            'z Zieltask einstellen' 
+ 
+#on("u")##on("b")#c Checken#off("b")##off("u")# 
+      Diese Menufunktion kann nur ausgeführt werden,
+   wenn der Dateiaustausch mit einem Archiv(manager)
+   erfolgt - ansonsten ist diese Menufunktion auch
+   nicht aktivierbar. Die Menufunktion dient dazu, auf
+   Diskette geschriebene Dateien auf Lesefehler hin zu
+   prüfen. Es empfiehlt sich, diese Prüfroutine auf neu
+   auf die Diskette geschriebene Dateien anzuwenden.
+   Sehen Sie dazu auch 'k Kombination' 
+      Alle Dateien der eingestellten Zieltask (Archiv)
+   werden zur Auswahl angeboten. Wenn Sie die Auswahl
+   durch die Tastenfolge <ESC><q> verlassen, werden alle
+   angekreuzten Dateien in der Reihenfolge, in der Sie
+   sie angekreuzt haben, "gecheckt", d.h. auf Lesefehler
+   hin überprüft. Der Vorgang wird auf dem Bildschirm
+   protokolliert. 
+ 
+   Fehlerfälle: 
+   -  Lesefehler auf dem Archiv 
+   -  Sehen Sie auch unter  'r Reservieren' 
+ 
+#on("u")##on("b")#k Kombination#off("b")##off("u")# 
+      Diese Menufunktion ist eine Kombination aus den
+   beiden Menufunktionen 's Schreiben' und 'c Checken'
+   (Sehen Sie weitere Informationen auch dort!). 
+      Alle Dateien der eigenen Task werden zur Auswahl
+   angeboten. Wenn Sie die Auswahl durch die Tastenfolge
+   <ESC><q> verlassen, werden alle angekreuzten Dateien
+   in der Reihenfolge, in der Sie sie angekreuzt haben,
+   in die eingestellte Zieltask kopiert (gegebenenfalls
+   müssen bereits vorhandene Dateien gleichen Namens in
+   der Zieltask gelöscht werden). Anschließend werden
+   alle Dateien, die gerade geschrieben wurden, gecheckt,
+   d.h. auf Lesefehler hin untersucht. Beide Vorgänge
+   werden auf dem Bildschirm protokolliert. 
+      Da die 'Check' - Operation nur bei Archivmanagern
+   zulässig ist, ist diese Menufunktion ebenfalls nur bei
+   Archivmanagern aktivierbar. Zur Erläuterung sehen
+   Sie bitte auch unter 'z Zieltask einstellen'. 
+ 
+#on("u")##on("b")#h Holen/Lesen#off("b")##off("u")# 
+      Die Menufunktion dient dazu, Dateien, die bereits
+   auf einer Archivdiskette oder in einer anderen Task
+   existieren, in die eigene Task zu kopieren. 
+      Alle Dateien der eingestellten Zieltask werden zur
+   Auswahl angeboten. Anschließend werden Kopien der
+   angekreuzten Dateien in der Reihenfolge des Ankreu­
+   zens in die eigene Task geholt. Das Original in der
+   Zieltask bleibt dabei unverändert! Der Vorgang wird
+   auf dem Bildschirm protokolliert. 
+      Sind in der eigenen Task schon Dateien mit glei­
+   chem Namen vorhanden, so wird gefragt, ob die 'alten'
+   Dateien überschrieben (gelöscht) werden dürfen. Nur
+   wenn Sie zustimmen, werden die in Ihrer Task existie­
+   renden Dateien (unwiederbringlich!) gelöscht und Ko­
+   pien der gleichnamigen Dateien aus der Zieltask ange­
+   fertigt. 
+      Stimmen Sie dem Löschvorgang nicht zu, dann blei­
+   ben die bisherigen Dateien in Ihrer Task erhalten -
+   die Dateien aus der Zieltask werden dann aber auch
+   nicht in Ihre Task kopiert! Um dennoch die Kopien zu
+   erhalten, können Sie die namensgleichen Dateien in
+   Ihrer Task umbenennen und dann erst die Dateien aus
+   der anderen Task anfordern. 
+      Normalerweise werden die Dateien vom Archiv der
+   eigenen Station geholt. Mit dem Menupunkt 'z Zieltask
+   einstellen' kann diese Einstellung verändert werden. 
+ 
+   Fehlerfälle: 
+   -  Lesefehler auf dem Archiv 
+   -  Sehen Sie auch unter  'r Reservieren' 
+                            's Schreiben' 
+                            'z Zieltask einstellen' 
+ 
+#on("u")##on("b")#l Löschen#off("b")##off("u")# 
+      Die Menufunktion dient dazu, Dateien in der Ziel­
+   task (unwiederbringlich!) zu löschen. Dazu werden alle
+   Dateien der eingestellten Zieltask zur Auswahl ange­
+   boten. Anschließend werden die angekreuzten Dateien
+   in der Reihenfolge ihres Ankreuzens gelöscht. Zur
+   Sicherheit muß noch einmal für jede einzelne Datei
+   bestätigt werden, daß sie auch tatsächlich gelöscht
+   werden soll. 
+      Beachten Sie, daß beim Löschen einer Datei auf ei­
+   ner Archivdiskette der Speicherplatz im allgemeinen
+   nicht wieder verwendet werden kann. In einem solchen
+   Fall könnte die Diskette voll geschrieben werden,
+   obwohl eigentlich genügend Platz vorhanden wäre.
+   Diese Probleme treten bei anderen Tasks, die keine
+   Archivmanager sind, nicht auf, da deren Speicherplatz
+   intelligenter verwaltet wird. 
+      Normalerweise ist als Zieltask das Archiv der eige­
+   nen Station eingestellt. Mit dem Menupunkt 'z Zieltask
+   einstellen' kann diese Einstellung verändert werden. 
+ 
+   Fehlerfälle: 
+   -  Sehen Sie auch unter  'r Reservieren' 
+                            's Schreiben' 
+                            'z Zieltask einstellen' 
+ 
+#on("u")##on("b")#v Verzeichnis#off("b")##off("u")# 
+      Mit dieser Menufunktion können Sie sich einen
+   Überblick über die in der Zieltask (z.B. auf dem Archiv)
+   vorhandenen Dateien verschaffen. 
+      Nach Aufruf der Funktion wird eine Liste der Da­
+   teien auf dem Bildschirm ausgegeben, die sich in der
+   Zieltask (z.B. auf dem Archiv) befinden. Ist die Zieltask
+   ein Archiv(manager), so wird auch angezeigt, wieviel
+   Platz auf der Diskette belegt ist. Da die Liste selbst
+   eine Datei ist, kann sie mit der Tastenkombination
+   <ESC><q> verlassen werden. Falls nicht alle Dateinamen
+   auf den Bildschirm passen, können Sie das Fenster mit
+   <HOP><hoch> und <HOP><runter> rollen. 
+ 
+   Fehlerfälle: 
+   -  Sehen Sie unter  'z Zieltask einstellen' 
+ 
+#on("u")##on("b")#d Drucken#off("b")##off("u")# 
+      Das Verzeichnis der Dateien in der Zieltask, das
+   man mit der Menufunktion 'v Verzeichnis' auf dem Bild­
+   schirm angezeigt bekommt, kann mit dieser Menufunk­
+   tion ausgedruckt werden. 
+      Zur Sicherheit fragt #on("b")#gs-DIALOG#off("b")# an, ob wirklich ein
+   solches Dateiverzeichnis der Zieltask gedruckt werden
+   soll. Bejaht man die Frage, so wird ein Dateiverzeich­
+   nis erstellt und zum Drucker geschickt. 
+ 
+   Fehlerfälle: 
+   -  Der Drucker ist nicht funktionsbereit. 
+   -  Der Drucker wird nicht über die Task 'PRINTER' be­
+      trieben. 
+   -  Auf Ihrem System werden die Druckkosten abge­
+      rechnet. Sie müssen sich mit einer Codenummer
+      identifizieren. 
+ 
+#on("u")##on("b")#i Initialisieren#off("b")##off("u")# 
+      Diese Menufunktion gestattet es, frische Disketten
+   zu formatieren, zu initialisieren bzw. beschriebene
+   Disketten vollständig zu löschen und ggf. dabei umzu­
+   benennen. Bei Aufruf dieser Menufunktion wird - so­
+   fern noch nicht geschehen - das Archivlaufwerk auto­
+   matisch reserviert. 
+      Wenn Sie eine fabrikneue Diskette aus der Verpak­
+   kung nehmen, müssen Sie diese zunächst #on("u")#formatieren#off("u")#.
+   Dabei wird die Diskette auf ein festgelegtes physika­
+   lisches Format eingestellt. Ohne daß diese Operation
+   vorausgegangen ist, kann eine Diskette weder be­
+   schrieben noch gelesen werden. 
+      Prinzipiell braucht eine Diskette nur ein einziges
+   Mal formatiert zu werden. Sie können Sie jedoch jeder­
+   zeit wieder formatieren - z.B. wenn Sie Disketten ha­
+   ben, von denen Sie nicht genau wissen, für welche
+   Zwecke sie zuvor verwendet wurden. 
+      Wenn Sie diese Menufunktion aktivieren, werden Sie
+   zunächst gefragt, ob Sie die Diskette auch formatie­
+   ren wollen. Bejahen Sie die Frage, so werden Ihnen
+   mehrere Formate zur Auswahl angeboten: 
+ 
+#on ("b")# 
+             +------------------------------------+ 
+             |     Formatieren einer Diskette     | 
+             |                                    | 
+             |  Dies sind die möglichen Formate:  | 
+             |                                    | 
+             |     1 ..... 40 Spur   -  360 KB    | 
+             |     2 ..... 80 Spur   -  720 KB    | 
+             |     3 ..... 5 1/4"    -  1,2 MB    | 
+             |     4 ..... 3 1/2"    -  1,4 MB    | 
+             |     s ..... Standard  -  Format    | 
+             |                                    | 
+             |         1   2   3   4   s          | 
+             +------------------------------------+ 
+#off("b")# 
+ 
+      Erkundigen Sie sich bei Ihrem Händler, welches
+   Format Sie bei Ihrem Rechner und den von Ihnen ver­
+   wendeten Disketten einstellen müssen. Manche Rechner
+   unterstützen diese Operation innerhalb des EUMEL-
+   Systems auch gar nicht, das Formatieren muß dann ir­
+   gendwie anders außerhalb des EUMEL-Systems gesche­
+   hen. 
+      Wenn Sie die Formatierung abgeschlossen oder auch
+   übersprungen haben, beginnt die eigentliche Initiali­
+   sierung der Diskette. Dabei wird als erstes der Ar­
+   chivname auf die Diskette geschrieben. Alle alten Da­
+   ten, die sich ggf. auf der Diskette befinden, werden
+   auch bei diesem Vorgang unwiederbringlich (!) ge­
+   löscht. 
+      Zur Sicherheit überprüft #on("b")#gs-DIALOG#off("b")# in jedem Falle,
+   ob es sich um eine EUMEL - Diskette handelt, und er­
+   fragt Ihr Einverständnis, ob die Diskette wirklich
+   initialisiert werden soll. Geben Sie hierzu Ihr Ein­
+   verständnis, dann erfragt #on("b")#gs-DIALOG#off("b")# noch den (neuen)
+   Archivnamen. Hatte die Diskette schon einen Namen,
+   dann wird dieser zum Überschreiben angeboten. Wollen
+   Sie den alten Archivnamen beibehalten, so brauchen
+   Sie nur die <RETURN>-Taste zu tippen, ansonsten kön­
+   nen Sie den Namen auch zuvor verändern oder einen
+   ganz neuen Namen hinschreiben. Anhand des ausgege­
+   benen Namens können Sie auch überprüfen, ob Sie die
+   richtige Diskette eingelegt haben. 
+      Das Initialisieren funktioniert natürlich nur,
+   wenn Sie als Zieltask einen Archivmanager eingestellt
+   haben - ansonsten ist diese Menufunktion gesperrt
+   (nicht aktivierbar!). 
+ 
+   Fehlerfälle: 
+   -  Formatieren ist nicht auf dem System möglich 
+   -  Sehen Sie auch unter  'r Reservieren' 
+                            'z Zieltask einstellen' 
+ 
+#on("u")##on("b")#z Zieltask einstellen#off("b")##off("u")# 
+     Mit dieser Menufunktion können Sie festlegen, mit
+  welcher Zieltask Sie kommunizieren, d.h. z.B. Dateien
+  austauschen möchten. Normalerweise ist hier das Archiv
+  am eigenen Rechner eingestellt. Das wird auch nach
+  Aufklappen des Pull-Down-Menus im Kasten rechts
+  unten angezeigt. 
+     Sie können aber auch eine andere Task einstellen
+  (z.B. die Vatertask oder die Task 'PUBLIC'), um mit diesen
+  Dateien auszutauschen oder um sich auch nur einen
+  Überblick über die dort vorhandenen Dateien zu ver­
+  schaffen. Wenn Sie mit Ihrem Rechner in ein EUMEL-Netz
+  integriert sind, können Sie auch auf Tasks anderer
+  Rechner zugreifen oder auch Disketten von Laufwerken
+  anderer Rechner einlesen (z.B. wenn Sie Disketten ande­
+  rer Formate haben, die von Ihrem Rechner nicht gelesen
+  werden können). 
+     Dabei werden zwei Anforderungen an die Zieltask
+  gestellt: Sie muß existieren und bereit für den Datei­
+  austausch sein, d.h es muß eine Managertask sein, auf
+  die Sie Zugriff haben. Versuchen Sie auf andere Tasks
+  zuzugreifen, so erhalten Sie entsprechende (Fehler-)­
+  Meldungen. 
+     Zu beachten ist noch, daß es im EUMEL-System ver­
+  schiedene Arten von Managertasks gibt - Archivmana­
+  ger und normale Dateimanager. Der Unterschied besteht
+  darin, daß ein Archivmanager vom Benutzer vor dem
+  Zugriff reserviert werden muß - anschließend hat nur
+  dieser Benutzer (bis zur Aufgabe der Reservierung) ein
+  Zugriffsrechts auf den Manager. Normale Dateimanager
+  können dagegen von mehreren Benutzern in beliebiger
+  Reihenfolge angesprochen werden. 
+     Ein Archivmanager kann auch auf bestimmte Disket­
+  tenformate spezialisert sein (z.B. auf das Lesen von
+  DOS-Disketten). Manche Rechner haben auch mehrere
+  Archivmanager für verschiedene Laufwerke etc. Durch
+  Einstellen unterschiedlicher Archivmanager können
+  Sie dann auf verschiedenen Laufwerken archivieren. 
+     Nach Aktivieren dieses Menupunktes werden Ihnen
+  die folgenden Alternativen angeboten: 
+ 
+#on ("b")# 
+          +-------------------------------------------+ 
+          |       Dateiaustausch gewünscht mit:       | 
+          |                                           | 
+          |      a ... Archiv    (Eigene Station)     | 
+          |                                           | 
+          |      v ... Vatertask                      | 
+          |                                           | 
+          |      p ... 'PUBLIC'  (Eigene Station)     | 
+          |                                           | 
+          |      s ... Sonstige Task                  | 
+          |                                           | 
+          |                                           | 
+          |   Archiv   Vatertask   PUBLIC   Sonstige  | 
+          +-------------------------------------------+ 
+#off("b")# 
+ 
+      Da der Dateiaustausch mit dem Standardarchiv der
+   eigenen Station (Task: 'ARCHIVE'), mit der Vatertask
+   und der Task 'PUBLIC' recht häufig in Anspruch genom­
+   men wird, sind diese drei Optionen unter den Alterna­
+   tiven direkt angegeben. Entscheiden Sie sich für eine
+   dieser drei Tasks, so nimmt #on("b")#gs-DIALOG#off("b")# alle notwendi­
+   gen Einstellungen vor. Möchten Sie dagegen in Kon­
+   takt mit einer anderen Task treten, so wählen Sie die
+   Alternative 's ... Sonstige Task'. 
+ 
+   In diesem Falle haben Sie noch 3 Angaben zu machen: 
+ 
+   -  Zunächst werden Sie nach dem Namen der Zieltask
+      gefragt. Geben Sie den Namen der Zieltask - ohne
+      Anführungsstriche (!) - ein und schließen Sie die
+      Eingabe mit der <RETURN>-Taste ab. (Den ausgegebe­
+      nen Namen der z.Z. eingestellten Task können Sie
+      dabei verändern bzw. überschreiben.) 
+   -  Dann wird die Nummer der Station im EUMEL-Netz
+      erfragt, auf der sich die Zieltask befindet. Die
+      Nummer Ihrer Station wird als Vorschlag ausgege­
+      ben. Wollen Sie mit einer Task auf Ihrem Rechner
+      kommunizieren, so brauchen Sie diesen Vorschlag
+      nur durch Drücken der <RETURN>-Taste zu bestäti­
+      gen; ansonsten tragen Sie zuvor die entsprechende
+      Stationsnummer ein. Ist Ihr Rechner nicht in ein
+      EUMEL-Netz integriert, so wird die Stationsnummer
+      0 (Null) ausgegeben. Bitte bestätigen Sie diese Sta­
+      tionsnummer durch Tippen der <RETURN>-Taste. 
+   -  Zum Abschluß müssen Sie noch angeben, ob die ein­
+      gestellte Zieltask ein Archivmanager ist oder
+      nicht. 
+ 
+      #on("b")#gs-DIALOG#off("b")# versucht dann den Kontakt herzustellen.
+   Je nachdem, welche Einstellung Sie vorgenommen ha­
+   ben, sind bestimmte Funktionen innerhalb des Menus
+   nicht aktivierbar. #on("b")#gs-DIALOG#off("b")# läßt nur die Funktionen
+   zu, die aufgrund Ihrer Einstellungen zulässig sind. 
+      Im Kasten rechts unten auf dem Bildschirm wird
+   jeweils angezeigt, welche Zieltask eingestellt ist.
+   Erscheint in diesem Kasten auch ein Hinweis auf den
+   Archivnamen, so haben Sie einen Archivmanager einge­
+   stellt. Ist dagegen vor dem Namen der Zieltask noch
+   eine Zahl und ein Schrägstrich angegeben, so haben
+   Sie eine Zieltask auf einem anderen Rechner einge­
+   stellt. 
+      Bedenken Sie, daß Operationen mit Tasks auf ande­
+   ren Stationen länger andauern können - werden Sie
+   nicht ungeduldig! 
+      Sie können die Einstellung der Zieltask jederzeit
+   wieder verändern! 
+ 
+   Fehlerfälle: 
+   -  Die eingestellte Zieltask existiert nicht. 
+   -  Die eingestellte Zieltask existiert zwar, ist aber
+      nicht empfangsbereit, d.h. ein Zugriff von Ihrer
+      Task aus ist nicht möglich! 
+   -  Das Netz ist nicht funktionsbereit (Collector-Task
+      fehlt). 
+   -  Die Kommunikation war nicht erfolgreich. 
+   -  Die gewünschte Operation kann mit der eingestell­
+      ten Zieltask nicht ausgeführt werden (Zieltask ist
+      z.B. gar kein Archivmanager - Sie aber versuchen,
+      das Laufwerk zu reservieren) 
+
diff --git a/doc/dialog/gs-dialog-5 b/doc/dialog/gs-dialog-5
new file mode 100644
index 0000000..f2b17cf
--- /dev/null
+++ b/doc/dialog/gs-dialog-5
@@ -0,0 +1,176 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (49)# 
+#headodd# 
+#center#gs-DIALOG#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-DIALOG 
+ 
+#end# 
+#center#5 
+ 
+#center#Informationen für Lehrer/Programmierer 
+ 
+ 
+5.1  "Verschlüsselung" der Dateien auf der Diskette 
+ 
+   Wenn Sie sich die Inhalte der Dateien angesehen haben,
+in denen die Programme für #on("b")#gs-DIALOG#off("b")# enthalten sind,
+werden Sie festgestellt haben, daß der Code dicht gepackt
+ist. Das war notwendig, um die gesamten Programme auf
+einer Diskette unterzubringen. 
+   Allerdings ist der Code #on("u")#nicht#off("u")# verschlüsselt - nur
+dichter gepackt. Auf der gelieferten Diskette befindet
+sich eine Datei mit Namen "gs-DIALOG decompress". In die­
+ser Datei ist das (einfache) Komprimier- und Dekompri­
+mierprogramm enthalten. Insertieren Sie dieses Programm
+in einer Task. Anschließend stehen Ihnen zwei Befehle zur
+Verfügung: 
+ 
+PROC komprimiere (TEXT CONST dateiname): 
+  Die angegebene Datei wird komprimiert; die Datei steht
+  anschließend unter gleichem Namen zur Verfügung. 
+ 
+PROC dekomprimiere (TEXT CONST dateiname): 
+  Eine zuvor mit 'komprimiere' bearbeitete Datei wird -
+  bis auf die Leerzeilen - in den Ursprungszustand über­
+  führt. Die Datei steht anschließend wieder unter glei­
+  chem Namen zur Verfügung. 
+ 
+   Dieser 'Service' ist vornehmlich für Lehrer gedacht.
+So können Programmteile im Unterricht Gegenstand von
+Betrachtungen sein; Schüler können nach optimaleren
+Algorithmen für Teillösungen suchen - ggf. Anregungen
+geben. Sinnvoll ist es, das eigentliche Programm nicht zu
+verändern, um die Lauffähigkeit der unter #on("b")#gs-DIALOG#off("b")#
+entwickelten Software nicht zu gefährden. 
+ 
+ 
+5.2  Nutzung der Graphikzeichen auf anderen Rechnern/
+Terminals 
+ 
+   Wie schon unter "2.4 Nutzung der 'Semi - Graphik -
+Zeichen'" erwähnt, ist #on("b")#gs-DIALOG#off("b")# darauf vorbereitet, für
+'IBM - kompatible Rechner' und für Terminals 'Beehive
+FT20' die Umrahmungen der Kästen als durchgezogene Li­
+nien auszugeben - dadurch gewinnt die Bildschirmdar­
+stellung. 
+   #on("b")#gs-DIALOG#off("b")# ist aber hinsichtlich der Graphikzeichen
+nur für diese Endgeräte vorbereitet und benutzt in allen
+anderen Fällen Zeichen des normalen Zeichensatzes. 
+   Sie können sich aber, sofern Ihr Rechner/Terminal
+über solche Semi - Graphikzeichen verfügt, leicht selbst
+eine Anpassung dafür erstellen. Auch darauf ist
+#on("b")#gs-DIALOG#off("b")# schon vorbereitet. Keine Angst, versuchen Sie
+es ruhig einmal. Sie können nichts falsch machen; denn
+sollte es Ihnen nicht gelingen, so können Sie jederzeit
+mit dem Befehl 'std graphic char' und einem anschließen­
+den <RETURN> die Standardeinstellung wieder vornehmen. 
+   Informieren Sie sich in Ihrer Terminal-/Rechner­
+beschreibung, welche Codes ausgegeben werden müssen, um
+die Grahpikzeichen darzustellen. Folgende Zeichen werden
+benötigt: 
+ 
+  Ecke oben links    :          ω         (f) 
+  Ecke oben rechts   :          �         (g) 
+  Ecke unten links   :          �         (e) 
+  Ecke unten rechts  :          �         (h) 
+ 
+  Balken oben        :          �         (n) 
+  Balken unten       :          ̂         (o) 
+  Balken links       :          ̄         (m) 
+  Balken rechts      :          ̃         (l) 
+  Kreuz              :          ̗         (i) 
+ 
+  waagerechte Linie  :          ̇         (k) 
+  senkrechte  Linie  :          �         (j) 
+ 
+  --------------------------------------------- 
+ 
+  ( Cursor sichtbar        :     ( ESC . 1 )  ) 
+  ( Cursor unsichtbar      :     ( ESC . 0 )  ) 
+ 
+ 
+   #on("b")#gs-DIALOG#off("b")# müssen nun die speziellen Codes Ihres Rech­
+ners/Terminals mitgeteilt werden. Dafür stehen die fol­
+genden Prozeduren zur Verfügung: 
+ 
+PROC ecke oben links    (TEXT CONST zeichenkette); 
+PROC ecke oben rechts   (TEXT CONST zeichenkette); 
+PROC ecke unten links   (TEXT CONST zeichenkette); 
+PROC ecke unten rechts  (TEXT CONST zeichenkette); 
+PROC balken oben        (TEXT CONST zeichenkette); 
+PROC balken unten       (TEXT CONST zeichenkette); 
+PROC balken links       (TEXT CONST zeichenkette); 
+PROC balken rechts      (TEXT CONST zeichenkette); 
+PROC waagerecht         (TEXT CONST zeichenkette); 
+PROC senkrecht          (TEXT CONST zeichenkette); 
+PROC kreuz              (TEXT CONST zeichenkette); 
+ 
+PROC cursor on          (TEXT CONST zeichenkette); 
+PROC cursor off         (TEXT CONST zeichenkette); 
+ 
+   Sofern möglich, kann auch noch ein Code eingegeben
+werden, damit der Cursor auf dem Bildschirm sichtbar bzw.
+unsichtbar ist. 
+   Wie man sich selbst eine Anpassung schreiben kann,
+wollen wir hier an einem Beispiel aufzeigen. Wir schrei­
+ben dazu eine Anpassung für das Terminal 'Ampex 210+'. 
+   In der Terminalbeschreibung ist angegeben, wie das
+Terminal konfiguriert sein muß - diese Konfiguartion
+haben wir eingestellt. Weiterhin ist angegeben, daß auf
+die Grapikzeichen durch die Zeichenfolge 'ESC $' umge­
+schaltet und durch die Zeichenfolge 'ESC %' auf den nor­
+malen Zeichensatz zurückgeschaltet wird. Für die jeweils
+speziellen Graphikzeichen sind bestimmte Buchstaben an­
+zugeben (z.B. für die 'Ecke oben links' der Buchstabe 'f').
+Die Zeichen für dieses Terminal sind oben hinter den Gra­
+phikzeichen in Klammern angegeben. Für 'ESC' muß der Code
+'27' ausgegeben werden. 
+ 
+PACKET eigene graphikanpassung DEFINES 
+ 
+       private graphic char: 
+ 
+PROC private graphic char: 
+  ecke oben links    (""27"$f"27"%"); 
+  ecke oben rechts   (""27"$g"27"%"); 
+  ecke unten links   (""27"$e"27"%"); 
+  ecke unten rechts  (""27"$h"27"%"); 
+  balken oben        (""27"$n"27"%"); 
+  balken rechts      (""27"$l"27"%"); 
+  balken links       (""27"$m"27"%"); 
+  balken unten       (""27"$o"27"%"); 
+  waagerecht         (""27"$k"27"%"); 
+  senkrecht          (""27"$j"27"%"); 
+  kreuz              (""27"$i"27"%"); 
+  cursor on          (""27".1"); 
+  cursor off         (""27".0"); 
+END PROC private graphic char; 
+ 
+END PACKET eigene graphikanpassung; 
+ 
+   Nachdem das Programm insertiert und der Befehl
+'private graphic char' gegeben ist, steht in dieser Task
+und allen Söhnen davon die Graphikanpassung für das
+Terminal 'Ampex 210+' zur Verfügung. 
+ 
+ 
+5.3  Fehlerbehandlung 
+ 
+   Haben Sie z.B. das Menu durch Tippen der <SV>-Taste
+verlassen, so kann es vorkommen, daß anschließend das
+Menu auf dem Bildschirm nicht ordnungsgemäß aufgebaut
+wird. Verlassen Sie dann die Menuebene durch die Tasten­
+folge <ESC><q>. 
+ 
+Wenn 'gib kommando:' erscheint, geben Sie den Befehl 
+ 
+   reset dialog <RETURN> 
+ 
+   Dadurch wird das Menusystem in den Anfangszustand
+gesetzt. Anschließend können Sie das von Ihnen ge­
+wünschte Programm (wieder) aufrufen. 
+
diff --git a/doc/dialog/gs-dialog-Inhaltsverzeichnis b/doc/dialog/gs-dialog-Inhaltsverzeichnis
new file mode 100644
index 0000000..741744f
--- /dev/null
+++ b/doc/dialog/gs-dialog-Inhaltsverzeichnis
@@ -0,0 +1,45 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+Inhaltsverzeichnis 
+ 
+ 
+1     Was kann gs-DIALOG                           3 
+ 
+2     Installation von gs-DIALOG                   6 
+2.1   Voraussetzungen                              6 
+2.2   Lieferumfang                                 6 
+2.3   Installation                                 6 
+2.4   Nutzung der 'Semi-Graphik-Zeichen'          10 
+ 
+3     Umgang mit den Menus; Eine Beispielsitzung  12 
+3.1   Aufruf der Archivverwaltung                 12 
+3.2   Bedienung des Menusystems                   14 
+      -  Aufbau der Menus (Bildschirmaufbau)      14 
+      -  Auswahl der Menupunkte                   15 
+      -  Informationen zu einem Menupunkt         18 
+      -  Informationen zur Bedienung des Menus    19 
+      -  Aktivierbare und nicht aktivierbare 
+         Menupunkte                               20 
+      -  Aktivieren von Menupunkten               21 
+      -  Dateiauswahl                             22 
+      -  Ja/Nein - Fragen                         26 
+      -  Eingaben                                 26 
+      -  Alternativen                             26 
+      -  Verlassen des Menus                      27 
+3.3   Zusammenfassung/Kurzbeschreibung            28 
+ 
+4     Beschreibung der Menufunktionen             30 
+4.1   Menufunktionen zum Oberbegriff  'Dateien'   30 
+4.2   Menufunktionen zum Oberbegriff  'Archiv'    36 
+ 
+5     Informationen für Lehrer/Programmierer      49 
+5.1   "Verschlüsselung" der Dateien auf der 
+      Diskette                                    49 
+5.2   Nutzung der Graphikzeichen auf andere 
+      Rechnern/Terminals                          50 
+5.3   Fehlerbehandlung                            53 
+
+
+
+
+
diff --git a/doc/dynamo/dynamo handbuch b/doc/dynamo/dynamo handbuch
new file mode 100644
index 0000000..4012973
--- /dev/null
+++ b/doc/dynamo/dynamo handbuch	
@@ -0,0 +1,1826 @@
+#block##pageblock##page (2)##setcount (1)##count per page# 
+#head# 
+#center#DYNAMO-Compiler 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottom odd# 
+#center#____________________________________________________________ 
+GMD #right#DYNAMO - % 
+#end# 
+#bottom even# 
+#center#____________________________________________________________ 
+DYNAMO - % #right#GMD 
+#end# 
+ 
+#ib#1. Einleitung#ie# 
+ 
+ 
+ 
+Diese Handbuch beschreibt die Funktion des EUMEL-DYNAMO-Compilers in der
+Version 3.3+ und seine Einschränkungen oder Änderungen gegenüber dem
+DYNAMO-Sprachstandard. In keiner Weise kann diese Beschreibung eine Einfüh­
+rung in die Programmiersprache DYNAMO ersetzen! 
+ 
+Die beschriebene Compilerversion enthält nun auch ein Modul zur Unterstützung von
+hochauflösender Grafik durch die häufig in IBM-PC/AT-Kompatiblen eingesetzte
+CGA-Grafikkarte. Dennoch ist es einfach möglich, diesen Grafikmodus auszuschal­ 
+ten, und somit die alte, zeichenorientierte Grafik weiter zu verwenden. 
+ 
+Der DYNAMO-Compiler wurde 1983 von Robert Keil und Torsten Fröhlich (Helm­
+holtz-Gymnasium, Bonn) im Rahmen des MIKROS-Projektes am Informatik-Kolleg 
+der GMD entwickelt. Für Spezifikation und Betreuung der Entwicklung war Dr. Diether
+Craemer verantwortlich, software-technische Unterstützung kam von Prof. John
+Henize, Dr. Peter Heyderhoff, Rudolf Legde und Dipl.- Math. Lothar Oppor. Die 
+Grafik wurde von D.Giffeler beigesteuert. 
+ 
+ 
+ 
+ 
+#ib#1.1. Referenzliteratur#ie# 
+ 
+ 
+ 
+ 
+  [1]  Craemer, Diether 
+       "Mathematisches Modellieren dynamischer Vorgänge" 
+       e. Einf. in die Programmiersprache DYNAMO 
+       Stuttgart, Teuber, 1985 
+       ISBN 3-519-02477-2 
+ 
+  [2]  Craemer, Diether 
+       "Fluß und Zustand - Simulation dynamischer Vorgänge in DYNAMO" 
+       in: LOGIN 5 (1985), Heft 1, S. 20-23 
+ 
+  [3]  Pugh, Alexander L. 
+       "DYNAMO II User's Manual" 
+       Cambridge, London 1973: MIT-Press 
+       ISBN 0-262-66018-0 
+#page# 
+ 
+#ib#1.2. Die Programmiersprache DYNAMO#ie# 
+ 
+ 
+ 
+DYNAMO wurde von einer Gruppe um Jay FORRESTER am Massachusetts Institute
+of Technology (MIT) um 1960 entwickelt. Die Sprache basiert auf der #on ("i")# System
+Dynamic#off ("i")# von FORRESTER. 
+ 
+In DYNAMO (#on ("u")##on ("b")#Dyna#off ("b")##off ("u")#mic #on ("u")##on ("b")#Mo#off ("b")##off ("u")#delling Language) können Systeme, in denen Veränderun­ 
+gen kontinuierlich geschehen, modelliert und simuliert werden. 
+ 
+Kontinuierliche Veränderungen von Größen werden über deren Veränderungsrate im
+Wesentlichen nach folgender Gleichung berechnet 
+ 
+Größe jetzt = Größe früher + DT * Veränderungsrate, 
+ 
+dabei ist DT die Länge des Zeitintervalls von "früher" bis "jetzt". 
+ 
+Außer diesen Gleichungen für Größen braucht man Gleichungen für die Verände­
+rungsraten, für Hilfsgrößen, zur Initialisierung von Größen, zur Definition von Konstan­
+ten und Tabellen, zu Angaben von Simulationsläufen und zur Wiedergabe von Ergeb­
+nissen in Zahlentabellen oder Diagrammen. 
+ 
+Alle diese Gleichungen können einfach in der Form, wie man sie aus dem Mathema­
+tik-Unterricht der Sekundarstufe kennt, hingeschrieben werden, ohne sich Gedanken
+über den Ablauf des Programms machen zu müssen. 
+ 
+#on ("b")# 
+DYNAMO ist also eine einfache funktional-applikative, nicht-prozedurale Sprache.#off ("b")# 
+ 
+Das macht ihren Reiz und ihre Leistungsfähigkeit aus, die zur Formulierung der be­
+kannten Weltmodelle von FORRESTER, MEADOWS ("Die Grenzen des Wachstums"),
+PESTEL, MESAROVIC u.a. in dieser Sprache führten. 
+ 
+Anwendungsgebiete der Sprache sind ökologische, gesellschaftliche, wirtschaftliche
+und technische Systeme, deren dynamisches Verhalten der Modellbildner nachbilden
+und studieren möchte. 
+ 
+Im Allgemeinen verfolgt der Modellbildner mit seinem Modell einen Zweck (Verhaltens­
+änderung des nachgebildeten Systems), so daß auch neben gesicherten Fakten die
+Wertvorstellungen des Modellbildners in das Modell eingehen. 
+ 
+ 
+ 
+ 
+#ib#1.3 Kurz-Einführung in die DYNAMO-
+Schreibweise#ie# 
+ 
+ 
+ 
+Die System Dynamic Methode benutzt als Analogie-Bild den Archetyp des Flusses: 
+ 
+  -  Wasser fließt durch das Flußbett, kann in Seen gestaut und in der Ge­
+     schwindigkeit durch Schleusen und Wehre reguliert werden. 
+ 
+  -  Analog dazu "fließt" Geld auf dem Überweisungsweg, wird in Konten gestaut,
+     und die Liquidität kann durch Zinssätze reguliert werden. 
+ 
+  -  Gedanken "fließen" auf Nervenbahnen, werden im Gehirn gespeichert, und
+     Gedankenströme werden über Synapsen reguliert. 
+ 
+  -  Autos "fließen" über Straßen, werden auf Parkplätzen gestaut, und der Ver­
+     kehrsfluß wird über Ampeln reguliert. 
+ 
+  -  Menschen "fließen" über Wanderwege, halten sich in Wohnorten auf, und die
+     Bevölkerungsdynamik wird durch ein komplexes, rückgekoppeltes Zusammen­
+     spiel von Ein- und Auswanderungsraten sowie Geburts- und Sterberaten
+     reguliert. 
+ 
+Am letzten Beispiel wird deutlich, daß sich ein soziales Phänomen nur im Zusam­
+menwirken vieler netzartig miteinander verbundener Variablen beschreiben läßt (wenn
+überhaupt). 
+ 
+Solange jedoch einigen Variablen ZUSTANDS-CHARAKTER ("Wasserstand") und
+anderen VERÄNDERUNGS-CHARAKTER ("Flußgeschwindigkeit") zugeordnet
+werden kann, können die Größen für Berechnungen folgender Art verwendet werden: 
+ 
+ 
+  Wasserstand jetzt = Wasserstand früher + vergangene Zeit * 
+                      (Zuflußrate - Abflußrate) 
+ 
+ 
+analog:  
+ 
+  Bevölkerung jetzt = Bevölkerung früher + vergangene Zeit * 
+                      (Geburtsrate - Sterberate) 
+ 
+ 
+Diese Schreibweise kann praktisch so in ein Computerprogramm übernommen wer­
+den. Mit geringfügigen Änderungen handelt es sich bei diesen Gleichungen schon um
+gültige Zeilen in der Programmiersprache DYNAMO. 
+ 
+In DYNAMO wird er Zeitpunkt "jetzt" durch das Anhängsel .K, der Zeitpunkt "früher"
+durch das Anhängsel .J, die Zeitspanne von jetzt bis später durch das Anhängsel .KL,
+die Zeitspanne von früher bis jetzt durch das Anhänsel .JK und die vergangene Zeit
+mit DT (wie "Delta Tempus": Zeitdifferenz) bezeichnet. Die Variablen mit Zustands-
+Charakter heißen LEVELS (Niveaus) und die Veränderungs-Charakter heißen RATES
+(Veränderungsraten, Geschwindigkeiten). Die entsprechenden Gleichungen werden mit
+L bzw. R gekennzeichnet. Es gib weitere Kennzeichnungen: 
+ 
+  C  für Konstantendefinition            (constant) 
+  T  für Tabellendefintion               (table) 
+  A  für Hilfsgrößen                     (auxiliaries) 
+  N  für Anfangswerte                    (initial) 
+  X  für Folgezeile                      (extension) 
+  PRINT für Ausgabe von Zahlen 
+  PLOT für Ausgabe von Diagrammen 
+ 
+Ein einfaches Bevölkerungsmodell könnte z.B. so geschriben werden: 
+ 
+ 
+  L BEVÖLKERUNG.K=BEVÖLKERUNG.J+DT*(GEBURTENRATE.JK 
+  X               -STERBERATE.JK) 
+  R STERBERATE.KL=5 
+  R GEBURTENRATE.KL=20 
+  N BEVÖLKERUNG=1000 
+  C DT=1                      (jedes Jahr wird neu berechnet) 
+  C LENGTH=60                 (60 Jahre werden simuliert) 
+  PRINT BEVÖLKERUNG 
+ 
+ 
+Für eine tiefere Einführung in DYNAMO sollte man die Referenzliteratur zu Rate
+ziehen. 
+ 
+ 
+ 
+ 
+#ib#1.4 Eine erste, kleine Sitzung mit dem
+DYNAMO-System#ie# 
+ 
+ 
+ 
+Wir gehen davon aus, daß das DYNAMO-System in ihrer Task generiert worden ist
+(siehe 2.). 
+ 
+  1. Tippen Sie das obrige Programm mittels des EUMEL-Editors ab. 
+ 
+  2. Verlassen Sie den Editor mit <ESC><q> und starten Sie den DYNAMO-
+     Compiler durch die Eingabe des Befehls "dynamo". 
+ 
+  3. Nach erfolgreichem Übersetzen sollte Ihnen nun das DYNAMO-Runtime-
+     System zur Verfügung stehen. Durch den Befehl 'run' wird das Programm aus­
+     geführt und Sie erhalten eine Zahlenkolonne, die die Entwicklung der Bevöl­
+     kerung in den zu untersuchenden 60 Jahren angibt. Falls Ihnen beim Abtippen
+     des Programms Fehler unterlaufen sein sollten, so kann das Programm nicht
+     fehlerfrei übersetzt werden. Fehlermeldunggen zur Compile-Zeit des
+     DYNAMO-Compilers werden im Paralleleditor angezeigt; das Programm kann
+     im oberen der beiden Editorfenster (in diesem befinden Sie sich auch nach
+     Fehlern) korrigiert werden. Danach können Sie erneut wie nach Punkt 2 ver­
+     fahren. 
+#page# 
+ 
+ 
+ 
+#ib#2. Generierung des DYNAMO-Compilers#ie# 
+ 
+ 
+ 
+Der DYNAMO-Compiler, seine Funktionen und die Beispielprogramme werden auf
+zwei Archiv-Disketten a#b#' 360 KB ausgeliefert. 
+ 
+Zum Generieren des DYNAMO-Systems legen Sie bitte die erste Diskette in das
+Dikettenlaufwerk Ihres Rechners und durch folgende Kommandozeile lesen Sie den
+Generator vom Archiv und starten ihn: 
+ 
+ 
+       archive ("dynamo"); fetch ("dyn.inserter", archive); run 
+ 
+ 
+Danach holt der Generator alle benötigten Dateien vom eingelegten Archiv bzw. von
+dem zweiten Archiv (nachdem er Sie zum Wechseln der Diskette aufgefordert hat).
+Anschließend wird der DYNAMO-Compiler insertiert. Am Ende der Generierung
+werden Sie gefragt werden, ob Sie den Compiler mit Grafik#u##count ("Grafik")##e# oder ohne benutzen
+wollen. Nach der Meldung "dynamo system generiert" können Sie den Compiler#foot#
+#u##value ("Grafik")##e# Es kann z.Zt. nur eine CGA-Grafikkarte betrieben werden 
+#end# 
+nutzen. 
+#page# 
+ 
+ 
+ 
+#ib#3. Der EUMEL-DYNAMO-Compiler#ie# 
+ 
+ 
+ 
+Der im EUMEL-System implementierte DYNAMO-Compiler ist ein 2-Pass-
+Compiler, der die DYNAMO-Programme zunächst in ELAN übersetzt. Der Vorteil
+dieser Methode besteht darin, daß es möglich ist, übersetzte Programme unabhängig
+vom DYNAMO-Compiler zur Ausführung bringen zu können. 
+ 
+Die Notation der im folgenden aufgeführten ELAN-Prozeduren des Compilers ent­
+spricht der in den EUMEL-Handbüchern üblichen Prozedurkopf-Schreibweise. 
+ 
+Als Beispiel: 
+ 
+ 
+  dynamo ("dyn.grasshasenfuchs") 
+ 
+ 
+ein Beispiel für den Aufruf der Prozedur mit der Prozedurkopf-Schreibweise 
+ 
+  PROC dynamo (TEXT CONST filename) 
+ 
+auf der Kommando-Ebene des Betriebssystems EUMEL. 
+ 
+Der Prozedur 'dynamo' wird beim Aufruf der Dateiname (TEXT) 'filename' übergeben
+und dadurch der Compiler auf die Datei mit dem Namen 'filename' angewendet. 
+ 
+ 
+ 
+ 
+#ib#3.1. Benutzung des DYNAMO-Compiler#ie# 
+ 
+ 
+ 
+Um ein DYNAMO-Programm zu Übersetzen, gibt es grundsätzlich zwei Möglichkei­
+ten. Erst einmal kann man ein DYNAMO-Programm in ein ELAN-Programm um­
+wandeln, jedoch ohne es dabei zur Ausführung zu bringen. Dieses ELAN-Programm
+kann man nun unabhängig vom eingentlichen Compiler starten. Die zweite, wohl öfter
+angewendete Methode ist, ein DYNAMO-Programm in ein ELAN-Programm zu
+compilieren, wobei es danach direkt ausgeführt wird. Ob danach ein ELAN-
+Programm zur Verfügung stehen soll, kann der Benutzer selbst entscheiden. 
+ 
+ 
+PROC dynamo 
+ 
+  Zweck: Aufruf des DYNAMO-Compilers mit 'quelldatei' = 'last param', d.h. das
+         zu übersetzende Programm steht in der zuletzt bearbeiteten Datei. 
+ 
+ 
+PROC dynamo (TEXT CONST quelldatei) 
+ 
+  Zweck: Ruft den DYNAMO-Compiler für die Datei 'quelldatei' auf. Anmerkung:
+         Gleichbedeutend mit 'dynamo (quelltext, quelltext + ".elan", TRUE)', s.
+         nächste Prozedur. 
+ 
+  Beispiel: 
+   
+ 
+           dynamo ("dyn.grashasenfuchs") 
+   
+ 
+         Der DYNAMO-Compiler wird auf die Datei "dyn.grashasenfuchs" ange­
+         wendet. 
+ 
+ 
+PROC dynamo (TEXT CONST quelldatei, zieldatei, 
+             BOOL CONST pass2 ausfuehren) 
+ 
+  Zweck: Diese Prozedur startet den DYNAMO-Compiler. 'quelldatei' gibt den
+         Namen der Datei an, in welcher der DYNAMO-Quelltext enthalten ist,
+         'zieldatei' ist der Name der Datei, die das erzeugte ELAN-Programm
+         beinhalten soll. Wenn 'pass2 ausfuehren' = TRUE, dann wird dieses auch
+         durch den ELAN-Compiler weiterverarbeitet (das Programm wird zur
+         Ausführung gebracht). 
+ 
+  Beispiel: 
+ 
+ 
+           dynamo ("dyn.grashasenfuchs", 
+                   "grashasenfuchs.elanprogramm", FALSE) 
+ 
+ 
+         Im obigen Beispiel wird der in der Datei "dyn.grashasenfuchs" enthaltene
+         DYNAMO-Quelltext in die Datei "grashasenfuchs.elanprogramm" als
+         ELAN-Programm geschrieben. Das ELAN-Programm wird nicht ausge­
+         führt. 
+ 
+ 
+PROC erase (BOOL CONST erase option) 
+ 
+  Zweck: Wenn 'erase option' = TRUE, so werden die erzeugten ELAN-Programme
+         nach Beendigung der Ausführung gelöscht, bei 'erase option' = FALSE
+         bleiben sie erhalten (Voreinstellung: 'erase option' = FALSE). 
+ 
+ 
+PROC error listing (TEXT CONST fehlerdatei) 
+ 
+  Zweck: Falls gewünscht ist, die Fehlermeldungen, die ggf. beim Übersetzen ein­
+         treten, auch in eine Datei zu schreiben, so können Sie hier unter 'fehler­
+         datei' einen Dateinamen angeben. Bei der Angabe von "" wird die Umlei­
+         tung in die Datei ausgeschaltet werden (Voreingestellt ist 'fehlerdatei' =
+         ""). 
+ 
+ 
+PROC graphic (BOOL CONST graphic option) 
+ 
+  Zweck: Mit dieser Prozedur läßt sich einstellen, ob bei der DYNAMO-Anweisung
+         PLOT die hochauflösende Grafik ('graphic option' = TRUE) oder die zei­
+         chenorientierte Grafik ('grafik option' = FALSE) verwendet werden soll. Die
+         Voreinstellung wird bei der Installation des Compilers erfragt. 
+ 
+ 
+PROC protokoll (BOOL CONST protokoll option) 
+ 
+  Zweck: Bei 'protokoll option' = TRUE werden alle Textausgaben, die bei der
+         Laufzeit des DYNAMO-Programmes auftreten, nicht nur auf dem Bild­
+         schirm dargestellt, sondern auch in eine Datei mit dem Namen "dyn.out"
+         protokolliert (voreingestellt ist 'protokoll option' = FALSE). Die Datei
+         "dyn.out" enthält auch Seitenvorschubbefehle ('\#page\#') und sollte nur mit
+         einem EUMEL-Printer ausgedruckt werden. 
+ 
+ 
+ 
+ 
+#ib#3.2. Abweichungen gegenüber dem 
+     Sprachstandard#ie# 
+ 
+ 
+ 
+ -  Die Länge der Namen ist nicht auf 7 Zeichen festgelegt, sondern praktisch be­
+    liebig (32000). Dies ist eine Erweiterung; wer seine Programme auch auf ande­
+    ren DYNAMO-Compilern laufen lassen will, sollte sich aber auf 7 Zeichen be­
+    schränken. 
+ 
+ -  Zahlen werden intern mit einer Mantisse von 13 Stellen abgespeichert, von denen
+    nur die ersten 7 bei der Ausgabe dargestellt werden. Die größte darstellbare Zahl
+    ist daher 9.999999999999e126. 
+ 
+ -  Die maximale Anzahl der Gleichungen ist auf 950 festgelegt. 
+ 
+ -  Der Compiler akzeptiert aus Gründen der besseren Lesbarkeit auch Programme,
+    die in Kleinschrift geschrieben sind. Dabei ist es sinnvoll, die Quellprogramme
+    konsistent zu halten (d.h. Groß- und Kleinschrift nicht zu vermischen). Man
+    sollte grundsätzlich Kleinschrift vorziehen, da diese vom Compiler auch effizienter
+    verarbeitet werden kann. 
+ 
+ -  Quellprogramme dürfen eine beliebige Zahl von Leerzeilen enthalten. X - Befeh­
+    le (Fortschreibungszeilen) werden davon nicht beeinflußt. 
+ 
+ -  In der augenblicklichen Version 3.3 des Compilers gelten folgende Einschränkun­
+    gen : 
+ 
+   1. Bei der Verarbeitung von Array-Gleichungen werden Compilerseitig keine
+      Semantik-Überprüfungen auf eventuell unzureichende Initialisierung oder
+      Überlappung (d.h. mehrfaches Setzen desselben Elements) durchgeführt.
+      Defaultmäßig bekommen alle Elemente einer Array-Gleichung bei der Initiali­
+      sierung den Wert '0.0' zugewiesen. 
+ 
+   2. Die maximale Größe von Tables und Array-Gleichungen ist durch Verwen­
+      dung des Vector-Pakets auf 4000 Elemente festgelegt. Da pro Table-Ele­
+      ment aber zur Zeit eine Zeile im Zielprogramm generiert wird, sollte man dies
+      besser nicht ausnutzen. 
+ 
+   3. Supplementary-Gleichungen werden aus Kompatibilitäts-Gründen korrekt
+      übersetzt, aber sonst wie Auxiliary-Gleichungen behandelt. 
+ 
+   4. Print ('prtper')- und Plotperiode ('pltper') werden nur als Konstanten verarbei­
+      tet. Falls Gleichungen für 'prtper' oder 'pltper' angegeben werden, so bewirken
+      diese keine Veränderung. 
+ 
+   5. Array-Gleichungen dürfen nicht mehr als eine Dimension besitzen. 
+ 
+   6. Für Gleichungen, die Makro-Aufrufe enthalten, sollten Initialisierungs (N)-
+      Gleichungen angegeben werden. 
+ 
+ 
+ 
+#ib#3.3. Das DYNAMO Runtime-System#ie# 
+ 
+ 
+ 
+Nach erfolgreicher Übersetzung wird vom Zielprogramm das Runtime-System aufge­
+rufen. In diesem Modus (das DYNAMO-Runtime-System meldet sich mit "dynamo
+runtime system :") ist es möglich, Konstanten zu ändern und DynamoProgramme zur
+Ausführung zu bringen. 
+ 
+Im DYNAMO-Runtime-System stehen folgende Kommandos zur Verfügung (näheres
+zur Notation siehe Kapitel 4, S. #to page ("Anweisungen und Funktionen")#). 
+ 
+ 
+  run 
+ 
+    Zweck: Ausführen des übersetzten Programms 
+ 
+ 
+  run <name> 
+ 
+    Zweck: Ausführen des übersetzten Programms und retten des Konstantendaten­
+           raums in des Datenraum mit dem Namen "<name>.const". Existiert der
+           Datenraum bereits, werden die Konstanten aus dem Datenraum in den
+           Lauf übernommen. Somit ermöglicht der Compiler, Konstantenwerte aus
+           einem früheren Lauf wieder zu verwenden. 
+ 
+ 
+  c <Konstantenname>=Wert [/<Konstantenname>=Wert [...]] 
+ 
+    Zweck: Änderung einer oder mehrerer Konstanten 
+ 
+ 
+  ? 
+ 
+    Zweck: Anzeigen der Konstanten und ihrer Werte 
+ 
+ 
+  quit 
+ 
+    Zweck: Verlassen des Runtime-Systems 
+ 
+ 
+  help 
+ 
+    Zweck: Zeigt eine kurze Erklärung 
+ 
+ 
+Bei PRINT- und PLOT-Ausgaben sind folgende Kommandos möglich: 
+ 
+  +       Nächster Bildschirm 
+  o       (Off), keine Unterbrechung der Ausgabe (nicht möglich bei hochauflösen­
+          der Grafik) 
+  e       (End), Zurück zum Runtime System 
+  p       Phasendiagramm (nur bei hochauflösender Grafik möglich) 
+ 
+ 
+ 
+#ib#3.4. Fehlermeldungen des 
+     DYNAMO-Compilers#ie# 
+ 
+ 
+ 
+Falls der Compiler einen Fehler im DYNAMO-Programm entdeckt, gibt er eine Feh­
+lermeldung nach dem folgenden Muster aus: 
+"Fehler in Zeile  <zeilennummer>  bei >>  <symbol>  <<  :  <fehlertext>. 
+ 
+Im  folgenden sind alle Fehlermeldungen und Möglichkeiten zur Abhilfe aufgelistet,
+sofern diese nicht klar ersichtlich sind: 
+ 
+ 1   GLEICHUNG DOPPELT DEFINIERT 
+ 
+ 2   DOPPELTE INITIALISIERUNG 
+ 
+ 3   FALSCHER ZEILENTYP 
+     ->  Erlaubt sind :  a, c, l, n, r, s, print, plot, note, spec, *, x, macro, mend,
+                         for, noise, run. 
+ 
+ 4   VERSCHACHTELTE MAKRO-DEFINITION 
+     ->  'mend' - Befehl fehlt. 
+ 
+ 5   MAKRO-NAME ERWARTET 
+ 
+ 6   '(' ERWARTET 
+ 
+ 7   FORMALER PARAMETER ERWARTET 
+ 
+ 8  ')' NACH PARAMETERLISTE ERWARTET 
+ 
+ 9  BEI AUXILIARIES NUR SUBSKRIPTION MIT '.K' ERLAUBT 
+ 
+10  BEI KONSTANTEN-DEFINITION NAME ERWARTET 
+ 
+11  BEI LEVELS NUR SUBSKRIPTION MIT '.K' ERLAUBT 
+ 
+12  BEI RATES NUR SUBSKRIPTTION MIT '.KL' ERLAUBT 
+ 
+13  BEI TABLE-DEFINITIONEN KEINE SUBSKRIPTION ERLAUBT 
+ 
+14  X - BEFEHL HIER NICHT ERLAUBT 
+ 
+15  BEI FOR-DEFINITION NAME ERWARTET 
+ 
+16  '=' NACH FOR-VARIABLE ERWARTET 
+ 
+17  BEREICHSANGABE ERWARTET 
+ 
+18  ',' ERWARTET 
+ 
+19  LOKALE GLEICHUNG NUR IN MAKRO ERLAUBT 
+ 
+20  BEI DEFINITION NAME ERWARTET 
+ 
+21  '=' ERWARTET 
+ 
+22  INDEX NICHT KORREKT 
+    ->  Als Index ist nur erlaubt :  <for variable> !, 
+                                     <add op> <ganze zahl>!. 
+                                     <add op> ::= "+"; "-". 
+ 
+23  ')' NACH INDIZIERUNG ERWARTET 
+ 
+24  PRTPER NICHT DEFINIERT 
+    ->  Wenn das Programm einen Print-Befehl enthält, muß 'prtper' (Printperiode)
+        als Konstante definiert werden. 
+ 
+25  PLTPER NICHT DEFINIERT 
+    ->  Wenn das Programm einen Plot-Befehl enthält, muß 'pltper' (Plotperiode)
+        als Konstante definiert werden. 
+ 
+26  '/' ODER ',' BEI PLOT ERWARTET 
+ 
+27  NAME ALS PLOTPARAMETER ERWARTET 
+ 
+28  DOPPELTE SCALE - ANGABE IN EINER GRUPPE 
+    ->  Wenn mehrere Plotparameter mit ',' getrennt werden (also die gleiche Ska­
+        lierung erhalten), dürfen nicht mehrere feste Skalierungen angegeben wer­
+        den. 
+ 
+29  ERSTE SCALE - ANGABE ERWARTET 
+ 
+30  ZWEITE SCALE - ANGABE ERWARTET 
+ 
+31  ')' NACH SCALE - ANGABE FEHLT 
+ 
+32  PRINTPARAMETER NICHT DEFINIERT 
+ 
+33  PRINTPARAMETER ERWARTET 
+ 
+34  TIME DARF NUR INITIALISIERT WERDEN 
+ 
+35  DT NICHT DEFINIERT 
+ 
+36  LENGTH NICHT DEFINIERT 
+ 
+37  BEI KONSTANTEN - DEFINITION ZAHL ERWARTET 
+ 
+38  BEI INITIALISIERUNG KONSTANTE ERWARTET 
+ 
+39  LEVELS MUESSEN INITIALISIERT WERDEN 
+ 
+40  KONSTANTE BEI TABLE ERWARTET 
+ 
+41  '/' ODER "," ERWARTET 
+ 
+42  TABLE - DEFINITION OHNE BENUTZUNG 
+ 
+43  SIMULTANE GLEICHUNGEN 
+    ->  Bei dem Versuch, A, R, oder N - Gleichungen zu sortieren, trat eine
+        direkte oder indirekte Rekursion auf. 
+ 
+44  FAKTOR ERWARTET 
+    ->  Erwartet :  <zahl>; 
+                    <funktions aufruf>; 
+                    <macro aufruf>; 
+                    <gleichungs name>; 
+                    '(', <ausdruck>, ')'; 
+                    <monadischer operator>, <faktor>. 
+                    <monadischer operator> ::= '+'; '-'. 
+ 
+45  TIME MUSS MIT '.J' ODER '.K' SUBSKRIBIERT WERDEN 
+ 
+46  SYMBOL NICHT DEFINIERT 
+ 
+47  FUNKTION NICHT DEFINIERT 
+ 
+48  UNZULAESSIGE INDIZIERUNG 
+    ->  Die Indices auf beiden Seiten der Gleichung müssen immer gleich sein. 
+ 
+49  FALSCHE PARAMETERANZAHL 
+ 
+50  FALSCHES TRENNSYMBOL ZWISCHEN PARAMETERN 
+ 
+51  ALS PARAMETER TABLE ERWARTET 
+ 
+52  FALSCHER PARAMETER IN TABLEFUNKTION 
+ 
+53  ZU VIELE AKTUELLE PARAMETER 
+ 
+54  ')' NACH MAKROAUFRUF FEHLT 
+ 
+55  REKURSIVER MAKROAUFRUF 
+ 
+56  BEI N - GLEICHUNG KEINE SUBSKRIPTION ERLAUBT 
+ 
+57  FALSCHE SUBSKRIPTION IN AUXILIARY - GLEICHUNG 
+ 
+58  ')' ERWARTET 
+ 
+59  FALSCHE SUBSKRIPTION IN LEVEL - GLEICHUNG 
+ 
+60  FALSCHE SUBSKRIPTION IN RATE - GLEICHUNG 
+ 
+61  FOR - VARIABLE NICHT DEFINIERT 
+    ->  Eine FOR - Variable muß vor der ersten Benutzung definiert werden. 
+ 
+62  KONSTANTE ERWARTET 
+ 
+63  FALSCHES REAL - FORMAT 
+    ->  Exponent fehlt 
+ 
+64  GLOBALE GLEICHUNG IN MACRO NICHT ERLAUBT 
+ 
+65  DOPPELTE DEFINITION BEI MEHRFACHEM MAKROAFRUF 
+ 
+66  ALS NOISE - PARAMETER ZAHL ERWARTET 
+#page# 
+ 
+#ib#4. Anweisungen und Funktionen des
+   EUMEL-DYNAMO-Compilers#ie# 
+#goal page ("Anweisungen und Funktionen")# 
+ 
+ 
+Dieses Kapitel gibt eine alphabetische Übersicht über die im EUMEL-DYNAMO-
+Compiler realisierten Anweisungen und Funktionen (wertliefernde Algorithmen). 
+ 
+Die Beschreibung der Anweisungen und Funktionen ist nach der DYNAMO-
+Syntaxregel angegeben, wobei folgende Zeichen mit besonderer Bedeutung verwendet
+werden: 
+ 
+  []          optionale Angabe 
+  [...]       beliebig häufige Wiederholung der letzten optionalen Angabe 
+  < >         in spitzen Klammern stehende Namen sind Variablen- bzw. Konstan­
+              tennamen 
+  <Name>      steht für einen beliebigen Bezeichner gemäß der DYNAMO-Syntax 
+  <Zahl>      bezeichnet einen beliebigen Wert (also auch eine Ausdruck) 
+  {}          Alternative Angabe 
+ 
+  X           DYNAMO Anweisung, kennzeichnet eine Fortsetzungsszeile der
+              vorhergegangenen Anweiung (S. #to page ("X")#) 
+ 
+Alle Anweisungen und Funktionen werden nach dem gleichen Schema dargestellt: 
+ 
+ 
+ 
+Funktionsname#right#Typ (Funkt. oder Anweisung) 
+ 
+ 
+Zweck:     Schlagwort zur Wirkung 
+ 
+Format:    Beschreibung des Formates (spezielle Zeichen s.o.) 
+ 
+Erklärung: kurze Beschreibung der Anweisung/Funktion 
+ 
+Beispiel:  Anwendung der Anweisung/Funktion 
+ 
+Programm:  Beispielprogramm, in welchem die Anweisung/Funktion angewendet wird. 
+ 
+Referenz:  Verweis auf ähnliche oder äquivalente Anweisungen/Funktionen im
+           Format '<Funktions- bzw. Anweisungsname>, Seitennummer'. 
+ 
+ 
+Eine oder mehrere dieser Felder können fehlen (z.B. wenn es keine Referenz oder
+kein Beispielprogramm gibt). 
+#page# 
+ 
+ 
+ 
+#ib#4.1. Übersicht über die Anweisungen und
+     Funktionen#ie# 
+ 
+ 
+ 
+#goal page ("A")##ib (2)#A#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Auxiliary-Gleichung (A-Gleichung, Hilfsgleichung) 
+ 
+Format:    A <Auxiliary-Name>.K=<Ausdruck>#u##count ("Ausdruck")##e# 
+#foot# 
+#u##value ("Ausdruck")##e# genaueres über die Definition eines Ausdruckes siehe [1], S. 93 
+#end# 
+ 
+Erklärung: Mit Hilfe von Auxiliary-Gleichungen werden Level- und Hilfsgrößen
+           (Auxiliaries) zum selben Zeitpunkt verknüpft. 
+ 
+Beispiel:  A JM.K=MM.K/MEJ 
+ 
+Programm:  "dyn.workfluc" 
+ 
+ 
+ 
+#ib (2)#ABS#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Absolutbetrag 
+ 
+Format:    ABS(<Zahl>) 
+ 
+Erklärung: Liefert den Absolutbetrag 
+ 
+ 
+           IF <Zahl> >= 0 THEN 
+             <Zahl> 
+           ELSE 
+             -  <Zahl> 
+           END IF  
+ 
+Beispiel:  N X=ABS(A*2.0) 
+ 
+ 
+ 
+#goal page ("ARCTAN")#ARCTAN#on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Berechnung der trigonometrischen Funktion Arcustangens 
+ 
+Format:    ARCTAN(<Zahl>) 
+ 
+Erklärung: Berechnet den Arcustangens von <Zahl>; Ergebnis im Bogenmaß. 
+ 
+Beispiel:  N X=ARCTAN(TAN(1.3))                (X = 1.3) 
+ 
+ 
+Referenz:  COSD, S. #to page ("COSD")# 
+           SIN, S. #to page ("SIN")# 
+           SIND, S. #to page ("SIND")# 
+           TAN, S. #to page ("TAN")# 
+           TAND, S. #to page ("TAND")# 
+           ARCTAND, S. #to page ("ARCTAN")# 
+           COS, S. #to page ("COS")# 
+ 
+ 
+ 
+#goal page ("ARCTAND")##ib (2)#ARCTAND#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Berechnung der trigonometrischen Funktion Arcustangens 
+ 
+Format:    ARCTAND(<Zahl>) 
+ 
+Erklärung: Berechnet den Arcustangens von <Zahl>; Ergebnis im Gradmaß 
+ 
+Beispiel:  N X=ARCTAND(TAND(45.0))             (X = 45.0) 
+ 
+ 
+Referenz:  COSD, S. #to page ("COSD")# 
+           SIN, S. #to page ("SIN")# 
+           SIND, S. #to page ("SIND")# 
+           TAN, S. #to page ("TAN")# 
+           TAND, S. #to page ("TAND")# 
+           COS, S. #to page ("COS")# 
+           ARCTAN, S. #to page ("ARCTAND")# 
+ 
+ 
+ 
+#goalpage ("C")##ib (2)#C#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Konstantendefinition 
+ 
+Format:    C <Name>=<Zahl> 
+ 
+Erklärung: Werte, die während eines Simulationslaufes gleich bleiben, können durch
+           die Konstantendefintion benannt werden (s. auch 'c' im Runtime-
+           System). 
+ 
+Beispiel:  C POPI=30.3 
+ 
+Programm:  "dyn.wohnen" 
+ 
+ 
+ 
+#goal page ("CLIP")##ib (2)#CLIP#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Wert nach Bedingung 
+ 
+Format:    CLIP(<Zahl1>,<Zahl2>,<Zahl3>,<Zahl4>) 
+ 
+Erklärung: Liefert den Wert des ersten Argumentes, wenn das dritte Argument
+           größer oder gleich dem vierten Argument ist. Andernfalls wird der Wert
+           des zweiten Argumentes geliefert. 
+ 
+ 
+           IF <Zahl3> >= <Zahl4> THEN 
+             <Zahl1> 
+           ELSE 
+             <Zahl2> 
+           END IF  
+ 
+Beispiel:  N X=CLIP(1.0,2.0,3.0,4.0)         (X = 2.0) 
+ 
+ 
+Programm:  "dyn.welt/forrester" 
+ 
+Referenz:  FIFGE, S. #to page ("FIFGE")#     (äquivalente Funktion) 
+ 
+ 
+ 
+#goalpage ("COS")#COS#on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Berechnung der trigonometrischen Funktion Cosinus 
+ 
+Format:    COS(<Zahl>) 
+ 
+Erklärung: Es wird der Cosinus des Wertes <Zahl>, welcher im Bogenmaß vorlie­
+           gen muß, geliefert. 
+ 
+Beispiel:  N X=COS(1.6)  
+ 
+Referenz:  COSD, S. #to page ("COSD")# 
+           SIN, S. #to page ("SIN")# 
+           SIND, S. #to page ("SIND")# 
+           TAN, S. #to page ("TAN")# 
+           TAND, S. #to page ("TAND")# 
+           ARCTAN, S. #to page ("ARCTAN")# 
+           ARCTAND, S. #to page ("ARCTAND")# 
+ 
+ 
+ 
+#goal page ("COSD")##ib (2)#COSD#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Berechnung der trigonometrischen Funktion Cosinus 
+ 
+Format:    COSD(<Zahl>) 
+ 
+Erklärung: Es wird der Cosinus des Wertes <Zahl>, welcher im Gradmaß vorliegen
+           muß, geliefert. 
+ 
+Beispiel:  N X=COSD(33.5)  
+ 
+Referenz:  COS, S. #to page ("COS")# 
+           SIN, S. #to page ("SIN")# 
+           SIND, S. #to page ("SIND")# 
+           TAN, S. #to page ("TAN")# 
+           TAND, S. #to page ("TAND")# 
+           ARCTAN, S. #to page ("ARCTAN")# 
+           ARCTAND, S. #to page ("ARCTAND")# 
+ 
+ 
+ 
+#goal page ("EXP")##ib (2)#EXP#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Exponentialfunktion zur Basis e 
+ 
+Format:    EXP(<Zahl>) 
+ 
+Erklärung: Liefert e#u#<Zahl>#e# 
+ 
+Beispiel:  N X=EXP(1.0)                          (X = 2.71 = e) 
+ 
+ 
+Referenz:  LN, S. #to page ("LN")#           (Umkehrfunktion) 
+ 
+ 
+ 
+#goal page ("FIFGE")##ib (2)#FIFGE#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Wert nach Bedingung (#on ("u")#f#off ("u")#irst #on ("u")#if#off ("u")# #on ("u")#g#off ("u")#reater or #on ("u")#e#off ("u")#qual) 
+ 
+Format:    FIFGE(<Zahl1>,<Zahl2>,<Zahl3>,<Zahl4>) 
+ 
+Erklärung: Liefert den Wert des ersten Argumentes, wenn das dritte Argument
+           größer oder gleich dem vierten Argument ist. Andernfalls wird der Wert
+           des zweiten Argumentes geliefert. 
+ 
+ 
+           IF <Zahl3> >= <Zahl4> THEN 
+             <Zahl1> 
+           ELSE 
+             <Zahl2> 
+           END IF  
+ 
+Beispiel:  N X=FIFGE(1.0,2.0,3.0,4.0)         (X = 2.0) 
+ 
+ 
+Referenz:  CLIP, S. #to page ("CLIP")#          (äquivalente Funktion) 
+ 
+ 
+ 
+#goal page ("FIFZE")##ib (2)#FIFZE#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Wert nach Bedingung (#on ("u")#f#off ("u")#irst #on ("u")#if#off ("u")# #on ("u")#ze#off ("u")#ro) 
+ 
+Format:    FIFZE(<Zahl1>,<Zahl2>,<Zahl3>) 
+ 
+Erklärung: Wenn der Parameter <Zahl3> den Wert 0 hat, so wird <Zahl1>
+           geliefert, andernfalls <Zahl2> 
+ 
+ 
+           IF <Zahl3> = 0 THEN 
+             <Zahl1> 
+           ELSE 
+             <Zahl2> 
+           END IF  
+ 
+Beispiel:  N X=FIFZE(1.0,2.0,3.0)              (X = 2.0) 
+ 
+ 
+Referenz:  SWITCH, S. #to page ("SWITCH")# 
+ 
+ 
+ 
+#goal page ("FLOOR")##ib (2)#FLOOR#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Vorkommastellen 
+ 
+Format:    FLOOR(<Zahl>) 
+ 
+Erklärung: Liefert die Vorkommastellen von <Zahl> 
+ 
+Beipiel:   N X=FLOOR(3.14)                      (X = 3.0) 
+ 
+ 
+Referenz:  FRAC, S. #to page ("FRAC")# 
+ 
+ 
+ 
+#ib (2)#FOR#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Schleifen-Definition 
+ 
+Format:    FOR <Name>=<Zahl1>,<Zahl2> 
+ 
+Erklärung: <Name> bezeichnet eine Schleifenvariable, die von <Zahl1> bis
+           <Zahl2> hochgezählt wird. Somit ist es möglich, gleiche Berechnungen
+           für die verschiedenen Werte einer Tabelle durchzuführen. 
+ 
+Beispiel:  FOR BERECHNUNGSZEITRAUM=1900,2100 
+ 
+ 
+Programm:  "dyn.bev" 
+ 
+ 
+ 
+#goal page ("FRAC")##ib (2)#FRAC#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Nachkommastellen 
+ 
+Format:    FRAC(<Zahl>) 
+ 
+Erklärung: Liefert die Nachkommastellen von <Zahl> 
+ 
+Beispiel:  N X=FRAC(3.14)                        (X = 0.14) 
+ 
+ 
+Referenz:  FLOOR, S. #to page ("FLOOR")# 
+ 
+ 
+ 
+#goal page ("L")##ib (2)#L#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Level-Gleichung 
+ 
+Format:    L <Level-Name>.K=<Level-Name>.J+ 
+                            <Vergangenheitsausdruck> 
+ 
+Erklärung: Die Level-Gleichung stellt einen gegenwärtigen Wert in Bezug zu
+           seinem Wert in der Vergangenheit und seiner Veränderungsrate in der
+           bis dahin vergangenen Zeit (Vergangenheitsausdruck s. [1], S. 96). 
+ 
+Beispiel:  L HASEN.K=CLIP(HASEN.J+DT*(HGRATE.JK 
+           X         -HSRATE.JK),0,HASEN.J,0)  
+ 
+Programm:  "dyn.grashasenfuchs" 
+ 
+ 
+ 
+#goal page ("LN")##ib (2)#LN#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Logarithmus-Funktion 
+ 
+Format:    LN(<Zahl>) 
+ 
+Erklärung: Berechnet den natürlichen Logarithmus von <Zahl> 
+ 
+Beispiel:  N X=LN(1.0)                           (X = 0.0) 
+ 
+ 
+Programm:  "dyn.wasseröko" 
+ 
+Referenz:  LOG2, S. #to page ("LOG2")# 
+           LOG10, S. #to page ("LOG10")# 
+           EXP, S. #to page ("EXP")# 
+ 
+ 
+ 
+#goal page ("LOG2")##ib (2)#LOG2#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Logarithmus-Funktion 
+ 
+Format:    LOG2(<Zahl>) 
+ 
+Erklärung: Berechnet den Logarithmus von <Zahl> zur Basis 2 
+ 
+Beispiel:  N X=LOG2(8.0)                         (X = 3.0) 
+ 
+ 
+Referenz:  LN, S. #to page ("LN")# 
+           LOG10, S. #to page ("LOG10")# 
+ 
+ 
+ 
+#goal page ("LOG10")##ib (2)#LOG10#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Logarithmus-Funktion 
+ 
+Format:    LOG10(<Zahl>) 
+ 
+Erklärung: Berechnet den Logarithmus von <Zahl> zur Basis 10 
+ 
+Beispiel:  N X=LOG10(100.0)                      (X = 2.0) 
+ 
+ 
+Referenz:  LOG2, S. #to page ("LOG2")# 
+           LN, S. #to page ("LN")# 
+           EXP, S. #to page ("EXP")# 
+ 
+ 
+ 
+#goal page ("MACRO")##ib (2)#MACRO#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Macro-Definition 
+ 
+Format:    MACRO <Name>(<Ausdruck>[,<Ausdruck>[...]]) 
+ 
+Erklärung: Durch die Verwendung der MACRO-Anweisung können Sie einer oder
+           mehreren DYNAMO-Gleichungen einen Namen geben (<Name>).
+           Macros müssen durch MEND abgeschloßen werden und dürfen #on ("u")#nicht#off ("u")#
+           rekursiv aufgerufen werden (vergl. Refinements in ELAN). 
+ 
+Beispiel:  MACRO SMOOTH(IN,DEL) 
+           L     SMOOTH.K=SMOOTH.J+DT*(IN.J-SMOOTH.J)/DEL 
+           N     SMOOTH=IN 
+           MEND  
+ 
+Programm:  "dyn.mac"     (diese Datei enthält alle bisherigen Makros) 
+ 
+Referenz:  MEND, S. #to page ("MEND")# 
+ 
+ 
+ 
+#goal page ("MAX")##ib (2)#MAX#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Maximum zweier Größen 
+ 
+Format:    MAX(<Zahl1>,<Zahl2>) 
+ 
+Erklärung: Liefert die größere Zahl aus <Zahl1> und <Zahl2> 
+ 
+ 
+           IF <Zahl1> > <Zahl2> THEN 
+             <Zahl1> 
+           ELSE 
+             <Zahl2> 
+           END IF  
+ 
+Beispiel:  N X=MAX(1.0,2.0)                     (X = 2.0) 
+ 
+ 
+Referenz:  MIN, S. #to page ("MIN")# 
+ 
+ 
+ 
+#goal page ("MEND")##ib (2)#MEND#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Macro-Definition 
+ 
+Format:    MEND 
+ 
+Erklärung: MEND beendet eine Macro-Definition 
+ 
+Beispiel:  MACRO SMOOTH(IN,DEL)  
+           L     SMOOTH.K=SMOOTH.J+DT*(IN.J-SMOOTH.J)  
+           X     /DEL  
+           N     SMOOTH=IN 
+           MEND  
+ 
+Programm:  "dyn.mac"       (diese Datei enthält alle bisherigen Makros) 
+ 
+Referenz:  MACRO, S. #to page ("MACRO")# 
+ 
+ 
+ 
+#goal page ("MIN")##ib (2)#MIN#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Minimum zweier Größen 
+ 
+Format:    MIN(<Zahl1>,<Zahl2>) 
+ 
+Erklärung: Liefert die kleinere Zahl aus <Zahl1> und <Zahl2> 
+ 
+Beispiel:  N X=MIN(1.0,2.0)                     (X = 1.0) 
+ 
+ 
+Programm:  "dyn.forst7" 
+ 
+Referenz:  MAX, S. #to page ("MAX")# 
+ 
+ 
+ 
+#goal page ("N")##ib (2)#N#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Initialisierungsgleichung 
+ 
+Format:    N <Name>=<Zahl> 
+ 
+Erklärung: Initialisert eine Variable mit dem Bezeichner <Name> auf den Wert
+           <Zahl>, d.h. es wird ihr ein Startwert zugewiesen. 
+ 
+Beispiel:  N X=1900  
+ 
+Programm:  "dyn.grashasenfuchs" 
+ 
+ 
+ 
+#goal page ("NOISE")##ib (2)#NOISE#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Pseudo-Zufallszahlen-Generator 
+ 
+Format:    NOISE(<Zahl>) 
+ 
+Erklärung: Diese Funktion liefert eine Pseudo-Zufallszahl zwischen -0.5 und +0.5
+           und setzt einen neuen Startwert für den Generator fest. Der Parameter
+           <Zahl> wird nicht ausgewertet. 
+ 
+Beispiel:  N X=NOISE(0) 
+ 
+Referenz:  NORMRN, S. #to page ("NORMRN")# 
+ 
+ 
+ 
+#goal page ("NORMRN")##ib (2)#NORMRN#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Pseudo-Zufallszahlen-Generator 
+ 
+Format:    NORM(<Zahl1>,<Zahl2>) 
+ 
+Erklärung: Liefert einen Wert zwischen <Zahl1> - <Zahl2> * 2.4 und <Zahl1>
+           + <Zahl2> * 2.4. 
+ 
+Beispiel:  N X=NORM(1.0,10.0) 
+ 
+Referenz:  NOISE, S. #to page ("NOISE")# 
+ 
+ 
+ 
+#ib (2)#NOTE#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Kommentar 
+ 
+Format:    NOTE <Kommentarzeile> 
+ 
+Erklärung: Die Zeilen, die mit NOTE gekennzeichnet sind, werden vom Compiler als
+           Kommentarzeilen erkannt und nicht beachtet. NOTE-Zeilen haben nur
+           dokumentierenden Charakter und sind für den Programmlauf ohne jede
+           Bedeutung. Dennoch sollte man, wenn immer möglich, Kommentare in
+           sein DYNAMO-Programm einfügen, denn sie sind in DYNAMO an­
+           nähernd die einzige Möglichkeit, ein Programm lesbar zu machen, damit
+           es auch nach längerer Zeit noch korrigiert werden kann. 
+ 
+Beispiel:  NOTE Dies ist eine Kommentarzeile 
+ 
+Programm:  "dyn.welt/forrester" 
+ 
+ 
+ 
+#goal page ("PLOT")##ib (2)#PLOT#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Darstellen der Ergebnisse in Diagrammform 
+ 
+Format:    PLOT <Name>[=<Druckzeichen>][(<Skalenbegin>, 
+                        <Skalenende>)][/...][,...] 
+ 
+Erklärung: Durch diese Anweisung werden die Größen nach PLTPER Zeiteinheiten
+           in einem Diagramm ausgegeben. Die Angabe eines Druckzeichens ist
+           nur bei zeichenorientierten Grafik erforderlich, denn bei hochauflösender
+           Grafik werden die Graphen der verschiedenen Größen durch unterschied­
+           liche Linientypen gezeichnet; fehlt bei der zeichenorientierten Grafik das
+           Druckzeichen, so werden die Graphen durch die Zahlen von 0...9 darge­
+           stellt. Bei "/" werden verschiedene, bei "," gleiche Skalen benutzt. 
+ 
+Beispiel:  PLOT GRAS=G(995,1005)/HASEN=H(85,115)  
+           X    /FUECHS=F(15,35)  
+ 
+Programm:  "dyn.grashasenfuchs" 
+ 
+Referenz:  PRINT, S. #to page ("PRINT")# 
+ 
+ 
+ 
+#goal page ("POWER")##ib (2)#POWER#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Potenzfunktion 
+ 
+Format:    POWER(<Zahl1>,<Zahl2>) 
+ 
+Erklärung: Liefert <Zahl1>#u#<Zahl2>#e# 
+ 
+Beipiel:   N X=POWER(2, 2)                       (X = 4) 
+ 
+ 
+Referenz:  SQRT, S. #to page ("SQRT")# 
+ 
+ 
+ 
+#goal page ("PRINT")##ib (2)#PRINT#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Darstellung der Ergebnisse in Tabellenform 
+ 
+Format:    PRINT <Name>[/...][,...] 
+ 
+Erklärung: Durch diese Anweisung werden die Werte (<Name>) nach PRTPER
+           Zeiteinheiten in einer Tabelle ausgegeben. Die Ausgabe kann umgeleitet
+           werden (s. 'protokoll'). 
+ 
+Beispiel:  PRINT GBEV,BEV(1),BEV(40),BEV(60),BEV(63)  
+           X     ,BEV(65),ZBEV,PRENT 
+ 
+Programm:  "dyn.bev" 
+ 
+Referenz:  PLOT, S. #to page ("PLOT")# 
+ 
+ 
+ 
+#goal page ("R")##ib (2)#R#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Rate-Gleichung 
+ 
+Format:    R<Rate-Name>.KL=<Gegenwartsausdruck> 
+ 
+Erklärung: Eine Rate-Gleichung stellt die Veränderungsrate in Bezug zu den aktu­
+           ellen Level-Größen. 
+ 
+Beispiel:  R FGRATE.KL=FGK*HASEN*FUECHS.K 
+ 
+ 
+Programm:  "dyn.grashasenfuchs" 
+ 
+Referenz:  A, S. #to page ("A")# 
+           C, S. #to page ("C")# 
+           L, S. #to page ("L")# 
+ 
+ 
+ 
+#ib (2)#RAMP#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Wert nach Bedingung 
+ 
+Format:    RAMP(<Zahl1>,<Zahl2>) 
+ 
+Erklärung: Wenn TIME kleiner <Zahl2>, dann liefert RAMP 0, andernfalls wird
+           <Zahl1> * (TIME - <Zahl2>) geliefert. 
+ 
+ 
+           IF TIME < <Zahl2> THEN 
+             0 
+           ELSE 
+             <Zahl1> * (TIME - <Zahl2>) 
+           END IF  
+ 
+ 
+ 
+#goal page ("RUN")##ib (2)#RUN#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Überschrift 
+ 
+Format:    RUN <Überschrift> 
+ 
+Erklärung: Gibt dem aktuellen Lauf eine Überschrift. Gleichzeitig ist
+           "<Überschrift>.const" der Name eines Datenraums, in dem die Kon­
+           stanten dieses Laufs aufgehoben werden (s. 'run' im Runtime-System). 
+ 
+Beispiel:  RUN Überschrift  
+ 
+Referenz:  *, S. #to page ("*")# 
+ 
+ 
+ 
+#ib (2)#S#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Supplementary-Gleichung 
+ 
+Format:    S <Name>.K=<Vergangenheitsausdruck> 
+ 
+Erklärung: Gleichungen für Hilfsgrößen werden durch Supplementary-Gleichungen
+           ausgedrückt. 
+ 
+Beispiel:  S SCHADSTOFFVERHÄLTNIS.K=COZWEI.K/OZWEI.K 
+ 
+ 
+ 
+ 
+#ib (2)#SCLPRD#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Skalarprodukt 
+ 
+Format:    SCLPRD(<Tabelle1>,<Zahl1>,<Zahl2>,<Tabelle2>,<Zahl3>) 
+ 
+Erklärung: Liefert das Skalarprokukt der Tabellen <Tabelle1> und <Tabelle2>,
+           wobei <Zahl1> und <Zahl2> den Ausschnitt aus der ersten Tabelle
+           angeben und <Zahl3> den Startindex für den Vektor in der zweiten
+           Tabelle angibt. 
+ 
+Beispiel:  GB.K=SCLPRD(BEV.K,15,44,GR,1)/2 
+ 
+ 
+Programm:  "dyn.bev" 
+ 
+ 
+ 
+#goal page ("SIN")##ib (2)#SIN#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Berechnung der trigonometrischen Funktion Sinus 
+ 
+Format:    SIN(<Zahl>) 
+ 
+Erklärung: Berechnet den Sinus von <Zahl>, welche im Bogenmaß angegeben
+           wird. 
+ 
+Beispiel:  N X=SIN(0.5) 
+ 
+Referenz:  COS, S. #to page ("COS")# 
+           COSD, S. #to page ("COSD")# 
+           SIND, S. #to page ("SIND")# 
+           TAN, S. #to page ("TAN")# 
+           TAND, S. #to page ("TAND")# 
+           ARCTAN, S. #to page ("ARCTAN")# 
+           ARCTAND, S. #to page ("ARCTAND")# 
+ 
+ 
+ 
+#goal page ("SIND")##ib (2)#SIND#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Berechnung der trigonometrischen Funktion Sinus 
+ 
+Format:    SIND(<Zahl>) 
+ 
+Erklärung: Berechnet den Sinus von <Zahl>, welche im Gradmaß angegeben wird. 
+ 
+Beispiel:  N X=SIND(45.0)  
+ 
+Referenz:  COS, S. #to page ("COS")# 
+           SIN, S. #to page ("SIN")# 
+           COSD, S. #to page ("COSD")# 
+           TAN, S. #to page ("TAN")# 
+           TAND, S. #to page ("TAND")# 
+           ARCTAN, S. #to page ("ARCTAN")# 
+           ARCTAND, S. #to page ("ARCTAND")# 
+ 
+ 
+ 
+#ib (2)#SPEC#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Lauf-Anweisung 
+ 
+                   DT=<Zahl1> 
+Format:    SPEC {  LENGTH=<Zahl2>    }[/...] 
+                   PLTPER=<Zahl3> 
+                   PRTPER=<Zahl4> 
+ 
+Erklärung: Durch die Lauf-Anweisung werden die Systemkonstanten festgesetzt.
+           Sie darf pro Lauf nur einmal benutzt werden. 
+ 
+Beispiel:  SPEC DT=1/PLTPER=1/PRTPER=1/LENGTH=2000 
+ 
+ 
+Referenz:  C, S. #to page ("C")#     (SPEC kann durch C-Def. ersetzt werden) 
+ 
+ 
+ 
+#goal page ("SQRT")##ib (2)#SQRT#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Quadratwurzel 
+ 
+Format:    SQRT(<Zahl>) 
+ 
+Erklärung: Berechnet die Quadratwurzel aus <Zahl> 
+ 
+Beispiel:  N X=SQRT(4.0)                         (X = 2.0) 
+ 
+ 
+Referenz:  POWER, S. #to page ("POWER")# 
+ 
+ 
+ 
+#ib (2)#STEP#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+Zweck:     Wert nach Bedingung 
+ 
+Format:    STEP(<Zahl1>,<Zahl2>) 
+ 
+Erklärung: Ist TIME kleiner <Zahl2>, so wird 0 geliefert, ansonsten <Zahl1> 
+ 
+ 
+           IF TIME < <Zahl2> THEN 
+             0.0 
+           ELSE 
+             <Zahl1> 
+           END IF  
+ 
+Beispiel:  N X=STEP(12.0,12.0)  
+ 
+ 
+ 
+#goal page ("SUM")##ib (2)#SUM#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Summierung einer Tabelle 
+ 
+Format:    SUM(<Tabelle>) 
+ 
+Erklärung: Liefert die Summe der Einträge in einer Tabelle 
+ 
+Beispiel:  A GESAMTBEV.K=SUM(BEV.K) 
+ 
+Programm:  "dyn.bev" 
+ 
+Referenz:  SUMV, S. #to page ("SUMV")# 
+ 
+ 
+ 
+#goal page ("SUMV")##ib (2)#SUMV#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Summierung einer Tabelle 
+ 
+Format:    SUMV(<Tabelle>,<Zahl1>,<Zahl2>) 
+ 
+Erklärung: Summierung der Einträge in der Tabelle von Element <Zahl1> bis
+           Element <Zahl2> 
+ 
+Beispiel:  A ZBEV.K=SUMV(BEV.K,16,59)          Teilbevölkerung 
+ 
+ 
+Programm:  "dyn.bev" 
+ 
+Referenz:  SUM, S. #to page ("SUM")# 
+ 
+ 
+ 
+#goal page ("SWITCH")##ib (2)#SWITCH#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Wert nach Bedingung 
+ 
+Format:    SWITCH(<Zahl1>,<Zahl2>,<Zahl3>) 
+ 
+Erklärung: Wenn der Parameter <Zahl3> den Wert 0 hat, so wird <Zahl1>
+           geliefert, andernfalls <Zahl2> (gleichbedeutend mit FIFZE). 
+ 
+ 
+           IF <Zahl3> = 0 THEN 
+             <Zahl1> 
+           ELSE 
+             <Zahl2> 
+           END IF  
+ 
+Beispiel:  N X=SWITCH(1.0,2.0,3.0)              (X = 2.0) 
+ 
+ 
+Referenz:  FIFZE, S. #to page ("FIFZE")# 
+ 
+ 
+ 
+#goal page ("T")##ib (2)#T#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Tabellen-Definition 
+ 
+Format:    T <Name>=<Zahl1>[/<Zahl2>[....]] 
+ 
+Erklärung: Durch die T-Anweisung wird eine Tabelle definiert, die Elemente wer­
+           den durch "/" getrennt hintereinander angegeben. 
+ 
+Beispiel:  T TABELLE=1/2/3/4/5/6/8/9/10/11/12 
+ 
+ 
+Programm:  "dyn.bev" 
+ 
+Referenz:  TABLE, S. #to page ("TABLE")# 
+           TABHL, S. #to page ("TABHL")# 
+ 
+ 
+ 
+#goal page ("TABHL")##ib (2)#TABHL#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Tabellenfunktion 
+ 
+Format:    TABHL(<Tabelle>,<Zahl1>,<Zahl2>,<Zahl3>) 
+ 
+Erklärung: IF <Zahl1> < <Zahl2> THEN  
+             <Tabelle> (<Zahl2>)  
+           ELIF <Zahl2> <= <Zahl1> AND <Zahl1> <= <Zahl3> THEN  
+             TABLE (<Tabelle>, <Zahl1>, <Zahl2>, <Zahl3>)  
+           ELSE  
+             <Tabelle> (<Zahl3>)  
+           END IF  
+ 
+Beispiel:  A BRMM.K=TABHL(BRMMT,MSL.K,0,5,1) 
+ 
+ 
+Programm:  "dyn.welt/forrester" 
+ 
+Referenz:  T, S. #to page ("T")# 
+           TABLE, S. #to page ("TABLE")# 
+ 
+ 
+ 
+#goal page ("TABLE")##ib (2)#TABLE#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Tabellenfunktion 
+ 
+Format:    TABLE(<Tabelle>,<Zahl1>,<Zahl2>,<Zahl3>,<Zahl4>) 
+ 
+Erklärung: Verknüpft die Werte aus <Tabelle> mit <Zahl1>, wobei <Zahl2> den
+           ersten und <Zahl3> den letzten Tabelleneintrag angibt. <Zahl4> stellt
+           die Schrittweite dar. 
+ 
+Beispiel:  T TABELLE=1/2/3/4/5  
+           A BEISP.K=TABLE(TABELLE,X.K,2,4,1)  
+ 
+Programm:  "dyn.welt/forrester" 
+ 
+Referenz:  T, S. #to page ("T")# 
+           TABHL, S. #to page ("TABHL")# 
+ 
+ 
+ 
+#goal page ("TAN")##ib (2)#TAN#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Berechnung der trigonometrischen Funktion Tangens 
+ 
+Format:    TAN(<Zahl>) 
+ 
+Erklärung: Berechnet den Tangens von <Zahl>, welche im Bogenmaß angegeben
+           wird. 
+ 
+Beispiel:  N X=TAN(0.5)  
+ 
+Referenz:  COS, S. #to page ("COS")# 
+           SIN, S. #to page ("SIN")# 
+           COSD, S. #to page ("COSD")# 
+           SIND, S. #to page ("TAN")# 
+           TAND, S. #to page ("TAND")# 
+           ARCTAN, S. #to page ("ARCTAN")# 
+           ARCTAND, S. #to page ("ARCTAND")# 
+ 
+ 
+ 
+#goal page ("TAND")##ib (2)#TAND#ie (2)##on ("i")##right#Funktion#off ("i")# 
+ 
+ 
+Zweck:     Berechnung der trigonometrischen Funktion Tangens 
+ 
+Format:    TAND(<Zahl>) 
+ 
+Erklärung: Berechnet den Tangens von <Zahl>, welche im Gradmaß angegeben
+           wird. 
+ 
+Beispiel:  N X=TAND(45.0)  
+ 
+Referenz:  COS, S. #to page ("COS")# 
+           SIN, S. #to page ("SIN")# 
+           COSD, S. #to page ("COSD")# 
+           TAN, S. #to page ("TAN")# 
+           SIND, S. #to page ("SIND")# 
+           ARCTAN, S. #to page ("ARCTAN")# 
+           ARCTAND, S. #to page ("ARCTAND")# 
+ 
+ 
+ 
+#goalpage ("X")##ib (2)#X#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Fortsetzungszeile 
+ 
+Format:    X <Fortsetzungszeile> 
+ 
+Erklärung: Eine in der vorangegangenen Zeile nicht beendete Anweisung wird nach
+           einer X-Anweisung fortgesetzt (Es können beliebig viele X-Anweisun­
+           gen nacheinander folgen). 
+ 
+Beispiel:  T TABELLE=1/2/3/4/5/6/7/8/9/10/11/12/13/14 
+           X         /15/16/17/18/19  
+ 
+Programm:  "dyn.bev" 
+ 
+ 
+ 
+#goal page ("*")##ib (2)#*#ie (2)##on ("i")##right#Anweisung#off ("i")# 
+ 
+ 
+Zweck:     Überschrift 
+ 
+Format:    * <Überschrift> 
+ 
+Erklärung: Gibt dem aktuellen Lauf eine Überschrift 
+ 
+Beispiel:  * Überschrift  
+ 
+Referenz:  RUN, S. #to page ("RUN")# 
+#page# 
+ 
+#ib#5. Makros in DYNAMO#ie# 
+ 
+ 
+ 
+ 
+Der DYNAMO-Compiler bietet die Möglichkeit, benutzereigene Funktionen zu definie­
+ren. Makros werden ähnlich wie Refinements in ELAN in das DYNAMO-Programm
+eingesetzt. Beim EUMEL-DYNAMO-Compiler werden mit "zz" beginnende Namen
+generiert, so daß Sie es vermeiden sollten, eigene Namen mit "zz" beginnen zu
+lassen. Weiterhin sollte man als Namen der aktuellen Parameter nicht die Namen der
+formellen Parameter verwenden. 
+ 
+Folgende Makros werden standardmäßig vom DYNAMO-Compiler zur Verfügung
+gestellt: 
+ 
+    macro delay1 (in, del)             Verzögerung erster Ordnung 
+ 
+    macro delay3 (in, del)             Verzögerung dritter Ordnung 
+                                       Material 
+ 
+    macro delay3p (in, del, ppl)       Verzögerung dritter Ordnung mit 
+                                       Pipeline 
+ 
+    macro delinf3 (in, del)            Verzögerung dritter Ordnung für 
+                                       Information 
+ 
+    macro smooth (in, del)             Verzögerung erster Ordnung für 
+                                       Information 
+ 
+ 
+ 
+ 
+#ib#5.1. Insertieren von Makros#ie# 
+ 
+ 
+ 
+ 
+Makros werden durch folgende Prozedur in die Compilertabelle eingetragen: 
+ 
+ 
+PROC insert macro (TEXT CONST filename): 
+ 
+  Zweck: Fügt die in der Datei 'filename' enthaltenen Makros in die Makrotabelle ein.
+         Die Datei sollte zweckmäßigerweise nur Makrodefinitionen enthalten. Es ist
+         - im Gegensatz zu normalen DYNAMO-Programmen - nicht nötig, die
+         Systemkonstanten zu definieren (die Standard-Makros sind in der Datei
+         "dyn.mac" enthalten; diese Datei kann beliebig ergänzt werden). 
+ 
+ 
+ 
+ 
+#ib#5.2. Aufbau eines Makros#ie# 
+ 
+ 
+ 
+ 
+Makros beginnen in DYNAMO immer mit der Anweisung MACRO (s. auch Seite #to page ("MACRO")#)
+und enden mit MEND (s. Seite #to page ("MEND")#). Dazwischen steht ein Makrorumpf, bestehend
+aus einer oder mehreren DYNAMO-Gleichungen. Beim Makroaufruf können, soweit
+vorher definiert, Parameter angegeben werden, jedoch rekursiv aufrufen kann man
+Makros nicht. 
+ 
+Beispiel:  MACRO SMOOTH (IN, DEL)  
+           L     SMOOTH.K = SMOOTH.J + DT * (IN.J - SMOOTH.J) 
+           X     /DEL  
+           N     SMOOTH   = IN  
+           MEND  
+ 
+Lokale Variablen in Makros beginnen mit einem $-Zeichen. Der Makro-Expandierer
+ersetzt das $-Zeichen durch "zz" gefolgt von einer Zahl. Aus diesem Grund sollen
+eigene Namen nicht mit "zz" beginnen. 
+ 
+Falls Sie eine Fehlermeldung bekommen, die sich auf einen mit "zz" beginnenden
+Namen bezieht, sollten Sie den Fehler in dem entsprechenden Makro suchen. 
+ 
+#on ("b")# 
+Achtung: #off ("b")#Makros sollten nur von fortgeschrittenden DYNAMO-Programmieren
+         verwendet werden, da Makros Eigenschaften von Refinements (textuelle
+         Ersetzung) und Prozeduren (Parameterübergabe) vereinigen. Der daraus
+         folgende Effekt ist nicht ganz einfach zu durchschauen. 
+#page# 
+ 
+ 
+ 
+#ib#6. Erweiterung des Sprachumfangs#ie# 
+ 
+ 
+ 
+ 
+Während Makros in DYNAMO geschrieben werden, ist es ferner möglich, die Menge
+der Funktionen mittels der Sprache ELAN zu erweitern. 
+ 
+Hierbei geht man wie folgt vor: 
+ 
+  1. Schreiben einer Funktion in ELAN (näheres siehe unten) 
+ 
+  2. Einbinden der Funktion in die Tabellen des DYNAMO-Compilers 
+ 
+    2.1. Einschreiben des Namens der Funktion, gefolgt von den Typen der Ein­
+         gabeparameter in die bestehende Datei "dyn.std", wobei folgende Typen
+         existieren: 
+ 
+           r     real (Datentyp REAL) 
+           t     table (Datentyp TAB) 
+ 
+         Abgeschlossen wird die "dyn.std"-Datei durch die Zeichensequenz "/*". 
+ 
+         Beispiele:  
+ 
+           power rr table trrrr /* 
+ 
+ 
+    2.2. Laden der Funktion(en) mittels der Prozedur 'init std ("dyn.std")' 
+ 
+ 
+Eine zur Einbindung in den DYNAMO-Compiler vorgesehene ELAN-Funktion wird
+unter Beachtung gewisser Regeln erstellt: 
+ 
+  1. Die deklarierten ELAN-Prozeduren dürfen nur Parameter vom Typ REAL oder
+     TAB besitzen oder gänzlich ohne Parameter sein. 
+ 
+  2. Der Typ des Resultaten muß vom Typ REAL sein. 
+ 
+Zur Manipulation von Tabellen wurde der Datentyp TAB geschaffen, auf welchen man
+wie auf das Standard-Vektorpaket zugreifen kann. 
+ 
+Beispiel:  
+ 
+    REAL PROC abs (REAL CONST a): 
+      IF a < 0.0 THEN 
+        -a 
+      ELSE 
+         a 
+      END IF 
+    END PROC abs; 
+ 
+    PROC sumv (TAB CONST tab, REAL CONST erstes, letztes): 
+      REAL VAR summe := 0.0; 
+      INT VAR i; 
+      FOR i FROM int (erstes) UPTO int (letztes) REPEAT 
+        summe INCR wert (tab, i) 
+      END REPEAT; 
+      summe 
+    END PROC sumv  
+ 
+ 
+ 
+ 
+#ib#6.1. Für fortgeschrittende ELAN-Program­
+     mierer#ie# 
+ 
+ 
+ 
+Der Quellcode des EUMEL-DYNAMO-Compilers wird mit ausgeliefert. Daher
+können Einschränkungen (s. 3.2 Abweichungen gegenüber dem Sprachstandard)
+leicht beseitigt werden. Wem z.B. die Anzahl der Gleichungen (950) zu wenig ist, der
+kann im Quelltext des Compilers diesen Wert (annähernd) beliebig nach oben hin
+erhöhen. 
+
diff --git a/doc/dynamo/dynamo handbuch.index b/doc/dynamo/dynamo handbuch.index
new file mode 100644
index 0000000..af77d79
--- /dev/null
+++ b/doc/dynamo/dynamo handbuch.index	
@@ -0,0 +1,69 @@
+#block##pageblock##page (52)# 
+#head# 
+#center#DYNAMO-Compiler 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottom odd# 
+#center#____________________________________________________________ 
+GMD #right#DYNAMO - % 
+#end# 
+#bottom even# 
+#center#____________________________________________________________ 
+DYNAMO - % #right#GMD 
+#end# 
+Anhang - Übersicht über Anweisungen und
+Funktionen 
+ 
+ 
+#clear pos##l pos (0.0)##r pos (10.0)##fillchar (" ")# 
+#table# 
+A   21 
+ABS   21 
+ARCTAND   22 
+C   23 
+CLIP   23 
+COSD   24 
+EXP   25 
+FIFGE   25 
+FIFZE   26 
+FLOOR   26 
+FOR   27 
+FRAC   27 
+L   28 
+LN   28 
+LOG2   29 
+LOG10   29 
+MACRO   30 
+MAX   31 
+MEND   31 
+MIN   32 
+N   32 
+NOISE   33 
+NORMRN   33 
+NOTE   34 
+PLOT   35 
+POWER   35 
+PRINT   36 
+R   36 
+RAMP   37 
+RUN   37 
+S   38 
+SCLPRD   38 
+SIN   39 
+SIND   39 
+SPEC   40 
+SQRT   40 
+STEP   41 
+SUM   41 
+SUMV   42 
+SWITCH   42 
+T   43 
+TABHL   43 
+TABLE   44 
+TAN   44 
+TAND   45 
+X   45 
+*   46 
+#table end#
+
diff --git a/doc/dynamo/dynamo handbuch.inhalt b/doc/dynamo/dynamo handbuch.inhalt
new file mode 100644
index 0000000..2d1b1f3
--- /dev/null
+++ b/doc/dynamo/dynamo handbuch.inhalt	
@@ -0,0 +1,131 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#DYNAMO 
+ 
+ 
+ 
+ 
+#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# 
+#block# 
+#center#____________________________________________________________________________ 
+ 
+ Copyright 1988 
+ 
+ Selbstverlag GMD 
+                        Alle Rechte vorbehalten. 
+                        Insbesondere ist die Überführung in maschinenlesbare
+                        Form, sowie das Speichern in Informationssystemen, auch
+                        auszugsweise, nur mit schriftlicher Genehmigung der
+                        GMD gestattet. 
+#center#____________________________________________________________________________ 
+ 
+ 
+ Herausgeber: 
+ 
+     Gesellschaft für Mathematik und Datenverarbeitung mbH 
+ 
+     Postfach 1240, Schloß Birlinghoven 
+     D-5205 Sankt Augustin 1 
+     Telefon(02241) 14-1, Telex 8 89 469 gmd d 
+     Telefax(02241) 14 28 89, BTX *43900\# 
+     Teletex 2627-224135=GMDVV 
+ 
+ 
+Autor: 
+ 
+  Christian Szymanski 
+ 
+nach Anregungen von: 
+ 
+  Diether Craemer, Robert Keil 
+ 
+überarbeitet von: 
+ 
+  Thomas Müller 
+ 
+Texterstellung: 
+ 
+  Dieser Text wurde mit der EUMEL-Textverarbeitung erstellt und aufbereitet und
+  mit dem Agfa Laserdrucksystem P400 gedruckt. 
+ 
+ 
+ 
+       Hinweis: 
+ 
+#on("italics")# 
+       Diese Dokumentation wurde mit größtmöglicher Sorgfalt erstellt. Dennoch wird
+       für die Korrektheit und Vollständigkeit der gemachten Angaben keine Gewähr
+       übernommen. Bei vermuteten Fehlern der Software oder der Dokumentation
+       bitten wir um baldige Meldung, damit eine Korrektur möglichst rasch erfolgen
+       kann. Anregungen und Kritik sind jederzeit willkommen.#off("italics")# 
+#page# 
+#pagenr ("%", 1")##setcount (1)##block##pageblock##count per page# 
+#head# 
+#center#DYNAMO-Compiler 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottom odd# 
+#center#____________________________________________________________ 
+GMD #right#DYNAMO - % 
+#end# 
+#bottom even# 
+#center#____________________________________________________________ 
+DYNAMO - % #right#GMD 
+#end# 
+ 
+Inhalt 
+ 
+ 
+ 
+#clear pos##lpos (0.0)##r pos (10.0)##fillchar (" ")# 
+#table# 
+1. Einleitung   2 
+  1.1. Referenzliteratur   2 
+  1.2. Die Programmiersprache DYNAMO   3 
+  1.3. Kurz-Einführung in die DYNAMO-Schreibweise   4 
+  1.4. Eine erste, kleine Sitzung mit dem DYNAMO-System   6 
+ 
+2. Generierung des DYNAMO-Compilers   7 
+ 
+3. Der EUMEL-DYNAMO-Compiler   8 
+  3.1. Benutzung des DYNAMO-Compiler   8 
+  3.2. Abweichungen gegenüber dem Sprachstandard   11 
+  3.3. Das DYNAMO Runtime-System   12 
+  3.4. Fehlermeldungen des DYNAMO-Compilers   14 
+ 
+4. Anweisungen und Funktionen des EUMEL-DYNAMO-Compilers   19 
+  4.1. Übersicht über die Anweisungen und Funktionen   21 
+ 
+5. Makros in DYNAMO   47 
+  5.1. Insertieren von Makros   48 
+  5.2. Aufbau eines Makros   48 
+ 
+6. Erweiterung des Sprachumfangs   50 
+  6.1. Für fortgeschrittende ELAN-Programmierer   51 
+ 
+Anhang - Übersicht über Anweisungen unf Funktionen   52 
+#table end#
+
diff --git a/doc/eudas/abb.1-1 b/doc/eudas/abb.1-1
new file mode 100644
index 0000000..06c27fd
--- /dev/null
+++ b/doc/eudas/abb.1-1
@@ -0,0 +1,94 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 7.1); (*viewport (0.0,0.0,13.5,7.1); *) 
+scale (1.0,1.0,0.0,0.0);
+(*clear pixels;*)
+ 
+karteikasten (1.0, 3.5, "Kartei A", "Wegner", "Herbert"); 
+karteikasten (5.0, 0.5, "Kartei B", "Regmann", "Karin"); 
+   
+LET myname = "abb.1-1";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+(* 
+pause (10000);
+*)
+PROC karteikasten (REAL CONST x, y, TEXT CONST name, t name, t vorname) : 
+ 
+  move (x - 0.1, y); 
+  draw (x + 3.6, y); 
+  draw (x + 3.6, y + 1.0); 
+  draw (x - 0.1, y + 1.0); 
+  draw (x - 0.1, y); 
+ 
+  move (x + 0.1, y + 1.1); 
+  draw (x + 0.5, y + 1.5); 
+  move (x + 0.1, y + 1.1); 
+  draw (x + 3.6, y + 1.1);
+  move (x - 0.1, y + 1.0); 
+  draw (x + 0.5, y + 1.6); 
+ 
+  move (x + 3.6, y); 
+  draw (x + 5.2, y + 1.6); 
+  draw (x + 5.2, y + 2.6); 
+  draw (x + 3.6, y + 1.0); 
+    move (x + 3.6, y + 1.1); draw (x + 5.0, y + 2.5); 
+    move (x + 5.2, y + 2.6); draw (x + 5.0, y + 2.6); 
+ 
+  move (x + 0.5, y + 1.1); 
+  draw (x + 0.5, y + 2.5); 
+  draw (x + 4.0, y + 2.5); 
+  draw (x + 4.0, y + 1.5); 
+  move (x + 0.5, y + 2.5); 
+  draw (x + 1.5, y + 3.5); 
+  draw (x + 5.0, y + 3.5); 
+  draw (x + 5.0, y + 2.5); 
+  move (x + 5.0, y + 3.5); 
+  draw (x + 4.0, y + 2.5); 
+  REAL VAR x off := 0.1; 
+  WHILE x off < 1.0 REP 
+    move (x + 0.5 + xoff, y + 2.5 + x off); 
+    draw (x + 4.0 + xoff, y + 2.5 + xoff); 
+    draw (x + 4.0 + xoff, y + 1.5 + xoff); 
+    x off INCR 0.1 
+  END REP; 
+  font size (0.5); 
+  font expansion (1.5); 
+  move (x + 0.5, y + 0.2); draw (name); 
+  font size (0.25);
+  move (x + 0.7, y + 2.10); draw ("Name"); 
+  move (x + 0.7, y + 1.65); draw ("Vorname"); 
+  move (x + 0.7, y + 1.20); draw ("Strasse");
+  move (x + 2.1, y + 2.10); draw (": " + t name); 
+  move (x + 2.1, y + 1.65); draw (": " + t vorname); 
+  move (x + 2.1, y + 1.20); draw (":");
+ 
+END PROC karteikasten;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/eudas/abb.4-1 b/doc/eudas/abb.4-1
new file mode 100644
index 0000000..439e052
--- /dev/null
+++ b/doc/eudas/abb.4-1
@@ -0,0 +1,43 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 3.2);   viewport (0.0,0.0,13.5,3.2);    
+(* scale (2.0,2.0,0.0,0.0); *)
+(*clear pixels;*) 
+ 
+font size (0.25); 
+font expansion (1.5);
+ 
+INT VAR i; 
+FOR i FROM 0 UPTO 4 REP 
+  move (2.0, real (i) * 0.5); 
+  draw (10.0, real (i) * 0.5); 
+  move (2.1, real (i) * 0.5 + 0.1); 
+  draw ("Feld " + code (code ("E") - i)); 
+END REP;
+move (2.0, 2.5); 
+draw (10.0, 2.5); 
+move (2.0, 2.5); 
+draw (2.0, 0.0); 
+move (3.5, 3.0); 
+draw (10.0, 3.0); 
+FOR i FROM 1 UPTO 4 REP 
+  move (2.0 + real (i) * 1.5, 3.0); 
+  draw (2.0 + real (i) * 1.5, 0.0); 
+  move (2.2 + real (i) * 1.5, 2.6); 
+  draw ("Satz " + text (i)) 
+END REP;
+move (9.5, 3.0); 
+draw (9.5, 0.0);
+(* 
+pause (1000);
+*) 
+   
+LET myname = "abb.4-1";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+ 
+
diff --git a/doc/eudas/abb.4-2 b/doc/eudas/abb.4-2
new file mode 100644
index 0000000..a836def
--- /dev/null
+++ b/doc/eudas/abb.4-2
@@ -0,0 +1,46 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 2.0); viewport (0.0,0.0,13.5,2.0); 
+(*scale (1.7,1.7,-1.6,0.0);*) 
+(* 
+clear pixels;
+*)
+ 
+kasten (1.0, 0.0, 3.0, 1.5); 
+kasten (7.0, 0.0, 3.0, 1.5); 
+font size (0.4); font expansion (1.5); 
+move (1.8, 0.6); draw ("Menü"); 
+move (7.9, 0.6); draw ("Hilfe"); 
+move (4.5, 1.0); draw (6.5, 1.0); 
+  draw (6.25, 1.25); move (6.5, 1.0); draw (6.25, 0.75); 
+move (6.5, 0.5); draw (4.5, 0.5); 
+  draw (4.75, 0.75); move (4.5, 0.5); draw (4.75, 0.25); 
+font size (0.25); 
+move (5.0, 1.1); draw ("ESC '?'"); 
+move (5.0, 0.6); draw ("ESC 'q'"); 
+move (10.5, 1.0); draw (11.5, 1.0); draw (11.5, 0.5); draw (10.5, 0.5); 
+  draw (10.75, 0.75); move (10.5, 0.5); draw (10.75, 0.25); 
+move (11.8, 0.9); draw ("ESC 'w'"); 
+move (11.8, 0.4); draw ("ESC 'z'");
+ 
+ 
+LET myname = "abb.4-2";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+(* 
+pause (9000);
+*)
+PROC kasten (REAL CONST x anf, y anf, x l, y l) : 
+ 
+  move (x anf, y anf); 
+  draw (x anf, y anf + y l); 
+  draw (x anf + x l, y anf + y l); 
+  draw (x anf +  x l, y anf); 
+  draw (x anf, y anf) 
+ 
+END PROC kasten;
+
diff --git a/doc/eudas/abb.6-1 b/doc/eudas/abb.6-1
new file mode 100644
index 0000000..fb83242
--- /dev/null
+++ b/doc/eudas/abb.6-1
@@ -0,0 +1,75 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 4.0); viewport (0.0,0.0,13.5,4.0); 
+(*scale (1.0,1.0, 0.0,0.0);*)
+(* 
+clear pixels;
+*)
+ 
+move (2.25, 1.0); draw (4.75, 1.0); 
+move (2.25, 3.0); draw (4.75, 3.0); 
+  move (2.5, 1.0); draw (2.5, 3.3); 
+  move (3.0, 1.0); draw (3.0, 3.3); 
+  move (3.5, 1.0); draw (3.5, 3.3); 
+  move (4.0, 1.0); draw (4.0, 3.3); 
+  move (4.5, 1.0); draw (4.5, 3.3); 
+font size (0.30); font expansion (1.5); 
+move (2.6, 3.1); draw ("4"); 
+move (2.6, 2.0); draw ("M");
+move (3.1, 3.1); draw ("5"); 
+move (3.1, 2.0); draw ("N"); 
+move (3.6, 3.1); draw ("6"); 
+move (3.6, 2.0); draw ("O"); 
+move (4.1, 3.1); draw ("7"); 
+move (4.1, 2.0); draw ("P"); 
+  pfeil (3.75, 0.75); 
+ 
+move (5.0, 2.0); draw (7.0, 2.0); draw (6.75, 2.25); 
+  move (7.0, 2.0); draw (6.75, 1.75); 
+move (5.0, 2.1); draw ("Einfügen"); 
+ 
+move (7.25, 1.0); draw (8.5, 1.0); move (9.0, 1.0); draw (10.25, 1.0); 
+move (7.25, 3.0); draw (8.5, 3.0); move (9.0, 3.0); draw (10.25, 3.0); 
+  move (7.5, 1.0); draw (7.5, 3.3); 
+  move (8.0, 1.0); draw (8.0, 3.3); 
+  move (8.5, 1.0); draw (8.5, 3.3); 
+  move (9.0, 1.0); draw (9.0, 3.3); 
+  move (9.5, 1.0); draw (9.5, 3.3); 
+  move (10.0, 1.0); draw (10.0, 3.3); 
+move (7.6, 3.1); draw ("4"); 
+move (7.6, 2.0); draw ("M"); 
+move (8.1, 3.1); draw ("5"); 
+move (8.1, 2.0); draw ("N"); 
+move (8.6, 3.1); draw ("6"); 
+move (9.1, 3.1); draw ("7"); 
+move (9.1, 2.0); draw ("O"); 
+move (9.6, 3.1); draw ("8"); 
+move (9.6, 2.0); draw ("P"); 
+ 
+pfeil (8.75, 0.75);
+ 
+PROC pfeil (REAL CONST x spitze, y spitze) : 
+ 
+  move (x spitze, y spitze); 
+  draw (x spitze + 0.25, y spitze - 0.25); 
+  draw (x spitze + 0.1, y spitze - 0.25); 
+  draw (x spitze + 0.1, y spitze - 0.5); 
+  draw (x spitze - 0.1, y spitze - 0.5); 
+  draw (x spitze - 0.1, y spitze - 0.25); 
+  draw (x spitze - 0.25, y spitze - 0.25); 
+  draw (x spitze, y spitze) 
+ 
+END PROC pfeil; 
+ 
+ 
+LET myname = "abb.6-1";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+(* 
+pause (9000)
+*)
+
diff --git a/doc/eudas/abb.6-2 b/doc/eudas/abb.6-2
new file mode 100644
index 0000000..7771a29
--- /dev/null
+++ b/doc/eudas/abb.6-2
@@ -0,0 +1,77 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 5.0); viewport (0.0,0.0,13.5,5.0); 
+(*scale (1.4,1.4, 0.0,0.0);*) 
+(*clear pixels;*) 
+ 
+move (2.5, 4.5); draw (12.4, 4.5); draw (12.4, 4.0); draw (11.0, 4.0); 
+  draw (11.0, 3.5); move (10.5, 3.5); draw (10.5, 4.0); draw (2.5, 4.0); 
+move (13.5, 4.5); draw (12.5, 4.5); draw (12.5, 3.5); move (13.0, 3.5); 
+  draw (13.0, 4.0); draw (13.5, 4.0); 
+move (2.5, 3.5); draw (13.5, 3.5); move (13.5, 3.0); draw (10.0, 3.0); 
+  draw (10.0, 2.5); move (9.5, 2.5); draw (9.5, 3.0); draw (2.5, 3.0); 
+move (10.5, 3.0); draw (10.5, 2.5); move (11.0, 2.5); draw (11.0, 3.0); 
+move (12.5, 2.5); draw (12.5, 3.0); move (13.0, 3.0); draw (13.0, 2.5); 
+move (2.5, 2.5); draw (6.4, 2.5); draw (6.4, 2.0); draw (4.0, 2.0); 
+  draw (4.0, 1.5); draw (6.5, 1.5); draw (6.5, 2.5); draw (13.5, 2.5); 
+  move (13.5, 2.0); draw (7.0, 2.0); draw (7.0, 1.5); draw (9.0, 1.5); 
+  draw (9.0, 1.0); draw (3.5, 1.0); draw (3.5, 2.0); draw (2.5, 2.0); 
+move (9.5, 2.0); draw (9.5, 1.0); draw (10.4, 1.0); draw (10.4, 1.5); 
+  draw (10.0, 1.5); draw (10.0, 2.0); 
+move (10.5, 2.0); draw (10.5, 1.0); draw (13.0, 1.0); draw (13.0, 2.0); 
+  move (11.0, 2.0); draw (11.0, 1.5); draw (12.5, 1.5); draw (12.5, 2.0); 
+move (4.5, 1.5); draw (4.75, 1.25); draw (4.5, 1.0); 
+move (5.5, 1.5); draw (5.75, 1.25); draw (5.5, 1.0); 
+move (7.5, 1.5); draw (7.75, 1.25); draw (7.5, 1.0); 
+move (11.5, 1.5); draw (11.75, 1.25); draw (11.5, 1.0); 
+ 
+font size (0.25); font expansion (1.4); 
+move (2.5, 4.1); draw ("K0"); 
+move (2.5, 3.1); draw ("N0"); 
+move (2.5, 2.1); draw ("A0"); 
+ 
+move (0.0, 4.1); draw ("'Kalender'"); 
+move (0.0, 3.1); draw ("'Namen'"); 
+move (0.0, 2.1); draw ("'Adressen'"); 
+move (0.0, 1.1); draw ("Arbeitskopie"); 
+ 
+move (4.9, 1.1); draw ("A1"); 
+move (5.9, 1.1); draw ("A2"); 
+move (7.9, 1.1); draw ("A3"); 
+move (11.9, 1.1); draw ("K1"); 
+ 
+x alignment (right); 
+move (13.5, 4.1); draw ("K1"); 
+move (13.5, 3.1); draw ("N0"); 
+move (13.5, 2.1); draw ("A2"); 
+ 
+x alignment (normal); 
+font size (0.2); 
+INT VAR i; 
+FOR i FROM 0 UPTO 10 REP 
+  time (2.5 + real (i) * 1.0, i) 
+END REP; 
+ 
+PROC time (REAL CONST x pos, INT CONST nr) : 
+ 
+  move (x pos, 4.9); draw (x pos, 4.6); 
+  move (x pos, 3.9); draw (x pos, 3.6); 
+  move (x pos, 2.9); draw (x pos, 2.6); 
+  move (x pos, 1.9); draw (x pos, 1.6); 
+  move (x pos, 0.9); draw (x pos, 0.6); 
+  move (x pos + 0.1, 0.6); draw (text (nr)) 
+ 
+END PROC time; 
+ 
+ 
+LET myname = "abb.6-2";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+(* 
+pause (9000); 
+*)
+
diff --git a/doc/eudas/abb.7-1 b/doc/eudas/abb.7-1
new file mode 100644
index 0000000..3536ad9
--- /dev/null
+++ b/doc/eudas/abb.7-1
@@ -0,0 +1,46 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 6.0);   viewport (0.0,0.0,13.5,6.0);
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+ 
+kasten (5.0, 4.5, 3.0, 1.0); 
+kasten (5.0, 1.5, 3.0, 1.0); 
+kasten (1.5, 3.0, 3.0, 1.0); 
+font size (0.35); font expansion (1.5); 
+x alignment (center);
+move (6.5, 4.8); draw ("Druckmuster"); 
+move (6.5, 1.8); draw ("Druckdatei"); 
+move (3.0, 3.3); draw ("EUDAS-Datei"); 
+move (6.5, 0.0); draw ("Drucker"); 
+ 
+move (6.5, 4.25); draw (6.5, 2.75); draw (6.25, 3.0); 
+  move (6.5, 2.75); draw (6.75, 3.0); 
+move (4.75, 3.5); draw (6.25, 3.5); draw (6.0, 3.75); 
+  move (6.25, 3.5); draw (6.0, 3.25); 
+move (6.5, 1.25); draw (6.5, 0.5); draw (6.75, 0.75); 
+  move (6.5, 0.5); draw (6.25, 0.75); 
+ 
+
+PROC kasten (REAL CONST x anf, y anf, x l, y l) : 
+ 
+  move (x anf, y anf); 
+  draw (x anf, y anf + y l); 
+  draw (x anf + x l, y anf + y l); 
+  draw (x anf +  x l, y anf); 
+  draw (x anf, y anf) 
+ 
+END PROC kasten;
+
+ 
+LET myname = "abb.7-1";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+(* 
+pause (9000); 
+*)
+
diff --git a/doc/eudas/abb.9-1 b/doc/eudas/abb.9-1
new file mode 100644
index 0000000..774b78b
--- /dev/null
+++ b/doc/eudas/abb.9-1
@@ -0,0 +1,41 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 4.0); viewport (0.0,0.0,13.5,4.0);
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+ 
+move (1.5, 1.0); draw (8.75, 1.0); 
+move (1.5, 3.5); draw (8.75, 3.5); 
+INT VAR i; 
+FOR i FROM 0 UPTO 9 REP 
+  move (1.75 + real (i) * 0.75, 3.7); 
+  draw (1.75 + real (i) * 0.75, 1.0); 
+END REP; 
+ 
+move (4.7, 3.7); draw (4.7, 1.0); 
+ 
+font size (0.25); font expansion (1.5); 
+x alignment (center); 
+FOR i FROM 0 UPTO 8 REP 
+  move (2.125 + real (i) * 0.75, 3.6); draw (text (i + 110)) 
+END REP; 
+FOR i FROM 1 UPTO 5 REP 
+  move (2.125 + real (i + 3) * 0.75, 0.6); draw ("(" + text (i) + ")") 
+END REP;
+ 
+font size (0.35); x alignment  (left); 
+move (2.0, 0.0); draw ("Datei A"); 
+move (5.0, 0.0); draw ("Datei B"); 
+ 
+ 
+LET myname = "abb.9-1";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+(* 
+pause (9000)
+*)
+
diff --git a/doc/eudas/abb.9-2 b/doc/eudas/abb.9-2
new file mode 100644
index 0000000..4e9444d
--- /dev/null
+++ b/doc/eudas/abb.9-2
@@ -0,0 +1,96 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 6.5); viewport (0.0,0.0,13.5,6.5); 
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+ 
+INT VAR i; 
+move (4.0, 0.0); draw (4.0, 2.0); 
+move (5.5, 0.0); draw (5.5, 2.0); 
+FOR i FROM 0 UPTO 4 REP 
+  move (4.0, real (i) * 0.5); 
+  draw (5.5, real (i) * 0.5)
+END REP; 
+ 
+move (4.0, 3.0); draw (4.0, 6.0); 
+move (5.5, 3.0); draw (5.5, 6.0); 
+FOR i FROM 0 UPTO 6 REP 
+  move (4.0, real (i) * 0.5 + 3.0); 
+  draw (5.5, real (i) * 0.5 + 3.0) 
+END REP; 
+ 
+move (7.5, 2.0); draw (7.5, 6.0); 
+move (9.0, 2.0); draw (9.0, 6.0); 
+FOR i FROM 0 UPTO 8 REP 
+  move (7.5, real (i) * 0.5 + 2.0); 
+  draw (9.0, real (i) * 0.5 + 2.0) 
+END REP; 
+ 
+strichel (5.5, 6.0, 7.5, 6.0); 
+strichel (5.5, 3.0, 7.5, 3.0); 
+strichel (5.5, 1.0, 7.5, 3.0); 
+strichel (5.5, 0.0, 7.5, 2.0); 
+ 
+move (5.5, 4.75); draw (6.0, 4.75); 
+  draw (6.0, 1.75); draw (5.5, 1.75); 
+move (4.0, 3.75); draw (3.5, 3.75); 
+  draw (3.5, 1.25); draw (4.0, 1.25); 
+ 
+font size (0.4); font expansion (1.5); 
+move (0.0, 0.8); draw ("Koppeldatei"); 
+move (0.0, 4.3); draw ("Hauptdatei"); 
+move (10.0, 4.3); draw ("virtuelle"); 
+move (10.0, 3.4); draw ("Datei");
+ 
+font size (0.3); 
+move (4.5, 0.1); draw ("H2"); 
+move (4.5, 0.6); draw ("H1"); 
+move (4.5, 1.1); draw ("B"); 
+move (4.5, 1.6); draw ("A"); 
+move (4.5, 3.1); draw ("F4"); 
+move (4.5, 3.6); draw ("B"); 
+move (4.5, 4.1); draw ("F3"); 
+move (4.5, 4.6); draw ("A"); 
+move (4.5, 5.1); draw ("F2"); 
+move (4.5, 5.6); draw ("F1"); 
+move (8.0, 5.6); draw ("F1"); 
+move (8.0, 5.1); draw ("F2"); 
+move (8.0, 4.6); draw ("A"); 
+move (8.0, 4.1); draw ("F3"); 
+move (8.0, 3.6); draw ("B"); 
+move (8.0, 3.1); draw ("F4"); 
+move (8.0, 2.6); draw ("H1"); 
+move (8.0, 2.1); draw ("H2"); 
+ 
+PROC strichel (REAL CONST x anf, y anf, x end, y end) : 
+ 
+  REAL VAR laenge := x end - x anf; 
+  INT VAR teile := int (abstand/ 0.4); 
+  REAL VAR verhaeltnis := (y end - y anf) / laenge;
+  laenge := laenge / (real (2 * teile + 1)); 
+  INT VAR i; 
+  FOR i FROM 0 UPTO teile REP 
+    move (x anf + real (i + i) * laenge, 
+          y anf + verhaeltnis * real (i + i) * laenge); 
+    draw (x anf + real (i + i + 1) * laenge, 
+          y anf + verhaeltnis * real (i + i + 1) * laenge) 
+  END REP . 
+ 
+abstand : 
+  sqrt ((y end - y anf) + (y end - y anf) + 
+        (x end - x anf) * (x end - x anf)) . 
+ 
+END PROC strichel; 
+ 
+ 
+LET myname = "abb.9-2";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+(* 
+pause (9000);
+*)
+
diff --git a/doc/eudas/abb.9-3 b/doc/eudas/abb.9-3
new file mode 100644
index 0000000..9b190ab
--- /dev/null
+++ b/doc/eudas/abb.9-3
@@ -0,0 +1,113 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 7.0); viewport (0.0,0.0,13.5,7.0); 
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+ 
+x alignment (center); 
+font size (0.3); font expansion (1.2); 
+kasten (1.5, 5.0, 2.0, 1.5); 
+move (2.5, 5.9); draw ("EUDAS-"); 
+move (2.5, 5.3); draw ("Datei 1"); 
+move (3.5, 5.75); draw (4.0, 5.75); 
+kasten (4.0, 5.0, 2.0, 1.5); 
+move (5.0, 5.9); draw ("gekettete"); 
+move (5.0, 5.3); draw ("Datei A"); 
+move (6.0, 5.75); draw (6.5, 5.75);
+kasten (6.5, 5.0, 2.0, 1.5); 
+move (7.5, 5.9); draw ("gekettete"); 
+move (7.5, 5.3); draw ("Datei B"); 
+kasten (1.5, 2.0, 2.0, 1.5); 
+move (2.5, 2.9); draw ("gekoppelte"); 
+move (2.5, 2.3); draw ("Datei C");
+kasten (4.0, 0.0, 2.0, 1.5); 
+move (5.0, 0.9); draw ("gekoppelte"); 
+move (5.0, 0.3); draw ("Datei D"); 
+ 
+punkt (9.0, 5.75); 
+punkt (9.25, 5.75); 
+punkt (9.5, 5.75); 
+ 
+strichel (1.0, 4.5, 10.0, 4.5); 
+strichel (1.0, 7.0, 10.0, 7.0); 
+strichel (1.0, 4.5, 1.0, 7.0); 
+x alignment (right); font size (0.4);
+move (10.0, 3.9); 
+draw ("Hauptdatei"); 
+ 
+punkt (2.5, 3.75); 
+punkt (2.5, 4.0); 
+punkt (2.5, 4.25); 
+ 
+punkt (5.0, 1.75); 
+punkt (5.0, 2.0); 
+punkt (5.0, 2.25); 
+punkt (5.0, 2.5); 
+punkt (5.0, 2.75); 
+punkt (5.0, 3.0); 
+punkt (5.0, 3.25); 
+punkt (5.0, 3.5); 
+punkt (5.0, 3.75); 
+punkt (5.0, 4.0); 
+punkt (5.0, 4.25); 
+ 
+PROC punkt (REAL CONST x pos, y pos) : 
+ 
+  LET p size = 0.025;
+  move (x pos, y pos + p size); 
+  draw (x pos + p size, y pos); 
+  draw (x pos, y pos - p size); 
+  draw (x pos - p size, y pos); 
+  draw (x pos, y pos + p size) 
+ 
+END PROC punkt; 
+ 
+ 
+PROC strichel (REAL CONST x anf, y anf, x end, y end) : 
+ 
+  REAL VAR laenge := x end - x anf; 
+  INT VAR teile := int (abstand/ 0.4); 
+  REAL VAR senkrecht, verhaeltnis; 
+  IF laenge <> 0.0 THEN
+    verhaeltnis := (y end - y anf) / laenge; senkrecht := 1.0 
+  ELSE 
+    verhaeltnis := 1.0; senkrecht := 0.0 ; 
+    laenge := y end - y anf
+  END IF;
+  laenge := laenge / (real (2 * teile + 1)); 
+  INT VAR i; 
+  FOR i FROM 0 UPTO teile REP 
+    move (x anf + real (i + i) * laenge * senkrecht,
+          y anf + verhaeltnis * real (i + i) * laenge); 
+    draw (x anf + real (i + i + 1) * laenge * senkrecht,
+          y anf + verhaeltnis * real (i + i + 1) * laenge) 
+  END REP . 
+ 
+abstand : 
+  sqrt ((y end - y anf) * (y end - y anf) + 
+        (x end - x anf) * (x end - x anf)) . 
+ 
+END PROC strichel; 
+ 
+PROC kasten (REAL CONST x anf, y anf, x l, y l) : 
+ 
+  move (x anf, y anf); 
+  draw (x anf, y anf + y l); 
+  draw (x anf + x l, y anf + y l); 
+  draw (x anf +  x l, y anf); 
+  draw (x anf, y anf) 
+ 
+END PROC kasten;
+ 
+ 
+LET myname = "abb.9-3";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+(* 
+pause (9000)
+*)
+
diff --git a/doc/eudas/abb.9-4 b/doc/eudas/abb.9-4
new file mode 100644
index 0000000..e243265
--- /dev/null
+++ b/doc/eudas/abb.9-4
@@ -0,0 +1,98 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 6.0); viewport (0.0,0.0,13.5,6.0);
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+ 
+kasten (2.0, 1.0, 1.4, 2.0); 
+kasten (3.5, 1.0, 1.4, 2.0); 
+kasten (6.5, 1.0, 1.4, 2.0); 
+kasten (2.0, 3.4, 1.4, 2.0); 
+kasten (5.0, 3.4, 1.4, 2.0); 
+kasten (6.5, 3.4, 1.4, 2.0); 
+  strichel (3.5, 3.4, 3.5, 5.4); 
+  strichel (3.5, 5.4, 4.9, 5.4); 
+  strichel (4.9, 5.4, 4.9, 3.4); 
+  strichel (4.9, 3.4, 3.5, 3.4); 
+move (1.9, 2.7); draw (1.5, 2.7); 
+draw (1.5, 4.6); draw (1.9, 4.6);
+ 
+x alignment (center); 
+font size (0.3); font expansion (1.4); 
+ 
+move (2.7, 5.6); draw ("22-1"); 
+move (2.7, 4.9); draw ("X"); 
+move (2.7, 4.4); draw ("K"); 
+move (2.7, 2.5); draw ("K"); 
+move (2.7, 2.0); draw ("N1"); 
+move (2.7, 0.4); draw ("(114)"); 
+ 
+move (4.2, 5.6); draw ("22-2"); 
+move (4.2, 4.9); draw ("X"); 
+move (4.2, 4.4); draw ("K"); 
+move (4.2, 2.5); draw ("K"); 
+move (4.2, 2.0); draw ("N2"); 
+move (4.2, 0.4); draw ("(209)"); 
+ 
+move (5.7, 5.6); draw ("23-1"); 
+move (5.7, 4.9); draw ("Y"); 
+move (5.7, 4.4); draw ("L"); 
+ 
+move (7.2, 5.6); draw ("24-1"); 
+move (7.2, 4.9); draw ("Z"); 
+move (7.2, 4.4); draw ("M"); 
+move (7.2, 2.5); draw ("M"); 
+move (7.2, 0.4); draw ("(17)"); 
+ 
+font size (0.4); x alignment (normal);
+move (8.5, 2.0); draw ("Koppeldatei"); 
+move (8.5, 4.4); draw ("Hauptdatei"); 
+ 
+PROC strichel (REAL CONST x anf, y anf, x end, y end) : 
+ 
+  REAL VAR laenge := x end - x anf; 
+  INT VAR teile := int (abstand/ 0.4); 
+  REAL VAR senkrecht, verhaeltnis; 
+  IF laenge <> 0.0 THEN
+    verhaeltnis := (y end - y anf) / laenge; senkrecht := 1.0 
+  ELSE 
+    verhaeltnis := 1.0; senkrecht := 0.0 ; 
+    laenge := y end - y anf
+  END IF;
+  laenge := laenge / (real (2 * teile + 1)); 
+  INT VAR i; 
+  FOR i FROM 0 UPTO teile REP 
+    move (x anf + real (i + i) * laenge * senkrecht,
+          y anf + verhaeltnis * real (i + i) * laenge); 
+    draw (x anf + real (i + i + 1) * laenge * senkrecht,
+          y anf + verhaeltnis * real (i + i + 1) * laenge) 
+  END REP . 
+ 
+abstand : 
+  sqrt ((y end - y anf) * (y end - y anf) + 
+        (x end - x anf) * (x end - x anf)) . 
+ 
+END PROC strichel; 
+ 
+PROC kasten (REAL CONST x anf, y anf, x l, y l) : 
+ 
+  move (x anf, y anf); 
+  draw (x anf, y anf + y l); 
+  draw (x anf + x l, y anf + y l); 
+  draw (x anf +  x l, y anf); 
+  draw (x anf, y anf) 
+ 
+END PROC kasten;
+ 
+ 
+LET myname = "abb.9-4";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+(* 
+pause (9000)
+*)
+
diff --git a/doc/eudas/abb.9-5 b/doc/eudas/abb.9-5
new file mode 100644
index 0000000..c00655c
--- /dev/null
+++ b/doc/eudas/abb.9-5
@@ -0,0 +1,51 @@
+init dgs; 
+window (0.0, 0.0, 13.5, 7.0); viewport (0.0,0.0,13.5,7.0); 
+(*scale (1.7,1.7, 0.0,0.0);*)
+(*clear pixels;*)
+ 
+kasten (1.5, 0.0, 3.5, 2.0); 
+kasten (7.0, 0.0, 3.5, 2.0); 
+kasten (4.0, 4.0, 4.0, 3.0); 
+  kasten (5.0, 5.5, 2.0, 1.0); 
+ 
+move (3.25, 2.25); draw (4.75, 3.75); 
+  draw (4.5, 3.75); move (4.75, 3.75); draw (4.75, 3.5); 
+  move (3.25, 2.25); draw (3.5, 2.25); 
+  move (3.25, 2.25); draw (3.25, 2.5); 
+move (8.75, 2.25); draw (7.25, 3.75); 
+  draw (7.5, 3.75); move (7.25, 3.75); draw (7.25, 3.5);
+  move (8.75, 2.25); draw (8.5, 2.25); 
+  move (8.75, 2.25); draw (8.75, 2.5);
+ 
+x alignment (center); 
+font size (0.4); font expansion (1.4); 
+ 
+move (3.25, 0.2); draw ("Benutzer A"); 
+move (8.75, 0.2); draw ("Benutzer B"); 
+move (6.0, 4.3); draw ("Manager"); 
+font size (0.3);
+move (6.0, 5.6); draw ("Kunden"); 
+ 
+PROC kasten (REAL CONST x anf, y anf, x l, y l) : 
+ 
+  move (x anf, y anf); 
+  draw (x anf, y anf + y l); 
+  draw (x anf + x l, y anf + y l); 
+  draw (x anf +  x l, y anf); 
+  draw (x anf, y anf) 
+ 
+END PROC kasten;
+ 
+ 
+LET myname = "abb.9-5";
+save pixels (myname + ".p"); 
+FILE VAR f := sequential file (modify, myname + ".p"); 
+to line (f, 1); insert record (f); 
+write record (f, "#linefeed (0.8)#"); 
+insert record (f); write record (f, myname); 
+to eof (f); insert record (f); write record (f, myname); 
+to line (f, 1);
+(* 
+pause (9000)
+*)
+
diff --git a/doc/eudas/bildergenerator b/doc/eudas/bildergenerator
new file mode 100644
index 0000000..8129476
--- /dev/null
+++ b/doc/eudas/bildergenerator
@@ -0,0 +1,25 @@
+PROC starten : 
+ 
+  command dialogue (FALSE); 
+  disable stop; 
+  fetch (name, /"DGS NEC"); 
+  run (name); 
+  save (name + ".p", /"DGS NEC"); 
+  end (myself) 
+ 
+END PROC starten; 
+ 
+TEXT VAR name; 
+ 
+PROC gen (TEXT CONST t) : 
+ 
+  name := t; 
+  begin ("p", PROC starten, a); 
+  TASK VAR a; 
+  WHILE exists (a) REP pause (100) END REP 
+ 
+END PROC gen; 
+ 
+gen ("abb.4-2"); 
+gen ("abb.6-1");
+
diff --git a/doc/eudas/eudas.hdb.1 b/doc/eudas/eudas.hdb.1
new file mode 100644
index 0000000..40b5a84
--- /dev/null
+++ b/doc/eudas/eudas.hdb.1
@@ -0,0 +1,267 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (3)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+#center##on("b")#"Was kann EUDAS ? 
+ 
+ 
+ 
+In diesem Kapitel wollen wir Ihnen erklären, was EUDAS Ihnen ei­
+gentlich bringen soll. Sie arbeiten sicher nicht nur aus Spaß am
+Computer, sondern wollen ihn für bestimmte Aufgaben einsetzen. Ein
+Computer kann bestimmte Aufgaben nur dann bearbeiten, wenn er
+dafür programmiert worden ist. 
+    EUDAS ist nun ein Programm, das allgemein Aufgaben der Da­
+tenverwaltung lösen kann. Zunächst wollen wir Ihnen erläutern,
+wodurch dieses Anwendungsgebiet genau charakterisiert wird. 
+ 
+ 
+1.1 Textverarbeitung und Datenverwaltung
+ 
+Es gibt zwei Einsatzbereiche des Computers, die von fast jedem An­
+wender benötigt werden, egal auf welchem Spezialgebiet er tätig ist:
+nämlich die #on("i")#Textverarbeitung#off("i")# und die #on("i")#Datenverwaltung#off("i")#. Durch die
+Unterscheidung dieser beiden Bereiche werden die charakteristi­
+schen Merkmale der Datenverwaltung abgegrenzt. 
+ 
+#on("b")#Textverarbeitung#off("b")# Die Textverarbeitung befaßt sich damit,
+einen beliebigen Text auf einem Rechner zu erfassen und anschließend
+über einen Drucker wieder auszugeben. Der Sinn dieser Arbeit liegt
+darin, daß man einen einmal eingegebenen Text sehr einfach ändern
+kann. Außerdem kann der Computer einige unangenehme Aufgaben
+übernehmen, die beim Schreiben von Texten auftreten: die Auftei­
+lung auf Zeilen und Seiten, die Seitennumerierung und vieles mehr. 
+    Charakteristisch für die Textverarbeitung ist, daß der Einfluß
+des Computers sich auf kosmetische Details beschränkt. Die Spei­
+cherung und eventuelle Aufbereitung zum Drucken haben praktisch
+nichts mit dem Inhalt des Textes zu tun. Dies wäre für den Rechner
+auch sehr schwierig, da die im Text enthaltenen Informationen in
+menschlicher Sprache vorliegen, die für einen Rechner nicht ver­
+ständlich ist. 
+ 
+#on("b")#Datenverwaltung#off("b")# Bei der Datenverwaltung werden ebenfalls
+textuelle Informationen gespeichert, diese liegen aber in einer aufberei­
+teten Form vor, die einen Teil des Inhalts für den Computer ver­
+ständlich macht. Bei der Datenverwaltung werden Objekte betrach­
+tet, die verschiedene Eigenschaften haben können. Ein solches
+Objekt kann z.B. eine Person sein. Als Eigenschaften werden mit
+dieser Person zusammenhängende Informationen betrachetet, die für
+die jeweilige Anwendung wichtig sind. 
+    Ein Beispiel für eine solche Betrachtungsweise ist der Arbeit­
+nehmer im Betrieb. Einige der typischerweise erfaßten Daten sind
+Name, Adresse, Telefon, Geburtsdatum und Geschlecht. Alle diese
+Daten sind Eigenschaften oder #on("i")#Attribute#off("i")#, die einem bestimmten
+Menschen mehr oder weniger fest zugeordnet sind. 
+    Die Betonung inhaltlicher Beziehungen erleichtert es dem Com­
+puter, die gespeicherten Daten in verschiedenen Variationen aus­
+zuwerten. 
+ 
+#on("b")#Beispiel#off("b")# Um die Unterscheidung zwischen Textverarbeitung
+und
+Datenverwaltung deutlicher zu machen, werden im folgenden Bei­
+spiel die Informationen über eine Person in zwei unterschiedlichen
+Formen dargeboten, die für den Menschen die gleiche Aussagekraft
+haben: 
+ 
+    1.  Frau Magdalene Kant, geb. Hagedorn, wurde am 12. Januar
+        1946 geboren. Sie wohnt in Bonn in der Meckenheimer Allee
+        112. Seit 1977 arbeitet sie in unserer Firma. Sie ist tele­
+        fonisch erreichbar unter der Nummer 0228/356782. 
+ 
+    2.  Name:              Magdalene 
+        Vorname:           Kant 
+        Geburtsname:       Hagedorn 
+        Geburtsdatum:      12.01.46 
+        Geschlecht:        weiblich 
+        Strasse:           Meckenheimer Allee 112 
+        PLZ:               5200 
+        Wohnort:           Bonn 1 
+        Vorwahl:           0228 
+        Telefon:           356782 
+        beschäftigt seit:  1977 
+ 
+Die Form der Darstellung wie in der ersten Alternative eignet sich
+nur für den Menschen, da die gleiche Information auf viele ver­
+schiedene Weisen ausgedrückt werden könnte (z.B. unterschiedlicher
+Satzbau). Die zweite Alternative beschränkt sich auf die für die
+bestimmte Anwendung wesentlichen Zusammenhänge; der Computer
+kann die Aufteilung der Information in einzelne Attribute ausnut­
+zen. 
+    In dieser zweiten Form können Sie Daten mit EUDAS erfassen
+und auch auswerten. Die Attribute können Sie jeweils passend zu
+den erfaßten Daten selbst bestimmen. 
+    Für Daten in der ersten Form steht Ihnen die EUMEL-Textver­
+arbeitung zur Verfügung. EUDAS wurde so entwickelt, daß Sie auch
+Daten an die Textverarbeitung übergeben können. 
+    Es ist nämlich möglich, einen freien Text aus der Attributdar­
+stellung automatisch zu erzeugen, indem Sie dem Computer den
+Satzbau mit entsprechenden Platzhaltern vorgeben. Der Rechner
+setzt die einzelnen Attribute dann an die angegebenen Stellen.
+Diese Funktion ist ein Kernstück von EUDAS und wird in Abschnitt
+1.3 näher erläutert. 
+ 
+ 
+1.2 EUDAS als Karteikasten 
+ 
+Wie Sie vielleicht schon bemerkt haben, ähnelt die zweite Form der
+Darstellung einer Karteikarte, auf der Platz für bestimmte Einträge
+freigehalten wird. Anhand dieses Modells können Sie sich in vielen
+Fällen die Arbeitsweise von EUDAS veranschaulichen. Sie sollten die
+Analogie allerdings nicht zu weit treiben: EUDAS schaufelt ja nicht
+wirklich mit Karteikarten herum. Manche Funktionen sind eben
+computerspezifisch und ließen sich mit Karteikarten gar nicht
+durchführen. 
+   Mit EUDAS können Sie die möglichen Einträge auf den Karteikar­
+ten (also die Attribute) völlig frei bestimmen; die einzige Beschrän­
+kung besteht darin, daß Sie in einem Karteikasten nur Karten mit
+völlig gleichem Aufbau verwenden können. Wenn Sie eine neue Kar­
+teikarte entwerfen wollen, brauchen Sie nur Namen für die einzel­
+nen Einträge anzugeben. EUDAS zeigt Ihnen dann quasi eine Karte
+am Bildschirm, in der diese Einträge aufgeführt sind. 
+    Sie können nun am Bildschirm Daten auf diese Karteikarten
+schreiben. Dabei dürfen die Einträge fast beliebig lang sein; wenn
+der Platz auf dem Bildschirm nicht reicht, können Sie sich Ihre
+überdimensionale Karteikarte in Ausschnitten ansehen. 
+    Die einmal eingegebenen Daten bleiben nun so lange gespei­
+chert, wie Sie wollen (bzw. bis Ihr Rechner zusammenfällt). Haben
+Sie beim Eintragen Fehler gemacht, können Sie diese jederzeit kor­
+rigieren oder später noch weitere Informationen ergänzen. 
+ 
+#free (7.5)# 
+ 
+#center#Abb. 1-1   EUDAS als Karteikasten 
+ 
+ 
+#on("b")#Anwendungen#off("b")# Mit den gespeicherten Daten können Sie nun
+ver­
+schiedene Dinge anstellen (bzw. vom Rechner anstellen lassen). Das
+Einfachste ist natürlich das, was Sie mit einer Kartei auch machen
+würden, sich nämlich einzelne Karteikarten anzuschauen. 
+    Um eine bestimmte Karteikarte herauszufinden, geben Sie
+EUDAS einfach den Inhalt vor, nach dem gesucht werden soll. Hier
+zeigt sich bereits der erste Vorteil eines Computers: Die Suche in
+der EUDAS-Kartei ist viel schneller, als Sie es von Hand könnten.
+Außerdem kann der Rechner keine Karte zufällig übersehen. 
+    EUDAS zeigt sich auch dann überlegen, wenn Sie einen ganz
+bestimmten Teil der Kartei durchforsten müssen. Eine Bücherei muß
+z.B. regelmäßig alle Bücher heraussuchen, deren Leihfrist über­
+schritten ist. Der Computer durchsucht in solchen Fällen ermü­
+dungsfrei auch große Datenmengen. 
+    Wenn Sie die Karteikarten in einer bestimmten Reihenfolge
+haben wollen, kann EUDAS auch das Sortieren übernehmen. Weitere
+automatische Vorgänge betreffen z.B. das Rauswerfen überflüssiger
+oder veralteter Karten. Die Einträge können auch nach einer be­
+stimmten Vorschrift alle geändert werden. Solche Aufgaben treten
+z.B. in der Schule auf, wo die Schüler jedes Jahr versetzt werden
+müssen (natürlich bis auf Ausnahmen). 
+    Auch Beziehungen zwischen verschiedenen Karteien kann
+EUDAS herstellen. Dies kann man noch einmal an dem Beispiel der
+Bücherei illustrieren. Wenn ein Buch gefunden wurde, dessen Leih­
+frist überschritten ist, muß der zugehörige Ausleiher gefunden und
+angeschrieben werden. Das Heraussuchen beider Karten kann EUDAS
+in einem Arbeitsgang durchführen. 
+ 
+ 
+1.3 Drucken 
+ 
+Eine besondere Stärke von EUDAS ist die Möglichkeit, die gespei­
+cherten Daten in schriftlicher Form auszuwerten. Dadurch, daß die
+Daten in einer Form gespeichert sind, die den Inhalt widerspiegelt,
+können die gleichen Daten in vielen verschiedenen Formen auf
+Papier ausgegeben werden. 
+ 
+ 
+ 
+ 
+                                Karl Eudas         
+              An                Poltersdorf        
+              XXXXXXXXXXX                          
+              XXXXXXXXXXX                          
+                                                   
+              XXXX XXXXXXXXXXXX                    
+                                                   
+              Lieber XXXXXXX !                     
+                                                   
+              Dies ist ein Beispiel für ein        
+              Druckmuster.                         
+                                                   
+                              Viele Grüße          
+                                                   
+ 
+ 
+#center#Abb. 1-2   Muster für die Druckausgabe 
+ 
+ 
+Zu diesem Zweck geben Sie EUDAS ein Muster des gewünschten Aus­
+drucks vor. Der Rechner setzt dann an entsprechend markierten
+Leerstellen die gespeicherten Informationen ein und druckt das
+Ergebnis aus. Auf diese Weise ersparen Sie sich die umfangreiche
+Schreibarbeit, die anfällt, wenn die Informationen auf den Kartei­
+karten in anderer Form benötigt werden. 
+    Natürlich müssen Sie zum Entwerfen des Formulars kein ge­
+wiefter Programmierer sein. Wenn Sie einen Rundbrief verschicken
+wollen, schreiben Sie den Brief, als wollten Sie Ihn nur einmal
+schicken. Lediglich im Adressfeld müssen Sie Platzhalter an den
+Stellen vorsehen, an denen später die wirklichen Adressen stehen
+sollen. 
+ 
+#on("b")#Verwendungsmöglichkeiten#off("b")# Die Möglichkeiten für solche
+Formulare
+sind unbegrenzt. Beispiele sind Briefe, Adreßaufkleber, Überwei­
+sungsaufträge und sortierte Listen. Mit den Inhalten einer Kartei
+können Sie beliebig viele verschiedene Ausgaben erzeugen. Bei dem
+obigen Beispiel der Leihbücherei könnten Sie EUDAS dazu einsetzen,
+nicht nur die säumigen Ausleiher herauszufinden, sondern die Mah­
+nung gleich fertig für einen Fensterbriefumschlag herzustellen. Für
+den Bediener bliebe die einzige Tätigkeit, diesen Vorgang anzuwer­
+fen. 
+    Wie weiter oben schon erwähnt, können Sie diese Ausgaben von
+EUDAS auch zur Textverarbeitung übernehmen. So können Sie zum
+Beispiel die Literaturliste für ein Buch mit EUDAS führen und Aus­
+züge später jeweils an die passenden Stellen einfügen. 
+ 
+#on("b")#Berechnungen#off("b")# Die Druckfunktion von EUDAS kann jedoch nicht
+nur
+zum Ausfüllen von Formularen verwendet werden. Wenn Sie Berech­
+nungen anstellen oder Auswertungen vornehmen wollen, können Sie
+im Druckmuster auch Anweisungen der Sprache ELAN verwenden.
+Damit haben Sie eine komplette Programmiersprache für Ihre Muster
+zur Verfügung. 
+    Ehe Sie einen Schreck bekommen: Selbst für komplizierte Muster
+brauchen Sie nur einen ganz kleinen Teil von ELAN zu beherrschen,
+da die meiste Arbeit immer von EUDAS übernommen wird (Sie müssen
+also nicht etwa selber ein ganzes Programm schreiben). 
+    Anwendungen für diese Möglichkeit gibt es genug. Angefangen
+von einfachen Zählungen bis hin zu statistischen Auswertungen,
+von einfachen Summen bis zum kompletten Rechnungsschreiben.
+Immer nimmt Ihnen EUDAS alles das ab, was automatisch ablaufen
+kann. Sie versorgen EUDAS nur noch mit den passenden Formeln für
+Ihre Anwendung. 
+ 
+ 
+1.4 Grenzen 
+ 
+Natürlich können Sie nicht alle Probleme mit EUDAS gleichermaßen
+gut lösen. EUDAS verwendet ein einfaches Modell (Karteikasten) und
+versucht, mit möglichst wenig Informationen von Ihrer Seite auszu­
+kommen. Kompliziertere Sachverhalte verlangen auch kompliziertere
+Strukturen, die Sie dann selbst entwerfen müssen. Eine einfache
+Lösung mit EUDAS kann in solchen Fällen zu langsam oder zu um­
+ständlich sein. 
+    Wenn Sie jedoch die wenigen Strukturprinzipien von EUDAS
+verstanden haben, werden Sie sehr schnell viele Probleme mit
+EUDAS lösen können. Zuerst erfassen Sie einfach alle Daten, die Sie
+brauchen und überlegen sich erst dann, in welcher Form Sie diese
+Daten haben wollen. Auch nachträglich können Sie jederzeit noch
+neue Daten und Formulare hinzufügen, so daß Sie mit der Zeit
+EUDAS gewinnbringend für viele Routineaufgaben benutzen werden.
+
diff --git a/doc/eudas/eudas.hdb.10 b/doc/eudas/eudas.hdb.10
new file mode 100644
index 0000000..442f575
--- /dev/null
+++ b/doc/eudas/eudas.hdb.10
@@ -0,0 +1,510 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (97)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+10 Datenabfrage am Bildschirm 
+ 
+ 
+ 
+10.1 Feldauswahl 
+ 
+Da die Anzahl der möglichen Felder bei EUDAS-Dateien viel größer
+ist als die Anzahl der zur Verfügung stehenden Zeilen auf dem
+Bildschirm (255 gegenüber 22), muß es eine Möglichkeit geben, auch
+die übrigen Felder anzusehen. 
+ 
+#on("b")#Rollen#off("b")# Dazu kann man den Bildschirmausschnitt in
+vertikaler
+Richtung #on("i")#rollen#off("i")#. Sie müssen sich die Bildschirmanzeige als einen
+Ausschnitt des wirklichen Satzes vorstellen. Um weitere Inhalte des
+Satzes zu sehen, verschieben Sie den Ausschnitt einfach. 
+    Dazu dienen die beiden Tastenkombinationen ESC OBEN und ESC
+UNTEN. Diese Kombinationen wirken nur im Menü "Einzelsatz". An
+der Bildschirmanzeige ändert sich natürlich nur dann etwas, wenn
+es noch weitere Felder zum Anzeigen gibt. 
+    Ob dies der Fall ist, können Sie an zwei Indikatoren ablesen.
+Zum einen wird hinter dem letzten Feld eine markierte Abschluß­
+zeile ausgegeben. Ist diese nicht sichtbar, gibt es noch Felder, die
+Sie mit ESC UNTEN hochholen können. Zum anderen steht die Num­
+mer der ersten Zeile in der Überschrift. Ist diese Nummer größer als
+1, können Sie mit ESC OBEN noch Felder sichtbar machen. 
+    Das Rollen ist oft auch dann notwendig, wenn sich ein Feld
+über mehrere Zeilen erstreckt. In diesem Fall kann es passieren,
+daß die erste Zeile des Feldes nicht mehr sichtbar ist, da sie ober­
+halb des Anzeigebereichs liegen würde. 
+ 
+#on("b")#Feldauswahl#off("b")# Eine weitere Möglichkeit bei zu vielen Feldern
+be­
+steht darin, nur die interessanten Felder zur Anzeige auszuwählen.
+Dies geschieht mit der Funktion 
+#free (0.2)# 
+ 
+        F Feldauswahl 
+ 
+#free (0.2)# 
+Ihnen werden alle Felder zur Auswahl angeboten. Kreuzen Sie die
+Felder an, die Sie sehen wollen und denken Sie daran, daß die Rei­
+henfolge des Ankreuzens beachtet wird. Anschließend werden Ihnen
+nur die ausgewählten Felder angezeigt. Falls Sie kein Feld ankreu­
+zen, bleibt die alte Feldauswahl bestehen. 
+    Wollen Sie wieder alle Felder sehen, müssen Sie diese nicht alle
+einzeln ankreuzen. Mit HOP 'x' in der Auswahl werden alle Felder
+angekreuzt (die noch nicht angekreuzt waren). Diese Tastenkombi­
+nation können Sie allgemein bei einer Auswahl verwenden. Sie
+können die Kreuzchen mit 'o' auch wieder löschen, um zum Beispiel
+"alle außer einem" auszuwählen. 
+    Beachten Sie, daß die Auswahl der anzuzeigenden Felder nichts
+mit der eigentlichen Dateistruktur zu tun hat, sondern nur für die
+Anzeige gilt. Den Verarbeitungsfunktionen (zum Beispiel Drucken)
+stehen natürlich nach wie vor alle Felder zur Verfügung. 
+    Unvermutete Effekte können dann entstehen, wenn Sie bei
+einer eingestellten Feldauswahl ändern oder einfügen. Die nicht
+ausgewählten Felder werden beim Ändern natürlich nicht geändert
+und beim Einfügen einfach leer gelassen. 
+ 
+ 
+10.2 Satzeditor 
+ 
+An dieser Stelle sollen noch einige weitere Funktionen des Satz­
+editors vorgestellt werden, die Sie noch nicht kennengelernt haben. 
+ 
+#on("b")#Rollen im Satzeditor#off("b")# Sie können auch rollen, wenn Sie sich
+im
+Satzeditor befinden (also beim Suchen, Einfügen und Ändern). Den­
+ken Sie daran, daß Sie die Einzelsatzanzeige immer mit ESC OBEN
+und ESC UNTEN rollen, während sonst (Editor, Auswahl von Datei­
+namen) immer mit HOP OBEN und HOP UNTEN gerollt wird. 
+    Diese Diskrepanz hat technische Gründe und läßt sich leider
+nicht vermeiden. Wie Sie sich vielleicht erinnern, führt das Blättern
+mit HOP OBEN und HOP UNTEN im Satzeditor dazu, daß die Korre­
+spondenz zwischen Feldnamen und Feldinhalt verlorengeht. Daher
+muß an dieser Stelle mit ESC statt HOP gearbeitet werden. 
+ 
+#on("b")#Ähnliche Sätze#off("b")# Wenn Sie mehrere ähnliche Sätze eintragen
+müssen,
+bietet Ihnen EUDAS eine Erleichterung an. Sie können nämlich beim
+Einfügen die Daten eines anderen Satzes übernehmen. 
+    Dazu müssen Sie beim Ändern oder Einfügen des anderen Satzes
+ESC 'p' drücken. Der Inhalt des Satzes wird dann in einen Zwischen­
+speicher gebracht. Beachten Sie, daß im Gegensatz zum EUMEL-
+Editor kein Text markiert sein muß, sondern immer der ganze Satz
+transportiert wird. 
+    Beim Einfügen eines neuen Satzes können Sie diesen Satz dann
+mit ESC 'g' in den Satzeditor übernehmen. Alle vorherigen Inhalte
+werden überschrieben. Anschließend können Sie die Daten nach
+Wunsch abändern. 
+    Der Inhalt des Zwischenspeichers kann beliebig oft auf diese
+Weise kopiert werden. Der Inhalt des Zwischenspeichers wird bei
+Ändern der Feldauswahl oder beim Öffnen einer neuen Datei ge­
+löscht. 
+ 
+#on("b")#Tagesdatum#off("b")# Im Satzeditor können Sie mit ESC 'D' das
+aktuelle
+Tagesdatum abfragen. Es wird an der aktuellen Cursorposition ein­
+getragen, als ob Sie es selbst getippt hätten. 
+    Auf diese Weise können Sie Sätze einfach mit Datum versehen
+oder nach Sätzen suchen, die mit dem Tagesdatum in Beziehung
+stehen (zum Beispiel 'Fälligkeit = Heute'). 
+ 
+ 
+10.3 Suchmuster 
+ 
+Die bisher genannten Möglichkeiten des Suchmusters sind noch
+etwas beschränkt. Eine Bedingung in unserer Adressendatei, die wir
+im Suchmuster noch nicht ausdrücken können, wäre zum Beispiel:
+Suche alle Adressen der Personen, die Wegner oder Simmern heißen. 
+    Diese Alternative, Wegner ODER Simmern, kann nun in EUDAS
+durch ein Komma ausgedrückt werden: 
+ 
+ 
+        Name     Wegner,Simmern 
+        Vorname 
+ 
+ 
+Beachten Sie, daß hinter dem Komma kein Leerzeichen folgen darf,
+wie Sie es vielleicht gewohnt sind, in einem Text zu schreiben.
+EUDAS kann nämlich nicht unterscheiden, ob Sie das Leerzeichen
+nur aus optischen Gründen geschrieben haben, oder ob Sie danach
+suchen wollen. 
+ 
+#on("b")#Lokale Alternative#off("b")# Die eben beschriebene
+Konstruktionsmethode
+heißt #on("i")#lokale Alternative#off("i")#. Lokal deshalb, weil Sie nur innerhalb
+eines Feldes gilt. Was das bedeuten soll, sehen Sie, wenn Sie die
+Bedingung mit einer weiteren Bedingung für ein anderes Feld kom­
+binieren: 
+ 
+ 
+        Name     Wegner,Simmern 
+        Vorname 
+        Strasse 
+        PLZ      5* 
+        Ort 
+ 
+ 
+Dieses Muster hat die Bedeutung: Wähle alle Personen namens Weg­
+ner oder Simmern aus, die im PLZ-Bereich 5 wohnen. Die beiden
+Bedingungen für den Namen sind mit der Bedingung für die PLZ mit
+UND verknüpft - das heißt, eine der beiden ersten Bedingungen muß
+zutreffen #on("i")#und#off("i")# die untere Bedingung. Dieses UND ist global, da es
+Bedingungen für verschiedene Felder miteinander verbindet. 
+    Natürlich können Sie für mehrere Felder gleichzeitig lokale
+Alternativen angeben. Eine anderes Suchmuster könnte zum Beispiel
+so aussehen: 
+ 
+ 
+        Name     Wegner,Simmern 
+        Vorname 
+        Strasse 
+        PLZ      5,5000 
+        Ort 
+ 
+ 
+In diesem Fall muß eine ausgewählte Person Wegner oder Simmern
+heißen und in Köln wohnen. 
+ 
+#on("b")#Globale Alternative#off("b")# Es wird nun aber für bestimmte
+Situationen
+noch eine andere Art von Alternativen benötigt. Als Beispiel soll
+ein Suchmuster dienen, das folgende Bedingung ausdrückt. Gesucht
+ist eine weibliche Person mit Namen Simmern oder eine männliche
+Person mit Namen Wegner. 
+    Dieser Fall läßt sich mit unseren bisherigen Mitteln nicht lö­
+sen. Es wird nämlich eine Alternative zwischen zwei zusammen­
+gesetzten Bedingungen gefordert. Als Ausweg bietet sich an, prak­
+tisch mehrere Suchmuster anzugeben, die dann mit ODER verknüpft
+werden. 
+     Um diese verschiedenen Suchmuster optisch am Bildschirm zu
+kennzeichnen, wird ein Semikolon als sogenannte #on("i")#globale Alternati­
+ve#off("i")# verwendet. Das Semikolon trennt das Suchmuster quasi in ver­
+schiedene Spalten auf, die jeweils eine eigene Bedingung enthalten
+können. Unser gewünschtes Suchmuster würde also so aussehen: 
+ 
+ 
+        Name     Wegner;Simmern 
+        Vorname 
+        Strasse 
+        PLZ 
+        Ort 
+        m/w      m;w 
+ 
+ 
+Ebenso wie bei lokalen Alternativen darf hinter dem Semikolon kein
+Leerzeichen folgen. Daher kann das zweite Semikolon auch nicht
+direkt unter dem ersten stehen. Die Spalten werden also einfach nur
+durchgezählt: nach dem ersten Semikolon beginnt die zweite Spal­
+te, nach dem zweiten Semikolon die dritte usw. 
+    In Zeilen, in denen keine Bedingungen stehen, kann auch das
+Semikolon weggelassen werden. Es kann ebenfalls weggelassen wer­
+den, wenn die weiteren Spalten leer sind. Steht ein Semikolon direkt
+am Anfang der Zeile, so ist die erste Spalte leer. 
+    Um dies zu illustrieren, sei hier noch ein weiteres Beispiel
+angegeben: 
+ 
+ 
+        Name     Wegner 
+        Vorname  ;Anna-Maria 
+        Strasse 
+ 
+ 
+In diesem Fall muß eine ausgewählte Person mit Nachnamen Wegner
+oder mit Vornamen Anna-Maria heißen. 
+ 
+#on("b")#Stern#off("b")# Bis jetzt haben Sie hauptsächlich Bedingungen
+betrachtet,
+die exakt zutreffen mußten. Sie wissen aber bereits, daß man auch
+Bedingungen angeben kann, bei denen nur ein Teil des zu suchen­
+den Feldes bekannt ist, nämlich indem der unbekannte Teil mit
+einem Stern markiert wird. 
+    In Kapitel 5 haben Sie gelernt, daß der Stern nur am Anfang
+und Ende des Musters stehen kann. Dies trifft nicht ganz zu, denn
+Sie können den Stern auch inmitten eines Textes anwenden. So
+trifft die Bedingung 'Si*n' auf alle Namen zu, die mit 'Si' beginnen
+und mit 'n' enden. 
+    Beachten Sie hier das "und" in der Formulierung der Bedingung.
+Das Muster ist eigentlich eine Schreibweise für zwei Bedingungen
+für ein Feld, die mit UND verknüpft sind. 
+    Sie können auch noch weitere Sterne in das Muster aufnehmen.
+Dabei gibt es jedoch eine Kleinigkeit zu beachten. Das Muster
+'*x*y*' bedeutet: das Feld muß ein 'x' und ein 'y' enthalten. Über
+die Reihenfolge der beiden Zeichen ist jedoch in dieser Bedingung
+nichts gesagt, obwohl es vielleicht vom Aussehen suggeriert wird. 
+    Denken Sie daran, keine zwei Sterne nebeneinander zu schrei­
+ben - eine solche Bedingung hätte keinen Sinn. 
+    Es gibt eine weitere spezielle Bedingung, die mit Hilfe des
+Sterns formuliert wird. Ein einzelner Stern bedeutet nämlich: Das
+Feld ist nicht leer. Beachten Sie den kleinen Unterschied: ein Stern
+in einem Muster kann für einen beliebigen Text stehen, der auch
+leer sein kann. Ein einzelner Stern jedoch steht für einen beliebigen
+Text, der nicht leer ist. 
+    Damit Sie ein Gefühl für die Verwendung des Sterns bekommen,
+hier noch ein paar Beispiele: 
+ 
+ 
+Mei*r* 
+ 
+    Der Name beginnt mit 'Mei' und enthält ein 'r'. Trifft zu auf
+    'Meier', 'Meiring', aber nicht auf 'Meiling' oder 'Merzei'. 
+ 
+ 
+Donau*dampf*schiff*schaft 
+ 
+    Feld beginnt mit 'Donau', endet mit 'schaft' und enthält
+    'dampf' und 'schiff'. Trifft zu auf 'Donaudampfschiffahrtsge­
+    sellschaft', aber auch auf 'Donaugesellschiffdampffahrtschaft'. 
+ 
+ 
+Roller*erfahren 
+ 
+    Dieses Muster muß man ganz genau interpretieren. Es bedeutet:
+    der Inhalt beginnt mit 'Roller' und endet mit 'erfahren'. Das
+    Muster trifft nicht nur auf 'Roller erfahren' sondern auch auf
+    'Rollerfahren' zu. Der Stern verliert also in diesem Fall seine
+    symbolische Bedeutung als Platzhalter für einen bestimmten
+    Text. 
+ 
+#on("b")#Vergleiche#off("b")# Es gibt in EUDAS noch weitere Muster, die
+einen gan­
+zen Bereich von Werten auswählen. Diese betreffen Bedingungen der
+Art "größer als" und "kleiner als". Solche Vergleichsbeziehungen
+werden durch zwei Punkte dargestellt. 
+    So wählt das Muster 'K..' alle Felder aus, die in der alphabe­
+tischen Reihenfolge hinter 'K' liegen, wobei das 'K' selbst mit ein­
+geschlossen ist. Umgekehrt trifft '..K' auf alle Felder zu, die davor
+liegen. 
+    Sie können beide Bedingungen auch kombinieren. So trifft die
+Bedingung 'A..K' auf alle Felder zu, die im Lexikon unter 'A' bis
+'J' erscheinen (die Felder mit 'K' sind hier ausgeschlossen). Beach­
+ten Sie, daß die direkte Kombination wieder die Verknüpfung zweier
+einzelner Bedingungen mit UND darstellt. 
+ 
+#on("b")#Negation#off("b")# Um den Bereich möglicher Suchmuster noch zu
+erweitern,
+können Sie einzelne Bedingungen auch noch verneinen. Dies ge­
+schieht durch Voranstellen zweier Minuszeichen. So bedeutet das
+Muster '--Meier', daß alle Personen ausgewählt werden, die nicht
+Meier heißen. 
+    Die Verneinung bezieht sich immer auf das unmittelbar folgende
+Muster (bis zum nächsten Komma, Semikolon oder dem Zeilenende)
+und nicht etwa auf eine ganze Zeile. Sie umfaßt jedoch die UND-
+Verknüpfung der kombinierten Bedingungen. So sind zum Beispiel die
+Muster '--E..M', '--E..,--..M' und '..E,M..' völlig gleichbedeu­
+tend. 
+ 
+#on("b")#Feldvergleich#off("b")# Als letztes haben Sie im Suchmuster auch
+noch die
+Möglichkeit, ein Feld mit anderen Feldern des gleichen Satzes zu
+vergleichen. Bisher hatten Sie ein Feld ja immer nur mit konstanten
+Texten verglichen. 
+    Um dies zu erreichen, geben Sie statt eines Vergleichstextes
+den Feldnamen des Feldes an, mit dem Sie vergleichen wollen. Zur
+Kennzeichnung müssen Sie dem Namen noch ein '&' voranstellen.
+Diese Konstruktion funktioniert mit allen bisher besprochenen Ver­
+gleichen. Beispielsweise trifft 
+ 
+ 
+        Feld1     ..&Feld2 
+ 
+ 
+auf alle Sätze zu, in denen der Inhalt von Feld1 kleiner ist als der
+Inhalt von Feld2. 
+    Im Gegensatz zum Druckmuster dürfen in den Feldnamen zwar
+Leerzeichen enthalten sein, nicht jedoch 
+#free (0.2)# 
+ 
+        ..     *     ,     ; 
+ 
+#free (0.2)# 
+da diese Zeichen als reservierte Zeichen gelten und jeweils als
+Begrenzer wirken. Die gleiche Beschränkung gilt dementsprechend
+auch für konstante Vergleichstexte. 
+    Beachten Sie, daß hinter dem '&' bis zum nächsten Begrenzer­
+zeichen ein gültiger (vorhandener) Feldname stehen muß. Anderen­
+falls wird der Text als konstantes Muster betrachtet. 
+    Wie schon oben gesagt, kann der Feldvergleich mit allen Ver­
+gleichen verwendet werden. Auch gemischte Konstruktionen sind
+zulässig, beispielsweise 
+ 
+ 
+        Feld1     A..&Feld3,*&Feld9* 
+ 
+ 
+Diese Bedingung trifft zu, wenn Feld1 größer oder gleich 'A', aber
+kleiner als der Inhalt von Feld3 ist, oder wenn der Inhalt von Feld9
+darin vorkommt. 
+ 
+#on("b")#Optimierung#off("b")# Hier noch eine Bemerkung zur Geschwindigkeit
+des
+Suchens. Je mehr Bedingungen Sie angeben, desto mehr Vergleiche
+müssen beim Suchen angestellt werden und desto länger dauert es. 
+    Das erste Feld einer Datei erfährt jedoch eine Sonderbehand­
+lung. Wenn Sie für dieses Feld ein Muster für Übereinstimmung
+angeben, kann der Suchvorgang enorm beschleunigt werden, da das
+erste Feld einer Datei intern speziell verwaltet wird. Damit das
+Verfahren funktioniert, dürfen keine globalen Alternativen oder
+lokale Alternativen für das erste Feld verwendet werden. 
+    Diese Suchoptimierung sollten Sie bereits beim Einrichten einer
+Datei berücksichtigen. Geben Sie als erstes Feld das an, nach dem
+am ehesten direkt gesucht wird. Typisches Beispiel hierfür ist der
+Nachname, aber auch Artikelnummern sind sinnvoll. Wichtig ist, daß
+das erste Feld nicht zu oft identisch ist und auch mehr als zwei
+Buchstaben enthält, damit die Optimierung ihre volle Wirksamkeit
+entfaltet. 
+    Denken Sie daran, daß durch die Feldauswahl ein beliebiges
+Feld als erstes auf dem Bildschirm stehen kann. Für die Optimierung
+wird jedoch immer das Feld betrachtet, das beim Einrichten der
+Datei als erstes angegeben wurde. 
+ 
+ 
+10.4 Markieren 
+ 
+Manchmal entsteht die Situation, daß Sie eine Reihe von Sätzen
+bearbeiten wollen, aber keine Suchbedingung formulieren können,
+die auf alle diese Sätze zutrifft. In diesem Fall bietet EUDAS Ihnen
+die Möglichkeit, solche Sätze von Hand zu markieren. 
+    Ein Beispiel: Sie haben eine ganze Reihe von Sätzen geändert
+und wollen diese Änderungen als Protokoll ausdrucken. Es läßt sich
+aber nicht mit Hilfe eines Suchmusters feststellen, welche Sätze
+geändert wurden. 
+    Als Abhilfe wählen Sie bei jedem geänderten Satz die Funktion 
+#free (0.2)# 
+ 
+        M Markierung 
+ 
+#free (0.2)# 
+Dadurch wird der bisher unmarkierte Satz markiert. Dies wird
+kenntlich an der Anzeige 'MARK+' in der Überschrift. Sobald Sie den
+ersten Satz markiert haben, erscheint bei jedem Satz, ob er markiert
+ist oder nicht. 
+    Haben Sie einen Satz irrtümlich markiert, können Sie die Mar­
+kierung mit der gleichen Funktion auch wieder entfernen. 
+    Alle Funktionen, die bisher die durch das Suchmuster ausge­
+wählten Sätze bearbeitet haben, arbeiten nun nur noch auf den
+markierten Sätzen. Somit können Sie anschließend mit der Druck­
+funktion die gewünschten Sätze drucken. Die Markierung hat also
+Priorität über die eingestellte Suchbedingung. Lediglich die Bewe­
+gung am Bildschirm beachtet immer nur die Suchbedingung. 
+    Sie können alle Markierungen der Datei mit der Funktion 
+#free (0.2)# 
+ 
+        Alle Markier. 
+        L Löschen 
+ 
+#free (0.2)# 
+im Menü 'Gesamtdatei' wieder entfernen. Anschließend wird beim
+Drucken wieder das Suchmuster beachtet. Die Markierungen ver­
+schwinden auch, wenn eine neue Datei geöffnet wird. Die Markie­
+rungen sind also nicht permanent in einer Datei gespeichert, son­
+dern existieren nur, während die Datei geöffnet ist. 
+    Bei Koppeldateien können Sie aus technischen Gründen immer
+nur alle Kombinationen auf einmal markieren. Die Markierung einer
+Kombination markiert auch alle anderen Kombinationen des gleichen
+Satzes. 
+ 
+ 
+10.5 Übersicht 
+ 
+Wie Sie bisher gesehen haben, zeigte EUDAS immer einen einzigen
+Satz in dem Standardformular auf dem Bildschirm. Es gibt jedoch
+auch eine Möglichkeit, mehrere Sätze gleichzeitig zu betrachten.
+Dazu dient die Funktion 
+#free (0.2)# 
+ 
+        U Übersicht 
+ 
+#free (0.2)# 
+im Menü 'Gesamtdatei'. 
+    In der Übersicht nimmt jeder Satz nur eine Bildschirmzeile in
+Anspruch. Die Feldinhalte werden, durch Komma getrennt, in der
+Zeile nacheinander aufgezählt, bis kein Platz mehr vorhanden ist.
+Am Anfang jeder Zeile steht die Satznummer und ob der jeweilige
+Satz markiert ist (entweder '+' für markiert oder '-'). In der Über­
+schrift stehen in gleicher Weise die Feldnamen angegeben. 
+    Der aktuelle Satz wird innerhalb der Übersichtsanzeige immer
+durch eine inverse Satznummer dargestellt. Es werden nur die durch
+das eingestellte Suchmuster ausgewählten Sätze gezeigt. Trifft die
+Selektionsbedingung nicht auf den aktuellen Satz zu, wird an seiner
+Stelle zur Information ein leerer Platzhalter angezeigt. Hinter dem
+letzten Satz wird auch das Dateiende als besonders gekennzeichne­
+ter Satz angegeben. 
+ 
+___________________________________________________________________________________________ 
+ 
+      ÜBERSICHT:   Blättern: HOP OBEN, HOP UNTEN   Ende: ESC q   Hilfe: ESC ? 
+      Satznr. Name, Vorname, PLZ, Ort, Strasse, m/w, 
+      1     - Wegner, Herbert, Krämergasse 12, 5000, Köln, m, 
+      2     - Sandmann, Helga, Willicher Weg 109, 5300, Bonn 1, w, 
+      3     - Katani, Albert, Lindenstr. 3, 5210, Troisdorf, m, 
+      4     - Ulmen, Peter, Mozartstraße 17, 5, Köln 60, m, 
+      5     - Regmann, Karin, Grengelweg 44, 5000, Köln 90, w, 
+      6     - Arken, Hubert, Talweg 12, 5200, Siegburg, m, 
+      7     - Simmern, Anna-Maria, Platanenweg 67, 5, Köln 3, w, 
+      8     - Kaufmann-Drescher, Angelika, Hauptstr. 123, 53, Bonn 2, w, 
+      9     - Fuhrmann, Harald, Glockengasse 44, 5000, Köln 1, m, 
+      10    - Seefeld, Friedrich, Kabelgasse, 5000, Köln-Ehrenfeld, m, 
+      11    - << DATEIENDE >> 
+ 
+___________________________________________________________________________________________ 
+ 
+ 
+#center#Abb. 10-1   Übersicht 
+ 
+ 
+#on("b")#Feldauswahl#off("b")# Wenn Sie die Funktion aufrufen, haben Sie
+zuerst
+noch die Möglichkeit, nur einen Teil der vorhandenen Felder zur
+Anzeige auszuwählen. Dazu bejahen Sie die Frage und können dann
+die Felder in der gewünschten Reihenfolge ankreuzen. Analog zur
+Funktion 'Feldauswahl' wird auch hier die zuletzt für die Übersicht
+verwendete Feldauswahl beibehalten, wenn Sie die Frage verneinen
+oder kein Feld ankreuzen. Die Feldauswahl für die Übersicht ist
+unabhängig von der Feldauswahl für die normale Satzanzeige. 
+    Von der Möglichkeit zur Feldauswahl sollten Sie Gebrauch ma­
+chen, denn durch die komprimierte Darstellung der Übersicht kann
+meistens nur ein kleiner Teil eines Satzes dargestellt werden. 
+ 
+#on("b")#Rollen#off("b")# Nachdem die Sätze auf dem Bildschirm erschienen
+sind,
+haben Sie wieder die Möglichkeit, die Darstellung zu rollen. Dazu
+können Sie die Pfeiltasten OBEN und UNTEN sowie die Tastenkombi­
+nationen HOP OBEN und HOP UNTEN verwenden. Diese Funktionen
+verschieben den invers dargestellten aktuellen Satz und funktio­
+nieren wie im Editor. Beachten Sie auch hier wieder den Unterschied
+zum Rollen in der Einzelsatzanzeige. 
+    Das Rollen wirkt wie ein Positionieren mit 'Weiter' oder 'Zu­
+rück'. Nach der Rückkehr aus der Übersicht können Sie sich also an
+einer ganz anderen Stelle in der Datei befinden. 
+   Es stehen Ihnen zum Rollen auch noch die folgenden Tasten­
+kombinationen zur Verfügung (wie im Editor): HOP RETURN macht
+den aktuellen Satz zum ersten auf der Seite. ESC '1' zeigt den er­
+sten Satz der Datei, ESC '9' analog dazu den letzten. 
+    Wenn Sie eine komplizierte Suchbedingung eingestellt haben
+und EUDAS viele Sätze erfolglos überprüfen muß, dauert der Bild­
+aufbau natürlich entsprechend lange. EUDAS gibt zu Ihrer Informa­
+tion aber immer die Nummer des Satzes aus, der gerade überprüft
+wird. Außerdem werden Tastenbefehle nach jeder Zeile angenommen,
+so daß Sie schon weiterblättern können, wenn Sie den ersten Satz
+gesehen haben. 
+ 
+#on("b")#Markieren#off("b")# In der Übersicht können Sie auch Sätze
+markieren. Mit
+'+' markieren Sie den aktuellen Satz; mit '-' entfernen Sie die Mar­
+kierung wieder. So können Sie einfach die Sätze ankreuzen, die Sie
+später bearbeiten wollen. 
+ 
+#on("b")#Verlassen#off("b")# Mit ESC 'q' können Sie die Übersicht wieder
+verlassen,
+auch mitten beim Aufbau des Bildes. Haben Sie erkannt, daß EUDAS
+sinnlos mit einer falschen Suchbedingung sucht, können Sie die
+Funktion auch mit ESC 'h' (Halt) abbrechen und gegebenenfalls ein
+neues Suchmuster einstellen.
+
diff --git a/doc/eudas/eudas.hdb.11 b/doc/eudas/eudas.hdb.11
new file mode 100644
index 0000000..6a59847
--- /dev/null
+++ b/doc/eudas/eudas.hdb.11
@@ -0,0 +1,674 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (109)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+11 Funktionen zur Bearbeitung 
+ 
+ 
+ 
+11.1 Sortieren 
+ 
+Wenn Sie die Sätze in Ihrer EUDAS-Datei in einer bestimmten Rei­
+henfolge haben wollen (dies wird in vielen Fällen zum Drucken
+verlangt), müssen Sie die Datei sortieren. Sie können EUDAS ange­
+ben, in welcher Reihenfolge die Sortierung erfolgen soll. Um die
+aktuelle Datei zu sortieren, rufen Sie die Funktion 
+#free (0.2)# 
+ 
+        Akt. Datei 
+        S Sortieren 
+ 
+#free (0.2)# 
+auf. Falls die Datei noch nie sortiert wurde, wird Ihnen auf jeden
+Fall die Sortierreihenfolge zum Auswählen angeboten. Anderenfalls
+werden Sie gefragt, ob Sie die vorherige Sortierreihenfolge ändern
+wollen. 
+    Das Sortieren wird als Veränderung betrachtet und nur auf der
+Arbeitskopie durchgeführt! 
+ 
+#on("b")#Sortierreihenfolge#off("b")# Die Sortierreihenfolge gibt an, welche
+Felder in
+welcher Reihenfolge beim Vergleichen zweier Sätze benutzt werden
+sollen. Zuerst wird das an erster Stelle angegebene Feld verglichen.
+Sind die Inhalte hier unterschiedlich, wird die Einordnung der Sätze
+nach diesem Feld bestimmt. 
+    Sind die Inhalte in diesem Feld aber gleich, so wird nach dem
+nächsten Feld verglichen. Ist kein weiteres Feld in der Sortierrei­
+henfolge angegeben, wird der Vergleich an dieser Stelle mit einem
+zufälligen Ergebnis abgebrochen, das heißt, es kann nicht vorher­
+gesagt werden, welcher der beiden Sätze zuerst kommt. 
+    Die Sortierreihenfolge können Sie in einer Menüauswahl einge­
+ben. Kreuzen Sie die Felder an, die Sie vergleichen wollen und ach­
+ten Sie auf die richtige Reihenfolge. Die eingegebene Reihenfolge
+wird in der Datei gespeichert, um beim nächsten Sortiervorgang
+wiederverwendet zu werden. 
+    Nachdem Sie alle bei der Sortierung zu berücksichtigenden
+angekreuzt haben, werden Sie für jedes dieser Felder gefragt, ob
+nach dem Feld aufsteigend oder absteigend sortiert werden soll. 
+ 
+#on("b")#Ablauf#off("b")# Der Ablauf des Sortierens wird durch Ausgabe von
+Satz­
+nummern dargestellt. Bis zur ausgegebenen Satznummer sind alle
+Sätze richtig sortiert. Bei Bedarf kann der Vorgang durch SV und
+dann 'halt' abgebrochen werden. Die Datei bleibt dabei auf jeden
+Fall intakt. 
+ 
+#on("b")#Optimierung#off("b")# Die gespeicherte Sortierreihenfolge wird auch
+noch zu
+einer weiteren Optimierung benutzt. Wenn eine Datei sortiert war
+und nur wenige Änderungen stattgefunden haben, brauchen beim
+nächsten Sortiervorgang nur die wenigen veränderten Sätze einzeln
+einsortiert zu werden. Das funktioniert natürlich nur unter der
+Voraussetzung, daß die gleiche Sortierreihenfolge gewählt wird. Das
+Sortieren braucht in diesem Fall erheblich weniger Zeit. 
+ 
+#on("b")#Probleme#off("b")# Normalerweise werden die einzelnen Felder nach
+dem
+EUMEL-Zeichencode verglichen. Das bedeutet, daß sich die Reihen­
+folge der Zeichen nach dem EUMEL-Zeichencode richtet. Ein Zeichen
+mit einem höheren Code wird also vor einem Zeichen mit einem
+niedrigeren Code einsortiert. 
+    In manchen Fällen ergeben sich mit diesem Vergleichsverfahren
+aber auch Schwierigkeiten. Wenn in einem Feld Zahlen oder DM-
+Beträge stehen, führt die Methode zu falschen Ergebnissen. Die '10'
+wird zum Beispiel vor der '2' einsortiert. Warum? Texte werden
+immer linksbündig geschrieben und verglichen. Bei Zahlen richtet
+sich die Wertigkeit jedoch nach dem Abstand vom Komma. 
+    Da bei Texten zuerst das erste Zeichen verglichen wird, ent­
+steht hier durch Vergleich von '1' und '2' der Eindruck, die '10'
+käme vor der '2'. Korrigieren könnte man dies, indem man ein Leer­
+zeichen vor die '2' schreibt. Wenn also die (nicht geschriebenen)
+Dezimalkommata direkt untereinanderstehen, werden Zahlen richtig
+verglichen. 
+ 
+#on("b")#Typ ZAHL#off("b")# EUDAS hat jedoch eine bequemere Art, dieses
+Problem zu
+behandeln. Ein Feld, das Zahlen enthalten soll, bekommt einen spe­
+ziellen Typ ZAHL zugewiesen, der zu einer richtigen Sortierung
+führt. 
+    Bei Feldern vom Typ ZAHL ignoriert EUDAS bei Vergleichen alle
+nichtnumerischen Zeichen und vergleicht den Wert der Zahl. So
+können Sie zum Beispiel in einem Satz '2,50 DM' und im anderen
+Satz '10 DM' eintragen - EUDAS kann jetzt die richtige Reihenfolge
+feststellen. 
+    Übrigens: falls Sie numerische Werte lieber mit einem Dezi­
+malpunkt statt einem Dezimalkomma schreiben, können Sie EUDAS
+das mit dem ELAN-Kommando 
+ 
+ 
+        dezimalkomma (".") 
+ 
+ 
+mitteilen. Wenn Sie ein solches Kommando eingeben wollen, können
+Sie im EUDAS-Menü ESC ESC drücken. In der Statuszeile erscheint
+dann die Aufforderung: 
+ 
+ 
+        Gib Kommando: 
+ 
+ 
+Hier können Sie wie im Editor oder im EUMEL-Monitor ein beliebiges
+Kommando eingeben und ausführen. 
+    Die Normaleinstellung für das Dezimalkomma erreichen Sie
+wieder durch das Kommando 
+ 
+ 
+        dezimalkomma (",") 
+ 
+ 
+ 
+#on("b")#Typ ändern#off("b")# Die Feldtypen sind eine permanente Eigenschaft
+einer
+EUDAS-Datei. Beim Einrichten einer neuen Datei wird zunächst der
+Standardtyp für alle Felder genommen. Sie erhalten jedoch Gelegen­
+heit, abweichende Feldtypen zu vergeben, wenn Sie die Frage 
+ 
+___________________________________________________________________________________________ 
+ 
+      Feldnamen oder Feldtypen ändern (j/n) ? 
+___________________________________________________________________________________________ 
+ 
+ 
+bejahen. 
+    Auch nachträglich können Sie die Feldtypen noch ändern. Dies
+geschieht mit der Funktion 
+#free (0.2)# 
+ 
+        F Feldstrukt. 
+ 
+#free (0.2)# 
+im Menü 'Öffnen'. Zunächst werden Sie gefragt, ob Sie noch weitere
+Feldnamen anfügen wollen. So könnten Sie die Datei um weitere
+Felder ergänzen, die bei allen Sätzen zunächst leer sind. Die neuen
+Felder müssen Sie wie beim Einrichten der Datei untereinander im
+Editor schreiben. 
+    Als zweites erscheint dann die gleiche Frage wie oben. Wenn
+Sie diese bejahen, wird Ihnen eine Auswahl der zu ändernden Fel­
+der mit Feldnamen und den zugehörigen Feldtypen angeboten. Kreu­
+zen Sie hier die Felder an, deren Feldtypen Sie ändern möchten. 
+    Da Sie mit dieser Funktion sowohl Feldnamen als auch Feld­
+typen verändern können, wird Ihnen für jedes Feld zunächst der
+Name zum Ändern angeboten. Sie können den Namen korrigieren oder
+überschreiben. Die Namensänderung hat jedoch keine Auswirkung
+auf den Feldinhalt! 
+    Wenn Sie den Namen nicht ändern wollen, drücken Sie einfach
+RETURN. Anschließend können Sie für das Feld den neuen Feldtyp
+angeben. Tippen Sie einen der vier Feldtypen als Text ein und
+drücken Sie RETURN. Anschließend hat das Feld einen neuen Typ.
+Die verschiedenen möglichen Typen werden jetzt genau erklärt. 
+ 
+#on("b")#Feldtypen#off("b")# TEXT ist der Standardtyp, der die Feldinhalte
+nach
+EUMEL-Zeichencode vergleicht. Den Typ ZAHL hatten wir schon
+weiter oben kennengelernt. Daneben gibt es noch den Typ DATUM. 
+    Dieser Typ vergleicht Daten der Form 'tt.mm.jj'. Soll ein sol­
+ches Datum richtig einsortiert werden, müßte es anderenfalls in der
+Reihenfolge umgedreht werden (also 'jj.mm.tt'). Dies ist aber nicht
+nötig, wenn das Feld den Typ DATUM bekommt. Beachten Sie, daß
+alle Inhalte, die nicht die beschriebene Form haben, als gleich be­
+trachtet werden. 
+    Der letzte Typ ist DIN. Dabei werden Texte nach DIN 5007 ver­
+glichen. Das bedeutet, daß Groß- und Kleinbuchstaben als gleich
+angesehen werden, daß alle nichtalphabetischen Zeichen ignoriert
+werden und die Umlaute ihren richtigen Platz bekommen (Umlaute
+werden in normalen Texten hinter allen anderen Zeichen einsor­
+tiert). Da hierfür ein relativ großer Zeitaufwand notwendig ist,
+sollte dieser Typ nur dann gewählt werden, wenn er erforderlich ist.
+Den schnellsten Vergleich ermöglicht der Typ TEXT. 
+ 
+#on("b")#Hinweis#off("b")# Beachten Sie, daß mit der Vergabe von Feldtypen
+keine
+Überprüfung der Eingabe verbunden ist. Insbesondere beim Datum
+wird nicht geprüft, ob die Form 'tt.mm.jj' eingehalten wurde. Wollen
+Sie solche Überprüfungen vornehmen, lesen Sie bitte Abschnitt 11.3. 
+ 
+ 
+11.2 Kopieren 
+ 
+In diesem Abschnitt sollen Sie erfahren, wie Sie eine EUDAS-Datei
+#on("i")#kopieren#off("i")# können. Diese Funktion kann nicht nur ein inhaltsgleiches
+Duplikat einer EUDAS-Datei herstellen (dies könnten Sie einfacher
+durch eine logische Kopie bewerkstelligen, s. 16.1), sondern auch
+komplizierte Umstrukturierungen vornehmen. 
+ 
+#on("b")#Kopiermuster#off("b")# Der Schlüssel zu dieser Leistungsfähigkeit
+ist das
+#on("i")#Kopiermuster#off("i")#. Wie beim Druckmuster legen Sie dadurch die genauen
+Auswirkungen der Funktion fest. 
+    Für jedes Feld in der Zieldatei, in die kopiert werden soll,
+enthält das Kopiermuster die Angabe, woraus der Inhalt dieses
+Feldes entstehen soll. Durch Auswahl und Reihenfolge dieser Anga­
+ben bestimmen Sie die Struktur der Zieldatei. 
+    Im einfachsten Fall sieht die Kopieranweisung für ein Feld wie
+folgt aus: 
+ 
+ 
+        "Feldname" K f ("Feldname"); 
+ 
+ 
+Das 'K' dient zur Festlegung der Kopierfunktion. Auf der linken
+Seite steht in Anführungsstrichen der Name des Zielfeldes. Der
+Ausdruck auf der rechten Seite gibt den zukünftigen Inhalt des
+Feldes an. Der Ausdruck im obigen Beispiel steht einfach für den
+Inhalt des Feldes 'Feldname' in der aktuellen Datei. Das Semikolon
+am Ende dient zur Abgrenzung, da der ganze Ausdruck auch mehrere
+Zeilen lang sein darf. 
+    In der oben genannten Form würde das Feld 'Feldname' iden­
+tisch in die Zieldatei kopiert. Weitere Möglichkeiten besprechen wir
+später. 
+ 
+#on("b")#Feldreihenfolge#off("b")# Zunächst wollen wir uns damit befassen,
+wie Sie
+die Feldreihenfolge in der Zieldatei beeinflussen können. Dies ge­
+schieht einfach dadurch, daß Sie die Kopieranweisungen in der ge­
+wünschten Reihenfolge aufschreiben. Damit können wir bereits ein
+erstes komplettes Beispiel betrachten: 
+ 
+ 
+        "Name" K f ("Name"); 
+        "Vorname" K f ("Vorname"); 
+        "PLZ" K f ("PLZ"); 
+        "Ort" K f ("Ort"); 
+        "Strasse" K f ("Strasse"); 
+        "m/w" K f ("m/w"); 
+ 
+ 
+Dieses Kopiermuster würde die bereits beschriebene Adressendatei
+identisch kopieren, da alle Felder in der gleichen Reihenfolge vor­
+kommen. 
+    Wenn Sie jedoch die Feldreihenfolge ändern wollen (um zum
+Beispiel ein anderes Feld als erstes zu optimieren), brauchen Sie
+bloß die Reihenfolge im Kopiermuster zu verändern: 
+ 
+ 
+        "Ort" K f ("Ort"); 
+        "Name" K f ("Name"); 
+        "Vorname" K f ("Vorname"); 
+        "PLZ" K f ("PLZ"); 
+        "Strasse" K f ("Strasse"); 
+        "m/w" K f ("m/w"); 
+ 
+ 
+Im Gegensatz zur Auswahl der Feldreihenfolge für die Anzeige än­
+dern Sie so die Feldreihenfolge für die Zieldatei permanent. 
+ 
+#on("b")#Felder anfügen#off("b")# Die beiden angegebenen Kopiermuster haben
+jedoch
+nur dann die beschriebene Wirkung, wenn die Zieldatei noch nicht
+existert. Bei einer existierenden Datei kann die Feldreihenfolge
+nicht mehr geändert werden; daher hat die Reihenfolge der Kopier­
+anweisungen dann keine Wirkung. 
+    Sie können jedoch zu einer existierenden Zieldatei noch Felder
+hinzufügen. EUDAS verwendet nämlich folgende einfache Vorschrift: 
+ 
+#limit (12.0)# 
+    Wenn als Zielfeld in einer Kopieranweisung ein Feld
+    genannt wird, das in der Zieldatei noch nicht vorkommt,
+    wird es als weiteres Feld der Zieldatei hinzugefügt. 
+#limit (13.5)# 
+ 
+Diese Strategie hat im Fall der nicht existierenden Datei zur Folge,
+daß alle Felder neu sind und in der Reihenfolge ihres Auftretens
+eingerichtet werden. Existiert die Datei schon, werden zusätzliche
+Felder am Ende angefügt. 
+    Beachten Sie, daß zusätzliche Felder für eine existierende
+Datei nur in den neu hinzukopierten Sätzen gefüllt sind. In den
+alten Sätzen bleiben alle neuen Felder einfach leer. 
+ 
+#on("b")#Satzauswahl#off("b")# An dieser Stelle sollte erwähnt werden, daß
+wie bei
+allen Funktionen, die die gesamte Datei betreffen, nur die durch die
+Suchbedingung ausgewählten Sätze kopiert werden. Ist mindestens
+ein Satz markiert, werden nur die markierten Sätze kopiert und die
+Suchbedingung ignoriert. 
+ 
+#on("b")#Teildatei#off("b")# Jetzt können Sie auch die zweite wichtige
+Aufgabe des
+Kopierens verstehen. Sie können aus einer Datei einen Teil der
+Sätze und einen Teil der Felder #on("i")#herausziehen#off("i")#. Danach haben Sie
+unter Umständen eine wesentlich kleinere Datei, die sich auch
+schneller bearbeiten läßt. Gerade wenn Sie nicht den allerneuesten
+64-Bit-Supercomputer haben, können Sie so viel Zeit sparen, wenn
+Sie wiederholt nur mit einem Teil der Datei arbeiten müssen. 
+    Die Auswahl der Sätze für einen solchen Zweck erfolgt über ein
+Suchmuster; im Kopiermuster geben Sie dann nur die gewünschten
+Felder an. 
+ 
+#on("b")#Aufruf#off("b")# An dieser Stelle wollen wir jetzt endlich
+behandeln, wie
+Sie die Kopierfunktion aufrufen. Dazu gibt es die Auswahl 
+#free (0.2)# 
+ 
+        Satzauswahl 
+        K Kopieren 
+ 
+#free (0.2)# 
+im Menü "Gesamtdatei". Als erstes werden Sie nach dem Namen der
+Zieldatei gefragt. Existiert die Zieldatei schon und war sie vorher
+sortiert, werden Sie gefragt, ob Sie die Datei zum Schluß wieder
+sortieren wollen. Wie immer beim Sortieren werden auch hier gege­
+benenfalls nur die neu hinzugekommenen Sätze einsortiert. 
+    Als nächstes müssen Sie den Namen des Kopiermusters angeben.
+Da das Kopiermuster eine normale Textdatei ist, können Sie sich
+einen beliebigen Namen ausdenken, unter dem das Muster dann
+gespeichert wird. 
+    Wollen Sie das Kopiermuster nicht aufbewahren, sondern nur
+einmal verwenden, brauchen Sie keinen Namen anzugeben. Drücken
+Sie einfach RETURN und für die Dauer des Kopierens wird das
+Kopiermuster als unbenannte Datei eingerichtet. 
+    Nachdem Sie den Namen des Kopiermusters eingegeben haben,
+gelangen Sie in den Editor, wo Sie das Muster ändern können. Damit
+Sie beim ersten Mal nicht so viel tippen müssen, bietet EUDAS Ihnen
+bei einer neuen Musterdatei ein #on("i")#Standard-Kopiermuster#off("i")# zum Ändern
+an. Das Aussehen des Standard-Kopiermusters richtet sich danach,
+ob die Zieldatei schon existiert oder nicht. 
+    Existiert die Zieldatei noch nicht, so werden im Standard-
+Kopiermuster alle Felder der Ausgangsdatei in ihrer originalen Rei­
+henfolge angegeben. Wenn Sie dieses Muster nicht noch ändern, wird
+die aktuelle Datei identisch kopiert. 
+    Sie können jedoch die Feldreihenfolge verändern oder Felder
+weglassen, indem Sie einfach die entsprechenden Zeilen vertauschen
+oder löschen. Für Umbenennungen überschreiben Sie einfach den
+Namen auf der linken Seite der Kopieranweisung. So können Sie das
+Kopiermuster mit geringstem Aufwand erstellen. 
+    Existiert die Zieldatei jedoch schon, werden Ihnen im Kopier­
+muster alle Felder der Zieldatei angeboten. Bei Feldern, die in der
+aktuellen Datei nicht vorkommen, erscheint folgende Anweisung: 
+ 
+ 
+        "Anrede" K ""; 
+ 
+ 
+Obwohl die Anweisung in diesem Fall keine Wirkung hat (wenn man
+sie wegließe, würde das Feld ebenfalls leer bleiben), ist sie dennoch
+aufgeführt, damit Sie auf der rechten Seite einen entsprechenden
+Ausdruck einsetzen können. 
+    Bei den angebotenen Anweisungen hat eine Änderung der Rei­
+henfolge oder eines Feldnamens keinen Sinn, da diese Felder ja alle
+bereits existieren. Jedoch können Sie die Ausdrücke auf der rechten
+Seite variieren und neue Anweisungen (Felder) hinzufügen. 
+ 
+#on("b")#Ablauf#off("b")# Wenn Sie die Eingabe des Kopiermusters mit ESC 'q'
+verlas­
+sen, wird das Kopiermuster übersetzt. Dabei können Fehlermeldun­
+gen auftreten. Sie können dann die Fehler korrigieren, wobei Sie die
+Fehlermeldungen gleichzeitig auf dem Bildschirm sehen können. War
+das Kopiermuster korrekt,  werden alle ausgewählten (bzw. markier­
+ten) Sätze der aktuellen Datei in die Zieldatei kopiert und diese
+anschließend gegebenenfalls noch sortiert. 
+    Die kopierten Sätze werden jeweils am Ende der Zieldatei ange­
+fügt. War die Zieldatei vorher schon sortiert, können Sie angeben,
+daß die neuen Sätze zum Schluß noch einsortiert werden. Anderen­
+falls können Sie die Datei anschließend mit der Funktion 'Sortieren'
+sortieren. 
+ 
+#on("b")#ELAN-Ausdrücke#off("b")# Wenn Sie schon einmal programmiert haben,
+wird
+Ihnen vielleicht aufgefallen sein, daß ein Kopiermuster einem
+ELAN-Programm verdächtig ähnlich sieht. Diese Vermutung trügt Sie
+nicht. Dies läßt den Schluß zu, daß Sie noch mehr ELAN hier an­
+bringen können. 
+    Haben Sie noch nie programmiert, sollten Sie jetzt nicht in
+Panik geraten, denn das Wichtigste dieses Abschnitts haben Sie
+bereits gelernt. Vielleicht sind Ihnen die folgenden Beispiele bereits
+ganz nützlich. Um alle Möglichkeiten auszunutzen, sollten Sie sich
+aber irgendwann (später!) mit den Kapiteln 14 und 15 befassen, in
+denen Sie Genaueres erfahren. 
+    Zunächst sei festgestellt, daß der rechte Teil einer Kopieran­
+weisung ein beliebiger ELAN-Ausdruck sein kann, der einen TEXT
+liefert. Den wichtigsten Ausdruck kennen Sie bereits: 
+ 
+ 
+        f ("Feldname") 
+ 
+ 
+liefert den Inhalt des Feldes 'Feldname' des aktuellen Satzes der
+aktuellen Datei. Gibt es das Feld nicht, erscheint eine Fehlermel­
+dung bei der Ausführung. 
+    Sie können jedoch auch einen konstanten Text angeben, der
+dann für alle Sätze gleich ist. Dazu schließen Sie den Text einfach
+in Anführungsstriche ein. Die folgende Kopieranweisung dient dazu,
+ein neues Feld einzurichten, das aber vorläufig noch leer bleiben
+soll: 
+ 
+ 
+        "Feldname" K ""; 
+ 
+ 
+Ebenso können Sie mehrere Felder zu einem neuen verbinden, zum
+Beispiel: 
+ 
+ 
+        "Wohnort" K f ("PLZ") + " " + f ("Ort"); 
+ 
+ 
+Das Pluszeichen kennzeichnet die Aneinanderreihung von zwei Tex­
+ten. Denken Sie auch immer an das Semikolon am Ende. In gleicher
+Weise können Sie viele andere Textfunktionen verwenden, die in
+Kapitel 14 beschrieben sind. 
+    Prinzipiell können Sie auch Bedingungen mit IF abfragen, wie
+zum Beispiel in der folgenden Übersetzung: 
+ 
+ 
+        IF f ("m/w") = "w" THEN 
+            "Anrede" K "Frau" 
+        ELSE 
+            "Anrede" K "Herr" 
+        END IF; 
+ 
+ 
+Auf diese Weise können Sie Kodierungen verschiedenster Art auto­
+matisch umsetzen. Sie müssen hierbei jedoch unbedingt darauf ach­
+ten, daß innerhalb der IF-Konstruktion immer eine Kopieranweisung
+ausgeführt wird. Falls nämlich kein Fall zutrifft und für ein Feld
+keine Kopieranweisung ausgeführt wird, wird das Feld bei einer
+neuen Datei auch nicht richtig eingerichtet. 
+ 
+ 
+11.3 Tragen 
+ 
+In Kapitel 6 hatten Sie gesehen, wie man einzelne Sätze aus der
+aktuellen Datei in eine andere trägt, und auch, wie man sie wieder
+zurückholen kann. Diese Funktion diente im wesentlichen dazu,
+nicht mehr benötigte Sätze zu entfernen. 
+    Sie haben aber auch die Möglichkeit, eine ganze Reihe von
+Sätzen in einem Arbeitsgang zu tragen, nämlich alle durch das
+Suchmuster ausgewählten beziehungsweise alle markierten Sätze.
+Diese Funktion dient ebenfalls dazu, Sätze zu entfernen, beispiels­
+weise alle Sätze, die vor einem gewissen Stichtag liegen. Als wei­
+tere Anwendung können Sie beim Tragen aber auch Bedingungen
+überprüfen. 
+    Diese #on("i")#Prüfbedingungen#off("i")# sollen sicherstellen, daß die Daten in
+einer Datei ganz bestimmten Richtlinien entsprechen. Zum Beispiel
+kann geprüft werden, ob ein eingegebenen Datum stimmen kann, ob
+ein Satz doppelt aufgenommen wurde oder ob eine Artikelnummer die
+richtige Anzahl von Stellen hat. 
+    Die Prüfbedingungen werden einer Datei fest zugeordnet. Sie
+können mit der Funktion 
+#free (0.2)# 
+ 
+        P Prüfbed. 
+ 
+#free (0.2)# 
+im Menü 'Öffnen' eingegeben oder geändert werden. Die Prüfbedin­
+gungen werden als Text im Editor geschrieben. 
+ 
+#on("b")#Ablauf#off("b")# Das ganze Verfahren läuft nun so ab: Sie fügen neue
+Sätze
+immer erst in eine Zwischendatei ein, die die gleiche Struktur wie
+die eigentliche Datei hat. Wenn Sie alle Sätze fertig eingegeben
+haben, tragen Sie diese Datei komplett in die gewünschte Datei.
+Dabei werden die Prüfbedingungen getestet. 
+    Erfüllt ein Satz die Bedingungen, wird er anstandslos getragen.
+Trifft eine Bedingung aber nicht zu, bleibt der Satz in der Zwi­
+schendatei und eine entsprechende Meldung wird ausgegeben. Die
+Meldungen werden gespeichert, um Sie später nochmal abrufen zu
+können. 
+    Sie müssen jetzt in der Zwischendatei die notwendigen Ände­
+rungen durchführen, damit die Prüfbedingungen erfüllt werden. Beim
+Aufruf der Funktion 
+#free (0.2)# 
+ 
+        A Ändern 
+ 
+#free (0.2)# 
+können Sie mit Hilfe der Tastenkombination ESC 'P' (großes P) die
+Datei mit den Fehlermeldungen in einem kleinen Teilfenster editie­
+ren. Anhand dieser Hinweise können Sie dann den Satz korrigieren.
+Die Meldungen bleiben bis zum nächsten Öffnen oder Tragen erhal­
+ten. 
+    Nach der Korrektur können Sie den gleichen Vorgang erneut
+aufrufen - es sind ja nur noch die zuerst fehlerhaften Sätze in der
+Zwischendatei. Bei Bedarf können Sie diesen Vorgang wiederholen,
+bis alle Sätze korrekt übernommen worden sind. 
+ 
+#on("b")#Aufruf#off("b")# Das Tragen wird aufgerufen durch die Funktion 
+#free (0.2)# 
+ 
+        Satzauswahl 
+        T Tragen 
+ 
+#free (0.2)# 
+Nach Eingabe des Zieldateinamens müssen Sie noch angeben, ob Sie
+die Prüfbedingungen testen wollen. 
+ 
+#on("b")#Prüfbedingungen#off("b")# Zu diskutieren bleibt noch die Form der
+Prüfbe­
+dingungen. Diese stellen ein kleines ELAN-Programm dar, in dem
+einige spezielle Prozeduren zum Prüfen enthalten sind. Wenn Sie
+nicht ELAN programmieren können, sollte Sie diese Bemerkung nicht
+erschrecken: die Prüfbedingungen sind einfach genug. 
+    Sie schreiben also die Prüfbedingungen jeweils untereinander.
+Eine mögliche Bedingung ist 
+ 
+ 
+        wertemenge ("Feldname", "Wert1,Wert2,Wert3,Wert4"); 
+ 
+ 
+Diese Bedingung gibt an, daß das Feld einen der angegebenen Werte
+haben muß. Die Werte werden untereinander durch Komma getrennt.
+Es gibt jedoch keine Möglichkeit, Werte mit Komma darzustellen, da
+das Komma immer als Trennung wirkt. Leerzeichen dürfen in den
+Werten vorkommen, sie müssen dann aber auch genau so im Feld
+stehen. 
+    Wir könnten zum Beispiel eine Bedingung für unser Feld 'm/w'
+wie folgt formulieren 
+ 
+ 
+        wertemenge ("m/w", "m,w"); 
+ 
+ 
+EUDAS würde sich dann beschweren, wenn das Feld leer wäre (ir­
+gendein Geschlecht muß die Person ja wohl haben). Wenn das Feld
+auch leer sein darf, geben Sie einfach zwei Kommata hintereinander
+oder ein Komma am Anfang an: 
+ 
+ 
+        wertemenge ("m/w", ",m,w"); 
+ 
+ 
+Eine andere Möglichkeit der Prüfbedingung besteht darin, eine
+Maske für ein Feld zu definieren. Diese Maske gibt an, daß an be­
+stimmten Stellen des Feldes nur bestimmte Zeichen stehen dürfen.
+So könnte man zum Beispiel folgende Maske für ein Datumsfeld
+angeben: 
+ 
+ 
+        feldmaske ("Datum", "99.99.99"); 
+ 
+ 
+Die Neunen haben hier eine spezielle Bedeutung und und stehen für
+eine beliebige Ziffer. Es gibt noch einige weitere Zeichen, die eine
+reservierte Bedeutung haben, nämlich: 
+ 
+ 
+        '9'   für jede Ziffer (wie schon erwähnt) 
+        'X'   für jedes Zeichen 
+        'A'   für jeden Großbuchstaben 
+        'a'   für jeden Kleinbuchstaben 
+        '*'   für eine Folge beliebiger Zeichen 
+ 
+ 
+Alle anderen Zeichen im Muster stehen für sich selbst. Eine Sonder­
+stellung besitzt der Stern; er sollte sparsam verwendet werden, da
+seine Benutzung etwas aufwendiger ist. Der Stern kann auch für
+eine leere Zeichenfolge stehen. Als weiteres Beispiel könnte man
+definieren 
+ 
+ 
+        feldmaske ("Name", "A*"); 
+ 
+ 
+damit immer ein Name angegeben ist, der noch dazu mit einem Groß­
+buchstaben beginnt. 
+    Für Bedingungen, die sich nicht mit diesen beiden Prozeduren
+formulieren lassen, gibt es noch 
+ 
+ 
+        pruefe ("Feldname", Bedingung); 
+ 
+ 
+Diese Prozedur erhält einen logischen (booleschen) Wert als Parame­
+ter, der einen Vergleich darstellt. Ist dieser Parameter falsch
+(FALSE), wird eine entsprechende Fehlermeldung protokolliert. So
+könnte man folgende Bedingung angeben: 
+ 
+ 
+        pruefe ("Alter", wert ("Alter") > 18.0); 
+ 
+ 
+Diese Bedingung würde sicherstellen, daß alle Personen in der Datei
+volljährig sind ('wert' ist eine von EUDAS definierte Funktion, die
+den Inhalt eines Feldes als REAL-Zahl liefert - denken Sie auch
+daran, daß der ELAN-Compiler Zahlen mit Dezimalpunkt geschrieben
+haben möchte). 
+    Da die Prüfbedingungen ein ELAN-Programm sind, können Sie
+natürlich sämtliche ELAN-Anweisungen verwenden. 
+    Weiterhin haben Sie die Möglichkeit, Doppeleinträge zu verhin­
+dern. Dazu geben Sie mit Hilfe der Prozedur 
+ 
+ 
+        eindeutige felder (n); 
+ 
+ 
+wieviele Felder vom ersten an eindeutig sein sollen. Ein zu tragen­
+der Satz, der mit irgendeinem anderen Satz in diesen Feldern über­
+einstimmt, wird als fehlerhaft zurückgewiesen. In unserer Adressen­
+datei könnte man 
+ 
+ 
+        eindeutige felder (2); 
+ 
+ 
+angeben. Damit würde ein neuer Satz mit bereits vorhandenem Na­
+men und Vornamen abgelehnt. 
+ 
+#on("b")#Limit#off("b")# Aus technischen Gründen können die Prüfbedingungen
+einer
+Datei nur 2000 Zeichen umfassen. Wollen Sie aufwendigere Bedin­
+gungen konstruieren, sollten Sie sich diese als Prozedur definieren
+und insertieren. In den Prüfbedingungen müssen Sie dann nur diese
+Prozedur aufrufen. 
+ 
+ 
+11.4 Automatische Änderungen 
+ 
+Mit EUDAS können Sie die geöffnete Datei nicht nur satzweise von
+Hand ändern, sondern auch automatisch die ganze Datei. Dazu müs­
+sen Sie dem Rechner eine Vorschrift geben, nach der er handeln
+kann. Ein solches #on("i")#Änderungsmuster#off("i")# stellt im Prinzip schon ein klei­
+nes Programm dar. Der Änderungsvorgang wird durch die Auswahl 
+#free (0.2)# 
+ 
+        V Verändern 
+ 
+#free (0.2)# 
+aufgerufen. Dabei wird der Name des Änderungsmusters erfragt. Dies
+ist eine normale Textdatei. Existiert das Muster noch nicht, können
+Sie den Inhalt an dieser Stelle im Editor angeben. Anschließend
+werden alle ausgewählten Sätze nach der Vorschrift bearbeitet.
+Dabei wird jeweils die aktuelle Satznummer ausgegeben. 
+ 
+#on("b")#Änderungsmuster#off("b")# Da auch ein Kopiermuster ein Programm ist,
+ist
+es nicht erstaunlich, daß Änderungsmuster ganz ähnlich aussehen.
+Eine typische Zeile sieht etwa so aus: 
+ 
+ 
+        "Feldname" V "neuer Inhalt"; 
+ 
+ 
+Diese Zeile bedeutet: Ersetze den Inhalt des Feldes 'Feldname'
+durch den Text 'neuer Inhalt'. Anstelle des neuen Textes kann
+wieder ein beliebiger ELAN-Ausdruck stehen. Ein Beispiel, in dem
+ein Feld einen Stern angehängt bekommt, sieht dann so aus: 
+ 
+ 
+        "Feldname" V f ("Feldname") + "*"; 
+ 
+ 
+Beachten Sie, daß Sie den Ausdruck auf der rechten Seite eventuell
+in Klammern setzen müssen (obwohl der Operator 'V' die niedrigste
+Priorität hat). Wenn Sie sich nicht sicher sind, können Sie den Aus­
+druck immer in Klammern einschließen. 
+    Ebenso wie im Kopiermuster können Sie hier beliebige ELAN-
+Ausdrücke verwenden. Auch IF-Abfragen und ähnliche Konstruktio­
+nen sind möglich, im Gegensatz zum Kopiermuster sogar ohne Be­
+schränkungen. 
+    Im Vergleich zu einem separat geschriebenen ELAN-Programm
+hat das Änderungsmuster den Vorteil, daß Sie nur die eigentlichen
+Veränderungsanweisungen kodieren müssen. Die wiederholte Anwen­
+dung auf die ausgewählten Sätze erledigt EUDAS automatisch. Wol­
+len Sie eine solche Änderungsanweisung fest insertieren, so brau­
+chen Sie das Muster nur in eine Prozedur zu verpacken und EUDAS
+zu übergeben (Näheres s. Referenzhandbuch). 
+
diff --git a/doc/eudas/eudas.hdb.12 b/doc/eudas/eudas.hdb.12
new file mode 100644
index 0000000..fba5ca5
--- /dev/null
+++ b/doc/eudas/eudas.hdb.12
@@ -0,0 +1,446 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (123)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+12 Weitere Möglichkeiten zum Drucken 
+ 
+ 
+ 
+12.1 Anschluß an die Textverarbeitung 
+ 
+Auf zweierlei Art und Weise kann der EUDAS-Druckgenerator mit
+den Programmen der EUMEL-Textverarbeitung zusammenarbeiten.
+Zum ersten können Ausgabedateien des Druckprozesses anschließend
+mit den Textkosmetik-Werkzeugen bearbeitet werden. Zum anderen
+kann EUDAS im Editor direkt Daten aus einer EUDAS-Datei in die
+editierte Datei importieren. 
+ 
+#on("b")#Druckrichtung#off("b")# Wie Sie schon in Kapitel 7 gesehen haben,
+kann
+man die Ausgabe des Druckgenerators statt auf den Drucker in eine
+Datei umleiten. Die Datei erhält dann einen automatisch generierten
+Namen. Sie können jedoch auch festlegen, daß die Ausgabe in eine
+ganz bestimmte Datei geschrieben werden soll. Dazu wählen Sie die
+Funktion 
+ 
+ 
+        Ausgabe 
+        R Richtung 
+ 
+ 
+im Druckmenü. Es erscheint die Frage 
+ 
+___________________________________________________________________________________________ 
+ 
+      Ausgabe automatisch zum Drucker (j/n) ? 
+___________________________________________________________________________________________ 
+ 
+ 
+Verneinen Sie die Frage und es erscheint 
+ 
+___________________________________________________________________________________________ 
+ 
+      Ausgabe in bestimmte Datei (j/n) ? 
+___________________________________________________________________________________________ 
+ 
+ 
+Wenn Sie diese Frage auch verneinen, erhält die Ausgabedatei einen
+automatisch generierten Namen. Wenn Sie die Frage aber bejahen,
+können Sie anschließend den Namen der Ausgabedatei angeben. 
+    Existiert die angegebene Datei schon, wird der Ausdruck am
+Ende der Datei angefügt. Anderenfalls wird die Datei neu eingerich­
+tet. 
+    Die Angabe der Ausgabedatei gilt jedoch nur für den folgenden
+Druckvorgang. Wenn Sie mehrmals in die gleiche Datei drucken wol­
+len, müssen Sie den Namen immer wieder neu angeben. Falls Sie dies
+vergessen, wird die folgenden Male wieder ein Name automatisch
+generiert. 
+ 
+#on("b")#Begrenzung der Dateigröße#off("b")# Für kleinere Systeme ist es
+vorteilhaft,
+wenn die Druckausgabe nicht in einer großen Datei gesammelt wird,
+sondern sich auf mehrere kleine Dateien verteilt. Da die Ausgabe­
+datei nach dem Drucken gelöscht wird, kann man auf diese Weise
+einen Hintergrundengpaß vermeiden. Es besteht die Möglichkeit, die
+maximale Größe der Ausgabedatei mit dem ELAN-Kommando 
+ 
+ 
+        maxdruckzeilen (1000) 
+ 
+ 
+auf eine bestimmte Zeilenzahl (maximal 4000) zu beschränken. Wenn
+der Druckgenerator nach der Bearbeitung eines Satzes feststellt,
+daß diese Maximalzahl überschritten wurde, wird die Ausgabedatei
+direkt gedruckt (falls durch 'Richtung' eingestellt) und eine neue
+Ausgabedatei eröffnet. 
+ 
+#on("b")#Initialisierungsteil#off("b")# Dabei ist jedoch zu beachten, daß
+Drucker­
+steuerungsanweisungen, die im Vorspann eingestellt wurden, jetzt in
+der neuen Datei nicht mehr vorhanden sind. In einem solchen Fall
+würden die folgenden Teile der Ausgabe mit einer anderen Einstel­
+lung gedruckt. 
+    Um dies zu vermeiden, können Sie solche Anweisungen in den
+#on("i")#Initialisierungsteil#off("i")# schreiben. Der Initialisierungsteil umfaßt alle
+Zeilen des Druckmusters bis zum ersten Abschnitt, also bis zur
+ersten Anweisung. Zeilen im Initialisierungsteil werden beim Eröff­
+nen einer neuen Ausgabedatei an den Anfang dieser Datei ge­
+schrieben. 
+    Druckersteuerungsanweisungen, die ein bestimmtes Schriftbild
+der Ausgabe erzeugen ('type', 'limit', 'linefeed', 'start' usw.), sollten
+also in den Initialisierungsteil vor Beginn aller Abschnitte ge­
+schrieben werden. 
+ 
+#on("b")#Nachbearbeitung#off("b")# Wenn Sie in der Druckausgabe verschiedene
+Schriften oder Proportionalschrift verwenden wollen, sollten Sie die
+folgenden Hinweise beachten. Da EUDAS keine Informationen über
+die Schriftbreiten und -größen hat, werden alle Schrifttypen gleich
+behandelt. Dies gilt insbesondere für die Zeilenbreite, die ja durch
+das Dateilimit des Druckmusters festgelegt ist. 
+    So kann es passieren, daß Zeilen mit kleinen Schrifttypen zu
+früh abgeschnitten werden, während Zeilen mit großen Schriften
+nicht mehr auf das Blatt passen. Für diesen Fall sollten Sie das
+größte benötigte Limit einstellen (zum Beispiel 135 bei Schmal­
+schrift auf DIN A 4) und die Ausgabedatei anschließend mit 'line­
+form' bearbeiten. 
+    'lineform' verteilt zu langen Text auf mehrere Zeilen. Außerdem
+werden gegebenenfalls Trennungen durchgeführt. 
+    'lineform' benötigt zur Information Absatzmarken. Fehlt an
+einer Zeile die Absatzmarke, wird die nächste Zeile so weit wie
+möglich direkt angehängt. Die Absatzmarken in der Ausgabedatei
+werden direkt aus dem Druckmuster übernommen (es ist nicht mög­
+lich, Absatzzeilen durch eingesetzte Leerzeichen zu erzeugen). Im
+Normalfall sollten alle Zeilen im Druckmuster eine Absatzmarke
+haben. 
+    Wenn Sie seitenorientierte Überschriften haben möchten, kön­
+nen Sie auch 'pageform' einsetzen. Die gewünschten Überschrift­
+anweisungen können Sie im Initialisierungsteil angeben. 
+    Die beiden Funktionen wählen Sie über den Menüpunkt 
+ 
+ 
+        N Nachbearb. 
+ 
+ 
+im Druckmenü. Dort können Sie den Namen der Ausgabedatei ange­
+ben, die Sie bearbeiten möchten. Es wird jeweils gefragt, ob Sie
+'lineform' und 'pageform' anwenden wollen. Das Ergebnis der Bear­
+beitung können Sie danach ausdrucken. 
+ 
+#on("b")#EUDAS im Editor#off("b")# Wenn Sie sich im Editor zum Zweck der
+Textver­
+arbeitung befinden, können Sie Daten aus einer EUDAS-Datei direkt
+in die editierte Datei übernehmen. Dazu wählen Sie zunächst die
+gewünschten Sätze aus - danach geben Sie den Namen eines Druck­
+musters an. EUDAS druckt die gewählten Sätze unter Beachtung des
+Druckmusters direkt in die editierte Datei. 
+    Wenn Sie das Kommando 
+ 
+ 
+        eudas 
+ 
+ 
+im Editor geben (nach ESC ESC), gelangen Sie in ein spezielles
+Kurzprogramm, das alle notwendigen Information von Ihnen erfragt. 
+    Zunächst müssen Sie den Namen der gewünschten EUDAS-Datei
+angeben. Diese Datei wird dann automatisch geöffnet. Vorher geöff­
+nete Dateien werden nach Anfrage gesichert. Beachten Sie, daß
+keine Datei mehr geöffnet ist, wenn Sie später EUDAS wieder normal
+aufrufen. 
+    Danach wird Ihnen eine Übersicht aller Sätze gezeigt - in einer
+Form, die Sie aus der Funktion 'Übersicht' bereits kennen. Wie dort
+wird Ihnen zunächst eine Auswahl der Felder angeboten, um die
+Anzeige übersichtlich zu halten. Anschließend können Sie noch ein
+Suchmuster angeben. 
+    In der Übersicht können Sie sich dann zu einem bestimmten
+Satz bewegen oder mehrere Sätze markieren. Nach dem Verlassen der
+Übersicht können Sie den aktuellen Satz oder alle ausgewählten
+(bzw. markierten) Sätze drucken. Natürlich können Sie auch beide
+Fragen verneinen. 
+    Zum Drucken wird der Name des Druckmusters erfragt. Dieses
+muß bereits existieren. Die Ausgabe wird an der Stelle eingefügt, an
+der der Cursor in der editierten Datei steht - die Zeile wird bei
+Bedarf aufgesplittet. 
+    Nach dem Drucken können Sie den Vorgang wiederholen, wenn
+Sie zum Beispiel einen weiteren Satz drucken wollen. Dazu können
+Sie auch ein neues Suchmuster angeben. Markierungen von Sätzen
+werden nach dem Drucken gelöscht. 
+ 
+ 
+12.2 Spaltendruck 
+ 
+Für manche Anwendungen reicht es nicht aus, wenn die bearbeite­
+ten Sätze jeweils untereinander in der Ausgabe erscheinen. Häufig­
+stes Beispiel dafür ist der Etikettendruck. Hierfür werden vielfach
+mehrbahnige Formulare eingesetzt. 
+    In diesem Fall müssen die Sätze bis zur gewünschten Anzahl
+von Spalten nebeneinander gesetzt werden - erst danach wird die
+nächste Reihe angefangen. 
+    EUDAS unterstützt diese Anwendung. Dazu wird hinter der
+'%WIEDERHOLUNG'-Anweisung die Anzahl der Spalten als Parameter
+geschrieben (durch Leerzeichen getrennt). Der Wiederholungsteil
+wird dann mit der angegebenen Anzahl von Spalten gedruckt. Zu
+beachten ist, daß Vorspann und Nachspann diese Spaltenanordnung
+durchbrechen, also immer hinter dem bisher Gedruckten beginnen. 
+    Die Spaltenbreite wird vom Dateilimit des Druckmusters be­
+stimmt. Die Zeilen eines Wiederholungsteils werden bis zum Limit
+mit Leerzeichen aufgefüllt, wenn der nächste Wiederholungsteil
+danebengesetzt wird. 
+    Alternativ kann die Spaltenbreite in Zeichen auch als zweiter
+Parameter angegeben werden. Der Wert gilt jedoch nur für den Wie­
+derholungsteil - Vor- und Nachspann richten sich immer nur nach
+dem Dateilimit. 
+    Es spielt keine Rolle, ob die nebeneinandergesetzten Wieder­
+holungsteile unterschiedliche Längen haben. Die kürzeren Teile
+werden einfach bei Bedarf durch Leerzeilen ergänzt. Es ist jedoch zu
+beachten, daß sich auf diese Weise unterschiedliche Längen für die
+einzelnen Reihen ergeben können. 
+    Beispiel: Das Ergebnis für Satz 1, 3, 4 und 5 sei vier Zeilen
+lang, für Satz 2 aber fünf Zeilen. Bei zweispaltigem Druck wird die
+erste Reihe eine Zeile länger als die folgenden (s. dazu Abb. 12-1). 
+ 
+ 
+        Satz 1              Satz 2 
+        braucht             braucht 
+        vier Zeilen.        ausnahmsweise 
+        ----------------    fünf Zeilen. 
+                            ---------------- 
+        Satz 3              Satz 4 
+        braucht             braucht 
+        vier Zeilen.        vier Zeilen. 
+        ----------------    ---------------- 
+        Satz 5 
+        braucht 
+        vier Zeilen. 
+        ----------------
+ 
+#center#Abb. 12-1   Seitenaufteilung beim Spaltendruck 
+ 
+ 
+#on("b")#Beispiel#off("b")# Zum Abschluß noch als Beispiel ein Druckmuster
+für ein
+dreibahniges Etikettenformular. Die Spaltenbreite und die Länge des
+Wiederholungsteils richten sich natürlich nach dem verwendeten
+Formular und müssen im Einzelfall ausprobiert werden. 
+ 
+ 
+        % VORSPANN 
+        \#start (1.0, 0.8)\# 
+        % WIEDERHOLUNG 3 40 
+ 
+        &Vorname %Name 
+        &Strasse 
+ 
+        &PLZ %Ort 
+        \#free (1.693)\# 
+ 
+ 
+ 
+12.3 Modi 
+ 
+Gesetzt der Fall, Sie wollen eine Tabelle drucken, deren Einträge
+auf jeden Fall in voller Länge erscheinen sollen, auch wenn sie die
+Spaltenbreite überschreiten. Dies würde bedeuten, daß Tabellenein­
+träge nach rechts geschoben werden, wenn vorhergehende Einträge
+länger sind. Für diesen Fall können also nur Feldmuster variabler
+Position (mit '%') eingesetzt werden. Diese werden jedoch auch nach
+links geschoben, wenn vorher kürzere Inhalte auftreten. 
+ 
+#on("b")#Tabellenmodus#off("b")# Um dieses Linksschieben zu unterdrücken,
+können
+Sie mit folgender Anweisung im Musterteil in den #on("i")#Tabellenmodus#off("i")#
+umschalten: 
+ 
+ 
+        % MODUS 2 
+ 
+ 
+Der so eingestellte Modus gilt bis zum Ende des jeweiligen Ab­
+schnitts. Zu Beginn eines Abschnitts ist der Modus 1 (Normalmodus)
+eingestellt. 
+ 
+#on("b")#Beispiel#off("b")# Um diese Anweisung auszuprobieren, sollten Sie
+folgendes Druckmuster auf unsere Beispieldatei anwenden: 
+ 
+ 
+        % WIEDERHOLUNG 
+        % MODUS 2 
+        &Vorname %Name 
+ 
+ 
+In der Ausgabe können Sie sehen, daß der Nachname nicht nach
+links geschoben wird, so daß eine Tabelle entsteht. Ist der Vorname
+jedoch zu lang, wird die Tabelleneinteilung durchbrochen und der
+Nachname nach rechts geschoben, um den Vornamen nicht abschnei­
+den zu müssen: 
+ 
+ 
+        Herbert  Wegner 
+        Helga    Sandmann 
+        Albert   Katani 
+        Peter    Ulmen 
+        Karin    Regmann 
+        Hubert   Arken 
+        Anna-Maria Simmern 
+        Angelika Kaufmann-Drescher 
+        Harald   Fuhrmann 
+        Friedrich Seefeld 
+ 
+ 
+#on("b")#Zeilenfortsetzung#off("b")# Eine weitere Möglichkeit, überlange
+Feldinhalte
+einzusetzen, besteht darin, daß der Rest des Inhaltes, der nicht
+mehr in den reservierten Raum paßt, in der nächsten Zeile fortge­
+setzt wird. Dies wird im Modus 3 erreicht. Falls ein Feldinhalt ab­
+geschnitten werden müßte, wird in diesem Modus die gleiche Mu­
+sterzeile nochmal mit den restlichen Inhalten gedruckt. Dies wird
+fortgesetzt, bis alle Inhalte abgearbeitet sind. 
+    Damit die Fortsetzung sinnvoll ist, wird das letzte Wort ganz in
+die nächste Zeile übernommen, falls es zerschnitten würde (ähnlich
+wie im Editor). Der dadurch freiwerdende Raum in der vorigen Zeile
+wird mit Leerzeichen gefüllt. Ist rechtsbündiges Einsetzen verlangt,
+werden die einzelnen Teile jeweils rechtsbündig in ihrem reservier­
+ten Platz justiert. 
+    Dieser Modus ist besonders interessant, wenn Sie längere Kom­
+mentare in eine EUDAS-Datei eintragen, die Sie dann natürlich auch
+wieder drucken wollen. Den Text tragen Sie bereits in mehreren
+Zeilen in die EUDAS-Datei ein. Beachten Sie, daß der Umbruch des
+Textes im Druck nicht mit dem Umbruch des Textes am Bildschirm
+übereinstimmt. Wollen Sie dies verhindern, müssen Sie jeden Absatz
+des Textes in ein eigenes Feld schreiben. 
+    Wie zu Anfang des Kapitels bereits angedeutet, kann der Um­
+bruch bei Proportionalschrift nicht korrekt sein, da EUDAS die Zei­
+chenbreiten nicht kennt. Um die nachfolgende Bearbeitung mit
+'lineform' zu ermöglichen, werden bei fortgesetzten Feldern grund­
+sätzlich keine Absatzmarken an die Zeilen geschrieben. Lediglich die
+letzte Fortsetzungszeile erhält eine Absatzmarke. 
+    In den Fortsetzungszeilen, werden die Feldmuster, deren Inhalte
+bereits abgearbeitet sind, leer eingesetzt. Die Mustertexte zwischen
+den Feldmustern werden in den Fortsetzungszeilen durch Leerzei­
+chen ersetzt. 
+    Die Anzahl der Fortsetzungszeilen kann durch die Anweisung 
+ 
+ 
+        % MEHR n 
+ 
+ 
+auf eine bestimmte Zahl 'n' festgelegt werden. Wenn alle Inhalte
+abgearbeitet wurden, aber die Anzahl der Zeilen noch nicht erreicht
+ist, werden entsprechend viele Zeilen mit leeren Inhalten erzeugt. 
+    Die Zeilenwiederholung kann auch mit dem Tabellenmodus kom­
+biniert werden. Dies wird im Modus 4 erreicht. Felder variabler
+Position werden auch in diesem Modus nicht nach links geschoben.
+Außerdem werden aber in Fortsetzungszeilen die Mustertexte zwi­
+schen den Feldmustern wiederholt, um z.B. Tabellenbegrenzungen zu
+erzeugen. 
+ 
+#on("b")#Beispiele#off("b")# Zur Verdeutlichung hier noch einige Beispiele.
+Das folgende Druckmuster: 
+ 
+ 
+        % WIEDERHOLUNG 
+        % MODUS 3 
+        Kommentar: &Kommentar 
+        ---------- 
+ 
+ 
+könnte folgende Ausgabe bewirken: 
+ 
+ 
+        Kommentar: Dies ist ein längerer Kommentar aus 
+                   einer EUDAS-Datei, der zum Drucken 
+                   auf eine Breite von 48 Zeichen 
+                   umbrochen worden ist. Nur die letzte 
+                   Zeile hat eine Absatzmarke. 
+        ---------- 
+ 
+ 
+Soll die Anzahl der Zeilen immer gleich bleiben, könnte man folgen­
+des Druckmuster verwenden: 
+ 
+ 
+        % WIEDERHOLUNG 
+        % MODUS 3 
+        % MEHR 5 
+        Kommentar: &Kommentar 
+    ---------- 
+ 
+ 
+Mit einem kürzeren Text ergäbe sich folgendes Bild: 
+ 
+ 
+        Kommentar: Nur ein kurzer Text. 
+ 
+ 
+ 
+ 
+        ---------- 
+ 
+ 
+Für eine Tabelle würde man den Modus 4 benutzen: 
+ 
+ 
+    % VORSPANN 
+    -------------------------------------------------------- 
+    ! Abk.    ! Kommentar                                  ! 
+    !---------+--------------------------------------------! 
+    % WIEDERHOLUNG 
+    % MODUS 4 
+    ! &abk    ! &Kommentar&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ! 
+    ----------+--------------------------------------------- 
+ 
+ 
+Als Ausgabe könnte folgender Text erscheinen: 
+ 
+ 
+    -------------------------------------------------------- 
+    ! Abk.    ! Kommentar                                  ! 
+    !---------+--------------------------------------------! 
+    ! MA11    ! Dieser Kurs hat eine Menge an besonderen   ! 
+    !         ! Eigenschaften, die ihn für jüngere         ! 
+    !         ! Teilnehmer geeignet erscheinen lassen.     ! 
+    !---------+--------------------------------------------! 
+    ! TD04    ! Stellt keine besonderen Anforderungen.     ! 
+    !---------+--------------------------------------------! 
+    ! PM01    ! Seit dem 01.01. eingerichtet und noch      ! 
+    !         ! nicht voll besetzt.                        ! 
+    ----------+--------------------------------------------- 
+ 
+ 
+Beachten Sie hier, daß Tabelleneinträge hier nicht wie im Modus 2
+geschoben, sondern auf weitere Zeilen verteilt werden, wenn sie zu
+lang sind. Außerdem werden die Tabellenbegrenzungen mit wieder­
+holt. Das Feldmuster für Kommentar muß jedoch mit fester Länge
+angegeben werden, da sonst die rechte Tabellenbegrenzung bis zum
+Dateilimit geschoben würde. 
+ 
+#on("b")#Zusammenfassung#off("b")# Zum Abschluß dieses Abschnitts eine
+Zusammenfassung aller möglichen Modi: 
+ 
+    Modus   Effekt 
+ 
+      1     Normalmodus. 
+            '%'-Feldmuster werden auch nach links geschoben. 
+            Keine Zeilenwiederholung. 
+ 
+      2     Tabellenmodus. 
+            '%'-Feldmuster werden nicht nach links geschoben. 
+            Keine Zeilenwiederholung. 
+ 
+      3     Normalmodus mit Zeilenwiederholung. 
+            '%'-Feldmuster werden auch nach links geschoben. 
+            Zeilenwiederholung ohne Zwischentexte. 
+ 
+      4     Tabellenmodus mit Zeilenwiederholung. 
+            '%'-Feldmuster werden nicht nach links geschoben. 
+            Zeilenwiederholung mit Zwischentexten. 
+ 
+
diff --git a/doc/eudas/eudas.hdb.13 b/doc/eudas/eudas.hdb.13
new file mode 100644
index 0000000..435fbfc
--- /dev/null
+++ b/doc/eudas/eudas.hdb.13
@@ -0,0 +1,757 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (133)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+13 Programmierung von Druckmustern 
+ 
+ 
+ 
+13.1 Abkürzungen 
+ 
+In den vorigen Kapiteln haben Sie erfahren, daß man Feldmuster
+von ganz bestimmter Länge definieren kann, deren Inhalt in genau
+dieser Länge eingesetzt und bei Bedarf abgeschnitten wird. Bei der
+Angabe dieser Länge spielt jedoch die Länge des Feldnamens eine
+ganz entscheidende Rolle. Das kürzeste Feldmuster fester Länge, das
+Sie definieren können, ist nämlich zwei Zeichen länger als der Feld­
+name (ein Musterzeichen vorher und eins nachher). 
+    Hätte das Feld 'PLZ' den Namen 'Postleitzahl' bekommen, so
+müßte ein solches Feldmuster mindestens eine Länge von 14 Zeichen
+haben. Damit Sie mit diesem Feldnamen auch ein Feldmuster der
+Länge 4 bekommen können (Postleitzahlen haben in den seltensten
+Fällen mehr als 4 Stellen), haben Sie die Möglichkeit, den Namen
+'Postleitzahl' für die Verwendung im Druckmuster geeignet abzu­
+kürzen. 
+    Abkürzungen haben jedoch noch eine viel weitreichendere
+Bedeutung. Mit ihnen ist es möglich, nicht nur die Feldinhalte einer
+EUDAS-Datei einzusetzen, sondern auch jeden anderen Text, den Sie
+mit einem ELAN-Programm erzeugen können. 
+    Die einfachsten zusätzlichen Daten, die Sie verwenden können,
+sind z.B. Datum und Uhrzeit. Für weitergehende Zwecke können Sie
+die Inhalte der EUDAS-Datei auch für Berechnungen verwenden und
+damit so umfangreiche Probleme wie das Schreiben von Rechnungen
+oder statistische Auswertungen unter Verwendung eines Druck­
+musters lösen. 
+ 
+#on("b")#Abkürzungsteil#off("b")# Abkürzungen werden in einem speziellen
+Abkür­
+zungsteil am Ende eines Abschnittes angegeben. Der Abkürzungsteil
+wird durch die Anweisung 
+ 
+ 
+        % ABKUERZUNGEN 
+ 
+ 
+eingeleitet. Eine Abkürzungsdefinition hat eine ähnliche Form wie
+ein Refinement (Falls Sie nicht wissen, was das ist, vergessen Sie
+es). Zu Beginn steht der Name der Abkürzung in Form eines Feld­
+musters, beginnend in der ersten Spalte. Danach folgt, durch Leer­
+zeichen getrennt, ein Doppelpunkt in der gleichen Zeile. Daran
+schließt sich ein beliebiger ELAN-Ausdruck an, der sich in freiem
+Format über beliebig viele Zeilen erstrecken kann und mit einem
+Punkt abgeschlossen werden muß. Dieser ELAN-Ausdruck muß ein
+TEXT-Objekt liefern. 
+ 
+#on("b")#Feldinhalt#off("b")# Für die Abfrage von Inhalten aus einer
+EUDAS-Datei ist der Ausdruck 
+ 
+ 
+        f ("Feldname") 
+ 
+ 
+vordefiniert. Die Abkürzung des Feldes 'Postleitzahl' würde also als
+Ausschnitt folgendermaßen aussehen: 
+ 
+ 
+    % ABKUERZUNGEN 
+    &p :  f ("Postleitzahl") . 
+ 
+ 
+Mit dieser Definition kann man im Muster so verfahren, als ob das
+Feld 'Postleitzahl' auch 'p' hieße. Diese einfachste Form der Ab­
+kürzung können Sie natürlich variieren, indem Sie für 'p' und
+'Postleitzahl' Ihre eigenen Namen einsetzen. 
+ 
+#on("b")#Übersetzung#off("b")# Beachten Sie, daß das Druckmuster in ein
+ELAN-Pro­
+gramm umgeformt werden muß, da ELAN-Ausdrücke in ihm vorkom­
+men. Das automatisch erzeugte ELAN-Programm wird dann vom
+ELAN-Compiler übersetzt und ausgeführt. Fehler in den ELAN-Aus­
+drücken im Abkürzungsteil können erst vom ELAN-Compiler ent­
+deckt werden. Dieser kennt jedoch das Druckmuster nicht und mel­
+det die Fehler anhand des generierten Programms. Sie müssen in
+einem solchen Fall aufpassen, daß Sie die Fehlerquelle an der rich­
+tigen Stelle im Druckmuster lokalisieren (Hilfestellungen dazu sind
+im Kapitel über die Übersetzung von Druckmustern zu finden). 
+ 
+#on("b")#Beispiel#off("b")# Um die Verwendung von Abkürzungen zu
+demonstrieren, wollen wir folgendes Druckmuster betrachten: 
+ 
+ 
+        % VORSPANN 
+        Adressenliste als Beispiel für Abkürzungen 
+        Stand: &Datum 
+        ------------------------------------------ 
+        % ABKUERZUNGEN 
+        &Datum : date . 
+ 
+        % WIEDERHOLUNG 
+        &&l :  &Vorname %Name 
+               &Strasse 
+          &&p& &Ort 
+        ------------------------------------------ 
+        % ABKUERZUNGEN 
+        &l : lfd nr . 
+        &p : f ("PLZ") . 
+ 
+        % NACHSPANN 
+        &l Adressen gedruckt. 
+ 
+ 
+Dieses Beispiel enthält eine ganze Reihe interessanter Details. Als
+erstes sollten Sie registrieren, daß auch im Vorspann oder Nach­
+spann Feldmuster verwendet werden können. Soll in diesem Fall ein
+Feldinhalt aus der EUDAS-Datei eingesetzt werden, so werden beim
+Vorspann die Inhalte des ersten und beim Nachspann die Inhalte des
+letzten durch Suchmuster ausgewählten Satzes verwendet. Daher
+kann auch jeder Abschnitt einen Abkürzungsteil haben. Abkürzun­
+gen gelten jedoch für alle Abschnitte (s. '&l'); die Aufteilung in
+mehrere Abkürzungsteile fördert im wesentlichen die Übersichtlich­
+keit. 
+    Versuchen Sie, an diesem Beispiel die wichtigsten Unterschiede
+zwischen dem #on("i")#Musterteil#off("i")# und dem #on("i")#Abkürzungsteil#off("i")# eines Abschnittes
+zu verstehen. Das Format des Musterteiles soll in die Ausgabe
+übernommen werden; daher ist dort die Stellung jedes Wortes wich­
+tig. Im Abkürzungsteil definieren Sie Abkürzungen ohne bestimm­
+tes Format - mit der einzigen Ausnahme, daß eine Abkürzungs­
+definition mit einem '&' in der ersten Spalte anfangen und ein
+Leerzeichen vor dem Doppelpunkt haben muß. Wie Sie sehen, dürfen
+dort Leerzeilen zur besseren Lesbarkeit eingefügt werden. 
+Sie sollten bei unserem Beispiel folgende Ausgabe erhalten: 
+ 
+ 
+        Adressenliste als Beispiel für Abkürzungen 
+        Stand: 28.12.84 
+        ------------------------------------------ 
+          1 :  Herbert Wegner 
+               Krämergasse 12 
+          5000 Köln 
+        ------------------------------------------ 
+          2 :  Helga Sandmann 
+               Willicher Weg 109 
+          5300 Bonn 1 
+        ------------------------------------------ 
+          3 :  Albert Katani 
+               Lindenstr. 3 
+          5210 Troisdorf 
+        ------------------------------------------ 
+          4 :  Peter Ulmen 
+               Mozartstraße 17 
+             5 Köln 60 
+        ------------------------------------------ 
+          5 :  Karin Regmann 
+               Grengelweg 44 
+          5000 Köln 90 
+        ------------------------------------------ 
+          6 :  Hubert Arken 
+               Talweg 12 
+          5200 Siegburg 
+        ------------------------------------------ 
+          7 :  Anna-Maria Simmern 
+               Platanenweg 67 
+             5 Köln 3 
+        ------------------------------------------ 
+          8 :  Angelika Kaufmann-Drescher 
+               Hauptstr. 123 
+            53 Bonn 2 
+        ------------------------------------------ 
+          9 :  Harald Fuhrmann 
+               Glockengasse 44 
+          5000 Köln 1 
+        ------------------------------------------ 
+         10 :  Friedrich Seefeld 
+               Kabelgasse 
+          5000 Köln-Ehrenfeld 
+        ------------------------------------------ 
+        10 Adressen gedruckt. 
+ 
+ 
+Nun zu den Abkürzungen im einzelnen. Das Feld 'PLZ' muß abge­
+kürzt werden, damit es rechtsbündig vor den Ort gedruckt werden
+kann. Die Abkürzung 'p' benutzt die im vorigen Kapitel beschriebe­
+ne Form zur Abfrage des Feldinhaltes. 
+    'Datum' wird als Abkürzung für das aktuelle Datum definiert,
+ein häufig benötigter Fall. 'date' ist der ELAN-Ausdruck, der das
+Datum liefert. (Bemerkung für ELAN-Programmierer: der Name der
+Abkürzung gehorcht nicht der ELAN-Syntax für Bezeichner). 
+    Eine für Tabellen sinnvolle Funktion wird bei der Definition
+von 'l' verwendet. Der von EUDAS definierte Ausdruck 'lfd nr' lie­
+fert die laufende Nummer des gerade gedruckten Satzes als Text.
+Dabei ist zu beachten, daß die laufende Nummer nicht mit der Satz­
+nummer übereinstimmt, sondern nur während des Druckvorganges
+von 1 an bei jedem gedruckten Satz hochgezählt wird. Diese Funk­
+tion dient dazu, die Sätze in der Liste durchzunumerieren. 
+    Die laufende Nummer soll in der Liste rechtsbündig mit Doppel­
+punkt vor dem Namen stehen. Dazu wird das Feldmuster '&&l' be­
+nutzt, eine Form, die eigentlich keinen Sinn hat (die Kombination
+'variable Länge' und 'rechtsbündig' gibt es nicht). Um ein möglichst
+kurzes Feldmuster schreiben zu können, wird in diesem Fall jedoch
+feste Länge unterstellt (auch ohne folgendes '&'). Damit hat das
+kürzeste Feldmuster fester Länge drei Zeichen sowohl im linksbün­
+digen ('&l&') wie auch im rechtsbündigen Fall ('&&l'). 
+ 
+#on("b")#Auswertungen#off("b")# Die Verwendung der Abkürzung 'l' im Nachspann
+kann als erstes Beispiel für eine Auswertungsfunktion gelten. Da
+für den Nachspann die Daten des letzten Satzes verwendet werden,
+erscheint hier die laufende Nummer des letzten Satzes und somit die
+Anzahl der Sätze, die gedruckt wurden. Das kann dazu benutzt
+werden, die Sätze zu zählen, die eine bestimmte Suchbedingung
+erfüllen. Folgendes Druckmuster zählt die Anzahl der Frauen oder
+Männer in der Datei: 
+ 
+ 
+        % NACHSPANN 
+        &l Personen mit dem Geschlecht '%<m/w>' vorhanden. 
+        % ABKUERZUNGEN 
+        &l : lfd nr . 
+ 
+ 
+Wenn Sie vor dem Drucken jetzt die Suchbedingung 'm' für das Feld
+'m/w' einstellen, werden alle Männer ausgewählt. Das Drucken be­
+steht in diesem Fall nur aus dem Hochzählen der laufenden Nummer
+für jeden Mann. Im Nachspann kann das Ergebnis dann ausgegeben
+werden; zugleich soll der aktuelle Wert des Feldes 'm/w' gedruckt
+werden, damit das Druckmuster auch für das Zählen der Frauen
+verwendet werden kann. 
+    Die beiden möglichen Ausgaben würden dann so aussehen: 
+ 
+ 
+        6 Personen mit dem Geschlecht 'm' vorhanden. 
+ 
+        4 Personen mit dem Geschlecht 'w' vorhanden. 
+ 
+ 
+#on("b")#Zusammenfassung#off("b")# Wir können die Erkenntnisse dieses
+Abschnittes wie folgt zusammenfassen: 
+ 
+*  Feldmuster können auch im Vorspann und Nachspann verwendet
+   werden. Im Vorspann werden die Daten des ersten, im Nachspann
+   die Daten des letzten ausgewählten Satzes verwendet. 
+ 
+*  Der Musterteil eines Abschnittes definiert ein Format; der Ab­
+   kürzungsteil ist formatfrei. 
+ 
+*  'lfd nr' dient zum Durchnumerieren aller gedruckten Sätze. 
+ 
+*  Ein rechtsbündiges Feldmuster hat immer auch feste Länge. 
+ 
+#on("b")#Komplexe Abkürzungen#off("b")# Mit Hilfe von Abkürzungen können wir
+jetzt auch bessere Musterbriefe schreiben. Ein Problem, das bereits
+angesprochen wurde, besteht darin, daß in der Anrede je nach Ge­
+schlecht 'Herr' oder 'Frau' stehen soll. Um dieses Problem zu lösen,
+wird der Inhalt des Feldes 'm/w' benötigt. 
+    Da in einer Abkürzung jede ELAN-Anweisung erlaubt ist, die
+einen Text liefert, können natürlich auch #on("i")#IF-Anweisungen#off("i")# verwen­
+det werden. Mit diesen Informationen können wir jetzt die Abkür­
+zung 'Anrede' definieren: 
+ 
+ 
+        % ABKUERZUNGEN 
+        &Anrede : 
+          IF f ("m/w") = "w" THEN 
+            "Frau" 
+          ELSE 
+            "Herr" 
+          END IF . 
+ 
+ 
+Für Nicht-Programmierer: Die IF-Anweisung besteht aus einer Ab­
+frage und zwei Alternativen. Die Abfrage steht zwischen dem IF und
+dem THEN und besteht in der Regel aus einer Abfrage, ob zwei
+Dinge gleich oder ungleich (<>), größer oder kleiner sind. Außerdem
+können mehrere Abfragen mit AND (und) und OR (oder) kombiniert
+werden. Näheres dazu im Kapitel 14. 
+    Die Alternative hinter dem THEN wird ausgewählt, wenn die
+Abfrage zutrifft. An dieser Stelle sind wieder beliebige Ausdrücke
+erlaubt, die einen Text liefern, einschließlich erneuter IF-Anwei­
+sungen (Schachtelung). Die Alternative zwischen ELSE und END IF
+wird ausgewählt, wenn die Abfrage nicht zutrifft. 
+ 
+#on("b")#Textkonstanten#off("b")# Bisher wurden nur ELAN-Funktionen als
+Textlie­
+feranten betrachtet ('date', 'lfd nr', 'f'). In unserem Fall werden
+aber #on("i")#Textkonstanten#off("i")# in den Alternativen der IF-Anweisung benö­
+tigt. Textkonstanten werden in ELAN in Anführungsstriche einge­
+schlossen, die aber nicht zum Text gehören. Innerhalb einer Text­
+konstanten werden Leerzeichen wie alle anderen Zeichen angesehen
+(erscheinen also auch nachher in der Ausgabe). 
+    Bei solchen Abkürzungen, die längere Anweisungen umfassen,
+sollten Sie das freie Format ausnutzen und eine möglichst über­
+sichtliche Darstellung wählen. Wie Sie sehen, muß nur der Doppel­
+punkt noch in der ersten Zeile stehen, der Rest kann sich beliebig
+auf die folgenden Zeilen erstrecken. 
+ 
+#on("b")#Beispiel#off("b")# Ein typischer Einsatz einer IF-Anweisung für die
+Anrede sieht so aus: 
+ 
+ 
+        % WIEDERHOLUNG 
+ 
+        Sehr geehrte&Anrede %<Name>! 
+ 
+        ... 
+        % ABKUERZUNGEN 
+        &Anrede : 
+          IF f ("m/w") = "m" THEN 
+            "r Herr" 
+          ELSE 
+            " Frau" 
+          END IF . 
+ 
+ 
+Sie sollten jetzt diese Konstruktion in einen Musterbrief einfügen
+können. Probieren Sie ihn dann als Beispiel aus ! 
+ 
+#on("b")#Weitere Möglichkeiten#off("b")# Durch Verwendung von Abkürzungen ist
+es
+auch möglich, rechtsbündige Felder mit einer Länge von weniger als
+3 Zeichen zu simulieren. Dies geschieht mit Hilfe der Textoperatio­
+nen von ELAN. Ohne ELAN-Vorkenntnisse können Sie dieses Bei­
+spiel überlesen. In unserer Liste im obigen Beispiel sind die laufen­
+den Nummern höchstens zweistellig und sollten deshalb auch nur
+zwei Stellen belegen. Dies würde folgende Abkürzung ermöglichen: 
+ 
+ 
+        % ABKUERZUNGEN 
+        &l :  text (lfd nr als zahl, 2) . 
+        lfd nr als zahl : int (lfd nr) . 
+ 
+ 
+Die Prozedur 'text' wird dazu benutzt, eine Zahl rechtsbündig auf
+zwei Stellen zu formatieren (s. EUMEL-Benutzerhandbuch). Da die
+Abkürzung immer eine Länge von zwei Zeichen hat, kann sie auch in
+einem Feldmuster variabler Länge eingesetzt werden. Die Attribute
+'feste Länge' und 'rechtsbündig' werden in diesem Fall also nicht
+durch das Feldmuster, sondern durch die Abkürzung selbst erzeugt. 
+    Um die Prozedur 'text' anwenden zu können, muß die laufende
+Nummer als Zahl (sprich: INT-Objekt) vorliegen. Diese Umwandlung
+wird mit der Prozedur 'int' vorgenommen, die einen Text in eine
+Zahl umwandelt. Obwohl man 'int (lfd nr)' direkt in den Aufruf von
+'text' hätte schreiben können, wird hier als Demonstration dafür ein
+Refinement verwendet. 
+    Refinements können in einem Abkürzungsteil neben Abkürzun­
+gen stehen und von allen Abkürzungen benutzt werden. Sie werden
+ähnlich geschrieben wie Abkürzungen, nur ihr Name muß in Klein­
+buchstaben geschrieben werden, dafür muß er nicht in der ersten
+Spalte anfangen und kann Leerzeichen enthalten. Bei komplizierte­
+ren Ausdrücken sollten Refinements zur besseren Lesbarkeit einge­
+setzt werden. 
+    Sie können die IF-Anweisung auch mit beliebig vielen ELIF-
+Teilen versehen. Achten Sie jedoch darauf, daß die IF-Anweisung
+#on("i")#immer#off("i")# irgendeinen Wert liefern muß. Sie dürfen also den ELSE-Teil
+nicht weglassen. Statt einer IF-Anweisung können Sie natürlich
+auch eine SELECT-Anweisung verwenden. Es stehen Ihnen im Prin­
+zip alle werteliefernden Anweisungen von ELAN zur Verfügung. 
+    Die Programmiersprache ELAN bietet Ihnen noch weit mehr
+Möglichkeiten, als hier beschrieben werden können. So können Sie
+sich eigene Prozeduren definieren und diese dann in Abkürzungen
+verwenden. In Kapitel 14 und 15 finden Sie eine Einführung in die
+wichtigsten Konstrukte, die für EUDAS gebraucht werden. 
+ 
+ 
+13.2 Bedingte Musterteile 
+ 
+Wenn größere Teile des Druckmusters in Abhängigkeit von bestimm­
+ten Daten unterschiedlich ausfallen sollen, werden die dazu benö­
+tigten Abkürzungen sehr umfangreich. Für solche Fälle kann man
+IF-Anweisungen auch im Musterteil eines Abschnitts verwenden. In
+diesem Fall werden die Alternativen der IF-Anweisung durch
+Musterzeilen dargestellt. 
+    Im Musterteil müssen jedoch die Zeilen, die Teil der IF-An­
+weisung sind, von den Musterzeilen unterschieden werden. Deshalb
+werden die Anweisungszeilen durch ein '%'-Zeichen in der ersten
+#on("i")#und#off("i")# zweiten Spalte gekennzeichnet. Das zweite '%'-Zeichen dient
+zur Unterscheidung von Anweisungen an den Druckgenerator, die
+nicht an den ELAN-Compiler übergeben werden sollen. 
+    Mit einer IF-Anweisung im Musterteil kann man das Anredepro­
+blem auch folgendermaßen lösen: 
+ 
+ 
+        % WIEDERHOLUNG 
+        %% IF f ("m/w") = "w" THEN 
+        Sehr geehrte Frau &<Name>! 
+        %% ELSE 
+        Sehr geehrter Herr &<Name>! 
+        %% END IF; 
+ 
+ 
+Beachten Sie den Unterschied, daß die IF-Anweisung hier mit einem
+Semikolon abgeschlossen werden muß - in Abkürzungen mußte ja ein
+Punkt danach folgen. Außerdem darf hier der ELSE-Teil (die zweite
+Alternative) fehlen, während in einer Abkürzung in jeder Alternati­
+ve etwas stehen muß (zumindest der leere Text ""). 
+    Falls sich der IF-THEN-Teil über mehr als eine Zeile erstrek­
+ken soll, muß jede dieser Zeilen mit '%%' beginnen, da die Folgezei­
+len sonst als Musterzeilen gedruckt würden. Benutzen Sie in einem
+solchen Fall jedoch besser ein Refinement, das Sie im Abkürzungs­
+teil definieren müssen. 
+    Sie können im Musterteil auch andere ELAN-Anweisungen
+verwenden. Der Unterschied zu Abkürzungen liegt darin, daß die
+Musterzeilen nicht als Werte angesehen werden, die die Anweisung
+liefern muß, sondern als Anweisungen, die dort aufgeführten Mu­
+sterzeilen einzusetzen und zu drucken. Daher kann im Musterteil
+auch eine FOR-Schleife sinnvoll sein, wenn in Abhängigkeit eines
+Wertes eine bestimmte Anzahl von Zeilen gedruckt werden soll. 
+ 
+ 
+13.3 Übersetzung 
+ 
+Wenn Sie bis jetzt auch als ELAN-Programmierer immer noch nicht
+ganz durchblicken, wie Sie welche ELAN-Anweisungen verwenden
+können, dann ist das noch kein Anlaß zur Sorge. Es ist kaum mög­
+lich, die genauen Auswirkungen beliebiger Anweisungen zu be­
+schreiben, ohne den Übersetzungsprozeß zu schildern, der diese
+Anweisungen zu einem ELAN-Programm zusammenbindet. Daher soll
+diese Übersetzung jetzt genauer erklärt werden. 
+ 
+#on("b")#Übersetzungsmechanismus#off("b")# Alle Zeilen eines Abkürzungsteils
+wer­
+den direkt in das Programm übernommen, wobei der Name einer Ab­
+kürzung durch einen beliebig gewählten Refinementnamen ersetzt
+wird ('abk' + eine laufende Nummer). Alle Abkürzungen und Re­
+finements werden als globale Refinements definiert, also außerhalb
+von Prozeduren. Dadurch wird erreicht, daß sie an jeder Stelle
+verwendet werden können. 
+    Damit eine Abkürzung richtig als Refinement übersetzt wird,
+muß sie ein TEXT-Objekt als Wert liefern. Die anderen Refinements
+sind beliebig, da Sie nur in selbstdefinierten Anweisungen verwen­
+det werden. Die Refinements der Abkürzungen werden in einer Zu­
+weisung an eine TEXT-Variable verwendet, damit der Druckgenera­
+tor auf den entsprechenden Wert zugreifen kann. 
+    Jeder Abschnitt wird dagegen als eine Prozedur übersetzt. Jede
+Folge von Musterzeilen wird in eine Anweisung übersetzt, diese
+Musterzeilen einzusetzen und zu drucken. Jede '%%'-Anweisung
+wird einfach unverändert dazwischen geschrieben. Die Vorspann-
+Prozedur wird einmal zu Anfang aufgerufen, die Prozedur für den
+Wiederholungsteil einmal für jeden ausgewählten Satz und die Nach­
+spann-Prozedur einmal am Schluß. 
+    Bei Fehlern im ELAN-Teil zeigt der Compiler das erzeugte Pro­
+gramm zusammen mit seinen Fehlermeldungen im Paralleleditor. Sie
+müssen nun die Fehlermeldung lokalisieren und anhand der eben
+gegebenen Hinweise in das ursprüngliche Druckmuster zurücküber­
+setzen, damit Sie dort den Fehler korrigieren können. 
+ 
+#on("b")#Beispiel#off("b")# Nun müßten Sie genug Informationen haben, um
+beliebige
+ELAN-Anweisungen in das Druckmuster einfügen zu können. Als
+Beispiel wollen wir versuchen, alle Männer und Frauen in der
+Adressendatei zu zählen, ohne ein Suchmuster einstellen zu müssen
+und ohne den Druckvorgang zweimal ablaufen zu lassen (wie dies
+bei dem obigen Beispiel der Fall war). Ein erster Versuch könnte so
+aussehen: 
+ 
+ 
+        % VORSPANN 
+        %% INT VAR maenner, frauen; 
+        %% maenner := 0; 
+        %% frauen := 0; 
+        % WIEDERHOLUNG 
+        %% IF f ("m/w") = "m" THEN 
+        %%   maenner INCR 1 
+        %% ELSE 
+        %%   frauen INCR 1 
+        %% END IF 
+        % NACHSPANN 
+        &maenner Männer und %frauen Frauen vorhanden. 
+ 
+ 
+Aber Vorsicht! In diesem Beispiel sind mehrere Fehler eingebaut.
+Finden Sie sie! 
+ 
+#on("b")#Fehler im Beispiel#off("b")# Der erste Fehler befindet sich im
+Nachspann.
+Hier wird versucht, die Namen der beiden Variablen 'maenner' und
+'frauen' direkt in einem Feldmuster zu verwenden. Diese beiden
+Namen sind dem Druckgenerator nicht bekannt, sondern nur dem
+ELAN-Compiler. Um die Werte der beiden Variablen einsetzen zu
+können, müssen Sie also zwei geeignete Abkürzungen definieren. 
+    Der zweite Fehler ist schwieriger zu finden. Wie oben gesagt,
+wird jeder Abschnitt in eine Prozedur übersetzt. Die in einem Ab­
+schnitt definierten Variablen können also nur in diesem Abschnitt
+verwendet werden (sie sind lokal) und auch nicht im Abkürzungs­
+teil, da dieser wieder global vereinbart wird. Die beiden im Vor­
+spann definierten Variablen stehen also im Wiederholungsteil und im
+Nachspann nicht zur Verfügung. 
+ 
+#on("b")#Anweisungen im Initialisierungsteil#off("b")# Für diesen Fall gibt
+es die
+Möglichkeit, ELAN-Anweisungen vor allen Abschnitten im Initiali­
+sierungsteil zu definieren. Diese Anweisungen sind dann ebenfalls
+global. Das richtige Druckmuster finden Sie auf der nächsten Seite. 
+    Natürlich könnten Sie die Initialisierung der beiden Variablen
+auch noch aus dem Vorspann herausnehmen. Denken Sie daran, daß
+Sie aus INT-Variablen erst einen Text machen müssen, ehe Sie sie
+in eine Musterzeile einsetzen können. Beachten Sie Schreibweise der
+Variablen: in ELAN können die Umlaute nicht in Bezeichnern ver­
+wendet werden, daher muß die Variable mit 'ae' geschrieben wer­
+den. Im Mustertext und in Abkürzungs- und Feldnamen können die
+Umlaute jedoch frei verwendet werden. 
+ 
+ 
+        %% INT VAR maenner, frauen; 
+        % VORSPANN 
+        %% maenner := 0; 
+        %% frauen := 0; 
+        % WIEDERHOLUNG 
+        %% IF f ("m/w") = "m" THEN 
+        %%   maenner INCR 1 
+        %% ELSE 
+        %%   frauen INCR 1 
+        %% END IF 
+        % NACHSPANN 
+        &m Männer und %f Frauen vorhanden . 
+        % ABKUERZUNGEN 
+        &m : text (maenner) . 
+        &f : text (frauen) . 
+ 
+ 
+ 
+13.4 Gruppen 
+ 
+Der Druckgenerator bietet die Möglichkeit, Vorspann und Nachspann
+nicht nur am Anfang und am Ende, sondern auch an bestimmten
+Stellen zwischen Sätzen zu drucken. Diese Stellen sind dadurch
+bestimmt, daß ein bestimmtes Merkmal (z.B. ein Feldinhalt) seinen
+Wert ändert. Ein solches Merkmal wird im Druckmuster #on("i")#Gruppe#off("i")# ge­
+nannt. 
+    Ein Beispiel für die Verwendung von Gruppen ist eine Schüler­
+datei, die nach Klassen geordnet ist. Definiert man das Feld 'Klas­
+se' als Gruppe, so wird jeweils am Ende einer Klasse ein Nachspann
+und am Beginn einer Klasse ein Vorspann gedruckt. 
+    Dieses Verfahren ist eine Erweiterung der bisher beschriebenen
+Methode, indem eine Datei quasi in mehrere Dateien untergliedert
+wird, die jedoch in einem Arbeitsgang gedruckt werden können.
+Voraussetzung dafür ist jedoch, daß die Datei nach dem Gruppen­
+merkmal geordnet ist - der Druckgenerator sammelt nicht erst alle
+Schüler einer Klasse aus der Datei, sondern erwartet sie hinter­
+einander. 
+ 
+#on("b")#Gruppendefinition#off("b")# Eine Gruppe wird im Initialisierungsteil
+des
+Druckmusters (also vor allen Abschnitten) definiert. Notwendige
+Daten sind eine Nummer zur Identifizierung und das Merkmal. Die
+Nummer sollte am sinnvollsten von 1 an vergeben werden; die mög­
+lichen Werte sind nach oben hin beschränkt. Das Merkmal ist ein
+beliebiger ELAN-Ausdruck, der einen Text liefert. Sinnvollerweise
+wird er den Inhalt eines Feldes enthalten. 
+    Gruppendefinitionen müssen nach allen ELAN-Anweisungen im
+Initialisierungsteil folgen, und zwar, weil die Gruppendefinitionen
+alle in einer Prozedur zusammengefaßt werden, die bei jedem neuen
+Satz auf Gruppenwechsel testet. 
+    Unter der Annahme, daß die oben erwähnte Schülerdatei ein
+Feld 'Klasse' besitzt, würde die Gruppe wie folgt definiert: 
+ 
+ 
+        % GRUPPE  1  f ("Klasse") 
+ 
+ 
+Nach der Anweisung 'GRUPPE' folgt die Gruppennummer und dann
+ein ELAN-Ausdruck. Die ganze Definition muß in einer Zeile stehen;
+reicht der Platz nicht aus, müssen Sie in einem Abkürzungsteil ein
+Refinement definieren. 
+ 
+#on("b")#Klassenliste#off("b")# Das komplette Druckmuster für die
+Klassenliste könn­
+te folgendes Aussehen haben, wenn außer 'Klasse' auch noch die
+Felder 'Name' und 'Vorname' vorhanden sind: 
+ 
+ 
+        % GRUPPE  1  f ("Klasse") 
+        % VORSPANN 
+        Klassenliste für Klasse &Klasse 
+        ---------------------------- 
+        % WIEDERHOLUNG 
+        &Vorname %Name 
+        % NACHSPANN 
+        \#page\# 
+ 
+ 
+Wenn eine Gruppe definiert ist, werden im Nachspann immer die
+Feldinhalte des letzten Satzes vor dem Gruppenwechsel gedruckt, im
+Vorspann die Inhalte des ersten Satzes nach dem Wechsel. Daher
+kann hier im Vorspann die Klasse gedruckt werden, da sie sich erst
+ändert, wenn schon wieder der nächste Vorspann gedruckt wird. 
+ 
+#on("b")#Mehrere Gruppen#off("b")# Wie die Identifikation über eine
+Gruppennummer
+vermuten läßt, können Sie mehrere Gruppen definieren. Nachspann
+und Vorspann werden jeweils gedruckt, wenn sich das Merkmal ir­
+gendeiner Gruppe ändert. Ob eine bestimmte Gruppe gewechselt hat,
+kann mit der Abfrage 
+ 
+ 
+        BOOL PROC gruppenwechsel (INT CONST gruppennummer) 
+ 
+ 
+in einer IF-Anweisung ermittelt werden. Vor dem ersten und nach
+dem letzten Satz wechseln automatisch alle Gruppen. 
+    Die ganze Datei bildet eine Quasi-Gruppe mit der Nummer 0.
+Sie ist immer definiert und wechselt nur vor dem ersten und nach
+dem letzten Satz. Sie ist es, die bewirkt, daß Vorspann und Nach­
+spann in ihrer normalen Weise gedruckt werden. 
+ 
+#on("b")#Anwendungsbeispiel#off("b")# Um einige der Möglichkeiten zu
+illustrieren,
+die durch Gruppen geschaffen werden, wollen wir als Beispiel eine
+Anwendung betrachten, die neue Wege für die Benutzung von EUDAS
+aufzeigt. 
+    Aus einer Datei, in der für jede Bestellung der Kunde, der Ar­
+tikel, die bestellte Menge und der Einzelpreis des Artikels einge­
+tragen werden, sollen anschließend Rechnungen gedruckt werden.
+Die Datei soll folgende Felder haben: 
+ 
+ 
+        'Kundennummer' 
+        'Artikelnummer' 
+        'Einzelpreis' 
+        'Menge' 
+ 
+ 
+Als Voraussetzung müssen die Bestellungen in der Datei jeweils
+nach Kunden geordnet vorliegen. Die Kundennummer wird als Gruppe
+definiert, so daß die Bestellungen eines Kunden zu einer Rechnung
+zusammengefaßt werden können. Das Druckmuster rechnet dann die
+einzelnen Preise zusammen und gibt eine Endsumme aus. 
+    Damit in der Rechnung Name und Adresse des Kunden auftau­
+chen können, wird zu der Bestellungsdatei die Kundendatei gekop­
+pelt, die folgende Felder haben soll: 
+ 
+ 
+        'Kundennummer' 
+        'Name' 
+        'Vorname' 
+        'Strasse' 
+        'PLZ' 
+        'Ort' 
+ 
+ 
+Stellen Sie sich zum Ausprobieren des folgenden Druckmusters ge­
+gebenenfalls eigene Daten zusammen. Hier nun das Druckmuster: 
+ 
+ 
+    %% REAL VAR gesamtpreis, summe; 
+    % GRUPPE  1  f ("Kundennummer") 
+    % VORSPANN 
+    %% summe := 0.0; 
+                                      Fa. Kraus & Sohn 
+                                      Schotterstr. 10 
+ 
+                                      5000 Köln 1 
+    &Vorname %Name 
+    &Strasse 
+ 
+    &PLZ &Ort                         &Datum 
+ 
+                   R E C H N U N G 
+                   =============== 
+ 
+    Menge  Artikelnr.       Einzelpreis  Gesamtpreis 
+    ------------------------------------------------ 
+    % ABKUERZUNGEN 
+    &Datum : date . 
+ 
+    % WIEDERHOLUNG 
+    %% gesamtpreis := round 
+    %%   (wert ("Einzelpreis") * wert ("Menge"), 2); 
+    %% summe INCR gesamtpreis; 
+    &Menge &Artikelnummer     &&&&epr&&    &&&&gpr&& 
+    % ABKUERZUNGEN 
+    &epr :  f ("Einzelpreis") . 
+    &gpr :  zahltext (gesamtpreis, 2) . 
+ 
+    % NACHSPANN 
+    ------------------------------------------------ 
+                             Summe:        &&&&sum&& 
+                             + 14% MWSt.   &&&Mwst&& 
+                                           ========= 
+                             Endbetrag     &&&&end&& 
+    \#page\# 
+    % ABKUERZUNGEN 
+    &sum  : zahltext (summe, 2) . 
+    &Mwst : zahltext (mwst, 2) . 
+    &end  : zahltext (summe + mwst, 2) . 
+    mwst  : round (summe * 0.14, 2) . 
+ 
+ 
+Im Initialisierungsteil dieses Druckmusters wird die Kundennummer
+als Gruppe definiert. Dies hat zur Folge, daß für jeden neuen Kun­
+den eine neue Rechnung begonnen wird, nachdem vorher im Nach­
+spann die Rechnungssumme des vorherigen Kunden berechnet und
+ausgedruckt wurde. Vor dieser Gruppendefinition sind 'gesamtpreis'
+und 'summe' definiert, die später als globale Variablen zur Verfü­
+gung stehen sollen. Diese Zeile darf nicht nach der Gruppendefini­
+tion stehen. 
+    Im Vorspann wird der Kopf der Rechnung angegeben. Dieser
+enthält neben den Daten des Kunden (aus der gekoppelten Kun­
+dendatei) noch das Datum. Die Kundennummer wird nur zum Kop­
+peln und als Gruppenmerkmal benötigt, erscheint also nicht auf der
+Rechnung. 
+    Es fällt auf, daß im Firmennamen ein '&'-Zeichen auftaucht,
+das doch für die Markierung von Feldmustern reserviert ist. Die
+beiden Musterzeichen können jedoch im normalen Text auftauchen,
+wenn ihnen direkt ein Leerzeichen folgt. In diesem Fall werden Sie
+nicht als Beginn eines Feldmusters interpretiert, sondern unverän­
+dert gedruckt. Der gleiche Fall taucht noch mit '%' im Nachspann
+auf. 
+    Im Wiederholungsteil wird zunächst aus dem Einzelpreis und der
+Menge des jeweiligen Artikels der Gesamtpreis für diesen Artikel
+berechnet. Für die Abfrage der Feldinhalte wird die Funktion 'wert'
+verwendet, die wie 'f' funktioniert, jedoch gleich einen REAL-Wert
+liefert. 
+    Zu beachten ist, daß 'wert' wie beim Sortieren von Zahl alle
+Sonderzeichen ignoriert. Weiterhin müssen die Zahlen mit dem ein­
+gestellten Dezimalkomma geschrieben werden (also normalerweise
+mit Komma), damit ihr Wert richtig erkannt wird. Anderenfalls soll­
+ten Sie den Dezimalpunkt einstellen (s. 11.1). 
+    Damit kaufmännisch richtig gerechnet wird, wird der Gesamt­
+preis auf 2 Nachkommastellen gerundet und erst dann aufsummiert.
+Würde der Gesamtpreis nur zum Einsetzen gerundet, könnten bei der
+anschließenden Addition der nicht gerundeten Werte eine falsche
+Gesamtsumme entstehen. 
+    Erst nach diesen Berechnungen kann die Musterzeile folgen, in
+die die Werte dann eingesetzt werden. Um eine Ausgabe mit zwei
+Nachkommastellen zu erzeugen, wird die von EUDAS definierte
+Funktion 'zahltext' benutzt. Diese erzeugt aus einem REAL-Wert
+einen Text mit der angegebenen Anzahl von Kommastellen und setzt
+das korrekte Dezimalkomma ein. Das Ergebnis dieser Funktion wird
+dann rechtsbündig eingesetzt. 
+    Im Nachspann wird dann der summierte Wert mit aufgeschlage­
+ner Mehrwertsteuer gedruckt. Die Mehrwertsteuer muß ebenfalls auf
+zwei Nachkommastellen gerundet werden. 
+ 
+#on("b")#Erweiterung#off("b")# Zur Erweiterung könnten Sie die Bestelldatei
+noch mit
+einer Artikeldatei koppeln, die etwa folgende Struktur haben würde: 
+ 
+ 
+        'Artikelnummer' 
+        'Bezeichnung' 
+        'Einzelpreis' 
+ 
+ 
+In diesem Fall könnten Sie noch jeweils die Artikelbezeichnung in
+eine Rechnungszeile drucken. Außerdem würde der Preis zentral
+gespeichert. Eine entsprechende Änderung des Druckmusters sollte
+Ihnen keine Schwierigkeiten bereiten. 
+ 
+ 
+
diff --git a/doc/eudas/eudas.hdb.14 b/doc/eudas/eudas.hdb.14
new file mode 100644
index 0000000..1aa3c87
--- /dev/null
+++ b/doc/eudas/eudas.hdb.14
@@ -0,0 +1,724 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (151)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+14 Ausdrücke in ELAN 
+ 
+ 
+ 
+14.1 Was sind Ausdrücke ? 
+ 
+In diesem Kapitel wollen wir uns mit ELAN-Ausdrücken beschäfti­
+gen, wie sie für EUDAS gebraucht werden. Natürlich kann dies keine
+ernsthafte Einführung für ELAN-Programmierer sein - mit solchen
+Ambitionen halten Sie sich am besten an die entsprechende ELAN-
+Literatur. 
+    Dieser Text richtet sich eher an den Benutzer, der kaum Erfah­
+rung mit ELAN hat, aber die Möglichkeiten von EUDAS optimal nut­
+zen will. Viele fortgeschrittene Fähigkeiten von EUDAS laufen ja
+über ELAN-Programme. 
+ 
+#on("b")#Vorkommen#off("b")# Sie haben ELAN-Ausdrücke bereits an
+verschiedenen
+Stellen eingesetzt, wenn Sie sich mit den vorhergehenden Kapiteln
+befaßt haben. ELAN-Ausdrücke werden in nahezu allen Verarbei­
+tungsfunktionen benötigt. 
+    Im Druckmuster dienen sie dazu, den Inhalt eines Feldmusters
+festzulegen. Die Definition einer Abkürzung besteht immer aus dem
+Namen der Abkürzung und einem Ausdruck. Ebenso wird in einer
+Gruppendefinition ein Ausdruck angegeben. 
+    Beim Kopiermuster und beim Änderungsmuster besteht jeweils
+die rechte Seite einer Anweisung aus einem Ausdruck. Weiterhin
+werden Ausdrücke auch in anderen ELAN-Konstruktionen benötigt,
+wie zum Beispiel direkt am Anfang einer IF-Anweisung. 
+ 
+#on("b")#Bedeutung#off("b")# Ein Ausdruck steht allgemein für einen Wert. Im
+ein­
+fachsten Fall kann dies eine Konstante sein, der Wert des Aus­
+drucks ändert sich also nicht. Anderenfalls spricht man von einem
+zusammengesetzten Ausdruck. Dessen Wert ergibt sich dann durch
+die Ausführung der im Ausdruck angegebenen Operationen. Dieser
+Wert kann je nach dem aktuellen Zustand des Systems verschieden
+sein, da er jedes Mal neu berechnet wird, wenn er gebraucht wird. 
+    Ein Beispiel für einen zusammengesetzten Ausdruck ist 2+2
+Dieser Ausdruck steht für den Wert 4. 
+    Der Wert eines Ausdrucks ist das, was uns eigentlich interes­
+siert. Beim Druckvorgang wird dieser Wert dann gedruckt, beim
+Kopieren und Verändern in ein Feld eingetragen. 
+ 
+#on("b")#Zusammensetzung#off("b")# Ausdrücke lassen sich aus verschiedenen
+Ele­
+menten zusammensetzen. Grundlage bilden die Konstanten. Konstan­
+ten können durch #on("i")#Operatoren#off("i")# miteinander verknüpft werden. So ist
+in dem Ausdruck 2+3 das '+' ein Operator, der die Konstanten 2
+und 3 verknüpft. Das Ergebnis der Verknüpfung hängt natürlich vom
+jeweiligen Operator ab. 
+    Wie Sie schon in der Schule gelernt haben ("Punktrechnung vor
+Strichrechnung"), muß man die Reihenfolge der Operatoren festlegen,
+wenn mehrere Operatoren im Spiel sind. Ähnliche Regeln gibt es für
+alle Operatoren in ELAN. 
+    Wenn eine andere Reihenfolge der Operatoren erwünscht ist,
+können Sie diese durch Einsatz von Klammern verändern. Auch dies
+dürfte Ihnen aus der Schule noch in Erinnerung sein. Der Unter­
+schied in ELAN ist lediglich, daß es dort einige zusätzliche Opera­
+toren gibt, die Ihnen nicht aus der Mathematik vertraut sind. 
+    Ein weiteres Konstruktionselement von Ausdrücken sind #on("i")#Funk­
+tionen#off("i")#. Auch diese kennen Sie aus der Schule. Lediglich die
+Schreibweise muß für den "dummen" Computer etwas ausführlicher
+gehalten werden (Beispiel: sin (3.14 * x)). 
+    Die Argumente der Funktion hinter dem Funktionsnamen müssen
+auf jeden Fall in Klammern stehen. In der Terminologie der Pro­
+grammiersprachen spricht man von #on("i")#Parametern#off("i")#. Parameter können
+wieder komplexe Ausdrücke sein. Bei Funktionen mit mehreren
+Parametern werden diese durch Komma getrennt: 
+ 
+ 
+        min (2.5 * x, x + 1.25) 
+ 
+ 
+ 
+14.2 Datentypen 
+ 
+Bevor wir beginnen, konkrete Ausdrücke zu behandeln, müssen wir
+erst das Konzept der #on("i")#Datentypen#off("i")# einführen. Grundidee dabei ist,
+daß es verschiedene Klassen von Werten gibt, die nicht einfach
+untereinander gemischt werden können. 
+    So gibt es in ELAN einen grundlegenden Unterschied zwischen
+#on("i")#Zahlen#off("i")# und #on("i")#Texten#off("i")#. Texte bestehen aus einer beliebigen Aneinan­
+derreihung von Zeichen, die im Normalfall nur für den betrachten­
+den Menschen eine Bedeutung haben. Mit Zahlen kann man dagegen
+Berechnungen anstellen. 
+    Der tiefere Grund für die Trennung in verschiedene Typen ist
+also, daß für jeden Typ gewisse Operationen definiert snd, die nur
+für diesen Typ sinnvoll sind. So ist zum Beispiel die Addition der
+beiden Texte "abc" und "-/-" völlig sinnlos. 
+    Aber nicht nur die Operationen sind verschieden, sondern auch
+die interne Darstellung im Rechner. So werden der Text "1234" und
+die Zahl 1234 völlig anders gespeichert, obwohl man ihnen die glei­
+che Bedeutung beimessen könnte. 
+ 
+#on("b")#Grundtypen#off("b")# In ELAN gibt es vier verschiedene Grundtypen,
+die für
+uns wichtig sind. Sie können sich in ELAN auch eigene Typen
+schaffen, dies geht jedoch weit über unsere Bedürfnisse hinaus. 
+    Der in EUDAS am meisten verwendete Typ heißt #on("i")#TEXT#off("i")#. TEXT-
+Objekte bestehen aus einer Folge von 0 bis 32000 Zeichen. Die Zei­
+chen entstammen einem Satz von 256 verschiedenen Symbolen, die
+jeweils eine andere Darstellung haben. Einige der Zeichen lassen
+sich überhaupt nicht darstellen, sondern führen bestimmte Funktio­
+nen aus (zum Beispiel Bildschirm löschen). 
+    Sämtliche Feldinhalte einer EUDAS-Datei sind TEXTe, ebenso
+die Zeilen von Textdateien. Auch Datei- und Feldnamen sind
+TEXTe. Von daher besteht eigentlich kein Grund, warum Sie sich
+außer zur Programmierung noch mit anderen Datentypen beschäfti­
+gen sollten. 
+    Neben den Texten gibt es noch die Zahlen. Diese sind in ihrer
+internen Darstellung so beschaffen, daß ein effizientes Rechnen mit
+ihnen möglich ist. Andererseits können sie nicht mehr beliebige
+Informationen darstellen, sondern haben eine sehr eingeschränkte
+Bedeutung. 
+    Um unterschiedichen Bedürfnissen gerecht zu werden, gibt es in
+ELAN zwei verschiedene Zahltypen. Der Typ #on("i")#INT#off("i")# umfaßt nur ganze
+Zahlen ohne Kommastellen. Damit die Zahl möglichst wenig Spei­
+cherplatz belegt, ist der Wertebereich bei den meisten Rechnern auf
+-32768..32767 beschränkt (die krummen Zahlen ergeben sich wegen
+der Binärarithmetik des Rechners). Dieser Typ eignet sich am besten
+zum Abzählen und zum Auswählen aus einer festen Anzahl von
+Objekten (zum Beispiel Feld 1 bis Feld 255). 
+    Zum eigentlichen Rechnen gibt es den Typ #on("i")#REAL#off("i")#. Dieser umfaßt
+auch Kommazahlen. Genauigkeit, Wertebereich und Darstellung sind
+nahezu identisch mit den Möglichkeiten eines Taschenrechners. der
+Typ REAL wird immer dann verwendet, wenn mit realen Größen
+(Geldbeträge, physikalische Werte) gerechnet werden muß. 
+    Zuletzt gibt es noch den Typ #on("i")#BOOL#off("i")#. Er hat nur zwei mögliche
+Werte, nämlich TRUE (wahr) und FALSE (falsch). Er wird dazu benö­
+tigt, Ausdrücke zu schreiben, die den Zweig einer IF-Anweisung
+bestimmen. 
+ 
+#on("b")#Denotation#off("b")# ELAN verfügt über einen strengen Typenschutz;
+das
+heißt, Objekte verschiedenen Typs dürfen nicht gemischt werden.
+Daher muß schon bei der Schreibweise der Konstanten festgelegt
+sein, welchen Typ die Konstante hat. 
+    Bei Texten geschieht dies durch den Einschluß in Anführungs­
+striche. Die Anführungsstriche sorgen gleichzeitig auch für eine
+Abgrenzung der Zeichen des Textes und des umgebenden Programms.
+Sie kennen diese Schreibweise bereits von vielen Stellen in EUDAS. 
+    Ebenfalls keine Probleme bereitet der Typ BOOL, da die
+Schreibweise der beiden möglichen Werte TRUE und FALSE eindeutig
+ist. 
+    Problematisch wird es bei den Zahlen. Da die ganzen Zahlen in
+den rationalen Zahlen enthalten sind, muß für die ganzen Zahlen
+durch die Schreibweise festgelegt werden, zu welchem der beiden
+Typen sie gehören. Man hat festgelegt, daß REAL-Zahlen immer mit
+Komma geschrieben werden müssen, während Zahlen ohne Komma den
+Typ INT haben (das Komma wird in ELAN bei den REAL-Zahlen in
+internationaler Schreibweise als Punkt notiert). 
+    So ist 4 eine INT-Zahl, während 4.0 den Typ REAL besitzt.
+Denken Sie in Zukunft immer daran, welcher Zahltyp jeweils ver­
+langt wird und richten Sie die Schreibweise danach. 
+ 
+#on("b")#Unterschied zu Feldtypen#off("b")# Verwechseln Sie die hier
+vorgestellten
+Datentypen nicht mit den Feldtypen einer EUDAS-Datei. Die Feld­
+typen beziehen sich immer auf den gleichen Datentyp, nämlich
+TEXT. Die Feldtypen bestimmen lediglich die spezielle Behandlung
+des Feldes beim Suchen und Sortieren, während Datentypen tat­
+sächlich Unterschiede in der Speicherung und den anwendbaren
+Operationen bedeuten. 
+    Daher können Sie Feldtypen auch nach Bedarf ändern, während
+der Datentyp eines Objekts ein für alle Mal feststeht. Merken Sie
+sich, daß Feldinhalte in EUDAS immer den Typ TEXT haben. 
+ 
+#on("b")#Umwandlungen#off("b")# Obwohl verschiedene Datentypen nicht
+miteinander
+gemischt werden dürfen, können sie mit speziellen Funktionen in­
+einander umgewandelt werden. So ist zum Beispiel die Addition von
+1 und 1.5 verboten, aber der folgende Ausdruck 
+ 
+ 
+        real (1) + 1.5 
+ 
+ 
+liefert den Wert 2.5 mit dem Typ REAL. Umgekehrt geht die Um­
+wandlung mit der Funktion 'int', dabei werden jedoch die Nachkom­
+mastellen abgeschnitten. Weitere Hinweise dazu erhalten Sie im
+Abschnitt 14.4. 
+    Wichtiger jedoch ist die Umwandlung von Zahlen in TEXT-Ob­
+jekte. Was Sie auf Ihrem Bildschirm oder Ausdruck sehen, sind ja
+immer nur Zeichenfolgen und damit Texte. Zahlen (INT oder REAL)
+in ihrer internen Darstellung können Sie prinzipiell nicht sehen. Sie
+müssen zur Darstellung immer in Texte umgewandelt werden. 
+    Auch beim Rechnen mit Werten aus EUDAS-Dateien müssen
+mehrere Umwandlungen stattfinden. Der Feldinhalt, der ja ein TEXT
+ist, muß zunächst in eine Zahl umgewandelt werden. Dann wird mit
+dieser Zahl gerechnet. Wenn das Ergebnis wieder in ein Feld einge­
+tragen oder gedruckt werden soll, muß eine Rückumwandlung in
+einen Text vorgenommen werden. 
+    Die zum Umwandeln benötigten Funktionen werden ebenfalls im
+Abschnitt 14.4 besprochen. 
+ 
+#on("b")#Funktionsbeschreibung#off("b")# In den zwei folgenden Abschnitten
+sollen
+die wichtigsten Funktionen und Operatoren anhand von Beispielen
+beschrieben werden. Da jede Funktion nur auf bestimmte Datentypen
+angewendet werden kann, gibt es eine Notation, die genau die Form
+eines Funktionsaufrufs festlegt. 
+ 
+ 
+        INT PROC min (INT CONST a, b) 
+ 
+ 
+Die obige Schreibweise hat folgende Bedeutung: Spezifiziert wird die
+Funktion 'min', die als Ergebnis einen INT-Wert liefert (das INT
+ganz links). Die Bezeichnung PROC gibt an, daß es sich um eine
+Funktion handelt. In Klammern ist dann angegeben, welche Parame­
+ter verwendet werden müssen. Die Funktion hat zwei Parameter,
+beide vom Typ INT. Die Bezeichnung CONST gibt an, daß auch Kon­
+stanten verwendet werden dürfen (Normalfall). 
+    Zu beachten ist, daß bei jedem Aufruf beide Parameter vorhan­
+den und vom Typ INT sein müssen. Anderenfalls gibt es eine Feh­
+lermeldung. 
+    Die gleiche Schreibweise wird auch zur Spezifikation von Ope­
+ratoren verwendet: 
+ 
+ 
+        INT OP + (INT CONST a, b) 
+ 
+ 
+Jedoch dürfen Operatoren nicht mit Parametern in Klammern ge­
+schrieben werden, sondern der Operator wird zwischen die Parameter
+geschrieben. 
+    Eine Besonderheit von ELAN ist es, daß es verschiedene Opera­
+toren und Funktionen mit gleichem Namen geben kann. Die Funktio­
+nen werden nur unterschieden nach dem Typ ihrer Parameter. So
+gibt es nicht nur den oben genannten Operator '+', sondern auch
+den folgenden: 
+ 
+ 
+        REAL OP + (REAL CONST a, b) 
+ 
+ 
+Obwohl im Aussehen gleich, handelt es sich doch um verschiedene
+Operatoren mit möglicherweise völlig verschiedener Wirkung. Dies
+sieht man an diesem Beispiel: 
+ 
+ 
+        TEXT OP + (TEXT CONST a, b) 
+ 
+ 
+Dieser Operator führt nun keine Addition aus, sondern eine #on("i")#Verket­
+tung#off("i")# zweier Texte. Je nach Typ der Parameter wird der entspre­
+chende Operator ausgesucht. 
+ 
+ 
+14.3 TEXT-Funktionen 
+ 
+In diesem Abschnitt wollen wir die wichtigsten Funktionen und
+Operatoren zur Behandlung von Texten beschreiben. Wie Sie noch
+sehen werden, spielt dabei aber auch der Typ INT eine gewisse
+Rolle. 
+ 
+#on("b")#EUDAS-Abfragen#off("b")# Die wichtigste Funktion zur Abfrage von
+Inhal­
+ten der aktuellen Datei sollten Sie bereits kennen: 
+ 
+ 
+        TEXT PROC f (TEXT CONST feldname) 
+ 
+ 
+Neu ist eigentlich nur die Schreibweise der Spezifikation. Sie sollten
+aber in der Lage sein, daraus einen konkreten Ausdruck zu kon­
+struieren. Bisher haben wir immer die Schreibweise 
+ 
+ 
+        f ("Feldname") 
+ 
+ 
+verwendet. Dies ist jedoch nur ein Beispiel. Die korrekte Angabe
+finden Sie oben. 
+    Die Funktion 'f' darf natürlich nicht angewendet werden, wenn
+keine Datei geöffnet ist. In die Verlegenheit kommen Sie aber nur
+beim Ausprobieren, denn alle gefährlichen EUDAS-Funktionen sind
+sonst gesperrt. 
+    Falls das angegebene Feld nicht existiert, wird mit einer Feh­
+lermeldung abgebrochen. Beachten Sie, daß dies immer erst bei der
+Ausführung festgestellt werden kann. Bei der Eingabe, zum Beispiel
+eines Druckmusters, kann dies noch nicht überprüft werden. 
+    Eine weitere Abfrage, die EUDAS während des Druckens ermög­
+licht, ist die Funktion 
+ 
+ 
+        TEXT PROC lfd nr 
+ 
+ 
+Diese hat keine Parameter und liefert die laufende Nummer des
+gedruckten Satzes. 
+    Diese beiden Funktionen können als Ausgangsbasis dienen zur
+Manipulation mit weiteren Funktionen. 
+ 
+#on("b")#Verkettung#off("b")# Zur Verkettung von Teiltexten gibt es den oben
+schon
+beschriebenen Operator '+'. Wenn Sie mehr als zwei Texte verketten
+wollen, können Sie den Operator beliebig hintereinander verwenden: 
+ 
+ 
+        f ("PLZ") + " " + f ("Ort") 
+ 
+ 
+Wie in diesem Beispiel können Sie sowohl Konstanten als auch Tex­
+te, die von anderen Funktionen geliefert werden, verketten. Beach­
+ten Sie, daß die Texte immer ohne Zwischenraum aneinandergehängt
+werden; daher wird im obigen Beispiel ein Leerzeichen extra ange­
+geben. 
+    Wenn Sie eine bestimmte Anzahl von gleichen Zeichen haben
+möchten (zum Beispiel für horizontale Linien oder große Zwischen­
+räume), können Sie dafür folgenden Operator verwenden: 
+ 
+ 
+        TEXT OP * (INT CONST anzahl, TEXT CONST einzeltext) 
+ 
+ 
+Hier sehen Sie als Beispiel einen Operator, der mit verschiedenen
+Datentypen arbeitet. Sie müssen die Parameter jedoch immer in der
+angegebenen Reihenfolge benutzen. Das folgende Beispiel ist kor­
+rekt: 
+ 
+ 
+        20 * "-" 
+ 
+ 
+während dies nicht erlaubt ist: 
+ 
+ 
+        "-" * 20 
+ 
+ 
+Wieder können Sie diesen Operator mit anderen Funktionen verknü­
+pfen: 
+ 
+ 
+        "!" + 10 * " " + "!" + 5 * "-" + "!" 
+ 
+ 
+Da der Multiplikationsoperator Vorrang vor der Addition hat, kom­
+men Sie hier sogar ohne Klammern aus (überlegen Sie sich, wo ein
+Fehler auftreten würde, wenn dies nicht so wäre). Als Ergebnis
+dieses komplexen Ausdrucks ergäbe sich der folgende Text: 
+ 
+ 
+        "!          !-----!" 
+ 
+ 
+#on("b")#Teiltexte#off("b")# Um auch Teile von Texten bearbeiten zu können,
+werden
+die Zeichen eines Textes von 1 an (mit INT-Zahlen) durchnumeriert.
+Anhand dieser Positionen können Sie Teiltexte extrahieren. 
+    Damit Sie die Position des letztes Zeichens (und damit die An­
+zahl der Zeichen) erfragen können, gibt es die Funktion 
+ 
+ 
+        INT PROC length (TEXT CONST text) 
+ 
+ 
+Wieviel Zeichen in einem Feld stehen, können Sie also mit 
+ 
+ 
+        length (f ("Feldname")) 
+ 
+ 
+erfahren. 
+    Einen Teiltext bekommen Sie mit der Funktion 'subtext'. Diese
+gibt es in zwei Ausführungen. 
+ 
+ 
+        TEXT PROC subtext (TEXT CONST text, INT CONST anfang) 
+ 
+ 
+liefert den Teiltext von einer bestimmten Position an (einschließ­
+lich) bis zum Textende. Mit 
+ 
+ 
+       TEXT PROC subtext (TEXT CONST t, INT CONST anf, ende) 
+ 
+ 
+können Sie auch die Position des letzten Zeichens (einschließlich)
+angeben. Daher würden die beiden folgenden Aufrufe 
+ 
+ 
+        subtext (f ("Feldname"), 1) 
+        subtext (f ("Feldname"), 1, length (f ("Feldname"))) 
+ 
+ 
+den Feldinhalt unverändert liefern. Ein weiteres Beispiel: 
+ 
+ 
+        subtext ("Ein Text als Beispiel", 5, 8) 
+ 
+ 
+liefert als Ergebnis "Text". 
+    Es gibt noch den Operator 'SUB', der jeweils nur ein Zeichen
+aus dem Text liefert: 
+ 
+ 
+        TEXT OP SUB (TEXT CONST text, INT CONST stelle) 
+ 
+ 
+Der Aufruf ist gleichwertig zu einem Aufruf von 'subtext', in dem
+beide Stellen gleich sind. 
+    Bei beiden Funktionen wird nicht vorhandener Text einfach
+ignoriert. So liefert 
+ 
+ 
+        subtext ("Hallo", 4, 8) 
+ 
+ 
+das Ergebnis "lo" und 
+ 
+ 
+        "Hallo" SUB 10 
+ 
+ 
+den leeren Text "". 
+ 
+#on("b")#Verschachtelte Ausdrücke#off("b")# Wie Sie bereits gesehen haben,
+kann
+man Ausdrücke ineinander verschachteln. Dies ist in unserem Fall
+sehr nützlich, wenn Teiltexte bestimmt werden sollen, deren Posi­
+tion nicht konstant ist. Ein Beispiel, in dem 'length' bei der Fest­
+legung der Endposition verwendet wird, haben Sie weiter oben
+bereits gesehen. 
+    Als weitere Möglichkeit können Sie mit Positionen, die ja INT-
+Zahlen sind, ganz normal rechnen. Folgender Ausdruck liefert zum
+Beispiel die letzten drei Zeichen eines Feldes: 
+ 
+ 
+        subtext (f ("Feldname"), length (f ("Feldname")) - 2) 
+ 
+ 
+Wichtig ist, daß ein Ausdruck, der wieder als Parameter für einen
+anderen Ausdruck verwendet werden soll, den richtigen Typ hat,
+der von dem anderen Ausdruck verlangt wird. 
+    In dem obigen Beispiel muß als Position ein INT verwendet
+werden. Diese Position wird vom Operator '-' berechnet. Es gibt
+aber nur einen Subtraktionsoperator, der einen INT liefert, nämlich
+den, der wiederum zwei INTs subtrahiert. Glücklicherweise sind
+sowohl 'length' als auch die 2 vom Typ INT, anderenfalls wäre der
+Ausdruck fehlerhaft. 'length' wiederum benötigt einen TEXT als
+Parameter, der von der Funktion 'f' stammt, die als Parameter eben­
+falls einen TEXT verlangt. 
+    Wie Sie sehen, kann es durchaus verwickelt zugehen, wenn ein
+Ausdruck aus den verschiedensten Teilausdrücken unterschiedlichen
+Typs zusammengesetzt ist. Die gleiche Überprüfung wie eben ge­
+schildert sollten Sie bei jedem Ausdruck vornehmen, damit keine
+Fehlermeldung erscheint. 
+ 
+#on("b")#Variable Positionen#off("b")# Zur Berechnung von Positionen gibt es
+noch eine weitere nützliche Prozedur, nämlich 
+ 
+ 
+        INT PROC pos (TEXT CONST text, teiltext) 
+ 
+ 
+Sie liefert die Position, an der der angegebene Teiltext zum ersten
+Mal in dem Text vorkommt, oder 0, wenn der Teiltext nicht darin
+vorkommt. So ist 
+ 
+ 
+        pos ("Hallo", "l") = 3 
+ 
+ 
+und 
+ 
+ 
+        pos ("Hallo", "lo") = 4 
+ 
+ 
+und 
+ 
+ 
+        pos ("Hallo", "xx") = 0 
+ 
+ 
+Diese Funktion kann zum Beispiel dazu verwendet werden, ein Feld
+in mehrere Teile aufzuspalten. Sind zum Beispiel Name und Vorname
+in einem Feld durch Leerzeichen getrennt hintereinandergeschrie­
+ben, liefert 
+ 
+ 
+        subtext (f ("Name"), 1, pos (f ("Name"), " ") - 1) 
+ 
+ 
+den Vornamen und entsprechend 
+ 
+ 
+        subtext (f ("Name"), pos (f ("Name"), " ") + 1) 
+ 
+ 
+den Nachnamen. Soll die Position erst ab einer gewissen Stelle ge­
+sucht werden, gibt es noch die folgende Variation der Funktion: 
+ 
+ 
+        INT PROC pos (TEXT CONST text, teiltext, INT CONST ab) 
+ 
+ 
+Bei dieser Funktion wird erst ab der angegebenen Stelle einschließ­
+lich gesucht. 
+ 
+ 
+14.4 Rechenfunktionen 
+ 
+#on("b")#Umwandlungen#off("b")# Bevor mit dem Inhalt eines Feldes gerechnet
+wer­
+den kann (auch wenn das Feld den Feldtyp ZAHL hat), muß der Wert
+des Feldinhaltes als REAL-Zahl berechnet werden. Dazu gibt es die
+Funktion 
+ 
+ 
+        REAL PROC wert (TEXT CONST feldname) 
+ 
+ 
+Die Funktion 'wert' ignoriert alle Sonderzeichen in dem Feld außer
+dem Minuszeichen (als Vorzeichen) und dem eingestellten Dezimal­
+komma. Wenn das Feld 'Summe' beispielsweise "-***20,09 DM" ent­
+hält, ergibt sich 
+ 
+ 
+        wert ("Summe") = 20.09 
+ 
+ 
+Zum kaufmännischen Rechnen ist es manchmal erforderlich, den Wert
+auf eine bestimmte Anzahl von Nachkommastellen zu runden. Diese
+Anzahl kann man bei einer Variante von 'wert' als Parameter ange­
+ben: 
+ 
+ 
+        REAL PROC wert (TEXT CONST feldname, 
+                        INT CONST kommastellen) 
+ 
+ 
+Mit den so erhaltenen Werten können Sie dann die weiter unten
+beschriebenen Berechnungen durchführen. Bevor Sie das Ergebnis
+jedoch drucken oder in ein Feld eintragen können, müssen Sie den
+REAL-Wert wieder in einen TEXT verwandeln. Dazu dient die Funk­
+tion 
+ 
+ 
+        TEXT PROC zahltext (REAL CONST wert, 
+                            INT CONST kommastellen) 
+ 
+ 
+Der übergebene Wert wird mit der gewünschten Anzahl von Komma­
+stellen als Text formatiert. Dazu wird der Wert gerundet. Außerdem
+wird statt eines Punktes das eingestellte Dezimalkomma eingesetzt.
+Die Länge des Textes richtet sich nach der Anzahl von benötigten
+Stellen, es werden also keine führenden Nullen oder Leerzeichen
+eingesetzt (dafür kann man den Text beim Drucken ja rechtsbündig
+einsetzen). 
+    Wird 0 als Kommastellen angegeben, wird auch kein Dezimal­
+komma erzeugt (Darstellung wie ein INT). Als Abkürzung können Sie
+auch 
+ 
+ 
+        TEXT PROC zahltext (TEXT CONST feldname, 
+                            INT CONST kommastellen) 
+ 
+ 
+als Ersatz für 
+ 
+ 
+        zahltext (wert ("Feldname"), kommastellen) 
+ 
+ 
+verwenden. So kann ein Feld einheitlich zum Drucken formatiert
+werden. 
+ 
+#on("b")#Arithmetik#off("b")# Sowohl mit INT- als auch mit REAL-Zahlen
+(jedoch
+nicht gemischt) können Sie die üblichen Rechenoperatoren '+', '-'
+und '*' verwenden. Auch Minimum ('min') und Maximum ('max') sind
+für zwei Parameter dieser Typen definiert. 
+    Lediglich die Division wird bei beiden Typen unterschiedlich
+gehandhabt. Für REAL-Zahlen gibt es den Operator '/' für die
+übliche Division. Da die ganzzahlige Division eine andere Bedeutung
+hat, wird dafür der Operator 'DIV' verwendet. Den Rest der ganz­
+zahligen Division liefert 'MOD'. 
+    'abs' liefert den Wert eines REAL oder INT ohne das Vorzeichen.
+Die Umwandlungsfunktionen 'int' und 'real' hatten wir ja bereits
+weiter oben erwähnt. 
+    Für REAL-Zahlen gibt es noch weitere mathematische Funktio­
+nen (Exponentialfunktion, Trigonometrie), die Sie am besten im
+EUMEL-Benutzerhandbuch nachschlagen, wenn Bedarf dafür besteht. 
+ 
+ 
+14.5 Abfragen 
+ 
+#on("b")#IF-Abfragen#off("b")# Wie Sie schon im vorigen Kapitel gesehen
+haben,
+kann man in Druckmustern auch IF-Abfragen als Ausdrücke ver­
+wenden. Die IF-Abfragen können zwar auch ineinander verschach­
+telt werden, sie dürfen jedoch nicht mehr innerhalb eines normalen
+Ausdrucks angewendet werden. 
+    Eine IF-Abfrage enthält 3 Teilausdrücke in folgender Form: 
+ 
+ 
+        IF 'BOOL-Ausdruck' THEN 
+          'Ausdruck1' 
+        ELSE 
+          'Ausdruck2' 
+        END IF 
+ 
+ 
+Der erste Ausdruck muß einen Wert vom Typ BOOL liefern, der ent­
+scheidet, welcher der beiden Teilausdrücke ausgewertet wird. Wir
+werden gleich noch sehen, was für Möglichkeiten es da gibt. 
+    Die beiden Teilausdrücke dürfen auch wieder IF-Abfragen sein,
+sind sie es jedoch nicht, dürfen in ihnen dann keine IF-Abfragen
+mehr vorkommen. Die IF-Abfragen liegen also immer auf der äußer­
+sten Ebene. 
+    Die beiden Teilausdrücke dürfen einen beliebigen Typ haben, er
+muß jedoch für beide gleich sein. 
+    Als Ergebnis der IF-Abfrage wird 'Ausdruck1' geliefert, wenn
+der BOOL-Ausdruck wahr ist, sonst 'Ausdruck2'. 
+ 
+#on("b")#Vergleiche#off("b")# Die wesentlichen Operationen, die boolesche
+Ausdrücke
+zur Verwendung in IF-Abfragen bilden, sind die Vergleichsoperato­
+ren: 
+ 
+ 
+        =   <>   <=   >=   <   > 
+ 
+ 
+Sie vergleichen jeweils zwei Elemente vom Typ TEXT, INT oder REAL
+und liefern TRUE (wahr) oder FALSE (falsch). Selbstverständlich
+können auch sie zwei zusammengesetzte Teilausdrücke vergleichen. 
+    Eine Anwendung ist zum Beispiel der Test, ob ein Text in einem
+anderen enthalten ist: 
+ 
+ 
+        IF pos (f ("Betrag"), "DM") > 0 THEN 
+          "deutsches Geld" 
+        ELSE 
+          "ausländisches Geld" 
+        END IF 
+ 
+ 
+Die Funktion 'pos' wird hier dazu benutzt, festzustellen, ob es sich
+um deutsches oder ausländisches Geld handelt. 
+    Oft müssen jedoch mehrere Vergleiche miteinander kombiniert
+werden. Zu diesem Zweck gibt es die beiden Operatoren AND (und)
+und OR (oder). Damit AND das Ergebnis TRUE liefert, müssen beide
+Vergleiche wahr sein, bei OR muß mindestens einer der beiden wahl
+sein. 
+    Die Reihenfolge aller dieser Operatoren ist so gewählt, daß
+normalerweise keine Klammern benötigt werden. Funktionen haben
+immer Vorrang vor Operatoren, bei den Operatoren kommt die Multi­
+plikation vor der Addition, dann kommen die Vergleiche, danach das
+AND und danach das OR. Alle anderen Operatoren (#on("i")#insbesondere
+SUB#off("i")#) teilen sich den letzten Rang. 
+    Wenn Sie also in einem Ausdruck mehrere Vergleiche mit AND
+und OR verknüpfen, und das OR soll stärker binden als das AND,
+müssen Sie dies durch Klammern ausdrücken. 
+    Den oben besprochenen Operator SUB sollten Sie immer in
+Klammern setzen, wenn Sie ihn in einem Vergleich benutzen. Da er
+die niedrigste Priorität hat, gäbe es sonst mit Sicherheit Fehler: 
+ 
+ 
+        IF (f ("Name") SUB 1) = "M" THEN 
+          "vielleicht Müller" 
+        ELSE 
+          "bestimmt nicht" 
+        END IF 
+ 
+ 
+#on("b")#Refinements#off("b")# Bisher hatten wir gesagt, daß IF-Abfragen
+nicht
+innerhalb von anderen Ausdrücken verwendet werden dürfen. Diese
+Einschränkung kann man umgehen, indem man #on("i")#Refinements#off("i")# verwen­
+det. 
+    Ein Refinement hat im Druckmuster eine ähnliche Wirkung wie
+eine Abkürzung, lediglich der Name darf nur mit Kleinbuchstaben
+und Ziffern geschrieben sein und kann nicht als Feldmuster ver­
+wendet werden. 
+ 
+ 
+        &abk : 
+          subtext (f ("Name"), namensanfang) . 
+        namensanfang : 
+          IF pos (f ("Name"), " ") > 0 THEN 
+            pos (f ("Name"), " ") + 1 
+          ELSE 
+            length (f ("Name")) 
+          END IF . 
+ 
+ 
+Innerhalb von Refinements dürfen auch wieder andere Refinements
+verwendet werden. 
+    Auch in Kopier- und Änderungsmustern können Sie Refinements
+verwenden. Hier müssen Sie jedoch darauf achten, daß alle Refine­
+ments am Ende gesammelt werden und vor dem ersten Refinement
+ein Punkt stehen muß. Ebenso müssen die Refinements wie im
+Druckmuster durch Punkte voneinander getrennt sein: 
+ 
+ 
+        "Anrede" K anrede; 
+        . 
+        anrede : 
+          IF f ("m/w") = "w" THEN 
+            "Frau" 
+          ELSE 
+            "Herr" 
+          END IF . 
+ 
+ 
+
diff --git a/doc/eudas/eudas.hdb.15 b/doc/eudas/eudas.hdb.15
new file mode 100644
index 0000000..c0a22cf
--- /dev/null
+++ b/doc/eudas/eudas.hdb.15
@@ -0,0 +1,286 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (165)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+15 Anweisungen in ELAN 
+ 
+ 
+ 
+15.1 Variablen und Zuweisungen 
+ 
+Im vorigen Kapitel haben wir Ausdrücke in ELAN kennengelernt. Der
+Wert eines Ausdrucks wird bei jeder Verwendung erneut berechnet.
+Wenn wir den Wert eines Ausdrucks aufbewahren wollen, müssen wir
+ihn schon in eine EUDAS-Datei schreiben. 
+    Oft tritt jedoch die Notwendigkeit auf, Werte zu merken, ohne
+sie in einer Datei zu speichern. Beispiel dafür ist ein Zählvorgang im
+Druckmuster. In jedem Wiederholungsteil muß der dazukommende
+Wert zum bisherigen, aufsummierten und aufbewahrten Wert addiert
+werden. Das Zwischenergebnis der Zählung muß also irgendwo ge­
+speichert werden. 
+ 
+#on("b")#Variablen#off("b")# Zu diesem Zweck gibt es Variablen. Sie sind
+ähnlich wie
+Felder in einer Datei. Ihre Existenz ist jedoch unabhängig von einer
+Datei. Außerdem sind sie zu Anfang nicht einfach leer, sondern
+haben einen undefinierten Wert. 
+    Variablen müssen im Programm definiert werden. Sie existieren
+dann während der Ausführung dieses Programms und gehen an­
+schließend verloren. Zu Beginn des Programms sind sie, wie schon
+gesagt, undefiniert. 
+    Eine Variable muß immer einen Typ haben. Dieser Typ ist für
+die Lebensdauer der Variable unveränderlich. Die Variable kann
+natürlich nur Werte dieses Typs annehmen. 
+    Eine Variablendefinition (oder auch -deklaration) besteht aus
+der Angabe eines Typs, dem Schlüsselwort VAR und einem freige­
+wählten Namen. Wie schon bei den Refinements darf ein solcher
+Name nur aus Kleinbuchstaben (keine Umlaute) und eventuell Zif­
+fern bestehen. Dagegen darf der Name Leerzeichen enthalten. 
+Beispiel: 
+ 
+ 
+        INT VAR zaehler; 
+        TEXT VAR feldname; 
+        REAL VAR mein ergebnis 1; 
+ 
+ 
+Das Semikolon am Ende beschließt die Definition. 
+    Die Lebensdauer einer Variablen hängt davon ab, an welcher
+Stelle sie definiert ist. Eine Variable, die im Druckmuster im Initia­
+lisierungsteil definiert ist, behält ihren Wert für die gesamte Dauer
+des Druckvorgangs. Eine Variable in einem Abschnitt lebt dagegen
+nur für eine Abarbeitung dieses Abschnitts. Bei der nächsten Abar­
+beitung ist sie wieder undefiniert. 
+    Das gleiche gilt für Kopier- und Änderungsmuster. Auch hier
+sind Variablen nur für die Dauer der Bearbeitung eines Satzes
+gültig. 
+ 
+#on("b")#Zuweisung#off("b")# Um einer Variablen einen Wert zu geben, führt
+man eine
+#on ("i")#Zuweisung#off("i")# aus. Die Zuweisung wird durch Doppelpunkt und Gleich­
+heitszeichen aneinandergeschrieben gekennzeichnet. Auf der linken
+Seite steht die Variable, auf der rechten Seite eine Ausdruck: 
+ 
+ 
+        zaehler := 1; 
+ 
+ 
+Wie oben schließt das Semikolon die Anweisung ab. Nach der Aus­
+führung hat die Variable den Wert 1. Der Wert vorher ist für die
+Zuweisung egal, er kann definiert oder undefiniert sein. 
+    Eine Variable kann in einem Ausdruck verwendet werden, indem
+man einfach den Namen hinschreibt. Der Ausdruck 
+ 
+ 
+        zaehler + 1 
+ 
+ 
+hat nach der obigen Zuweisung den Wert 2. Eine Variable muß bei
+der Verwendung definiert sein, sonst können beliebige Fehler ent­
+stehen. Es muß also vor der ersten Verwendung ausdrücklich eine
+Zuweisung erfolgt sein. 
+    Da Variablen in Ausdrücken verwendet werden können und
+Ausdrücke auf der rechten Seite einer Zuweisung stehen, ist folgen­
+de Konstruktion möglich: 
+ 
+ 
+        zaehler := zaehler + 1; 
+ 
+ 
+Diese Zeile bewirkt, daß der Wert der Variable um 1 erhöht wird.
+Zuerst wird bei der Zuweisung der Wert des Ausdrucks auf der rech­
+ten Seite bestimmt. Zu diesem Zeitpunkt habe die Variable bei­
+spielsweise den Wert 1. Der Ausdruck hat dann den Wert 2 (1+1).
+Dieser Wert wird der neue Wert der Variablen. 
+    Bei der nächsten Ausführung würde sich der gleiche Vorgang
+wiederholen, so daß die Variable anschließend den Wert 3 hat. 
+    Auch bei der Zuweisung gilt natürlich, daß die Variable auf der
+linken Seite den gleichen Datentyp haben muß wie der Ausdruck auf
+der rechten Seite. 
+ 
+#on("b")#Initialisierung#off("b")# Sie können Variablendeklaration und
+Zuweisung
+auch miteinander verknüpfen, so daß die Variable gleich zu Anfang
+einen Wert erhält: 
+ 
+ 
+        INT VAR zaehler := 0; 
+ 
+ 
+Dieses Verfahren ist eine gute Vorsichtsmaßregel, damit Sie keine
+undefinierten Variablen verwenden. 
+ 
+#on("b")#Inkrement#off("b")# Da der Fall so häufig auftritt, daß der Wert
+einer Vari­
+ablen um einen bestimmten Wert erhöht wird (bei allen Zählvorgän­
+gen), gibt es auch dafür eine Abkürzung, und zwar die beiden Ope­
+ratoren INCR und DECR. 
+ 
+ 
+        zaehler INCR 1; 
+        mein ergebnis 1 DECR 24.4; 
+ 
+ 
+Die Operatoren sind für REALs und INTs definiert. INCR erhöht um
+einen Betrag, DECR erniedrigt. Auf der rechten Seite darf wieder ein
+beliebiger Ausdruck stehen. 
+    Für TEXTe gibt es eine ähnliche Abkürzung, allerdings nur für
+die Addition (Verkettung). Hier heißt der Operator CAT. Die beiden
+folgenden Zeilen haben die gleiche Bedeutung: 
+ 
+ 
+        feldname := feldname + "."; 
+        feldname CAT "."; 
+ 
+ 
+ 
+15.2 Weitere Konstruktionen 
+ 
+#on("b")#IF#off("b")# Die Ihnen bereits bekannte IF-Konstruktion dient nicht
+nur
+dazu, Werte zu liefern, sondern steuert auch die Abarbeitung von
+beliebigen Anweisungen. Diese Anweisungen können Kopier- und
+Änderungsanweisungen sein (s. Kapitel 11), oder die oben beschrie­
+benen Zuweisungen. 
+    In einem Teil der IF-Konstruktion können auch mehrere Anwei­
+sungen stehen. Diese müssen dann jedoch unbedingt durch Semiko­
+lon getrennt sein. Mehrere Anweisungen hintereinander haben ein­
+fach die Bedeutung der Ausführung in der notierten Reihenfolge. 
+    Als drittes kann auch der ELSE-Teil weggelassen, da nicht in
+jedem Fall ein Ergebnis erwartet wird. Falls die Bedingung nicht
+zutrifft, muß nicht unbedingt etwas ausgeführt werden. 
+ 
+ 
+        IF zaehler > 0 THEN 
+          zaehler DECR 1; 
+          mein ergebnis 1 INCR wert ("zaehlfeld") 
+        END IF; 
+ 
+ 
+Auch diese IF-Konstruktion kann wieder geschachtelt werden. Für
+viele Fälle gibt es jedoch einen ELIF-Teil, der die Verschachtelung
+erspart: 
+ 
+ 
+        IF f ("m/w") = "m" THEN 
+          maenner INCR 1 
+        ELIF f ("m/w") = "w" THEN 
+          frauen INCR 1 
+        ELSE 
+          zweifelhaft INCR 1 
+        END IF; 
+ 
+ 
+Der ELIF-Teil beinhaltet noch einmal einen Test. Dieser Test wird
+jedoch nur dann durchgeführt, wenn die erste Bedingung falsch war.
+Gibt es noch mehr Wahlmöglichkeiten, können Sie beliebig viele
+ELIF-Teile benutzen. 
+    Beachten Sie, daß die letzte Anweisung in einem Teil der IF-
+Konstruktion nicht unbedingt ein folgendes Semikolon haben muß
+(das Semikolon soll nur trennen). Ein Semikolon an dieser Stelle
+kann aber auch nicht schaden. 
+ 
+#on("b")#Werteliefernde Programme#off("b")# Nicht nur Ausdrücke können Werte
+lie­
+fern, sondern auch ganze Anweisungsfolgen. Dies ist eine Erweite­
+rung der werteliefernden IF-Konstruktion. Sie können dies für Ab­
+kürzungen oder Refinements ausnutzen. 
+ 
+ 
+        endergebnis : 
+          gesammelte zeichen CAT "."; 
+          gesammelte zeichen . 
+ 
+ 
+In diesem Beispiel werden in einer Textvariable bestimmte Zeichen
+gesammelt. Zum Schluß soll ein Punkt angefügt werden und dieser
+Text dann als Ergebnis des Refinements geliefert werden. 
+    Damit eine Anweisungsfolge einen Wert liefert, muß am Ende
+der Anweisungsfolge ein Ausdruck stehen. Der Wert des Ausdrucks
+nach Abarbeitung der Anweisungen ist dann der Wert der Anwei­
+sungsfolge. 
+    Allerdings kann man den gleichen Wert oft verschieden aus­
+drücken. Folgendes Refinement hat die gleiche Wirkung wie oben: 
+ 
+ 
+        endergebnis : 
+          gesammelte zeichen + "." . 
+ 
+ 
+In manchen Fällen ist eine Formulierung als werteliefernde Anwei­
+sungsfolge jedoch übersichtlicher. 
+ 
+#on("b")#Beispiel#off("b")# Zum Abschluß dieses Kapitels wollen wir als
+Beispiel eine
+statistische Auswertung einer Zahlenreihe als Druckmuster formu­
+lieren. 
+    Gegeben sei eine Datei mit folgenden Feldern: 
+ 
+ 
+        "Meßwert 1" 
+        "Meßwert 2" 
+ 
+ 
+Wir wollen als Ergebnis Mittelwert und Standardabweichung der
+beiden Meßwerte ausdrucken. Dazu dient das Druckmuster auf der
+folgenden Seite. 
+    Im Initialisierungsteil des Druckmusters werden die notwendi­
+gen Variablen definiert und initialisiert. Beachten Sie hier, daß in
+einer Definition mehrere Variablen durch Komma getrennt aufgeführt
+werden können, wenn sie den gleichen Typ haben. 
+    Im Wiederholungsteil müssen dann jeweils die Zwischensummen
+aktualisiert werden. Da mit der Funktion 'wert' eine relativ auf­
+wendige Umwandlung verbunden ist, wird der Wert des jeweiligen
+Feldes erst einmal in einer Variable zwischengespeichert, da er
+mehrmals benötigt wird. Diese Zwischenspeicherungsvariable muß
+nicht initialisiert werden 
+    Im Nachspann werden dann die Ergebnisse gedruckt. Die Formeln
+sind jeweils als Abkürzungen definiert. Die Funktion 'zahltext' sorgt
+dafür, daß die Werte mit drei Nachkommastellen (gerundet) aufge­
+führt werden. 
+    Da die Formeln relativ komplex sind, werden sie auf mehrere
+Zeilen verteilt (in ELAN hat das Zeilenende keine Bedeutung). 
+ 
+ 
+        %% REAL VAR 
+        %%   messwert, 
+        %%   summe 1 := 0.0, quadratsumme 1 := 0.0, 
+        %%   summe 2 := 0.0, quadratsumme 2 := 0.0; 
+        %% INT VAR anzahl := 0; 
+        % WIEDERHOLUNG 
+        %% anzahl INCR 1; 
+        %% messwert := wert ("Meßwert 1"); 
+        %% summe 1 INCR messwert; 
+        %% quadratsumme 1 INCR messwert * messwert; 
+        %% messwert := wert ("Meßwert 2"); 
+        %% summe 2 INCR messwert; 
+        %% quadratsumme 2 INCR messwert * messwert; 
+        % NACHSPANN 
+        &anz Meßwerte. 
+                               Meßwert 1       Meßwert 2 
+        Mittelwert             &&mw1&&&&       &&mw2&&&& 
+        Standardabweichung     &&st1&&&&       &&st2&&&& 
+        % ABKUERZUNGEN 
+        &mw1 : zahltext (summe 1 / real (anzahl), 3) . 
+        &mw2 : zahltext (summe 2 / real (anzahl), 3) . 
+        &st1 : zahltext 
+          (sqrt ((quadratsumme 1 - summe 1 * summe 1 / 
+               real (anzahl)) / real (anzahl - 1)), 3) . 
+        &st2 : zahltext 
+          (sqrt ((quadratsumme 2 - summe 2 * summe 2 / 
+               real (anzahl)) / real (anzahl - 1)), 3) . 
+ 
+ 
+Mit entsprechenden Formeln können Sie dieses Beispiel für Ihre
+eigenen Statistiken erweitern. Die Beispiele der letzten beiden Ka­
+pitel sollten Ihnen genügend Anregungen dafür gegeben haben. 
+
diff --git a/doc/eudas/eudas.hdb.16 b/doc/eudas/eudas.hdb.16
new file mode 100644
index 0000000..5f5d575
--- /dev/null
+++ b/doc/eudas/eudas.hdb.16
@@ -0,0 +1,350 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (171)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+16 Dateiverwaltung mit EUDAS 
+ 
+ 
+ 
+16.1 Dateien im System 
+ 
+Zum Bearbeiten von Dateien innerhalb des Systems gibt es das Menü
+'Dateien', das Sie bereits in Kapitel 4 kurz kennengelernt haben.
+An dieser Stelle sollen die übrigen Funktionen dieses Menüs be­
+sprochen werden. 
+ 
+ 
+        -------------- 
+        Dateien System 
+        U Übersicht 
+        -------------- 
+        Datei 
+        L Löschen 
+        N Umbenennen 
+        K Kopieren 
+        P Platzbedarf 
+        A Aufräumen 
+        -------------- 
+ 
+#center#Abb. 16-1   Menü 'Dateien' 
+ 
+ 
+Beachten Sie, daß alle Funktionen in diesem Menü mit Dateien
+beliebiger Struktur arbeiten können, also sowohl mit Textdateien
+als auch EUDAS-Dateien (und anderen). Dies liegt daran, daß
+Dateien an dieser Stelle einfach als "schwarze Kästen" mit beliebi­
+gem Inhalt betrachtet werden. 
+ 
+#on("b")#Übersicht#off("b")# Die Funktion 'Übersicht' haben Sie bereits
+ausprobiert.
+Sie zeigt in einem Editorfenster an der rechten Seite alle Dateien,
+die sich in Ihrer Task befinden. Falls nicht alle Dateien auf den
+Bildschirm passen, können Sie das Fenster mit HOP OBEN und HOP
+UNTEN rollen. Sie verlassen die Übersicht wie üblich mit ESC 'q'. 
+ 
+#on("b")#Löschen#off("b")# Auch die Funktion 'Löschen' sollten Sie schon
+kennen.
+Mit dieser Funktion verschwindet eine Datei auf Nimmerwieder­
+sehen. Daher werden Sie sicherheitshalber immer gefragt, ob Sie die
+Datei wirklich löschen wollen. Sie können in einer Auswahl auch
+alle zu löschenden Dateien ankreuzen (dann wird trotzdem nochmal
+gefragt). 
+    Eine EUDAS-Datei, die gerade geöffnet ist, können Sie nicht
+löschen (sonst würde EUDAS zumindest durcheinanderkommen). Sie
+müssen die Datei zuerst sichern - oder nicht sichern, aber die
+Arbeitskopien löschen. 
+ 
+#on("b")#Umbenennen#off("b")# Mit der Funktion 'Umbenennen' können Sie einer
+Datei
+einen neuen Namen geben. Sie werden zuerst aufgefordert, den alten
+Namen der Datei einzugeben. Alternativ können Sie hier wieder die
+umzubenennenden Dateien auswählen. Danach wird Ihnen (für jede
+ausgewählte Datei) der alte Dateiname zum Überschreiben angebo­
+ten. 
+    Sie können diesen Namen mit den üblichen Editierfunktionen
+verändern oder mit HOP RUBOUT löschen und ganz neu eingeben.
+Auf diese Weise sparen Sie sich erheblichen Tippaufwand, wenn Sie
+einen langen Dateinamen an nur einer Stelle verändern wollen. 
+ 
+#on("b")#Kopieren#off("b")# Wie in Abschnitt 11.2 bereits angedeutet, gibt es
+eine
+Funktion zum logischen Kopieren von Dateien. Dies ist eine Funk­
+tion, die sich auf spezielle Eigenschaften des EUMEL-Systems
+stützt. Wenn Sie eine Datei #on("i")#logisch#off("i")# kopieren, wird lediglich ein
+Verweis kopiert. Die Daten werden zunächst nur einmal für beide
+Dateien gespeichert. 
+    Natürlich hätte das Ganze wenig Sinn, wenn danach bei Ände­
+rungen immer beide Dateien geändert würden. Bei Änderungen an
+einer Datei werden jedoch nur die geänderten Daten getrennt ange­
+legt, der Rest wird weiterhin gemeinsam benutzt. Die beiden Dateien
+sind also nach außen hin komplett unabhängig, intern werden je­
+doch gemeinsame Daten so weit wie möglich geteilt. Auf diese Weise
+wird sowohl Zeit als auch Speicherplatz gespart. 
+    Dieses Verfahren ist besonders dann sinnvoll, wenn Sie sich
+einen bestimmten Stand einer Datei aufbewahren wollen. In diesem
+Fall stellen Sie sich eine logische Kopie her und arbeiten mit dem
+Original weiter. Es werden dann nur die Daten zusätzlich angelegt,
+die Sie seit der Kopie verändert haben. 
+    EUDAS benutzt die gleiche Funktion auch für die Arbeitskopie.
+Die Arbeitskopie teilt ebenfalls ihre Daten mit dem Original. Ande­
+renfalls wäre es ja auch zeitlich gar nicht möglich, beim Öffnen eine
+Arbeitskopie anzufertigen. 
+    Beim Aufruf der Funktion 'Kopieren' werden Sie zunächst nach
+dem Namen der Datei gefragt (wie üblich mit Auswahlmöglichkeit).
+Dann können Sie einen neuen Namen für die Kopie angeben. Dieser
+neue Name darf jedoch nicht für eine andere Datei vergeben sein.
+Wollen Sie eine andere Datei überkopieren, müssen Sie diese zu­
+nächst löschen. 
+    Denken Sie daran, daß die hier beschriebene Funktion sich
+wesentlich vom Kopieren im Menü 'Gesamtdatei' unterscheidet. Dort
+wird nämlich eine tatsächliche Kopie durchgeführt, dafür können Sie
+sich dann auch selektiv bestimmte Daten herausgreifen. Außerdem
+gilt die dortige Funktion nur für EUDAS-Dateien. 
+ 
+#on("b")#Platzbedarf#off("b")# Zu Ihrer Information können Sie sich auch den
+Platz­
+bedarf anzeigen lassen, den eine Datei auf dem Speichermedium hat.
+Wenn Sie den Namen der Datei angegeben haben, wird Ihnen die
+Größe in "Kilobyte" (KB) angegeben. Ein KB entspricht etwa 1000
+Zeichen, also einer halben vollgeschriebenen Bildschirmseite. 
+    Bei logisch kopierten Dateien wird für jede Datei der benötigte
+Platz separat angegeben. Sie können die Zahlen also nicht einfach
+addieren, um den Gesamtspeicherbedarf zu ermitteln, da Sie dann
+die gemeinsam benutzten Bereiche doppelt zählen würden. 
+ 
+#on("b")#Aufräumen#off("b")# Wenn eine Datei viel geändert wurde, führen zwei
+Effekte zu einer langsameren Verarbeitung dieser Datei. Zum einen
+wird durch Textleichen der Platzbedarf größer. Dies tritt vor allem
+dann auf, wenn zu einzelnen Sätzen immer etwas hinzugefügt wurde
+(eine Folge der Flexibilität, mit variablen Textlängen operieren zu
+dürfen). 
+    Da der Platzbedarf der Datei also wächst, sind mehr Speicher­
+zugriffe notwendig, als es dem Inhalt entspricht. Doch nicht nur der
+Platz, sondern auch die Verteilung der Sätze machen sich unange­
+nehm bemerkbar. Da vergrößerte Sätze intern am Ende der Datei
+gespeichert werden, werden logisch aufeinanderfolgende Sätze phy­
+sikalisch weit verstreut. 
+    Der gleiche Effekt ensteht auch durch Umsortieren oder Ein­
+fügen von Sätzen. Um die Datei sequentiell zu bearbeiten, sind also
+ständig wechselnde Speicherzugriffe erforderlich. 
+    Die beiden beschriebenen Effekte führen zur Geschwindigkeits­
+verringerung. Dies kann verhindert werden, indem die Datei in eine
+frische Datei umkopiert wird. Diesen Vorgang nennt man #on("i")#Reorgani­
+sieren#off("i")#. Dafür gibt es die Funktion 'Aufräumen'. 
+    Während des Umkopierens werden die Satznummern ausgegeben.
+Achten Sie darauf, daß zum Reorganisieren genügend Platz auf dem
+System vorhanden ist, um eine komplette Kopie der zu reorganisie­
+renden Datei aufzunehmen. 
+    Zum Reorganisieren muß nämlich tatsächlich eine physikalische
+Kopie angefertigt werden. Eine logische Kopie oder das Schreiben
+auf das Archiv reorganisieren eine Datei dagegen nicht, wohl aber
+die Funktion 'Kopieren' im Menü 'Gesamtdatei'. 
+    Da der Inhalt gelesen werden muß, funktioniert die Funktion
+'Aufräumen' im Gegensatz zu den oben gemachten Versprechungen
+nur für Textdateien oder EUDAS-Dateien, nicht aber für andere
+Dateitypen. Die Unterscheidung der Dateitypen wird automatisch
+vorgenommen. 
+ 
+ 
+16.2 Dateien auf dem Archiv 
+ 
+Mit den Funktionen im Menü 'Archiv' können Sie nicht nur Dateien
+auf dem Archiv behandeln, sondern auch in anderen Tasks oder per
+EUMEL-Netz sogar auf anderen Rechnern. 
+ 
+ 
+        -------------- 
+        Dateien Archiv 
+        U Übersicht 
+        D Üb. Drucken 
+        -------------- 
+        Datei 
+        K Kopieren 
+          vom Archiv 
+        S Schreiben 
+          auf Archiv 
+        L Löschen 
+          auf Archiv 
+        -------------- 
+        Archivdiskette 
+        I Init 
+        -------------- 
+        Z Zielarchiv 
+        P Paßwort 
+        R Reservieren 
+        -------------- 
+ 
+#center#Abb. 16-2   Menue 'Archiv' 
+ 
+ 
+#on("b")#Zielarchiv#off("b")# Dazu können Sie die Task einstellen, mit der
+Sie arbei­
+ten möchten. Normaleinstellung ist die Task 'ARCHIVE', die Ihre
+Archivdiskette bedient. Dies wird auch in der untersten Bildschirm­
+zeile angezeigt. 
+    Die Task stellen Sie mit der Funktion 'Zielarchiv' ein. Sie
+werden dann nach dem Namen der Task gefragt. Diese Task muß
+eine Managertask sein (also unabhängig vom Bildschirm arbeiten)
+und sie muß bereits existieren. 
+    Wenn Sie auf Ihrem Rechner das EUMEL-Netz installiert haben,
+werden Sie auch nach der Nummer der Zielstation gefragt, also der
+Nummer des Rechners, auf dem die gewünschte Task arbeitet. Durch
+Drücken von RETURN wird automatisch Ihre eigene Stationsnummer
+verwendet. 
+    Nun gibt es zwei Arten von Managertasks, mit denen EUDAS
+zusammenarbeiten kann, #on("i")#Archivmanager#off("i")# und normale Dateimanager.
+Der Unterschied besteht darin, daß ein Archivmanager für einen
+Benutzer reserviert werden muß, damit man nicht auf Disketten
+eines anderen Benutzers zugreifen kann. Normale Dateimanager
+können und sollen dagegen von mehreren Benutzern in beliebiger
+Reihenfolge angesprochen werden. 
+    Manche Rechner haben mehrere Archivmanager für mehrere
+Diskettenlaufwerke. Durch das Einstellen des Zielarchivs können Sie
+auf verschiedenen Laufwerken archivieren. Ein Archivmanager kann
+sich natürlich auch auf einem anderen Rechner befinden. Sie benut­
+zen dann dessen Diskettenlaufwerk. 
+    Beim Einstellen des Zielarchivs wird als letztes gefragt, ob die
+Zieltask ein Archivmanager ist oder nicht. Im Normalfall sollten Sie
+die Frage bejahen, wenn Sie 'ARCHIVE' einstellen, und ansonsten
+verneinen (s. die obigen Ausnahmefälle). 
+    Das eingestellte Zielarchiv wird jeweils in der untersten Bild­
+schirmzeile angezeigt. 
+    Die Reservierung eines Archivmanagers findet beim ersten Zu­
+griff statt. Beim Umschalten des Zielarchivs oder Verlassen des
+Menüs wird die Reservierung automatisch wieder aufgehoben. 
+ 
+#on("b")#Übersicht#off("b")# Mit der Funktion 'Übersicht' können Sie eine
+Auflistung
+aller Dateien abrufen, die sich auf der Archivdiskette (bzw. in dem
+eingestellten Manager) befinden. Wie die Dateiübersicht im System
+können Sie die Darstellung wie im Editor rollen und mit ESC 'q'
+verlassen. 
+    Wollen Sie die Übersicht gedruckt haben, rufen Sie die Funktion
+'Übersicht drucken' auf. Die Übersicht wird dann nochmals zusam­
+mengestellt und gleich gedruckt. 
+ 
+#on("b")#Schreiben und Lesen#off("b")# Mit den Funktionen 'Kopieren vom
+Archiv'
+und 'Schreiben auf Archiv' können Sie Dateien zwischen dem Archiv
+und Ihrer Task hin und her transportieren. Es wird jeweils eine
+Kopie angefertigt, das heißt das Original auf der Diskette oder in
+Ihrer Task wird nicht verändert. 
+    Wenn die transportierte Datei an ihrem Ziel schon existiert,
+wird gefragt, ob die vorher existierende Datei gelöscht (überschrie­
+ben) werden soll. Überschreiben aus Versehen ist nicht möglich,
+wenn Sie die Frage sorgfältig beantworten. 
+    Beim Aufruf der Funktionen können Sie den gewünschten Da­
+teinamen angeben oder in der Auswahl ankreuzen. Die Auswahl ist
+hier besonders sinnvoll, wenn Sie mehrere Dateien (eventuell sogar
+in einer bestimmten Reihenfolge) sichern müssen. Außerdem können
+Sie ja keine Datei transportieren, die nicht existiert; alle Möglich­
+keiten werden Ihnen also durch Ankreuzen angeboten. 
+    Beachten Sie, daß beim Überschreiben einer Datei auf einer
+Archivdiskette der Speicherplatz der alten (überschriebenen) Ver­
+sion im allgemeinen nicht wiederverwendet werden kann. In diesem
+Fall kann das Archiv voll werden, obwohl eigentlich genügend Platz
+da wäre. 
+ 
+#on("b")#Löschen#off("b")# Das gleiche Problem tritt auf beim Löschen einer
+Datei
+auf dem Archiv. Mit der Funktion 'Löschen auf Archiv' können Sie
+zwar die Datei auf der Diskette ungültig machen, der Platz wird
+jedoch nur dann wiederverwendet, wenn es die letzte Datei auf der
+Diskette war. Anderenfalls bleiben "Leichen" übrig, die Sie in der
+Archivübersicht als Striche erkennen können. 
+    Diese Probleme treten jedoch mit anderen Managern nicht auf,
+da diese Ihren Speicherplatz intelligenter verwalten können. 
+ 
+#on("b")#Initialisieren#off("b")# Als Abhilfe bei einem übergelaufenen Archiv
+müssen
+Sie das ganze Archiv initialisieren und neu beschreiben. Dazu gibt
+es die Funktion 'Init'. 
+    Diese Funktion müssen Sie auch dann verwenden, wenn Sie eine
+Archivdiskette zum ersten Mal verwenden. Auf dem Archiv muß
+nämlich als erstes der Archivname eingetragen werden, ehe es be­
+nutzt werden kann. Diesen Namen müssen Sie hier angeben. 
+    Alle alten Daten des Archivs werden komplett gelöscht. Daher
+müssen Sie vorher die noch gültigen Daten vom Archiv ins System
+kopiert haben. Wenn das Archiv vorher schon beschrieben war,
+werden Sie anhand des Namens gefragt, ob Sie die richtige Diskette
+zum Überschreiben eingelegt haben. 
+    Wenn Sie eine fabrikneue Diskette aus der Verpackung nehmen,
+müssen Sie diese vor der Initialisierung #on("i")#formatieren#off("i")#. Dabei wird die
+Diskette auf ein bestimmtes physikalisches Format eingestellt. Ohne
+diese Operation ist weder Schreiben noch Lesen überhaupt möglich. 
+    In der Regel muß eine Diskette nur einmal formatiert werden.
+Sie können sie jedoch jederzeit wieder formatieren (wenn Sie zum
+Beispiel nicht wissen, was Ihnen da für eine alte Diskette in die
+Finger geraten ist). 
+    Am Anfang des Initialisierens werden Sie gefragt, ob Sie die
+Diskette formatieren wollen. Manche Rechner unterstützen diese
+Operation innerhalb des EUMEL-Systems nicht. In diesem Fall (und
+natürlich auch sonst normalerweise) müssen Sie die Frage vernei­
+nen. Das Formatieren muß dann vorher irgendwie außerhalb des
+Systems geschehen sein. 
+    Das Initialisieren funktioniert natürlich nur bei Archivmana­
+gern. Bei einer anderen Zieltask ist diese Funktion gesperrt. 
+ 
+#on("b")#Paßwort#off("b")# Dateien in einem allgemeinen Dateimanager (nicht
+jedoch
+auf dem Archiv) können Sie mit einem Paßwort gegen unbefugten
+Zugriff sichern. Sinnvolle Voraussetzung dafür ist, daß der Datei­
+manager selbst mit einem anderen Paßwort gegen Betreten gesichert
+ist. 
+    Das von Ihnen verwendete Paßwort geben Sie mit der Funktion
+'Paßwort' ein. Damit Ihnen niemand über die Schulter schauen
+kann, werden alle Zeichen auf dem Bildschirm als Punkte darge­
+stellt. Anschließend müssen Sie das Paßwort noch einmal eingeben,
+damit sich kein unbemerkter Schreibfehler eingeschlichen hat. 
+    Das Paßwort wird dann bei allen Transport- und Löschopera­
+tionen abgefragt. Eine Datei im Manager erhält Ihr Paßwort zuge­
+wiesen, wenn Sie sie das erste Mal im Manager ablegen. Bei allen
+folgenden Zugriffen muß das gleiche Paßwort eingestellt sein, sonst
+wird der Zugriff verweigert. 
+    Natürlich können Sie für verschiedene Dateien verschiedene
+Paßwörter einstellen. Trotz Einstellung eines Paßworts können auch
+andere Benutzer ihre Dateien im gleichen Manager ablegen. 
+    Sie können auch für Schreiben (und Löschen) sowie Lesen
+unterschiedliche Paßwörter einstellen. Dazu benutzen Sie einfach
+einen Trennstrich in der Form 
+ 
+ 
+        Schreibpaßwort/Lesepaßwort 
+ 
+ 
+Soll eine Datei überhaupt nicht überschrieben oder gelöscht werden
+können, können Sie '-' als Schreibpaßwort verwenden: 
+ 
+ 
+        -/Lesepaßwort 
+ 
+ 
+Die Datei kann dann nur beim direkten Betreten der Managertask
+verändert werden. 
+    Wollen Sie die Paßworteinstellung wieder aufheben, drücken Sie
+bei der Paßworteingabe nur RETURN, da der leere Text als "kein
+Paßwort" interpretiert wird. 
+ 
+#on("b")#Reservieren#off("b")# Wollen Sie eine Task als Zieltask verwenden,
+die zwar
+kein Archivmanager ist, aber reserviert werden muß (zum Beispiel
+'DOS' zum Ansprechen fremder Diskettenformate) müssen Sie die
+Reservierung mit der Funktion 'Reservieren' selbst vornehmen. Die
+Zieltask darf nicht als Archivmanager gekennzeichnet sein (dann ist
+die Funktion 'Reservieren' nämlich gesperrt). 
+    Bei der Reservierung müssen Sie den Reservierungsparameter
+(abhängig von der Art der Zieltask - bei 'DOS' beispielsweise den
+Modus) als Text eingeben. Nach der Reservierung können Sie die
+anderen Funktionen des Archivmenüs verwenden. 
+    Die Freigabe der Zieltask erfolgt automatisch beim Verlassen
+des Menüs oder beim Einstellen einer neuen Zieltask. 
+
diff --git a/doc/eudas/eudas.hdb.2 b/doc/eudas/eudas.hdb.2
new file mode 100644
index 0000000..f3f14e1
--- /dev/null
+++ b/doc/eudas/eudas.hdb.2
@@ -0,0 +1,178 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (11)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+2 Installation des Programms
+ 
+ 
+ 
+Bevor Sie EUDAS auf Ihrem System benutzen können, müssen Sie das
+Programm zuvor installieren. Wenn EUDAS schon auf Ihrem System
+zur Verfügung steht, können Sie dieses Kapitel getrost überlesen. 
+ 
+ 
+2.1 Lieferumfang 
+ 
+EUDAS wird auf einer Diskette geliefert, die alle notwendigen Pro­
+gramme enthält. Um den Inhalt der Diskette feststellen zu können,
+starten Sie Ihr System und bringen es dazu, daß 'gib kommando:'
+erscheint. Dann legen Sie die Diskette ein und geben das Kommando 
+ 
+ 
+    archive ("EUDAS"); list (archive); release (archive) 
+ 
+ 
+Anschließend erscheint eine Übersicht der auf dem Archiv vorhan­
+denen Programmteile. Folgende Namen sollten sich in dieser Über­
+sicht wiederfinden: 
+ 
+ 
+    "eudas.1" 
+    "eudas.2" 
+    "eudas.3" 
+    "eudas.4" 
+    "eudas.init" 
+    "eudas.generator" 
+    "Adressen" 
+ 
+ 
+Eventuell können noch weitere Namen in der Übersicht auftauchen.
+Sollte einer der angegebenen Namen nicht vorhanden sein, rekla­
+mieren Sie die Diskette. Falls Sie statt der Übersicht eine Fehler­
+meldung erhalten, sollten Sie überprüfen, ob die Diskette das rich­
+tige Format besitzt oder Ihr Diskettenlaufwerk Probleme bereitet. 
+    Wenn Sie so den Inhalt der Diskette kontrolliert haben, können
+Sie EUDAS installieren. Je nachdem, ob Sie ein Single-User oder ein
+Multi-User System benutzen, sind die Anweisungen unterschiedlich.
+Sie brauchen nur den Sie betreffenden der beiden folgenden Ab­
+schnitte zu lesen. Falls Sie nicht wissen, welches System Sie benut­
+zen: ein Multi-User System wird auf der Systemdiskette und am
+Bildschirm durch die Kennzeichnung 'EUMEL x.y.z/M' identifiziert,
+bei einem Single-User System steht als letztes Zeichen ein 'S'. 
+ 
+ 
+2.2 Single-User
+ 
+Dieser Abschnitt betrifft Sie nur, wenn Sie EUDAS auf einem
+Single-User System installieren wollen. 
+    Sie können EUDAS immer nur auf einer bestimmten Hinter­
+grunddiskette installieren. Auf dieser Diskette sollten noch min­
+destens 250 KB frei sein (stellen Sie dies durch das Kommando
+'storage info' sicher). EUDAS kann anschließend auch nur auf dieser
+Diskette verwendet werden. 
+    Starten Sie nun die gewünschte Diskette. Dann legen Sie die
+Diskette, auf der EUDAS sich befindet, in das Archivlaufwerk. Geben
+Sie dann das Kommando 
+ 
+ 
+    archive ("EUDAS"); fetch ("eudas.generator", archive); run 
+ 
+ 
+Sie haben damit das Generatorprogramm gestartet, das die Installa­
+tion automatisch durchführt. Lassen Sie während dieses Vorganges
+das EUDAS-Archiv eingelegt. Sie werden benachrichtigt, wenn die
+Generierung abgeschlossen ist. 
+    Wenn Sie EUDAS auf allen Ihren Hintergrunddisketten haben
+möchten, können Sie das so erzeugte System als Muttersystem
+sichern. Mit dem Kommando 'save system' können Sie den Hinter­
+grund komprimiert auf eine leere Archivdiskette schreiben. Mit
+dieser Sicherung können Sie dann jederzeit neue Systemdisketten
+wie von Ihrem Originalsystem herstellen. 
+ 
+#on("b")#Einschränkungen#off("b")# Aus Platzgründen hat die
+Single-User-Version von EUDAS folgende Einschränkungen: 
+#free (0.2)# 
+  Sie können die Funktionen Ketten und Koppeln nicht verwenden. 
+#free (0.2)# 
+  Sie können im Druckmuster keine ELAN-Anweisungen und -Aus­
+   drücke verwenden. 
+#free (0.2)# 
+  Es stehen nur einige allgemeine Hilfstexte zur Verfügung. 
+#free (0.2)# 
+  Funktionen, die mehrere Tasks vorausssetzen, sind ebenfalls
+   gesperrt. 
+#free (0.2)# 
+Die betreffenden Funktionen sind zwar gegebenenfalls im Menü
+enthalten, lassen sich aber nicht aufrufen. 
+ 
+ 
+2.3 Multi-User 
+ 
+Dieser Abschnitt betrifft Sie nur, wenn Sie EUDAS auf einem Mul­
+ti-User System installieren wollen. 
+    EUDAS muß in einer bestimmten Task installiert werden. Alle
+neuen Söhne und Enkel dieser Task können dann EUDAS aufrufen.
+Im Normalfall wird diese Task 'PUBLIC' sein. 
+    Zum Installieren müssen Sie in diese Task gehen (in diesem
+Beispiel 'PUBLIC'). Dazu rufen Sie durch Tippen der SV-Taste den
+Supervisor und geben das Kommando 
+ 
+ 
+    continue ("PUBLIC") 
+ 
+ 
+Stelle Sie mit Hilfe des 'storage info'-Kommandos fest, ob auf Ihrem
+Hintergrund noch mindestens 300 KB frei sind (dieser Platz wird zur
+Generierung benötigt). Dann legen Sie die EUDAS-Archivdiskette ein
+und geben folgendes Kommando 
+ 
+ 
+    archive ("EUDAS"); fetch ("eudas.generator", archive); run 
+ 
+ 
+Falls die Task 'PUBLIC' Söhne besitzt, werden Sie gefragt, ob Sie
+diese löschen wollen. EUDAS steht nämlich nur in den Söhnen zur
+Verfügung, die #on("i")#nach#off("i")# der Installation eingerichtet wurden. Antworten
+Sie auf die Frage durch einfaches Tippen von 'j' oder 'n'. wenn Sie
+die Frage verneinen, können Sie die Generierung zu diesem Zeit­
+punkt auch noch abbrechen und zunächst die Söhne aufräumen. 
+    Es erscheint die Frage 
+ 
+ 
+        Ausführliche Hilfstexte installieren ? (j/n) 
+ 
+ 
+Verneinen Sie die Frage, wenn in Ihrem System der Speicherplatz
+kritisch ist (zum Beispiel wenn Sie keine Festplatte haben). Es
+werden dann nur die wichtigsten allgemeinen Hilfstexte installiert
+(Ersparnis etwa 40 KByte). 
+    Anschließend wird die automatische Generierung gestartet.
+Lassen Sie die EUDAS-Archivdiskette eingelegt. Die Generierung ist
+beendet, wenn das EUMEL-Bild erscheint. Die Task, in der die
+Generierung stattfindet, wird automatisch zu einer Managertask, das
+heißt, daß man von ihr Söhne einrichten kann. 
+    Sie können das so erweiterte System auch mit 'save system' auf
+einer oder mehreren Archivdiskette sichern. Lesen Sie dazu die
+Hinweise zur Systemsicherung im EUMEL-Systemhandbuch. 
+ 
+#on("b")#Korrekturversionen#off("b")# Falls Sie später einmal eine
+Korrekturversion
+von EUDAS bekommen, sollten Sie vor der neuen Generierung die
+Task, in der EUDAS vorher generiert war, löschen (Vorsicht: alle
+Söhne werden mitgelöscht) und wieder neu einrichten. Anderenfalls
+bleibt die alte Version als unzugängliche "Leiche" auf Ihrem System
+liegen. 
+    In diesem Fall und auch, wenn Sie mehrere Programme in der
+gleichen Task installieren, kann es zum Überlauf der internen Über­
+setzertabellen kommen. Für größere Installationen oder wenn Sie
+viele verschiedene Programme benutzen, empfiehlt es sich, zur
+Generierung eine eigene Task 'EUDAS' als Sohn von 'PUBLIC' zu
+verwenden. Sie dürfen dann aber in 'PUBLIC' nicht zu viel insertie­
+ren, da 'EUDAS' ja alle Programme von 'PUBLIC' erbt. Denken Sie
+daran, daß Sie EUDAS nur in Tasks benutzen können, die unter der
+Task 'EUDAS' eingerichtet wurden. 
+ 
+ 
+
+
+
+
diff --git a/doc/eudas/eudas.hdb.3 b/doc/eudas/eudas.hdb.3
new file mode 100644
index 0000000..e89ff4f
--- /dev/null
+++ b/doc/eudas/eudas.hdb.3
@@ -0,0 +1,515 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (15)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+3 Ein Beispiel zum Ausprobieren 
+ 
+ 
+ 
+Bevor Sie in die tieferen Geheimnisse von EUDAS einsteigen, sollen
+Sie in diesem Kapitel erst einige Erfahrungen mit der Bedienung
+sammeln. Dadurch erhalten Sie Sicherheit im Umgang mit dem Pro­
+gramm und haben bereits einen Eindruck dessen, was Sie anschlie­
+ßend erwartet. 
+    Das Durchlesen dieses Kapitels ist nur dann sinnvoll, wenn Sie
+die Anweisungen selbst am Rechner ausprobieren. Anderenfalls
+beginnen Sie besser mit dem nächsten Kapitel. 
+    Im folgenden sind die Eingaben, die Sie machen sollen, kursiv
+gedruckt, während Ausgaben des Rechners normal erscheinen.
+Außerdem erscheinen spezielle Tasten in spitzen Klammern: 
+ 
+ 
+            <RET> 
+ 
+ 
+Bitte tippen Sie nicht die eckigen Klammern oder Großbuchstaben,
+sondern die entsprechende Taste. Oft haben die Sondertasten auch
+etwas andere Bezeichnungen (die obige zum Beispiel 'CR', 'Carriage
+Return', 'RETURN', 'ENTER'). Bitte fragen Sie bei Unklarheiten Ihren
+Systemlieferanten oder -betreuer. 
+ 
+ 
+3.1 Start 
+ 
+Die Anweisungen zum Starten von EUDAS sind unterschiedlich, je
+nachdem wie Ihr System eingerichtet ist. Bitte beachten Sie daher
+die verschiedenen Fälle. 
+ 
+1. Falls Sie EUDAS nicht selbst installiert haben, fragen Sie am
+   besten Ihren Systembetreuer. Ansonsten verhalten Sie sich wie
+   unter 2. 
+ 
+2. Falls Sie EUDAS nach den Anweisungen von Kapitel 2 in einem
+   Multi-User-System eingerichtet haben, müssen Sie zunächst eine
+   Arbeitstask (Arbeitsbereich) einrichten. Dazu tippen Sie die
+   SV-Taste (diese trägt häufig die unterschiedlichsten Bezeich­
+   nungen). Es erscheint 
+ 
+ 
+                      EUMEL x.y.z/M 
+ 
+           gib supervisor kommando : 
+ 
+ 
+   Sie tippen nun folgendes Kommando: 
+ 
+ 
+           #on("i")#begin ("arbeit")#off("i")#<RET> 
+ 
+ 
+   Vergessen Sie nicht die RETURN-Taste am Schluß. Machen Sie
+   jetzt weiter bei Punkt 4. 
+ 
+3. Falls Sie ein Single-User-System besitzen, starten Sie die
+   Systemdiskette und geben das Datum ein. Dann machen Sie wei­
+   ter mit Punkt 4. 
+ 
+4. Danach erscheint: 
+ 
+ 
+           gib kommando : 
+ 
+ 
+   und Sie tippen: 
+ 
+ 
+           #on("i")#eudas#off("i")#<RET> 
+ 
+ 
+   Als Ergebnis wird das EUDAS-Eingangsmenü angezeigt (s. Abb.
+   3-1 auf der nächsten Seite). 
+ 
+ 
+3.2 Daten eintragen 
+ 
+Als Beispiel sollen Sie eine kleine Adressenkartei einrichten. Der
+Fachausdruck für eine elektronische Kartei ist #on("i")#Datei#off("i")#. 
+ 
+___________________________________________________________________________________________ 
+ 
+      EUDAS:   Öffnen   Einzelsatz   Gesamtdatei   Drucken   Dateien   Archiv 
+      --------------: 
+      EUDAS-Datei   : 
+      O Öffnen      : 
+      - Ketten      : 
+      - Koppeln     :              EEEEE U   U DDDD    A    SSSS 
+      --------------:              E     U   U D   D  A A  S 
+      Arbeitskopie  :              EEE   U   U D   D AAAAA  SSS 
+      - Sichern     :              E     U   U D   D A   A     S 
+      --------------:              EEEEE  UUU  DDDD  A   A SSSS 
+      Aktuelle Datei: 
+      - Notizen     :              Version 4.3 
+      - Feldstrukt. :              Stand: 14.07.87 
+      - Prüfbeding. : 
+      --------------:              (C) Copyright 
+      Mehrbenutzer  :              Thomas Berlage 
+      M Manager     :              Software-Systeme 
+      --------------: 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+      Akt.Datei:                    Manager:                        Datum: 22.07.87 
+___________________________________________________________________________________________ 
+ 
+ 
+#center#Abb. 3-1   EUDAS-Eingangsmenü 
+ 
+ 
+    Zunächst müssen Sie eine neue Datei einrichten. Dazu tippen
+Sie die Leertaste. Dadurch wird die invers dargestellte Funktion
+'Öffnen' ausgeführt. Folgen Sie bitte dem nachstehenden Dialog auf
+der rechten Bildschirmseite: 
+ 
+ 
+        Name der Datei: #on ("i")#Mitglieder#off("i")#<RET> 
+        "Mitglieder" neu einrichten ? (j/n) #on("i")#j#off("i")# 
+ 
+ 
+Unter der Überschrift 'Neue Feldnamen' tippen Sie jetzt folgendes
+(bitte keine Leerstellen vor den Namen tippen): 
+ 
+ 
+        #on("i")#Name#off("i")#<RET> 
+        #on("i")#Vorname#off("i")#<RET> 
+        #on("i")#PLZ#off("i")#<RET> 
+        #on("i")#Ort#off("i")#<RET> 
+        #on("i")#Strasse#off("i")#<RET> 
+        #on("i")#m/w#off("i")#<ESC>#on("i")#q#off("i")# 
+ 
+ 
+Zum Schluß beantworten Sie noch eine Frage: 
+ 
+ 
+        Feldnamen oder Feldtypen aendern ? (j/n) #on("i")#n#off("i")# 
+ 
+ 
+Damit ist die neue Datei eingerichtet. 
+    Nun tippen Sie die Pfeiltaste <RECHTS>. Es erscheint ein neues
+Menübild (s. Abb. 3-2). 
+ 
+___________________________________________________________________________________________ 
+ 
+      EUDAS:   Öffnen   Einzelsatz   Gesamtdatei   Drucken   Dateien   Archiv 
+      --------------: Satz 1        .........ENDE... Mitglieder .......... Feld 1 
+      Positionieren : Name 
+      W Weiter      : Vorname 
+      Z Zurück      : PLZ 
+      N Satz.Nr     : Ort 
+      --------------: Strasse 
+      Suchbedingung : m/w 
+      S Setzen      : ........................................................... 
+      L Löschen     : 
+      M Markierung  : 
+      --------------: 
+      Datensatz     : 
+      E Einfügen    : 
+      A Ändern      : 
+      T Tragen      : 
+      H Holen       : 
+      --------------: 
+      F Feldauswahl : 
+      --------------: 
+                    : 
+                    : 
+                    : 
+ 
+___________________________________________________________________________________________ 
+ 
+ 
+#center#Abb. 3-2   Menü 'Einzelsatz' 
+ 
+ 
+Nun tippen Sie so lange die Pfeiltaste <UNTEN>, bis die Funktion
+'Einfügen' invers markiert ist. Dann tippen Sie die Leertaste zum Aus­
+führen dieser Funktion. Die Schreibmarke springt nach rechts ins
+Datenfeld zum Eingeben. Geben Sie jetzt den ersten Datensatz wie
+folgt ein: 
+ 
+ 
+        #on("i")#Wegner#off("i")#<RET> 
+        #on("i")#Herbert#off("i")#<RET> 
+        #on("i")#5000#off("i")#<RET> 
+        #on("i")#Köln#off("i")#<RET> 
+        #on("i")#Krämergasse 12#off("i")#<RET> 
+        #on("i")#m#off("i")#<ESC>#on("i")#w#off("i")# 
+ 
+ 
+Anschließend wird das Datenfeld wieder freigemacht, so daß Sie
+gleich den zweiten Datensatz eingeben können. Dies tun Sie auf die
+gleiche Weise, nur mit anderen Daten: 
+ 
+ 
+        #on("i")#Sandmann#off("i")#<RET> 
+        #on("i")#Helga#off("i")#<RET> 
+        #on("i")#5300#off("i")#<RET> 
+        #on("i")#Bonn 1#off("i")#<RET> 
+        #on("i")#Willicher Weg 109#off("i")#<RET> 
+        #on("i")#w#off("i")#<ESC>#on("i")#w#off("i")# 
+ 
+ 
+Ebenso verfahren Sie dann weiter mit den folgenden Daten. Falls Sie
+sich vertippt haben, können Sie mit den vier Pfeiltasten an die
+entsprechende Stelle gehen und die falschen Buchstaben über­
+schreiben. 
+ 
+ 
+        #on("i")#Katani#off("i")#<RET> 
+        #on("i")#Albert#off("i")#<RET> 
+        #on("i")#5210#off("i")#<RET> 
+        #on("i")#Troisdorf#off("i")#<RET> 
+        #on("i")#Lindenstr. 3#off("i")#<RET> 
+        #on("i")#m#off("i")#<ESC>#on("i")#w#off("i")# 
+ 
+        #on("i")#Ulmen#off("i")#<RET> 
+        #on("i")#Peter#off("i")#<RET> 
+        #on("i")#5#off("i")#<RET> 
+        #on("i")#Köln 60#off("i")#<RET> 
+        #on("i")#Mozartstraße 17#off("i")#<RET> 
+        #on("i")#m#off("i")#<ESC>#on("i")#w#off("i")# 
+ 
+        #on("i")#Regmann#off("i")#<RET> 
+        #on("i")#Karin#off("i")#<RET> 
+        #on("i")#5000#off("i")#<RET> 
+        #on("i")#Köln 90#off("i")#<RET> 
+        #on("i")#Grengelweg 44#off("i")#<RET> 
+        #on("i")#w#off("i")#<ESC>#on("i")#w#off("i")# 
+ 
+        #on("i")#Arken#off("i")#<RET> 
+        #on("i")#Hubert#off("i")#<RET> 
+        #on("i")#5200#off("i")#<RET> 
+        #on("i")#Siegburg#off("i")#<RET> 
+        #on("i")#Talweg 12#off("i")#<RET> 
+        #on("i")#m#off("i")#<ESC>#on("i")#w#off("i")# 
+ 
+        #on("i")#Simmern#off("i")#<RET> 
+        #on("i")#Anna-Maria#off("i")#<RET> 
+        #on("i")#5#off("i")#<RET> 
+        #on("i")#Köln 3#off("i")#<RET> 
+        #on("i")#Platanenweg 67#off("i")#<RET> 
+        #on("i")#w#off("i")#<ESC>#on("i")#w#off("i")# 
+ 
+        #on("i")#Kaufmann-Drescher#off("i")#<RET> 
+        #on("i")#Angelika#off("i")#<RET> 
+        #on("i")#53#off("i")#<RET> 
+        #on("i")#Bonn#off("i")#<RET> 
+        #on("i")#Hauptstr. 123#off("i")#<RET> 
+        #on("i")#w#off("i")#<ESC>#on("i")#w#off("i")# 
+ 
+        #on("i")#Fuhrmann#off("i")#<RET> 
+        #on("i")#Harald#off("i")#<RET> 
+        #on("i")#5000#off("i")#<RET> 
+        #on("i")#Köln 1#off("i")#<RET> 
+        #on("i")#Glockengasse 44#off("i")#<RET> 
+        #on("i")#m#off("i")#<ESC>#on("i")#w#off("i")# 
+ 
+ 
+Bei der letzten Adresse ist die letzte Taste unterschiedlich, da Sie
+keine weiteren Daten mehr eintragen wollen. Bitte beachten Sie dies. 
+ 
+ 
+        #on("i")#Seefeld#off("i")#<RET> 
+        #on("i")#Friedrich#off("i")#<RET> 
+        #on("i")#5000#off("i")#<RET> 
+        #on("i")#Köln-Ehrenfeld#off("i")#<RET> 
+        #on("i")#Kabelgasse#off("i")#<RET> 
+        #on("i")#m#off("i")#<ESC>#on("i")#q#off("i")# 
+ 
+ 
+Damit die neu eingetragenen Daten permanent gespeichert sind,
+müssen Sie sie #on("i")#sichern#off("i")#. Dazu kehren Sie durch Tippen von <LINKS>
+in das erste Menü zurück. Dort tippen Sie wieder so lange <UNTEN>,
+bis die Funktion 'Sichern' markiert ist. Tippen Sie dann die Leer­
+taste zum Ausführen und folgen dem nachstehenden Dialog: 
+ 
+ 
+        Arbeitskopie "Mitglieder" veraendert! Sichern ? (j/n) #on("i")#j#off("i")# 
+        Alte Version ueberschreiben ? (j/n) #on("i")#j#off("i")# 
+        Interne Arbeitskopien loeschen ? (j/n) #on("i")#j#off("i")# 
+ 
+ 
+Damit steht Ihnen nun eine Mitgliederdatei mit 10 Einträgen zur
+weiteren Verfügung. 
+ 
+ 
+3.3 Daten abfragen 
+ 
+Um Daten abzufragen, müssen Sie die Datei zunächst wieder öffnen.
+Dazu bewegen Sie die inverse Markierung durch mehrmaliges Tippen
+von <OBEN> nach oben bis zur Funktion 'Öffnen' und tippen Sie die
+Leertaste. Danach ergibt sich folgender Dialog: 
+ 
+ 
+        Name der Datei: #on("i")#Mitglieder#off("i")#<RET> 
+        Wollen Sie etwas aendern (eine Arbeitskopie einrichten) 
+                                                 ? (j/n) #on("i")#n#off("i")# 
+ 
+ 
+Danach gehen Sie durch Tippen von <RECHTS> in das zweite Menü.
+Dort erscheint jetzt die zehnte Adresse. 
+    Zunächst sollen Sie an den Anfang gehen. Dazu schieben Sie
+die Markierung auf die Funktion 'Satz.Nr' mit Hilfe der Pfeiltasten
+und tippen dann die Leertaste. Nach folgender Angabe 
+ 
+ 
+        Neue Satznummer: #on("i")#1#off("i")#<RET> 
+ 
+ 
+erscheint die erste Adresse. Nun sollen Sie nach der Adresse von
+Harald Fuhrmann suchen. Dazu bringen Sie die Markierung auf die
+Funktion 'Suchbedingung Setzen' und tippen die Leertaste. Die
+Schreibmarke springt wieder in das Datenfeld. Dort geben Sie ein: 
+ 
+ 
+        #on("i")#Fuhrmann#off("i")#<ESC>#on("i")#q#off("i")# 
+ 
+ 
+In der markierten Überschrift erscheint 'SUCH-' zum Zeichen, daß
+eine Suchbedingung eingestellt ist. Dann schieben Sie die Markie­
+rung auf die Funktion 'Weiter' und tippen die Leertaste. Kurz da­
+nach erscheint die Adresse von Herrn Fuhrmann mit dem Hinweis
+'SUCH+' (gefunden). 
+    Führen Sie dann die Funktion 'Zurück' aus (Verschieben der
+Markierung und Tippen der Leertaste). Es erscheint wieder die erste
+Adresse mit dem Hinweis 'SUCH-' (kein weiterer Fuhrmann gefun­
+den). Führen Sie dann die Funktion `Suchbedingung Löschen' aus.
+Der 'SUCH'-Hinweis verschwindet wieder. 
+    Als nächstes sollen Sie die Daten nach allen weiblichen Mit­
+gliedern durchsuchen. Dazu führen Sie wieder die Funktion 'Such­
+bedingung Setzen' aus. Diesmal tippen Sie im Datenfeld fünfmal die
+Pfeiltaste <UNTEN>, bis die Schreibmarke neben der Bezeichnung
+'m/w' steht. Dort tippen Sie 
+ 
+ 
+        #on("i")#w#off("i")#<ESC>#on("i")#q#off("i")# 
+ 
+ 
+Wenn Sie jetzt die Funktion 'Weiter' ausführen, erscheint das erste
+weibliche Mitglied, Frau Sandmann. Da aber noch weitere Frauen in
+der Datei vorkommen, führen Sie erneut 'Weiter' aus und es erschei­
+nen die nächsten weiblichen Mitglieder. 
+    Wenn kein gesuchtes Mitglied mehr gefunden wurde, erscheint
+ein leeres Datenfeld mit den Bezeichnungen 'ENDE' und 'SUCH-' in
+der Überschrift. Durch mehrmaliges Ausführen von 'Zurück' können
+Sie die weiblichen Mitglieder wieder in der umgekehrten Reihenfolge
+ansehen, bis Sie an den Anfang der Datei kommen. 
+    Bitte lassen Sie die Suchbedingung eingestellt, denn im näch­
+sten Abschnitt wollen wir alle weiblichen Mitglieder ausdrucken. 
+ 
+ 
+3.4 Drucken 
+ 
+Zuerst begeben Sie sich durch zweimaliges Tippen von <RECHTS> in
+das Druckmenü, das in Abb. 3-3 gezeigt wird. 
+ 
+___________________________________________________________________________________________ 
+ 
+      EUDAS:   Öffnen   Einzelsatz   Gesamtdatei   Drucken   Dateien   Archiv 
+      --------------: 
+      Satzauswahl   : 
+      D Drucken     : 
+      --------------: 
+      Druckausgabe  : 
+      R Richtung    : 
+      --------------: 
+      Textdatei     : 
+      E Editieren   : 
+      A Ausdrucken  : 
+      N Nachbearb.  : 
+      --------------: 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+      Akt.Datei: "Mitglieder"                                       Datum: 22.07.87 
+___________________________________________________________________________________________ 
+ 
+ 
+#center#Abb. 3-3   Menü 'Drucken' 
+ 
+ 
+Zunächst müssen Sie ein Druckmuster erstellen, das angibt, wie der
+Druck aussehen soll. Dazu führen Sie die Funktion 'Textdatei Edi­
+tieren' aus. Es erscheint die Aufforderung: 
+ 
+ 
+        Name der Datei: #on("i")#liste#off("i")#<RET> 
+ 
+ 
+Dann wird der Bildschirm gelöscht und Sie können folgendes einge­
+ben: 
+ 
+ 
+        #on("i")#% VORSPANN#off ("i")#<RET> 
+        #on("i")#Liste der weiblichen Mitglieder#off ("i")#<RET> 
+        #on("i")#-------------------------------#off ("i")#<RET> 
+        #on("i")#% WIEDERHOLUNG#off ("i")#<RET> 
+        #on("i")#&Vorname %Name#off ("i")#<ESC>#on("i")#q#off("i")# 
+ 
+ 
+Ebenso wie beim Eingeben von Daten können Sie hier mit den Pfeil­
+tasten auf fehlerhafte Stellen zurückgehen und dort korrigieren. 
+    Nun sollten Sie sich vergewissern, ob Ihr Drucker eingeschaltet
+und bereit (Ready) ist. Falls Sie keinen Drucker haben, folgen Sie
+bitte den Anweisungen unter 2. Anderenfalls gehen Sie wie folgt
+vor. 
+ 
+1. Rufen Sie die Funktion 'Richtung' auf und beantworten Sie
+   folgende Frage: 
+ 
+ 
+        Ausgabe automatisch zum Drucker ? (j/n) #on("i")#j#off("i")# 
+ 
+ 
+   Dann rufen Sie die Funktion 'Drucken' auf und geben den Namen
+   des Druckmusters an: 
+ 
+ 
+        Name des Druckmusters: #on("i")#liste#off ("i")#<RET> 
+ 
+ 
+   Als Ergebnis sollte folgende Liste auf Ihrem Drucker erscheinen: 
+ 
+ 
+        Liste der weiblichen Mitglieder 
+        ------------------------------- 
+        Helga Sandmann 
+        Karin Regmann 
+        Anna-Maria Simmern 
+        Angelika Kaufmann-Drescher 
+ 
+ 
+2. Rufen Sie die Funktion 'Richtung' auf und beantworten Sie
+   folgende Fragen: 
+ 
+ 
+        Ausgabe automatisch zum Drucker ? (j/n) #on("i")#n#off("i")# 
+        Ausgabe in bestimmte Datei ? (j/n) #on("i")#n#off("i")# 
+ 
+ 
+   Dann rufen Sie die Funktion 'Drucken' auf und geben den Namen
+   des Druckmusters an: 
+ 
+ 
+        Name des Druckmusters: #on("i")#liste#off ("i")#<RET> 
+ 
+ 
+   Nach dem Ende des Druckprozesses (wenn das Sternchen vor
+   'Drucken' wieder durch ein 'D' ersetzt worden ist), rufen Sie
+   wieder die Funktion 'Textdatei Editieren' auf und geben folgen­
+   den Namen an: 
+ 
+ 
+        Name der Datei: #on("i")#liste.a$1#off("i")#<RET> 
+ 
+ 
+   Es erscheint die gleiche Ausgabe wie unter 1 beschrieben auf
+   dem Bildschirm. Wenn Sie die Ausgabe genug gesehen haben,
+   kehren Sie durch 
+ 
+ 
+        <ESC>#on("i")#q#off("i")# 
+ 
+ 
+   wieder in das Menü zurück. 
+ 
+ 
+3.5 Ergebnis
+ 
+Da Sie sich wieder im Menü befinden, könne Sie EUDAS durch 
+ 
+        <ESC>#on("i")#q#off("i")# 
+ 
+wieder verlassen. Danach können Sie Ihre Sitzung beenden, etwas
+Anderes tun oder EUDAS erneut aufrufen. 
+ 
+    Sie haben nun selbst ausprobiert, wie Sie unter EUDAS Daten
+eingeben können, wie Sie diese Daten abrufen und in ihnen suchen
+können. Sie haben die Daten auch schon ausgedruckt. 
+    Damit Sie besser verstehen, was Sie soeben gemacht haben,
+werden Sie in den folgenden vier Kapiteln die Grundfunktionen von
+EUDAS mit den dazugehörigen Erläuterungen kennenlernen. 
+    Danach können Sie dann selber Ihre eigene Anwendung entwer­
+fen und EUDAS zu Ihrer Arbeitserleichterung einsetzen. 
+
+
+
+
+
+
diff --git a/doc/eudas/eudas.hdb.5 b/doc/eudas/eudas.hdb.5
new file mode 100644
index 0000000..b5927ea
--- /dev/null
+++ b/doc/eudas/eudas.hdb.5
@@ -0,0 +1,386 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (43)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+5 Gespeicherte Daten abfragen 
+ 
+ 
+ 
+5.1 Öffnen 
+ 
+Als letzte Vorbereitung, bevor Sie mit der Adreßdatei spielen kön­
+nen, müssen Sie die Datei wie einen Karteikasten #on("i")#öffnen#off("i")#. Nach dem
+Öffnen beziehen sich alle weiteren Funktionen auf die gerade ge­
+öffnete Datei. Aus diesem Grund darf auch immer nur eine einzige
+Datei geöffnet sein - als hätte auf Ihrem Schreibtisch nur ein Kar­
+teikasten Platz. 
+    Dazu wählen Sie jetzt wieder das erste Menü an. Dort finden
+Sie die Funktion 
+#free (0.2)# 
+ 
+        O Öffnen 
+ 
+#free (0.2)# 
+Wählen Sie diese Funktion aus. Dann drücken Sie die Leertaste, um
+die Funktion auszuführen. Als erstes erscheint im unteren Teil des
+Bildschirms eine Frage: 
+ 
+___________________________________________________________________________________________ 
+ 
+      Wollen Sie etwas aendern (eine Arbeitskopie anlegen) (j/n) ? 
+___________________________________________________________________________________________ 
+ 
+ 
+Der Cursor bleibt hinter der Frage stehen. Sie kennen diesen Frage­
+zustand ja schon. 
+    In diesem Fall wollen Sie an der Spieldatei nichts verändern,
+Sie beantworten die Frage also mit einem 'n'. Als nächstes werden
+Sie nach dem Namen gefragt (Beachten Sie auch hier wieder die
+Statuszeile). 
+    Tippen Sie nun 'Adressen' und beenden Sie die Eingabe mit
+RETURN. EUDAS öffnet die Datei und kehrt zum Menü zurück. Alter­
+nativ können Sie die Datei auch in einer Auswahl ankreuzen, wenn
+Sie ESC 'z' tippen. 
+ 
+#on("b")#Fußzeile#off("b")# Nach der Ausführung dieser Funktion sollten Sie
+Ihre
+Aufmerksamkeit auf die letzte Zeile des Bildschirms richten. Hier
+finden Sie jetzt folgendes vor: 
+ 
+___________________________________________________________________________________________ 
+ 
+      Akt.Datei: "Adressen"         Manager:                        Datum: 22.07.87 
+___________________________________________________________________________________________ 
+ 
+ 
+Neben dem Datum und dem eingestellten Manager (dies kommt viel
+später) sehen Sie hier, welche Datei Sie geöffnet haben und nun
+bearbeiten können. Diese Fußzeile finden Sie auch in den ande­
+ren Menüs. Lediglich die mittlere Angabe ändert sich bei den ande­
+ren Menüs (eine Erläuterung dazu finden Sie in späteren Kapiteln). 
+ 
+#on("b")#Anzeige#off("b")# Zum Anzeigen der Daten in der Adreßdatei müssen Sie
+das
+zweite Menü 'Einzelsatz' anwählen (durch Drücken der Pfeiltaste
+RECHTS). Am linken Rand erscheint das neue Menü mit den Anzei­
+gefunktionen. Der Rest des Bildschirms enthält das Formular für die
+Adreßdatei mit den Daten des ersten Satzes. Abbildung 5-1 zeigt
+das Bild, das sich dann ergibt. 
+ 
+___________________________________________________________________________________________ 
+ 
+      EUDAS:   Öffnen   Einzelsatz   Gesamtdatei   Drucken   Dateien   Archiv 
+      --------------: Satz 1    ................... Adressen ....... Zeile 1 
+      Positionieren : Name     Wegner 
+      W Weiter      : Vorname  Herbert 
+      Z Zurück      : PLZ      5000 
+      N Satz.Nr     : Ort      Köln 
+      --------------: Strasse  Krämergasse 12 
+      Suchbedingung : m/w      m 
+      S Setzen      : ........................................................... 
+      L Löschen     : 
+      M Markierung  : 
+      --------------: 
+      Datensatz     : 
+      - Einfügen    : 
+      - Ändern      : 
+      - Tragen      : 
+      - Holen       : 
+      --------------: 
+      F Feldauswahl : 
+      --------------: 
+                    : 
+                    : 
+                    : 
+ 
+___________________________________________________________________________________________ 
+ 
+ 
+#center#Abb. 5-1   Menü 'Einzelsatz' 
+ 
+ 
+Das automatisch generierte Formular zeigt immer genau einen Satz.
+Das Formular besteht aus drei Teilen: der Überschrift, dem Feldteil
+und der Abschlußzeile. In der #on("i")#Überschrift#off("i")# steht der Name der Datei
+("Adressen"), die Satznummer (1) und die Nummer der ersten ange­
+zeigten Zeile (immer 1, außer wenn die Datei mehr Felder hat, als
+auf den Bildschirm passen). In manchen Fällen können auch noch
+weitere Informationen dort auftauchen, wie wir später sehen wer­
+den. 
+    Im #on("i")#Feldteil#off("i")# befindet sich der eigentliche Inhalt, und zwar sind
+links markiert die Feldnamen zu sehen, während rechts die zugehö­
+rigen Inhalte des betreffenden Satzes stehen. Dieses Bild ähnelt
+einer Karteikarte mit einem festen Format. 
+    Die #on("i")#Abschlußzeile#off("i")# am Ende gibt an, daß für diesen Satz keine
+weiteren Informationen mehr vorhanden sind. Wir werden aber spä­
+ter noch sehen, wie man anderenfalls die restlichen Informatio­
+nen sichtbar machen kann. 
+ 
+ 
+5.2 Bewegen 
+ 
+Nun wollen Sie nicht immer nur einen Satz betrachten (das wäre ja
+furchtbar langweilig). Daher müssen Sie die Möglichkeit haben, sich
+in der Datei zu "bewegen". Dies geschieht mit Hilfe der beiden
+Funktionen 
+#free (0.2)# 
+ 
+        W Weiter 
+ 
+#free (0.2)# 
+und 
+#free (0.2)# 
+ 
+        Z Zurück 
+ 
+#free (0.2)# 
+Sie haben die Wirkung, daß der Satz mit der nächsthöheren bzw.
+nächstniedrigeren Satznummer angezeigt wird. Natürlich funktioniert
+dies nur, wenn noch ein Satz vorhanden ist: am Anfang (Satz 1)
+können Sie nicht zurückgehen. In diesem Fall ignoriert EUDAS Ihren
+Befehl einfach. 
+    Wenn Sie bis zum Ende der Datei gehen (keine Angst - diese
+Datei enthält nur 10 Sätze), werden Sie feststellen, daß zum Schluß
+ein ganz leerer Satz erscheint. Dieser Satz ist eine Art Endemarkie­
+rung; er informiert Sie, daß keine weiteren Sätze vorhanden sind.
+Dieser Satz ist aber kein richtiger Satz, daher wird in der Über­
+schrift 'ENDE' angezeigt. (Wenn Ihnen diese Art Endemarkierung
+merkwürdig erscheint: sie hat schon einen triftigen Grund, s.6.2). 
+    Um einen Satz mit bekannter Satznummer gezielt anzuwählen,
+können Sie die Funktion 
+#free (0.2)# 
+ 
+        N Satz.Nr 
+ 
+#free (0.2)# 
+verwenden. Sie müssen anschließend die Satznummer eingeben (Bitte
+mit RETURN beenden). Ist der Satz vorhanden, erscheint dieser,
+ansonsten stehen Sie am Ende der Datei. 
+ 
+#on("b")#Aufruf über Buchstaben#off("b")# Vielleicht ist Ihnen inzwischen
+schon
+aufgefallen, daß vor jeder Funktion in einem Menü ein Buchstabe
+steht. Damit hat es folgendes auf sich: da das Positionieren des
+Cursors zum Auswählen einer Funktion mehrere Tastendrücke erfor­
+dern kann, haben Sie die Möglichkeit, jede Funktion auch über
+einen Buchstaben auszuführen. 
+    Dies ist besonders dann sinnvoll, wenn Sie mit den eben be­
+sprochenen Funktionen schnell in der Datei "blättern" wollen. An­
+dererseits müssen Sie sich aber für eine schnelle Reaktion auch
+einige der Tasten merken. Für die Praxis empfiehlt sich folgender
+Kompromiß: die meistgebrauchten Funktionen über Buchstaben und
+der Rest durch Positionieren im Menü. 
+ 
+ 
+5.3 Suchen 
+ 
+Stellen Sie sich vor, die Datei wäre größer und Sie müßten eine
+bestimmte Adresse heraussuchen. Dazu würden Sie durch die ganze
+Datei durchgehen, bis die gewünschte Adresse erscheint. Das wäre
+natürlich bei vielen Adressen eine ungeheuer mühselige Arbeit, die
+mit einem Karteikasten wahrscheinlich schneller zu erledigen wäre. 
+    EUDAS bietet Ihnen jedoch die Möglichkeit, nach bestimmten
+Sätzen zu suchen. Dazu müssen Sie angeben, wonach gesucht werden
+soll. Als Beispiel wollen wir die Adresse von Frau Simmern su­
+chen. Bewegen Sie sich zunächst zurück bis auf den ersten Satz.
+Dann wählen Sie die Funktion 
+#free (0.2)# 
+ 
+        Suchbedingung 
+        S Setzen 
+ 
+#free (0.2)# 
+Auf dem Bildschirm verschwinden die Feldinhalte und der Cursor
+steht hinter dem ersten Feldnamen. Dies bedeutet, daß Sie neben
+die Feldnamen etwas schreiben können. Auch in der Statuszeile
+erscheint statt der Anzeige der Menünamen ein Hinweis auf die
+Eingabemöglichkeit (s. Abb. 5-2). Sie befinden sich jetzt in einem
+Zustand, in dem Sie hinter die Feldnamen etwas schreiben können
+(dem sogenannten #on("i")#Satzeditor#off("i")#). 
+    Als Angabe, was gesucht werden soll, schreiben Sie jetzt in der
+ersten Zeile neben 'Name' die Bedingung 'Simmern'. Sie haben jetzt
+ein einfaches #on("i")#Suchmuster#off("i")# angegeben. Ein Suchmuster besteht aus
+Bedingungen, die neben die Feldnamen geschrieben werden. Unser
+einfaches Suchmuster lautet übersetzt: 
+ 
+    Wähle alle Sätze aus, bei denen 'Simmern' im Feld 'Name'
+    steht. 
+ 
+Beenden Sie die Eingabe des Suchmusters mit ESC 'q'. Es erscheint
+wieder das vorherige Bild, mit dem Unterschied, daß jetzt in der
+Überschrift ein 'SUCH-' auftaucht. EUDAS steht immer noch auf dem
+ersten Satz. 
+    Die Anzeige 'SUCH' gibt an, daß ein Suchmuster eingestellt
+wurde. Das Minuszeichen bedeutet, daß der aktuelle Satz die Such­
+bedingung jedoch #on("i")#nicht#off("i")# erfüllt. 
+ 
+___________________________________________________________________________________________ 
+ 
+      SUCHMUSTER EINGEBEN:    Abbruch: ESC h    Beenden: ESC q    Hilfe: ESC ? 
+      --------------: Satz 1    .................... ............... Zeile 1 
+      Positionieren : Name     Simmern 
+      W Weiter      : Vorname 
+      Z Zurück      : PLZ 
+      N Satz.Nr     : Ort 
+      --------------: Strasse 
+      Suchbedingung : m/w 
+      * Setzen      : ........................................................... 
+      L Löschen     : 
+      M Markierung  : 
+      --------------: 
+      Datensatz     : 
+      - Einfügen    : 
+      - Ändern      : 
+      - Tragen      : 
+      - Holen       : 
+      --------------: 
+      F Feldauswahl : 
+      --------------: 
+                    : 
+                    : 
+___________________________________________________________________________________________ 
+ 
+ 
+#center#Abb. 5-2  Eingabe eines Suchmusters 
+ 
+ 
+#on("b")#Positionierung#off("b")# Das Suchen beginnt erst, wenn Sie sich in
+der Datei
+bewegen. In diesem Fall erhalten die Funktionen 'Satz weiter' und
+'Satz zurück' eine etwas geänderte Bedeutung. Sie gehen nämlich
+nicht einfach zum nächsten bzw. vorigen Satz, sondern zum näch­
+sten bzw. vorigen Satz. 
+    Als Indikator, daß Sie sich auf dem gesuchten Satz befinden,
+dient die Anzeige 'SUCH+'. Probieren Sie dies jetzt aus, indem Sie
+weitergehen. Als nächster Satz erscheint der gewünschte Satz 7. Die
+nicht ausgewählten Sätze wurden also übersprungen. Das gleiche
+passiert, wenn Sie noch weiter gehen. Da kein passender Satz mehr
+vorhanden ist, erscheint der leere Endesatz. 
+ 
+#limit (12.0)# 
+    Denken Sie daran, daß das Einstellen der Suchbedingung
+    noch keine Suche bewirkt. Diese müssen Sie selbst
+    durch Positionieren mit 'Weiter' oder 'Zurück' auslösen. 
+#limit (13.5)# 
+ 
+Sollten Sie sich nicht am Anfang der Datei befinden, wenn Sie eine
+Suchbedingung einstellen, kann es sein, daß sich der gesuchte Satz
+vor oder hinter der aktuellen Position befindet. In diesem Fall
+müssen Sie entscheiden, ob Sie vorwärts oder rückwärts gehen.
+Wenn Sie rückwärts gehen und der Satz ist nicht in diesem Ab­
+schnitt, erscheint der erste Satz mit der Anzeige 'SUCH-'. Gehen Sie
+dann wieder vorwärts, finden Sie den Satz auf jeden Fall. 
+    Die Funktion 'Satz.Nr' richtet sich natürlich nicht nach der
+eingestellten Bedingung, da Sie ja eine bestimmte Satznummer wün­
+schen. Aus der 'SUCH'-Anzeige können Sie jedoch entnehmen, ob
+die Suchbedingung auf diesen Satz zutrifft. 
+ 
+#on("b")#Suchbedingung löschen#off("b")# Wollen Sie wieder alle Sätze sehen,
+müssen Sie die Funktion 
+#free (0.2)# 
+ 
+        Suchbedingung 
+        L Löschen 
+ 
+#free (0.2)# 
+auswählen. Die Anzeige 'SUCH' verschwindet wieder, um anzudeu­
+ten, daß keine Suchbedingung mehr eingestellt ist. 
+ 
+#on("b")#Beispiel#off("b")# Um den Charakter einer Selektion nochmal deutlich
+zu
+machen, sollen Sie jetzt eine Bedingung einstellen, die auf mehrere
+Sätze zutrifft. Dies hätte uns auch eben passieren können, wenn es
+mehrere Simmern gegeben hätte. Wir können zum Beispiel alle weib­
+lichen Personen auswählen. 
+    Als erstes löschen Sie die alte Suchbedingung. Tun Sie dies
+nicht, wird Ihnen beim nächsten Eingeben das alte Suchmuster zum
+Ändern angeboten. Dies ist praktisch, wenn ein Suchmuster nicht
+den erhofften Erfolg brachte und Sie es modifizieren wollen. 
+    Danach wählen Sie erneut die Funktion 'Suchbedingung setzen'.
+Nun bewegen Sie den Cursor mit der Pfeiltaste UNTEN neben den
+Feldnamen 'm/w'. Dort tragen Sie die Bedingung 'w' ein. Verlassen
+Sie die Eingabe mit ESC 'q'. 
+    Wenn Sie sich jetzt in der Datei bewegen, sehen Sie, daß immer
+nur weibliche Personen angezeigt werden - die männlichen werden
+unterdrückt (in Umkehrung der Realität). 
+ 
+ 
+              !  1  !     !  3  !  4  !     !  6  ! 
+        +-----+-----+-----+-----+-----+-----+-----+ 
+        !Name ! ..  !     ! ..  ! ..  !     ! ..  ! 
+        !     !     !     !     !     !     !     ! 
+           :     :           :     :           : 
+        !     !     !     !     !     !     !     ! 
+        !m/w  ! w   !     ! w   ! w   !     ! w   ! 
+        +-----+-----+     +-----+-----+     +-----+ 
+ 
+#center#Abb. 5-3  Wirkung einer Selektion 
+ 
+ 
+ 
+5.4 Suchbedingungen 
+ 
+Im letzten Abschnitt haben Sie gesehen, wie das Einstellen einer
+Suchbedingung funktioniert. In diesem Abschnitt sollen Sie weitere
+Möglichkeiten zur Formulierung von Suchmustern kennenlernen. 
+    Die erste Möglichkeit kennen Sie schon. Wenn neben einen
+Feldnamen ein Text geschrieben wird, bedeutet dies, daß ausge­
+wählte Sätze im Inhalt dieses Feldes mit dem Text übereinstimmen
+müssen. 
+ 
+#on("b")#Kombination#off("b")# Nun kann es sein, daß mehrere Bedingungen
+gelten
+müssen. Im ersten Beispiel des vorigen Abschnitts hätten wir zum
+Beispiel auch noch den Vornamen 'Anna-Maria' angeben können, um
+bei mehreren Simmern die richtige auszuwählen. Wird also in mehre­
+re Felder eine Bedingung geschrieben, müssen alle diese Bedingun­
+gen gleichzeitig zutreffen. 
+    Würden Sie in unserem Beispiel noch als dritte Bedingung 'm'
+für das Feld 'm/w' angeben, würde gar kein Satz mehr ausgewählt,
+da Anna-Maria Simmern natürlich nicht männlich ist. Auch das
+kann also passieren. 
+ 
+ 
+        Name     Simmern 
+        Vorname  Anna-Maria 
+        .. 
+        .. 
+        m/w      m 
+ 
+#center#Abb. 5-4   Kombination von Bedingungen 
+ 
+ 
+#on("b")#Stern#off("b")# Die Bedingungen, die wir bis jetzt kennengelernt
+haben,
+müssen alle ganz exakt zutreffen. Häufig tritt aber der Fall auf,
+daß der gesuchte Name nicht genau bekannt ist. In diesem Fall
+kann der Name im Suchmuster auch teilweise eingegeben werden.
+Der unbekannte Teil am Anfang oder am Ende wird einfach durch
+einen Stern markiert. 
+    Wenn Sie also als Bedingung 'Sim*' für den Namen angeben, so
+würde dies auf den Namen Simmern zutreffen, aber zum Beispiel
+auch auf Simmerath oder Simon. Die Bedingung '*mern' würde nicht
+nur auf Simmern zutreffen, sondern auch auf Pommern. 
+    Der Stern kann aber auch für einen leeren Text stehen. So
+trifft 'Simmern*' auf Simmern zu, aber auch auf Doppelnamen. die
+mit Simmern beginnen. Wissen Sie jetzt nicht, ob Simmern in dem
+Doppelnamen vorne oder hinten erscheint, können Sie auch an bei­
+den Seiten einen Stern machen. Die Bedingung '*Simmern*' trifft
+nicht nur auf Simmern, sondern sowohl auf Deckerath-Simmern als
+auch auf Simmern-Jakob zu. 
+    Es gibt noch eine Reihe von weiteren Möglichkeiten, Bedingun­
+gen im Suchmuster zu formulieren. Auch komplexe Kombinationen
+von Bedingungen sind möglich. Mit dem bisher Besprochenen sollten
+Sie aber in vielen Fällen auskommen. Die übrigen Möglichkeiten
+werden in Abschnitt 10.2 erklärt. Schauen Sie bei Bedarf dort nach. 
+ 
+
diff --git a/doc/eudas/eudas.hdb.6 b/doc/eudas/eudas.hdb.6
new file mode 100644
index 0000000..e617881
--- /dev/null
+++ b/doc/eudas/eudas.hdb.6
@@ -0,0 +1,394 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (51)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+6 Daten eingeben und ändern 
+ 
+ 
+ 
+6.1 Neue Datei einrichten 
+ 
+Nachdem Sie sich bis jetzt an einer existierenden Datei erprobt
+haben, können Sie nun dazu übergehen, eine eigene neue Datei
+einzurichten. Als Beispiel sollen Sie ein kleines Telefonregister
+erstellen. 
+    Dazu gehen Sie wieder in das Menü 'Öffnen' zurück und wäh­
+len erneut die Funktion 
+#free (0.2)# 
+ 
+        O Öffnen 
+ 
+#free (0.2)# 
+indem Sie mehrmals OBEN tippen, bis die Funktion markiert. Dann
+tippen Sie die Lerrtaste zum Ausführen. Als Dateinamen geben Sie
+'Telefonnummern' an. 
+    Da die Datei 'Telefonnummern' noch nicht existiert, werden Sie
+gefragt: 
+ 
+ 
+        "Telefonnummern" neu einrichten ? (j/n) #on("i")#j#off("i")# 
+ 
+ 
+Es kann ja sein, daß Sie sich vertippt haben und eine andere,
+existierende Datei meinten. In unserem Fall wird die Datei aber
+wirklich neu eingerichtet, daher bejahen Sie die Frage. 
+ 
+#on("b")#Feldnamen eingeben#off("b")# Wenn Sie beim Öffnen eine Datei neu
+einrich­
+ten, müssen Sie zuerst die Feldnamen festlegen, zum Beispiel diese: 
+ 
+ 
+        'Name' 
+        'Vorname' 
+        'Strasse' 
+        'PLZ' 
+        'Ort' 
+        'Telefon' 
+        'Bemerkungen' 
+ 
+ 
+Ihnen wird jetzt Gelegenheit gegeben, die Feldnamen untereinander
+einzugeben. Zur Korrektur können Sie die gleichen Tasten verwen­
+den wie im Editor (beachten Sie dazu die Statuszeile am oberen
+Bildschirmrand. 
+   Geben Sie die Namen in dieser Reihenfolge ein. Tippen Sie nach
+jedem Namen die RETURN-Taste, damit der nächste Name in eine
+neue Zeile kommt. Beenden Sie die Eingabe mit ESC 'q'. 
+    Die folgende Frage ermöglicht es Ihnen, noch weitere Eigen­
+schaften der Felder festzulegen. Dies ist jedoch im Normalfall nicht
+nötig. Beantworten Sie also die Frage mit 'n'. Ihre Datei ist nun
+eingerichtet. 
+    Wie Sie sehen, besteht das Einrichten einer Datei eigentlich
+nur aus der Eingabe der Feldnamen. Wenn Sie später noch Felder
+anfügen wollen, ist dies ohne weiteres möglich. 
+ 
+ 
+6.2 Sätze Einfügen 
+ 
+Nachdem die Datei nun eingerichtet worden ist, sollen Sie zunächst
+einige Sätze eingeben. Wenn Sie wieder das Menü 'Einzelsatz' an­
+wählen, sehen Sie nur den leeren Satz mit der Anzeige 'ENDE', der
+das Dateiende markiert. Um neue Sätze aufzunehmen, gibt es die
+Funktion 
+#free (0.2)# 
+ 
+        E Einfügen 
+ 
+#free (0.2)# 
+Wenn Sie diese Funktion aufrufen, geschieht etwas Ähnliches wie
+beim Eingeben des Suchmusters. Der Cursor wandert wieder hinter
+den ersten Feldnamen und in der Statuszeile erscheint die Auffor­
+derung 
+ 
+___________________________________________________________________________________________ 
+ 
+        SATZ EINFUEGEN:   Abbruch: ESC h   Beenden: ESC q   Hilfe: ESC ? 
+___________________________________________________________________________________________ 
+ 
+ 
+Sie können nun die Feldinhalte der einzelnen Felder neben die
+entsprechenden Feldnamen schreiben. Mit der RETURN-Taste schlie­
+ßen Sie eine Zeile ab und gelangen in die nächste. 
+    Um eventuelle falsche Eingaben zu korrigieren, können Sie
+ähnlich wie im Editor mit den Pfeiltasten herumfahren und falsche
+Eingaben überschreiben. Die Taste RUBOUT löscht falsche Zeichen.
+Sie beenden die Eingabe mit ESC 'q'. Anschließend ist der neue Satz
+vorhanden. 
+ 
+ 
+#free (4.5)# 
+ 
+#center#Abb. 6-1   Einfügen 
+ 
+ 
+#on("b")#Wirkung#off("b")# Die Wirkungsweise der Funktion 'Einfügen'
+verdeutlicht
+die Abb. 6-1. Dargestellt ist ein Ausschnitt aus einer Datei mit den
+Sätzen 4 bis 7 und durch Buchstaben dargestellten, beliebigen In­
+halten. Satz 6 sei der aktuelle Satz. 
+    Beim Einfügen wird nun vor dem aktuellen Satz eine Lücke für
+den neuen Satz geschaffen, die zunächst noch leer ist und dann von
+Ihnen ausgefüllt werden muß. Die Satznummern aller folgenden Sätze
+erhöhen sich um 1. 
+    Die Leerstelle bleibt nur dann erhalten, wenn Sie Daten für den
+neuen Satz eingeben. Anderenfalls wird nach ESC 'q' wieder der alte
+Zustand hergestellt. 
+    Dieses Verfahren erklärt auch, warum das Ende der Datei ein
+leerer Pseudosatz ist. Um nämlich am Ende der Datei einen neuen
+Satz anzufügen, muß man vor dem Endesatz einen Satz einfügen. 
+    Nachdem Sie also jetzt den ersten Satz eingegeben haben,
+müssen Sie sich wieder zum Ende bewegen, damit der nächste Satz
+hinter dem ersten steht. Für diesen häufig benötigten Vorgang gibt
+es eine Abkürzung: Wenn Sie die Eingabe mit ESC 'w' (Weiter) statt
+ESC 'q' beenden, geht EUDAS nach dem Einfügen des Satzes weiter
+zum nächsten und fügt dort wieder einen Satz ein. 
+    Auf diese Weise können Sie also schnell eine ganze Reihe von
+Sätzen nacheinander eingeben. Nachdem Sie einen Satz eingegeben
+haben, tippen Sie ESC 'w' und können gleich anschließend schon mit
+der Eingabe des nächsten Satzes beginnen. Alle so eingegebenen
+Sätze erscheinen nachher in der Reihenfolge der Eingabe. 
+ 
+#on("b")#Satzeditor#off("b")# Bei der Eingabe eines neuen Satzes haben Sie
+nahezu
+alle Möglichkeiten, die auch der EUMEL-Editor bietet. Der be­
+schreibbare Bereich ist jedoch kleiner. Er umfaßt das ganze Gebiet,
+in dem sonst die Feldinhalte erscheinen. 
+    Wie beim Editor können Sie den Cursor mit den Cursortasten
+(Pfeiltasten) bewegen. Mit der Taste RUBOUT können Sie ein Zeichen
+löschen. Die restlichen Zeichen der Zeile rücken dann nach. Mit
+RUBIN dagegen schalten Sie in einen Einfügemodus um. Alle einge­
+gebenen Zeichen werden dann eingefügt - der Rest der Zeile rückt
+entsprechend nach rechts. Nochmaliges Tippen von RUBIN schaltet
+wieder in den alten Modus. Welcher Modus eingeschaltet ist, steht
+in der Überschriftzeile. 
+    Mit der Kombination ESC RUBOUT können Sie den Rest einer
+Zeile ab der Cursorposition löschen. Steht der Cursor in der ersten
+Spalte, wird dementsprechend die ganze Zeile gelöscht. Im Unter­
+schied zum EUMEL-Editor rücken die folgenden Zeilen jedoch nicht
+herauf. 
+    Entsprechend fügen Sie mit der Funktion ESC RUBIN eine neue
+Zeile ein. Dies ist immer dann erforderlich, wenn ein Feldinhalt
+nicht auf eine Zeile paßt. Der Teil der Zeile, der hinter dem Cursor
+steht, wird bei ESC RUBIN in die neue Zeile mitgenommen. 
+    Normalerweise tippen Sie ESC RUBIN, wenn Sie an das Ende
+einer Zeile kommen. Wenn Sie aber weiterschreiben, wird die Zeile
+einfach gerollt. Dies ist nicht weiter schlimm, aber Sie können den
+ganzen Feldinhalt nicht auf einmal sehen. 
+    In der normalen Anzeige wird ein überlanger Inhalt auf jeden
+Fall auf mehrere Zeilen verteilt. 
+ 
+#on("b")#Warnung#off("b")# Ein Hinweis für alle, die sich mit der
+Editorbedienung
+schon auskennen: EUDAS benutzt den Editor als Unterprogramm.
+Jedoch haben einige Editorfunktionen unliebsame Auswirkungen.
+Besonders gefährlich sind hier HOP RUBOUT und HOP RUBIN. Diese
+Funktion zerstören die Korrespondenz zwischen Feldnamen und
+Feldinhalten, das heißt der Feldinhalt steht nicht mehr neben dem
+Feldnamen. 
+    Weiterhin können Sie das Editorbild rollen, ohne daß die Feld­
+namen mitrollen (zum Beispiel wenn Sie in der untersten Zeile
+RETURN drücken). In diesem Fall ist die Korrespondenz auch nicht
+erhalten, das heißt die Inhalte stehen falsch, sind aber eigentlich
+richtig. 
+    In solchen Fällen erscheint am oberen oder unteren Rand der
+Hinweis "Bitte ESC '1' druecken". Wenn das Editorbild nur gerollt
+wurde, verschwindet durch ESC '1' der Hinweis wieder und das Bild
+ist in Ordnung. Wenn jedoch Zeilen gelöscht oder eingefügt wurden,
+müssen Sie diese Änderungen von Hand wieder rückgängig machen,
+bis der Hinweis verschwindet. Sie sollten also HOP RUBOUT und HOP
+RUBIN im Satzeditor nicht verwenden. 
+    Im Zweifelsfall, wenn Sie meinen, den Satz durcheinanderge­
+bracht zu haben, können Sie immer mit ESC 'h' abbrechen. Es steht
+dann der vorherige Zustand für einen neuen Versuch zur Verfügung. 
+ 
+ 
+6.3 Daten ändern 
+ 
+Wenn Sie nachträglich noch eingegebene Daten ändern wollen, kön­
+nen Sie die Funktion 
+#free (0.2)# 
+ 
+        A Ändern 
+ 
+#free (0.2)# 
+verwenden. Sie haben anschließend wie beim Einfügen Gelegenheit,
+neue Daten einzugeben. Allerdings werden Ihnen die bisherigen
+Daten gleich mit angeboten, so daß Sie nur die Änderungen ein­
+geben müssen. Alles andere kann unverändert bleiben. Auch diese
+Funktion wird mit ESC 'q' verlassen. ESC 'w' funktioniert beim
+Ändern ebenfalls (der nächste Satz wird zum Ändern angeboten). 
+   Stellen Sie beim Ändern oder Einfügen fest, daß Sie irgendeinen
+krassen Fehler gemacht haben, können Sie die Operation mit ESC 'h'
+abbrechen. Beim Ändern bleibt dann der alte Zustand unverändert,
+beim Einfügen wird kein Satz eingefügt. 
+ 
+#on("b")#Löschen#off("b")# Für den Fall, daß Sie einen Satz wieder ganz aus
+der
+Datei löschen wollen, hat EUDAS eine besondere Vorsichtsmaßnahme
+vorgesehen. Damit der Satz nicht gleich unwiederbringlich verloren­
+geht, müssen Sie ihn zunächst in eine andere Datei #on("i")#tragen#off("i")#. Falls
+das Löschen ein Irrtum war, können Sie den Satz von dort noch
+wiederholen. In vielen Fällen besteht ohnehin die Anforderung, daß
+auch die nicht mehr aktuellen Daten noch eine gewisse Zeit aufge­
+hoben werden müssen. 
+    Zum Tragen gibt es die Funktion 
+ 
+ 
+        Datensatz 
+        T Tragen 
+ 
+ 
+Sie werden nach einem Dateinamen gefragt. Geben Sie hier zum
+Beispiel 'müll' an. Da diese Datei noch nicht existiert, werden Sie
+gefragt, ob Sie sie neu einrichten wollen (falls Sie sich vielleicht
+verschrieben haben). Danach wird der aktuelle Satz in die Datei
+'müll' transportiert. Am Bildschirm erscheint der nächste Satz. Der
+getragene Satz kommt an das Ende der Zieldatei. 
+    Eine Bedingung beim Tragen ist, daß die Zieldatei immer die
+gleichen Felder haben muß wie die aktuelle Datei. Sie können also
+nicht aus verschieden strukturierten Dateien in die gleiche Datei
+tragen. 
+    Zum Zurückholen eines Satzes benutzen Sie die Funktion 
+ 
+ 
+        Datensatz 
+        H Holen 
+ 
+ 
+Der letzte Satz der Datei, die Sie angeben, wird vor dem aktuellen
+Satz eingefügt. Dadurch wird der Effekt des letzten Tragens wieder
+aufgehoben. 
+    Um die getragenen Sätze endgültig zu vernichten, müssen Sie
+die Zieldatei als Ganzes löschen. Die dazu notwendige Funktion aus
+dem Menü 'Dateien' haben Sie bereits in Abschnitt 4.4 kennenge­
+lernt. 
+ 
+ 
+6.4 Arbeitskopie sichern 
+ 
+Wenn Sie eine Datei zum Ändern öffnen oder sie gerade neu einge­
+richtet haben, wird von dieser Datei intern eine Arbeitskopie ange­
+legt, die dann geändert wird. Sie müssen diese Arbeitskopie nach
+den Änderungen sichern, damit die Änderungen wirksam werden. 
+    In unserem Beispiel ist die Datei "Telefonnummern" immer noch
+leer. Die Änderungen sind momentan nur in der internen Kopie
+vorhanden. Wenn Sie die Datei zum Beispiel auf eine Archivdiskette
+schreiben wollten, würden Sie eine leere Datei auf der Diskette
+haben. 
+    Zum Sichern rufen Sie die Funktion 
+#free (0.2)# 
+ 
+        S Sichern 
+ 
+#free (0.2)# 
+im ersten Menü auf. Es erscheint dann folgende Frage: 
+ 
+___________________________________________________________________________________________ 
+ 
+      Arbeitskopie "Telefonnummern" veraendert! Sichern (j/n) ? 
+___________________________________________________________________________________________ 
+ 
+ 
+Beantworten Sie diese Frage mit 'j'. Als nächstes wird gefragt: 
+ 
+___________________________________________________________________________________________ 
+ 
+      Alte Version überschreiben (j/n) ? 
+___________________________________________________________________________________________ 
+ 
+ 
+Beantworten Sie auch diese Frage mit 'j'. Die Arbeitskopie über­
+schreibt dann die (leere) Version vor dem Ändern. 
+    Wenn Sie die Frage verneint hätten, könnten Sie anschließend
+einen neuen Namen für die Arbeitskopie angeben. Dies wäre dann
+sinnvoll, wenn Sie den Stand vor den Änderungen noch aufbewahren
+wollen. In diesem Fall ist es jedoch nutzlos, die alte leere Datei
+noch behalten zu wollen. 
+    Abschließend wird gefragt, ob Sie die Arbeitskopien löschen
+wollen. Wenn Sie noch weiter mit der Datei arbeiten wollen, vernei­
+nen Sie diese Frage. Die Datei bleibt dann geöffnet. Anderenfalls
+müßten Sie die Datei neu öffnen, wenn Sie sie wieder ansehen wol­
+len. 
+ 
+#on("b")#Arbeitskopien#off("b")# Es ist sehr wichtig, daß Sie sich die
+Funktionsweise
+mit der Arbeitskopie immer vor Augen halten, damit Sie später bei
+der Arbeit mit EUDAS nicht überrascht werden. 
+    Eine Arbeitskopie wird immer dann angelegt, wenn Sie beim
+Öffnen einer EUDAS-Datei angeben, daß Sie diese Datei ändern
+wollen. In dem Beispiel haben Sie eine neue Datei eingerichtet.
+EUDAS nimmt dann automatisch an, daß Sie ändern wollen. Öffnen
+Sie eine existierende Datei, werden Sie gefragt 
+ 
+___________________________________________________________________________________________ 
+ 
+      Wollen Sie etwas ändern (Arbeitskopie anlegen) (j/n) ? 
+___________________________________________________________________________________________ 
+ 
+ 
+Wenn Sie diese Frage verneinen, wird keine Arbeitskopie angelegt;
+alle Änderungsfunktionen werden jedoch gesperrt. Daran können Sie
+auch erkennen, daß keine Arbeitskopie vorliegt. 
+    Die Arbeitskopie, die EUDAS sich anlegt, ist anonym. Wenn Sie
+sich also im Menü 'Dateien' eine Übersicht zeigen lassen, erscheint
+nur das Original. Bevor Sie mit diesem Original etwas anstellen
+(zum Beispiel auf Archiv schreiben), sollten Sie sich vergewissern,
+daß Sie die Arbeitskopie gesichert haben, da das Original sonst
+nicht auf dem neuesten Stand ist. 
+    Um Sie in diesem Fall zu warnen, erscheint vor einer geöffneten
+Datei in einer Dateiauswahl das Symbol <!>, zum Beispiel: 
+ 
+ 
+          o <!> "Telefonnummern" 
+          o "Mitglieder" 
+ 
+ 
+Wenn Sie dieses Symbol sehen, sollten Sie die Datei lieber erst
+sichern, bevor Sie etwas mit ihr anstellen. 
+ 
+#on("b")#Beispiel#off("b")# Um die Arbeitsweise von EUDAS noch besser zu
+verstehen,
+betrachten Sie das Beispiel in Abb. 6-2. Nehmen Sie an, Sie haben
+drei EUDAS-Dateien 'Kalender', 'Namen' und 'Adressen' mit ihren
+Anfangsinhalten K0, N0 und A0 (symbolisch). In dem Diagramm sind
+die Vorgänge zu den Zeitpunkten 0 bis 10 mit ihren Auswirkungen
+auf die Inhalte der Dateien und der Arbeitskopie dargestellt. 
+ 
+ 
+#free (5.5)# 
+#center#Abb. 6-2   Beispiel zur Arbeitskopie 
+ 
+ 
+Zu den einzelnen Zeitpunkten passiere folgendes: 
+ 
+0:   Anfangszustand. Es wurde noch keine Datei geöffnet, also ist
+     keine Arbeitskopie vorhanden. Es könnte aber auch eine
+     beliebige Datei ohne Änderungserlaubnis geöffnet sein. 
+#free (0.2)# 
+1:   Die Datei 'Adressen' wird geöffnet zum Ändern. Der momen­
+     tane Zustand der Datei wird als Arbeitskopie übernommen. 
+#free (0.2)# 
+2:   Es wird eine Änderung vorgenommen (zum Beispiel) ein Satz
+     eingefügt). Diese Änderung betrifft aber nur die Kopie - die
+     Datei 'Adressen' als Original bleibt unverändert. 
+#free (0.2)# 
+3:   Eine weitere Änderung führt zum Inhalt A2 der Arbeitsko­
+     pie. 
+#free (0.2)# 
+4:   Aufruf von 'Sichern'. Die alte Version von 'Adressen' wird
+     überschrieben und durch den Inhalt A2 ersetzt. Die Frage
+     nach dem Löschen der Arbeitskopie wird verneint; daher bleibt
+     die Kopie auch erhalten. 
+#free (0.2)# 
+5:   Die Kopie wird erneut verändert. 
+#free (0.2)# 
+6:   Aufruf von 'Sichern'. Die Frage, ob die Kopie gesichert wer­
+     den soll, wird verneint. Die Arbeitskopie soll jedoch gelöscht
+     werden. Als Ergebnis geht die Änderung A3 verloren (viel­
+     leicht war diese Änderung ein Irrtum). Die Datei 'Adressen'
+     wird nicht verändert. Es ist keine Arbeitskopie mehr vor­
+     handen. 
+#free (0.2)# 
+7:   Die Datei 'Namen' wird zum Ändern geöffnet. 
+#free (0.2)# 
+8:   Die Datei 'Kalender' wird zum Ändern geöffnet. Da an der
+     vorigen Arbeitskopie keine Änderungen vorgenommen wurden,
+     kann die Kopie einfach überschrieben werden. Anderenfalls
+     wäre an dieser Stelle die Möglichkeit zum Sichern angeboten
+     worden. 
+#free (0.2)# 
+9:   Es wird eine Änderung durchgeführt. 
+#free (0.2)# 
+10:  Die geänderte Arbeitskopie wird gesichert, das Original über­
+     schrieben und die Arbeitskopie gelöscht (Normalfall). 
+ 
+
diff --git a/doc/eudas/eudas.hdb.7 b/doc/eudas/eudas.hdb.7
new file mode 100644
index 0000000..d6f1bf3
--- /dev/null
+++ b/doc/eudas/eudas.hdb.7
@@ -0,0 +1,687 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (61)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+7 Ausdrucken der Daten 
+ 
+ 
+ 
+7.1 Druckmuster 
+ 
+Nachdem Sie sich die Inhalte der EUDAS-Datei ausgiebig am Bild­
+schirm angesehen haben, möchten Sie die gespeicherten Daten sicher
+auch in gedruckter Form auf Papier sehen. Sie können eine
+EUDAS-Datei jedoch nicht ohne weiteres ausdrucken, da sie eine
+andere Struktur als normale Textdateien hat. 
+    Vor dem Drucken müssen also die Inhalte der EUDAS-Datei
+zunächst in lesbarer Form in eine Textdatei geschrieben werden.
+EUDAS kann diese Aufgabe jedoch ohne Ihre Hilfe nicht alleine be­
+wältigen. 
+    Es taucht nämlich das Problem auf, daß die Dateiinhalte in
+vielen verschiedenen Formen dargestellt werden können (Sie erin­
+nern sich sicher noch an das erste Kapitel). Vielleicht wollen Sie
+bestimmte Überschriften haben oder die Daten müssen auf ein be­
+stimmtes Formular passen. 
+    Um die Ausgabe nach Ihren Wünschen zu gestalten, müssen Sie
+also dem Rechner genau angeben, an welcher Stelle welche Felder
+gedruckt werden sollen usw. Dies geht am einfachsten, indem Sie
+dem Rechner ein Muster vorsetzen, nach dem er dann die richtigen
+Ausdrucke erstellen kann. Dieses Muster schreiben Sie in eine eige­
+ne Textdatei, die #on("i")#Druckmuster#off("i")# genannt wird. Aus den Daten der
+EUDAS-Datei und der Form, die im Druckmuster angegeben ist, wird
+dann eine weitere Textdatei erzeugt, die die Daten in der ge­
+wünschten Form enthält und die anschließend automatisch gedruckt
+werden kann. 
+    Durch ein Druckmuster erhalten Sie fast völlige Freiheit in der
+Gestaltung Ihrer Ausdrucke. Zum Beispiel können aus einer einzigen
+Adressendatei einfache Listen, Einladungskarten oder Rundbriefe
+erzeugt werden. Für eine einfache Adressenliste entspricht das
+Druckmuster einer Zeile der Liste, wobei angegeben wird, in welche
+Spalten die Inhalte gedruckt werden. Zum Drucken von Einladungs­
+karten wird als Druckmuster eine Einladungskarte verwendet, in der
+die Stellen markiert sind, an denen die Adresse erscheinen soll. Das
+gleiche kann man mit einem Brief machen, der dann mit jeder
+Adresse einmal ausgedruckt wird. 
+ 
+#on("b")#Druckverfahren#off("b")# Man kann sich diesen Druckprozeß wie folgt
+vorstellen: 
+ 
+ 
+#free (6.5)# 
+ 
+#center#Abb. 7-1   Druckverfahren 
+ 
+ 
+Vereinfacht gesagt (das genaue Verfahren wird später beschrieben)
+wird für jeden Satz der EUDAS-Datei das Druckmuster einmal in die
+Druckdatei übernommen. Dabei werden die Inhalte aus der EUDAS-
+Datei in einer noch anzugebenden Weise an den gewünschten Stellen
+eingefügt. 
+    Im weiteren sollen Sie erfahren, wie ein Druckmuster genau
+aussieht und wie daraus ein Ausdruck entsteht. 
+ 
+#on("b")#Beispiel#off("b")# Im folgenden sollen Sie zur Demonstration die
+bereits in
+Kapitel 3 und 4 beschriebene Beispieldatei verwenden. Nach Mög­
+lichkeit sollten Sie die angegebenen Beispiele mit dieser Datei
+selbst am Rechner ausprobieren. 
+ 
+Folgende Sätze befinden sich in der Datei: 
+ 
+ 
+     Vorname Name, Strasse, PLZ Ort, m/w 
+     ------------------------------------------------------- 
+     Herbert Wegner, Krämergasse 12, 5000 Köln, m 
+     Helga Sandmann, Willicher Weg 109, 5300 Bonn 1, w 
+     Albert Katani, Lindenstr. 3, 5210 Troisdorf, m 
+     Peter Ulmen, Mozartstraße 17, 5 Köln 60, m 
+     Karin Regmann, Grengelweg 44, 5000 Köln 90, w 
+     Hubert Arken, Talweg 12, 5200 Siegburg, m 
+     Anna-Maria Simmern, Platanenweg 67, 5 Köln 3, w 
+     Angelika Kaufmann-Drescher, Hauptstr. 123, 53 Bonn 2, w 
+     Harald Fuhrmann, Glockengasse 44, 5000 Köln 1, m 
+     Friedrich Seefeld, Kabelgasse, 5000 Köln-Ehrenfeld, m 
+ 
+ 
+Wie Sie sehen, wurde die Reihenfolge der Felder gegenüber der Datei
+teilweise verändert und Name und Vorname ohne Komma hinterein­
+andergeschrieben, während die anderen Feldinhalte durch Komma
+getrennt sind. Diese Liste wurde unter Verwendung eines Druck­
+musters erzeugt. 
+    Da dieses Druckmuster jedoch vorerst noch zu kompliziert ist,
+sollen Sie erst einmal ein einfacheres Druckmuster erstellen und
+versuchen, nur die Namen aus der Datei in Tabellenform auszuge­
+ben. 
+    Das dafür nötige Druckmuster hat folgendes Aussehen: 
+ 
+ 
+        % WIEDERHOLUNG 
+        ! &Name              ! &Vorname         ! 
+ 
+ 
+Das Druckmuster besteht nur aus zwei Zeilen, von der die zwei­
+te das eigentliche Muster darstellt. Die erste Zeile ist eine #on("i")# Anwei­
+sung#off("i")# an den Druckgenerator. 'WIEDERHOLUNG' gibt an, daß die
+folgenden Zeilen für jeden Satz wiederholt werden sollen (warum
+diese Angabe notwendig ist, werden Sie später einsehen). Das Pro­
+zentzeichen kennzeichnet eine Anweisung und muß unbedingt in der
+ersten Spalte des Druckmusters stehen, also ganz am linken Rand. 
+    In der zweiten Zeile ist zu sehen, daß das Zeichen '&' dazu
+benutzt wird, die Stellen zu markieren, an denen nachher Feldin­
+halte eingesetzt werden sollen. Hinter dem '&'-Zeichen folgt der
+Name des Feldes, das an dieser Stelle eingesetzt werden soll. Eine
+solche Konstruktion wird #on("i")#Feldmuster#off("i")# genannt. Beachten Sie, daß
+Feldnamen hier immer ohne Anführungsstriche geschrieben werden
+müssen. Die Ausrufungszeichen bilden den eigentlichen Mustertext
+und werden unverändert als Tabellenbegrenzung in die Ausgabe
+übernommen. 
+    Als Ergebnis des Druckprozesses sollte folgende Ausgabe auf
+dem Drucker erscheinen: 
+ 
+ 
+        ! Wegner             ! Herbert          ! 
+        ! Sandmann           ! Helga            ! 
+        ! Katani             ! Albert           ! 
+        ! Ulmen              ! Peter            ! 
+        ! Regmann            ! Karin            ! 
+        ! Arken              ! Hubert           ! 
+        ! Simmern            ! Anna-Maria       ! 
+        ! Kaufmann-Drescher  ! Angelika         ! 
+        ! Fuhrmann           ! Harald           ! 
+        ! Seefeld            ! Friedrich        ! 
+ 
+ 
+Sie können erkennen, daß die Feldmuster in der Ausgabe jeweils
+durch den Inhalt des zugehörigen Feldes ersetzt worden sind. Der
+übrige Text in der Musterzeile ist unverändert geblieben. Beachten
+Sie, daß das '&' ein reserviertes Zeichen ist, das ein Feldmuster im
+umgebenden Text kennzeichnet und daher (vorerst) nicht gedruckt
+werden kann. 
+ 
+ 
+7.2 Aufruf 
+ 
+In diesem Abschnitt sollen Sie erfahren, wie Sie diese Ausgabe
+selbst erzeugen können. Damit der Druckgenerator arbeiten kann,
+müssen Sie die Datei 'Adressen' erst einmal öffnen. Anschließend
+wählen Sie das Menü 'Drucken' an. 
+ 
+#on("b")#Druckmuster erstellen#off("b")# Als nächstes müssen Sie das
+Druckmuster erstellen. Hierfür gibt es die Funktion 
+#free (0.2)# 
+ 
+        Textdatei 
+        E Editieren 
+ 
+#free (0.2)# 
+da das Druckmuster eine normale Textdatei ist. 
+    Wählen Sie diese Funktion. Sie werden dann nach einem Namen
+für das Druckmuster gefragt. Wir wollen das Druckmuster 'Namens­
+liste' nennen - Sie können aber auch einen beliebigen anderen
+Namen wählen. Denken Sie daran, die Anführungsstriche nicht mit
+einzugeben. 
+    Es erscheint anschließend das gewohnte Editorbild mit einer
+entsprechenden Statuszeile. Geben Sie die zwei Zeilen des Druck­
+musters ein und beenden Sie den Editor mit ESC 'q'. Damit ist das
+Druckmuster fertig. 
+ 
+    Die hier beschriebene Funktion können Sie nicht nur zum Er­
+stellen, sondern auch zum Ändern und einfachen Ansehen eines
+Druckmusters bzw. einer Textdatei allgemein verwenden. Es wird
+Ihnen immer der jeweilige Inhalt präsentiert, den Sie dann nach
+Belieben abändern können oder nicht. 
+ 
+___________________________________________________________________________________________ 
+ 
+      EUDAS:   Öffnen   Einzelsatz   Gesamtdatei   Drucken   Dateien   Archiv 
+      --------------: 
+      Satzauswahl   : 
+      D Drucken     : 
+      --------------: 
+      Druckausgabe  : 
+      R Richtung    : 
+      --------------: 
+      Textdatei     : 
+      E Editieren   : 
+      A Ausdrucken  : 
+      N Nachbearb.  : 
+      --------------: 
+ 
+___________________________________________________________________________________________ 
+ 
+#center#Abb. 7-2   Menü "Drucken" 
+ 
+ 
+#on("b")#Ausgaberichtung#off("b")# Bevor Sie jetzt weitermachen, sollten Sie
+über­
+prüfen, ob an Ihrem System ein Drucker angeschlossen ist. Der
+Drucker sollte bei den folgenden Versuchen betriebsbereit sein. 
+    Ist kein Drucker angeschlossen oder wollen Sie kein Papier
+verschwenden, haben Sie die Möglichkeit, den Ausdruck als Text­
+datei zu erhalten. Dazu wählen Sie die Funktion 
+#free (0.2)# 
+ 
+        Ausgabe 
+        R Richtung 
+ 
+#free (0.2)# 
+an. Beantworten Sie beide Fragen, die Ihnen gestellt werden, mit
+'n'. Die Ausgaben stehen dann nachher in Dateien mit einem Namen
+der Form 
+#free (0.2)# 
+ 
+        Namensliste.a$n 
+ 
+#free (0.2)# 
+die Sie sich mit der oben beschriebenen Funktion dann genau wie
+ein Druckmuster anschauen können. Der Name besteht also aus dem
+Namen des Druckmusters, dem ein '.a$' angehängt wird. Die Nummer
+'n' dient zur Unterscheidung bei mehreren aufeinanderfolgenden
+Ausgaben. Um Verwirrung zu vermeiden, sollten Sie die Datei nach
+dem Anschauen löschen (im Menü 'Dateien'). 
+ 
+#on("b")#Druckaufruf#off("b")# Wenn Sie diese Hinweise beachtet haben, können
+Sie den Druckvorgang mit der Auswahl 
+#free (0.2)# 
+ 
+        Satzauswahl 
+        D Drucken 
+ 
+#free (0.2)# 
+starten. Sie werden hier nach dem Namen des Druckmusters gefragt,
+das Sie verwenden wollen (Sie können ja durchaus eine ganze Reihe
+von verschiedenen Druckmustern haben). 
+    Sie können den Ablauf des Druckvorganges daran verfolgen,
+daß jeweils die Nummer des Satzes ausgegeben wird, der gerade
+bearbeitet wird. Probieren Sie eventuell auch kleine Abwandlungen
+des Druckmusters aus, indem Sie die Tabellenspalten schmaler oder
+breiter machen oder die Ausrufungszeichen durch ein anderes Zei­
+chen ersetzen (je nach Geschmack). 
+ 
+#on("b")#Ausgabedatei#off("b")# Wollen Sie die erzeugte Ausgabe (die in der
+Datei
+'Namensliste.a$1' steht) irgendwann tatsächlich ausdrucken, ver­
+wenden Sie die Funktion 
+#free (0.2)# 
+ 
+        A Ausdrucken 
+ 
+#free (0.2)# 
+Sie werden dann nach dem Namen der Textdatei gefragt. Beachten
+Sie, daß Sie diese Funktion #on("i")#nicht#off("i")# zum Drucken von EUDAS-Dateien
+verwenden können, da aus einer EUDAS-Datei erst eine Druckdatei
+erzeugt werden muß. 
+    Auch wenn Sie angegeben haben, daß die Ausgabe des Druck­
+prozesses direkt ausgedruckt werden soll, startet Ihr Drucker erst,
+wenn EUDAS die ganze Datei durchgegangen ist und der Vorgang für
+Sie beendet ist. Dies liegt am EUMEL-System, das nur vollständige
+Druckaufträge entgegennimmt, damit sich mehrere Benutzer nicht in
+die Quere kommen können. In einem Multi-User-System können Sie
+weiterarbeiten, während der Drucker beschäftig ist. 
+ 
+#on("b")#Fehler#off("b")# Bevor der eigentliche Druckprozeß gestartet wird,
+wird das
+Druckmuster auf unsinnige oder unverständliche Konstruktionen
+überprüft. Ist dem Druckgenerator etwas suspekt, gibt er eine Feh­
+lermeldung aus, in der die fragliche Situation von seiner Seite aus
+beschrieben wird. Er kann natürlich nicht Ihren Fehler "verstehen".
+Daher müssen Sie unter Umständen eine Fehlermeldung erst inter­
+pretieren, ehe Sie die wahre Ursache erkennen können. 
+    Damit Sie einen aufgetretenen Fehler gleich korrigieren können,
+werden Ihnen das Druckmuster und die Fehlermeldungen parallel auf
+dem Bildschirm zum Ändern und Anschauen angeboten. Sie können
+mit dem Editor das Druckmuster ändern und in den Fehlermeldungen
+blättern. Diese Konfiguration wird Paralleleditor genannt. Mit ESC
+'w' wechseln Sie zwischen den beiden Bildschirmhälften. 
+ 
+#on("b")#Suchbedingung#off("b")# Wollen Sie nicht alle Namen ausdrucken, so
+können
+Sie vorher ein Suchmuster einstellen, das nur auf die gewünschten
+Namen zutrifft (wie im Kapitel 5 beschrieben). Der Druckgenerator
+richtet sich immer nach dem aktuell eingestellten Suchmuster und
+druckt nur die ausgewählten Sätze. Wenn Sie zum Beispiel die Na­
+men aller Frauen ausdrucken wollen, stellen Sie im Tastenmodus ein
+Suchmuster ein (das sollten Sie können), das für das Feld 'm/w' die
+Bedingung 'w' enthält. Danach können Sie den Druckgenerator auf­
+rufen. Vergessen Sie nicht, das Suchmuster anschließend wieder zu
+löschen. 
+ 
+#on("b")#Feldnamen abfragen#off("b")# Wenn Sie selber ein Druckmuster
+erstellen,
+wird es häufiger vorkommen, daß Sie die genaue Schreibweise der
+Feldnamen nicht im Kopf haben. Für diesen Zweck definiert EUDAS
+im Editor eine spezielle Tastenkombination. 
+    Wenn Sie dort ESC 'F' tippen (großes 'F'), erhalten Sie eine
+Auswahl aller Felder der gerade geöffneten Datei. Sie können sich
+die Namen einfach ansehen, aber auch direkt in den Text des
+Druckmusters übernehmen. 
+    Wenn Sie nämlich vor dem Verlassen der Auswahl mit ESC 'q'
+ein Feld ankreuzen, wird anschließend der Name in Anführungs­
+strichen an die Position geschrieben, an der vor dem Aufruf der
+Cursor stand. Auf diese Weise können Sie sich auch das Tippen
+langer Feldnamen vereinfachen. 
+    Beachten Sie, daß Sie im Normalfall im Druckmuster die Anfüh­
+rungsstriche wieder entfernen müssen. Die Anführungsstriche dienen
+zur Abgrenzung, wie weit der Feldname geht. Falls der Name Leer­
+zeichen enthält, beachten Sie bitte den Absatz 'Abgrenzung der
+Feldnamen' in Abschnitt 7.4. 
+ 
+ 
+7.3 Abschnitte 
+ 
+Die Tabellen, die Sie bis jetzt erzeugen können, sehen optisch noch
+nicht sehr gut aus. Es fehlt auf jeden Fall eine vernünftige Über­
+schrift. Um eine Überschrift zu erzeugen, können Sie im Druckmuster
+einen #on("i")#Vorspann#off("i")# definieren, der ganz zu Anfang einmal gedruckt
+wird. 
+    Dieser Vorspann wird durch die Anweisung 
+ 
+ 
+        % VORSPANN 
+ 
+ 
+eingeleitet (bitte nicht vergessen, daß das '%'-Zeichen für eine
+Anweisung in der ersten Spalte stehen muß). Die folgenden Zeilen
+bis zur 'WIEDERHOLUNG'-Anweisung gehören zum Vorspann. Ein
+Druckmuster für unsere Namensliste mit Überschrift könnte dann so
+aussehen: 
+ 
+ 
+        % VORSPANN 
+        Alle Namen aus der EUDAS-Datei 'adressen' 
+        ----------------------------------------- 
+        % WIEDERHOLUNG 
+        ! &Name              ! &Vorname         ! 
+ 
+ 
+Der Druckgenerator erzeugt mit diesem Druckmuster die gewünschte
+Liste mit Überschrift. Sie können als Vorspann natürlich auch einen
+beliebigen anderen Text verwenden. 
+    In einer analogen Weise können Sie die Liste noch durch eine
+waagerechte Linie abschließen, indem Sie einen #on("i")#Nachspann#off("i")# definie­
+ren. Die dafür notwendige Anweisung heißt 
+ 
+ 
+        % NACHSPANN 
+ 
+ 
+Die Zeilen nach dieser Anweisung werden gedruckt, nachdem alle
+Sätze bearbeitet worden sind. Das folgende Druckmuster erzeugt
+schon eine sehr schöne Liste: 
+ 
+ 
+        % VORSPANN 
+        Alle Namen aus der EUDAS-Datei 'adressen' 
+        ----------------------------------------- 
+        % WIEDERHOLUNG 
+        ! &Name              ! &Vorname         ! 
+        % NACHSPANN 
+        ----------------------------------------- 
+ 
+ 
+nämlich: 
+ 
+ 
+        Alle Namen aus der EUDAS-Datei 'adressen' 
+        ----------------------------------------- 
+        ! Wegner             ! Herbert          ! 
+        ! Sandmann           ! Helga            ! 
+        ! Katani             ! Albert           ! 
+        ! Ulmen              ! Peter            ! 
+        ! Regmann            ! Karin            ! 
+        ! Arken              ! Hubert           ! 
+        ! Simmern            ! Anna-Maria       ! 
+        ! Kaufmann-Drescher  ! Angelika         ! 
+        ! Fuhrmann           ! Harald           ! 
+        ! Seefeld            ! Friedrich        ! 
+        ----------------------------------------- 
+ 
+ 
+Die drei Teile, aus denen ein Druckmuster bestehen kann (Vorspann,
+Nachspann und Wiederholungsteil), werden #on("i")#Abschnitte#off("i")# genannt. Wie
+Sie später noch sehen werden, haben Abschnitte eine Reihe von
+gemeinsamen Eigenschaften. Ein Abschnitt wird durch eine eigene
+Anweisung eingeleitet und endet, wenn ein anderer Abschnitt be­
+ginnt oder das Druckmuster zu Ende ist. Alle Abschnitte können
+auch weggelassen werden, irgendein Abschnitt muß aber immer
+vorhanden sein. So ist es zum Beispiel möglich, ein Druckmuster zu
+bauen, das nur aus einem Nachspann besteht (Sie werden allerdings
+jetzt noch nicht verstehen können, warum so etwas sinnvoll sein
+kann). 
+    Zum Abschluß dieses Kapitels hier noch einmal eine Übersicht
+der bisher vorgestellten Anweisungen: 
+ 
+ 
+        Anweisung      !  Bedeutung 
+        ---------------+---------------------------------- 
+        % VORSPANN     ! leitet Vorspann ein 
+        % WIEDERHOLUNG ! leitet Wiederholungsteil ein 
+        % NACHSPANN    ! leitet Nachspann ein 
+ 
+ 
+ 
+7.4 Feldmuster 
+ 
+Mit den bis jetzt beschriebenen Möglichkeiten des Druckgenerators
+können Sie schon sehr viel anfangen. Es fehlt aber noch die Mög­
+lichkeit, mehrere Feldinhalte direkt hintereinander zu schreiben,
+egal wie lang diese Inhalte sind. Diese Fähigkeit wird zum Beispiel
+für die anfangs vorgestellte Liste benötigt. 
+ 
+#on("b")#Variable Position#off("b")# Die Feldmuster, die Sie bis jetzt
+kennen, begin­
+nen mit einem '&'-Zeichen und werden immer genau an der Stelle
+gedruckt, an der sie stehen (feste Position). Sie können ein Feld­
+muster aber auch mit '%' beginnen lassen. In diesem Fall kann der
+Inhalt verschoben werden (variable Position), je nachdem, ob vorhe­
+rige Inhalte kürzer oder länger sind. 
+    '%' ist wie '&' ein reserviertes Zeichen, kann also nicht direkt
+gedruckt werden. Da '&' und '%' Feldmuster einleiten, heißen sie
+#on("i")#Musterzeichen#off("i")#. 
+    Um Feldmuster variabler Position einmal auszuprobieren, soll­
+ten Sie unser bisheriges Druckmuster in der folgenden Weise um­
+schreiben: 
+ 
+ 
+        % WIEDERHOLUNG 
+        &Vorname %Name 
+ 
+ 
+(Vorspann und Nachspann der Einfachheit halber mal weggelassen).
+Als Ergebnis erhalten wir: 
+ 
+ 
+        Herbert Wegner 
+        Helga Sandmann 
+        Albert Katani 
+        Peter Ulmen 
+        Karin Regmann 
+        Hubert Arken 
+        Anna-Maria Simmern 
+        Angelika Kaufmann-Drescher 
+        Harald Fuhrmann 
+        Friedrich Seefeld 
+ 
+ 
+Das Feldmuster '%Name' ist also entsprechend der Länge des Vor­
+namens nach links oder nach rechts gerutscht. Zu beachten ist, daß
+ein Feldmuster mit '%' nicht in der ersten Spalte stehen darf, denn
+dann würde die Zeile als Anweisung angesehen. Ein Feldmuster
+variabler Position wäre ja auch in der ersten Spalte wenig sinnvoll. 
+ 
+#on("b")#Feste Länge#off("b")# Außer den beiden bisher besprochenen einfachen
+Arten (mit '&' oder '%') gibt es noch weitere Ausprägungen von
+Feldmustern für besondere Fälle. Wird ein Feldmuster noch von
+weiteren Musterzeichen gefolgt, dann wird dieses Feldmuster immer
+in der reservierten Länge eingesetzt. Die reservierte Länge reicht
+vom ersten bis zum letzten Musterzeichen. Durch die zusätzlichen
+Musterzeichen wird also ein bestimmter Platz freigehalten. 
+    Ersetzt man im obigen Druckmuster '&Vorname' durch
+'&Vorname&&', wird der Effekt des folgenden '%'-Feldes wieder
+aufgehoben, da jetzt für alle Vornamen die gleiche Länge verwendet
+wird (Probieren Sie dies aus). 
+    Bei einem solchen Feldmuster mit fester Länge wird der Inhalt
+abgeschnitten, falls er diese Länge überschreitet; ist der Inhalt
+kürzer, wird rechts mit Leerstellen aufgefüllt. Aber auch bei Feld­
+mustern mit variabler Länge (also ohne folgende Musterzeichen)
+kann abgeschnitten werden, nämlich genau dann, wenn der Inhalt so
+lang ist, daß ein folgendes Feld mit fester Position (mit '&' anfan­
+gend) überschrieben würde. Hätten wir also in unserem ersten
+Druckmuster nicht genügend Platz für die Spalten vorgesehen,
+wären einige Namen abgeschnitten worden (probieren Sie es nochmal
+aus, falls es Ihnen nicht schon passiert ist). 
+    In einem weiteren Fall werden Feldmuster variabler Länge
+abgeschnitten, nämlich wenn die generierte Zeile die maximale
+Zeilenlänge überschreitet. Die maximale Zeilenlänge richtet sich
+nach dem Dateilimit, das für das Druckmuster eingestellt ist. Nor­
+malerweise ist dies 77, so daß Sie in Normalschrift die Zeilenbreite
+auf einem DIN A4-Blatt nicht überschreiten. 
+    Benutzen Sie jedoch breites Papier oder eine schmale Schrift,
+sollten Sie während der Eingabe des Druckmusters ESC ESC tippen
+und das Kommando 
+ 
+ 
+        limit (135) 
+ 
+ 
+eingeben. EUDAS nutzt dann die volle Zeilenbreite aus. 
+ 
+#on("b")#Rechtsbündig#off("b")# Sie sind jetzt aber noch nicht zu Ende mit
+den
+Feldmustervariationen. Eine letzte Möglichkeit besteht darin, den
+Inhalt rechtsbündig in ein Feldmuster einzusetzen. Dies hat natür­
+lich nur Sinn bei fester Länge. Man erreicht dies dadurch, daß man
+das Feldmuster mit mehreren Musterzeichen beginnen läßt. So ist 
+ 
+ 
+        %%Vorname% 
+ 
+ 
+die rechtsbündige Version von 
+ 
+ 
+        %Vorname%% 
+ 
+ 
+Beide Feldmuster sind gleich lang, beim ersten wird jedoch am lin­
+ken Rand aufgefüllt oder abgeschnitten, beim zweiten dagegen am
+rechten Rand. 
+ 
+#on("b")#Zusammenfassung#off("b")# Hier noch einmal eine Zusammenstellung
+aller möglichen Feldmustertypen: 
+ 
+ 
+        Typ ! Beispiel  ! Position ! Länge    ! bündig 
+        ----+-----------+------------------------------ 
+         1  ! &Name     ! fest     ! variabel ! links 
+         2  ! %Name     ! variabel ! variabel ! links 
+         3  ! &Name&&&  ! fest     ! fest     ! links 
+         4  ! %Name%%%  ! variabel ! fest     ! links 
+         5  ! &&&Name&  ! fest     ! fest     ! rechts 
+         6  ! %%%Name%  ! variabel ! fest     ! rechts 
+ 
+ 
+Wir können zusammenfassen: 
+#free (0.2)# 
+*  Feldmuster dienen im Druckmuster dazu, Stellen zu markieren, an
+   denen Inhalte eingesetzt werden sollen. 
+#free (0.2)# 
+*  Feldmuster beginnen mit einem Musterzeichen ('&' oder '%');
+   darauf folgt der Feldname. 
+#free (0.2)# 
+*  Durch '&' wird feste und durch '%' variable Position festgelegt. 
+#free (0.2)# 
+*  Durch zusätzliche Musterzeichen kann eine feste Länge angege­
+   ben werden; mehrere Musterzeichen am Anfang führen zu rechts­
+   bündigem Einsetzen. 
+ 
+#on("b")#Abgrenzung der Feldnamen#off("b")# Als nächstes sollen Sie den Fall
+be­
+trachten, daß Sie einen Namen in der oft auftretenden Form 
+ 
+ 
+        Name, Vorname 
+ 
+ 
+schreiben wollen. Die Schwierigkeit liegt in dem Komma, das direkt
+hinter dem Namen folgen soll. Sie könnten versuchen, diese Situa­
+tion im Druckmuster folgendermaßen darzustellen: 
+ 
+ 
+        % WIEDERHOLUNG 
+        &Name, %Vorname 
+ 
+ 
+In diesem Fall erhalten Sie aber die Fehlermeldung 
+ 
+ 
+        FEHLER in Zeile 2 bei >>Name,<< 
+           diese Abkuerzung ist nicht definiert 
+ 
+ 
+Wenn Sie sich nicht genau vorstellen können, wie der Druckgenera­
+tor ein Feldmuster liest, wird Ihnen dieser Fehler mysteriös er­
+scheinen, denn 'Name' ist doch als Feld definiert (was eine Abkür­
+zung ist, werden Sie in Kapitel 13 lernen). Den entscheidenden
+Hinweis liefert jedoch das Komma. Offensichtlich hat der Druck­
+generator das Komma als Teil des Feldnamens angesehen. 
+    Dies liegt daran, daß ja irgendwann der Feldname in einem
+Feldmuster beendet sein muß. Normalerweise interpretiert der
+Druckgenerator ein Leerzeichen oder Musterzeichen als Ende des
+Namens, alle vorherigen Zeichen gehören mit zum Feldnamen. Wenn
+nun aber nach dem Feldmuster kein Leerzeichen folgen soll (wie in
+unserem Beispiel) oder der Feldname selbst Leerzeichen enthält
+(dies ist ja erlaubt, könnte aber im Druckmuster nie erkannt wer­
+den), muß noch eine zusätzliche Angabe erfolgen. 
+    In solchen Fällen kann der Feldname in spitze Klammern einge­
+schlossen werden. Der Druckgenerator sieht den Feldnamen dann bei
+der ersten schließenden Klammer als beendet an, wobei die Klam­
+mern natürlich nicht zum Feldnamen gehören, aber auch nicht ge­
+druckt werden. 
+    Das obige Beispiel müßte also richtig so formuliert werden: 
+ 
+ 
+        % WIEDERHOLUNG 
+        &<Name>, %Vorname 
+ 
+ 
+Wenn Sie dieses Druckmuster ausprobieren, werden Sie sehen, daß
+die Namen tatsächlich in der gewünschten Form erscheinen. 
+ 
+#on("b")#Leerautomatik#off("b")# Es gibt noch eine trickreiche Automatik in
+EUDAS,
+die in manchen Fällen ganz nützlich ist - und zwar in Fällen, in
+denen Sie mehrere Felder als Aufzählung durch Leerzeichen ge­
+trennt drucken wollen. Nehmen wir an, unsere Adreßdatei hätte
+noch ein Feld 'Titel', in das Sie bei Bedarf 'Dr.' oder 'Prof. Dr.'
+eintragen. In der Adresse würden Sie dann angeben: 
+ 
+ 
+        &Titel %Vorname %Name 
+ 
+ 
+Wenn der Titel jedoch leer ist, würde ein störendes Leerzeichen vor
+dem Namen bleiben. In einem solchen Fall entfernt EUDAS das Leer­
+zeichen automatisch. Vorbedingung für diese Automatik ist, daß es
+sich um ein Feld variabler Länge handelt und vor dem Feld noch ein
+Leerzeichen steht (außer in Spalte 1). 
+ 
+#on("b")#Aufgabe#off("b")# Sie sollten jetzt die Möglichkeiten des
+Druckgenerators
+soweit kennengelernt haben, daß Sie ein Druckmuster für die zu
+Anfang des Kapitels erwähnte Liste aller Dateiinhalte erstellen
+können. Versuchen Sie dies zunächst allein, ehe Sie die Lösung
+nachschauen. 
+ 
+ 
+Hier nun die Lösung: 
+ 
+ 
+     % VORSPANN 
+     Vorname Name, Strasse, PLZ Ort, m/w 
+     ------------------------------------------------------- 
+     % WIEDERHOLUNG 
+     &Vorname %<Name>, %<Strasse>, %PLZ %<Ort>, %m/w 
+ 
+ 
+Beachten Sie die spitzen Klammern, die nötig sind, um das Kom­
+ma ohne Zwischenraum anzuschließen. 
+ 
+#on("b")#Beispiel#off("b")# Als letztes Beispiel sollen Sie einen Fall
+betrachten, bei
+dem pro Satz mehr als eine einzelne Listenzeile gedruckt werden
+soll, und zwar sollen Sie einen Brief schreiben, in den der Druck­
+generator die Adressen verschiedener Leute einfügen soll. Die Er­
+stellung von Formbriefen ist eine sehr häufige Anwendung von
+EUDAS. Mit den bisher beschriebenen Konstrukten kann man etwa
+folgendes Druckmuster schreiben: 
+ 
+ 
+        % WIEDERHOLUNG 
+             &Vorname %Name 
+             &Strasse 
+             &PLZ %Ort 
+ 
+             Lieber &Vorname ! 
+ 
+             Ich lade Dich mit diesem Brief zu 
+             meiner nächsten Party ein. 
+             Bring gute Laune und was zu Essen mit. 
+ 
+                                     Viele Grüße 
+        \#page\# 
+ 
+ 
+Die letzte Zeile zeigt eine Möglichkeit, von der Sie wahrscheinlich
+öfter Gebrauch machen werden, nämlich Druckersteuerungsanwei­
+sungen in das Druckmuster einzufügen. Die Anweisung '\#page\#'
+wird an den Drucker weitergereicht und bewirkt, daß nach jedem
+Brief eine neue Seite angefangen wird (Sie wollen sicher nicht
+mehrere Briefe auf ein Blatt drucken). Sie können auch andere An­
+weisungen verwenden, z.B. neue Schrifttypen einstellen. Informieren
+Sie sich gegebenenfalls, welche Anweisungen die Textkosmetik zur
+Verfügung stellt. 
+ 
+#on("b")#Ausblick#off("b")# Sie kennen jetzt bereits einen großen Teil der
+Möglich­
+keiten des Druckgenerators. Einige wünschenswerte Fähigkeiten
+fehlen jedoch noch. So wäre es vorteilhaft, wenn abhängig vom
+Inhalt des Feldes 'm/w' die Anrede 'Sehr geehrter Herr' oder 'Sehr
+geehrte Frau' erzeugt werden könnte. Außerdem könnte das im
+Rechner vorhandene Datum automatisch in den Brief übernommen
+werden. Diese Möglichkeiten werden den Kapiteln 12 und 13 be­
+schrieben. 
+    Sie sollten diese jedoch erst dann durchlesen, wenn Sie eine
+gewisse Sicherheit im Umgang mit Druckmustern erlangt haben.
+Zuvor sollten Sie die Inhalte dieses Kapitels beherrschen, damit Sie
+EUDAS gut nutzen können. 
+
diff --git a/doc/eudas/eudas.hdb.8 b/doc/eudas/eudas.hdb.8
new file mode 100644
index 0000000..83246e9
--- /dev/null
+++ b/doc/eudas/eudas.hdb.8
@@ -0,0 +1,211 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (75)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+8 Was war und was noch kommt
+ 
+ 
+ 
+8.1 Rückblick 
+ 
+So! Wenn Sie bis hierhin gut mitgearbeitet haben, haben Sie die
+erste und wichtigste Etappe beim Erlernen von EUDAS schon ge­
+schafft. Bevor Sie kennenlernen, was für Möglichkeiten Ihnen EUDAS
+sonst noch bietet, wollen wir die wichtigsten Dinge rekapitulieren,
+die Sie gelernt haben sollten. 
+ 
+#on("b")#EUDAS-Dateien#off("b")# Sie sollten wissen, wie EUDAS-Dateien
+aussehen,
+und daß sie sich von normalen Textdateien unterscheiden. Diese
+Unterscheidung sollten Sie immer beachten, denn es gibt Funktio­
+nen, die nur EUDAS-Dateien annehmen (zum Beispiel 'Öffnen'),
+andere, die nur Textdateien annehmen (zum Beispiel 'Textdatei
+erstellen') und solche, die mit beliebigen Arten von Dateien "ohne
+Ansehen der Person" funktionieren (zum Beispiel 'Kopieren vom
+Archiv'). 
+ 
+#on("b")#Bedienung#off("b")# Sie sollten wissen, wie man eine Funktion im
+Menü
+aufruft; wie Sie EUDAS die notwendigen Informationen (zum Beispiel
+Dateinamen) mitgeben und wie Sie in besonderen Situationen (Feh­
+ler, Abbruch) reagieren können. Zur problemlosen Bedienung sollten
+Sie auch die jeweilige Statuszeile interpretieren können. 
+ 
+#on("b")#Dateiverwaltung#off("b")# Sie sollten wissen, wie Sie Dateien von
+Archiv­
+disketten holen und dort auch wieder abspeichern können. Dazu ist
+die Dateiauswahl durch Ankreuzen sehr hilfreich. Sie sollten von
+Anfang an darauf achten, daß Sie Ihre Dateien regelmäßig auf dem
+Archiv sichern, damit Sie bei etwaigen Problemen mit Ihrem Rechner
+die Daten nicht verlieren. 
+ 
+#on("b")#Öffnen#off("b")# Sie sollten wissen, daß Sie eine EUDAS-Datei vor
+dem
+Bearbeiten erst öffnen müssen. Weiterhin sollten Sie mit der Ar­
+beitskopie umgehen können, die EUDAS bei Änderungen anlegt.
+Denken Sie daran, Ihre Datei nach Änderungen zu sichern. Sie soll­
+ten auch neue EUDAS-Dateien mit eigener Struktur anlegen können. 
+ 
+#on("b")#Ansehen und Ändern#off("b")# Sie sollten wissen, wie Sie die Daten
+Ihrer
+EUDAS-Dateien am Bildschirm abrufen können - entweder manuell
+oder mit Hilfe eines Suchmusters. Sie sollten Änderungen und Ein­
+fügungen durchführen können. 
+ 
+#on("b")#Drucken#off("b")# Sie sollten wissen, wie Sie die Daten einer
+EUDAS-Datei
+mit Hilfe eines Druckmusters ausdrucken können. Denken Sie daran,
+daß dies ein zweistufiger Vorgang ist (Generierung der Druckdatei -
+Ausgeben an Drucker), den Sie an verschiedenen Stellen beeinflus­
+sen können. 
+ 
+Lesen Sie das entsprechende Kapitel erneut durch, wenn Sie sich bei
+einem Punkt dieser Aufzählung nicht sicher sind. Wichtig ist auch,
+daß Sie die bschriebenen Funktionen selbst am Rechner ausprobiert
+haben. 
+    Wenn Sie dies alles geduldig absolviert haben, sind Sie in der
+Lage, EUDAS sinnvoll für Ihre eigenen Probleme einzusetzen. Sie
+sollten jetzt ruhig versuchen, eigene Lösungen zu realisieren. Sicher
+werden Sie dabei erkennen, daß Ihnen noch einige Möglichkeiten
+fehlen. Die Chancen sind aber gut, daß EUDAS Ihnen diese Möglich­
+keiten bietet. 
+    Im nächsten Abschnitt erhalten Sie einen Überblick darüber,
+was EUDAS noch zur Verfügung stellt. Dort können Sie sich orien­
+tieren, welche Kapitel Sie lesen sollten, wenn Sie bestimmte Fragen
+haben. 
+ 
+ 
+8.2 Ausblick 
+ 
+Im zweiten Teil dieses Handbuchs erwarten Sie eine ganze Reihe
+interessanter Themen. Dort werden Erweiterungen und Verallgemei­
+nerungen von Funktionen beschreiben, die Sie bereits kennen. Viele
+Funktionen sind jedoch ganz neu und manchmal auch nicht ganz
+einfach zu beherrschen. 
+ 
+#on("b")#Kapitel 9#off("b")# Das neunte Kapitel befaßt sich mit der
+grundsätzlichen
+Struktur der geöffneten Datei. Sie erfahren, daß Sie mehr als eine
+Datei gleichzeitig öffnen und bearbeiten können. Zum einen können
+Sie gleichartige Dateien verketten oder Dateien über Beziehungen
+koppeln. Insbesondere das Koppeln ist eine wichtige Grundlage für
+viele fortgeschrittene Anwendungen von EUDAS. 
+    In diesem Kapitel wird auch beschrieben, wie Sie auf einem
+Mehrplatzsystem von mehreren Plätzen aus auf die gleichen EUDAS-
+Dateien zugreifen können. Die Fähigkeiten von EUDAS auf diesem
+Gebiet erreichen nicht das Niveau von großen Datenbanksystemen,
+sind jedoch einfach anzuwenden und in vielen Fällen nützlich. 
+ 
+#on("b")#Kapitel 10#off("b")# Im zehnten Kapitel erfahren Sie, wie Sie den
+Bildschirm
+übersichtlicher gestalten können, wenn Sie Dateien mit zahlreichen
+Feldern benötigen. Sie können bestimmte Felder auswählen, aber
+auch die Sätze einfach ausschnittweise ansehen. 
+    Das Suchmuster besitzt noch viele Fähigkeiten, die im ersten
+Teil nicht zur Sprache gekommen sind. Sie können mehrere Bedin­
+gungen auf verschiedene Weisen miteinander kombinieren. Auch
+einige neue Vergleiche treten auf. Außerdem können Sie mehrere
+Felder eines Satzes miteinander vergleichen. 
+    Zum schnellen Überblick steht Ihnen eine Funktion bereit, die
+jeweils einen Satz pro Bildschirmzeile anzeigt. In dieser Übersicht
+können Sie blättern und auch Sätze markieren (ankreuzen), um Sie
+später zu bearbeiten. 
+ 
+#on("b")#Kapitel 11#off("b")# Das elfte Kapitel ist den Funktionen zur
+Bearbeitung
+gewidmet. Dort erfahren Sie, wie Sie eine Datei sortieren können.
+Außerdem können Sie eine Datei ausschnittweise kopieren, wobei Sie
+noch eine Vielzahl von Manipulationsmöglichkeiten haben. 
+    Auch das Tragen von mehreren Sätzen in einem Arbeitsgang ist
+möglich. Dabei können Konsistenzbedingungen einer Datei überprüft
+werden. 
+    Als letztes erfahren Sie, wie man eine EUDAS-Datei automa­
+tisch nach einer beliebigen Vorschrift ändern kann. Hier, wie bei
+den vorherigen Funktionen, werden Sie zum ersten Mal erkennen,
+wieviel man mit der Programmiersprache ELAN innerhalb von EUDAS
+ohne viel Aufwand machen kann. 
+ 
+#on("b")#Kapitel 12#off("b")# Das nächste Kapitel zeigt Ihnen weitere
+Möglichkeiten
+zum Drucken. Sie können die Druckausgabe vor dem Drucken noch
+mit den Programmen der EUMEL-Textverarbeitung aufbereiten. Auch
+innerhalb der EUMEL-Textverarbeitung können Sie EUDAS aufrufen,
+um Daten aus einer EUDAS-Datei in den Text einzufügen. 
+    EUDAS kann auch in mehreren Spalten drucken (zum Beispiel
+für Etiketten). Schließlich wird noch beschrieben, wie Sie lange
+Felder auf mehrere Zeilen aufteilen können und welche speziellen
+Möglichkeiten Sie zur Erzeugung von Tabellen haben. 
+ 
+#on("b")#Kapitel 13#off("b")# Ab hier beginnt die Beschreibung dessen, was
+die
+Ausgabe des Druckgenerators so ungeheuer anpassungsfähig macht:
+die Verwendung der Programmiersprache ELAN. 
+    Mit einfachsten ELAN-Elementen können Sie komplizierte For­
+matierungswünsche erfüllen. Dazu können Sie den Inhalt von Feld­
+mustern durch vorherige Bearbeitung und durch die Abfrage von
+Bedingungen manipulieren. Ganze Musterteile können in Abhängig­
+keit von Bedingungen variabel gestaltet werden. 
+    Auch der Ablauf von Druckvorgängen kann von Bedingungen
+abhängig gemacht werden. So lassen sich gesteuert Vorspann und
+Nachspann innerhalb des Ausdrucks einfügen und Zwischenüber­
+schriften oder -summen bilden (Gruppenverarbeitung). 
+ 
+#on("b")#Kapitel 14 und 15#off("b")# Für denjenigen, der noch nie mit ELAN zu
+tun
+hatte, werden diese Möglichkeiten sicher nicht ganz einfach zu
+verstehen sein. Obwohl die vorherigen Kapitel viele benutzbare
+Beispiele enthalten, ist zur vollen Ausnutzung ein gewisses Ver­
+ständnis von ELAN notwendig. 
+    Dies soll in den Kapitel 14 und 15 vermittelt werden, und zwar
+in dem Umfang, in dem es in EUDAS nötig ist (Sie sollen hier nicht
+zum ELAN-Programmierer ausgebildet werden). Für den ELAN-
+Kenner bieten diese Kapitel sicher nichts Neues, aber sie enthalten
+viele Beispiele und Beschreibungen der Funktionen, die für EUDAS
+wichtig sind. 
+    Dabei geht Kapitel 15 weiter auf die Sprachmittel für Zählvor­
+gänge, Auswertungen und statistische Anwendungen ein, während in
+Kapitel 14 die grundlegenden Ausdrücke zur Formulierung von
+Manipulationen besprochen werden. 
+ 
+#on("b")#Kapitel 16#off("b")# Im letzten Kapitel geht es dann wieder
+harmloser zu.
+Hier werden die Funktionen beschrieben, die unter EUDAS zur
+allgemeinen Dateiverwaltung zur Verfügung stehen. Im Grunde sind
+dies alles Funktionen, die vom EUMEL-System zur Verfügung ge­
+stellt werden. EUDAS integriert sie lediglich in ein Menüsystem,
+damit Sie als Benutzer die Funktionen möglichst einfach aufrufen
+können. 
+    Aber auch dem erfahrenen EUMEL-Benutzer bieten die Funktio­
+nen einen zusätzlichen Komfort, da auch hier die praktische Aus­
+wahl durch Ankreuzen in allen Funktionen vertreten ist. Außerdem
+wird die Anzahl von Tastendrücken zum Erreichen eines Ziels ver­
+ringert. Daher besteht auch für den "Profi" keine Notwendigkeit,
+grundsätzlich mit einer Kommandoschnittstelle weiterzuarbeiten. 
+ 
+#on("b")#Referenzhandbuch#off("b")# Im Referenzhandbuch sind alle hier
+besproche­
+nen Funktionen noch einmal in einer sehr kurzen, zusammenfassen­
+den und abstrakten Form aufgeführt. Dort sollen Sie nachschlagen,
+wenn Sie eine ganz bestimmte Information suchen und sich mit
+EUDAS bereits auskennen. 
+    Sie können jedoch auch ohne das Referenzhandbuch auskommen,
+denn alles, was Sie wissen müssen, steht auch hier im Benutzer­
+handbuch. 
+    Das Referenzhandbuch enthält auch einen Teil, der sich spe­
+ziell an den ELAN-Programmierer wendet, der besondere Anwendun­
+gen mit EUDAS realisieren will. Allerdings sollten alle dort be­
+schriebenen Möglichkeiten mit Vorsicht betrachtet werden, da sie im
+Normalfall nicht so abgesichert sind, wie die hier beschriebenen
+Fähigkeiten. Auch sollten Sie mit den Einsatzmöglichkeiten von
+ELAN, wie sie in den Kapitel 11 und 13 beschrieben sind, wirklich
+alle praktischen Probleme erledigen können. 
+
diff --git a/doc/eudas/eudas.hdb.9 b/doc/eudas/eudas.hdb.9
new file mode 100644
index 0000000..341feca
--- /dev/null
+++ b/doc/eudas/eudas.hdb.9
@@ -0,0 +1,556 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (83)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+9 Das virtuelle Dateikonzept 
+ 
+ 
+ 
+9.1 Konzept 
+ 
+Bisher haben Sie zu einem Zeitpunkt immer nur eine EUDAS-Datei
+bearbeiten können. Wenn Sie zu einer anderen Datei wechseln woll­
+ten, mußten Sie die eine Datei sichern und die andere Datei wieder
+öffnen. Es gibt jedoch Fälle, in denen Beziehungen zwischen mehre­
+ren Dateien bestehen. Daher kann EUDAS auch mit mehreren Dateien
+gleichzeitig umgehen. 
+    Es hat jedoch Vorteile, wenn man nur mit einer Datei arbeitet.
+Sie müssen dann nicht immer den Namen der gewünschten Datei
+angeben, wenn Sie eine Funktion ausführen. Dies brauchen Sie nur
+einmal beim Öffnen zu tun - danach ist eindeutig festgelegt, wel­
+che Datei gemeint ist. 
+    EUDAS versucht diese Vorteile auch bei mehreren Dateien zu
+erhalten. Die verschiedenen Dateien werden so kombiniert, daß eine
+neue Datei entsteht. Sie arbeiten dann nur mit dieser Datei, die alle
+Daten der Einzeldateien enthält. 
+    Damit Sie aber nicht so lange warten müssen, geschieht dieser
+Kombinationsvorgang erst beim Ansehen. Die kombinierte Datei ist
+also nicht wirklich vorhanden, sondern ihre Einzelsätze werden nur
+bei Bedarf erzeugt. Daher heißt diese Gesamtdatei auch #on("i")#virtuelle#off("i")#
+(scheinbare) Datei. 
+    Eine Kombination von Dateien ist auf zwei Arten möglich. Sie
+können gleichartige Dateien hintereinander#on("i")#ketten#off("i")#, oder Sie können
+Dateien über gemeinsame Felder #on("i")#koppeln#off("i")#. Beide Methoden können
+auch kombiniert werden. 
+ 
+#on("b")#Änderungen#off("b")# Die virtuelle Datei kann auch verändert werden.
+Die
+Veränderungen werden dann in den entsprechenden Ursprungsda­
+teien vorgenommen. Es ist jedoch nicht immer eindeutig, wie diese
+Änderungen aussehen sollen. Achten Sie daher auf die speziellen
+Regeln, die bei solchen Änderungen gelten, damit Sie die Auswir­
+kungen einer Änderung abschätzen können. 
+    Wenn Sie Veränderungen vorgenommen haben, müssen Sie die
+Arbeitskopien anschließend wieder sichern. Denken Sie daran, daß
+EUDAS immer auf unbenannten Kopien arbeitet, wenn Sie ändern
+wollen. Beim Sichern von mehreren Dateien wird Ihnen zu jeder
+Datei einzeln angezeigt, ob sie tatsächlich verändert wurde. Sie
+können dann ebenfalls einzeln entscheiden, ob Sie die Datei sichern
+wollen oder nicht. 
+ 
+ 
+9.2 Ketten 
+ 
+Wenn Sie einmal EUDAS-Dateien mit mehreren tausend Sätzen er­
+stellen, werden Sie feststellen, daß deren Handhabung recht um­
+ständlich sein kann. Da die Datei sehr groß ist, dauern zum Beispiel
+Kopiervorgänge aufs Archiv viel länger als bei kleinen Dateien. 
+    Wenn Sie nun auch noch für jede kleine Änderung die Datei
+vom Archiv holen und anschließend wieder zurückschreiben müssen,
+werden Sie einen Weg suchen, diese Arbeit zu erleichtern. Die ein­
+fachste Möglichkeit wäre, einen schnelleren Rechner zu kaufen. Dies
+ist gleichzeitig aber auch die teuerste. 
+ 
+ 
+#free (4.5)# 
+ 
+#center#Abb. 9-1   Verkettung von A und B 
+ 
+ 
+EUDAS ermöglicht es Ihnen nun, die große Datei in mehrere kleine
+aufzuspalten. In der Regel gibt es bei solch großen Dateien ein
+Kriterium, nach dem die Sätze in verschiedene Dateien verteilt
+werden können. Jede einzelne Datei kann nun bequem geändert
+werden. 
+    Ein Problem entsteht jedoch, wenn alle Dateien zusammen ver­
+arbeitet werden müssen (zum Beispiel beim Drucken). Für einen
+solchen Vorgang können Sie die kleineren Dateien logisch aneinan­
+derketten. 
+    Dies bedeutet für Sie, daß alle kleinen Dateien wie eine große
+Datei wirken. Wenn Sie beim Bewegen in der Datei das Ende einer
+einzelnen Datei erreichen, kommen Sie automatisch an den Anfang
+der nächsten Datei. 
+ 
+#on("b")#Aufruf#off("b")# Damit dies funktioniert, müssen die Dateien
+natürlich
+gleiche Feldstruktur haben. Außerdem ist die Zahl der verkettbaren
+Dateien aus technischen Gründen auf 10 beschränkt. 
+    Sie können die Dateien verketten, indem Sie die Funktion 
+#free (0.2)# 
+ 
+        K Ketten 
+ 
+#free (0.2)# 
+im Menü 'Öffnen' aufrufen. 
+ 
+#on("b")#Änderungen#off("b")# In der virtuellen Datei ist sowohl Einfügen als
+auch
+Ändern erlaubt. Beim Einfügen ist jedoch zu beachten, daß am Ende
+einer Datei nicht angefügt werden kann. Dies liegt daran, daß Sie
+entweder vor dem letzten Satz der einen Datei oder vor dem ersten
+Satz der anderen Datei einfügen. Der Endesatz der einen Datei, der
+normalerweise sichtbar wäre, wird übersprungen. 
+    Am Ende der letzten Datei können Sie natürlich anfügen, da
+deren Endemarkierung als Ende der ganzen Datei ja wieder sichtbar
+ist. 
+ 
+ 
+9.3 Koppeln 
+ 
+Nachdem das Verketten von Dateien noch ganz einfach zu verstehen
+war, kommt jetzt eine Funktion auf Sie zu, die kompliziertere Mög­
+lichkeiten in sich birgt: nämlich das Koppeln. 
+    Es kommt häufiger vor, daß sich ein Feld einer Datei auf einen
+bestimmten Satz in einer anderen Datei bezieht. So könnten zum
+Beispiel die Ausleihen einer Bücherei in folgender Datei gespeichert
+sein: 
+ 
+ 
+        'Name' 
+        'Vorname' 
+        'Datum' 
+        'Buch-Nr.' 
+ 
+ 
+Wenn jetzt ein Ausleiher sein Rückgabedatum überschritten hat,
+möchte die Bücherei dem Kunden ein Mahnschreiben schicken. Auf
+diesem Schreiben soll aber nicht die Buch-Nr. erscheinen, sondern
+Autor und Titel des Buches. 
+    Diese Sekundärinformationen sind in einer anderen Datei ge­
+speichert, der Bestandskartei: 
+ 
+ 
+        'Buch-Nr.' 
+        'Autor' 
+        'Titel' 
+        'Verlag' 
+ 
+ 
+Alle Dateistrukturen hier sind natürlich zwecks größerer Übersicht­
+lichkeit vereinfacht. Um jetzt dem Kunden das Mahnschreiben zu
+schicken, müssen die Informationen in den beiden Dateien korreliert
+werden. 
+ 
+#on("b")#Aufruf#off("b")# Zuerst wird die Ausleihdatei normal geöffnet. Dazu
+wird dann die Bestandsdatei mit Hilfe der Funktion 
+#free (0.2)# 
+ 
+        K Koppeln 
+ 
+#free (0.2)# 
+gekoppelt. Dies hat folgenden Effekt: 
+    Die Sätze erscheinen normal so, wie sie in der Ausleihdatei
+auftauchen, also für jede Ausleihe genau ein Satz. Dazu erscheint
+aber jeweils die Beschreibung des ausgeliehenen Buches aus der
+Bestandsdatei: die beiden Dateien wurden über das Feld "Buch-Nr."
+gekoppelt. 
+    Als Struktur ergibt sich für die kombinierte Datei: 
+ 
+ 
+        'Name' 
+        'Vorname' 
+        'Datum' 
+        'Buch-Nr.' 
+        'Titel' 
+        'Autor' 
+        'Verlag' 
+ 
+ 
+Die Felder der Koppeldatei wurden also noch hinzugefügt. 
+ 
+#on("b")#Koppelfelder#off("b")# Zwei Dinge sind in diesem Zusammenhang
+wichtig:
+Damit der Koppelvorgang ohne allzuviele Vorgaben auskommen kann,
+müssen Felder, über die gekoppelt wird, den gleichen Namen haben
+- und zwar exakt Zeichen für Zeichen. Zum zweiten muß ein solches
+#on("i")#Koppelfeld#off("i")# am Anfang der gekoppelten Datei (in unserem Fall der
+Bestandsdatei) stehen. Dies ist aus technischen Gründen notwendig,
+damit der Koppelvorgang in vernünftiger Geschwindigkeit ablaufen
+kann. 
+ 
+ 
+#free (7.0)# 
+ 
+#center#Abb. 9-2   Schema des Koppelvorgangs 
+ 
+ 
+#on("b")#Mehrere Dateien#off("b")# Genau wie beim Ketten ist die Kombination
+der
+Dateien nicht physikalisch, sondern nur scheinbar vollzogen worden.
+Bis zum Limit der maximal geöffneten Dateien (10) können Sie auch
+weitere Dateien dazukoppeln. Die Koppelfelder dieser Dateien kön­
+nen sich jedoch immer nur auf die erste Datei beziehen, also nicht
+auf eine andere Koppeldatei. 
+    Dies könnte man in unserem Beispiel ausnutzen. Die Bücherei
+hat sicher auch eine Datei ihrer Mitglieder. Diese könnte etwa so
+aussehen: 
+ 
+ 
+        'Name' 
+        'Vorname' 
+        'm/w' 
+        'Strasse' 
+        'PLZ' 
+        'Ort' 
+ 
+ 
+Diese Datei können wir ebenfalls zur Ausleihdatei dazukoppeln.
+Damit haben wir auch gleich die Quelle gewonnen, aus der wir die
+Anschrift für das Mahnschreiben gewinnen können. 
+    Die Kopplung geschieht in diesem Fall über zwei Felder, näm­
+lich 'Name' und 'Vorname'. Damit ein Mitglied eindeutig identifi­
+ziert wird, werden beide Namen gebraucht. Dies berücksichtigt auch
+das Koppelverfahren. Wiederum müssen die Namen exakt mit Namen
+der ersten Datei übereinstimmen. 
+    Wenn mehrere Koppelfelder für eine Koppeldatei notwendig sind,
+müssen Sie alle hintereinander stehen. Wäre die Struktur der Mit­
+gliederdatei etwa 
+ 
+ 
+        'Name' 
+        'Titel' 
+        'Vorname' 
+        'm/w' 
+        'Strasse' 
+        'PLZ' 
+        'Ort' 
+ 
+ 
+würde nur über 'Name' gekoppelt, da 'Titel' in der ersten Datei
+nicht vorkommt. Alle weiteren Felder können dann keine Koppelfel­
+der mehr werden. Durch Umstellen der Feldreihenfolge der Koppel­
+datei (durch Umkopieren) oder durch entsprechende Benennung von
+Feldern können Sie immer den gewünschten Effekt erzielen. 
+ 
+ 
+#free (8.0)# 
+ 
+#center#Abb. 9-3   Aufbau der virtuellen Datei 
+ 
+ 
+#on("b")#Zusammenfassung#off("b")# An dieser Stelle wollen wir die Ergebnisse
+dieses Abschnitts als Regel zusammenfassen: 
+ 
+#limit (12.0)# 
+    Die ersten Felder der Koppeldatei, die wörtlich an be­
+    liebiger Stelle auch in der ersten Datei auftauchen,
+    werden Koppelfelder genannt. Zu einem Satz der ersten
+    Datei wird ein Satz der Koppeldatei gezeigt, der im In­
+    halt der Koppelfelder übereinstimmt. 
+#limit (13.5)# 
+ 
+Übersetzt in unser Beispiel heißt dies: 'Buch-Nr.' bzw. 'Name' und
+'Vorname' sind Koppelfelder. Zu einer bestimmten Ausleihe erschei­
+nen die Daten des Buches mit der angegebenen Buch-Nr. bzw. die
+Adresse des Mitgliedes mit den angegebenen Namen. 
+ 
+ 
+9.4 Auswirkungen des Koppelns 
+ 
+Nachdem Sie nun das Grundprinzip des Koppelns kennen, sollen Sie
+einige Auswirkungen dieses Verfahrens kennenlernen. 
+    Ein Beispiel dazu finden Sie in Abb. 9-4. Dargestellt sind je­
+weils die Satznummern und einige Inhalte. Die zweite Zeile in der
+Hauptdatei und die erste in der Koppeldatei stellen das Koppelfeld
+dar. 
+ 
+ 
+#free (6.5)# 
+ 
+#center#Abb. 9-4   Kombinationen 
+ 
+ 
+#on("b")#Kombinationen#off("b")# Zuerst muß geklärt werden, was passiert,
+wenn es
+keinen passenden Satz in der Koppeldatei gibt. Zum Beispiel könnte
+eine Buchnummer eingegeben worden sein, die in der Bestandsdatei
+nicht existiert. In diesem Fall zeigt EUDAS für die Felder der Kop­
+peldatei einfach einen leeren Inhalt an (siehe Satz 23 der Haupt­
+datei, es gibt keinen Satz mit 'L' in der Koppeldatei). 
+    Wenn umgekehrt zu einem bestimmten Buch keine Ausleihe
+existiert, macht das natürlich nichts - das Buch erscheint nur
+dann, wenn Sie die Bestandsdatei alleine öffnen. 
+    Weiterhin kann es passieren, daß es zwei passende Sätze in der
+Koppeldatei gibt. Dies kommt dann vor, wenn zwei Mitglieder glei­
+chen Namen und gleichen Vornamen haben (was gar nicht so selten
+ist). In diesem Fall zeigt EUDAS beide Kombinationen an (siehe
+Satz 23 der Hauptdatei). Die Ausleihe erscheint also zweimal, je­
+weils mit einem anderen Mitglied. 
+    Damit man diesen Fall ohne weiteres erkennen kann, führt
+EUDAS bei Kopplungen zwei Nummern: zum einen die normale Satz­
+nummer und zum anderen eine Kombinationsnummer. In dem eben
+besprochenen Fall würde die Satznummer gleichbleiben, die Kombi­
+nationsnummer aber hochgezählt werden. Am Bildschirm wird die
+Kombinationsnummer durch Bindestrich getrennt hinter die Satz­
+nummer geschrieben, wenn Sie Dateien koppeln. 
+    Das Durchgehen aller Kombinationen zu einem Satz der Haupt­
+datei passiert aber nur dann, wenn Sie sich mit der Funktion 'Satz
+weiter' in der Datei bewegen. Wenn Sie rückwärts gehen oder auf
+einen bestimmten Satz positionieren, wird immer nur die erste Kom­
+bination angezeigt (Dies hat zum Teil technische Gründe). Beim
+Zurückgehen von Satz 23-1 in dem Beispiel würde also auf Satz
+22-1 positioniert und die Kombination 22-2 übersprungen. 
+ 
+#on("b")#Änderungen#off("b")# Auch wenn Sie Dateien gekoppelt haben, können
+Sie
+immer noch Sätze ändern und einfügen (wenn Sie dies beim Öffnen
+erlaubt haben). Die Auswirkungen der Veränderungen sind jedoch
+nicht mehr ganz so einfach wie bei geketteten Dateien, wo sich die
+Änderungen ja einfach auf den aktuellen Satz bezogen. 
+    Als Grundregel gilt, daß Änderungen möglichst wenig Auswir­
+kungen auf die Koppeldateien haben sollen. Das führt dazu, daß
+beim Einfügen eines neuen Satzes oder beim Entfernen eines Satzes
+durch Tragen keine Aktion in der Koppeldatei durchgeführt wird.
+Dies ist auch nicht nötig, denn wenn zum Beispiel ein neuer (zu­
+nächst leerer) Satz eingefügt wird, existiert sowieso noch kein
+passender Satz in der Koppeldatei und die entsprechenden Felder
+bleiben leer. Hingegen darf beim Entfernen eines Satzes der Satz in
+der Koppeldatei nicht entfernt werden, da er ja noch zu einem an­
+deren Satz gehören könnte. 
+    Änderungen an den Koppelfeldern können nun zu drei verschie­
+denen Reaktionen führen: 
+ 
+1.  Es wird kein Satz der Koppeldatei geändert, sondern nur ein
+    neuer passender Satz gesucht. Dies geschieht immer dann, wenn
+    außer den Koppelfeldern nur leere Inhalte für die Felder der
+    Koppeldatei angegeben sind. Nach dem Ändern oder Einfügen
+    werden dann die Inhalte des neuen Koppelsatzes angezeigt. 
+ 
+    Beispiel: Bei einer Ausleihe geben Sie Name und Vorname des
+    Ausleihers an, nicht aber seine Adresse. Wenn Sie den Satzedi­
+    tor beim Einfügen mit ESC 'q' verlassen, wird die zugehörige
+    Adresse angezeigt (falls der entsprechende Name in der Kop­
+    peldatei vorhanden ist). 
+ 
+2.  Es wird ein neuer Satz in der Koppeldatei angefügt. Dies ge­
+    schieht immer dann, wenn die Koppelfelder verändert wurden
+    und die anderen Felder der Koppeldatei nicht leer sind. Da­
+    durch soll verhindert werden, daß die Koppelfelder in einem
+    Satz verändert werden, der vielleicht noch zu einem anderen
+    Satz paßt. 
+ 
+    Beispiel: Sie geben bei einer Ausleihe auch die Adresse mit
+    an. Wenn eine Person mit gleichem Namen und Vornamen bereits
+    existiert, wird die dort gespeicherte Adresse nicht überschrie­
+    ben. Stattdessen wird die zweite Adresse auch in die Koppel­
+    datei eingetragen. Beim nächsten Ansehen bekommen Sie dann
+    zwei Adressen angezeigt. So wird verhindert, daß Sie ungewollt
+    die erste Adresse vernichten. 
+ 
+3.  Der Satz in der Koppeldatei wird verändert. Dies geschieht nur
+    dann, wenn die Koppelfelder unverändert geblieben sind, der
+    Rest sich aber geändert hat. 
+ 
+    Beispiel: Sie ändern eine Ausleihe mit der zugehörigen
+    Adresse. Sie geben nur eine neue Straße an und lassen Name
+    und Vorname unverändert. Der Satz in der Koppeldatei enthält
+    anschließend die neue Straße. 
+ 
+Da Koppeldateien keine Sortierung besitzen müssen, werden neue
+Sätze der Koppeldatei immer am Ende angefügt. Dies ist zu beach­
+ten, wenn die Koppeldatei auch allein verwendet werden soll. Ge­
+gebenenfalls müssen Sie die Koppeldatei dann erst sortieren. 
+ 
+ 
+9.5 Umschalten auf Koppeldatei 
+ 
+Häufig kommt es vor, daß Sie beim Einfügen eines neuen Satzes mit
+gekoppelten Dateien die Verbindung mit einem existierenden Satz
+der Koppeldatei erreichen wollen, aber den notwendigen Inhalt der
+Koppelfelder nicht auswendig wissen. 
+    So wollen Sie beim Eingeben einer Ausleihe Name und Vorname
+des Entleihers nicht immer wieder abtippen. Dabei ist auch die
+Gefahr von Eingabefehlern sehr groß. Stattdessen wollen Sie lieber
+erst den Entleiher in der Mitgliederdatei suchen und dessen Namen
+dann automatisch in den Entleihsatz übernehmen. 
+    Hierfür bietet Ihnen EUDAS eine Unterstützung an. 
+ 
+#on("b")#Ausführung#off("b")# Während Sie sich in der virtuellen Datei
+befinden,
+können Sie auf eine bestimmte Koppeldatei umschalten, die Sie dann
+wie eine Einzeldatei bearbeiten können. Beim Zurückschalten haben
+Sie dann die Möglichkeit, die Koppelfelder des gefundenen Satzes zu
+übernehmen. 
+    Das Umschalten bewirken Sie durch die Tastenkombination ESC
+'K' (großes K) nur im Menü 'Einzelsatz' sowie im Satzeditor beim
+Einfügen und Ändern. An anderen Stellen hat dieser Befehl keine
+Wirkung. Bei mehreren Koppeldateien werden Ihnen die Dateien der
+Reihenfolge nach angeboten. Durch Verneinung aller Fragen können
+Sie die Funktion ohne Wirkung beenden. 
+    Haben Sie nun umgeschaltet, wird Ihnen die Koppeldatei dar­
+geboten, als hätten Sie sie allein geöffnet. Sie können die Datei
+auch beliebig ändern (wenn Sie dies beim Öffnen angegeben haben).
+Nur die Anzeige <KOPPEL> in der Bildüberschrift zeigt an, daß Sie
+sich in einer Koppeldatei befinden. Sie können auch Funktionen in
+anderen Menüs aufrufen. 
+    Das Zurückschalten geschieht im Menü 'Einzelsatz' mit der
+gleichen Tastenkombination. Alle Einstellungen der virtuellen Datei
+von vorher bis auf die Feldauswahl bleiben erhalten. 
+    Wenn Sie nicht im Menü, sondern im Satzeditor (also beim
+Ändern oder Einfügen) umschalten, werden Sie zunächst wieder aus
+dem Satzeditor rausgeworfen. Sie können dann in der Koppeldatei
+den gewünschten Satz aufsuchen (oder neu eintragen). Beim Zurück­
+schalten werden Sie gefragt, ob Sie die Koppelfelder übernehmen
+wollen oder nicht. Danach kehren Sie automatisch wieder in den
+Satzeditor zurück, wobei jetzt die Koppelfelder gegebenenfalls aus­
+gefüllt oder überschrieben sind. 
+    Durch erneutes Umschalten können Sie den Vorgang auch für
+weitere Koppeldateien wiederholen. 
+    Die Position, die Sie beim Umschalten in der Koppeldatei einge­
+nommen haben, wird bis zum nächsten Umschalten gespeichert. Sie
+kommen dann zunächst wieder auf den gleichen Satz. So können Sie
+die gleichen Koppelfelder wie beim letzten Mal übernehmen, indem
+Sie einfach zweimal ESC 'K' tippen. 
+ 
+#on("b")#Beispiel#off("b")# Der typische Vorgang beim Entleihen würde dann
+wie folgt
+aussehen. Zunächst öffnen Sie die Entleihdatei mit Änderungser­
+laubnis; dann koppeln Sie die Mitgliederdatei und die Bestandsdatei
+dazu. 
+    Für eine neue Ausleihe rufen Sie zunächst die Funktion 'Ein­
+fügen' auf. Dann tippen Sie ESC 'K' und schalten auf die Mitglie­
+derdatei um. Dort suchen Sie das Mitglied und schalten wieder zu­
+rück. Existierte das Mitglied noch nicht, können Sie es gleich ein­
+tragen. Beim Zurückschalten übernehmen Sie den Namen des Mit­
+glieds. 
+    Dann tragen Sie die Nummer des Buches ein (die müssen Sie nur
+dann suchen, wenn Sie nicht auf dem Buch steht). Das Entleihdatum
+erhalten Sie mit Hilfe der Tastenkombination ESC 'D' (wird im näch­
+sten Kapitel beschrieben). 
+    Wollen Sie mehrere Ausleihen für ein Mitglied eintragen, so
+tippen Sie beim nächsten Einfügen einfach zweimal ESC 'K', ohne
+dazwischen eine Positionierung vorzunehmen. 
+ 
+ 
+9.6 Mehrfachbenutzung 
+ 
+EUDAS ermöglicht es mehreren Benutzern an einem Rechner, mit den
+gleichen Dateien zu arbeiten. Dies ist eigentlich nichts Besonderes,
+denn das EUMEL-System ist ja bereits von Haus aus dazu geeignet.
+Es müssen jedoch einige Schutzvorkehrungen getroffen werden,
+damit dadurch keine Probleme entstehen. 
+    Als Grundvoraussetzung für die Mehrfachbenutzung müssen
+EUDAS-Dateien in einer unabhängigen #on("i")#Managertask#off("i")# gespeichert
+sein. Eine Managertask kann man sich durch das Kommando 'global
+manager' einrichten. In dieser Task sollte dann nicht mehr gearbei­
+tet werden. 
+    Stattdessen kann sich der Benutzer Dateien aus dieser Mana­
+gertask kopieren und auch wieder dorthin zurückschreiben. Wie Sie
+dies im EUDAS-Menü bewerkstelligen können, wird im Kapitel 16
+beschrieben. Es sei nochmal betont, daß dies eine Methode ist, die
+Sie für beliebige Dateien verwenden können. 
+    Im Kapitel 16 ist weiterhin auch beschrieben, wie Sie solche
+Dateien mit #on("i")#Passworten#off("i")# schützen können, so daß sie nicht jeder
+benutzen kann. Schauen Sie bei Bedarf dort nach. 
+ 
+ 
+#free (7.7)# 
+ 
+#center#Abb. 9-5   Mehrfachbenutzung 
+ 
+ 
+#on("b")#Konflikte#off("b")# Wir wollen uns jedoch jetzt um ein Problem
+kümmern, das
+bei dieser Art von Mehrfachbenutzung auftritt. Nehmen wir an,
+unsere Bücherei habe zwei Plätze, an denen Entleihen durchgeführt
+werden können. Beide Plätze sollen mit der gleichen Entleihdatei
+arbeiten (wie Sie gleich noch sehen werden und aus anderen Grün­
+den würde man EUDAS für eine solche Bücherei nicht einsetzen -
+wir wollen hier nur das Prinzip illustrieren). 
+    Der Ablauf wäre dann folgendermaßen. Jeder Platz kopiert sich
+für eine Entleihe die gemeinsame Datei aus der Managertask, öffnet
+sie, trägt die Entleihe ein und sichert die Datei wieder. Dann wird
+die Datei in die Managertask zurückgeschrieben, wo sie die alte
+Entleihdatei ersetzt. 
+    Abgesehen von dem viel zu hohen manuellen Aufwand kann der
+Fall eintreten, daß beide gleichzeitig eine Entleihe bearbeiten.
+Nehmen wir an, beide benutzen die Entleihdatei mit dem symboli­
+schen Inhalt A. Auf Platz 1 kommt noch die Entleihe B, auf Platz 2
+die Entleihe C dazu. Platz 1 will anschließend den Inhalt AB zu­
+rückschreiben, Platz 2 den Inhalt AC. 
+    Je nach der zeitlichen Reihenfolge wird nur eine der beiden
+Versionen übrigbleiben, da derjenige, der später zurücksichert, die
+vorherige Version überschreibt. Richtig sollte die endgültige Version
+ABC herauskommen. Unser Beispiel führt jedoch auf jeden Fall zu
+einer fehlerhaften Datei. 
+    Grund dafür ist, daß beim Zurückschreiben der ganzen Datei ein
+Platz gesperrt werden muß, während der andere Platz eine Datei
+zum Ändern angefordert hat. Man könnte auch dazu übergehen, nur
+einzelne Sätze zu übertragen; diese Methode wird jedoch von EUDAS
+wegen des hohen Aufwandes nicht unterstützt (daher würde man
+EUDAS eben auch nicht für eine Mehrplatz-Bücherei nehmen). 
+    In vielen Fällen reicht das Sperren ganzer Dateien jedoch aus,
+besonders, wenn nicht ganz so häufig an einzelnen Sätzen geändert
+wird. EUDAS bietet dafür neben der notwendigen Sperre auch noch
+eine automatische Versendung der Dateien an. 
+ 
+#on("b")#Manager#off("b")# Es bietet sich an, dieses Kopieren der Dateien
+beim Öff­
+nen (auch Koppeln und Ketten) und Sichern automatisch durchzu­
+führen. Als Voraussetzung dafür müssen Sie EUDAS angeben, mit
+welcher Managertask Sie arbeiten wollen. Dazu dient die Funktion 
+#free (0.2)# 
+ 
+        M Manager 
+ 
+#free (0.2)# 
+im Menü 'Öffnen'. Sie werden dann nach dem Namen der Task ge­
+fragt. Geben Sie keinen Namen an, wird der Managermodus wieder
+ausgeschaltet. Welche Task als Manager eingestellt ist, sehen Sie in
+der untersten Bildschirmzeile. 
+    In der Task, die Sie angeben, muß EUDAS insertiert sein (oder
+in einem Vater), da sonst die Sperre nicht funktioniert. 
+    Wenn Sie nun einen solchen Manager angegeben haben, können
+Sie beim Öffnen Dateinamen aus dieser Task angeben. Auch bei ESC
+'z' werden Ihnen alle Namen aus dem Manager mit angeboten. Wenn
+Sie einen solchen Namen angeben, der nicht aus Ihrer eigenen Task
+stammt, wird die Datei vor dem Öffnen automatisch kopiert. Wenn
+Sie angegeben haben, daß Sie die Datei verändern wollen, wird in
+der Managertask eine entsprechende Sperre gesetzt. 
+    Wenn Sie die Datei nach Änderungen dann sichern, wird die
+geänderte Kopie zurückgeschrieben. Die Sperre wird jedoch erst
+dann aufgehoben, wenn Sie die Arbeitskopien endgültig löschen. 
+    Möchte nun ein anderer Benutzer diese Datei öffnen, während
+Sie sie ändern, kann er dies nur, wenn er sie nicht ändern will.
+Natürlich wird die Datei dann auch nicht wieder zurückgeschickt.
+Will er sie ändern, erhält er eine Fehlermeldung und kann den
+Versuch später wiederholen. 
+ 
+#on("b")#Vorsichtsmaßregeln#off("b")# Bedenken Sie, daß der Schutz nur
+wirksam sein
+kann, wenn Sie diesen Vorgang nicht unter Umgehung der Menü­
+steuerung ausführen. Würden Sie sich zum Beispiel eine Datei vom
+Manager holen (s. Kapitel 16), ohne daß Sie ein Änderungsvorhaben
+anmelden können, können Sie diese Datei ja trotzdem ändern und
+wieder zurückschicken. In diesem Fall hat EUDAS keine Kontrolle
+mehr über die Datei. 
+    Aus dem gleichen Grund sollten Sie sich die Managertask auch
+nicht an Ihren Bildschirm holen, denn auch dann könnten Sie ohne
+Kontrolle Änderungen durchführen (zudem kann der Manager wäh­
+rend dieser Zeit nicht auf andere Benutzer reagieren). 
+    Nur wenn Sie eine neue Datei im Manager anlegen, müssen Sie
+dies von Hand tun. Dazu erstellen Sie die Datei ganz normal und
+schreiben Sie mit der in Kapitel 16 beschriebenen Funktion zum
+Manager. Sie sollten jedoch darauf achten, daß dort nicht schon
+eine Datei gleichen Namens liegt (EUDAS fragt ja dann, ob über­
+schrieben werden soll). 
+
diff --git a/doc/eudas/eudas.hdb.inhalt b/doc/eudas/eudas.hdb.inhalt
new file mode 100644
index 0000000..62134f8
--- /dev/null
+++ b/doc/eudas/eudas.hdb.inhalt
@@ -0,0 +1,133 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+Inhalt 
+ 
+ 
+ 
+      Vorwort  . . . . . . . . . . . . . . . . . . .  i 
+      Inhalt . . . . . . . . . . . . . . . . . . . .  iii 
+ 
+ 
+I. Die ersten Schritte 
+ 
+#on("b")#1   Was kann EUDAS ?#off("b")# 
+#free (0.2)# 
+1.1   Textverarbeitung und Datenverwaltung . . . . .  3 
+1.2   EUDAS als Karteikasten . . . . . . . . . . . .  5 
+1.3   Drucken  . . . . . . . . . . . . . . . . . . .  7 
+1.4   Grenzen  . . . . . . . . . . . . . . . . . . .  9 
+ 
+#on("b")#2   Installation#off("b")# 
+#free (0.2)# 
+2.1   Lieferumfang . . . . . . . . . . . . . . . . .  11 
+2.2   Single-User  . . . . . . . . . . . . . . . . .  12 
+2.3   Multi-User . . . . . . . . . . . . . . . . . .  13 
+ 
+#on("b")#3   Ein Beispiel zum Ausprobieren#off("b")# 
+#free (0.2)# 
+3.1   Start  . . . . . . . . . . . . . . . . . . . .  15 
+3.2   Daten eintragen  . . . . . . . . . . . . . . .  16 
+3.3   Daten abfragen . . . . . . . . . . . . . . . .  21 
+3.4   Drucken  . . . . . . . . . . . . . . . . . . .  22 
+3.5   Ergebnis . . . . . . . . . . . . . . . . . . .  24 
+ 
+ 
+II. Einführung in die Benutzung 
+ 
+#on("b")#4   Umgang mit Dateien und Menüs#off("b")# 
+#free (0.2)# 
+4.1   EUDAS-Dateien  . . . . . . . . . . . . . . . .  27 
+4.2   EUDAS-Menüs  . . . . . . . . . . . . . . . . .  29 
+4.3   Archivmenü . . . . . . . . . . . . . . . . . .  32 
+4.4   Dateiverwaltung  . . . . . . . . . . . . . . .  37 
+4.5   Bedienungsregeln . . . . . . . . . . . . . . .  39 
+ 
+#on("b")#5   Gespeicherte Daten abfragen#off("b")# 
+#free (0.2)# 
+5.1   Öffnen . . . . . . . . . . . . . . . . . . . .  43 
+5.2   Bewegen  . . . . . . . . . . . . . . . . . . .  45 
+5.3   Suchen . . . . . . . . . . . . . . . . . . . .  46 
+5.4   Suchbedingungen  . . . . . . . . . . . . . . .  49 
+ 
+#on("b")#6   Daten eingeben und ändern#off("b")# 
+#free (0.2)# 
+6.1   Neue Datei einrichten  . . . . . . . . . . . .  51 
+6.2   Sätze einfügen . . . . . . . . . . . . . . . .  52 
+6.3   Daten ändern . . . . . . . . . . . . . . . . .  55 
+6.4   Arbeitskopie sichern . . . . . . . . . . . . .  56 
+ 
+#on("b")#7   Ausdrucken der Daten#off("b")# 
+#free (0.2)# 
+7.1   Druckmuster  . . . . . . . . . . . . . . . . .  61 
+7.2   Aufruf . . . . . . . . . . . . . . . . . . . .  64 
+7.3   Abschnitte . . . . . . . . . . . . . . . . . .  67 
+7.4   Feldmuster . . . . . . . . . . . . . . . . . .  69 
+ 
+#on("b")#8   Was war und was noch kommt#off("b")# 
+#free (0.2)# 
+8.1   Rückblick  . . . . . . . . . . . . . . . . . .  75 
+8.2   Ausblick . . . . . . . . . . . . . . . . . . .  76 
+ 
+ 
+III. Weitere Möglichkeiten 
+ 
+#on("b")#9   Das virtuelle Dateikonzept#off("b")# 
+#free (0.2)# 
+9.1   Konzept  . . . . . . . . . . . . . . . . . . .  83 
+9.2   Ketten . . . . . . . . . . . . . . . . . . . .  84 
+9.3   Koppeln  . . . . . . . . . . . . . . . . . . .  85 
+9.4   Auswirkungen des Koppelns  . . . . . . . . . .  89 
+9.5   Umschalten auf Koppeldatei . . . . . . . . . .  92 
+9.6   Mehrfachbenutzung  . . . . . . . . . . . . . .  93 
+ 
+#on("b")#10  Datenabfrage am Bildschirm#off("b")# 
+#free (0.2)# 
+10.1  Feldauswahl  . . . . . . . . . . . . . . . . .  97 
+10.2  Satzeditor . . . . . . . . . . . . . . . . . .  98 
+10.3  Suchmuster . . . . . . . . . . . . . . . . . .  99 
+10.4  Markieren  . . . . . . . . . . . . . . . . . .  104 
+10.5  Übersicht  . . . . . . . . . . . . . . . . . .  105 
+ 
+#on("b")#11  Funktionen zur Bearbeitung#off("b")# 
+#free (0.2)# 
+11.1  Sortieren  . . . . . . . . . . . . . . . . . .  109 
+11.2  Kopieren . . . . . . . . . . . . . . . . . . .  112 
+11.3  Tragen . . . . . . . . . . . . . . . . . . . .  118 
+11.4  Automatische Änderungen  . . . . . . . . . . .  121 
+ 
+#on("b")#12  Weitere Möglichkeiten zum Drucken#off("b")# 
+#free (0.2)# 
+12.1  Anschluß an die Textverarbeitung . . . . . . .  123 
+12.2  Spaltendruck . . . . . . . . . . . . . . . . .  126 
+12.3  Modi . . . . . . . . . . . . . . . . . . . . .  128 
+ 
+#on("b")#13  Programmierung von Druckmustern#off("b")# 
+#free (0.2)# 
+13.1  Abkürzungen  . . . . . . . . . . . . . . . . .  133 
+13.2  Bedingte Musterteile . . . . . . . . . . . . .  141 
+13.3  Übersetzung  . . . . . . . . . . . . . . . . .  142 
+13.4  Gruppen  . . . . . . . . . . . . . . . . . . .  144 
+ 
+#on("b")#14  Ausdrücke in ELAN#off("b")# 
+#free (0.2)# 
+14.1  Was sind Ausdrücke ? . . . . . . . . . . . . .  151 
+14.2  Datentypen . . . . . . . . . . . . . . . . . .  152 
+14.3  TEXT-Funktionen  . . . . . . . . . . . . . . .  156 
+14.4  Rechenfunktionen . . . . . . . . . . . . . . .  160 
+14.5  Abfragen . . . . . . . . . . . . . . . . . . .  161 
+ 
+#on("b")#15  Anweisungen in ELAN#off("b")# 
+#free (0.2)# 
+15.1  Variablen und Zuweisungen  . . . . . . . . . .  165 
+15.2  Weitere Konstruktionen . . . . . . . . . . . .  168 
+ 
+#on("b")#16  Dateiverwaltung mit EUDAS#off("b")# 
+#free (0.2)# 
+16.1  Dateien im System  . . . . . . . . . . . . . .  171 
+16.2  Dateien auf dem Archiv . . . . . . . . . . . .  174 
+ 
+ 
+IV. Anhang 
+ 
+      Register . . . . . . . . . . . . . . . . . . .  181 
+
diff --git a/doc/eudas/eudas.hdb.macros b/doc/eudas/eudas.hdb.macros
new file mode 100644
index 0000000..d06e6d1
--- /dev/null
+++ b/doc/eudas/eudas.hdb.macros
@@ -0,0 +1,80 @@
+#*format# 
+#limit (13.5)##start (3.5,2.5)##pagelength (21.0)##block# 
+#:firsthead (false)# 
+#linefeed (1.07)# 
+#*macro end# 
+#*text# 
+#type ("prop10")# 
+#linefeed (1.07)# 
+#*macro end# 
+#*beispiel# 
+#type ("12")# 
+#linefeed (0.97)# 
+#*macro end# 
+#*bildschirm# 
+#type ("17")# 
+#linefeed(0.83)# 
+#*macro end# 
+#*proc# 
+#type ("12")# 
+#*macro end# 
+#*endproc# 
+#free (0.1)# 
+#type ("prop10")# 
+#linefeed (1.0)# 
+#*macro end# 
+#*abschnitt ($1,$2,$3)# 
+#headodd# 
+#on("b")#$1#right#$3    %#off("b")# 
+#free (1.0)# 
+#end# 
+#on("b")##ib(9)#$1#ie(9,"   $3")# $2#off("b")# 
+#*macro end# 
+#*char($1)# 
+$1
+#*macro end# 
+#*kapitel ($1,$2,$3,$4)# 
+#free (1.3)# 
+#"nlq"# 
+#type("roman.24")# 
+#on("b")##center#$1#off("b")# 
+#free (0.2)# 
+#type ("roman.18")# 
+#on("b")##center#$2 #off("b")# 
+#on("b")##center# $3#off("b")# 
+#on("b")##center#$4#off("b")# 
+#type ("prop10")# 
+#free (0.6)# 
+#headeven# 
+#on("b")#%    $2 $3 $4#off("b")# 
+#free (1.0)# 
+#end# 
+#headodd# 
+#right##on("b")#%#off("b")# 
+#free (1.0)# 
+#end# 
+#*macro end# 
+#*f2# 
+#free (0.2)# 
+#*macro end# 
+#*a ($1)# 
+#on("b")#$1.#off("b")# 
+#*macro end# 
+#*bsp ($1)# 
+#type("12")#$1#type("prop")#
+#*macro end# 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/eudas/eudas.hdb.titel b/doc/eudas/eudas.hdb.titel
new file mode 100644
index 0000000..b8cc805
--- /dev/null
+++ b/doc/eudas/eudas.hdb.titel
@@ -0,0 +1,99 @@
+#limit (14.0)# 
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#E U D A S 
+ 
+ 
+ 
+ 
+#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# 
+ 
+#free (6.0)# 
+#on("b")#EUDAS#off("b")# 
+#free (1.0)# 
+#on("b")#Anwender-#off("b")# 
+#on("b")#Datenverwaltungssystem#off("b")# 
+#free (2.0)# 
+#on ("b")#VERSION 4#off("b")# 
+#free(1.0)# 
+#on("u")#                                                    #off("u")# 
+#free (0.5)# 
+#on("b")#BENUTZERHANDBUCH#off("b")# 
+#block# 
+#page# 
+#free (12.0)# 
+Ausgabe Juli 1987 
+ 
+Dieses Handbuch und das zugehörige Programm sind urheberrechtlich
+geschützt. Die dadurch begründeten Rechte, insbesondere der Ver­
+vielfältigung in irgendeiner Form, bleiben dem Autor vorbehalten. 
+ 
+Es kann keine Garantie dafür übernommen werden, daß das Pro­
+gramm für eine bestimmte Anwendung geeignet ist. Die Verantwor­
+tung dafür liegt beim Kunden. 
+ 
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrekt­
+heit und Vollständigkeit der Angaben wird aber keine Gewähr über­
+nommen. Das Handbuch kann jederzeit ohne Ankündigung geändert
+werden. 
+ 
+(c) Copyright 1987  Thomas Berlage 
+                    Software-Systeme 
+                    Im alten Keller 3 
+#free (0.1)# 
+                    D-5205 Sankt Augustin 1 
+#page# 
+#free (7.0)# 
+#center##on("b")#I.#off("b")# 
+#free (1.0)# 
+#center##on("b")#DIE#off("b")# 
+#center##on("b")#ERSTEN#off ("b")# 
+#center##on("b")#SCHRITTE#off("b")# 
+#page# 
+#free (7.0)# 
+#center##on("b")#II.#off("b")# 
+#free (1.0)# 
+#center##on("b")#EINFÜHRUNG#off("b")# 
+#center##on("b")#IN DIE#off ("b")# 
+#center##on("b")#BENUTZUNG#off("b")# 
+#page# 
+#free (7.0)# 
+#center##on("b")#III.#off("b")# 
+#free (1.0)# 
+#center##on("b")#WEITERE#off("b")# 
+#center##on("b")#MÖGLICHKEITEN#off("b")# 
+#page# 
+#free (7.0)# 
+#center##on("b")#IV.#off("b")# 
+#free (1.0)# 
+#center##on("b")#ANHANG#off("b")# 
+
+
+
+
+
+
+
+
diff --git a/doc/eudas/eudas.hdb.vorwort b/doc/eudas/eudas.hdb.vorwort
new file mode 100644
index 0000000..6f7f17c
--- /dev/null
+++ b/doc/eudas/eudas.hdb.vorwort
@@ -0,0 +1,89 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#EUDAS 
+ 
+ 
+ 
+ 
+#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# 
+Vorwort 
+ 
+ 
+ 
+Lieber EUDAS-Benutzer ! 
+ 
+Dieses Handbuch soll Sie bei Ihrer Arbeit mit EUDAS begleiten. Ob­
+wohl EUDAS nicht schwierig zu bedienen ist, gibt es doch eine Reihe
+von Dingen zu lernen, ehe Sie ein EUDAS-Spezialist geworden sind. 
+    Um Ihnen diesen Weg möglichst einfach zu machen, ist die
+EUDAS-Dokumentation in zwei Handbücher aufgeteilt. Dies ist das
+#on("b")#Benutzerhandbuch#off("b")#, das Ihnen eine gut lesbare Einführung in alle
+Fähigkeiten von EUDAS bieten soll. Außerdem gibt es noch das
+#on("b")#Referenzhandbuch#off("b")#, das Ihnen zum Nachschlagen und als Hilfe beim
+Programmieren dienen soll. 
+ 
+    Bis Sie EUDAS gut beherrschen, sollten Sie sich also mit dem
+Benutzerhandbuch beschäftigen. Das Benutzerhandbuch ist nochmal
+in drei Teile aufgeteilt, um Ihnen das Lernen zu erleichtern. In
+jedem Teil werden die vorher behandelten Dinge zyklisch wieder
+aufgenommen und auf höherem Niveau erweitert. 
+    Der allererste Teil des Handbuchs umfaßt nur drei Kapitel und
+soll Ihnen über den ersten Tag mit EUDAS hinweghelfen. Dort finden
+Sie eine Übersicht, was Sie mit EUDAS anfangen können, wie Sie das
+Programm auf Ihrem Rechner installieren und ein kurzes Beispiel
+zum Ausprobieren. 
+    Im zweiten Teil lernen Sie dann die Grundkonzepte von EUDAS
+anhand von zahlreichen Beispielen kennen. Sie sollten die Beispiele
+am Rechner ausprobieren und ihre Bedeutung verstehen. Nach dem
+Durcharbeiten dieses Teils (was höchstens wenige Tage in Anspruch
+nimmt) sind Sie dann in der Lage, EUDAS für eigene Zwecke anzu­
+wenden. 
+    Wenn Ihre Ansprüche dann wachsen, sollten Sie sich mit dem
+dritten Teil befassen. Hier erhalten Sie Einblick in weitergehende
+Möglichkeiten von EUDAS. Die einzelnen Kapitel sind relativ unab­
+hängig voneinander, so daß Sie nur die für Sie interessanten
+genauer durchlesen müssen. 
+   In Kapitel 8 finden Sie als Orientierung nicht nur eine Wieder­
+holung dessen, was Sie im zweiten Teil gelernt haben sollten, son­
+dern auch eine Übersicht, welche weiteren Möglichkeiten im dritten
+Teil noch beschrieben werden. 
+ 
+    Im Referenzhandbuch finden Sie später, wenn Sie einige Erfah­
+rung gesammelt haben, eine genaue Beschreibung der Wirkungsweise
+aller Funktionen. Um diese zu verstehen, sollten Sie jedoch bereits
+eine grobe Ahnung der Wirkungsweise haben. 
+    Als zweites finden Sie im Referenzhandbuch Informationen für
+Programmierer, die EUDAS-Funktionen in eigenen Programmen ver­
+wenden wollen. Dies sollte jedoch in den meisten Fällen nicht not­
+wendig sein, so daß dieser Teil für Spezialisten reserviert bleibt. 
+ 
+    Trotz größter Bemühungen kann das Handbuch natürlich nicht
+frei von Unklarheiten und Fehlern sein. Anregungen und Kritik sind
+daher dringend erwünscht, um diese Dokumentation zu verbessern. 
+ 
+Und nun viel Spaß bei Ihrer Arbeit mit EUDAS ! 
+
diff --git a/doc/eudas/eudas.ref.1 b/doc/eudas/eudas.ref.1
new file mode 100644
index 0000000..7c66368
--- /dev/null
+++ b/doc/eudas/eudas.ref.1
@@ -0,0 +1,326 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (3)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+Zustände und Bedienung 
+ 
+ 
+ 
+1.1 Zustände
+ 
+EUDAS befindet sich zu jeder Zeit in einem von 11 verschiedenen
+Zuständen. Für jeden Zustand ist festgelegt, welche Eingabetasten
+benutzt werden können und welche Wirkung sie haben. Bestimmte
+Tastenfunktionen führen in einen anderen Zustand. Obwohl für
+jeden Zustand andere Tastenkombinationen gültig sind, wird für die
+gleiche Funktion in jedem Zustand auch die gleiche Taste oder
+Tastenkombination verwendet. 
+    Die wichtigsten Tastenfunktionen eines Zustandes werden in
+der #on("i")#Statuszeile#off("i")# am oberen Bildschirmrand angezeigt. 
+    Im folgenden sind alle möglichen Zustände als Übersicht be­
+schrieben. Eine Übersicht der Zustandsübergänge enthält Abb. 1-1. 
+    Zu jedem Zustand wird die entsprechende Statuszeile darge­
+stellt sowie alle möglichen Tastenfunktionen und ihre Bedeutung. 
+ 
+EUDAS:   Öffnen   Einzelsatz   Gesamtdatei   Drucken   Dateien   Archiv 
+ 
+_____________________________________________________ 
+ 
+OBEN         Anwahl der nächsthöheren Funktion 
+UNTEN        Anwahl der nächsttieferen Funktion 
+RECHTS       Anwahl des nächsten Menüs zur Rechten 
+LINKS        Anwahl des nächsten Menüs zur Linken 
+HOP OBEN     Anwahl der ersten Funktion 
+HOP UNTEN    Anwahl der letzten Funktion 
+'1' .. '6'   Anwahl des entsprechenden Menüs 
+LEER         Ausführen der gewählten Funktion 
+'Buchstabe'  Ausführen der Funktion mit 'Buchstabe' davor 
+ESC '?'      Hilfestellung zur gewählten Funktion 
+ESC ESC      Eingabe von ELAN-Kommandos 
+ 
+ 
+HILFE:    Beenden: ESC q    Seite weiter: ESC w    Seite zurueck: ESC z 
+ 
+_____________________________________________________ 
+ 
+ESC 'w'      Blättern zur nächsten Seite 
+ESC 'z'      Blättern zur vorigen Seite 
+ESC 'q'      Verlassen (Rückkehr in alten Zustand) 
+ 
+ 
+AUSWAHL:  Ankreuzen: 'x'  Durchstreichen: 'o'  Beenden: ESC q  Hilfe: ESC ? 
+ 
+_____________________________________________________ 
+ 
+'x'          Auswahl ankreuzen 
+'o'          Ankreuzen rückgängig machen 
+LEER         Ankreuzen und Auswahl sofort verlassen 
+OBEN         Zur nächsten Auswahl nach oben 
+UNTEN        Zur nächsten Auswahl nach unten 
+HOP OBEN     Zur obersten Auswahl bzw. eine Seite zurück 
+HOP UNTEN    Zur untersten Auswahl bzw. eine Seite weiter 
+HOP RETURN   Aktuelle Auswahl wird erste auf der Seite 
+ESC '1'      zur ersten Auswahl 
+ESC '9'      zur letzten Auswahl 
+ESC 'q'      Auswahl verlassen und weitermachen 
+ESC '?'      Hilfe zur Auswahl 
+HOP 'x'      alle freien Wahlen ankreuzen 
+HOP 'o'      alle Kreuze entfernen 
+ESC 'h'      Auswahl und Funktion abbrechen 
+ 
+ 
+EINGABE:  Bestätigen: RETURN  Zeigen: ESC z  Abbrechen: ESC h  Hilfe: ESC ? 
+ 
+_____________________________________________________ 
+ 
+RECHTS       zum nächsten Zeichen 
+LINKS        zum vorigen Zeichen 
+HOP RECHTS   zum letzten Zeichen 
+HOP LINKS    zum ersten Zeichen 
+RUBOUT       Zeichen löschen 
+RUBIN        Einfügemodus umschalten 
+HOP RUBOUT   Rest der Zeile löschen 
+'Zeichen'    Zeichen überschreiben oder einfügen 
+RETURN       Eingabe abschließen und weitermachen 
+ESC '?'      Hilfe zur Eingabe 
+ESC 'h'      Eingabe und Funktion abbrechen 
+ESC 'z'      Auswahl zeigen (falls in Statuszeile aufgeführt) 
+ 
+ 
+FRAGE:   Bejahen: j,J   Verneinen: n,N   Abbrechen: ESC h   Hilfe: ESC ? 
+ 
+_____________________________________________________ 
+ 
+'j', 'J'     Frage bejahen 
+'n', 'N'     Frage verneinen 
+ESC '?'      Hilfe zur Frage 
+ESC 'h'      Frage und Funktion abbrechen 
+ 
+ 
+!!! FEHLER !!!     Quittieren: ESC q     Hilfe zur Meldung: ESC ? 
+ 
+_____________________________________________________ 
+ 
+ESC '?'      Hilfe zum Fehler 
+ESC 'Taste'  Fehler quittieren 
+'Taste'      Fehler quittieren 
+ 
+ 
+SATZ ÄNDERN:    Abbruch: ESC h    Beenden: ESC q    Hilfe: ESC ? 
+SATZ EINFÜGEN:    Abbruch: ESC h    Beenden: ESC q    Hilfe: ESC ? 
+SUCHMUSTER EINGEBEN:    Abbruch: ESC h    Beenden: ESC q    Hilfe: ESC ? 
+ 
+_____________________________________________________ 
+ 
+ESC OBEN     eine Seite zurück blättern 
+ESC UNTEN    eine Seite vor blättern 
+ESC '?'      Hilfe zum Satzeditor 
+ESC 'p'      ganzen Satz merken (nicht bei Suchmuster) 
+ESC 'g'      Satz durch gemerkten ersetzen (nicht bei Such­
+             muster) 
+ESC 'h'      Abbruch der Funktion 
+ESC 'D'      Tagesdatum schreiben 
+ESC 'F'      Prüffehler nach Tragen editieren 
+ESC 'w'      Verlassen und mit nächstem Satz erneut aufrufen
+             (nicht im Suchmuster) 
+ESC 'z'      Verlassen und mit vorigem Satz erneut aufrufen
+             (nicht im Suchmuster) 
+ESC RUBIN    Rest der Zeile in neue Zeile umbrechen 
+ESC RUBOUT   Rest der Zeile löschen 
+HOP RUBIN    nicht verwenden! 
+HOP RUBOUT   nicht verwenden! 
+ 
+Weitere Tasten siehe EUMEL-Benutzerhandbuch (Editor). 
+ 
+ 
+Bitte warten.. 
+ 
+_____________________________________________________ 
+ 
+keine Tasten erlaubt (außer SV) 
+ 
+ 
+ZEIGEN:   Blättern: HOP OBEN, HOP UNTEN   Ende: ESC q   Hilfe: ESC ? 
+ 
+_____________________________________________________ 
+ 
+HOP OBEN     auf erste Zeile bzw. eine Seite zurück 
+HOP UNTEN    auf letzte Zeile bzw. eine Seite vor 
+ESC '?'      Hilfe zur Übersicht 
+ESC 'h'      Abbruch der Funktion 
+ESC 'q'      Verlassen 
+ 
+ 
+EDITIEREN:   Abbruch: ESC h   Verlassen: ESC q   Hilfe: ESC ? 
+ 
+_____________________________________________________ 
+ 
+ESC 'F'      Feldnamen anzeigen und auswählen 
+ESC 'h'      Abbruch der Funktion 
+ 
+Weitere Tasten siehe EUMEL-Benutzerhandbuch (Editor). 
+ 
+ 
+Gib Kommando: 
+ 
+_____________________________________________________ 
+ 
+Tasten siehe EINGABE. 
+ 
+ 
+#free (18.5)# 
+ 
+#center#Abb. 1-1   Zustandsübergänge 
+ 
+ 
+ 
+ 
+1.2 Menüs 
+ 
+Menüs dienen zur Auswahl von Funktionen. Sie werden am linken
+Rand des Bildschirms angezeigt. Welches Menü aktiv ist, wird durch
+Markierung des Menünamens in der obersten Bildschirmzeile unter
+allen zur Verfügung stehenden Menüs angezeigt. In jedem Menü ist
+die zuletzt ausgeführte Funktion ebenfalls markiert. 
+ 
+#on("b")#Ausführen von Funktionen#off("b")# Zum Ausführen einer bestimmten
+Funk­
+tion wird mit Hilfe der Cursortasten ein bestimmtes Menü und die
+gewünschte Funktion angewählt. Die Funktion wird dann durch
+Drücken der Leertaste ausgeführt. Alternativ kann auch der vor der
+Funktion stehende Buchstabe gedrückt werden. 
+    Die einzelnen Menüs können auch durch Nummern (1 bis 6)
+angewählt werden (absolute Positionierung). 
+    Soll eine andere Taste als die Leertaste zum Ausführen ver­
+wendet werden, so kann dies durch die Prozedur 'ausfuehrtaste'
+angegeben werden (s. Abschnitt 10.3). 
+    Funktionen, deren Ausführung augenblicklich nicht möglich
+oder nicht sinnvoll ist, werden durch ein vorangestelltes Minuszei­
+chen gekennzeichnet. Sie können zwar angewählt, nicht aber ausge­
+führt werden. 
+    Durch ESC '?' wird ein erläuternder Hilfstext zur gerade ange­
+wählten Funktion angezeigt. Näheres dazu s. Abschnitt 1.4. 
+    Durch ESC ESC kann ein beliebiges ELAN-Kommando eingegeben
+und ausgeführt werden. Die Eingabe des Kommandos erfolgt in der
+Statuszeile. 
+ 
+ 
+1.3 Auswahl 
+ 
+Die Auswahlfunktion dient dazu, aus vorhandenen Datei- oder
+Feldnamen in bestimmter Reihenfolge auszuwählen. Die einzelnen
+Namen werden untereinander aufgelistet. 
+    Vor jedem Namen ist ein 'o' zum Ankreuzen angegeben. Mit den
+Cursortasten kann der Cursor vor einen bestimmten Namen positio­
+niert werden. Mit 'x' kann dieser Name dann angekreuzt werden. Das
+Ankreuzen kann durch 'o' wieder rückgängig gemacht werden. 
+    Die Reihenfolge des Ankreuzens wird durch vorangestellte
+Nummern gekennzeichnet. Die Namen werden von der entsprechenden
+Funktion später in genau dieser Reihenfolge verwendet. 
+    Wenn nicht alle Namen auf den Bildschirm passen, kann die
+Darstellung gerollt werden. Ein Teil der Überschrift bleibt dabei
+stehen; am Anfang und am Ende wird jeweils eine Abschlußzeile zur
+Kennzeichnung mitgerollt. 
+    Mit ESC '?' kann eine Hilfestellung abgerufen werden. Mit ESC
+'q' wird die Auswahl beendet. Mit ESC 'h' können die Auswahl und
+die in Ausführung befindliche Operation abgebrochen werden. 
+ 
+ 
+1.4 Hilfe und Dialog 
+ 
+In den meisten Situationen kann durch ESC '?' eine spezifische
+Hilfestellung abgerufen werden. Die Anzeige der Hilfsinformation
+geschieht im rechten Bildschirmteil. 
+    Die Texte sind seitenweise aufgebaut. Es wird immer eine Seite
+angezeigt. Mit ESC 'w' bzw. ESC 'z' kann auf die nächste bzw, vorige
+Seite umgeblättert werden. Mit ESC 'q' wird die Hilfestellung wieder
+verlassen und die Situation wiederhergestellt, in der die Hilfe auf­
+gerufen wurde. 
+ 
+#on("b")#Fragen#off("b")# Die meisten Funktionen wickeln zur Eingabe von
+zusätz­
+lichen Parametern oder zum Stellen von Fragen einen Dialog in der
+unteren Schirmhälfte ab. Es gibt zwei Möglichkeiten des Dialogs:
+eine Frage oder die Eingabe eines Textes. 
+    Bei einer Frage kann man mit 'j' oder 'n' antworten. Sowohl
+große als auch kleine Buchstaben werden akzeptiert. Mit ESC '?'
+kann eine Hilfsinformation zu der Frage abgerufen werden. ESC 'h'
+bricht die fragende Funktion ab. 
+ 
+#on("b")#Eingabe#off("b")# Bei der Eingabe eines Textes können die üblichen
+Opera­
+tionen zum Editieren in einer Zeile verwendet werden. Die Eingabe
+wird durch RETURN beendet. Auch hier kann durch ESC '?' eine
+Hilfsinformation abgerufen werden. ESC 'h' bricht ebenfalls die fra­
+gende Funktion ab. In einigen Fällen (ersichtlich aus der Statuszei­
+le) kann durch ESC 'z' eine Auswahl der verfügbaren Namen abgeru­
+fen werden. 
+ 
+ 
+1.5 Editor 
+ 
+Der EUMEL-Editor wird in EUDAS auf zweierlei Weise aufgerufen.
+Zum einen dient er im Satzformular zum Eingeben von Daten und
+Suchmustern. Dort wird er als #on("i")#Satzeditor#off("i")# bezeichnet. Da hier die
+Feldnamen mit berücksichtigt werden müssen, gibt es einige Unter­
+schiede zum normalen Editor. 
+    An anderen Stellen wird der Editor ohne Änderungen eingesetzt
+zum Eingeben von Feldnamen oder Mustern. In diesem Fall finden
+Sie die Bedienungshinweise im EUMEL-Benutzerhandbuch. 
+ 
+#on("b")#Satzeditor#off("b")# Beim Ändern, Einfügen und Eingeben des
+Suchmusters
+wird im EUDAS-Formular der Editor aufgerufen. Das Editorfenster
+beschränkt sich auf den rechten Teil des Formulars, der einen Teil
+der Überschrift und die Feldinhalte umfaßt. Im Satzeditor können
+dann die entsprechenden Inhalte eingegeben bzw. verändert werden. 
+    Rollen unter Beibehaltung der Korrespondenz ist durch ESC
+OBEN und ESC UNTEN möglich. Diese Funktionen wirken wie bei der
+Anzeige - das Editorfenster wird ebenfalls entsprechend mitgerollt.
+Mit ESC '1' kann wie üblich auf die erste, mit ESC '9' auf die letzte
+Zeile gesprungen werden. Auch diese Funktionen passen die Feld­
+namen entsprechend an. 
+    Falls die für ein Feld vorgesehenen Zeilen nicht für den Inhalt
+ausreichen, kann durch ESC RUBIN eine weitere Zeile für dieses Feld
+bereitgestellt werden. ESC RUBIN wirkt wie zweimal HOP RUBIN, die
+Korrespondenz mit den Feldnamen bleibt jedoch gewahrt. 
+    Zum Löschen steht ESC RUBOUT zur Verfügung. Es löscht eine
+ganze Zeile, aber nur, wenn für dieses Feld noch andere Zeilen zur
+Verfügung stehen, wird die Zeile tatsächlich vom Bildschirm ent­
+fernt. Im Normalfall bleibt sonst eine Leerzeile für dieses Feld ste­
+hen. 
+    Ist die Information für ein Feld auf mehrere Zeilen verteilt, so
+werden diese Zeilen zur Verarbeitung aneinandergehängt. Gegebe­
+nenfalls wird zwischen zwei Zeilen noch ein Leerzeichen eingefügt. 
+    Der Editor kann wie üblich mit ESC 'q' verlassen werden. ESC
+'h' bricht die Funktion ab, ohne die erfolgten Änderungen und Ein­
+gaben zu berücksichtigen. Mit ESC 'w' und ESC 'z' kann das Bearbei­
+ten von mehreren Sätzen beschleunigt werden. Durch diese Tasten­
+kombinationen wird der Editor verlassen und die gleiche Operation
+(Ändern/Einfügen) beim nächsten bzw. vorigen Satz wiederholt. 
+ 
+#on("b")#Hinweis#off("b")# Aus technischen Gründen kann das Editorfenster
+gegen­
+über den Feldnamen verschoben werden (durch Rollen mit HOP
+UNTEN zum Beispiel). Dabei geht die sichtbare Korrespondenz zwi­
+schen Feldnamen und Feldinhalten verloren. Ein solcher Fall wird
+durch einen markierten Balken mit entsprechender Meldung ange­
+zeigt. Durch ESC '1' wird das Fenster aber wieder zurechtgerückt. 
+    Aus diesem Grund sollte im Satzeditor auf HOP OBEN und HOP
+UNTEN sowie auf RETURN am Ende des Fensters verzichtet werden.
+Auch HOP RUBIN und HOP RUBOUT sollten nicht verwendet werden,
+weil auf diese Weise die Anzahl der Zeilen verändert wird. Eine
+solche Störung kann nicht durch ESC '1' beseitigt werden. Von Hand
+müssen die entsprechenden Zeilen wieder gelöscht oder eingefügt
+werden. 
+ 
+
diff --git a/doc/eudas/eudas.ref.10 b/doc/eudas/eudas.ref.10
new file mode 100644
index 0000000..fbfcf7e
--- /dev/null
+++ b/doc/eudas/eudas.ref.10
@@ -0,0 +1,406 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (97)#
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+10 Programmierung der Menüs 
+ 
+ 
+ 
+10.1 Menüformat 
+ 
+EUDAS verwendet drei verschiedene Strukturen zur Benutzerunter­
+stützung: Menü, Auswahl und Hilfestellung. Ein Menü dient zur
+Auswahl von Funktionen, eine Auswahl bietet Feld- oder Datei­
+namen an und eine Hilfestellung zeigt einen Informationstext. 
+    Alle diese Strukturen werden aus einer Initialisierungsdatei
+eingelesen. Die Initialisierungsdatei ist eine normale Textdatei. Ihr
+Format soll in diesem Abschnitt beschrieben werden. 
+    Die Strukturen können in beliebiger Reihenfolge in der Initiali­
+sierungsdatei stehen. Jede Struktur wird durch eine spezielle
+Anweisung eingeleitet. Anweisungen beginnen ähnlich wie im
+Druckmuster mit einem Prozentzeichen. Dementsprechend gibt es die
+drei Anweisungen 
+ 
+ 
+    % MENUE "Name" 
+    % AUSWAHL "Name" 
+    % HILFE "Gebiet/Name" 
+ 
+ 
+die jeweils eine Struktur einleiten. Beendet wird eine Definition
+immer mit 
+ 
+ 
+    % ENDE 
+ 
+ 
+#on("b")#Menü#off("b")# Für ein Menü wird noch der Text angegeben, der auf
+dem
+Bildschirm erscheinen soll. Er wird durch die Anweisung 
+ 
+ 
+    % BILD 
+ 
+ 
+eingeleitet. Danach folgen Zeilen mit dem Bildschirminhalt in der
+gewünschten Größe (die tatsächliche Anzeigegröße wird erst beim
+Aufruf angegeben). Dabei werden die Auswahlpositionen, auf denen
+der Cursor sich bewegen kann, durch ein geschütztes Leerzeichen in
+Spalte 2 festgelegt. 
+    Nach der Angabe des Bildes muß für jede mögliche Auswahl­
+position noch eine weitere Angabe gemacht werden. Die Auswahl­
+positionen (oder Felder) werden dabei von oben nach unten durch­
+gezählt. Begonnen wird mit der Nummer 1. 
+    Eine Felddefinition hat das Format 
+ 
+ 
+    % FELD nr "Hilfstext" "Tasten" 
+ 
+ 
+Die Nummer identifiziert das Feld. Der Hilfstext gibt den Namen der
+Hilfestellung an, die gezeigt werden soll, wenn auf diesem Feld ESC
+'?' gedrückt wird. Die Tasten sind alle Zeichen, die gedrückt werden
+können, um dieses Feld direkt auszuführen. 
+    Anschließend an die Felddefinition kann in weiteren Zeilen
+noch ein ELAN-Programm folgen, das bei Auswahl des Feldes aus­
+geführt wird. 
+ 
+#on("b")#Auswahl#off("b")# Für eine Auswahl muß zuerst ein Vorspann angegeben
+werden, der immer in den ersten Bildschirmzeilen der Auswahl an­
+gezeigt wird. Dieser wird durch 
+ 
+ 
+    % VORSPANN 
+ 
+ 
+eingeleitet. Danach folgt das Bild. Das Bild setzt sich aus drei Tei­
+len zusammen. Die erste Zeile, in der ein geschütztes Leerzeichen
+vorkommt, bildet den Wiederholungsteil. Diese Zeile wird nachher so
+oft wie nötig mit entsprechenden Inhalten wiederholt, wobei das
+geschützte Leerzeichen als Bindestrich dargestellt wird, auf dem
+sich der Cursor bewegen kann. Die Teile davor und danach werden
+jeweils bei Bedarf mitgerollt. 
+    Die Wiederholungszeile darf mehrere geschützte Leerzeichen
+enthalten. Die Inhalte werden dann in mehreren Spalten angezeigt.
+Zu beachten ist, daß vor einem Trennstrich noch mindestens fünf
+Zeichen Platz für eine laufende Nummer bleiben müssen. 
+ 
+#on("b")#Hilfe#off("b")# Der Name einer Hilfestellung setzt sich aus zwei
+Teilen
+zusammen, die durch einen Schrägstrich getrennt werden. Der erste
+Name gibt die Kategorie der Hilfestellung an, der zweite Name den
+Einzeltext. Dies dient dazu, die relativ große Zahl der Hilfstexte
+überschaubar zu machen. Als Beispiel 
+ 
+ 
+    % HILFE "JA/Allgemein" 
+ 
+ 
+Eine Hilfestellung besteht einfach aus mehreren Seiten Text. Jede
+Seite wird durch die AnweisungQ
+ 
+ 
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q
+ 
+ 
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q
+ 
+ 
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q
+ 
+ 
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q̈Q
+Q̈Q̈Q̈Q̈Q̈Q̈Q̈estellung, wobei die Seiten einfach von 1 an durch­
+gezählt werden. Anschließend darf für diese Seite natürlich kein
+Text folgen. 
+ 
+ 
+10.2 Verwaltung der Menüs 
+ 
+Alle Menüdaten werden intern in Datenräumen gehalten. Dabei sind
+die einzelnen Strukturen getrennt. Mit 'menuedaten einlesen' kön­
+nen Menüdaten aus einer Struktur gelesen und abgespeichert wer­
+den. Existierende Strukturen werden dabei überschrieben, neue
+hinzugefügt. 
+    Mit 'menuenamen' können die vorhandenen Strukturen abgefragt
+werden. Mit 'menue loeschen' werden einzelne Strukturen oder alle
+Menüdaten gelöscht. Damit die Datenräume mit den Menüdaten auch
+an Söhne übergeben werden, ist der 'global manager' entsprechend
+geändert. Dies wird im einzelnen durch 'menue manager' bewirkt.
+Der neue Global Manager akzeptiert auch Anfragen von Tasks, die
+nicht Söhne oder Enkel sind. 
+ 
+ 
+PROC menuedaten einlesen (TEXT CONST dateiname) 
+ 
+    Die in der Datei enthaltenen Strukturen werden eingelesen und
+    abgespeichert. Treten bei diesem Prozeß Fehler auf, so wird
+    eine entsprechende Meldung ins EUMEL-Notizbuch geschrieben
+    und nachher im Paralleleditor angezeigt. 
+ 
+ 
+THESAURUS PROC menuenamen (INT CONST index) 
+ 
+    Liefert die Namen der Strukturen. Der Index hat folgende Be­
+    deutung: 
+      1: Hilfskategorien 
+      2: Menüs 
+      3: Auswahlen 
+    Ist der Index negativ, so werden die Hilfsnamen der entspre­
+    chenden Hilfskategorie geliefert, die im Thesaurus den Index
+    mit umgekehrtem Vorzeichen hat. 
+ 
+ 
+PROC menue loeschen (TEXT CONST name, INT CONST index) 
+ 
+    Löscht den Namen in dem Thesaurus mit dem angegebenen In­
+    dex, falls dort der Name vorhanden ist. 
+ 
+ 
+PROC menue loeschen (BOOL CONST hilfen reduzieren) 
+ 
+    Löscht alle Menüdaten. Ist 'hilfen reduzieren' verlangt, wird
+    beim späteren Einlesen der Hilfstexte jeweils nur der erste
+    Text einer Kategorie gespeichert, um Platz zu sparen. 
+ 
+ 
+PROC global manager 
+ 
+    Geänderter Manager, der die Menüdatenräume in Söhne trans­
+    portiert und Sperren setzen kann. Ersetzt den normalen 'free
+    global manager'. Nur im Multi-User-System vorhanden. 
+ 
+ 
+PROC menue manager (DATASPACE VAR ds, 
+                    INT CONST order, phase, 
+                    TASK CONST order task) 
+ 
+    Eigentliche Manager-Routine. Kann dazu dienen, Managererwei­
+    terungen vorzunehmen. Nur im Multi-User-System vorhanden.
+    Beispiel: der Manager soll nur Aufträge von Söhnen annehmen. 
+ 
+ 
+      PROC new manager (DATASPACE VAR ds, 
+                        INT CONST order, phase, 
+                        TASK CONST order task): 
+ 
+        LET begin code = 4; 
+        IF order task < myself OR order = begin code OR 
+           order task = supervisor THEN 
+          menue manager (ds, order, phase, order task) 
+        ELSE 
+          errorstop ("kein Sohn") 
+        END IF 
+ 
+      END PROC new manager; 
+ 
+      global manager (PROC new manager) 
+          (* startet den Manager *) 
+ 
+ 
+ 
+10.3 Aufruf 
+ 
+Menüs werden mit der Prozedur 'menue anbieten' aufgerufen. Dabei
+muß neben den Namen ein Fenster übergeben werden, in dem die
+Menüs dann angezeigt werden. Es ist darauf zu achten, daß das
+Fenster groß genug ist, um wenigstens die Auswahlpositionen im
+Bild zu haben. 
+    Außerdem muß eine Prozedur übergeben werden, die die einzel­
+nen Funktionen ausführt. Diese Prozedur erhält als Parameter die
+Nummer der ausgewählten Funktion. 
+    Mit 'waehlbar' können Auswahlen gesperrt werden. Diese Anga­
+be kann jedoch nicht vor Aufruf von 'menue anbieten' erfolgen, da
+dann alle Sperren erstmal gelöscht werden. Zum Setzen der Sperren
+beim Betreten eines Menüs dient ein besonderer Code, mit dem die
+übergebene Prozedur aufgerufen wird. 
+    Eine Auswahl wird mit der Prozedur 'auswahl anbieten' aufge­
+rufen. Diese bekommt ebenfalls ein Fenster übergeben, außerdem
+den Namen einer Hilfestellung, die bei Bedarf aufgerufen werden
+kann. Weiterhin muß eine Prozedur übergeben werden, die die aus­
+zuwählenden Texte erzeugt. Die gewählten Texte können anschlie­
+ßend mit der Prozedur 'wahl' abgefragt werden. 
+    Eine Hilfestellung wird durch die Prozedur 'hilfe anbieten'
+ausgegeben. Dabei muß außer dem Namen auch noch ein Fenster
+übergeben werden. 
+    Mit 'status anzeigen' kann ein Text in der Statuszeile ausge­
+geben werden. Die Menüprogramme tun dies für ihren Bereich jedoch
+selbst. 
+ 
+ 
+PROC menue anbieten (ROW 6 TEXT CONST menuenamen, 
+           FENSTER VAR f, 
+           BOOL CONST esc erlaubt, 
+           PROC (INT CONST, INT CONST) interpreter) 
+ 
+    Die angegebenen Menüs werden in dem Fenster 'f' angezeigt.
+    Das Fenster wird nach Beendigung des Menüs als verändert
+    gekennzeichnet. Die Namen der 6 Menüs werden in die Titelzeile
+    aufgenommen. Die Menünamen sollten mit einer Menüidentifika­
+    tion versehen sein, zum Beispiel "EUDAS.Öffnen". Der Text vor
+    dem Punkt wird an den Anfang der Titelzeile gestellt und bei
+    den einzelnen Menünamen unterdrückt. Nicht benötigte Menüs
+    müssen als "" angegeben werden. 
+ 
+    'esc erlaubt' gibt an, ob mit ESC ESC ein Kommandodialog ge­
+    führt werden kann. Die übergebene Prozedur muß die einzelnen
+    Funktionen ausführen, die als Zahl übergeben werden. Der
+    Interpreter wird im 'disable stop' aufgerufen, daher ist in der
+    Regel ein 'enable stop' erforderlich. 
+ 
+    Die Parameter für 'interpreter' haben folgende Bedeutung: 
+    Par. 1:   0       Aufruf zur Initialisierung der Sperren
+                      oder anderen Initialisierungen zu Beginn 
+              1..6    Angabe des aktuellen Menüs 
+    Par. 2:   1..23   Aufruf der entsprechenden Funktion 
+              0       Eintritt in ein neues Menü (wird vor der
+                      Ausgabe dieses Menüs aufgerufen) 
+              -1      Verlassen des Menüs 
+              -2      Bildschirmupdate (nach Eintritt in das
+                      Menü, wenn das Menü ganz ausgegeben ist,
+                      oder wenn der Bildschirm nach 'Gib
+                      Kommando:' zerstört worden ist) 
+ 
+    FEHLER: 
+ 
+    #on("i")#"Name" existiert nicht.#off("i")# 
+    Das angegebene Menü ist nicht vorhanden. 
+ 
+ 
+PROC waehlbar (INT CONST menuenr, funktionsnr 
+               BOOL CONST moeglich) 
+ 
+    Setzt die Funktionssperre der angegebenen Funktion. Muß in­
+    nerhalb von 'menue anbieten' aufgerufen werden. Zu Beginn von
+    'menue anbieten' sind jeweils alle Funktionen erlaubt. 
+ 
+ 
+PROC ausfuehrtaste (TEXT CONST taste) 
+ 
+    Setzt die Taste, die Funktionen ausführt. Ist standardmäßig die
+    Leertaste. 
+ 
+    FEHLER: 
+ 
+    #on("i")#falsche Ausfuehrtaste#off("i")# 
+    Es muß ein einzelnes Zeichen angegeben werden, das nicht
+    bereits anderweitig verwendet wird. 
+ 
+ 
+PROC auswahl anbieten (TEXT CONST name, FENSTER CONST f, 
+                       TEXT CONST hilfe, 
+                       PROC (TEXT VAR, INT CONST) inhalt) 
+ 
+    Ruft die Auswahl in dem angegebenen Fenster auf. 'hilfe' wird
+    als Hilfestellung verwendet. Die Prozedur 'inhalt' liefert den
+    Text, der an der n-ten Position stehen soll. Wenn keine wei­
+    teren Texte vorhanden sind, muß für alle weiteren Positionen
+    "" geliefert werden. 
+ 
+    FEHLER: 
+ 
+    #on("i")#"Name" existiert nicht.#off("i")# 
+    Die angegebene Auswahl ist nicht vorhanden. 
+ 
+ 
+INT PROC wahl (INT CONST stelle) 
+ 
+    Liefert die Nummer des Textes, der an der n-ten Stelle ausge­
+    wählt wurde. Wurde kein weiterer Text mehr gewählt, so wird 0
+    geliefert. 
+ 
+ 
+PROC hilfe anbieten (TEXT CONST name, FENSTER CONST f) 
+ 
+    Bietet den Hilfstext in dem angegebenen Fenster an. Existiert
+    die Hilfe innerhalb der angegebenen Kategorie nicht, wird die
+    erste Hilfe der Kategorie angezeigt. 
+ 
+    FEHLER: 
+ 
+    #on("i")#Hilfe existiert nicht#off("i")# 
+    Die angegebene Hilfskategorie ist nicht vorhanden. 
+ 
+ 
+PROC status anzeigen (TEXT CONST zeile) 
+ 
+    Zeigt den angegebenen Text in der obersten Bildschirmzeile an. 
+ 
+ 
+10.4 Dialog 
+ 
+EUDAS führt den Benutzerdialog in einem Fenster, dessen Größe
+durch 'dialogfenster' eingestellt wird. Das Dialogfenster wird zei­
+lenweise belegt. 'dialog' reserviert eine neue Zeile für eine beliebi­
+ge Ausgabe. Wenn das Fenster voll ist oder überschrieben wurde,
+wird in der ersten Zeile wieder angefangen. Den gleichen Effekt
+kann man mit 'neuer dialog' erreichen. 
+    Mit 'ja' kann man im Dialogfenster eine Frage stellen. Als Ant­
+wort kann auch eine Hilfestellung angefordert werden oder die
+Funktion abgebrochen werden. Mit 'editget' kann man nach Auffor­
+derung einen Text eingeben lassen. Dabei stehen die gleichen
+zusätzlichen Möglichkeiten zur Verfügung. 
+    Mit 'fehler ausgeben' kann eine durch 'errorstop' erzeugte Feh­
+lermeldung im Dialogfenster angezeigt werden. Der Benutzer muß
+erst eine Taste drücken, ehe er weitermachen kann. Auch hier kann
+eine Hilfestellung zu der Fehlermeldung abgerufen werden. 
+ 
+ 
+PROC dialogfenster (INT CONST x, y, xl, yl) 
+ 
+    Gibt die Fenstergröße und -position des Dialogfensters an. Für
+    den ganzen Bildschirm müßte (1, 1, 79, 24) angegeben werden. 
+ 
+ 
+PROC dialog 
+ 
+    Positioniert den Cursor auf die nächste Dialogzeile im Dialog­
+    fenster. Wurde das Fenster verändert, wird das Fenster ge­
+    löscht und auf die erste Zeile positioniert. 
+ 
+ 
+PROC neuer dialog 
+ 
+    Sorgt dafür, daß der nächste Aufruf von 'dialog' wieder in
+    einem leeren Fenster beginnt. 
+ 
+ 
+BOOL PROC ja (TEXT CONST frage, hilfe) 
+ 
+    Stellt die angegebene Frage. Es kann die angegebene Hilfsin­
+    formation abgerufen werden. Außerdem wird durch ESC 'h' ein
+    Abbruch (errorstop ("")) erzeugt. 
+ 
+ 
+PROC editget (TEXT CONST prompt, TEXT VAR eingabe, 
+              TEXT CONST res, hilfe) 
+ 
+    Gibt den Text 'prompt' aus und editiert dahinter 'eingabe'. Es
+    kann die angegebene Hilfsinformation abgerufen werden. 'res'
+    gibt an, bei welchen ESC-Folgetasten das Editieren beendet
+    werden soll. In einem solchen Fall wird als Eingabe (ESC + die
+    gedrückte Taste) zurückgeliefert. 
+ 
+ 
+PROC fehler ausgeben 
+ 
+    Im Dialogfenster wird die letzte Fehlermeldung ausgegeben.
+    Gleichzeitig wird der Fehlerzustand gelöscht. Der Benutzer muß
+    eine Taste drücken, um weiterzumachen. Alternativ kann die
+    Hilfsinformation "FEHLER/" + text (errorcode) abgerufen wer­
+    den. 
+ 
+
diff --git a/doc/eudas/eudas.ref.11 b/doc/eudas/eudas.ref.11
new file mode 100644
index 0000000..48d36c3
--- /dev/null
+++ b/doc/eudas/eudas.ref.11
@@ -0,0 +1,347 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (105)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+11 Programmierung von Anwendungen 
+ 
+ 
+ 
+Zur Realisierung eigener EUDAS-Anwendungen mit Hilfe von ELAN-
+Programmen gibt es mehrere Möglichkeiten mit zunehmender Lei­
+stungsfähigkeit, aber auch steigender Komplexität und Fehleranfäl­
+ligkeit. In den folgenden Abschnitten werden die drei wesentlichen
+Methoden vorgestellt. Sie sollten erst dann eine kompliziertere
+Methode in Angriff nehmen, wenn Sie die einfachere beherrschen. 
+ 
+ 
+11.1 Musterprogramme 
+ 
+Die bevorzugte Methode zur Erstellung eigener Anwendungen unter
+EUDAS ist die Programmierung von Mustern. EUDAS läßt dies bei
+Druckmustern, Kopiermustern und Änderungsmustern zu. 
+    In diesem Fall steuert EUDAS den Ablauf des Programms im
+groben automatisch. Die jeweils unterschiedlichen Anweisungen, was
+im einzelnen zu tun ist, werden in ELAN programmiert. Aus dem
+Muster mit diesen zusätzlichen Anweisungen generiert EUDAS dann
+das Programm und führt es mit Hilfe des ELAN-Compilers aus. 
+ 
+#on("b")#Vorteile#off("b")# Diese Methode hat den Vorteil, daß nur die
+minimal not­
+wendigen Anweisungen tatsächlich selbst programmiert werden
+müssen. Dafür reichen bereits geringe ELAN-Kenntnisse vollkommen
+aus. Ein Muster kann relativ schnell erstellt und getestet werden.
+Durch den einfachen Aufbau ist auch die Fehlerwahrscheinlichkeit
+beim Entwickeln geringer als bei anderen Methoden. 
+    Daneben lassen sich die Musterprogramme jeweils bequem im
+Menü durch Angabe des Namens oder durch Ankreuzen ausführen,
+also auch durch unbedarfte Benutzer. 
+ 
+#on("b")#Nachteile#off("b")# Nachteil dieser Methode ist, daß jeweils beim
+Aufruf das
+Programm nochmal neu erzeugt und übersetzt werden muß, da die
+Übersetzung auch von der gerade geöffneten Datei abhängt. Dies
+stört besonders bei umfangreichen Druckmustern (auf langsamen
+Rechnern). 
+    Zum zweiten wird ein umfangreiches Druckmuster auch bald
+unübersichtlich, da Strukturierungshilfen für größere Programme
+fehlen. Der eigentliche Mustertext ist dann schwer von den zahlrei­
+chen Abkürzungen zu trennen. 
+    Als Abhilfe für diese beiden Nachteile bietet es sich an, um­
+fangreichere Abkürzungen bzw. Ausdrücke eingebettet in ein
+ELAN-Paket aus dem Muster herauszunehmen und vorher zu in­
+sertieren. 
+    Dadurch fällt zum einen die ständige Neuübersetzung dieser
+Ausdrücke weg, zum anderen ist das eigentliche Muster wieder
+überschaubar. Voraussetzung zur Anwendung eines solchen Musters
+ist dann jedoch, daß das zugehörige Paket in der jeweiligen Task
+bereits vorher übersetzt wurde. 
+    Die nachfolgenden Beispiele zeigen, wie dieses Verfahren in der
+Realität aussehen kann. 
+ 
+#on("b")#Beispiel 1#off("b")# In der Schulverwaltung soll ein Kopier- oder
+Ände­
+rungsmuster erstellt werden, das die Versetzung am Schuljahresende
+realisiert. Angenommen wird eine Datei, die alle Schüler enthält.
+Schüler, die nicht versetzt werden, sind vorher im Feld 'Versetzung'
+mit einem beliebigen Text gekennzeichnet worden (zum Beispiel
+'Nachprüfung' o.ä.). 
+    Die Versetzung kann auf zweierlei Weise erfolgen: zum einen
+durch automatische Änderung, wenn die alte Version noch auf einer
+Archivdiskette aufgehoben wird, oder durch Kopieren in eine neue
+Datei. 
+    Bei beiden Mustern ist die einzige Änderung die Angabe der
+neuen Klasse. Daher bietet es sich an, eine Prozedur 'neue klasse'
+zu definieren, die als Ergebnis die neue Klasse eines Schülers lie­
+fert. Diese Prozedur kann dann im Änderungsmuster wie folgt ver­
+wendet werden: 
+ 
+ 
+        "Klasse" V neue klasse; 
+ 
+ 
+Entsprechend läuft die Verwendung im Kopiermuster: 
+ 
+ 
+        "Name" K f ("Name"); 
+        "Vorname" K f ("Vorname"); 
+        "Klasse" K neue klasse; 
+        ... 
+ 
+ 
+Die Prozedur 'neue klasse' muß dann in einem Paket definiert wer­
+den, das etwa folgendes Aussehen haben könnte (spezifische Ände­
+rungen natürlich möglich): 
+ 
+ 
+    PACKET klassenwechsel DEFINES neue klasse: 
+ 
+    TEXT PROC neue klasse : 
+ 
+      IF f ("Versetzung") = "" THEN 
+        klasse um 1 erhoeht 
+      ELSE 
+        alte klasse ohne zusatz 
+      END IF . 
+ 
+    klasse um 1 erhoeht : 
+      INT CONST alte klasse := int (f ("Klasse")); 
+      IF alte klasse < 9 THEN 
+        "0" + text (alte klasse + 1) + zusatz 
+      ELSE 
+        text (alte klasse + 1) + zusatz 
+      END IF . 
+ 
+    zusatz : 
+      f ("Klasse") SUB 3. 
+ 
+    alte klasse ohne zusatz : 
+      subtext (f ("Klasse"), 1, 2) . 
+ 
+    END PROC neue klasse; 
+ 
+    END PACKET klassenwechsel; 
+ 
+ 
+Schüler, die versetzt werden, erhalten ihre neue Jahrgangsstufe mit
+dem alten Klassenzusatz zugeteilt. Dabei ist darauf zu achten, daß
+die Klassen 5 bis 9 eine '0' vorangestellt bekommen, damit die
+Sortierung funktioniert. 
+    Schüler, die nicht versetzt werden, behalten ihre alte Jahr­
+gangsstufe, allerdings ohne einen Klassenzusatz, der ihnen an­
+schließend manuell zugewiesen werden muß. 
+    Zur Benutzung muß das oben angegebene Paket in eine Text­
+datei geschrieben und mit dem Kommando 'insert' fest insertiert
+werden. 
+ 
+#on("b")#Beispiel 2#off("b")# Aus einer Datei mit bibliographischen Einträgen
+sollen
+bestimmte Literaturhinweise gedruckt werden. Der Literaturhinweis
+soll jeweils als Endlostext umbrochen werden. Dafür müssen in einer
+Abkürzung alle Daten verkettet werden. Es sei das folgende ein­
+fache Druckmuster vorgegeben: 
+ 
+ 
+    % WIEDERHOLUNG 
+    % MODUS 3 
+    [&<krz>]    &titel 
+ 
+    % ABKUERZUNGEN 
+    &krz :  f ("Kurzbez") .    (* z.B. "Lew84" *) 
+    &titel :  titel lang . 
+ 
+ 
+Die Prozedur 'titel lang' wird in folgendem Paket definiert: 
+ 
+ 
+    PACKET bibliographie DEFINES titel lang : 
+ 
+    TEXT VAR puffer;   (* verringert Heap-Belastung *) 
+ 
+    TEXT PROC titel lang : 
+ 
+      puffer := f ("Name 1"); 
+      puffer CAT ", "; 
+      puffer CAT f ("Vorname 1"); 
+      ggf weitere namen; 
+      titel kursiv; 
+      enthalten in; 
+      erscheinungsort und jahr; 
+      puffer . 
+ 
+    ggf weitere namen: 
+      IF f ("Name 2") <> "" THEN 
+        puffer CAT "; "; 
+        puffer CAT f ("Name 2") 
+      END IF . 
+ 
+    titel kursiv : 
+      puffer CAT "   \#on (""i"")\#"; 
+      puffer CAT f ("Titel"); 
+      puffer CAT "\#off (""i"")\#, " . 
+ 
+    enthalten in : 
+      IF f ("in") <> "" THEN 
+        puffer CAT " in: "; 
+        puffer CAT f ("in"); 
+        puffer CAT ", " 
+      END IF . 
+ 
+    erscheinungsort und jahr : 
+      puffer CAT f ("Ort"); 
+      puffer CAT ", "; 
+      puffer CAT f ("Jahr") . 
+ 
+    END PROC titel lang; 
+ 
+    END PACKET bibliographie; 
+ 
+ 
+Die Puffervariable wird verwendet, um die bei Verwendung des
+Operators '+' entstehende Heapbelastung zu verringern. An diese
+Variable werden nacheinander alle notwendigen Daten mit den ent­
+sprechenden Trennzeichen angehängt. 
+    Im Druckmuster wird dieser lange Text dann im Modus 3 auf
+mehrere Zeilen umbrochen, wobei die Einrückung erhalten bleibt. Die
+Druckausgabe kann dann bei Bedarf noch mit 'lineform' bearbeitet
+werden, um einen noch besseren Umbruch zu erzielen. 
+ 
+ 
+11.2 Dateianwendungen 
+ 
+Die zweite Möglichkeit der Programmierung unter EUDAS besteht
+darin, ELAN-Programme zu schreiben, die EUDAS-Dateien mit Hilfe
+des in Kapitel 6 beschriebenen Datentyps EUDAT manipulieren. Die
+Programmierung gestaltet sich ähnlich wie mit FILEs. 
+ 
+#on("b")#Vorteile#off("b")# Durch dieses Verfahren haben Sie volle Freiheit
+der Pro­
+grammierung. Da lediglich die Struktur der EUDAS-Dateien als
+Datenspeicher verwendet wird, sind sehr viele Anwendungen denk­
+bar. 
+    Außerdem können so beliebig viele Dateien gleichzeitig bear­
+beitet werden. Da die Programme nicht auf die virtuelle Datei zu­
+greifen, ist ein Konflikt mit dem aktuellen Zustand von EUDAS
+nahezu ausgeschlossen. 
+ 
+#on("b")#Nachteile#off("b")# Der Nachteil dieses Verfahrens ist, daß viele
+Dinge
+selbst programmiert werden müssen, so zum Beispiel das Durchgehen
+einer Datei. Auch die Hilfsmittel der virtuellen Datei wie Such­
+muster, Koppeln und alle Anwendungen, die auf die virtuelle Datei
+zugreifen, stehen nicht zur Verfügung. 
+ 
+#on("b")#Beispiel 1#off("b")# Die in Abschnitt 6.6 vorgestellte Anwendung als
+Asso­
+ziativspeicher kann als Beispiel für diese Methode dienen. 
+ 
+#on("b")#Beispiel 2#off("b")# Eine EUDAS-Datei (zum Beispiel eine
+Schülerdatei) soll
+in mehrere Dateien aufgespalten werden (zum Beispiel klassen­
+weise). Dies kann durch das folgende Beispielprogramm bewirkt
+werden: 
+ 
+ 
+    LET 
+      klassenfeld = 3, 
+      quellname = "Schüler", 
+      zielname = "Jahrgang "; 
+    ROW 9 EUDAT VAR ziel; 
+    EUDAT VAR quelle; 
+    SATZ VAR feldnamen; 
+ 
+    quelle oeffnen; 
+    zieldateien einrichten; 
+    auf satz (quelle, 1); 
+    WHILE NOT dateiende (quelle) REP 
+      aktuellen satz kopieren; 
+      weiter (quelle) 
+    END REP . 
+ 
+    quelle oeffnen : 
+      oeffne (quelle, quellname); 
+      feldnamen lesen (quelle, feldnamen) . 
+ 
+    zieldateien einrichten : 
+      INT VAR i; 
+      FOR i FROM 1 UPTO 9 REP 
+        oeffne (ziel (i), zielname + text (i + 4)); 
+        feldnamen aendern (ziel (i), feldnamen) 
+      END REP . 
+ 
+    aktuellen satz kopieren : 
+      SATZ VAR satz; 
+      satz lesen (quelle, satz); 
+      satz einfuegen (ziel (stufe), satz); 
+      weiter (ziel (stufe)) . 
+ 
+    stufe : 
+      TEXT VAR klasse; 
+      feld lesen (satz, klassenfeld, klasse); 
+      int (klasse) - 4 . 
+ 
+ 
+ 
+11.3 Integrierte Anwendungen 
+ 
+Die schwierigste Möglichkeit, Anwendungen unter EUDAS zu reali­
+sieren, ist ihre Integration. Ein solches Programm greift selbst auf
+die virtuelle Datei zu, nutzt die Funktionen von EUDAS so weit wie
+möglich und definiert vielleicht sogar ein eigenes Menü. 
+ 
+#on("b")#Vorteile#off("b")# Auf diese Weise können natürlich alle
+Möglichkeiten
+ausgeschöpft werden. Sie können Programme erstellen, die als eine
+natürliche Erweiterung von EUDAS wirken oder EUDAS ganz erset­
+zen. 
+ 
+#on("b")#Nachteile#off("b")# Eine solche Integration ist aber besonders
+schwierig,
+wenn EUDAS und die Erweiterung nebeneinander benutzt werden
+sollen. In diesem Fall hat EUDAS keine komplette Kontrolle der
+Interaktion, so daß leicht undefinierte Zustände möglich sind. 
+    Weniger Probleme treten auf, wenn sichergestellt ist, daß nur
+die Anwendung selbst verwendet wird. Auch in diesem Fall ist zu
+beachten, daß EUDAS nicht als Programmierumgebung für Anwen­
+dungssysteme konzipiert wurde und daher nicht immer leicht zu
+benutzen ist. 
+    Am einfachsten ist es noch, nur eigene Menüs für eine andere
+Anwendung zu verwenden, da die Menüprozeduren relativ unabhän­
+gig vom Rest sind. 
+ 
+#on("b")#Richtlinien#off("b")# Bei Erweiterungen von EUDAS sind folgende
+Richtlinien zu beachten: 
+ 
+1. Ein Programm, das selber Dateien für die virtuelle Datei öffnen
+   will, sollte vorher prüfen, ob noch eine Datei geöffnet ist und in
+   diesem Fall abbrechen. Beim Multi-User-Betrieb ist nämlich
+   sonst nicht gewährleistet, daß alle Sperren wieder entfernt
+   werden. 
+ 
+2. Ein solches Programm sollte seine eigenen Dateien vor dem
+   Wechsel zu EUDAS selbst wieder sichern und die Arbeitskopien
+   löschen, damit der Ausgangszustand zu Beginn des Programms
+   wiederhergestellt wird. 
+ 
+3. Programme, die Menüs benutzen, sollten nicht unter EUDAS auf­
+   gerufen werden, da sonst eine Beeinflussung der EUDAS-Menüs
+   möglich ist. 
+ 
+An dieser Stelle soll noch einmal von der Erstellung integrierter
+Anwendungen abgeraten werden, wenn es auch andere Möglichkeiten
+gibt, das gegebene Problem mit EUDAS zu lösen. Der hohe Aufwand
+dieser Methode rechtfertigt sich nur in wenigen Fällen. 
+    Experimentierfreudige Anwender werden sich durch diese War­
+nung sowieso nicht abhalten lassen. Ihnen sollte aber bewußt sein,
+daß ein solches Vorgehen auf eigene Gefahr stattfindet und kein
+Anspruch auf Beratung oder Fehlerbeseitigung in einem solchen Fall
+besteht. 
+
diff --git a/doc/eudas/eudas.ref.2 b/doc/eudas/eudas.ref.2
new file mode 100644
index 0000000..2447897
--- /dev/null
+++ b/doc/eudas/eudas.ref.2
@@ -0,0 +1,830 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (13)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+2 Zusammenstellung der Funktionen 
+ 
+ 
+ 
+Im folgenden finden Sie eine Übersicht über alle Menüfunktionen. Zu
+jeder Funktion ist aufgeführt, welche Parameter angegeben werden
+müssen. Die Parameter werden als Text erfragt. Bei einigen Funk­
+tionen können alle möglichen Parameterwerte mit ESC 'z' (Zeigen)
+als Auswahl abgerufen werden. Bei manchen können in der Auswahl
+mehrere Werte angekreuzt werden, die dann nacheinander abgear­
+beitet werden. Welcher Fall zutrifft, ist jeweils aufgeführt. 
+ 
+ 
+2.1 Menü 'Öffnen' 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#O           EUDAS-Datei Öffnen#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  EUDAS-Dateiname, mit Zeigen, eine Wahl 
+ 
+Zweck:      Stellt eine EUDAS-Datei als aktuelle Arbeitsdatei ein.
+            Falls eine vorher geöffnete Datei verändert wurde,
+            wird sie nach Anfrage gesichert. Falls die zu öffnende
+            Datei noch nicht existiert, kann sie nach Anfrage
+            eingerichtet werden. Dabei müssen dann die Feld­
+            namen angegeben werden. 
+ 
+            Es wird gefragt, ob die Datei geändert werden soll. In
+            diesem Fall wird eine Arbeitskopie hergestellt. Fast
+            alle EUDAS-Funktionen beziehen sich nachher auf die
+            so eingestellte Datei. 
+ 
+            Ist ein Mehrbenutzer-Manager eingestellt, kann auch
+            eine Datei aus dieser Managertask als Parameter
+            angegeben werden. Die Datei wird dann automatisch
+            von dort kopiert und eine Sperre im Manager gesetzt,
+            falls Änderungen vorgenommen werden sollen. 
+ 
+Verweise:   Abschnitt 3.2 
+            Benutzerhandbuch Abschnitt 5.1 und 9.1 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#E           EUDAS-Datei Ketten#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  EUDAS-Dateiname, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Falls bereits eine EUDAS-Datei geöffnet ist, kann eine
+            weitere Datei gleicher Struktur logisch angekettet
+            werden. Bei der Bearbeitung werden dann beide Datei­
+            en wie eine zusammenhängende Datei behandelt. 
+ 
+            Die gekettete Datei kann ebenfalls verändert werden,
+            wenn dies beim Öffnen der ersten Datei angegeben
+            wurde. Die angegebene Datei kann auch aus einem
+            Manager stammen. 
+ 
+Verweise:   Abschnitt 3.2 
+            Benutzerhandbuch Abschnitt 9.2 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#K           EUDAS-Datei Koppeln#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  EUDAS-Dateiname, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Falls bereits eine Datei geöffnet ist, kann eine andere
+            EUDAS-Datei dazugekoppelt werden. Dazu muß min­
+            destens das erste Feld der zu koppelnden Datei in der
+            bereits geöffneten Datei vorkommen. 
+ 
+            Nach dem Koppeln erscheinen beide Dateien wie eine
+            Datei. Zu jedem Satz der ersten Datei erscheinen je­
+            weils alle Sätze der Koppeldatei, die in dem Koppelfeld
+            übereinstimmen. 
+ 
+            Die gekoppelte Datei kann ebenfalls verändert werden,
+            wenn dies beim Öffnen der ersten Datei angegeben
+            wurde. Die angegebene Datei kann auch aus einem
+            Manager stammen. 
+ 
+Verweise:   Abschnitt 3.3 
+            Benutzerhandbuch Abschnitt 9.3 und 9.4 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#S           Arbeitskopie Sichern#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Wurde eine EUDAS-Datei geöffnet und verändert, muß
+            zum Schluß die veränderte Arbeitskopie wieder ge­
+            sichert werden. Die Arbeitskopie kann entweder ge­
+            löscht werden, die alte Version ersetzen oder unter
+            einem neuen Namen registriert werden. 
+ 
+            Für jede veränderte Datei wird zunächst erfragt, ob
+            die alte Version überschrieben werden soll. Dies ist
+            der Normalfall. Bei Verneinung dieser Frage muß ein
+            neuer Name für die Arbeitskopie angegeben werden. 
+ 
+            Zum Schluß wird erfragt, ob alle Arbeitskopien ge­
+            löscht werden sollen (Normalfall: ja). Anderenfalls
+            bleiben die Dateien weiter geöffnet. 
+ 
+Verweise:   Abschnitt 3.5 
+            Benutzerhandbuch Abschnitt 6.4 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#N           Notizen ansehen/ändern#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Zu jeder EUDAS-Datei kann als Notiz ein beliebiger
+            Text gespeichert werden. Dieser Text der aktuellen
+            Datei wird mit dieser Funktion im Editor angezeigt
+            und kann verändert werden, wenn eine Arbeitskopie
+            angelegt wurde. Anderenfalls werden etwaige Verän­
+            derungen einfach ignoriert. 
+ 
+Verweise:   Abschnitt 3.1 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#F           Feldstruktur ändern#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Mit dieser Funktion können neue Felder an die aktu­
+            elle Datei angefügt werden. Außerdem lassen sich
+            Feldnamen und Feldtypen ändern. Die Feldtypen be­
+            stimmen die Behandlung eines Feldes beim Suchen oder
+            Sortieren (z.B. von Zahlen). 
+ 
+            Zunächst wird erfragt, ob neue Feldnamen angefügt
+            werden sollen. Diese können dann im Editor eingege­
+            ben werden. Danach wird gefragt, ob Feldnamen oder
+            Feldtypen geändert werden sollen (neu angefügte
+            Felder erhalten erst einmal den Typ TEXT). Falls die
+            Frage bejaht wird, können in einer Auswahl die zu
+            ändernden Felder angekreuzt werden. Für jedes ange­
+            kreuzte Feld werden dann der Name und der Typ zum
+            Überschreiben angeboten. 
+ 
+Verweise:   Abschnitt 3.1 
+            Benutzerhandbuch Abschnitt 11.1 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#P           Prüfbedingungen ansehen/ändern#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Beim Tragen in eine EUDAS-Datei können Bedingungen
+            für die zu tragenden Sätze überprüft werden. Diese
+            Bedingungen für die aktuelle Datei können mit dieser
+            Funktion angezeigt und, falls erlaubt, auch geändert
+            werden. 
+ 
+Verweise:   Abschnitt 3.1 und 4.4 
+            Benutzerhandbuch Abschnitt 11.3 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#M           Mehrbenutzer Manager einstellen#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Managertaskname, kein Zeigen 
+ 
+Zweck:      EUDAS kann beim Öffnen eine Datei von einer anderen
+            Task des Systems kopieren. Dadurch können mehrere
+            Benutzer kontrolliert auf die gleiche Datei zugreifen.
+            Wenn diese Möglichkeit verwendet werden soll, muß
+            mit dieser Funktion zunächst die in Frage kommende
+            Managertask angegeben werden. 
+ 
+Verweise:   Abschnitt 3.7 
+            Benutzerhandbuch Abschnitt 9.6 
+ 
+ 
+2.2 Menü 'Einzelsatz' 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#W           Weiter#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Geht einen Satz weiter in der aktuellen Datei - falls
+            eine Suchbedingung eingestellt ist, weiter zum näch­
+            sten ausgewählten Satz. 
+ 
+Verweise:   Abschnitt 4.2 
+            Benutzerhandbuch Abschnitt 5.2 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#Z           Zurück#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Geht einen Satz zurück in der aktuellen Datei - falls
+            eine Suchbedingung eingestellt ist, zurück zum vori­
+            gen ausgewählten Satz. 
+ 
+Verweise:   Abschnitt 4.2 
+            Benutzerhandbuch Abschnitt 5.2 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#N           Auf Satz Nr. ..#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Positioniert auf einen bestimmten Satz der aktuellen
+            Datei, dessen Satznummer eingegeben werden muß, und
+            zwar unabhängig, ob der Satz durch die Suchbedingung
+            ausgewählt wird oder nicht. Trifft die eingestellte
+            Suchbedingung nicht auf den Satz zu, erscheint
+            'SUCH-' in der Überschrift. Existiert die eingegebene
+            Satznummer nicht, positioniert EUDAS hinter den
+            letzten Satz der Datei. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 5.2 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#S           Suchbedingung Setzen#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Es kann eine neue Suchbedingung für die aktuelle
+            Datei eingegeben werden, bzw. eine vorher eingestellte
+            Suchbedingung wird zum Ändern angeboten. Die Such­
+            bedingung wird in Form eines Suchmusters in das
+            Satzformular geschrieben. 
+ 
+            Die eingestellte Suchbedingung wird beim Positionieren
+            und bei allen Bearbeitungsfunktionen beachtet. 
+ 
+Verweise:   Abschnitt 4.2 
+            Benutzerhandbuch Abschnitt 5.3, 5.4 und 10.3 
+ 
+ 
+#linefeed (0.5)# 
+#on("b")#L           Suchbedingung Löschen#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Die eingestellte Suchbedingung wird wieder gelöscht. 
+ 
+Verweise:   Abschnitt 4.2 
+            Benutzerhandbuch Abschnitt 5.3 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#M           Markierung umkehren#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Mit dieser Funktion können einzelne Sätze zur späte­
+            ren Bearbeitung markiert werden. Falls der aktuelle
+            Satz bereits markiert ist, wird die Markierung wieder
+            entfernt, ansonsten wird er markiert. 
+ 
+            Wenn mindestens ein Satz markiert ist, beachten die
+            Bearbeitungsfunktionen nur die markierten Sätze. So
+            kann eine manuelle Auswahl durchgeführt werden. Die
+            Markierung bleibt nur bis zum Sichern bestehen. Sie
+            ist keine permanente Eigenschaft einer EUDAS-Datei. 
+ 
+Verweise:   Abschnitt 4.2 
+            Benutzerhandbuch Abschnitt 10.4 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#E           Datensatz Einfügen#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Mit dieser Funktion wird vor dem aktuellen Satz ein
+            leerer Satz eingefügt, für den anschließend die Feld­
+            inhalte im Satzformular eingetragen werden können. 
+ 
+Verweise:   Abschnitt 3.4 
+            Benutzerhandbuch Abschnitt 6.2 und 10.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#A           Datensatz Ändern#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Die Inhalte des aktuellen Satzes werden im Satzformu­
+            lar zum Ändern angeboten. 
+ 
+Verweise:   Abschnitt 3.4 
+            Benutzerhandbuch Abschnitt 6.3 und 10.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#T           Datensatz Tragen#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  EUDAS-Dateiname, mit Zeigen, eine Wahl 
+ 
+Zweck:      Mit dieser Funktion kann der aktuelle Satz in eine
+            anderen EUDAS-Datei gleicher Struktur transportiert
+            werden. In der Zieldatei wird er am Ende angefügt. 
+ 
+Verweise:   Abschnitt 4.4 
+            Benutzerhandbuch Abschnitt 6.3 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#H           Datensatz Holen#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  EUDAS-Dateiname, mit Zeigen, eine Wahl 
+ 
+Zweck:      Mit dieser Funktion kann der letzte Satz einer ande­
+            ren Datei vor dem aktuellen Satz eingefügt werden,
+            sofern die Struktur gleich ist. Damit kann ein vorher­
+            gegangenes Tragen rückgängig gemacht werden. 
+ 
+Verweise:   Abschnitt 4.4 
+            Benutzerhandbuch Abschnitt 6.3 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#F           Feldauswahl#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Die Felder der aktuellen Datei werden in einer Aus­
+            wahl angeboten. Am Bildschirm werden danach nur die
+            ausgewählten Felder in der gewählten Reihenfolge
+            dargestellt. Die Auswahl hat jedoch nur Auswirkung
+            auf die Darstellung am Bildschirm, anderen Funktionen
+            stehen nach wie vor alle Felder zur Verfügung. Die
+            Auswahl gilt bis zum Sichern, sie wird also nicht mit
+            der Datei abgespeichert. 
+ 
+Verweise:   Abschnitt 4.1 
+            Benutzerhandbuch Abschnitt 10.1 
+ 
+ 
+2.3 Menü 'Gesamtdatei' 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#K           Satzauswahl Kopieren#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  EUDAS-Dateiname, mit Zeigen, eine Wahl 
+            Name Kopiermuster, ohne Zeigen 
+ 
+Zweck:      Mit dieser Funktion werden die ausgewählten bzw.
+            markierten Sätze der aktuellen Datei in eine andere
+            Datei kopiert. Welche Felder kopiert werden sollen und
+            in welcher Reihenfolge, wird durch ein Kopiermuster
+            festgelegt. Dieses Kopiermuster kann benannt werden
+            oder unbenannt nur für ein Mal erstellt werden. Wird
+            das Kopiermuster neu erstellt, wird ein Standard-
+            Kopiermuster zum Ändern angeboten. 
+ 
+Verweise:   Abschnitt 4.4 
+            Benutzerhandbuch Abschnitt 11.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#T           Satzauswahl Tragen#off("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  EUDAS-Dateiname, mit Zeigen, eine Wahl 
+ 
+Zweck:      Transportieren der ausgewählten bzw. markierten
+            Sätze in eine andere Datei gleicher Struktur. Die Sätze
+            werden in der Zieldatei am Ende eingefügt. 
+ 
+Verweise:   Abschnitt 4.4 
+            Benutzerhandbuch Abschnitt 11.3 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#V           Satzauswahl Verändern#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Name Änderungsmuster, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Bearbeiten der ausgewählten bzw. markierten Sätze
+            der aktuellen Datei nach Vorgabe einer Änderungs­
+            vorschrift. 
+ 
+Verweise:   Abschnitt 4.4 
+            Benutzerhandbuch Abschnitt 11.4 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#U           Übersicht Satzauswahl#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Anzeige aller ausgewählten Sätze in einem Über­
+            sichtsformat mit einem Satz pro Bildschirmzeile. Die
+            Felder, die in der Übersicht angezeigt werden sollen,
+            können vorher ausgewählt werden. In der Übersicht ist
+            Blättern und Markieren von Sätzen möglich. 
+ 
+Verweise:   Abschnitt 4.1 
+            Benutzerhandbuch Abschnitt 10.5 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#S           Aktuelle Datei Sortieren#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Sortieren der aktuellen Datei in beliebiger Reihenfolge
+            auf- oder absteigend. Zum Sortieren muß eine Ar­
+            beitskopie angelegt sein. Die Feldreihenfolge, in der
+            sortiert werden soll, wird vorher erfragt. 
+ 
+Verweise:   Abschnitt 4.3 
+            Benutzerhandbuch Abschnitt 11.1 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#L           Alle Markierungen Löschen#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Löschen aller Markierungen der aktuellen Datei. 
+ 
+Verweise:   Abschnitt 4.2 
+            Benutzerhandbuch Abschnitt 10.4 
+ 
+ 
+2.4 Menü 'Drucken' 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#D           Satzauswahl Drucken#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Name Druckmuster, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Ausdruck des Inhalts der ausgewählten oder markier­
+            ten Sätze in druckbarer Form nach Vorgabe eines
+            Druckmusters. Die Ausgabe kann automatisch zum
+            Drucker geschickt werden oder erst in einer Datei
+            zwischengespeichert werden. 
+ 
+Verweise:   Kapitel 5 
+            Benutzerhandbuch Abschnitt 7.1 und 7.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#R           Richtung Druckausgabe#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Mit dieser Funktion kann festgelegt werden, ob die
+            Druckausgabe automatisch zum Drucker geschickt wird,
+            in eine bestimmte Datei oder in eine automatisch
+            eingerichtete Datei geschrieben wird. 
+ 
+            Die Angabe einer bestimmten Datei gilt nur für den
+            nächsten Druckvorgang. Sie muß also gegebenenfalls
+            wieder neu eingestellt werden. 
+ 
+Verweise:   Abschnitt 5.2 
+            Benutzerhandbuch Abschnitt 7.2 und 12.1 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#E           Textdatei Editieren#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Name Textdatei, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Aufruf des EUMEL-Editors zum Erstellen und Ändern
+            von Druckmustern und Änderungsmustern sowie zum
+            Ansehen der Druckausgabe. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 7.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#A           Textdatei Ausdrucken#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Name Textdatei, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Mit dieser Funktion kann eine Textdatei oder die
+            zwischengespeicherte Ausgabe des Druckens einer
+            EUDAS-Datei zum Drucker geschickt werden. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 7.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#N           Textdatei Nachbearbeiten#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Name Textdatei, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Mit dieser Funktion kann die zwischengespeicherte
+            Ausgabe des Druckens einer EUDAS-Datei mit den
+            Textkosmetikprogrammen 'lineform' und 'pageform'
+            bearbeitet werden. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 12.1 
+ 
+ 
+2.5 Menü 'Dateien' 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#U          Übersicht Dateien System#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Übersicht über die Dateien im System in der aktuellen
+            Benutzertask. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.1 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#L           Datei Löschen#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Dateiname, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Löschen einer beliebigen Datei in der aktuellen Be­
+            nutzertask nach Anfrage. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.1 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#N           Datei Umbenennen#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Dateiname, mit Zeigen, mehrfache Wahl 
+            Neuer Name, ohne Zeigen 
+ 
+Zweck:      Umbenennen einer beliebigen Datei in der aktuellen
+            Benutzertask. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.1 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#K           Datei Kopieren#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Dateiname, mit Zeigen, mehrfache Wahl 
+            Zieldateiname, ohne Zeigen 
+ 
+Zweck:      Anfertigen einer logischen Kopie einer beliebigen
+            Datei in der aktuellen Benutzertask. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.1 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#P           Platzbedarf einer Datei#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Dateiname, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Zeigt den belegten Speicherplatz einer beliebigen
+            Datei in der aktuellen Benutzertask. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.1 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#A           Datei Aufräumen#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Dateiname, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Reorganisieren einer Textdatei oder einer EUDAS-
+            Datei, um Platz zu sparen oder den Zugriff zu be­
+            schleunigen. Empfiehlt sich bei stark veränderten
+            oder umsortierten Dateien. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.1 
+ 
+ 
+2.6 Menü 'Archiv' 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#U           Übersicht Dateien Archiv#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Übersicht aller Dateien auf der eingelegten Archivdis­
+            kette. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#D           Archivübersicht Drucken#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Die Archivübersicht wird direkt zum Drucker ge­
+            schickt. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#K           Datei Kopieren vom Archiv#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Dateiname, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Eine Datei auf der Archivdiskette wird in die aktuelle
+            Benutzertask kopiert. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#S           Datei Schreiben auf Archiv#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Archivname 
+            Dateiname, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Eine Datei aus der aktuellen Benutzertask wird auf
+            die eingelegte Archivdiskette geschrieben. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#L           Datei Löschen auf Archiv#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Archivname 
+            Dateiname, mit Zeigen, mehrfache Wahl 
+ 
+Zweck:      Löschen einer Datei auf der eingelegten Archivdisket­
+            te. Der Platz kann jedoch nicht immer wiederverwendet
+            werden. 
+ 
+Verweis:    Benutzerhandbuch Abschnitt 16.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#I           Archivdiskette Initialisieren#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  keine 
+ 
+Zweck:      Mit dieser Funktion kann eine Archivdiskette komplett
+            gelöscht werden. Die Diskette kann dabei auch gleich­
+            zeitig formatiert werden, falls der Rechner dies zu­
+            läßt. Das Initialisieren ist notwendig, bevor eine neue
+            Diskette als Archiv verwendet werden kann. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#Z           Zielarchiv einstellen#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Managertaskname, ohne Zeigen 
+ 
+Zweck:      Mit dieser Funktion kann eine Managertask angegeben
+            werden, die als Ziel der Archivoperationen dient.
+            Damit können Dateien auch in beliebigen Managertasks
+            oder über das EUMEL-Netz gesichert werden. 
+ 
+            Es wird erfragt, ob die angegebene Task ein Archiv­
+            manager oder ein gewöhnlicher Dateimanager ist. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#P           Paßwort einstellen#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Paßwort 
+ 
+Zweck:      Mit dieser Funktion kann ein Paßwort eingestellt
+            werden, das bei der Kommunikation mit allgemeinen
+            Managertasks überprüft wird. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.2 
+ 
+ 
+#linefeed (0.5)# 
+#on ("b")#R           Archivmanager Reservieren#off ("b")# 
+#linefeed (1.07)# 
+_____________________________________________________ 
+ 
+Parameter:  Reservierungstext 
+ 
+Zweck:      Falls als Zielarchiv eine Managertask eingestellt ist,
+            die zwar kein Archivmanager ist, aber reserviert
+            werden muß (z.B. 'DOS'), kann die Reservierung mit
+            dieser Funktion ausgeführt werden. Die Freigabe
+            erfolgt automatisch beim Verlassen des Menüs. 
+ 
+Verweise:   Benutzerhandbuch Abschnitt 16.2 
+ 
+ 
+ 
+2.7 Kurzabfrage 
+ 
+Wird 'eudas' innerhalb des EUMEL-Editors aufgerufen, so wird eine
+spezielle Kurzabfrage gestartet. Diese ermöglicht die Übernahme von
+Druckdaten direkt in die editierte Datei. 
+    Zunächst wird der Dateiname der zu verwendenden EUDAS-
+Datei erfragt. Diese Datei wird dann geöffnet. Vorher geöffnete und
+veränderte Dateien werden nach Anfrage gesichert. 
+    Als nächstes kann für die folgende Übersicht eine Feldauswahl
+eingestellt werden, damit die relevanten Felder auch auf dem Bild­
+schirm erscheinen. 
+    Danach beginnt ein wiederholbarer Prozeß mit der Eingabe
+eines Suchmusters nach Anfrage. Die ausgewählten Sätze werden
+dann in einer Übersicht gezeigt. In der Übersicht können auch Sätze
+markiert werden. 
+    Nach Verlassen der Übersicht bestehen drei Möglichkeiten zum
+Drucken: Falls mindestens ein Satz markiert wurde, können nach
+Anfrage alle markierten Sätze gedruckt werden. Wurde kein Satz
+markiert, können nach Anfrage alle ausgewählten (bzw. vorher
+angezeigten) Sätze gedruckt werden. Wird diese Frage jeweils ver­
+neint, kann nach Anfrage auch der aktuelle Satz als einziger ge­
+druckt werden. 
+    Wurde eine der Fragen bejaht, wird der Name des Druckmusters
+erfragt, das bereits existieren muß. Das Ergebnis der Druckausgabe
+wird dann an der aktuellen Cursorposition in der editierten Datei
+eingefügt. 
+    Der Prozeß kann danach mit einem anderen Suchmuster wieder­
+holt werden. Dabei werden alle Markierungen wieder gelöscht. 
+
diff --git a/doc/eudas/eudas.ref.3 b/doc/eudas/eudas.ref.3
new file mode 100644
index 0000000..9b58b9b
--- /dev/null
+++ b/doc/eudas/eudas.ref.3
@@ -0,0 +1,270 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (31)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+3 Das virtuelle Dateimodell 
+ 
+ 
+ 
+3.1 Dateistruktur 
+ 
+Eine EUDAS-Datei hat folgende Bestandteile: 
+ 
+- 0 bis 5000 #on("i")#Sätze#off("i")#, von 1 an durchnumeriert. Jeder Satz enthält für
+  jedes Feld einen variabel langen Text als Inhalt, der standard­
+  mäßig leer ist. 
+ 
+- 1 bis 256 #on("i")#Felder#off("i")#, die die Sätze aufteilen. Jedes Feld besitzt einen
+  #on("i")#Feldnamen#off("i")# als Text und einen von vier #on("i")#Feldtypen#off("i")# (TEXT, ZAHL,
+  DATUM oder DIN). Der Feldname dient zur Identifizierung des
+  Feldes, der Feldtyp spezifiziert die Art der Behandlung beim Ver­
+  gleichen von Feldern. 
+ 
+- Drei Zusatztexte. Der erste nimmt die #on("i")#Prüfbedingungen#off("i")# auf, der
+  zweite speichert das Datum der letzten Veränderung und der
+  dritte kann allgemeine #on("i")#Notizen#off("i")# aufnehmen. 
+ 
+- Einen #on("i")#Satzzeiger#off("i")#, der einen bestimmten Satz als aktuellen Satz
+  auszeichnet. Der Satzzeiger kann durch Positionierungsoperatio­
+  nen verändert werden. 
+ 
+- Eine #on("i")#Sortierreihenfolge#off("i")#, die angibt, in welcher Feldreihenfolge die
+  Datei zuletzt sortiert worden ist. Dazu für jeden Satz eine Anga­
+  be, ob er entsprechend dieser Reihenfolge an der richtigen Posi­
+  tion steht. 
+ 
+- Eine interne Datenstruktur, die beschleunigten Zugriff auf eine
+  Satz nach dem Inhalt des ersten Feldes ermöglicht. Diese Struktur
+  steht ganz unter Kontrolle von EUDAS und kann nicht von außen
+  manipuliert werden. 
+ 
+ 
+3.2 Öffnen 
+ 
+#on("b")#Virtuelle Datei#off("b")# Die meisten EUDAS-Funktionen arbeiten
+nicht
+direkt auf einer EUDAS-Datei, sondern auf der sogenannten #on("i")#vir­
+tuellen Datei#off("i")#, die aus mehreren realen Dateien bestehen kann. Die
+virtuelle Datei erscheint nach außen hin wie eine einzelne
+EUDAS-Datei. Die Operationen auf der virtuellen Datei werden je­
+weils auf die einzelnen Bestandteile abgebildet. 
+    Damit eine EUDAS-Datei Bestandteil der virtuellen Datei wird,
+muß sie geöffnet werden. Dieses Öffnen kann auf dreierlei Art und
+Weise geschehen. 
+    Das Öffnen der ersten Datei stellt eine neue virtuelle Datei
+her. Die Feldnamen und Feldeigenschaften der ersten Datei werden
+in der virtuellen Datei übernommen. Dies ist der Normalfall, in dem
+sich die virtuelle Datei noch nicht von der zugrundeliegenden Datei
+unterscheidet. 
+    Bei diesem ersten Öffnen muß angegeben werden, ob die vir­
+tuelle Datei verändert werden soll oder nicht. Falls die virtuelle
+Datei verändert werden soll, wird eine Arbeitskopie aller geöffneten
+Dateien angelegt. Die Ursprungsdateien können erst am Ende der
+Arbeit mit den geänderten Kopien überschrieben werden. 
+ 
+#on("b")#Weitere Dateien#off("b")# Weitere Dateien können gekettet oder
+gekoppelt
+werden. Gekettete Dateien werden logisch an die zuerst geöffnete
+Datei angehängt. Ihre Dateistruktur wird ignoriert, sollte aber mit
+der ersten Datei übereinstimmen. Die Folge aneinander geketteter
+EUDAS-Dateien wird als #on("i")#Hauptdatei#off("i")# bezeichnet. 
+    In der Hauptdatei werden die Sätze von 1 an durchnumeriert;
+die Aufeinanderfolge der Sätze wird durch die Anordnung der Sätze
+in den einzelnen Dateien und die Reihenfolge bestimmt, in der die
+Dateien gekettet wurden. 
+    Die gekoppelten Dateien werden der Hauptdatei untergeordnet.
+Die in ihnen enthaltenen Informationen werden nur angezeigt, wenn
+sie mit einem Satzinhalt der Hauptdatei korrespondieren. Der
+Mechanismus dieser Satzkopplung wird im nächsten Abschnitt
+beschrieben. 
+ 
+ 
+#free (8.0)# 
+ 
+#center#Abb. 3-1   Schematischer Aufbau der virtuellen Datei 
+ 
+ 
+ 
+3.3 Koppeln 
+ 
+    Die Sätze der gekoppelten Dateien werden in Relation zu den
+Sätzen in der Hauptdatei gesetzt. Zu jedem Satz in der Hauptdatei
+kann eine Anzahl von Sätzen aus jeder Koppeldatei gehören. Diese
+Sätze müssen in den Inhalten der sogenannten #on("i")#Koppelfelder#off("i")# über­
+einstimmen. 
+    Welche Felder Koppelfelder sind, richtet sich nach den Feld­
+namen. Die ersten Felder der Koppeldatei, die auch in der Haupt­
+datei vorhanden sind, werden als Koppelfelder betrachtet. Die Kop­
+pelfelder müssen also bei der Koppeldatei am Anfang stehen - in
+der Hauptdatei kann jedes beliebige Feld ein Koppelfeld sein. 
+    Wenn eine Datei zur virtuellen Datei gekoppelt wird, werden
+alle Felder, die nicht Koppelfelder sind, in die virtuelle Datei auf­
+genommen. Die Koppelfelder brauchen nicht noch mal wiederholt zu
+werden, da ihr Inhalt ja immer identisch ist. 
+    Zu beachten ist, daß bei diesem Verfahren auch Namenskonflik­
+te entstehen können, wenn nach den Koppelfeldern später wieder
+ein Feldname vorkommt, der auch in der Hauptdatei vorhanden ist.
+In den Fällen, in denen Felder durch ihren Namen angesprochen
+werden, ist dann das zweite Feld gleichen Namens nicht verfügbar. 
+ 
+ 
+#free (7.0)# 
+ 
+#center#Abb. 3-2   Schema des Koppelvorgangs 
+ 
+ 
+#on("b")#Kombinationen#off("b")# Beim Vorwärtsgehen in der virtuellen Datei
+werden
+zu jedem Satz der Hauptdatei nacheinander alle möglichen Kombina­
+tionen der zugehörigen Koppelsätze angezeigt, denn es können
+mehrere passende Koppelsätze vorhanden sein. Die Satznummer
+bleibt dabei gleich; die einzelnen Kombinationen werden von 1 an
+durchgezählt. Beim Rückwärtsgehen wird aus technischen Gründen
+immer nur die erste Kombination angezeigt. 
+    Existiert zu einem Satz kein passender Koppelsatz, so bleiben
+die entsprechenden Felder leer. Die Koppelsätze müssen in der
+ganzen Koppeldatei gesucht werden, daher ist bei großen Koppel­
+dateien die Suchzeit zu berücksichtigen. 
+ 
+ 
+3.4 Änderungen 
+ 
+In der virtuellen Datei kann auch geändert werden. Dabei ist jedoch
+Vorsicht angebracht. Es muß festgelegt sein, wie Änderungen der
+einzelnen Felder auf die beteiligten Dateien abgebildet werden. 
+    Falls die virtuelle Datei keine Koppeldateien enthält, werden
+Änderungen am aktuellen Satz an der zugehörigen Datei durchge­
+führt. Das Löschen eines Satzes wird auch direkt in der Datei
+durchgeführt. Ein neuer Satz wird immer in der Datei eingefügt, zu
+der der aktuelle Satz gehört - am Ende der ersten Datei kann also
+kein Satz eingefügt werden, wenn noch weitere Dateien folgen. 
+    Enthält die virtuelle Datei Koppeldateien, werden die Änderun­
+gen in der Hauptdatei wie oben beschrieben durchgeführt. Änderun­
+gen, die Felder in den Koppeldateien betreffen, werden nach folgen­
+der Entscheidungstabelle behandelt: 
+ 
+                                   1  2  3  4  5 
+                                  --------------- 
+    Koppelfelder verändert         N  J  J  N  N 
+    Übrige Felder verändert        N  -  -  J  J 
+    Übrige Felder leer             -  J  N  -  N 
+    Vorher Koppelsatz vorhanden    -  -  -  J  N 
+                                  --------------- 
+    Neuen Satz einfügen                  x     x 
+    Koppelsatz ändern                       x 
+    Kopplung aktualisieren            x 
+ 
+Fall 1: Es wurden keine Veränderungen an den Feldern des Kop­
+        pelsatzes vorgenommen, daher ist auch keine Aktion not­
+        wendig. 
+ 
+Fall 2: Eines der Koppelfelder wurde verändert. Die Änderung wird
+        in der Hauptdatei durchgeführt. Die übrigen Felder des
+        Koppelsatzes sind jedoch als leer angegeben. In diesem Fall
+        wird der Koppelsatz nicht verändert, sondern nur eine
+        neue Korrespondenz gesucht. 
+ 
+Fall 3: Eines der Koppelfelder wurde verändert, gleichzeitig ent­
+        halten aber auch die anderen Felder Informationen. In
+        diesem Fall wird ein neuer Satz in der Koppeldatei ange­
+        fügt, der die neuen Inhalte enthält. So wird vermieden,
+        daß an anderer Stelle plötzlich kein passender Koppelsatz
+        mehr vorhanden ist. 
+ 
+Fall 4: Nur Felder der Koppeldatei, die nicht Koppelfelder sind,
+        wurden verändert, außerdem existierte ein korrespondie­
+        render Satz in der Koppeldatei. In diesem Fall werden die
+        Informationen im Koppelsatz abgeändert. 
+ 
+Fall 5: Wie 4, nur war vorher noch kein Koppelsatz vorhanden
+        (Felder waren leer). In diesem Fall muß ein neuer Satz in
+        die Koppeldatei eingefügt werden. Einfügungen in die
+        Koppeldatei geschehen immer am Dateiende. 
+ 
+#on("b")#Einfügen/Löschen#off("b")# Beim Löschen eines Satzes der virtuellen
+Datei
+durch Tragen bleiben die Koppeldateien unverändert. Nach dem
+Einfügen eines neuen Satzes wird nur dann ein Satz in einer Kop­
+peldatei eingefügt, wenn dieser Satz nicht nur Koppelfelder enthal­
+ten würde. Falls beim Einfügen nur die Koppelfelder angegeben
+werden, wird ein korrespondierender Satz in der Koppeldatei ge­
+sucht. Vergleichen Sie hierzu die Regeln beim Ändern. 
+ 
+ 
+3.5 Sichern 
+ 
+Falls Änderungen der virtuellen Datei erlaubt sind, arbeitet EUDAS
+immer auf Sicherheitskopien der beteiligten Dateien. Eine Datei, die
+wirklich verändert wurde, muß vor dem Aufbau einer neuen virtuel­
+len Datei gesichert oder explizit gelöscht werden. 
+    Für jede einzelne Datei kann festgelegt werden, ob sie gesi­
+chert werden soll oder nicht. Als Hilfe wird dazu für jede Datei
+angegeben, ob sie tatsächlich verändert wurde oder nicht. Die
+Arbeitskopie kann beim Sichern die alte Version überschreiben oder
+unter einem neuen Namen gesichert werden. 
+    Am Ende des Sicherns können die Arbeitskopien gelöscht wer­
+den. Anderenfalls werden die Dateien so betrachtet, als ob sie di­
+rekt nach dem Sichern wieder geöffnet worden wären und stehen
+weiterhin zur Verfügung. 
+    Falls alle Dateien entweder gesichert oder nicht verändert
+sind, werden beim nächsten Öffnen einer neuen virtuellen Datei die
+vorherigen Arbeitskopien gelöscht. 
+ 
+ 
+3.6 Umschalten auf Koppeldatei 
+ 
+Falls eine Datei gekoppelt ist, kann man die virtuelle Datei auf
+diese Koppeldatei umschalten. Dadurch verhält sich die virtuelle
+Datei so, als ob nur diese Koppeldatei geöffnet wäre. Die Einstel­
+lungen der Hauptdatei wie Markierungen und Suchbedingung bleiben
+jedoch erhalten und stehen beim Zurückschalten wieder zur Verfü­
+gung. 
+    Die Satzposition der Koppeldatei beim letzten Umschalten wird
+ebenfalls gespeichert und wird beim nächsten Umschalten wieder
+eingenommen, unabhängig von der tatsächlichen Satzposition der
+Koppeldatei zu diesem Zeitpunkt. 
+    Für die Koppeldatei können eigene Markierungen vergeben
+werden, die auch nach dem Umschalten gespeichert bleiben. Auch
+ein Suchmuster kann für die Koppeldatei eingestellt werden, dies
+geht jedoch beim Zurückschalten wieder verloren. Die eingestellte
+Feldauswahl für die Bildschirmanzeige geht leider bei jedem Um­
+schalten verloren. 
+    Das Umschalten kann entweder im Menü 'Einzelsatz' oder beim
+Einfügen und Ändern durch ESC 'K' bewirkt werden, ebenso das
+Zurückschalten nur im Menü 'Einzelsatz'. Beim Umschalten aus Ein­
+fügen oder Ändern erfolgt beim Zurückschalten eine Rückkehr in
+diesen Zustand. Dabei können nach Anfrage die Koppelfelder des
+aktuellen Satzes der Koppeldatei in die Hauptdatei übernommen und
+damit eine bestimmte Kopplung bewirkt werden. 
+ 
+ 
+3.7 Mehrbenutzerbetrieb 
+ 
+Durch Einstellen einer Managertask für den Mehrbenutzerbetrieb
+können auch Dateien dieser Managertask beim Öffnen direkt ver­
+wendet werden. Die Datei wird automatisch aus der Managertask
+kopiert und geöffnet. 
+    Falls die Datei geändert werden soll, wird eine Sperre in der
+Managertask gesetzt, die verhindert, daß auch ein anderer Benutzer
+diese Datei zum Ändern öffnet. Beim Sichern erfolgt dann ein Rück­
+schreiben der Arbeitskopie. Die Sperre wird jedoch erst dann zu­
+rückgesetzt, wenn alle Arbeitskopien gelöscht werden, da erst dann
+keine Möglichkeit des Rückschreibens mehr besteht. 
+    Alle Dateien der Managertask werden bei der Dateiauswahl zum
+Öffnen mit angeboten. Falls eine Datei in beiden Tasks existiert,
+wird die Datei in der Managertask genommen, die Datei der eigenen
+Task jedoch erst nach Anfrage überschrieben. 
+    Damit die Sperre funktionieren kann, muß EUDAS in der Mana­
+gertask zur Verfügung stehen und die Task muß #on("i")#nach#off("i")# dem Insertie­
+ren von EUDAS als 'global manager' definiert werden (nicht 'free
+global manager' verwenden). 
+
diff --git a/doc/eudas/eudas.ref.4 b/doc/eudas/eudas.ref.4
new file mode 100644
index 0000000..cfd6daf
--- /dev/null
+++ b/doc/eudas/eudas.ref.4
@@ -0,0 +1,441 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (39)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+4 Ansehen und Bearbeiten 
+ 
+ 
+ 
+4.1 Anzeige 
+ 
+Die Anzeige und Eingabe von Einzelsätzen sowie die Eingabe von
+Suchmustern geschieht in einem Standardformular in einem recht­
+eckigen Fenster. Dieses Fenster befindet sich in der rechten Bild­
+schirmhälfte. 
+    Das Formular besteht aus vier Teilen: der Überschrift, den
+Feldnamen, den Feldinhalten und der Abschlußzeile (s. Abbildung). 
+ 
+                          Überschrift 
+#free (0.3)# 
+      Satz 33       ..SUCH+..MARK-... datei ............... Feld 1 
+      Feld 1      
+      Feld 2 
+      Feld 3              Feldinhalte 
+      
+      Feld 4 
+      .............................................................. 
+#free (0.3)# 
+  Feldnamen                    Abschlußzeile 
+ 
+ 
+ 
+#on("b")#Überschrift#off("b")# Die Überschrift zeigt folgende Informationen
+an: 
+ 
+    Satz n[-m] 
+    Die Satznummer des aktuellen Satzes, bei gekoppelten Dateien
+    auch die Satzkombination. 
+ 
+    SUCH+/- 
+    Zeigt an, ob der aktuelle Satz die eingestellte Suchbedingung
+    erfüllt oder nicht (wird während Eintragungen nicht angezeigt).
+    Wenn keine Suchbedingung eingestellt ist, erscheint diese An­
+    zeige nicht. 
+ 
+    MARK+/- 
+    Zeigt an, ob der aktuelle Satz markiert ist oder nicht (Wird
+    während Eintragungen nicht angezeigt). Wenn kein Satz mar­
+    kiert ist, erscheint diese Anzeige nicht. 
+ 
+    ENDE 
+    Wird hinter dem letzten Satz der Datei als Kennzeichnung des
+    Endesatzes ausgegeben. 
+ 
+    'Dateiname' 
+    Gibt den Namen der ersten geöffneten Datei an. 
+ 
+    <KOPPPEL> 
+    Erscheint statt des Dateinamens, wenn auf eine Koppeldatei
+    umgeschaltet wurde. 
+ 
+    Feld n/Zeile n 
+    Zeilennummer des obersten angezeigten Feldes (bei Anzeige)
+    bzw. der aktuellen Cursorzeile (während Eintragungen). 
+ 
+#on("b")#Feldteil#off("b")# Die Feldnamen sind zur Unterscheidung von den
+Feld­
+inhalten invers dargestellt. Die Breite der Feldnamen richtet sich
+nach der Länge des längsten Feldnamens. Ist dieser zu lang, um
+noch eine ordentliche Anzeige zu ermöglichen, wird bei einer be­
+stimmten Länge der Rest des Namens abgeschnitten. 
+    Zwischen dem Feldnamen an der linken Seite und dem dane­
+benstehenden Feldinhalt besteht immer eine Korrespondenz, d.h. der
+Inhalt eines Feldes wird direkt neben dem Namen dargestellt. In der
+Regel wird pro Feld eine Bildschirmzeile reserviert. Kann der Feld­
+inhalt jedoch nicht mehr in einer Zeile untergebracht werden, wer­
+den weitere Zeilen zur Darstellung dieses Feldes herangezogen. In
+diesen Zeilen steht statt des Feldnamens nur ein markierter Leer­
+raum. 
+    Alle folgenden Zeilen ohne Namen gehören zu dem gleichen
+Feld. Der Inhalt wird auf diese Zeilen umbrochen, d.h. wenn ein
+Wort nicht mehr auf die Zeile paßt, wird es komplett in die nächste
+Zeile geschrieben (wie beim Editor). Wörter werden nur dann zer­
+schnitten, wenn sie nicht als Ganzes auf eine Zeile passen. Wörter
+werden untereinander durch Leerzeichen getrennt. 
+    Aus Effizienzgründen werden in bestimmten Fällen auch mehr
+Folgezeilen als nötig angezeigt. Hat nämlich ein neuer Satz einen
+kürzeren Inhalt als der vorige, so werden die Feldnamen nur dann
+wieder zusammengerückt, wenn das ganze Bild neugeschrieben wer­
+den muß. Anderenfalls werden nur die Feldinhalte aktualisiert. 
+    Die Bildausgabe wird unterbrochen, wenn 'w' oder 'z' gedrückt
+wurde, da dann die Inhalte des aktuellen Satzes nicht mehr inter­
+essieren. 
+ 
+#on("b")#Rollen#off("b")# Da nicht alle Felder auf den Bildschirm passen
+müssen, kann das Bild gerollt werden. 
+    Mit ESC UNTEN wird um eine Seite nach unten geblättert, mit
+ESC OBEN wieder zurück. Hinter dem letzten Feld erscheint ein
+markierter Balken als Abschlußzeile. Weiter als bis zum Erscheinen
+dieses Balken kann nicht gerollt werden. Mit ESC '1' wird ganz an
+den Anfang gerollt, mit ESC '9' ganz ans Ende. 
+    Bei Feldern, die sich über mehrere Zeilen erstrecken, kann es
+passieren, daß nach dem Rollen die erste Bildschirmzeile nicht die
+erste Zeile eines Feldes ist, also der erste Teil eines Feldes nicht
+dargestellt wird. Trotzdem wird in diesem Fall in der ersten Anzei­
+gezeile der Feldname angezeigt. 
+ 
+#on("b")#Feldauswahl#off("b")# Man kann auswählen, welche Felder in welcher
+Rei­
+henfolge angezeigt werden sollen. Dies dient der besseren Übersicht.
+Von der Anzeige werden nur die ausgewählten Felder behandelt, die
+anderen Felder bleiben leer, werden nicht verändert oder berück­
+sichtigt. Die Anzeigeauswahl ändert jedoch nichts an der Datei­
+struktur. 
+    Die Feldauswahl ist keine permanente Eigenschaft einer
+EUDAS-Datei. Sie geht daher bei einem neuen Öffnen oder beim
+Umschalten auf eine Koppeldatei verloren. 
+ 
+#on("b")#Übersicht#off("b")# Im Gegensatz zur normalen Anzeige, bei der ein
+Satz pro
+Bildschirm dargestellt wird, können in der Übersicht mehrere Sätze
+gleichzeitig überschaut werden. Dabei wird jeder Satz in einer Zeile
+untergebracht. Die Auswahl der Felder, die in der Übersicht er­
+scheinen sollen, wird vor Beginn der Funktion erfragt. 
+    In jeder Zeile steht die Nummer des jeweiligen Satzes, eine
+Anzeige, ob er markiert ist (+) oder nicht (-) und die Feldinhalte
+in der gewählten Reihenfolge und Auswahl, jeweils duch Komma und
+Leerzeichen getrennt. Inhalte, die nicht mehr auf die Zeile passen,
+werden abgeschnitten. 
+    Es werden nur durch das Suchmuster ausgewählte Sätze ange­
+zeigt. Ist der aktuelle Satz nicht ausgewählt, so erscheint an seiner
+Stelle '<< >>' als Hinweis. In der Überschrift sind die Feldnamen
+angegeben - durch Komma getrennt, so viele wie hinpassen. 
+    Die Satznummer des aktuellen Satzes ist jeweils markiert. In
+der Übersicht kann geblättert werden. HOP OBEN und HOP UNTEN,
+OBEN und UNTEN wirken wie im Editor. 
+    Durch '+' oder '-' kann auch die Markierung des aktuellen
+Satzes verändert werden. 
+ 
+ 
+4.2 Satzauswahl 
+ 
+Die Auswahl der Sätze, die gedruckt oder mit den Funktionen aus
+Abschnitt 4.4 bearbeitet werden sollen, kann entweder durch eine
+Suchbedingung oder durch Markierung vorgenommen werden. Wenn
+mindestens ein Satz markiert ist, werden von den Bearbeitungs­
+funktionen nur die markierten Sätze behandelt. Anderenfalls wird
+die eingestellte Suchbedingung beachtet. 
+    Die Bildschirmanzeige richtet sich immer nur nach der einge­
+stellten Suchbedingung. 
+ 
+#on("b")#Suchmuster#off("b")# Ein Suchmuster gibt für jedes Feld bestimmte
+Bedin­
+gungen an. Es wird im Standardformular mit Hilfe des Satzeditors
+eingegeben. Dabei stehen neben jedem Feld die Bedingungen für
+dieses Feld in einer intuitiv verständlichen Form. Folgende Einzel­
+bedingungen sind möglich: 
+ 
+    Muster            Inhalt ist gleich Muster 
+    Muster..          Inhalt ist größergleich Muster 
+    ..Muster          Inhalt ist kleiner Muster 
+    Muster1..Muster2  Inhalt liegt dazwischen 
+    *Muster           Inhalt endet mit Muster 
+    Muster*           Inhalt beginnt mit Muster 
+    *Muster*          Inhalt enthält Muster 
+    *                 Inhalt ist nicht leer 
+    ++                Satz markiert (unabhängig vom Feldinhalt) 
+ 
+Die ersten vier Einzelbedingungen beachten auch den Typ eines
+Feldes (wie er bei der Feldstruktur eingegeben werden kann und
+beim Sortieren beachtet wird). So werden z.B. bei der Gleichheit von
+Zahlen alle nicht-numerischen Zeichen ignoriert (s. Sortieren). 
+    Die drei Bedingungen mit Stern können auch miteinander ver­
+knüpft werden. Die Einzelbedingungen müssen dann alle zutreffen,
+damit der Satz ausgewählt wird. So bedeutet zum Beispiel das
+Muster 'M1*M2*M3*M4', daß das Feld mit 'M1' beginnen und mit 'M4'
+enden muß. Außerdem muß es 'M2' und 'M3' enthalten, jedoch nicht
+unbedingt in der angegebenen Reihenfolge. 
+    Wird der Mustertext durch '&' und einen gültigen Feldnamen der
+aktuellen Datei ersetzt, findet der Vergleich nicht mit einem
+Mustertext, sondern mit dem Inhalt des angegebenen Feldes statt.
+Als Feldtyp für den Vergleich wird in diesem Fall der Typ des Fel­
+des genommen, in dem der Vergleich steht. 
+ 
+#on("b")#Verknüpfung#off("b")# Einzelbedingungen können durch Voranstellen
+von
+'--' verneint werden. Einzelbedingungen für verschiedene Felder
+werden mit UND verknüpft. 
+    Es gibt zwei Arten der ODER-Verknüpfung: die lokale und die
+globale. Die lokale ODER-Verknüpfung wird durch ein Komma zwi­
+schen Einzelbedingungen realisiert. Sie hat eine höhere Priorität als
+das UND zwischen verschiedenen Feldern. So hat folgendes Such­
+muster 
+ 
+ 
+    Feld1   Bed1,Bed2 
+    Feld2   Bed3 
+ 
+ 
+die Bedeutung 
+ 
+ 
+    ( Bed1 (Feld1) ODER Bed2 (Feld2) ) UND Bed3 (Feld3) 
+ 
+ 
+Die globale ODER-Verknüpfung wird durch ein Semikolon repräsen­
+tiert. Alle Einzelbedingungen nach dem n-ten Semikolon aller Zeilen
+werden zu einer Alternative zusammengefaßt. Damit hat das Such­
+muster 
+ 
+ 
+    Feld1   Bed1;Bed2 
+    Feld2   Bed3 
+ 
+ 
+die Bedeutung 
+ 
+ 
+    ( Bed1 (Feld1) UND Bed3 (Feld2) ) ODER Bed2 (Feld1) 
+ 
+ 
+Damit ergibt sich für die Priorität der einzelnen Konstruktionen
+folgende Reihenfolge: 
+ 
+    höchste        Einzelbedingung 
+                   Verkettung von Einzelbedingungen (UND) 
+                   Verneinung 
+                   lokales ODER 
+                   UND zwischen Feldern 
+    niedrigste     globales ODER 
+ 
+#on("b")#Optimierung#off("b")# Wenn für das erste Feld einer Datei eine
+Gleich-
+Bedingung angegeben wurde und keine globale Alternative vorhan­
+den ist, kann der Suchvorgang wegen der Dateistruktur optimiert
+werden, indem nur Sätze untersucht werden müssen, die im ersten
+Feld den gesuchten Text enthalten. 
+ 
+#on("b")#Reservierte Zeichen#off("b")# Im Rahmen der Analyse einer
+Musterzeile
+wirken folgende Zeichenfolgen als unbeschränkt reservierte Zeichen: 
+ 
+ 
+        ,    ;    ..    * 
+ 
+ 
+Sie dürfen daher in keinem Mustertext oder Feldnamen vorkommen,
+da sie als Separator wirken. Die beiden folgenden Zeichenfolgen
+werden nur zu Anfang eines durch die vorstehenden Separatoren
+gebildeten Abschnitts erkannt: 
+ 
+ 
+        --    &    ++ 
+ 
+ 
+Sie dürfen daher prinzipiell an weiterer Stelle vorkommen, ohne als
+Sonderzeichen erkannt zu werden. Alle anderen Zeichen in der Zeile
+werden dem Mustertext bzw. Feldnamen ohne weitere Interpretation
+zugeordnet. 
+ 
+ 
+4.3 Sortieren und Reorganisieren 
+ 
+Eine EUDAS-Datei kann in einer beliebigen Feldreihenfolge sortiert
+werden. Mit dieser Angabe kann man bestimmen, welche Felder beim
+Vergleich zweier Sätze berücksichtigt werden sollen und in welcher
+Reihenfolge. 
+    Die Sortierreihenfolge wird in der Datei gespeichert und wird
+anschließend immer wieder verwendet, wenn keine anderen Angaben
+gemacht wurden. 
+    Der Sortierzustand einer Datei wird ebenfalls gespeichert. Wenn
+nur wenige Sätze seit der letzten Sortierung verändert wurden,
+müssen auch nur diese Sätze einsortiert werden. 
+ 
+#on("b")#Feldtypen#off("b")# Um eine korrekte Sortierung auch von Zahlen oder
+Daten sicherzustellen, wird jedem Feld einer EUDAS-Datei ein Feld­
+typ zugeordnet, der beim Sortieren (und auch beim Suchen) berück­
+sichtigt wird. 
+    Es gibt folgende Feldtypen (als Standard wird der Typ TEXT
+verwendet): 
+ 
+  TEXT   Vergleich von Texten nach dem EUMEL-Code der einzel­
+         nen Zeichen. Dies ist Standard und sorgt für schnellst­
+         möglichen Vergleich. Die weiteren Typen brauchen erheb­
+         lich mehr Zeit. 
+ 
+  DIN    Vergleich nach DIN 5007 (s. EUMEL-Benutzerhandbuch).
+         Umlaute werden korrekt eingeordnet, Groß- und Klein­
+         buchstaben werden gleichbehandelt, Sonderzeichen werden
+         ignoriert. 
+ 
+  ZAHL   Der Wert einer Zahl wird verglichen. Außer den Ziffern,
+         dem Dezimalkomma und dem Minuszeichen vor der ersten
+         Ziffer werden alle anderen Zeichen ignoriert. Das Dezi­
+         malkomma ist standardmäßig auf ',' eingestellt, kann aber
+         verändert werden (s. Abschnitt 6.5). Die nicht ignorierten
+         Zeichen werden in eine REAL-Zahl umgewandelt und dann
+         verglichen. 
+ 
+  DATUM  Es werden Daten der Form 'tt.mm.jj' verglichen. In diesem
+         Fall werden Tag und Jahr vertauscht und dann vergli­
+         chen. Texte mit einer anderen Länge als 8 werden alle
+         als gleich betrachtet. 
+ 
+#on("b")#Reorganisieren#off("b")# Wenn viele Änderungen an einer EUDAS-Datei
+vorgenommen worden sind, steigt ihr Platzbedarf durch viele Text­
+leichen an. In diesem Fall empfiehlt es sich, die Datei zu reorgani­
+sieren. Auch wenn beim Sortieren viele Sätze vertauscht wurden,
+sollte die Datei reorganisiert werden, da beim Sortieren die physi­
+kalische Reihenfolge der Sätze nicht verändert wird. In diesem Fall
+ergibt sich nach dem Reorganisieren ein Geschwindigkeitsvorteil. 
+ 
+ 
+4.4 Bearbeiten 
+ 
+#on("b")#Kopieren#off("b")# Durch Kopieren kann ein Ausschnitt aus der
+virtuellen
+Datei in eine andere EUDAS-Datei kopiert werden. Es werden alle
+ausgewählten Sätze kopiert. Wenn mindestens ein Satz markiert ist,
+werden alle markierten Sätze als ausgewählt betrachtet, ansonsten
+alle, die durch die Suchbedingung angegeben sind. Die kopierten
+Sätze werden am Ende der Zieldatei angefügt. 
+    Welche Felder kopiert werden sollen, wird durch das Kopier­
+muster angegeben. Hierbei können auch mehrere Felder zu einem
+verschmolzen werden. Allgemein ergeben sich die Felder der Ziel­
+datei aus einem beliebigen ELAN-Ausdruck. 
+    Das Kopiermuster ist ein ELAN-Programm und enthält im we­
+sentlichen Ausdrücke der Form 
+ 
+ 
+        "Feldname" K Ausdruck ; 
+ 
+ 
+Durch diese Anweisung wird der Ausdruck in das Feld der Zieldatei
+mit dem angegebenen Namen kopiert. Existiert dieses Feld in der
+Zieldatei noch nicht, so wird es als letztes angefügt. Falls die
+Zieldatei noch nicht existiert, wird sie eingerichtet. In diesem Fall
+bestimmt also die Reihenfolge der 'K'-Ausdrücke die Reihenfolge der
+Feldnamen in der Zieldatei. 
+    Da die Reihenfolge der 'K'-Ausdrücke wichtig ist, dürfen diese
+nicht in einer IF-Anweisung stehen, sondern müssen für jeden Satz
+komplett in der gleichen Reihenfolge ausgeführt werden. 
+ 
+#on("b")#Standard-Kopiermuster#off("b")# Vor dem Kopieren wird ein Standard-
+Kopiermuster zum Editieren angeboten, das sich nach der Zieldatei
+richtet. Existiert die Zieldatei noch nicht, wird das Muster so kon­
+struiert, daß alle Felder der virtuellen Datei unverändert kopiert
+werden. Wollen Sie einige Felder nicht kopieren, brauchen Sie nur
+die entsprechenden Zeilen zu löschen; wollen Sie die Felder in eine
+andere Reihenfolge bringen, müssen Sie die Zeilen umordnen. 
+    Existiert die Zieldatei bereits, gibt das Standard-Kopiermuster
+an, daß alle Felder der Zieldatei einen Wert erhalten. Ist ein Feld
+der Zieldatei in der virtuellen Datei enthalten, so wird dieses ko­
+piert, ansonsten erhält das Feld einen leeren Inhalt. Sie können in
+diesem Fall weitere Felder angeben oder für die leeren Felder Aus­
+drücke formulieren. 
+ 
+#on("b")#Tragen#off("b")# Durch Tragen werden alle ausgewählten Sätze der
+virtuel­
+len Datei in eine andere Datei transportiert. Sie sind in der vir­
+tuellen Datei dann nicht mehr vorhanden. Damit bei diesem Vorgang
+keine Informationen verlorengehen können, muß die Zieldatei so
+viele Felder haben wie die virtuelle Datei. Normalerweise sollte sie
+in der Feldstruktur mit der virtuellen Datei übereinstimmen. 
+    Die getragenen Sätze werden jeweils am Ende der Datei ange­
+fügt. 
+    Beim Tragen können zusätzlich noch Konsistenzbedingungen
+überprüft werden. Die Prüfbedingungen sind in der Zieldatei gespei­
+chert und können beim Ändern der Feldstruktur angegeben werden. 
+    Die Prüfbedingung ist ein ELAN-Programm, das vor dem Tragen
+des jeweiligen Satzes ausgeführt wird. Durch spezielle Testprozedu­
+ren kann das Tragen des Satzes verhindert werden, wenn diese
+Prozeduren ein negatives Ergebnis liefern. Gleichzeitig wird eine
+Meldung in eine Protokolldatei geschrieben, die dann zur Identifi­
+zierung der fehlerhaften Sätze dienen kann. 
+    Folgende Prüfprozeduren stehen zur Verfügung (siehe auch
+Abschnitt 8.3): 
+ 
+ 
+    pruefe ("Feldname", Bedingung) 
+ 
+        Hiermit kann eine beliebige Bedingung (BOOL-Ausdruck in
+        ELAN) überprüft werden. 
+ 
+ 
+    wertemenge ("Feldname", "Wert1,Wert2,...,Wertn") 
+ 
+        Das Feld muß einen in der angegebenen Liste enthaltenen
+        Werte annehmen. 
+ 
+ 
+    feldmaske ("Feldname", "Maske") 
+ 
+        Das Feld wird auf Übereinstimmung mit der Maske geprüft.
+        Fünf spezielle Zeichen in der Maske können dabei auf
+        mehrere Zeichen zutreffen: 
+          '9'  alle Ziffern 
+          'a'  alle Kleinbuchstaben, Umlaute, 'ß' 
+          'A'  alle Großbuchstaben, Umlaute 
+          'X'  alle Zeichen 
+          '*'  Folge von beliebigen Zeichen 
+        Der Stern sollte sparsam angewendet werden, da er verar­
+        beitungsaufwendig ist. 
+ 
+ 
+    eindeutige felder (n) 
+ 
+        Die Zahl 'n' gibt an, die wieviel ersten Felder der Zieldatei
+        eindeutig sein müssen. Stimmt der zu tragende Satz mit
+        einem Satz der Zieldatei in diesen Feldern überein, wird
+        eine Fehlermeldung erzeugt. 
+ 
+Es können auch einzelne Sätze manuell getragen werden. In diesem
+Fall wird die Prüfbedingung nicht getestet. Ebenso kann der Satz
+wieder zurückgeholt und in der aktuellen Datei eingefügt werden. 
+ 
+#on("b")#Nach Vorschrift ändern#off("b")# Die ausgewählten Sätze der
+virtuellen
+Datei können automatisch nach einer Verarbeitungsvorchrift geän­
+dert werden. Die Verarbeitungsvorschrift ist ein ELAN-Programm, in
+dem mit Hilfe des Operators 'V' Änderungen angegeben werden: 
+ 
+ 
+        "Feldname" V TEXT-Ausdruck ; 
+ 
+ 
+Das angegebene Feld erhält den Inhalt, der durch den Ausdruck
+angegeben ist. Änderungen an Koppeldateien werden wie im Dialog
+behandelt (s. Abschnitt 3.4). 
+ 
+ 
+ 
+
diff --git a/doc/eudas/eudas.ref.5 b/doc/eudas/eudas.ref.5
new file mode 100644
index 0000000..02971ea
--- /dev/null
+++ b/doc/eudas/eudas.ref.5
@@ -0,0 +1,432 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (49)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+5 Drucken und Druckmuster 
+ 
+ 
+ 
+5.1 Druckmustersyntax 
+ 
+Ein Druckmuster ist eine Beschreibung für die Form, in der die In­
+halte einer EUDAS-Datei ausgedruckt werden sollen. Der syntakti­
+sche Aufbau des Druckmusters ist zeilenorientiert und gehorcht
+folgender Syntax: 
+ 
+    Druckmuster : 
+      [ Initialisierungsteil ] 
+      [ Vorspann ] 
+      [ Wiederholungsteil ] 
+      [ Nachspann ] 
+ 
+    Initialisierungsteil : 
+      ( Kommandozeile #char (""124"")# Textzeile )* 
+      ( GRUPPE-Anweisung #char(""124"")# Textzeile )* 
+ 
+    Vorspann : 
+      VORSPANN-Anweisung  Abschnitt 
+ 
+    Wiederholungsteil : 
+      WIEDERHOLUNG-Anweisung  Abschnitt 
+ 
+    Nachspann : 
+      NACHSPANN-Anweisung  Abschnitt 
+ 
+    Abschnitt : 
+      Musterteil 
+      [ ABKUERZUNGEN-Anweisung  Abkürzungsteil ] 
+ 
+    Musterteil : 
+      ( Musterzeile #char(""124"")# Kommandozeile #char(""124"")# 
+        MODUS-Anweisung #char (""124"")# MEHR-Anweisung )* 
+ 
+Zur Notation: [] bedeutet optional, ()* beliebig häufige Wiederho­
+lung, #char(""124"")# Alternative und keine Angabe einfache Aneinanderreihung.
+Die verschiedenen Zeilentypen werden weiter unten beschrieben. 
+    Zusätzlich gilt die Bedingung, daß von Vorspann, Wiederho­
+lungsteil und Nachspann mindestens einer vorhanden sein muß. 
+ 
+#on("b")#Zeilentypen#off("b")# Im Druckmuster gibt es 6 verschiedene
+Zeilentypen: 
+ 
+#on("i")#Kommandozeilen#off("i")# 
+    Eine Kommandozeile beginnt mit '%%' in der ersten und zweiten
+    Spalte. Der Inhalt der Zeile ab Spalte 3 wird dem ELAN-Compi­
+    ler übergeben. Die Bedeutung dieser Zeilen ergibt sich aus dem
+    in 5.4 beschriebenen Übersetzungsmechanismus. 
+ 
+#on("i")#Anweisungen#off("i")# 
+    Anweisungen beginnen mit '%' in der ersten Spalte und dienen
+    zur Steuerung des Druckgenerators. Der Name der Anweisung
+    muß in Großbuchstaben und ohne Leerzeichen geschrieben
+    werden. Davor dürfen sich noch Leerzeichen befinden. An­
+    schließend können noch Parameter folgen, die nur durch Leer­
+    zeichen getrennt aneinander gereiht werden. Die Syntax einer
+    Anweisung ähnelt der eines Operators in ELAN. 
+ 
+#on("i")#Textzeilen#off("i")# 
+    Textzeilen sind die nicht anderweitig markierten Zeilen im
+    Initialisierungsteil. Sie werden unverändert an den Anfang
+    jeder Druckdatei gestellt. 
+ 
+#on("i")#Musterzeilen#off("i")# 
+    Musterzeilen sind nicht besonders gekennzeichnete Zeilen im
+    Musterteil. Sie enthalten Feldmuster und werden nach dem
+    Einsetzen von Inhalten in die Ausgabedatei übernommen. Die
+    Interpretation der Musterzeilen wird in Abschnitt 5.3 beschrie­
+    ben. 
+ 
+#on("i")#Abkürzungszeilen#off("i")# 
+    Abkürzungszeilen markieren den Beginn einer Abkürzung im
+    Abkürzungsteil eines Abschnittes. Sie werden durch '&' in der
+    ersten Spalte gekennzeichnet. Darauf folgt ohne Zwischenraum
+    der Name einer Abkürzung (ohne Leerzeichen) und danach
+    durch Leerzeichen getrennt ein Semikolon. Der Name der Ab­
+    kürzung wird bei der Übersetzung durch einen Refinementnamen
+    ersetzt und die Zeile dem ELAN-Compiler übergeben. Der Rest
+    der Zeile kann also den Beginn eines werteliefernden Refine­
+    ments enthalten. 
+ 
+#on("i")#Programmzeilen#off("i")# 
+    Programmzeilen sind die nicht durch '&' markierten Zeilen im
+    Abkürzungsteil. Sie werden unverändert an den ELAN-Compiler
+    übergeben. Der erlaubte Inhalt richtet sich nach dem Überset­
+    zungsmechanismus (5.4). 
+ 
+ 
+5.2 Der Druckvorgang 
+ 
+Der Druckvorgang besteht im wesentlichen darin, daß für alle zu
+bearbeitenden Sätze der Wiederholungsteil einmal interpretiert wird
+und das Ergebnis in eine Ausgabedatei geschrieben wird, die dann
+gedruckt werden kann. Wenn mindestens ein Satz markiert ist, wer­
+den alle markierten Sätze der virtuellen Datei bearbeitet, ansonsten
+alle durch die Suchbedingung erfaßten. 
+ 
+#on("b")#Gruppen#off("b")# Eine #on("i")#Gruppe#off("i")# ist eine Folge von Sätzen, die in einem be­
+stimmten Merkmal übereinstimmen. Durch eine GRUPPE-Anweisung
+der Form 
+ 
+ 
+        % GRUPPE n  Ausdruck 
+ 
+ 
+werden aufeinanderfolgende Sätze mit gleichem Wert des angegebe­
+nen Ausdrucks gruppiert. Über die Nummer 'n' kann festgestellt
+werden, ob sich das angegebene Merkmal verändert hat. Dies ge­
+schieht mit der Prozedur 
+ 
+ 
+        BOOL PROC gruppenwechsel (INT CONST gruppennr) 
+ 
+ 
+Immer wenn zwischen zwei Sätzen ein Gruppenwechsel stattfindet,
+wird beim vorigen Satz der Nachspann und beim folgenden Satz der
+Vorspann einmal interpretiert. Dies führt dazu, daß entsprechende
+Vorspann- bzw. Nachspannzeilen gedruckt werden. 
+    Vor dem ersten und nach dem letzten zu bearbeitenden Satz
+wechseln alle Gruppen, d.h. dort wird immer ein Vorspann bzw.
+Nachspann erzeugt. 
+    Ist ein zu interpretierender Abschnitt nicht vorhanden, so wird
+an dieser Stelle keine Ausgabe erzeugt. Die Textzeilen des Initali­
+sierungsteils werden auf jeden Fall bei Beginn des Druckvorganges
+in die Ausgabedatei geschrieben. Falls die Ausgabedatei voll ist,
+wird eine neue Datei angefangen und die Zeilen des Initialisie­
+rungsteils erneut an den Anfang gestellt. 
+ 
+ 
+        Satz-  Gruppen-  Ausgabe 
+        nummer merkmal 
+#free (0.1)# 
+                                     Initialisierungsteil 
+        ------------------------------------------------- 
+          1        x                 Vorspann 
+                         WDH-Teil 
+          2        x     WDH-Teil 
+                                     Nachspann 
+        ------------------------------------------------- 
+          3        y                 Vorspann 
+                         WDH-Teil 
+          4        y     WDH-Teil 
+          5        y     WDH-Teil 
+                                     Nachspann 
+        ------------------------------------------------- 
+        ENDE 
+ 
+#center#Abb. 5-1   Ablauf des Druckvorganges mit Gruppen 
+ 
+ 
+#on("b")#Spaltendruck#off("b")# Normalerweise werden die Ausgaben der
+einzelnen
+Abschnitte hintereinander in der Ausgabedatei plaziert. Durch An­
+gabe einer Nummer als Parameter in der WIEDERHOLUNG-Anweisung
+können auch soviel Spalten wie angegeben nebeneinander gedruckt
+werden. Die Spaltenbreite wird dabei durch das Dateilimit (Komman­
+do 'limit' im Editor) festgelegt. Alternativ kann die Spaltenbreite
+auch als zweiter Parameter durch Leerzeichen getrennt angegeben
+werden. 
+    Vorspann und Nachspann werden jedoch auf jeden Fall wieder
+in eine eigene Zeile geschrieben, der Spaltendruck also unterbro­
+chen. 
+ 
+ 
+5.3 Interpretation von Musterzeilen 
+ 
+Musterzeilen können Feldmuster enthalten, die bei der Interpreta­
+tion durch entsprechende Inhalte ersetzt werden, ehe die Muster­
+zeile in die Ausgabedatei übernommen wird. Der Beginn eines Feld­
+musters wird durch ein Musterzeichen ('&' oder '%') markiert. Wo
+und wie der Inhalt eingesetzt wird, kann durch folgende Variationen
+angegeben werden: 
+ 
+ 
+        Typ ! Beispiel  ! Position ! Länge    ! bündig 
+        ----+-----------+------------------------------ 
+         1  ! &Name     ! fest     ! variabel ! links 
+         2  ! %Name     ! variabel ! variabel ! links 
+         3  ! &Name&&&  ! fest     ! fest     ! links 
+         4  ! %Name%%%  ! variabel ! fest     ! links 
+         5  ! &&&Name&  ! fest     ! fest     ! rechts 
+         6  ! %%%Name%  ! variabel ! fest     ! rechts 
+ 
+ 
+Der in dem Feldmuster angegebene Name muß Name einer Abkür­
+zung in irgendeinem Abkürzungsteil oder eines Feldes sein. Der
+Name darf kein Leerzeichen oder Musterzeichen enthalten. Falls dies
+doch der Fall ist, muß der Name in spitze Klammern eingeschlossen
+werden. 
+    Bei fester Länge wird bei zu kurzem Inhalt mit Leerzeichen
+aufgefüllt, bei zu langem Inhalt abgeschnitten. Bei linksbündigem
+Einsetzen geschieht dies an der rechten, sonst an der linken Seite. 
+    Feldmuster variabler Länge können je nach Inhalt dazu führen,
+daß der folgende Teil der Musterzeile verschoben wird. Für diesen
+Einsetzprozeß gelten die folgenden Regeln: 
+ 
+#on("b")#Position#off("b")# Feldmuster fester Position (mit '&' beginnend)
+werden
+immer in der Position eingesetzt, in der sie stehen. Feldmuster
+variabler Position (mit '%' beginnen) können nach rechts verschoben
+werden, wenn vorherige Inhalte länger als ihre Muster sind, und
+nach links, wenn Modus 1 oder 3 eingestellt ist und vorherige In­
+halte kürzer sind. 
+ 
+#on("b")#Länge#off("b")# Feldmuster variabler Länge erhalten auf jeden Fall
+den
+Platz, der durch die Länge des Feldmusters reserviert ist. Sind die
+Inhalte kürzer, kann der gewonnene Platz als Reserve für andere
+Feldmuster verwendet werden; sind die Inhalte länger, so wird der
+Inhalt so weit eingesetzt, wie noch Reserve vorhanden ist und der
+Rest abgeschnitten. 
+    Muß in ein Feldmuster variabler Länge ein leerer Inhalt einge­
+setzt werden, so werden beim Drucken auch die auf das Feldmuster
+folgenden Leerzeichen unterdrückt, falls vor dem Feldmuster noch
+ein Leerzeichen steht oder das Feldmuster in Spalte 1 beginnt. 
+    Feldmuster fester Länge werden immer in ihrer reservierten
+Länge eingesetzt. Sie werden im folgenden behandelt wie Feldmuster
+variabler Länge, deren Inhalt so lang ist wie das Feldmuster. 
+ 
+#on("b")#Verteilung#off("b")# Die Verteilung der verschiebbaren Feldmuster
+auf der
+Zeile geschieht jeweils in dem Abschnitt zwischen zwei Feldmustern
+fester Position bzw. Zeilenanfang oder Zeilenende. Für jeden Ab­
+schnitt wird festgestellt, wieviel Stellen die Inhalte insgesamt mehr
+oder weniger als ihre Muster benötigen. 
+    Der Längenausgleich geschieht zwischen dem letzten Feldmuster
+und dem Ende des Abschnitts. Dort wird ein Pufferplatz bestimmt,
+der bei Überlänge bis auf ein Leerzeichen verkleinert werden kann
+und an dem bei Unterlänge zusätzliche Leerzeichen eingefügt wer­
+den. 
+    Außer am Pufferplatz wird an keinem Mustertext des Abschnitts
+etwas geändert. Zwischentexte zwischen den Feldmustern werden
+unverändert übertragen und mit den umgebenden Feldmustern ver­
+schoben. 
+    Als Pufferplatz wird die erste Lücke hinter dem letzten Feld­
+muster eines Abschnittes verwendet, die mehr als ein Leerzeichen
+enthält. Ist keine solche Lücke vorhanden, wird das Ende des Ab­
+schnitts verwendet, falls dort ein Leerzeichen steht, und sonst das
+Ende des letzten Feldmusters. 
+    Die durch den Pufferplatz und kürzere Inhalte gewonnene Re­
+serve wird von links an die Feldmuster mit Überlänge verteilt, bis
+die Reserve verbraucht ist. 
+ 
+#on("b")#Zeilende#off("b")# Das Zeilenende wird als ein Quasi-Feldmuster mit
+fester
+Position aufgefaßt, das am Limit der Druckmusterdatei steht. Es
+sind also keine Einsetzungen möglich, die über das Limit der Datei
+hinausgehen. Als Pufferplatz wird hier jedoch die erste Blanklücke
+vom Zeilenende her verwendet, damit Mustertexte am Zeilenende
+gegebenenfalls stehenbleiben. Ist keine solche Lücke vorhanden, so
+wird das Zeilenende als Pufferplatz verwendet. 
+    Obwohl nicht als Pufferplatz ausgewiesen, kann der Raum zwi­
+schen Zeilenende und Dateilimit als Reserve verwendet werden. 
+ 
+#on("b")#Modi#off("b")# Der Einsetzmechanismus kann durch die MODUS-Anweisung
+mit einem Parameter verändert werden. Folgende Modi stehen zur
+Verfügung: 
+ 
+ 
+        Modus ! Effekt 
+        ------+---------------------------------------- 
+          1   ! Normalmodus. 
+              ! '%'-Feldmuster werden auch 
+              ! nach links geschoben. 
+              ! Keine Zeilenwiederholung. 
+        ------+---------------------------------------- 
+          2   ! Tabellenmodus. 
+              ! '%'-Feldmuster werden nicht 
+              ! nach links geschoben. 
+              ! Keine Zeilenwiederholung. 
+        ------+---------------------------------------- 
+          3   ! Normalmodus mit Zeilenwiederholung. 
+              ! '%'-Feldmuster werden auch 
+              ! nach links geschoben. 
+              ! Zeilenwiederholung ohne Zwischentexte. 
+        ------+---------------------------------------- 
+          4   ! Tabellenmodus mit Zeilenwiederholung. 
+              ! '%'-Feldmuster werden nicht 
+              ! nach links geschoben. 
+              ! Zeilenwiederholung mit Zwischentexten. 
+        ------+---------------------------------------- 
+ 
+ 
+Bei Zeilenwiederholung werden Inhalte in einer folgenden Zeile
+fortgesetzt, falls sie in der ersten Zeile nicht untergebracht werden
+konnten. Dazu wird die Musterzeile mit den Restinhalten erneut
+interpretiert. Je nach Modus werden auch die Zwischentexte noch
+wiederholt. Der Restinhalt umfaßt immer noch das ganze letzte Wort,
+das nicht mehr auf die vorige Zeile paßte. Es findet also ein Um­
+bruch statt. Die Positionen, die in der vorigen Zeile vom Anfang des
+Wortes eingenommen würden, werden durch Leerzeichen ersetzt. 
+    Durch die MEHR-Anweisung mit einem Parameter kann die Zahl
+der Zeilenwiederholungen für die nächste Musterzeile festgesetzt
+werden. Dies hat jedoch nur eine Auswirkung, falls Zeilenwieder­
+holung zugelassen ist. Stehen zur Interpretation keine Restinhalte
+mehr zur Verfügung, wird mit leeren Inhalten weitergearbeitet. Kann
+ein Inhalt bei der vorgegebenen Anzahl von Zeilen nicht ganz dar­
+gestellt werden, wird der Rest nicht ausgegeben. 
+ 
+ 
+5.4 Anschluß zum ELAN-Compiler 
+ 
+Falls in einem Druckmuster Abkürzungen, Kommandozeilen oder
+Gruppendefinitionen vorkommen, wird das Druckmuster in ein
+ELAN-Programm umgewandelt, das dann vom ELAN-Compiler über­
+setzt wird. 
+    Alle Zeilen eines Abkürzungsteils werden direkt in das Pro­
+gramm übernommen, wobei der Name einer Abkürzung durch einen
+beliebig gewählten Refinementnamen ersetzt wird ('abk' + eine lau­
+fende Nummer). Alle Abkürzungen und Refinements werden als glo­
+bale Refinements definiert, also außerhalb von Prozeduren. Dadurch
+wird erreicht, daß sie an jeder Stelle verwendet werden können. 
+    Damit eine Abkürzung richtig als Refinement übersetzt wird,
+muß sie ein TEXT-Objekt als Wert liefern. Die anderen Refinements
+sind beliebig, da sie nur in selbstdefinierten Anweisungen verwen­
+det werden. Die Refinements der Abkürzungen werden in einer Zu­
+weisung an eine TEXT-Variable verwendet, damit der Druckgenera­
+tor auf den entsprechenden Wert zugreifen kann. 
+    Jeder Abschnitt wird dagegen als eine Prozedur übersetzt. Eine
+Folge von Musterzeilen wird in eine Anweisung übersetzt, diese
+Musterzeilen einzusetzen und zu drucken. Eine '%%'-Anweisung wird
+einfach unverändert dazwischengeschrieben. Die Prozedur für den
+Wiederholungsteil wird einmal für jeden ausgewählten Satz aufgeru­
+fen, die Vorspann- und die Nachspann-Prozedur einmal bei jedem
+Gruppenwechsel. 
+    Anweisungen im Initialisierungsteil werden an den Anfang des
+Programms als globale Definitionen gestellt. 
+ 
+#on("b")#Fehler#off("b")# Findet sich in dem erzeugten ELAN-Programm ein
+Fehler,
+der durch den Druckgenerator nicht erkannt werden konnte (z.B.
+eine Abkürzung liefert keinen Wert), so muß der ELAN-Compiler
+diesen Fehler erkennen. Anschließend zeigt er das erzeugte Pro­
+gramm zusammen mit seinen Fehlermeldungen im Paralleleditor. Sie
+müssen nun die Fehlermeldung lokalisieren und anhand der eben
+gegebenen Hinweise in das ursprüngliche Druckmuster zurücküber­
+setzen, damit Sie dort den Fehler korrigieren können. 
+ 
+ 
+5.5 Fehlermeldungen 
+ 
+Folgende Fehlermeldungen können bei der Übersetzung eines Druck­
+musters auftreten: 
+ 
+#on("i")#keine schliessende Klammer in Feldmuster#off("i")# 
+  Wenn der Name in einem Feldmuster in spitze Klammern einge­
+  schlossen werden soll, muß noch in der gleichen Zeile eine
+  schließende Klammer vorhanden sein. 
+ 
+#on("i")#kein Kommando in Kommandozeile#off("i")# 
+  Eine Zeile, die mit '%' beginnt, enthält keinen weiteren Text. 
+ 
+#on("i")#unbekanntes Kommando#off("i")# 
+  Das erste Wort in einer Kommandozeile ist kein bekanntes Kom­
+  mando. 
+ 
+#on("i")#kein % WIEDERHOLUNG gefunden#off("i")# 
+  Das Druckmuster enthält keine Anweisung, die den Beginn eines
+  Abschnittes markiert. Es muß aber mindestens ein Abschnitt
+  vorhanden sein. 
+ 
+#on("i")#nur GRUPPE-Anweisung erlaubt#off("i")# 
+  Im Initialisierungsteil ist nur die GRUPPE-Anweisung erlaubt. 
+ 
+#on("i")#keine ELAN-Anweisung im Initialisierungsteil nach Gruppen­ 
+definition#off("i")# 
+  Sobald im Initialisierungsteil eine GRUPPE-Anweisung aufgetreten
+  ist, ist keine Kommandozeile mehr möglich. 
+ 
+#on("i")#illegale Gruppennummer#off("i")# 
+  In einer GRUPPE-Anweisung wurde eine zu große Nummer angege­
+  ben. Gruppen sollten von 1 an durchnumeriert werden. 
+ 
+#on("i")#diese Gruppe wurde schon definiert#off("i")# 
+  Eine Gruppennummer wurde mehrfach verwendet. 
+ 
+#on("i")#diese Abkürzung ist nicht definiert#off("i")# 
+  Ein Name in einem Feldmuster tritt nicht als Feld-oder Abkür­
+  zungsname auf. Eventuell enthält er ein Leerzeichen! 
+ 
+#on("i")#dieser Abschnitt wurde schon einmal definiert#off("i")# 
+  Kein Abschnitt kann mehrmals angegeben werden. 
+ 
+#on("i")#falscher Modus#off("i")# 
+  In einer MODUS-Anweisung wurde ein nicht definierter Modus als
+  Parameter angegeben. 
+ 
+#on("i")#diese Anweisung darf im Musterteil nicht vorkommen#off("i")# 
+ 
+#on("i")#im Abkürzungsteil darf keine Anweisung auftreten#off("i")# 
+ 
+#on("i")#in dieser Zeile stehen zu viele Feldmuster#off("i")# 
+  Es können maximal 24 Feldmuster in einer Zeile stehen. Abhilfe:
+  mehrere Feldmuster durch eine Abkürzung zusammenfassen. 
+ 
+#on("i")#das Druckmuster enthält zu viele Feldmuster#off("i")# 
+  Die Gesamtanzahl der Feldmuster ist begrenzt. Abhilfe: mehrere
+  Feldmuster durch eine Abkürzung zusammenfassen. 
+ 
+#on("i")#nach dem "&" soll direkt der Name einer Abkürzung folgen#off("i")# 
+  In einer Abkürzungszeile stehen Leerzeichen hinter dem '&'. 
+ 
+#on("i")#kein Doppelpunkt nach Abkürzung#off("i")# 
+  Nach dem Abkürzungsnamen in einer Abkürzungszeile muß durch
+  ein Leerzeichen getrennt ein Doppelpunkt folgen. 
+ 
+#on("i")#Abkürzung mehrfach definiert#off("i")# 
+  Die Abkürzung wurde unter dem gleichen Namen schon einmal,
+  vielleicht in einem anderen Abschnitt, definiert. 
+ 
+#on("i")#das Druckmuster enthält zu viele Abkürzungen#off("i")# 
+  Abhilfe: mehrere Abkürzungen zu einem Ausdruck zusammenfas­
+  sen. 
+ 
+
diff --git a/doc/eudas/eudas.ref.6 b/doc/eudas/eudas.ref.6
new file mode 100644
index 0000000..7c8ada6
--- /dev/null
+++ b/doc/eudas/eudas.ref.6
@@ -0,0 +1,399 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (61)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+6 Struktur von EUDAS-Dateien 
+ 
+ 
+ 
+EUDAS-Dateien können unabhängig von EUDAS über den Daten­
+typ EUDAT manipuliert werden. Die zur Verfügung stehenden Zu­
+griffsoperationen sind in diesem Kapitel beschrieben. 
+    Der Datentyp EUDAT ist analog zum Datentyp FILE. Jede
+EUDAT-Variable kann an eine EUDAS-Datei angekoppelt werden.
+Dadurch lassen sich beliebig viele EUDAS-Dateien gleichzeitig be­
+arbeiten. Wie der Abschnitt 6.6 zeigt, sind so auch ganz andere
+Anwendungen realisierbar. 
+    Die wesentlichen EUDAS-Funktionen (Ansehen, Suchen, Druk­
+ken) können jedoch nicht direkt auf EUDAT-Variablen angewendet
+werden, sondern greifen auf die virtuelle Datei zu, die im nächsten
+Kapitel beschreiben wird. 
+ 
+ 
+6.1 Der Datentyp SATZ 
+ 
+Der Datentyp SATZ stellt einen einzelnen EUDAS-Satz dar, der
+intern als TEXT realisiert ist. Ein SATZ besteht aus bis zu 256
+Feldern, die jeweils einen TEXT enthalten können. Nach dem Initi­
+alisieren sind alle Felder mit "" vorbelegt. Die Felder können über
+Nummern von 1 bis 256 angesprochen werden. 
+    Damit kann man sich einen SATZ als dynamisches ROW n TEXT
+vorstellen, das bis zu 256 Elemente haben kann. Anders als ein
+entsprechendes ROW belegt ein leerer SATZ praktisch keinen Spei­
+cherplatz. 
+    Folgende Zugriffsprozeduren stehen zur Verfügung: 
+ 
+TYPE SATZ 
+ 
+OP := (SATZ VAR, SATZ CONST) 
+ 
+PROC satz initialisieren (SATZ VAR) 
+    Jeder SATZ muß vor Benutzung initialisiert werden. 
+ 
+INT PROC felderzahl (SATZ CONST) 
+    Liefert die Nummer des höchsten belegten Feldes. 
+ 
+PROC feld lesen (SATZ CONST, INT CONST feldnr, 
+                 TEXT VAR inhalt) 
+    Liest den Inhalt des Feldes 'feldnr' in 'inhalt'. 
+ 
+    FEHLER: 
+ 
+    #on("i")#n ist keine Feldnummer#off("i")# 
+    'n' liegt außerhalb des Bereiches 1..256. 
+ 
+PROC feld bearbeiten (SATZ CONST, INT CONST feldnr, 
+     PROC (TEXT CONST, INT CONST, INT CONST) bearbeite) 
+    Ruft 'bearbeite' auf, wobei 'bearbeite' ein Text und zwei Posi­
+    tionen in diesem Text übergeben werden. Die Positionen geben
+    das erste und das letzte Zeichen des durch 'feldnr' ausgewähl­
+    ten Feldes an. Ist der Anfang größer als das Ende, so ist das
+    Feld leer. 
+ 
+    FEHLER: 
+ 
+    #on("i")#n ist keine Feldnummer#off("i")# 
+    'n' liegt außerhalb des Bereiches 1..256. 
+ 
+PROC feld aendern (SATZ VAR, INT CONST feldnr, 
+                   TEXT CONST inhalt) 
+    Schreibt 'inhalt' in das Feld mit der Nummer 'feldnr' 
+ 
+    FEHLER: 
+ 
+    #on("i")#n ist keine Feldnummer#off("i")# 
+    'n' liegt außerhalb des Bereiches 1..256. 
+ 
+INT PROC feldindex (SATZ CONST, TEXT CONST muster) 
+    Falls eines der Felder 'muster' enthält, wird die Nummer dieses
+    Feldes geliefert, sonst 0. 
+ 
+ 
+6.2 Der Datentyp EUDAT 
+ 
+Der Datentyp EUDAT muß ähnlich wie ein FILE an einen benann­
+ten oder unbenannten Datenraum angekoppelt werden. Der Daten­
+raum hat anschließend den Typ 3243. Weitere Zugriffe auf eine
+EUDAT-Variable sind erst nach erfolgtem Ankoppeln zulässig. An­
+derenfalls können undefinierte Fehler entstehen. 
+ 
+TYPE EUDAT 
+ 
+PROC oeffne (EUDAT VAR, TEXT CONST dateiname) 
+    Koppelt die EUDAT-Variable an die EUDAS-Datei mit dem
+    Namen 'dateiname' an. Die Datei wird eingerichtet, falls sie
+    noch nicht existiert. 
+ 
+    FEHLER: 
+ 
+    #on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+    Die angegebene Datei hat nicht den Typ 3243. 
+ 
+PROC oeffne (EUDAT VAR, DATASPACE CONST ds) 
+    Koppelt die EUDAT-Variable an den Datenraum 'ds'. 
+ 
+    FEHLER: 
+ 
+    #on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+    Der Datenraum wurde bereits verwendet und hat nicht den Typ
+    3243. 
+ 
+Eine EUDAS-Datei ist in Felder und Sätze unterteilt. Die Felder
+werden beim Zugriff über Nummern angesprochen. Jedem Feld ist
+jedoch zur Identifikation ein TEXT als Feldname zugeordnet. Die
+Feldnamen werden als SATZ gespeichert, wobei jedes Feld seinen
+zugeordneten Namen enthält. 
+ 
+INT PROC felderzahl (EUDAT CONST) 
+    Liefert Anzahl der benannten Felder. Ist zu Anfang 0. 
+ 
+PROC feldnamen aendern (EUDAT VAR, 
+                        SATZ CONST neue namen) 
+    Setzt die Feldnamen einer Datei. Ist 'felderzahl (neue namen)'
+    größer als die Felderzahl der Datei, so wird die Felderzahl der
+    Datei entsprechend heraufgesetzt. 
+ 
+PROC feldnamen lesen (EUDAT CONST, SATZ VAR namen) 
+    Liefert alle Feldnamen in einer SATZ-Variablen. 
+ 
+Eine EUDAS-Datei enthält drei zusätzliche Notiztexte. Zwei davon
+sind bereits reserviert, und zwar: 
+#free (0.2)# 
+  1: Prüfbedingungen 
+  2: Datum der letzten Änderung 
+ 
+Der dritte kann für freie Notizen verwendet werden. 
+ 
+PROC notizen lesen (EUDAT CONST, INT CONST notiz nr, 
+                    TEXT VAR notizen) 
+    Schreibt die Notizen der EUDAS-Datei in 'notizen' ('notiz nr' =
+   1,2,3). 
+ 
+PROC notizen aendern (EUDAT VAR, INT CONST notiz nr, 
+                      TEXT CONST notizen) 
+    Ändert die Notizen. Alte Notizen werden dabei überschrieben
+    ('notiz nr' = 1,2,3). 
+ 
+ 
+6.3 Satzposition 
+ 
+Eine EUDAS-Datei läßt sich sequentiell vorwärts und rückwärts
+bearbeiten. Dazu gibt es eine aktuelle Satzposition. Ein bestimmter
+Satz kann auch direkt angesprungen werden. Die Prozeduren, die
+nach dem Inhalt des ersten Feldes suchen, arbeiten besonders
+schnell, da die entsprechenden Sätze über eine Hashmethode gefun­
+den werden. 
+ 
+INT PROC satznr (EUDAT CONST) 
+    Liefert aktuelle Satzposition. 
+ 
+INT PROC saetze (EUDAT CONST) 
+    Liefert Anzahl der Sätze. 
+ 
+BOOL PROC dateiende (EUDAT CONST) 
+    Liefert TRUE, wenn 'satznr' groesser als 'saetze' ist. Die letzte
+    erreichbare Satzposition liegt um eins hinter dem letzten Satz
+    (um auch am Ende anfügen zu können). 
+ 
+PROC auf satz (EUDAT VAR, INT CONST satznr) 
+    Positioniert auf den gewünschten Satz. Bei nicht existierenden
+    Sätzen wird auf den ersten bzw. hinter den letzten Satz ge­
+    sprungen. 
+ 
+PROC weiter (EUDAT VAR) 
+    Geht einen Satz weiter, jedoch nicht über das Dateiende hinaus. 
+ 
+PROC zurueck (EUDAT VAR) 
+    Geht einen Satz zurück, falls der erste Satz noch nicht erreicht
+    ist. 
+ 
+PROC auf satz (EUDAT VAR, TEXT CONST muster) 
+    Positioniert auf den ersten Satz, der als erstes Feld 'muster'
+    enthält, anderenfalls hinter den letzten Satz. 
+ 
+PROC weiter (EUDAT VAR, TEXT CONST muster) 
+    Geht weiter, bis das erste Feld 'muster' enthält, bzw. bis hinter
+    den letzten Satz. 
+ 
+PROC zurueck (EUDAT VAR, TEXT CONST muster) 
+    Geht zurück, bis das erste Feld 'muster' enthält, bzw. auf den
+    ersten Satz der EUDAS-Datei. 
+ 
+ 
+6.4 Satzzugriffe 
+ 
+Der aktuelle Satz ist ein SATZ-Objekt. Auf die Felder des aktuellen
+Satzes kann direkt zugegriffen werden. 
+ 
+PROC feld lesen (EUDAT CONST, INT CONST feldnr, 
+                 TEXT VAR inhalt) 
+    Wirkt wie 'feld lesen' auf den aktuellen Satz. 
+ 
+PROC feld aendern (EUDAT VAR, INT CONST feldnr, 
+                   TEXT CONST inhalt) 
+    Wirkt wie 'feld aendern' auf den aktuellen Satz. 
+ 
+PROC feld bearbeiten (EUDAT CONST, INT CONST feldnr, 
+     PROC (TEXT CONST, INT CONST, INT CONST) bearbeite) 
+     Wirkt wie 'feld bearbeiten' auf den aktuellen Satz. 
+ 
+Der aktuelle Satz kann auch als Ganzes bearbeitet werden. 
+ 
+PROC satz lesen (EUDAT CONST, SATZ VAR satz) 
+    Liefert den aktuellen Satz. 
+ 
+PROC satz aendern (EUDAT VAR, SATZ CONST satz) 
+    Ersetzt den aktuellen Satz durch 'satz'. 
+ 
+PROC satz einfuegen (EUDAT VAR, SATZ CONST satz) 
+    Fügt 'satz' vor dem aktuellen Satz ein. 
+ 
+    FEHLER: 
+ 
+    #on("i")#EUDAS-Datei voll#off("i")# 
+    Eine EUDAS-Datei faßt mindestens 5000 Sätze. 
+ 
+PROC satz loeschen (EUDAT VAR) 
+    Löscht den aktuellen Satz. 
+ 
+ 
+6.5 Sortieren und Reorganisieren 
+ 
+Zum Sortieren können für die einzelnen Felder Typen angegeben
+werden, damit auch Zahlen und Daten richtig sortiert werden kön­
+nen. Außerdem kann die Feldreihenfolge angegeben werden, nach
+der sortiert werden soll. 
+ 
+PROC feldinfo (EUDAT VAR, INT CONST feldnr, info) 
+    Setzt den Feldtyp des Feldes 'feldnr'. Es bedeuten 
+      -1 : normaler Text (Standard) 
+       0 : Text nach DIN. Ziffern und Sonderzeichen werden igno­
+           riert. Groß-und Kleinbuchstaben gelten gleich. Umlaute
+           werden beachtet. 
+       1 : Zahl (beim Vergleich werden alle Zeichen außer Zif­
+           fern ignoriert). 
+       2 : Datum. Es werden Daten der Form "tt.mm.jj" vergli­
+           chen. 
+ 
+INT PROC feldinfo (EUDAT CONST, INT CONST feldnr) 
+    Der Feldtyp des angegebenen Feldes wird geliefert. Zu Anfang
+    ist -1 voreingestellt. 
+ 
+INT PROC unsortierte saetze (EUDAT CONST) 
+    Liefert die Anzahl von Sätzen, die seit dem letzten Sortiervor­
+    gang geändert wurden. Bei einer neuen Datei, die noch nie
+    sortiert wurde, wird immer 0 geliefert. 
+ 
+PROC dezimalkomma (TEXT CONST komma) 
+    Stellt das Dezimalkomma ein, das beim Vergleich von Zahlen
+    gelten soll. 
+ 
+    FEHLER: 
+ 
+    #on("i")#Nicht erlaubtes Dezimalkomma#off("i")# 
+    Nur Texte der Länge 1 sind zugelassen. 
+ 
+TEXT PROC dezimalkomma 
+    Liefert das eingestellte Dezimalkomma ("," ist voreingestellt). 
+ 
+PROC sortiere (EUDAT VAR, TEXT CONST reihenfolge) 
+    Sortiert die Datei in der von 'reihenfolge' angegebenen Reihen­
+    folge. Dabei enthält 'reihenfolge' an der Stelle 2*i+1 den Code
+    der Feldnummer, die als i-te in der Sortierung berücksichtigt
+    werden soll. Das Zeichen an der Stelle 2*i gibt an, ob das Feld
+    mit der davorstehenden Feldnummer aufsteigend ('+') oder
+    absteigend ('-') sortiert werden soll. 
+ 
+PROC sortiere (EUDAT VAR) 
+    Sortiert die Datei in der zuletzt eingestellten Reihenfolge.
+    Wurde noch keine Reihenfolge angegeben, wird die Datei in der
+    Feldreihenfolge sortiert. 
+ 
+TEXT PROC sortierreihenfolge (EUDAT CONST) 
+    Liefert die zuletzt eingestellte Reihenfolge. Wurde noch nicht
+    sortiert, so wird "" geliefert. 
+ 
+Nach umfangreichen Änderungen an einer EUDAS-Datei ist eine
+Reorganisation sinnvoll, um "Textleichen" zu beseitigen. 
+ 
+PROC reorganisiere (TEXT CONST dateiname) 
+    Die EUDAS-Datei mit dem Namen 'dateiname' wird reorgani­
+    siert. 
+ 
+ 
+6.6 EUDAS-Dateien als Assoziativspeicher 
+ 
+In diesem Abschnitt soll ein Beispiel erläutert werden, in dem
+EUDAS-Dateien unabhängig von EUDAS für einen ganz anderen
+Zweck benutzt werden. Das folgende kurze Paket soll ein Abkür­
+zungsverzeichnis realisieren, das auf einer EUDAS-Datei basiert. 
+ 
+ 
+    PACKET abkuerzungsverzeichnis 
+      DEFINES 
+      verzeichnis laden, 
+      abkuerzung einfuegen, 
+      abkuerzung aendern, 
+      abkuerzung loeschen, 
+      langform : 
+ 
+    EUDAT VAR verz; 
+    SATZ VAR satz; 
+    TEXT VAR inhalt; 
+ 
+    PROC verzeichnis laden (TEXT CONST dateiname) : 
+ 
+      oeffne (verz, dateiname) 
+ 
+    END PROC verzeichnis laden; 
+ 
+    PROC abkuerzung einfuegen (TEXT CONST abk, lang) : 
+ 
+      auf satz (verz, abk); 
+      IF NOT dateiende (verz) THEN 
+        errorstop ("Abkürzung existiert bereits") 
+      ELSE 
+        satz initialisieren (satz); 
+        feld aendern (satz, 1, abk); 
+        feld aendern (satz, 2, lang); 
+        satz einfuegen (satz) 
+      END IF 
+ 
+    END PROC abkuerzung einfuegen; 
+ 
+    PROC abkuerzung aendern (TEXT CONST abk, lang) : 
+ 
+      auf satz (verz, abk); 
+      IF dateiende (verz) THEN 
+        errorstop ("Abkürzung existiert nicht") 
+      ELSE 
+        feld aendern (verz, 2, lang) 
+      END IF 
+ 
+    END PROC abkuerzung aendern; 
+ 
+    PROC abkuerzung loeschen (TEXT CONST abk) : 
+ 
+      auf satz (verz, abk); 
+      IF NOT dateiende (verz) THEN 
+        satz loeschen (verz) 
+      END IF 
+ 
+    END PROC abkuerzung loeschen; 
+ 
+    TEXT PROC langform (TEXT CONST abk) : 
+ 
+      auf satz (verz, abk); 
+      IF dateiende (verz) THEN 
+        inhalt := ""; 
+        errorstop ("Abkürzung nicht vorhanden") 
+      ELSE 
+        feld lesen (verz, 2, inhalt) 
+      END IF; 
+      inhalt
+ 
+    END PROC langform; 
+ 
+    END PACKET abkuerzungsverzeichnis; 
+ 
+ 
+Die Prozedur 'verzeichnis laden' koppelt die interne EUDAT-Vari­
+able 'verz' an eine benannte EUDAS-Datei, die eventuell vorher mit
+EUDAS erstellt wurde. In diesem Beispiel sind die Feldnamen egal;
+falls die übergebene EUDAS-Datei noch nicht existiert, wird sie mit
+0 Feldern eingerichtet, was aber nur für eine spätere Anzeige mit
+EUDAS störend wäre. 
+    Grundlage für das Aufsuchen einer bestimmten Abkürzung bil­
+det immer die Prozedur 'auf satz', die nach dem Inhalt des ersten
+Feldes optimiert sucht. Falls die Abkürzung nicht gefunden wurde,
+wird auf das Dateiende positioniert, daher wird jeweils 'dateiende'
+abgefragt. 
+    Beim Einfügen eines neuen Satzes muß eine komplette Satz­
+variable angegeben werden, die bereits mit den Inhalten gefüllt ist.
+Beim späteren Ändern kann jedoch direkt auf ein Feld zugegriffen
+werden, ohne die Satzvariable explizit rauszuholen. 
+    Die Abfrage einer bestimmten Abkürzung bereitet dann keine
+Schwierigkeiten mehr. 
+    Für die Verwendung von EUDAS-Dateien in diesem Beispiel
+spricht zum einen die einfache Programmierung, zum anderen aber
+auch die Möglichkeit, das erstellte Verzeichnis mit den Hilfsmitteln
+
diff --git a/doc/eudas/eudas.ref.7 b/doc/eudas/eudas.ref.7
new file mode 100644
index 0000000..31b3031
--- /dev/null
+++ b/doc/eudas/eudas.ref.7
@@ -0,0 +1,447 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (71)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+7 Verwaltung der offenen Dateien 
+ 
+ 
+Die in diesem Kapitel beschriebene Schnittstelle verbindet mehrere
+EUDAS-Dateien zu einem großen Dateimodell. Diese virtuelle Datei
+dient als Grundlage für die meisten EUDAS-Funktionen. Zuerst muß
+eine Datei als Bestandteil der virtuellen Datei geöffnet werden, ehe
+sie bearbeitet werden kann. Es ist so bei den Funktionen keine
+Angabe mehr nötig, welche Datei gemeint ist. 
+    Diese Schnittstelle ist in vielen Teilen für die interne
+EUDAS-Anwendung ausgelegt. Bei einigen Prozeduren werden aus
+Effizienzgründen keinerlei Überprüfungen auf illegale Aufrufe oder
+Parameter durchgeführt. Wollen Sie eine solche Prozedur dennoch
+verwenden, sollten Sie die Einhaltung der angegebenen Bedingungen
+sorgfältig überprüfen. 
+ 
+ 
+7.1 Dateiverwaltung 
+ 
+Mit 'oeffne' wird eine Datei zum Bearbeiten geöffnet. Mit 'kette' und
+'kopple' können weitere Dateien dazugekettet bzw. dazugekoppelt
+werden. Durch 'sichere' können veränderte Kopien zurückgeschrie­
+ben werden. Durch 'dateien loeschen' werden die internen Kopien
+gelöscht. 
+    Mit 'anzahl dateien' kann die Anzahl der vorhandenen Dateien
+erfragt werden. 'anzahl koppeldateien' gibt Auskunft darüber, wie­
+viel Dateien davon gekoppelt sind. 'aendern erlaubt' gibt den Status
+wieder, der beim Öffnen der ersten Datei angegeben wurde. 'inhalt
+veraendert' gibt an, ob die angegebene Datei verändert wurde. Mit
+'eudas dateiname' können die Namen der geöffneten Dateien erfragt
+werden. Bei jedem 'oeffne' wird 'dateiversion' um 1 erhöht. Dies
+dient dazu, ein erfolgtes neues Öffnen von anderen Stellen aus zu
+entdecken. 
+    Mit 'auf koppeldatei' kann die virtuelle Datei auf eine Koppel­
+datei umgeschaltet werden, so daß der Eindruck entsteht, nur diese
+Datei wäre geöffnet worden. 
+ 
+PROC oeffne (TEXT CONST dateiname, 
+             BOOL CONST aendern erlaubt) 
+    Falls Ändern erlaubt sein soll, wird eine Kopie der angegebenen
+    Datei zur Bearbeitung für EUDAS angelegt. Vorher geöffnete
+    Dateien werden gelöscht. Die Änderungserlaubnis wird entspre­
+    chend gesetzt. Es wird die Satzposition der EUDAS-Datei ange­
+    nommen (Ausnahme: steht die EUDAS-Datei hinter dem letzten
+    Satz, wird auf Satz 1 positioniert). 'dateiversion' sowie 'anzahl
+    dateien' werden um 1 erhöht. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#Datei nicht gesichert#off("i")# 
+    Eine vorher geöffnete Datei war verändert, aber nicht gesi­
+    chert. 
+#f1# 
+    #on("i")#Datei existiert nicht#off("i")# 
+    Die angegebene Datei ist nicht vorhanden. 
+#f1# 
+    #on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+    Die angegebene Datei hat nicht den für EUDAS-Dateien festge­
+    legten Typ. 
+ 
+PROC kopple (TEXT CONST dateiname) 
+    Die angegebene Datei wird zu den bereits geöffneten Dateien
+    dazugekoppelt. Falls Ändern erlaubt ist, wird eine Kopie dieser
+    Datei verwendet. Dabei werden die ersten Felder der Datei, die
+    bereits in der Hauptdatei vorhanden sind, als Koppelfelder
+    festgelegt. Alle weiteren Felder werden zusätzlich zu den bis­
+    herigen angelegt. 'dateiversion', 'anzahl dateien' und 'anzahl 
+    koppeldateien' werden um 1 erhöht. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#keine Datei geoeffnet#off("i")# 
+    Es muß vorher eine Datei geöffnet werden. 
+#f1# 
+    #on("i")#Zuviel Dateien geoeffnet#off("i")# 
+    Die Anzahl der gleichzeitig geöffneten Dateien ist begrenzt. 
+#f1# 
+    #on("i")#Datei existiert nicht#off("i")# 
+    Die angegebene Datei ist nicht vorhanden. 
+#f1# 
+    #on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+    Die angegebene Datei hat nicht den für EUDAS-Dateien festge­
+    legten Typ. 
+#f1# 
+    #on("i")#Zu viele Felder#off("i")# 
+    Die Anzahl der Felder insgesamt ist begrenzt. 
+#f1# 
+    #on("i")#Zu viele Koppelfelder#off("i")# 
+    Die Anzahl der Koppelfelder ist begrenzt. 
+#f1# 
+    #on("i")#keine Koppelfelder vorhanden#off("i")# 
+    Das erste Feld der zu koppelnden Datei ist in der Hauptdatei
+    nicht vorhanden (unterschiedliche Feldnamen). 
+ 
+PROC kette (TEXT CONST dateiname) 
+    Die angegebene Datei wird an die Hauptdatei angekettet, d.h.
+    die Sätze der neuen Datei werden am bisherigen Dateiende
+    angefügt. Falls Ändern erlaubt ist, wird eine Kopie dieser Datei
+    verwendet. Die zu kettende Datei muß in der Feldstruktur nicht
+    mit der Hauptdatei übereinstimmen. Die aktuelle Satzposition
+    wird beibehalten. 'dateiversion' und 'anzahl dateien' werden um
+    1 erhöht. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#keine Datei geoeffnet#off("i")# 
+    Es muß vorher eine Datei geöffnet werden. 
+#f1# 
+    #on("i")#Zuviel Dateien geoeffnet#off("i")# 
+    Die Anzahl der gleichzeitig geöffneten Dateien ist begrenzt. 
+#f1# 
+    #on("i")#Datei existiert nicht#off("i")# 
+    Die angegebene Datei ist nicht vorhanden. 
+#f1# 
+    #on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+    Die angegebene Datei hat nicht den für EUDAS-Dateien festge­
+    legten Typ. 
+ 
+PROC sichere (INT CONST dateinr, TEXT CONST dateiname) 
+    Die geöffneten Dateien werden in der Reihenfolge ihres Öffnens
+    durchnumeriert (von 1 an). Die Arbeitskopie mit der angegebe­
+    nen Nummer wird unter dem angegebenen Namen gesichert, aber
+    selbst nicht verändert. Die vorher unter diesem Namen vorhan­
+    dene Datei wird gelöscht. War die zu sichernde Arbeitskopie
+    verändert worden, so wird sie anschließend als nicht verändert
+    angesehen. 
+    Bedingungen: 
+      1 <= dateinr <= anzahl dateien 
+ 
+PROC dateien loeschen (BOOL CONST auch geaenderte) 
+    Es werden alle geöffneten Arbeitskopien gelöscht. EUDAS wird
+    wieder in den Anfangszustand versetzt. Wird 'auch geaenderte'
+    angegeben, wird bei geänderten, aber nicht gesicherten Dateien
+    die Fehlermeldung unterdrückt. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#Datei nicht gesichert#off("i")# 
+    Eine vorher geöffnete Datei war verändert, aber nicht gesi­
+    chert. 
+ 
+BOOL PROC auf koppeldatei 
+    Liefert TRUE, wenn auf eine Koppeldatei umgeschaltet wurde. 
+ 
+PROC auf koppeldatei (INT CONST nr) 
+    Umschalten auf Koppeldatei 'nr'. Ist bereits umgeschaltet, wird
+    wieder zurückgeschaltet. In diesem Fall werden bei 'nr' = 1 die
+    Koppelfelder übernommen, anderenfalls nicht. Beim Umschalten
+    bleiben Satzposition, Markierungen und Suchmuster gespeichert.
+    In der Koppeldatei wird die beim letzten Umschalten eingestell­
+    te Position wieder eingenommen. 'dateiversion' wird um 1 er­
+    höht. 
+ 
+INT PROC anzahl dateien 
+    Gibt die Anzahl der insgesamt geöffneten Dateien an. 
+ 
+INT PROC anzahl koppeldateien 
+    Gibt die Anzahl der gekoppelten Dateien an. 
+ 
+BOOL PROC aendern erlaubt 
+    Reflektiert den Status, der bei 'oeffne' gesetzt wurde. 
+ 
+BOOL PROC inhalt veraendert (INT CONST dateinr) 
+    Gibt an, ob die geöffnete Datei mit der angegebenen Nummer
+    verändert wurde. Wird ggf. von 'sichere' zurückgesetzt. 
+    Bedingung: 
+      1 <= dateinr <= anzahl dateien 
+ 
+TEXT PROC eudas dateiname (INT CONST dateinr) 
+    Liefert den Namen, unter dem die entsprechende Datei geöffnet
+    wurde. 
+    Bedingung: 
+      1 <= dateinr <= anzahl dateien 
+ 
+INT PROC dateiversion 
+    Wird bei jedem 'oeffne', 'kette' und 'kopple' zyklisch erhöht. 
+ 
+INT PROC folgedatei (INT CONST dateinr) 
+    Eine geöffnete EUDAS-Datei wird in eine von zwei Listen auf­
+    genommen, die der geketteten Dateien und die der gekoppelten.
+    Diese Prozedur liefert jeweils die Nummer der nächsten Datei in
+    der Liste, am Ende aber 0. Die Liste der geketteten Dateien
+    beginnt immer mit 1, mit 'folgedatei (0)' erhält man die erste
+    gekoppelte Datei. 
+    Bedingung: 
+      0 <= dateinr <= anzahl dateien 
+ 
+ 
+7.2 Feldstruktur 
+ 
+Die einzelnen Sätze der kombinierten EUDAS-Datei sind in Felder
+unterteilt. Diese setzen sich zusammen aus den Feldern der Haupt­
+datei und der einzelnen Koppeldateien, wobei die Koppelfelder je­
+weils nur einmal auftauchen. 
+    'anzahl felder' liefert die Anzahl der vorhanden Felder. Mit
+'feldnamen lesen' und 'feldnamen bearbeiten' können die Feldnamen
+abgefragt werden. 'feldnummer' liefert einen Index für einen vor­
+gegebenen Feldnamen, da die Felder immer über Nummern angespro­
+chen werden. 
+    Die Prozeduren 'feld lesen' und 'feld bearbeiten' ermöglichen
+den Zugriff auf den Feldinhalt des aktuellen Satzes; durch 'feld
+aendern' kann dieser Inhalt abgeändert werden. 
+ 
+INT PROC anzahl felder 
+    Liefert die Anzahl der vorhanden Felder. 
+ 
+PROC feldnamen lesen (INT CONST feldnr, 
+                      TEXT VAR feldname) 
+    Liefert in 'feldname' den Namen des Feldes mit der Nummer
+    'feldnr'. 
+    Bedingung: 
+      1 <= feldnr <= anzahl felder 
+ 
+PROC feldnamen bearbeiten (INT CONST feldnr, 
+     PROC (TEXT CONST, INT CONST, INT CONST) bearbeite) 
+    Die Prozedur 'bearbeite' wird aufgerufen. Als Parameter werden
+    ein Text und Anfangs- und Endposition des gewünschten Feld­
+    namens in diesem Text übergeben. Verhindert unnötiges Kopie­
+    ren des Feldnamens in eine TEXT-Variable. Der übergebene
+    Text darf nicht verändert werden! 
+    Bedingung: 
+      1 <= feldnr <= anzahl felder 
+ 
+INT PROC feldnummer (TEXT CONST feldname) 
+    Liefert den index zu dem angegebenen Feldnamen. Falls ein
+    solcher Name nicht existiert, wird 0 geliefert. 
+ 
+PROC feld lesen (INT CONST feldnr, TEXT VAR inhalt) 
+    Liefert den Inhalt des angegebenen Feldes. 
+    Bedingung: 
+      1 <= feldnr <= anzahl felder 
+ 
+PROC feld bearbeiten (INT CONST feldnr, 
+     PROC (TEXT CONST, INT CONST, INT CONST) bearbeite) 
+    Die Prozedur 'bearbeite' wird aufgerufen. Der Feldinhalt des
+    angegebenen Feldes steht im übergebenen Text innerhalb der
+    Grenzen. Ist die Obergrenze kleiner als die Untergrenze, so ist
+    das Feld leer. 
+    Bedingung: 
+      1 <= feldnr <= anzahl felder 
+ 
+PROC feld aendern (INT CONST feldnr, TEXT CONST inhalt) 
+    Ändert den Inhalt des angegebenen Feldes. 
+    Bedingung: 
+      NOT ende der datei 
+      1 <= feldnr <= anzahl felder 
+ 
+INT PROC feldinfo (INT CONST feldnummer) 
+    Liefert den Typ des angegebenen Feldes. 
+    Bedingung: 
+      1 <= feldnummer <= anzahl felder 
+ 
+PROC notizen lesen (INT CONST nr, TEXT VAR inhalt) 
+    Liest die angegebenen Notizen ('nr' = 1,2,3) aus der ersten
+    Datei oder der umgeschalteten Koppeldatei. 
+ 
+PROC notizen aendern (INT CONST nr, TEXT CONST inhalt) 
+    Ändert die Notizen ('nr' = 1,2,3) der ersten Datei oder der um­
+    geschalteten Koppeldatei. 
+ 
+ 
+7.3 Positionierung 
+ 
+Das virtuelle Dateimodell von EUDAS verfügt ebenfalls über eine
+Satzposition, die verändert werden kann. 
+    Durch 'satznummer' wird die aktuelle Satznummer geliefert,
+beim Koppeln kann über 'satzkombination' die Reihenfolge der Kop­
+pelkombinationen bestimmt werden. 'dateiende' zeigt an, ob die
+Satzposition hinter dem letzten Satz liegt. Mit 'weiter' und 'zurueck'
+erfolgt die eigentliche Positionierung. Hier kann außer der Positio­
+nierung um Einzelsätze auch die Positionierung auf den nächsten
+ausgewählten oder markierten Satz angefordert werden. Mit 'auf 
+satz' schließlich kann ein bestimmter Satz angesprungen werden. 
+ 
+INT PROC satznummer 
+    Liefert die Nummer des aktuellen Satzes. Die Sätze werden von
+    1 an durchnumeriert, wobei über die geketteten Dateien wei­
+    tergezählt wird. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+INT PROC satzkombination 
+    Liefert die laufende Nummer der Koppelkombination des aktuel­
+    len Satzes. Wird nur durch 'weiter' im Einzelsatzmodus erhöht.
+    Normalerweise 1. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+BOOL PROC dateiende 
+    Gibt an, ob die Satzposition hinter dem letzten Satz liegt. 
+ 
+PROC weiter (INT CONST modus) 
+    Erhöht die aktuelle Satzposition. Für 'modus' gibt es 3 Möglich­
+    keiten: 
+    1: Falls eine weitere Satzkombination besteht, wird diese ein­
+       genommen, sonst zum nächsten Satz. 
+    2: Zum nächsten durch Suchbedingung ausgewählten Satz. Wird
+       optimiert. 
+    3: Zum nächsten markierten Satz. Wird optimiert. 
+    Ist kein Satz mehr vorhanden, wird die Satzposition hinter dem
+    letzten Satz eingenommen. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+PROC zurueck (INT CONST modus) 
+    Geht um einen Satz zurück. Die Modusangabe ist wie bei 'wei­
+    ter', jedoch wird im Modus 1 keine weitere Satzkombination
+    ausprobiert. Die Positionierung endet bei Satz 1. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+PROC auf satz (INT CONST satznr) 
+    Geht auf den angegebenen Satz. Ist 'satznr' < 1, wird auf Satz 1
+    positioniert, ist der angegebene Satz nicht vorhanden, wird
+    hinter den letzten Satz positioniert. Es wird jeweils die erste
+    Satzkombination eingenommen. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+ 
+7.4 Änderungen 
+ 
+Sätze des Dateimodells können eingefügt oder gelöscht werden.
+Durch das Einfügen entsteht ein leerer Satz vor dem aktuellen Satz;
+alle weiteren Sätze rücken eine Stelle weiter. Beim Löschen wird
+dieser Vorgang wieder rückgängig gemacht. 
+    Durch 'satz einfuegen' wird ein Leersatz eingefügt; durch
+'satz loeschen' wird der aktuelle Satz gelöscht. 
+    Sätze in gekoppelten Dateien werden grundsätzlich nicht ge­
+löscht; auch beim Einfügen entsteht nicht automatisch ein Leersatz
+in den gekoppelten Dateien. Änderungen in den Koppeldateien
+(durch 'feld aendern') werden gepuffert. Durch 'aenderungen ein­
+tragen' werden die Änderungen dann in die Koppeldateien eingetra­
+gen. Dabei kann auch ein neuer Satz in die Koppeldatei eingefügt
+werden. Bei Positionierungen wird diese Prozedur automatisch auf­
+gerufen. 
+ 
+PROC satz einfuegen 
+    Fügt vor dem aktuellen Satz einen Leersatz ein. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+PROC satz loeschen 
+    Löscht den aktuellen Satz. Hat hinter dem letzten Satz keine
+    Wirkung. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+PROC aenderungen eintragen 
+    Trägt die gepufferten Änderungen in die Koppeldateien ein.
+    Dabei können die folgenden Fälle auftreten: 
+    1. Der Satz in der Koppeldatei wird geändert. 
+       Dies geschieht dann, wenn vorher ein passender Satz in der
+       Koppeldatei vorhanden war und die Koppelfelder nicht ver­
+       ändert wurden. 
+    2. In der Koppeldatei wird ein neuer Satz eingefügt. 
+       Wenn die Koppelfelder und noch andere Felder einer Datei
+       geändert wurden, wird in dieser Datei ein neuer Satz einge­
+       fügt. 
+    3. Es wird neu gekoppelt. 
+       Wurden nur die Koppelfelder einer Datei geändert, wird ein
+       neuer, zu diesen Feldern passender Satz gesucht. Nach
+       'aenderungen eintragen' erscheinen unter den Feldern der
+       Datei die neuen Inhalte. 
+ 
+ 
+7.5 Suchbedingungen 
+ 
+Über 'suchbedingung' kann eine Suchbedingung eingetragen werden,
+die für jeden Satz geprüft werden soll. Mit 'satz ausgewaehlt' wird
+erfragt, ob der aktuelle Satz die Suchbedingung erfüllt. Die Such­
+bedingung kann mit 'suchbedingung loeschen' wieder ausgeschaltet
+werden. 
+    Einzelne Sätze können auch markiert werden. Nach einem Öff­
+nen ist zunächst kein Satz markiert. Durch 'markierung  aendern'
+kann die Markierung eines Satzes geändert werden. 'satz markiert'
+fragt ab, ob der aktuelle Satz markiert ist. 'markierte saetze' liefert
+die Anzahl der markierten Sätze. Mit 'markierungen loeschen' wer­
+den alle Markierungen entfernt. 
+ 
+PROC suchbedingung (INT CONST feldnr, 
+                    TEXT CONST bedingung) 
+    Stellt für das angegebene Feld die im Text als Muster angege­
+    bene Suchbedingung ein. Weitere Aufrufe verknüpfen die Be­
+    dingungen mit UND (auch wenn das gleiche Feld erneut angege­
+    ben wird). 
+    Bedingung: 
+      anzahl dateien > 0 
+      1 <= feldnr <= anzahl felder 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#Suchmuster zu umfangreich#off("i")# 
+    Es wurden zu viele Vergleiche gefordert. 
+ 
+BOOL PROC satz ausgewaehlt 
+    Gibt an, ob die Suchbedingung auf den aktuellen Satz zutrifft.
+    Hinter dem letzten Satz wird immer FALSE geliefert. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+PROC suchbedingung lesen (INT CONST feldnr, TEXT VAR bedingung) 
+    Liefert die zuletzt für das angegebene Feld eingestellte Bedin­
+    gung, falls die Suchbedingung nicht gelöscht und keine Datei
+    neu geöffnet wurde. 
+    Bedingung: 
+      1 <= feldnr <= anzahl felder 
+ 
+PROC suchbedingung loeschen 
+    Löscht die eingestellte Suchbedingung wieder. Anschließend
+    sind alle Sätze ausgewählt. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+PROC markierung aendern 
+    Ändert die Markierung des aktuellen Satzes ins Gegenteil. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+BOOL PROC satz markiert 
+    Gibt an, ob der aktuelle Satz markiert ist. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+INT PROC markierte saetze 
+    Gibt an, wieviel Sätze insgesamt markiert sind. 
+    Bedingung: 
+      anzahl dateien > 0 
+ 
+PROC markierungen loeschen 
+    Löscht alle Markierungen. 
+    Bedingung: 
+      anzahl dateien > 0 
+
diff --git a/doc/eudas/eudas.ref.8 b/doc/eudas/eudas.ref.8
new file mode 100644
index 0000000..fc2b3bc
--- /dev/null
+++ b/doc/eudas/eudas.ref.8
@@ -0,0 +1,454 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (83)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+8 Funktionen zur Bearbeitung 
+ 
+ 
+ 
+Die Verarbeitungsfunktionen arbeiten jeweils auf der aktuell geöff­
+neten Datei. Falls mindestens ein Satz markiert ist, werden nur
+markierte Sätze bearbeitet, anderenfalls die durch die Suchbedin­
+gung ausgewählten Sätze. 
+ 
+ 
+8.1 Drucken 
+ 
+Zum Drucken wird ein Druckmuster als Textdatei benötigt. Dessen
+Name muß beim Aufruf der Prozedur 'drucke' angegeben werden.
+Werden beim Übersetzen des Druckmusters Fehler entdeckt, so wird
+der Paralleleditor aufgerufen und kein Druckvorgang durchgeführt. 
+    Normalerweise sendet der Druckgenerator die Ausgabe direkt
+zum Drucker. Alternativ kann die Ausgabe auch in eine Datei ge­
+schrieben werden. Dieses Verfahren kann mit 'direkt drucken' umge­
+stellt werden. Der Aufruf 
+ 
+ 
+    direkt drucken (TRUE) 
+ 
+ 
+sendet alle Dateien direkt zum Drucker, mit 
+ 
+ 
+    direkt drucken (FALSE) 
+ 
+ 
+wird die Ausgabe in Dateien abgelegt. Diese Dateien erhalten Namen
+der Form 
+ 
+ 
+    "Druckmustername.a$n" 
+ 
+ 
+wobei 'n' eine laufende Nummer zur Unterscheidung ist. 
+    Soll die Druckausgabe in eine ganz bestimmte Datei geleitet
+werden, so kann vor dem Aufruf von 'drucke' die Prozedur 'druck­
+datei' aufgerufen werden, die als Parameter den Namen der Ausga­
+bedatei erhält. Existiert die Datei noch nicht, wird sie eingerichtet,
+ansonsten wird die Ausgabe am Ende angehängt. 
+    Die Einstellung der Ausgabedatei gilt nur für einen Druckvor­
+gang und überschreibt für diesen Druckvorgang 'direkt drucken'.
+Beim nächsten Druckvorgang wird wieder die durch 'direkt drucken'
+festgelegte Einstellung verwendet. 
+    Wenn beim Drucken ein großes Ausgabevolumen anfällt, kann es
+sinnvoll sein, die Ausgabe in mehrere kleine Dateien aufzuteilen.
+Dies gilt auch, wenn direkt gedruckt werden soll, da auch in diesem
+Fall eine Zwischendatei erzeugt werden muß. Die maximale Anzahl
+von Zeilen pro Datei wird durch 'max druckzeilen' angegeben. 
+    Der dort angegeben Wert gilt nur ungefähr - ein Wechsel der
+Ausgabedatei findet dann statt, wenn die Ausgabedatei nach Bear­
+beitung eines Satzes die Maximalanzahl überschritten hat. In die
+neue Datei wird anschließend zuerst der Initialisierungsteil des
+Druckmusters kopiert, ehe mit der Ausgabe des nächsten Satzes
+fortgefahren wird. 
+ 
+Die Prozeduren im einzelnen: 
+ 
+ 
+PROC drucke (TEXT CONST druckmuster) 
+ 
+    Die aktuell geöffnete Datei wird nach dem angegebenen Druck­
+    muster gedruckt. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#Datei "druckmuster" existiert nicht#off("i")# 
+    Das angegebene Druckmuster ist nicht vorhanden. 
+#f1# 
+    #on("i")#keine Datei geoeffnet#off("i")# 
+    Zum Drucken muß eine Datei geöffnet sein. 
+#f1# 
+    #on("i")#direkt Drucken nicht möglich#off("i")# 
+    Es ist kein Druckprogramm installiert oder der Spooler läßt sich
+    mit 'print' nicht ansprechen. Der Druck wird abgebrochen, die
+    Ausgabedatei ist noch vorhanden. 
+ 
+ 
+PROC direkt drucken (BOOL CONST ja) 
+ 
+    Gibt an, ob die Druckausgaben direkt gedruckt oder in einer
+    Datei gesammelt werden sollen. 
+ 
+ 
+PROC druckdatei (TEXT CONST ausgabedatei) 
+ 
+    Leitet die Druckausgabe des nächsten Druckvorgangs in die
+    Datei 'ausgabedatei'. Die Einstellung von 'direkt drucken' wird
+    für diesen Druckvorgang überschrieben. Die Ausgabe wird am
+    Ende der Datei angehängt, falls nötig, wird die Ausgabedatei
+    vorher eingerichtet. 
+ 
+ 
+PROC maxdruckzeilen (INT CONST zeilen) 
+ 
+    Stellt die maximale Anzahl von Zeilen für die Ausgabedatei ein.
+    Beim Überschreiten dieses Wertes wird eine neue Datei ange­
+    fangen. Standardwert ist 4000. 
+ 
+ 
+TEXT PROC lfd nr 
+ 
+    Liefert während des Druckens die laufende Nummer des gerade
+    gedruckten Satzes als Text. 
+ 
+ 
+BOOL PROC gruppenwechsel (INT CONST gruppennr) 
+ 
+    Kann innerhalb eines Vor- oder Nachspanns beim Drucken ab­
+    gefragt werden, um festzustellen, ob die angegebene Gruppe
+    gewechselt und damit den Vor- bzw. Nachspann mitverursacht
+    hat (es können zu einem Zeitpunkt mehrere Gruppen wechseln).
+    Die Gruppennummer 0 gibt die Standardgruppe an, die nur vor
+    dem ersten und nach dem letzten Satz wechselt. 
+ 
+ 
+8.2 Kopieren 
+ 
+Zum selektiven Kopieren von EUDAS-Dateien wird ein Kopiermuster
+benötigt. Dieses gibt die Zuordnung zwischen Feldern der Ziel- und
+der Quelldatei an. Die Quelldatei ist immer die aktuell geöffnete
+Datei. 
+    Die Kopierfunktion wird durch 'kopiere' aufgerufen. Parameter
+sind der Name der Zieldatei und das Kopiermuster als FILE. Alter­
+nativ kann statt des Kopiermusters eine Prozedur übergeben wer­
+den, die die Kopieranweisungen erhält. 
+    Der eigentliche Kopiervorgang wird durch den Operator 'K'
+bewirkt. Dieser erhält den Zielfeldnamen und einen TEXT-Aus­
+druck als Parameter. Der Wert des TEXT-Ausdrucks wird in das
+jeweilige Feld der Zieldatei geschrieben. 
+    Existiert die Zieldatei noch nicht, so wird sie mit den Feldern
+eingerichtet, die in den einzelnen 'K'-Ausdrücken angegeben sind
+und zwar in der angeführten Reihenfolge. Existiert die Zieldatei, so
+werden gegebenenfalls noch nicht vorhandene Felder am Ende ange­
+fügt. 
+    Die Prozedur 'std kopiermuster' liefert zu einer gegebenen
+Zieldatei ein Standard-Muster, das als Auswahlgrundlage dienen
+kann. Existiert die Zieldatei nicht, werden alle Felder der Quell­
+datei 1 : 1 kopiert, anderenfalls wird zu jedem Feld der Zieldatei
+ein passendes Feld der Quelldatei gesucht - die Feldreihenfolge
+richtet sich in diesem Fall nach der Zieldatei. 
+ 
+ 
+PROC kopiere (TEXT CONST dateiname, 
+              FILE VAR kopiermuster) 
+ 
+    Die aktuell geöffnete Datei wird nach den Angaben in 'kopier­
+    muster' in die Datei 'dateiname' kopiert. Das Kopiermuster wird
+    dem ELAN-Compiler übergeben. Tritt bei der Übersetzung ein
+    Fehler auf, wird der Paralleleditor aufgerufen. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+    Zieldatei existiert, ist aber keine EUDAS-Datei. 
+#f1# 
+    #on("i")#keine Datei geoeffnet#off("i")# 
+    Es muß eine virtuelle Datei vorhanden sein. 
+ 
+ 
+PROC kopiere (TEXT CONST dateiname, PROC kopierfunktion) 
+ 
+    Wie oben, nur ist die Kopierfunktion gleich als Prozedur vor­
+    handen. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+    Zieldatei existiert, ist aber keine EUDAS-Datei. 
+#f1# 
+    #on("i")#keine Datei geoeffnet#off("i")# 
+    Es muß eine virtuelle Datei vorhanden sein. 
+ 
+ 
+OP K (TEXT CONST feldname, ausdruck) 
+ 
+    Kopiert den Ausdruck in das Feld 'feldname' der Zieldatei.
+    Dieses Feld wird eingerichtet, falls es noch nicht existiert.
+    Dieser Operator ist nur während eines Kopiervorganges de­
+    finiert (also in einem Kopiermuster oder einer Kopierfunktion).
+    Er darf nicht in einer IF-Klausel stehen, sondern muß bei
+    jedem Satz mit gleichem Feldnamen an der gleichen Stelle auf­
+    gerufen werden. 
+ 
+ 
+PROC std kopiermuster (TEXT CONST dateiname, 
+                       FILE VAR kopiermuster) 
+ 
+    Liefert ein Standard-Kopiermuster, abhängig von der Zieldatei
+    'dateiname'. Existiert diese nicht, wird die Quelldatei unverän­
+    dert kopiert, ansonsten richtet sich das Kopiermuster nach der
+    Zieldatei. 
+ 
+ 
+8.3 Tragen 
+ 
+Durch Tragen können Sätze komplett in eine Zieldatei transportiert
+werden. In der Quelldatei sind sie anschließend nicht mehr vorhan­
+den. Eine ganze Auswahl von Sätzen kann mit 'trage' transportiert
+werden. 'trage satz' transportiert nur den aktuellen Satz. Mit
+'hole satz' kann der letzte Satz der Zieldatei wieder zurückgeholt
+werden, so daß eine EUDAS-Datei auch als Zwischenspeicher für
+Einzelsätze verwendet werden kann. 
+    Existiert die Zieldatei bereits, muß sie mindestens so viele
+Felder wie die Quelldatei besitzen, damit keine Informationen ver­
+lorengehen können. Die Feldnamen müssen nicht übereinstimmen.
+Existiert die Zieldatei noch nicht, wird sie mit den Feldern der
+Quelldatei eingerichtet. 
+    Die Tragefunktion kann um eine gleichzeitige Prüfung erweitert
+werden. Dabei werden Bedingungen überprüft, die bei der Zieldatei
+gespeichert sind. Sätze, die diese Bedingungen verletzen, werden
+nicht getragen. Eine entsprechende Meldung wird in eine Protokoll­
+datei geschrieben, die als Parameter übergeben werden muß. 
+    Die Prüfbedingungen stehen als ausführbares Programm in den
+Notizen der Zieldatei. Prüfbedingungen können mit mehreren Proze­
+duren formuliert werden. 'pruefe' nimmt eine beliebige Bedingung als
+Parameter und gibt bei Mißerfolg eine Meldung aus. 'wertemenge'
+prüft auf Übereinstimmung mit einem der angegebenen Werte. 'feld­
+maske' legt eine Maske für ein Feld fest, die auf den Inhalt zutref­
+fen muß. 
+    Mit Hilfe der Prozedur 'eindeutige felder' können Satzduplikate
+erkannt werden. Auch diese werden nicht getragen. 
+    Die bei den Prüfbedingungen angegebenen Feldnamen müssen in
+der Quelldatei vorhanden sein. Falls eine Prüfprozedur außerhalb
+von 'trage' aufgerufen wird, führt eine Verletzung der Prüfbedin­
+gung zu einem 'errorstop'. 
+ 
+ 
+PROC trage (TEXT CONST dateiname, 
+            FILE VAR protokoll, BOOL CONST test) 
+ 
+    Alle ausgewählten Sätze werden in die Datei 'dateiname' getra­
+    gen. Diese wird gegebenenfalls eingerichtet. Falls 'test' ange­
+    geben ist, werden die in den Notizen der Zieldatei enthaltenen
+    Bedingungen geprüft. Nur in diesem Fall muß 'protokoll' initial­
+    isiert sein. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#kein Satz zum Tragen vorhanden#off("i")# 
+    Die Quelldatei ist leer oder es ist keine Datei geöffnet. 
+#f1# 
+    #on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+    Zieldatei existiert, ist aber keine EUDAS-Datei. 
+#f1# 
+    #on("i")#Zieldatei hat falsche Felderzahl#off("i")# 
+    Zu wenig Felder in der Zieldatei. 
+ 
+ 
+PROC trage satz (TEXT CONST dateiname) 
+ 
+    Der aktuelle Satz wird in die Datei 'dateiname' getragen. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#kein Satz zum Tragen vorhanden#off("i")# 
+    Keine Datei geöffnet oder Datei ist am Ende. 
+#f1# 
+    #on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+    Zieldatei existiert, ist aber keine EUDAS-Datei. 
+#f1# 
+    #on("i")#Zieldatei hat falsche Felderzahl#off("i")# 
+    Zu wenig Felder in der Zieldatei. 
+ 
+ 
+PROC pruefe (TEXT CONST feldname, BOOL CONST bedingung) 
+ 
+    Wenn die angegebene Bedingung FALSE liefert, wird eine Mel­
+    dung in die Protokolldatei geschrieben und der jeweilige Satz
+    nicht getragen. 
+ 
+ 
+PROC wertemenge (TEXT CONST feldname. menge) 
+ 
+    Es wird geprüft, ob das angegebene Feld in der Wertemenge
+    enthalten ist. Die einzelnen Werte in der Wertemenge werden
+    dabei durch Komma getrennt. Leerzeichen sind signifikant. 
+ 
+ 
+PROC feldmaske (TEXT CONST feldname, maske) 
+ 
+    Es wird geprüft, ob das angegebene Feld zu der Maske paßt. Die
+    Zeichen in der Maske haben dabei folgende Bedeutung: 
+      '9'   trifft auf jede Ziffer zu 
+      'X'   trifft auf jedes Zeichen zu 
+      'A'   trifft auf jeden Großbuchstaben zu (einschließlich
+            Umlaute) 
+      'a'   trifft auf jeden Kleinbuchstaben zu (einschließlich
+            Umlaute und 'ß') 
+      '*'   trifft auf eine Folge beliebiger Zeichen zu (auch die
+            leere Folge). Eine sparsame Verwendung wird empfoh­
+            len, da die Bearbeitung sehr aufwendig ist. 
+    Alle anderen Zeichen treffen nur auf ein gleiches Zeichen zu. 
+ 
+ 
+PROC eindeutige felder (INT CONST anzahl) 
+ 
+    Gibt an, die wieviel ersten Felder einen Satz eindeutig identifi­
+    zieren sollen. Ein Satz, der mit einem Satz der Datei in diesen
+    Feldern übereinstimmt, wird nicht getragen. Ohne diese Angabe
+    wird keine derartige Prüfung vorgenommen. 
+ 
+ 
+PROC hole satz (TEXT CONST dateiname) 
+ 
+    Holt den letzten Satz der angegebenen Datei und fügt ihn vor
+    dem aktuellen Satz ein. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#"dateiname" existiert nicht#off("i")# 
+#f1# 
+    #on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+    Zieldatei existiert, ist aber keine EUDAS-Datei. 
+#f1# 
+    #on("i")#Zieldatei hat falsche Felderzahl#off("i")# 
+    Zu viele Felder in der angegebenen Datei. 
+#f1# 
+    #on("i")#Kein Satz zum Tragen vorhanden#off("i")# 
+    Die angegebene Datei ist leer. 
+#f1# 
+    #on("i")#keine Datei geoeffnet#off("i")# 
+    Es muß eine virtuelle Datei vorhanden sein. 
+ 
+ 
+8.4 Verarbeitung 
+ 
+Die ausgewählten Sätze der aktuellen Datei können nach einer
+Verarbeitungsvorschrift verändert oder geprüft werden. Dies ge­
+schieht durch die Prozedur 'verarbeite'. Als Parameter kann ent­
+weder ein Verarbeitungsmuster als FILE oder die Verarbeitungs­
+funktion direkt als Prozedur übergeben werden. 
+    Die Vorschrift wird durch den Operator 'V' realisiert. 
+ 
+ 
+PROC verarbeite (FILE VAR verarbeitungsmuster) 
+ 
+    Die aktuelle Datei wird nach dem angegebenen Muster bearbei­
+    tet. Enthält die Vorschrift, die dem ELAN-Compiler übergeben
+    wird, einen Fehler, wird der Paralleleditor aufgerufen. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#keine Datei geoeffnet#off("i")# 
+    Es muß eine virtuelle Datei vorhanden sein. 
+ 
+ 
+PROC verarbeite (PROC verarbeitungsfunktion) 
+ 
+    Wie oben, nur wird die Vorschrift direkt als Prozedur überge­
+    ben. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#keine Datei geoeffnet#off("i")# 
+    Es muß eine virtuelle Datei vorhanden sein. 
+ 
+ 
+OP V (TEXT CONST feldname, ausdruck) 
+ 
+    Das angegebene Feld des aktuellen Satzes wird durch den Aus­
+    druck ersetzt. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#Das Feld "feldname" ist nicht definiert.#off("i")# 
+    Das angegebene Feld ist nicht vorhanden. 
+ 
+ 
+8.5 Funktionen in Ausdrücken 
+ 
+Für Ausdrücke bei den in diesem Kapitel beschriebenen Prozeduren
+sind einfache Funktionen zur Abfrage von Feldinhalten vorhanden.
+Mit 'f' kann der Inhalt eines benannten Feldes erfragt werden, bei
+'wert' wird der Inhalt erst in eine REAL-Zahl umgewandelt, wobei
+nichtnumerische Zeichen ignoriert werden. 
+    Die Prozedur 'textdarstellung' kann dazu verwendet werden,
+den Wert einer TEXT-Variablen als TEXT-Denoter in ELAN-Syntax
+darzustellen. 
+    Die Prozedur 'zahltext' kann dazu verwendet werden, aus einer
+REAL-Zahl einen mit der richtigen Zahl von Nachkommastellen ver­
+sehenen, variabel langen Text zu machen. 
+ 
+ 
+TEXT PROC f (TEXT CONST feldname) 
+ 
+    Liefert den Inhalt des angegebenen Feldes. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#Das Feld "feldname" ist nicht definiert.#off("i")# 
+ 
+ 
+REAL PROC wert (TEXT CONST feldname) 
+ 
+    Liefert den Inhalt des angegebenen Feldes als REAL. Dabei
+    werden nichtnumerische Zeichen ignoriert, ausgenommen das
+    Minuszeichen und das eingestellte Dezimalkomma (s. 'dezimal­
+    komma'). Tritt kein numerisches Zeichen auf, wird der Wert 0.0
+    geliefert. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#Das Feld "feldname" ist nicht definiert.#off("i")# 
+ 
+ 
+REAL PROC wert (TEXT CONST feldname, INT CONST kommastellen) 
+ 
+    Wie 'wert' mit einem Parameter, nur daß das Ergebnis auf die
+    angegebene Anzahl von Nachkommastellen gerundet wird. 
+ 
+    FEHLER: 
+#f1# 
+    #on("i")#Das Feld "feldname" ist nicht definiert.#off("i")# 
+ 
+ 
+TEXT PROC textdarstellung (TEXT CONST anzeigetext) 
+ 
+    Liefert 'anzeigetext' als TEXT-Denoter, also in Anführungs­
+    strichen. Anführungsstriche im Text werden dabei verdoppelt.
+    Steuerzeichen von 0 bis 31 werden in lesbare Form gebracht. 
+ 
+ 
+TEXT PROC zahltext (REAL CONST wert, INT CONST kommastellen) 
+ 
+    Liefert den Text des angegebenen Werts mit dem eingestellten
+    Dezimalkomma und mit der angegebenen Zahl von Nachkomma­
+    stellen. Sind die Kommastellen 0, wird auch das Komma unter­
+    drückt. Der Text erhält soviel Stellen, wie zur Darstellung
+    benötigt werden. 
+ 
+ 
+TEXT PROC zahltext (TEXT CONST feldname, 
+                    INT CONST kommastellen) 
+ 
+    Wirkt wie 'zahltext (wert (feldname), kommastellen)'. 
+
diff --git a/doc/eudas/eudas.ref.9 b/doc/eudas/eudas.ref.9
new file mode 100644
index 0000000..dc2dd0d
--- /dev/null
+++ b/doc/eudas/eudas.ref.9
@@ -0,0 +1,194 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (93)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+9 Anzeige 
+ 
+ 
+ 
+9.1 Fensterverwalter 
+ 
+Funktionen, die einen Teil des Bildschirms in einem rechteckigen
+Fenster beschreiben, werden über den Fensterverwalter untereinan­
+der koordiniert. Jede Funktion fordert für ihren Fensterbereich eine
+Variable vom Typ FENSTER an. Vor jedem Bildschirmzugriff kann die
+Funktion erfahren, ob andere Programme den Bildschirm im Fenster­
+bereich überschrieben haben. Gleichzeitig meldet sie damit Verän­
+derungen an anderen Fenstern an, die sich mit dem eigenen über­
+schneiden. 
+ 
+ 
+PROC fenster initialisieren (FENSTER VAR neu) 
+ 
+    Jede Fenstervariable muß vor Benutzung initialisiert werden. 
+ 
+ 
+PROC fenstergroesse setzen (FENSTER VAR fenster, 
+                            INT CONST x anf, y anf, 
+                                      x laenge, y laenge) 
+ 
+    Die Fenstergröße des Fensters wird gesetzt. 'x anf' und 'y anf'
+    werden von 1..n gezählt. Die Größe eines 24x80-Bildschirms
+    entspricht den Angaben (1, 1, 79, 24). Da das letzte Zeichen
+    einer Zeile wegen Rollgefahr nicht benutzt werden kann, werden
+    nur 79 Spalten angegeben. 
+ 
+    FEHLER: 
+ 
+    #on("i")#zu viele Fenster#off("i")# 
+    Es sind nur 16 verschiedene Fenstergrößen möglich. 
+ 
+ 
+PROC fenstergroesse (FENSTER CONST fenster, 
+                     INT VAR x anf, y anf, 
+                             x laenge, y laenge) 
+ 
+    Meldet die eingestellte Größe des Fensters. 
+ 
+ 
+PROC fensterzugriff (FENSTER CONST mein fenster, 
+                     BOOL VAR veraendert) 
+ 
+    Ein Zugriff auf 'mein fenster' wird angemeldet. 'veraendert' gibt
+    an, ob das Fenster seit dem letzten Zugriff durch einen über­
+    schneidenden Zugriff verändert wurde. Beim ersten Zugriff ist
+    'veraendert' immer TRUE. 
+ 
+ 
+PROC fenster veraendert (FENSTER CONST fenster) 
+ 
+    Falls ein Unterprogramm eine FENSTER-Variable des Hauptpro­
+    grammes benutzt, kennzeichnet das Unterprogramm das Fenster
+    mit dieser Prozedur als benutzt, damit das Hauptprogramm das
+    Bild neu ausgibt. 
+ 
+ 
+PROC bildschirm neu 
+ 
+    Gibt an, daß der Bildschirm von einer Funktion benutzt wurde,
+    die ihre Zugriffe nicht über den Fensterverwalter anmeldet.
+    Alle Fenster werden als verändert gekennzeichnet. 
+ 
+ 
+9.2 Anzeigegrundfunktionen 
+ 
+Sämtliche Anzeigefunktionen werden in einem Fenster abgewickelt,
+dessen Größe durch 'anzeigefenster' bestimmt wird. 
+    Die Funktion 'bildausgeben' übernimmt die eigentliche Ausgabe.
+Dabei kann durch Parameter mitgeteilt werden, ob sich an der Datei
+außer der Markierung etwas geändert hat. Hat sich nichts geändert,
+wird zur Optimierung unter Umständen nur die Markierung neu
+ausgegeben. Das Bild wird jedoch auf jeden Fall ganz ausgegeben,
+wenn das Fenster von anderer Seite verändert wurde. Auch das
+Öffnen einer neuen Datei wird automatisch erkannt und richtig
+behandelt. 
+    Welche Felder dargestellt werden sollen, kann durch 'feldaus­
+wahl' angegeben werden. Dabei ist für jeden Anzeigemodus eine
+eigene Feldauswahl möglich. Die Darstellung kann durch 'rollen' in
+vertikaler Richtung verschoben werden. 
+    Mit 'uebersicht' kann die Übersicht ausgegeben werden. Ihre
+Größe wird durch 'uebersichtsfenster' angegeben. 
+ 
+ 
+PROC anzeigefenster (INT CONST x anf, y anf, 
+                               x laenge, y laenge) 
+ 
+    Das Anzeigefenster wird in der entsprechenden Größe reser­
+    viert. 
+ 
+    FEHLER: 
+ 
+    #on("i")#Anzeigefenster zu klein#off("i")# 
+    Das Fenster ist zu schmal (< 40 Zeichen), um eine sinnvolle
+    Anzeige zuzulassen. 
+ 
+ 
+PROC bild ausgeben (BOOL CONST datei veraendert) 
+ 
+    Im Anzeigefenster wird das Bild je nach eingestelltem Modus
+    ausgegeben, wenn das Fenster verändert wurde oder 'satz ver­
+    aendert' TRUE ist. 'satz veraendert' muß immer dann angegeben
+    werden, wenn am Inhalt der virtuellen Datei etwas verändert
+    wurde. 
+ 
+ 
+PROC feldauswahl (TEXT CONST feldcode) 
+ 
+    Die im aktuellen Modus anzuzeigenden Felder und ihre Reihen­
+    folge werden ausgewählt. Dabei enthält 'feldcodes' an der i-ten
+    Stelle den Code der Feldnummer des Feldes, das an i-ter Posi­
+    tion erscheinen soll. 
+ 
+ 
+PROC rollen (INT CONST anzahl) 
+ 
+    Die Darstellung wird um die angegebene Anzahl von Zeilen
+    gerollt. Bei einer positiven Angabe wird zu höheren Feld- bzw.
+    Satznummern gerollt (Bild bewegt sich umgekehrt). Beim ersten
+    bzw. letzten Feld bzw. Satz hört das Rollen automatisch auf. 
+ 
+ 
+PROC uebersichtsfenster (INT CONST x anf, y anf, 
+                                   x laenge, y laenge) 
+ 
+    Legt die Größe des Übersichtsfensters fest. 
+ 
+ 
+PROC uebersicht (TEXT CONST feldauswahl) 
+ 
+    Ruft eine Übersicht der aktuellen Datei auf, in der geblättert
+    und markiert werden kann. In 'feldauswahl' steht an der Stelle
+    i der Code der Feldnummer, die als i-tes in der Aufzählung
+    erscheinen soll. 
+ 
+ 
+9.3 Editorfunktionen 
+ 
+Es stehen drei Funktionen zur Verfügung, die den Editor im Anzei­
+gemodus benutzen. Sie dienen zum Einfügen und Ändern sowie zum
+Eingeben eines Suchmusters. 
+    Der Editor wird durch ESC 'q' verlassen. Weitere ESC-Funk­
+tionen, die zum Verlassen führen sollen, können durch 'exit zeichen'
+angegegeben und nach Funktionsausführung mit 'exit durch' abge­
+fragt werden. 
+ 
+ 
+PROC aendern (PROC hilfe) 
+ 
+    Bietet den aktuellen Satz zum Ändern an. Steht die virtuelle
+    Datei am Ende, wird automatisch 'einfuegen' durchgeführt. Bei
+    ESC '?' wird 'hilfe' aufgerufen. 
+ 
+ 
+PROC einfuegen (PROC hilfe) 
+ 
+    Fügt vor dem aktuellen Satz einen Satz ein, dessen Inhalt im
+    Editor angegeben wird. Bei ESC '?' wird 'hilfe' aufgerufen. 
+ 
+ 
+PROC suchen (PROC hilfe) 
+ 
+    Im Editor wird eine neue Suchbedingung eingegeben. Bei ESC '?'
+    wird 'hilfe' aufgerufen. 
+ 
+ 
+PROC exit durch (TEXT CONST zeichenkette) 
+ 
+    Gibt die Zeichen an, die beim Drücken nach ESC zum Verlassen
+    des Editors führen sollen. Die eingegebenen Daten werden je­
+    doch vorher auf jeden Fall noch verarbeitet. 
+ 
+ 
+TEXT PROC exit durch 
+ 
+    Gibt an, durch welches Zeichen der Editor verlassen wurde. 
+
diff --git a/doc/eudas/eudas.ref.fehler b/doc/eudas/eudas.ref.fehler
new file mode 100644
index 0000000..736d009
--- /dev/null
+++ b/doc/eudas/eudas.ref.fehler
@@ -0,0 +1,139 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (115)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+Fehlermeldungen 
+ 
+ 
+ 
+In diesem Kapitel sind alle Fehlermeldungen aufgeführt, die von
+EUDAS erzeugt werden und zum Abbruch einer Funktion führen
+können. 
+ 
+#on("i")#'n' ist keine Feldnummer#off("i")# 
+  Es wurde eine Nummer als Feldnummer angegeben, die nicht er­
+  laubt ist. 
+ 
+#on("i")#Datei ist keine EUDAS-Datei#off("i")# 
+  Es wurde versucht, eine andere Datei als EUDAS-Datei zu bear­
+  beiten. 
+ 
+#on("i")#inkonsistente EUDAS-Datei#off("i")# 
+  Die interne Struktur der Datei ist zerstört. Kann durch Hardware­
+  probleme (Archiv-Lesefehler) oder EUDAS-interne Fehler ent­
+  standen sein. 
+ 
+#on("i")#EUDAS-Datei voll#off("i")# 
+  Eine EUDAS-Datei kann nur eine bestimmte Anzahl von Sätzen
+  aufnehmen (mindestens 5000). 
+ 
+#on("i")#Nicht erlaubtes Dezimalkomma#off("i")# 
+  Als Dezimalkomma kann nur ein einzelnes Zeichen angegeben
+  werden. 
+ 
+#on("i")#Zuviel Dateien geoeffnet#off("i")# 
+  Es können nicht mehr als 10 Dateien gleichzeitig geöffnet, geket­
+  tet und gekoppelt sein. 
+ 
+#on("i")#Zu viele Felder#off("i")# 
+  Alle geöffneten Dateien zusammen dürfen nicht mehr als 256
+  Felder der virtuellen Datei ergeben. 
+ 
+#on("i")#Zu viele Koppelfelder#off("i")# 
+  Es dürfen insgesamt nicht mehr als 32 Koppelfelder entstehen. 
+ 
+#on("i")#keine Koppelfelder vorhanden#off("i")# 
+  Eine Datei kann nicht gekoppelt werden, wenn Sie kein Koppelfeld
+  besitzt. 
+ 
+#on("i")#keine Datei geoeffnet#off("i")# 
+  Es kann nicht gekettet oder gekoppelt werden, wenn noch keine
+  Datei geöffnet wurde. Ebenfalls sind keine Verarbeitungsproze­
+  duren möglich. 
+ 
+#on("i")#Nicht möglich, wenn auf Koppeldatei geschaltet#off("i")# 
+  Wenn auf eine Koppeldatei umgeschaltet wurde, ist Öffnen, Ketten
+  und Koppeln nicht möglich. 
+ 
+#on("i")#kein direkter Dateizugriff bei geketteten oder gekoppelten Dateien#off("i")# 
+  Wenn Dateien gekettet oder gekoppelt sind, ist Sortieren und
+  Ändern der Feldstruktur nicht möglich. 
+ 
+#on("i")#Datei nicht gesichert#off("i")# 
+  Eine vorher geöffnete Datei ist verändert und nicht gesichert. 
+ 
+#on("i")#Datei wird von anderer Task geändert#off("i")# 
+  Das Öffnen der Datei zum Ändern ist im Moment nicht möglich, da
+  ein anderer Benutzer sie bereits ändert. 
+ 
+#on("i")#Suchmuster zu umfangreich#off("i")# 
+  Ein Suchmuster darf nicht mehr als 100 Vergleiche erfordern. 
+ 
+#on("i")#direkt Drucken nicht moeglich#off("i")# 
+  Entweder ist kein Druckprogramm installiert oder die Spooltask
+  reagiert nicht. 
+ 
+#on("i")#Das Feld "Feldname" ist nicht definiert#off("i")# 
+  Sie haben einen falschen Namen angegeben. 
+ 
+#on("i")#Kein Satz zum Tragen vorhanden#off("i")# 
+  Es wurde versucht, aus einer leeren Datei oder am Dateiende zu
+  tragen. 
+ 
+#on("i")#Zieldatei hat falsche Felderzahl#off("i")# 
+  Eine Zieldatei beim Tragen hat weniger Felder als die aktuelle
+  Datei. Daher würden beim Tragen Informationen verlorengehen. 
+ 
+#on("i")#Zieldatei darf nicht geöffnet sein#off("i")# 
+  Eine geöffnete Datei ist als Zieldatei nicht zulässig. 
+ 
+#on("i")#Das Feld "Feldname" verletzt die Pruefbedingung#off("i")# 
+  Eine Prüfprozedur wurde außerhalb des Tragens aufgerufen und
+  die Bedingung war nicht erfüllt. 
+ 
+#on("i")#Das Feld "Feldname" ist nicht in der Wertemenge#off("i")# 
+  Eine Prüfprozedur wurde außerhalb des Tragens aufgerufen und
+  die Bedingung war nicht erfüllt. 
+ 
+#on("i")#Das Feld "Feldname" stimmt nicht mit der Maske ueberein#off("i")# 
+  Eine Prüfprozedur wurde außerhalb des Tragens aufgerufen und
+  die Bedingung war nicht erfüllt. 
+ 
+#on("i")#Zu viele Fenster#off("i")# 
+  Es sind nicht mehr als 16 verschiedene Größen von Fenstern
+  möglich. 
+ 
+#on("i")#Fenster zu klein#off("i")# 
+  Ein Menü wurde in einem zu kleinen Fenster aufgerufen. 
+ 
+#on("i")#Hilfe existiert nicht#off("i")# 
+  Es wurde versucht, eine nicht vorhandene Hilfestellung aufzu­
+  rufen. 
+ 
+#on("i")#Hilfe ist leer#off("i")# 
+  Die angewählte Hilfestellung enthält keinen Text. 
+ 
+#on("i")#Anzeigefenster zu klein#off("i")# 
+  Das Anzeigefenster muß mindestens 40 Zeichen breit sein. 
+ 
+#on("i")#Ungueltige Satznummer#off("i")# 
+  Der angegebene Text stellt keine Satznummer dar. 
+ 
+#on("i")#kein rekursiver Aufruf#off("i")# 
+  Innerhalb von EUDAS darf 'eudas' nicht erneut aufgerufen wer­
+  den. 
+ 
+#on("i")#Task existiert nicht#off("i")# 
+  Es wurde versucht, eine nicht existente Task als Manager einzu­
+  stellen. 
+ 
+
diff --git a/doc/eudas/eudas.ref.inhalt b/doc/eudas/eudas.ref.inhalt
new file mode 100644
index 0000000..ae997cb
--- /dev/null
+++ b/doc/eudas/eudas.ref.inhalt
@@ -0,0 +1,120 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (3)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+Inhalt 
+ 
+ 
+ 
+      Vorwort  . . . . . . . . . . . . . . . . . . .  i 
+      Inhalt . . . . . . . . . . . . . . . . . . . .  iii 
+ 
+ 
+I. Funktionen zum Nachschlagen 
+ 
+#on("b")#1   Zustände und Bedienung#off("b")# 
+#free (0.2)# 
+1.1   Zustände . . . . . . . . . . . . . . . . . . .  3 
+1.2   Menüs  . . . . . . . . . . . . . . . . . . . .  8 
+1.3   Auswahl  . . . . . . . . . . . . . . . . . . .  8 
+1.4   Hilfe und Dialog . . . . . . . . . . . . . . .  9 
+1.5   Editor . . . . . . . . . . . . . . . . . . . .  9 
+ 
+#on("b")#2   Zusammenstellung der Funktionen#off("b")# 
+#free (0.2)# 
+2.1   Menü 'Öffnen'  . . . . . . . . . . . . . . . .  13 
+2.2   Menü 'Einzelsatz'  . . . . . . . . . . . . . .  17 
+2.3   Menü 'Gesamtdatei' . . . . . . . . . . . . . .  21 
+2.4   Menü 'Drucken' . . . . . . . . . . . . . . . .  23 
+2.5   Menü 'Dateien' . . . . . . . . . . . . . . . .  25 
+2.6   Menü 'Archiv'  . . . . . . . . . . . . . . . .  27 
+2.7   Kurzabfrage  . . . . . . . . . . . . . . . . .  29 
+ 
+#on("b")#3   Das virtuelle Dateimodell#off("b")# 
+#free (0.2)# 
+3.1   Dateistruktur  . . . . . . . . . . . . . . . .  31 
+3.2   Öffnen . . . . . . . . . . . . . . . . . . . .  32 
+3.3   Koppeln  . . . . . . . . . . . . . . . . . . .  33 
+3.4   Änderungen . . . . . . . . . . . . . . . . . .  34 
+3.5   Sichern  . . . . . . . . . . . . . . . . . . .  36 
+3.6   Umschalten auf Koppeldatei . . . . . . . . . .  36 
+3.7   Mehrbenutzerbetrieb  . . . . . . . . . . . . .  37 
+ 
+#on("b")#4   Ansehen und Bearbeiten#off("b")# 
+#free (0.2)# 
+4.1   Anzeige  . . . . . . . . . . . . . . . . . . .  39 
+4.2   Satzauswahl  . . . . . . . . . . . . . . . . .  42 
+4.3   Sortieren und Reorganisieren . . . . . . . . .  44 
+4.4   Bearbeiten . . . . . . . . . . . . . . . . . .  46 
+ 
+#on("b")#5   Drucken und Druckmuster#off("b")# 
+#free (0.2)# 
+5.1   Druckmustersyntax  . . . . . . . . . . . . . .  49 
+5.2   Der Druckvorgang . . . . . . . . . . . . . . .  51 
+5.3   Interpretation von Musterzeilen  . . . . . . .  52 
+5.4   Anschluß zum ELAN-Compiler . . . . . . . . . .  56 
+5.5   Fehlermeldungen  . . . . . . . . . . . . . . .  57 
+ 
+ 
+II. EUDAS für Programmierer 
+ 
+#on("b")#6   Struktur von EUDAS-Dateien#off("b")# 
+#free (0.2)# 
+6.1   Der Datentyp SATZ  . . . . . . . . . . . . . .  61 
+6.2   Der Datentyp EUDAT . . . . . . . . . . . . . .  63 
+6.3   Satzposition . . . . . . . . . . . . . . . . .  64 
+6.4   Satzzugriffe . . . . . . . . . . . . . . . . .  65 
+6.5   Sortieren und Reorganisieren . . . . . . . . .  66 
+6.6   EUDAS-Dateien als Assoziativspeicher . . . . .  68 
+ 
+#on("b")#7   Verwaltung der offenen Dateien#off("b")# 
+#free (0.2)# 
+7.1   Dateiverwaltung  . . . . . . . . . . . . . . .  71 
+7.2   Feldstruktur . . . . . . . . . . . . . . . . .  75 
+7.3   Positionierung . . . . . . . . . . . . . . . .  77 
+7.4   Änderungen . . . . . . . . . . . . . . . . . .  78 
+7.5   Suchbedingungen  . . . . . . . . . . . . . . .  79 
+ 
+#on("b")#8   Funktionen zur Bearbeitung#off("b")# 
+#free (0.2)# 
+8.1   Drucken  . . . . . . . . . . . . . . . . . . .  83 
+8.2   Kopieren . . . . . . . . . . . . . . . . . . .  85 
+8.3   Tragen . . . . . . . . . . . . . . . . . . . .  87 
+8.4   Verarbeitung . . . . . . . . . . . . . . . . .  89 
+8.5   Funktionen in Ausdrücken . . . . . . . . . . .  90 
+ 
+#on("b")#9   Anzeige#off("b")# 
+#free (0.2)# 
+9.1   Fensterverwalter . . . . . . . . . . . . . . .  93 
+9.2   Anzeigegrundfunktionen . . . . . . . . . . . .  94 
+9.3   Editorfunktionen . . . . . . . . . . . . . . .  95 
+ 
+#on("b")#10  Programmierung der Menüs#off("b")# 
+#free (0.2)# 
+10.1  Menüformat . . . . . . . . . . . . . . . . . .  97 
+10.2  Verwaltung der Menüs . . . . . . . . . . . . .  99 
+10.3  Aufruf . . . . . . . . . . . . . . . . . . . .  101 
+10.4  Dialog . . . . . . . . . . . . . . . . . . . .  103 
+ 
+#on("b")#11  Programmierung von Anwendungen#off("b")# 
+#free (0.2)# 
+11.1  Musterprogramme  . . . . . . . . . . . . . . .  105 
+11.2  Dateianwendungen . . . . . . . . . . . . . . .  109 
+11.3  Integrierte Anwendungen  . . . . . . . . . . .  111 
+ 
+ 
+III. Anhang 
+ 
+      Fehlermeldungen  . . . . . . . . . . . . . . .  115 
+      Prozeduren mit Parametern  . . . . . . . . . .  119 
+      Register . . . . . . . . . . . . . . . . . . .  125 
+
diff --git a/doc/eudas/eudas.ref.macros b/doc/eudas/eudas.ref.macros
new file mode 100644
index 0000000..1d24468
--- /dev/null
+++ b/doc/eudas/eudas.ref.macros
@@ -0,0 +1,73 @@
+#*format# 
+#limit (13.5)##start (3.5,2.5)##pagelength (21.0)##block# 
+#:firsthead (false)# 
+#linefeed (1.07)# 
+#*macro end# 
+#*text# 
+#type ("prop10")# 
+#linefeed (1.07)# 
+#*macro end# 
+#*beispiel# 
+#type ("12")# 
+#linefeed (0.97)# 
+#*macro end# 
+#*bildschirm# 
+#type ("15")# 
+#linefeed(0.83)# 
+#*macro end# 
+#*proc# 
+#type ("12")# 
+#*macro end# 
+#*endproc# 
+#free (0.1)# 
+#type ("prop10")# 
+#linefeed (1.07)# 
+#*macro end# 
+#*abschnitt ($1,$2,$3)# 
+#headodd# 
+#on("b")#$1#right#$3    %#off("b")# 
+#free (1.0)# 
+#end# 
+#on("b")##ib(9)#$1#ie(9,"   $3")# $2#off("b")# 
+#*macro end# 
+#*char($1)# 
+$1
+#*macro end# 
+#*kapitel ($1,$2,$3,$4)# 
+#free (1.3)# 
+#"nlq"# 
+#type("roman.24")# 
+#on("b")##center#$1#off("b")# 
+#free (0.2)# 
+#type ("roman.18")# 
+#on("b")##center#$2 #off("b")# 
+#on("b")##center# $3#off("b")# 
+#on("b")##center#$4#off("b")# 
+#type ("prop10")# 
+#free (0.6)# 
+#headeven# 
+#on("b")#%    $2 $3 $4#off("b")# 
+#free (1.0)# 
+#end# 
+#headodd# 
+#right##on("b")#%#off("b")# 
+#free (1.0)# 
+#end# 
+#*macro end# 
+#*f2# 
+#free (0.2)# 
+#*macro end# 
+#*a ($1)# 
+#on("b")#$1.#off("b")# 
+#*macro end# 
+#*bsp ($1)# 
+#type("12")#$1#type("prop")#
+#*macro end# 
+#*f1# 
+#free (0.1)# 
+#*macro end# 
+
+
+
+
+
diff --git a/doc/eudas/eudas.ref.proz b/doc/eudas/eudas.ref.proz
new file mode 100644
index 0000000..2007bc1
--- /dev/null
+++ b/doc/eudas/eudas.ref.proz
@@ -0,0 +1,205 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (119)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+Prozeduren mit Parametern 
+ 
+ 
+ 
+ 
+:= (SATZ VAR, SATZ CONST)                                   6.1 
+ 
+aendern (PROC hilfe)                                        9.3 
+aendern erlaubt : BOOL                                      7.1 
+aenderungen eintragen                                       7.4 
+anzahl dateien : INT                                        7.1 
+anzahl felder : INT                                         7.2 
+anzahl koppeldateien : INT                                  7.1 
+anzeigefenster (INT CONST x anf, y anf, 
+                          x laenge, y laenge)               9.2 
+auf satz (EUDAT VAR, INT CONST satznr)                      6.3 
+auf satz (EUDAT VAR, TEXT CONST muster)                     6.3 
+auf satz (INT CONST satznr)                                 7.3 
+ausfuehrtaste (TEXT CONST taste)                           10.3 
+auswahl anbieten (TEXT CONST name, FENSTER CONST f, 
+                  TEXT CONST hilfe, 
+                  PROC (TEXT VAR, INT CONST) inhalt)       10.3 
+ 
+bild ausgeben (BOOL CONST datei veraendert)                 9.2 
+bildschirm neu                                              9.1 
+ 
+dateiende (EUDAT CONST) : BOOL                              6.3 
+dateiende : BOOL                                            7.3 
+dateien loeschen (BOOL CONST auch geaenderte)               7.1 
+dateiversion : INT                                          7.1 
+dezimalkomma (TEXT CONST komma)                             6.5 
+dezimalkomma : TEXT                                         6.5 
+dialog                                                     10.4 
+dialogfenster (INT CONST x anf, y anf, 
+                         x laenge, y laenge)               10.4 
+direkt drucken (BOOL CONST ja)                              8.1 
+druckdatei (TEXT CONST dateiname)                           8.1 
+drucke (TEXT CONST mustername)                              8.1 
+ 
+editget (TEXT CONST prompt, TEXT VAR eingabe, 
+         TEXT CONST res, hilfe)                            10.4 
+eindeutige felder (INT CONST anzahl)                        8.3 
+einfuegen (PROC hilfe)                                      9.3 
+eudas dateiname (INT CONST dateinr) : TEXT                  7.1 
+EUDAT                                                       6.2 
+exit durch (TEXT CONST exit zeichen)                        9.3 
+exit durch : TEXT                                           9.3 
+ 
+f (TEXT CONST feldname) : TEXT                              8.5 
+fehler ausgeben                                            10.4 
+feld aendern (SATZ VAR, INT CONST feldnr, 
+              TEXT CONST inhalt)                            6.1 
+feld aendern (EUDAT VAR, INT CONST feldnr, 
+              TEXT CONST inhalt)                            6.4 
+feld aendern (INT CONST feldnr, TEXT CONST inhalt)          7.2 
+feldauswahl (TEXT CONST feldcodes)                          9.2 
+feld bearbeiten (SATZ CONST, INT CONST feldnr, 
+  PROC (TEXT CONST, INT CONST, INT CONST) bearbeite)        6.1 
+feld bearbeiten (EUDAT CONST, INT CONST feldnr, 
+  PROC (TEXT CONST, INT CONST, INT CONST) bearbeite)        6.4 
+feld bearbeiten (INT CONST feldnr, 
+  PROC (TEXT CONST, INT CONST, INT CONST) bearbeite)        7.2 
+felderzahl (SATZ CONST) : INT                               6.1 
+felderzahl (EUDAT CONST) : INT                              6.2 
+feldindex (SATZ CONST, TEXT CONST muster) : INT             6.1 
+feldinfo (EUDAT VAR, INT CONST feldnr, info)                6.5 
+feldinfo (EUDAT CONST, INT CONST feldnr) : INT              6.5 
+feld lesen (SATZ CONST, INT CONST feldnr, 
+            TEXT VAR inhalt)                                6.1 
+feld lesen (EUDAT CONST, INT CONST feldnr, 
+            TEXT VAR inhalt)                                6.4 
+feld lesen (INT CONST feldnr, TEXT VAR inhalt)              7.2 
+feldmaske (TEXT CONST feldname, maske)                      8.3 
+feldnamen aendern (EUDAT VAR, SATZ CONST namen)             6.2 
+feldnamen bearbeiten (INT CONST feldnr, 
+  PROC (TEXT CONST, INT CONST, INT CONST) bearbeite)        7.2 
+feldnamen lesen (EUDAT CONST, SATZ VAR namen)               6.2 
+feldnamen lesen (INT CONST feldnr, TEXT VAR name)           7.2 
+feldnummer (TEXT CONST feldname) : INT                      7.2 
+FENSTER                                                     9.1 
+fenstergroesse (FENSTER CONST f, 
+                INT VAR x anf, y anf, 
+                        x laenge, y laenge)                 9.1 
+fenstergroesse setzen (FENSTER VAR fenster, 
+                       INT CONST x anf, y anf, 
+                                 x laenge, y laenge)        9.1 
+fenster initialisieren (FENSTER VAR fenster)                9.1 
+fenster veraendert (FENSTER CONST fenster)                  9.1 
+fensterzugriff (FENSTER CONST fenster, 
+                BOOL VAR veraendert)                        9.1 
+ 
+global manager                                             10.2 
+gruppenwechsel (INT CONST gruppennr) : BOOL                 8.1 
+ 
+hilfe anbieten (TEXT CONST name, FENSTER CONST f)          10.3 
+hole satz (TEXT CONST dateiname)                            8.3 
+ 
+inhalt veraendert (INT CONST dateinr) : BOOL                7.1 
+ja (TEXT CONST frage, hilfe) : BOOL                        10.4 
+ 
+K (TEXT CONST feldname, ausdruck)                           8.2 
+kette (TEXT CONST dateiname)                                7.1 
+kopiere (TEXT CONST dateiname, FILE VAR muster)             8.2 
+kopiere (TEXT CONST dateiname, PROC kopierfunktion)         8.2 
+kopple (TEXT CONST dateiname)                               7.1 
+ 
+lfd nr : TEXT                                               8.1 
+ 
+markierte saetze : INT                                      7.5 
+markierung aendern                                          7.5 
+markierungen loeschen                                       7.5 
+maxdruckzeilen (INT CONST anzahl zeilen)                    8.1 
+menue anbieten (ROW 6 TEXT CONST menuenamen, 
+                FENSTER VAR f, 
+                BOOL CONST esc erlaubt, 
+                PROC (INT CONST, INT CONST) interpreter)   10.3 
+menuedaten einlesen (TEXT CONST dateiname)                 10.2 
+menue loeschen (TEXT CONST name, INT CONST index)          10.2 
+menue loeschen (BOOL CONST hilfen reduzieren)              10.2 
+menue manager (DATASPACE VAR ds, 
+               INT CONST order, phase, 
+               TASK CONST order task)                      10.2 
+menuenamen (INT CONST index) : THESAURUS                   10.2 
+ 
+neuer dialog                                               10.4 
+notizen aendern (EUDAT VAR, INT CONST notiz nr, 
+                 TEXT CONST notizen)                        6.2 
+notizen lesen (EUDAT CONST, INT CONST notiz nr, 
+               TEXT VAR notizen)                            6.2 
+ 
+oeffne (EUDAT VAR, TEXT CONST dateiname)                    6.2 
+oeffne (TEXT CONST dateiname, 
+        BOOL CONST aendern erlaubt)                         7.1 
+ 
+pruefe (TEXT CONST feldname, BOOL CONST bedingung)          8.3 
+ 
+reorganisiere (TEXT CONST dateiname)                        6.5 
+rollen (INT CONST anzahl)                                   9.2 
+ 
+saetze (EUDAT CONST) : INT                                  6.3 
+SATZ                                                        6.1 
+satz aendern (EUDAT VAR, SATZ CONST neuer satz)             6.4 
+satz ausgewaehlt : BOOL                                     7.5 
+satz einfuegen (EUDAT VAR, SATZ CONST satz)                 6.4 
+satz einfuegen                                              7.4 
+satz initialisieren (SATZ VAR satz)                         6.1 
+satzkombination : INT                                       7.3 
+satz lesen (EUDAT CONST, SATZ VAR satz)                     6.4 
+satz loeschen (EUDAT VAR)                                   6.4 
+satz loeschen                                               7.4 
+satz markiert : BOOL                                        7.5 
+satznr (EUDAT CONST) : INT                                  6.3 
+satznummer : INT                                            7.3 
+sichere (INT CONST dateinr, TEXT CONST dateiname)           7.1 
+sortiere (EUDAT VAR, TEXT CONST reihenfolge)                6.5 
+sortiere (EUDAT VAR)                                        6.5 
+sortierreihenfolge (EUDAT CONST) : TEXT                     6.5 
+status anzeigen (TEXT CONST zeile)                         10.3 
+std kopiermuster (TEXT CONST dateiname, FILE VAR f)         8.2 
+suchbedingung (INT CONST feldnr, 
+               TEXT CONST bedingung)                        7.5 
+suchbedingung loeschen                                      7.5 
+suchen (PROC hilfe)                                         9.3 
+ 
+textdarstellung (TEXT CONST text) : TEXT                    8.5 
+trage (TEXT CONST dateiname, FILE VAR protokoll, 
+       BOOL CONST test)                                     8.3 
+trage satz (TEXT CONST dateiname)                           8.3 
+ 
+unsortierte saetze (EUDAT CONST) : INT                      6.5 
+ 
+V (TEXT CONST feldname, ausdruck)                           8.4 
+verarbeite (FILE VAR verarbeitungsmuster)                   8.4 
+verarbeite (PROC verarbeitungsfunktion)                     8.4 
+ 
+waehlbar (INT CONST menuenr, funktionsnr, 
+          BOOL CONST moeglich)                             10.3 
+wahl (INT CONST stelle) : INT                              10.3 
+weiter (EUDAT VAR)                                          6.3 
+weiter (EUDAT VAR, TEXT CONST muster)                       6.3 
+weiter (INT CONST modus)                                    7.3 
+wert (TEXT CONST feldname) : REAL                           8.5 
+wert (TEXT CONST feldname, INT CONST kommastellen) : REAL   8.5 
+wertemenge (TEXT CONST feldname, menge)                     8.3 
+ 
+zahltext (REAL CONST wert, INT CONST kommastellen) : TEXT   8.5 
+zahltext (TEXT CONST feldname, 
+          INT CONST kommastellen) : TEXT                    8.5 
+zurueck (EUDAT VAR)                                         6.3 
+zurueck (EUDAT VAR, TEXT CONST muster)                      6.3 
+zurueck (INT CONST modus)                                   7.3 
+
diff --git a/doc/eudas/eudas.ref.reg b/doc/eudas/eudas.ref.reg
new file mode 100644
index 0000000..a34307a
--- /dev/null
+++ b/doc/eudas/eudas.ref.reg
@@ -0,0 +1,436 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (125)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+Register 
+ 
+ 
+ 
+#columns (2, 0.5)# 
+#limit (6.5)# 
+ABKUERZUNGEN-Anweisung 49 
+Abkürzungsteil 49 
+Abkürzungsverzeichnis 68 
+Abkürzungszeile 50 
+Abschlußzeile 39 
+aendern 96 
+Ändern 10, 19 
+  -, nach Vorschrift 48 
+aendern erlaubt 74 
+Änderungen 34 
+aenderungen eintragen 79 
+Änderungsmuster 21 
+Alternative 43 
+Ankreuzen 8 
+anzahl dateien 74 
+anzahl felder 75 
+anzahl koppeldateien 74 
+Anzeige 39, 93 
+anzeigefenster 95 
+Arbeitskopie 13, 32 
+  -, löschen 15, 36 
+  -, sichern 15, 36 
+Archivmanager 28 
+  -, reservieren 29 
+Archiv (Menü) 27 
+Archivübersicht drucken 27 
+Assoziativspeicher 68 
+auf koppeldatei 74 
+Aufräumen 26 
+auf satz 65, 78 
+Auf Satz Nr. 17 
+Ausdrucken 24 
+Ausführen 8 
+ausfuehrtaste 8, 102 
+AUSWAHL 97 
+AUSWAHL: 4 
+Auswahl 8 
+  -, Format 98 
+auswahl anbieten 103 
+ 
+Bearbeiten 46 
+BILD 97 
+bild ausgeben 95 
+bildschirm neu 94 
+ 
+Datei, aufräumen 26 
+  -, kopieren (logisch) 25 
+  -, kopieren vom Archiv 27 
+  -, löschen 25 
+  -, löschen auf Archiv 28 
+  -, Platzbedarf 26 
+  -, reorganisieren 26 
+  -, schreiben auf Archiv 27 
+  -, umbenennen 25 
+  -, virtuelle 32, 71 
+Dateianwendungen 109 
+Dateien Archiv, Übersicht 27 
+dateiende 64, 78 
+dateien loeschen 74 
+Dateien (Menü) 25 
+Dateien System, Übersicht 25 
+Dateilimit 52 
+Dateimanager 28 
+Dateiname 40 
+dateiversion 75 
+DATUM 45 
+Dezimalkomma 45 
+dezimalkomma 67 
+dialog 104 
+Dialog 9, 103 
+dialogfenster 104 
+DIN 45 
+direkt drucken 83f. 
+Druckausgabe, Richtung 23 
+druckdatei 85 
+drucke 84 
+Drucken 23, 49, 83 
+  -, Archivübersicht 27 
+Drucken (Menü) 23 
+Druckmuster 23, 49, 83 
+  -, Fehler 56 
+Druckvorgang 51 
+ 
+editget 104 
+EDITIEREN: 6 
+Editieren 23 
+  -, Zeile 9 
+Editor 9, 29 
+eindeutige felder 47, 89 
+einfuegen 96 
+Einfügen 10, 19 
+  -, Satz 36 
+  -, Zeile 10 
+EINGABE: 4 
+Eingabe 9 
+Einzelsatz (Menü) 17 
+ELAN-Compiler 56 
+ELAN-Kommandos 8 
+ENDE 97 
+Endekennzeichnung 40 
+ESC '?' 6 
+ESC '9' 4 
+ESC '1' 4 
+ESC '?' 4 
+ESC '?' 3 
+ESC 'D' 5 
+ESC ESC 3 
+ESC 'F' 5f. 
+ESC 'g' 5 
+ESC 'h' 4ff. 
+ESC 'K' 36 
+ESC OBEN 5 
+ESC 'p' 5 
+ESC 'q' 4, 6 
+ESC RUBIN 5 
+ESC RUBOUT 5 
+ESC UNTEN 5 
+ESC 'w' 4f. 
+ESC 'z' 4f. 
+eudas 29 
+EUDAS: 3 
+EUDAS-Datei, aufspalten 110 
+  -, drucken 23, 49, 83 
+  -, einrichten 13 
+  -, ketten 14, 32 
+  -, kopieren 21, 46, 85 
+  -, koppeln 14, 32 
+  -, nach Vorschrift ändern 48 
+  -, öffnen 13, 32 
+  -, reorganisieren 67 
+  -, sortieren 22 
+  -, Struktur 31, 61 
+  -, tragen 46, 87 
+  -, Übersicht 22 
+  -, verändern 21 
+eudas dateiname 75 
+EUDAT 61, 63, 109 
+EUMEL-Netz 28 
+exit durch 96 
+ 
+f 91 
+FEHLER 5 
+fehler ausgeben 104 
+Feld 31 
+FELD 98 
+feld aendern 62, 65, 76 
+Feldauswahl 20, 41, 95 
+feld bearbeiten 62, 65, 76 
+felderzahl 62, 63 
+feldindex 62 
+feldinfo 66, 77 
+Feldinhalt 31, 39 
+feld lesen 65, 76 
+feldmaske 47, 89 
+Feldmuster 53 
+Feldname 31, 39 
+  -, ändern 16 
+  -, anfügen 16 
+feldnamen aendern 63 
+feldnamen bearbeiten 76 
+feldnamen lesen 64, 76 
+feldnummer 76 
+Feldstruktur 15 
+Feldtyp 31, 42 
+Feldtypen 45, 66 
+  -, ändern 16 
+Feldvergleich 43 
+Fenster 93 
+fenstergroesse 94 
+fenstergroesse setzen 93 
+fenster initialisieren 93 
+fenster veraendert 94 
+fensterzugriff 94 
+folgedatei 75 
+Folgezeilen 41 
+Formular 39 
+FRAGE: 5 
+Fragen 9 
+Funktion, ausführen 8 
+  -, gesperrte 8 
+ 
+Gesamtdatei (Menü) 21 
+Gib Kommando: 6 
+global manager 36, 100 
+Gruppe 51 
+GRUPPE-Anweisung 49 
+gruppenwechsel 51, 85 
+ 
+Hauptdatei 32 
+HILFE: 4 
+HILFE 97, 99 
+Hilfe 9 
+  -, Format 98 
+hilfe anbieten 103 
+Holen 19 
+hole satz 89 
+HOP LINKS 4 
+HOP 'o' 4 
+HOP OBEN 3ff. 
+HOP RECHTS 4 
+HOP RETURN 4 
+HOP RUBOUT 4 
+HOP UNTEN 3ff. 
+HOP 'x' 4 
+ 
+inhalt veraendert 74 
+Initialisieren 28 
+Initialisierungsteil 49 
+ 
+ja 104 
+ 
+K 46, 86 
+kette 73 
+Ketten 14, 32 
+Klassenwechsel 106 
+Kombinationen 34 
+Kommandos 8 
+Kommandozeile 50 
+kopiere 86 
+Kopieren 21, 46, 85 
+Kopieren (logisch) 25 
+Kopieren vom Archiv 27 
+Kopiermuster 21, 46 
+KOPPEL 40 
+Koppeldatei, umschalten auf 36 
+Koppelfelder 33 
+Koppeln 14, 32f. 
+kopple 72 
+Kurzabfrage 29 
+ 
+LEER 3f. 
+Leertaste 8 
+lfd nr 85 
+lineform 24 
+LINKS 3f. 
+Literaturangaben 108 
+Löschen 25 
+  -, Satz 36 
+  -, Zeile 10 
+Löschen auf Archiv 28 
+ 
+Manager 13 
+Manager (Mehrbenutzer) 16, 36 
+markierte saetze 81 
+Markierung 18, 40, 42 
+markierung aendern 81 
+Markierungen löschen 22 
+markierungen loeschen 81 
+maxdruckzeilen 85 
+MEHR-Anweisung 50 
+MENUE 97 
+Menü 8 
+  -, Aufruf 101 
+  -, Verwaltung 99 
+menue anbieten 101 
+menuedaten einlesen 99 
+Menüformat 97 
+menue loeschen 100 
+menue manager 100 
+menuenamen 100 
+Modi 55 
+MODUS-Anweisung 50 
+Musterprogramme 105 
+Musterteil 50 
+Musterzeichen 53 
+Musterzeile 50 
+  -, Interpretation 52 
+ 
+Nachbearbeiten 24 
+Nachspann 49 
+NACHSPANN-Anweisung 49 
+Namenskonflikte 33 
+neuer dialog 104 
+Normalmodus 55 
+Notizen 15, 31, 64 
+notizen aendern 64, 77 
+notizen lesen 64, 77 
+ 
+'o' 4 
+OBEN 3f. 
+ODER-Verknüpfung 43 
+oeffne 63, 72 
+Öffnen 32 
+Öffnen (Menü) 13 
+ 
+pageform 24 
+Paralleleditor 56, 83 
+Paßwort 29 
+Platzbedarf 26 
+Positionieren 17, 31, 64, 77 
+Priorität 44 
+Programmzeile 51 
+Protokolldatei 47 
+Prüfbedingungen 16, 31, 47, 64,
+   87 
+pruefe 47, 88 
+Pufferplatz 54 
+ 
+RECHTS 3f. 
+Refinement 56 
+reorganisiere 67 
+Reorganisieren 26, 45, 67 
+Reservieren 29 
+RETURN 4 
+Richtung Druckausgabe 23 
+rollen 95 
+Rollen 41 
+RUBIN 4 
+RUBOUT 4 
+ 
+saetze 64 
+SATZ 61 
+Satz 31 
+satz aendern 66 
+satz ausgewaehlt 80 
+Satzauswahl 42 
+Satzeditor 9 
+satz einfuegen 66, 79 
+Satzformular 39 
+satz initialisieren 62 
+satzkombination 77 
+satz lesen 66 
+satz loeschen 66, 79 
+satz markiert 81 
+satznr 64 
+satznummer 77 
+Satznummer 39 
+Satzposition 64 
+Satzzeiger 31 
+Satzzugriffe 65 
+Schreiben auf Archiv 27 
+SEITE 99 
+sichere 73 
+Sichern 15, 36 
+sortiere 67 
+Sortieren 22, 31, 44, 66 
+Sortierreihenfolge 31, 44 
+sortierreihenfolge 67 
+Sortierzustand 45 
+Spaltendruck 52 
+Sperre 36 
+Standard-Kopiermuster 21, 46 
+status anzeigen 103 
+Statuszeile 3 
+std kopiermuster 87 
+Suchbedingung 17, 39, 42 
+  -, löschen 18 
+  -, setzen 18 
+suchbedingung 80 
+suchbedingung lesen 80 
+suchbedingung loeschen 80 
+suchen 96 
+Suchen, Optimierung 44 
+Suchmuster 42 
+  -, eingeben 10 
+ 
+Tabellenmodus 55 
+Tasten 3 
+Tastenfunktionen 3 
+TEXT 45 
+textdarstellung 91 
+Textdatei, ausdrucken 24 
+  -, editieren 23 
+  -, nachbearbeiten 24 
+Textzeile 49f. 
+trage 88 
+Tragen 16, 19, 21, 46, 87 
+trage satz 88 
+ 
+uebersicht 95 
+uebersichtsfenster 95 
+Umbenennen 25 
+Umbruch 40, 55 
+Umschalten auf Koppeldatei 36 
+UND-Verknüpfung 43 
+unsortierte saetze 67 
+UNTEN 3f. 
+Überschrift 39 
+Übersicht 22, 41 
+Übersicht Dateien Archiv 27 
+Übersicht Dateien System 25 
+ 
+V 48, 90 
+Verändern 21 
+verarbeite 90 
+Verarbeitung 89 
+Verknüpfung von Bedingungen
+43 
+virtuelle Datei 32, 71 
+VORSPANN 98 
+Vorspann 49 
+VORSPANN-Anweisung 49 
+ 
+waehlbar 102 
+wahl 103 
+Warten 6 
+weiter 65, 78 
+Weiter 17 
+wert 91 
+wertemenge 47, 88 
+WIEDERHOLUNG-Anweisung 49 
+Wiederholungsteil 49 
+ 
+'x' 4 
+ 
+ZAHL 45 
+zahltext 91 
+Zeichen, reservierte 44 
+ZEIGEN: 6 
+Zeilenende 54 
+Zeilenwiederholung 55 
+Zielarchiv 28 
+Zurück 17 
+zurueck 65, 78 
+Zustand 3 
+Zustandsübergänge 7 
+
diff --git a/doc/eudas/eudas.ref.titel b/doc/eudas/eudas.ref.titel
new file mode 100644
index 0000000..223a839
--- /dev/null
+++ b/doc/eudas/eudas.ref.titel
@@ -0,0 +1,91 @@
+#limit (14.0)# 
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#gs-MP BAP 
+ 
+ 
+ 
+ 
+#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# 
+#free (6.0)# 
+#on("b")#EUDAS#off("b")# 
+#free (1.0)# 
+#on("b")#Anwender-#off("b")# 
+#on("b")#Datenverwaltungssystem#off("b")# 
+#free (2.0)# 
+#on ("b")#VERSION 4#off("b")# 
+#free(1.0)# 
+#on("u")#                                                    #off("u")# 
+#free (0.5)# 
+#on("b")#REFERENZHANDBUCH#off("b")# 
+#block# 
+#page# 
+#free (9.5)# 
+Hergestellt mit Hilfe der EUMEL-Textverarbeitung und des Pro­
+gramms FontMaster der Martin Schönbeck GmbH. 
+#free (1.7)# 
+Ausgabe September 1987 
+ 
+Dieses Handbuch und das zugehörige Programm sind urheberrechtlich
+geschützt. Die dadurch begründeten Rechte, insbesondere der Ver­
+vielfältigung in irgendeiner Form, bleiben dem Autor vorbehalten. 
+ 
+Es kann keine Garantie dafür übernommen werden, daß das Pro­
+gramm für eine bestimmte Anwendung geeignet ist. Die Verantwor­
+tung dafür liegt beim Kunden. 
+ 
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrekt­
+heit und Vollständigkeit der Angaben wird aber keine Gewähr über­
+nommen. Das Handbuch kann jederzeit ohne Ankündigung geändert
+werden. 
+ 
+(c) Copyright 1987  Thomas Berlage 
+                    Software-Systeme 
+                    Im alten Keller 3 
+#free (0.1)# 
+                    D-5205 Sankt Augustin 1 
+#page# 
+#free (7.0)# 
+#center##on("b")#I.#off("b")# 
+#free (1.0)# 
+#center##on("b")#FUNKTIONEN#off("b")# 
+#center##on("b")#ZUM#off ("b")# 
+#center##on("b")#NACHSCHLAGEN#off("b")# 
+#page# 
+#free (7.0)# 
+#center##on("b")#II.#off("b")# 
+#free (1.0)# 
+#center##on("b")#EUDAS#off("b")# 
+#center##on("b")#FÜR#off ("b")# 
+#center##on("b")#PROGRAMMIERER#off("b")# 
+#page# 
+#free (7.0)# 
+#center##on("b")#III.#off("b")# 
+#free (1.0)# 
+#center##on("b")#ANHANG#off("b")# 
+
+
+
+
diff --git a/doc/eudas/eudas.ref.vorwort b/doc/eudas/eudas.ref.vorwort
new file mode 100644
index 0000000..f911be8
--- /dev/null
+++ b/doc/eudas/eudas.ref.vorwort
@@ -0,0 +1,81 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#EUDAS 
+ 
+ 
+ 
+ 
+#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# 
+#center#1 
+ 
+Vorwort 
+ 
+ 
+ 
+Lieber EUDAS-Benutzer! 
+ 
+Dies ist das zweite Handbuch, das Sie zu EUDAS bekommen. Wenn
+Sie sich mit EUDAS noch nicht auskennen, sollten Sie zunächst das
+#on("i")#Benutzerhandbuch#off("i")# zu Rate ziehen, ehe Sie in dieses Handbuch
+schauen. 
+ 
+    Das #on("i")#Referenzhandbuch#off("i")# ist in zwei Teile geteilt. Im ersten Teil
+finden Sie eine Übersicht über alle EUDAS-Funktionen (im Kapitel
+2) sowie zusammengefaßte Informationen über die Bedienung (Kapi­
+tel 1) und die genaue Wirkung der einzelnen Funktionen (Kapitel 3
+bis 5). Dieser Teil soll Ihnen zum Nachschlagen dienen, wenn Sie
+eine bestimmte Information suchen. 
+    Im zweiten Teil sind alle Informationen zusammengefaßt, die
+ein Programmierer zur Benutzung der EUDAS-Funktionen braucht. Es
+sei an dieser Stelle jedoch davon abgeraten, sofort eigene Program­
+me zu schreiben, da sich in vielen Fällen die gleiche Wirkung auch
+durch Programmierung innerhalb von EUDAS-Funktionen erreichen
+läßt (zum Beispiel in Druck- und Änderungsmustern). 
+    Im Zweifelsfall orientieren Sie sich anhand von Kapitel 11, wie
+Sie Ihr Problem am besten lösen können. 
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/eudas/ref.abb.1-1 b/doc/eudas/ref.abb.1-1
new file mode 100644
index 0000000..d3b3217
--- /dev/null
+++ b/doc/eudas/ref.abb.1-1
@@ -0,0 +1,42 @@
+#limit (13.5)# 
+#start (3.5, 5.0)# 
+#lpos (0.5)##c pos (3.5)##c pos (4.7)##cpos (7.0)##c pos (10.5)# 
+#table# 
+         eudas   ESC q    
+ 
+      ESC ESC     ESC h 
+#free (0.2)# 
+GIB KDO:        EUDAS    
+#free (0.2)# 
+      ESC h       
+    RET           LEER  'Buchst.'    
+ 
+            ESC q           
+ 
+            FEHLER 
+ 
+ 
+   WARTEN          
+         n, j    
+            FRAGE 
+ 
+         RET    
+            EINGABE 
+#linefeed (0.5)# 
+ 
+ 
+            ESC z           
+         ESC q    
+#linefeed (1.0)# 
+            AUSWAHL 
+ 
+         ESC q    
+            EDITIEREN 
+ 
+         ESC q    
+            SATZEDITOR 
+ESC ?   ESC q             
+         ESC q    
+HILFE           ZEIGEN 
+ 
+
diff --git a/doc/eudas/register b/doc/eudas/register
new file mode 100644
index 0000000..9cca0fc
--- /dev/null
+++ b/doc/eudas/register
@@ -0,0 +1,490 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (181)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+Register 
+ 
+ 
+ 
+#columns (2, 0.5)# 
+#limit (6.5)# 
+% 63, 69, 148 
+%% 141 
+& 63, 69, 103, 148 
+<!> 57 
+-- 103 
+.. 102 
+.a$ 65 
+'+' 107 
+'-' 107 
+ 
+Abbruch 35 
+Abkürzungen 133 
+Abkürzungsteil 134, 140 
+Absatzmarken 125, 129 
+Abschlußzeile 45 
+Abschneiden 71 
+Abschnitt 67, 69, 134 
+Alternative 99 
+  -, globale 100 
+  -, lokale 99 
+AND 162 
+Ändern 55 
+Änderungen 83, 85, 90, 95 
+  -, automatisch 121 
+Änderungsmuster 121, 166 
+Anführungsstrich 27, 34 
+Ankreuzen 36, 40 
+Anrede 138 
+Anweisung 63 
+  -, Textkosmetik 74 
+Anzeige 44 
+  -, rollen 97 
+Arbeitsbereich 16 
+Arbeitskopie 56, 84, 173 
+  -, Beispiel 58 
+  -, löschen 57 
+Arbeitstask 16 
+Archiv 32 
+  -, anmelden 34 
+  -diskette 36 
+  -, lesen 34 
+  -, löschen 176 
+  -manager 175, 177 
+  -menü 33, 174 
+  -name 34, 36 
+  -, schreiben 36 
+  -übersicht 175 
+Arithmetik 161 
+Attribut 4, 29 
+Aufräumen 173 
+Ausdrucken 66 
+Ausdrücke 116, 151 
+  -, Zusammensetzung 152 
+Ausgabedatei 66 
+Ausgaberichtung 65 
+Auswahlzustand 36, 40 
+Automatische Änderungen 121 
+ 
+Bedienungsregeln 39 
+begin 16 
+Benutzerhandbuch i 
+Berechnungen 8 
+Bewegen 45 
+Bildschirmaufbau 45 
+Bitte warten 34, 40 
+blättern 46 
+BOOL 154, 162 
+ 
+Carriage Return 15 
+CAT 167 
+CONST 155 
+CR 15 
+Cursor 35, 46 
+  -tasten 54 
+ 
+date 137 
+Datei 27 
+  -arten 27 
+  -, aufräumen 173 
+  -auswahl 36 
+  -größe, Begrenzung 124 
+  -, kopieren 172 
+  -limit 71 
+  -, löschen 38, 172 
+  -namen 172 
+  -, Platzbedarf 173 
+  -, reorganisieren 174 
+  -sperre 95 
+  -, umbenennen 172 
+  -verwaltung 37 
+  -, virtuelle 83 
+Dateien, Archiv 174 
+  - (Menü) 38, 171 
+  -, System 171 
+DATEIENDE 106 
+Daten, ändern 55 
+  -, anzeigen 44 
+  -, sichern 33 
+  -typen 152 
+  -typen, umwandeln 154 
+  -verwaltung 3 
+Datum 44, 99, 133, 137 
+DATUM 112 
+DECR 167 
+Denotation 154 
+Dezimalkomma 111, 161 
+Dezimalpunkt 148 
+DIN 112 
+Diskette 28, 32 
+  -, formatieren 176 
+  -, initialisieren 176 
+Diskettenlaufwerk 175 
+Doppeleinträge 121 
+DOS 178 
+Druckausgabe, Bearbeitung 125 
+Drucken 7, 61 
+  -, Ablauf 66 
+  -, Aufruf 64, 66 
+  - (Menü) 22, 65 
+  -, Übersicht 175 
+Druckersteuerungsanweisungen
+   74, 124 
+Druckmuster 13, 23, 61, 166 
+  -, Fehler 134 
+  -, Übersetzung 134, 142 
+  -, Zeilenlänge 71 
+Druckrichtung 123 
+Druckverfahren 62 
+ 
+Editieren 64 
+Editor 34, 41, 52, 125 
+eindeutige felder 121 
+Einfügen 18, 52 
+Eingabe, Daten 52 
+  -, Suchmuster 46 
+Eingabeüberprüfung 112 
+Eingabezustand 35, 40 
+Eingangsmenü 17 
+Einzelsatz (Menü) 18, 44, 92, 97 
+ELAN-Anweisungen 141 
+ELAN-Ausdrücke 116, 151 
+ELAN-Compiler 134 
+ELIF 168 
+ELSE 139 
+ENDE 45 
+Endesatz 45, 48, 53, 85 
+ENTER 15 
+ESC '1' 107 
+ESC '?' 31, 39, 40 
+ESC '9' 107 
+ESC 'D' 99 
+ESC ESC 41, 111 
+ESC 'F' 67 
+ESC 'g' 99 
+ESC 'h' 35, 39, 40, 55, 107 
+ESC 'K' 92 
+ESC OBEN 97 
+ESC 'p' 99 
+ESC 'P' 118 
+ESC 'q' 32ff.,40 , 47, 65, 107 
+ESC RUBIN 54 
+ESC RUBOUT 54 
+ESC UNTEN 97 
+ESC 'w' 32, 40, 53 
+ESC 'z' 32, 36, 40, 95 
+Etiketten 126 
+eudas 30, 125 
+EUDAS-Archivdiskette 11, 29 
+EUDAS-Datei 27, 61, 171 
+  -, drucken 61 
+  -, einrichten 17, 51 
+  -, Grenzen 29 
+  -, kopieren 113 
+  -, Mehrfachbenutzung 93 
+  -, Struktur 28 
+EUDAS, Aufruf 30 
+  -, Installation 11 
+  -, Start 15 
+  -, Verlassen 24, 32 
+EUMEL-Netz 175 
+EUMEL-Textverarbeitung 5 
+EUMEL-Zeichencode 110 
+ 
+f 117, 134, 156 
+FALSE 154 
+Fehler, Druckmuster 66 
+  -, quittieren 36 
+  -zustand 35, 40 
+Feld 29 
+Feldauswahl 97, 106 
+Felder, anfügen 111, 114 
+Feldinhalt 29, 156, 160 
+feldmaske 120 
+Feldmuster 63, 69 
+Feldmustertypen 71 
+Feldnamen 29, 67 
+  -, abfragen 67 
+  -, Abgrenzung 72 
+  -, ändern 112 
+  -, eingeben 51 
+  -, Länge 133 
+Feldreihenfolge 113 
+Feldstruktur 111 
+Feldteil 45 
+Feldtypen 110, 154 
+  -, ändern 111 
+Feldvergleich 103 
+Formatieren 177 
+Formbrief 74 
+Formular 8, 44 
+Fragezustand 38, 40 
+Funktionen 152 
+  -, ausführen 31, 46 
+  -, auswählen 30 
+  -, gesperrt 31 
+Fußzeile 44 
+ 
+Gib Kommando 41, 11 
+global manager 93 
+GRUPPE 145 
+Gruppen 144 
+  -definition 145 
+  -, mehrere 145 
+  -wechsel 145 
+gruppenwechsel 145 
+ 
+halt 39, 110 
+Hardwarefehler 33 
+Hauptdatei 87ff. 
+Hilfe 31 
+Hilfezustand 31, 40 
+Hilfstexte 13, 31 
+Hintergrunddiskette 12 
+Hintergrundengpaß 124 
+Holen 56 
+HOP OBEN 40, 98, 106 
+HOP RETURN 106 
+HOP RUBIN 54 
+HOP RUBOUT 54 
+HOP UNTEN 40, 98, 106 
+HOP 'x' 98 
+ 
+IF 117 
+IF-Abfragen 161, 168 
+IF-Anweisungen 138 
+INCR 167 
+Init 176 
+Initialisierungsteil 124, 143 
+Installation 11 
+int 140 
+INT 153 
+ 
+K 113 
+Karteikarten 5 
+KB 173 
+Ketten 13, 83, 85, 95 
+Kilobyte 173 
+Klammern 163 
+  -, spitze 72 
+Kombination 89 
+Kombinationsnummer 90 
+Kopieren, logisch 172 
+  -, EUDAS-Datei 112 
+  - (vom Archiv) 34, 176 
+Kopieranweisung 113 
+Kopiermuster 113, 115, 166 
+  -, Übersetzung 116 
+KOPPEL 92 
+Koppeldatei, Markierung 105 
+  -, Position 93 
+  -, umschalten 92 
+Koppelfeld 86, 89 
+  -, übernehmen 92 
+Koppeln 13, 83, 85, 95 
+  -, mehrere Dateien 87 
+Koppelvorgang, Schema 87 
+Korrekturversion 14 
+ 
+Länge, feste 70, 137 
+  -, variable 70 
+Leerautomatik 73 
+Leertaste 17, 31 
+length 158 
+lfd nr 137, 157 
+limit 71, 125 
+lineform 125, 129 
+LINKS 31, 35 
+linksbündig 71 
+Linksschieben 128 
+list (archive) 34 
+Löschen 55 
+  - (auf Archiv) 176 
+  - (Datei) 172 
+ 
+Manager 93, 95 
+Managertask 175 
+MARK 104 
+Markieren 104 
+  -, in Übersicht 107 
+Markierung 104 
+  -, löschen 105 
+maxdruckzeilen 124 
+MEHR 129 
+Mehrfachbenutzung 93 
+Menü 30 
+Menüzustand 31, 40 
+min 155 
+Modi 128 
+Multi-User 12 
+Multi-User-System 16 
+Musterbrief 139 
+Musterteil 135 
+Musterzeichen 70 
+ 
+Nachbearbeitung 125 
+Nachspann 68, 144 
+NACHSPANN 68 
+Negation 103 
+Netz 175 
+Numerieren 137 
+ 
+'o' 40, 98 
+OBEN 30, 106 
+ODER 100 
+Öffnen 17, 21, 43, 51, 57, 83, 95 
+  - (Menü) 30 
+Operatoren 152, 155 
+  -, Priorität 163 
+OR 163 
+ 
+pageform 125 
+Paralleleditor 67, 142 
+Parameter 152 
+Paßwort 94, 177 
+Pfeiltasten 54 
+Platzbedarf, Datei 173 
+pos 159 
+Position, feste 69 
+  -, variable 69 
+Positionierung 48 
+Proportionalschrift 129 
+Prüfbedingungen 118 
+pruefe 120 
+PUBLIC 13 
+ 
+REAL 153 
+real 155 
+RECHTS 31, 55 
+rechtsbündig 71, 137 
+Referenzhandbuch i, 79 
+Refinement 134, 140, 163 
+Reorganisieren 174 
+Reservieren 178 
+RET 15 
+RETURN 15 
+Richtung, Druckausgabe 65, 123 
+Rollen 97, 106 
+RUBIN 35, 54 
+RUBOUT 35, 54 
+Runden 160 
+ 
+Satz 29 
+  -, anwählen 46 
+  -editor 41, 47, 53, 92, 98 
+  -, einfügen 52 
+  -, holen 56 
+  -, löschen 55 
+  -, tragen 55 
+Satz.Nr 46, 48 
+Satznummer 45, 90 
+Satzauswahl, kopieren 114 
+Schreiben (auf Archiv) 36, 176 
+Schreibmarke 35 
+Schrifttypen 125 
+Selektion 48 
+Sichern 20, 56, 84, 95 
+Single-User 12 
+Single-User-System 16 
+Sortieren 109 
+  -, Optimierung 110 
+  -, Zieldatei 115 
+Sortierreihenfolge 109 
+Spaltenbreite 126 
+Spaltendruck 126 
+Speicherplatz 14, 38, 176 
+  -, Datei 173 
+Sperren von Dateien 95 
+Standard-Kopiermuster 115 
+Stationsnummer 175 
+Statistik 169 
+Statuszeile 31, 39 
+Stern 50, 101 
+SUB 158, 163 
+subtext 158 
+SUCH 47 
+Suchbedingung f. Drucken 67 
+Suchbedingung, Kombination 49 
+Suchbedingung löschen 48 
+Suchbedingung setzen 46 
+Suchen 21, 46 
+  -, Optimierung 104 
+Suchmuster 47, 99 
+  -, Eingabe 47 
+SV-Taste 16, 39 
+System 32 
+ 
+Tabellenmodus 128 
+Tagesdatum 99 
+Task, Manager 93 
+Tasks 13 
+Teildatei 114 
+Teiltexte 158 
+TEXT 112, 153 
+text 140 
+Textdatei 28, 61, 171 
+  -, ändern 65 
+  -, ansehen 65 
+  -, ausdrucken 66 
+  -, editieren 64 
+Texte, verketten 156 
+Text-Funktionen 156 
+Textkonstanten 139 
+Text, konstanter 117 
+Text, Länge 158 
+Textverarbeitung 3, 123 
+THEN 139 
+Tragen 55, 118 
+TRUE 154 
+ 
+Uhrzeit 133 
+Umbruch 129 
+Umlaute 143 
+Umschalten auf Koppeldatei 92 
+UND 100ff. 
+UNTEN 30, 106 
+Überschrift 45, 68 
+Übersicht (Archiv) 34, 175 
+  - (Dateien) 37, 171 
+  - (Sätze) 105 
+ 
+V 122 
+VAR 165 
+Variablen 165 
+  -, Initialisierung 143, 167 
+  -, Lebensdauer 166 
+  -, Typ 165 
+Verändern 121 
+Vergleiche 102, 162 
+virtuelle Datei 83 
+Vorspann 68, 144 
+VORSPANN 68 
+ 
+Weiter 45, 48, 90 
+wert 148, 160 
+wertemenge 119 
+WIEDERHOLUNG 63, 126 
+ 
+'x' 36, 40 
+ 
+ZAHL 110 
+zahltext 148, 160 
+Zeichen, reservierte 64, 69, 103 
+Zeigen 40 
+Zeile einfügen 54 
+Zeilenfortsetzung 129 
+Zeilenlänge 71 
+Zielarchiv 175 
+Zieldatei, Struktur 113 
+Zurück 45, 48, 90 
+Zustand 31, 40 
+Zuweisung 166 
+ 
+
diff --git a/doc/eudas/uedas.hdb.4 b/doc/eudas/uedas.hdb.4
new file mode 100644
index 0000000..ecbfd58
--- /dev/null
+++ b/doc/eudas/uedas.hdb.4
@@ -0,0 +1,686 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (27)# 
+#headodd# 
+#center#EUDAS#right#% 
+ 
+#end# 
+#headeven# 
+%#center#EUDAS 
+ 
+#end# 
+#center#1 
+ 
+4 Umgang mit Dateien und Menüs 
+ 
+ 
+ 
+Zu Anfang dieses Teils sollen Sie zunächst die Terminologie von
+EUDAS kennenlernen. Das Karteikartenmodell des ersten Kapitels
+muß ja auf einem Rechner realisiert werden. Dazu müssen erst eini­
+ge Ausdrücke erklärt werden. 
+ 
+ 
+4.1 EUDAS-Dateien 
+ 
+Der wichtigste Ausdruck, der Ihnen noch sehr häufig begegnen wird,
+ist #on("i")#Datei#off("i")#. Eine Datei ist eine Sammlung von Informationen in einem
+Computer, die als ein Objekt transportiert und behandelt werden
+können. Dieser Name wurde analog zu "Kartei" gebildet, mit dem
+Unterschied, daß eine "Daten-Kartei" gemeint ist. 
+    Jede Datei hat einen eigenen Namen, durch den sie identifiziert
+wird. Der Name ist oft in Anführungsstriche eingeschlossen - die
+Anführungsstriche gehören jedoch nicht zum Namen, sondern dienen
+nur zur Abgrenzung, welche Zeichen zum Namen gehören. Der Name
+ist also wie die Aufschrift auf einem Aktenordner. Wenn alle Ordner
+im Schrank stehen, können Sie anhand des Namens den richtigen
+Ordner finden, anderenfalls müßten Sie alle Ordner öffnen. 
+ 
+#on("b")#Dateiarten#off("b")# Dateien werden nun für viele verschiedene Arten
+von
+Informationen benutzt. Sie können einerseits Texte enthalten oder
+auch Karteien, Grafiken, Formeln oder Zahlenkolonnen. Sie haben
+bereits im ersten Kapitel den Unterschied zwischen Datenverwaltung
+und Textverarbeitung kennengelernt. In diesem Zusammenhang sind
+die beiden ersten Verwendungsweisen wichtig. 
+ 
+#limit (12.0)# 
+        #on("i")#Textdateien#off("i")# 
+        sind Dateien, die normale Texte enthalten, die mit
+        dem Editor verändert und einfach ausgedruckt
+        werden können. In ihnen werden also Informationen
+        gespeichert, wie die Textverarbeitung sie benötigt. 
+ 
+        #on("i")#EUDAS-Dateien#off("i")# 
+        sind dagegen Dateien, die Informationen in der
+        Form von Karteikarten enthalten. Sie haben also
+        die Struktur, wie sie von der Datenverwaltung be­
+        nötigt wird. 
+#limit (13.5)# 
+ 
+    Der Computer kann aber auch alle Arten von Dateien gleich­
+behandeln, und zwar dann, wenn der Inhalt der Dateien nicht be­
+trachtet werden muß. 
+    Ein häufiger Fall ist zum Beispiel, wenn Dateien zur Sicherung
+auf eine Diskette geschrieben werden sollen. In diesem Fall genügt
+die Angabe des Namens; dem Rechner ist es egal, welchen Inhalt die
+Datei hat. 
+    Anders ist es aber, wenn Sie den Inhalt betrachten wollen.
+Dazu brauchen Sie dann ein Programm, das die innere Struktur der
+Datei kennt. Textdateien können Sie zum Beispiel mit dem Editor
+ansehen. EUDAS-Dateien müssen Sie jedoch mit EUDAS ansehen, da
+der Editor die EUDAS-Struktur nicht kennt. Es ist in vielen Fällen
+sinnvoll, durch einen Zusatz im Dateinamen zu kennzeichnen, ob es
+sich um eine Textdatei oder eine EUDAS-Datei handelt. 
+ 
+ 
+#free (3.7)# 
+ 
+#center#Abb. 4-1   Struktur einer EUDAS-Datei 
+ 
+ 
+#on("b")#Terminologie#off("b")# EUDAS verwendet bestimmte Ausdrücke, um die
+Strukturelemente einer EUDAS-Datei zu kennzeichnen. Die Struktur
+einer EUDAS-Datei ist schematisch in Abb. 4-1 dargestellt. Die
+Ausdrücke wurden nun nicht direkt aus dem Karteikartenmodell
+übernommen, da es auch noch andere Modelle gibt und keine fal­
+schen Assoziationen auftreten sollen. 
+    EUDAS verwendet die Bezeichnung #on("i")#Satz#off("i")# für eine Karteikarte.
+Eine EUDAS-Datei besteht also aus einer Anzahl von gleichartigen
+Sätzen. Zur Veranschaulichung kann man sich diese nebeneinander­
+gelegt vorstellen. 
+    Jeder Satz ist unterteilt in sogenannte #on("i")#Felder#off("i")#. Ein Feld ent­
+spricht einem Attribut bzw. einem Eintrag auf der Karteikarte. Ein
+Feld ist wiederum unterteilt in einen #on("i")#Feldnamen#off("i")# und einen #on("i")#Feldin­
+halt#off("i")#. 
+    Der Feldname identifiziert ein bestimmtes Feld innerhalb eines
+Satzes. Die Feldnamen sind natürlich für alle Sätze gleich. Die
+Feldnamen einer EUDAS-Datei sind beliebig und können von Ihnen
+selbst festgelegt werden. 
+    Der Feldinhalt enthält die eigentliche Information des entspre­
+chenden Attributs. Der Feldinhalt darf ebenfalls aus beliebig vielen
+Zeichen bestehen. Die Feldinhalte sind natürlich für jeden Satz
+verschieden und stellen die eigentliche gespeicherte Information
+dar. 
+ 
+#on("b")#Grenzen#off("b")# Aus technischen Gründen gibt es natürlich auch
+einige
+Beschränkungen, die hier nicht verschwiegen werden sollen. Eine
+Datei kann maximal etwa 5000 Sätze enthalten, ein Satz darf aus
+maximal 255 Feldern bestehen. Insgesamt kann ein Satz etwa 32000
+Zeichen umfassen. Die einzelnen Sätze in der EUDAS-Datei werden
+durch ihre jeweilige Positionsnummer identifiziert, also quasi von 1
+bis 5000 durchnumeriert. 
+ 
+ 
+4.2 EUDAS-Menüs 
+ 
+In den folgenden Abschnitten sollen Sie lernen, wie die Bedienung
+von EUDAS funktioniert. Dazu sollen Sie eine EUDAS-Beispieldatei
+von der EUDAS-Diskette in Ihr System holen. Diese Datei brauchen
+Sie dann später, um die Funktionen von EUDAS zu kennenzulernen. 
+    Die Beispieldatei hat den gleichen Inhalt wie die in Kapitel 3
+von Ihnen erstellte Datei. Falls Ihnen also die EUDAS-Archiv­
+diskette nicht zur Verfügung steht, können Sie in diesem Kapitel
+auch jede andere Archivdiskette verwenden. 
+    Bitte beachten Sie im folgenden, daß Sie einfache Anführungs­
+striche nicht mit eingeben, doppelte Anführungsstriche aber wohl. 
+ 
+#on("b")#EUDAS-Aufruf#off("b")# Zuerst müssen Sie EUDAS aufrufen. Dazu
+begeben
+Sie sich in die in Kapitel 3 eingerichtete Task ('continue ("arbeit")')
+und geben bei 'gib kommando:' das Kommando 'eudas': 
+ 
+ 
+        gib kommando: 
+        #on("i")#eudas#off("i")#<RET> 
+ 
+ 
+Falls Ihr System über Menüs gesteuert wird, müssen Sie eine ent­
+sprechende Funktion wählen. Anschließend erscheint folgendes
+Menü: 
+ 
+___________________________________________________________________________________________ 
+ 
+      EUDAS:   Öffnen   Einzelsatz   Gesamtdatei   Drucken   Dateien   Archiv 
+      --------------: 
+      EUDAS-Datei   : 
+      O Öffnen      : 
+      - Ketten      : 
+      - Koppeln     : 
+      --------------: 
+      Arbeitskopie  : 
+      - Sichern     : 
+      --------------: 
+      Aktuelle Datei: 
+      - Notizen     : 
+      - Feldstrukt. : 
+      - Prüfbeding. : 
+      --------------: 
+      Mehrbenutzer  : 
+      M Manager     : 
+      --------------: 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+      Akt.Datei:                    Manager:                       Datum: 22.07.87 
+___________________________________________________________________________________________ 
+ 
+ 
+#on("b")#Menüs#off("b")# Ein #on("i")#Menü#off("i")# ist eine Auswahl für einige verschiedene Funk­
+tionen. Die Funktionen sind jeweils benannt und werden durch einen
+davorstehenden Buchstaben oder ein Minuszeichen gekennzeichnet.
+Eine der Funktionen ist immer durch inverse Darstellung markiert. 
+    Diese Markierung können Sie nun mit Hilfe der Pfeiltasten OBEN
+und UNTEN verschieben. Auf diese Weise können Sie sich die ge­
+wünschte Funktion auswählen. Die Funktionen werden jedoch durch
+das Markieren nicht ausgeführt. Sie können also beliebig mit den
+Pfeiltasten herumexperimentieren. 
+    Ausgeführt wird die markierte Funktion, wenn Sie die Leertaste
+drücken. Sofort erscheint ein Stern vor dem Funktionsnamen, um
+anzuzeigen, daß die Ausführung beginnt. Probieren Sie dies jetzt
+nicht aus, dazu ist später Gelegenheit. 
+    Funktionen mit einem Minuszeichen davor können Sie zwar
+anwählen (markieren), aber nicht ausführen. Solche Funktionen sind
+momentan gesperrt, weil ihre Ausführung keinen Sinn hat oder sogar
+Fehler erzeugen würde. 
+    Mit den Pfeiltasten LINKS und RECHTS können Sie im Menüzu­
+stand weitere EUDAS-Menüs abrufen. Welche Menüs zur Verfügung
+stehen, zeigt Ihnen die oberste Bildschirmzeile. Das aktuelle Menü
+ist jeweils invers dargestellt. 
+ 
+#on("b")#Hilfe#off("b")# Wenn Sie nun wissen möchten, welche Bedeutung die
+mar­
+kierte Funktion hat (die Funktionsbezeichnungen sind aus Platz­
+gründen sehr kurz gehalten), können Sie einen #on("i")#Hilfstext#off("i")# zu dieser
+Funktion abrufen. Dies erfolgt durch die Betätigung der Tasten ESC
+und '?' hintereinander. Diese doppelten Tastenkombinationen mit der
+ESC-Taste am Anfang werden Ihnen noch sehr häufig begegnen -
+denken Sie immer daran, die Tasten hintereinander und nicht
+gleichzeitig zu tippen. Der zeitliche Abstand zwischen den Tasten­
+drücken kann beliebig lang sein; hingegen sollten Sie eine Taste
+nicht zu lange drücken, da sonst eventuell eine automatische Wie­
+derholfunktion Ihrer Tastatur startet. 
+    Probieren Sie nun die Tastenkombination ESC '?' aus. Als Reak­
+tion erscheint in der rechten Hälfte des Bildschirms ein Text. Dieser
+sollte Ihnen die gewünschten Informationen bieten. 
+    Gleichzeitig hat sich aber auch die oberste Bildschirmzeile
+verändert. Sie zeigt jetzt folgendes Bild: 
+ 
+___________________________________________________________________________________________ 
+ 
+      HILFE:  Beenden: ESC q   Seite weiter: ESC w   Seite zurueck: ESC z 
+___________________________________________________________________________________________ 
+ 
+ 
+#on("b")#Zustände#off("b")# Wenn Sie sich nicht im Menü befinden, fungiert
+die ober­
+ste Zeile als sogenannte #on("i")#Statuszeile#off("i")#. Diese Zeile zeigt immer an, in
+welchem #on("i")#Zustand#off("i")# das Programm sich befindet. Der Zustand des Pro­
+gramms hat nämlich Einfluß darauf, welche Tasten Sie drücken
+können und wie das Programm darauf reagiert. Die Statuszeile zeigt
+daher außer dem Zustand auch die wichtigsten Tastenfunktionen. 
+    Sie kennen jetzt also schon zwei Zustände von EUDAS: den
+Menüzustand und den Hilfe-Zustand. 
+ 
+#on("b")#Hilfe-Zustand#off("b")# Vom Menüzustand kommen Sie über die
+Tastenkom­
+bination ESC '?' in den Hilfe-Zustand. Im Hilfe-Zustand haben die
+Pfeiltasten OBEN und UNTEN keine Wirkung mehr (probieren Sie dies
+aus). 
+    Ein Hilfstext besteht im allgemeinen aus mehreren Seiten. Die
+erste Seite enthält dabei die speziellen Informationen, danach
+folgen dann allgemeine Informationen. Mit den Tastenkombinationen
+ESC 'w' und ESC 'z' können Sie zwischen den Seiten umschalten
+(denken Sie daran, was oben über Tastenkombinationen gesagt
+wurde). Wenn Sie dies ausprobieren, werden Sie auf der zweiten
+Seite allgemeine Hinweise zur Menübedienung finden. Auf der letz­
+ten Seite wird ESC 'w' ignoriert, ebenso ESC 'z' auf der ersten Seite. 
+    Mit der Tastenkombination ESC 'q' (quit) kehren Sie aus dem
+Hilfezustand in den vorherigen Zustand zurück. Diese Tastenkombi­
+nation löst allgemein in EUDAS die Rückkehr in den alten Zustand
+aus. Wenn Sie ESC 'q' getippt haben, erscheint die alte Menüzeile
+und Sie können wieder Funktionen auswählen. 
+    Der Hilfszustand läßt sich von nahezu allen (noch zu bespre­
+chenden) Zuständen mit ESC '?' aufrufen. Es wird jeweils ein zum
+aktuellen Zustand passender Hilfstext ausgegeben. 
+    Die möglichen Zustandsübergange sind nochmal in Abb. 4-2
+zusammengefaßt. 
+ 
+ 
+#free (2.5)# 
+ 
+#center#Abb. 4-2   Menü- und Hilfezustand 
+ 
+ 
+#on("b")#EUDAS verlassen#off("b")# Im Menüzustand können Sie EUDAS jederzeit
+durch Tippen von ESC 'q' verlassen. Sie landen dann wieder bei 'gib
+kommando:'. 
+ 
+ 
+4.3 Archivmenü 
+ 
+#on("b")#System/Archiv#off("b")# An dieser Stelle müssen Sie sich die Begriffe #on("i")#Archiv#off("i")#
+und #on("i")#System#off("i")# klarmachen. Als Archiv bezeichnet man die Möglichkeit,
+bei Bedarf Disketten in Ihren Rechner einlegen können, um Dateien
+(und Programme) von anderen Rechnern zu übernehmen. Um diese
+Dateien bearbeiten zu können, müssen Sie sie in das System (Ihre
+Festplatte oder Hintergrunddiskette) kopieren. 
+    Die wichtigste Aufgabe des Archivs ist es, Daten vor Beschädi­
+gung zu sichern. Durch Fehlbedienung oder Systemfehler kann es
+nämlich leicht geschehen, daß die Daten in Ihrem System verloren
+gehen oder zerstört werden. Wenn Sie die Daten jedoch auf einer
+Diskette gesichert und die Diskette sicher verwahrt haben, können
+Sie die Daten wiederherstellen. 
+    Es ist sehr wichtig, daß Sie Ihre Dateien auf Archivdisketten
+sichern, denn ein einziger Hardwarefehler kann die Arbeit von
+Jahren vernichten (Sagen Sie nicht: "Mir passiert so etwas nicht" -
+bis jetzt hat es noch jeden erwischt). 
+ 
+___________________________________________________________________________________________ 
+ 
+      EUDAS:   Öffnen   Einzelsatz   Gesamtdatei   Drucken   Dateien   Archiv 
+      --------------: 
+      Dateien Archiv: 
+      U Übersicht   : 
+      D Üb. Drucken : 
+      --------------: 
+      Datei         : 
+      K Kopieren    : 
+        vom Archiv  : 
+      S Schreiben   : 
+        auf Archiv  : 
+      L Löschen     : 
+        auf Archiv  : 
+      --------------: 
+      Archivdiskette: 
+      I Init        : 
+      --------------: 
+      Z Zielarchiv  : 
+      P Paßwort     : 
+      - Reservieren : 
+      --------------: 
+                    : 
+                    : 
+      Akt.Datei:                    Ziel: "ARCHIVE"                Datum: 22.07.87 
+___________________________________________________________________________________________ 
+ 
+ 
+#center#Abb. 4-3   Archivmenü 
+ 
+ 
+#on("b")#Archivmenü#off("b")# Wenn Sie EUDAS aufrufen, befinden Sie sich
+immer im
+ersten Menü. Sie benötigen jedoch jetzt Funktionen aus dem sech­
+sten Menü 'Archiv'. Wählen Sie dieses Menü jetzt an. Es erscheint
+das in Abb. 4-3 dargestellte Bild. Die Funktionen in diesem Menü
+befassen sich mit beliebigen Dateien auf dem Archiv. 
+    Für den Versuch legen Sie bitte die EUDAS-Archivdiskette ein.
+Dann wählen Sie die Funktion 'Übersicht' in dem Menü an, wenn sie
+nicht schon markiert ist. Sie können nun die ausgewählte Funktion
+durch Tippen der Leertaste ausführen. 
+    In der obersten Zeile erscheint nun der Hinweis 'Bitte war­
+ten..'. Er zeigt an, daß nun eine Funktion ausgeführt wird, bei der
+Sie zunächst nichts tun können. Sie sollten in diesem Zustand keine
+Tasten drücken, denn EUDAS kann nicht darauf reagieren. 
+ 
+#on("b")#Archivübersicht#off("b")# Nach einer mehr oder minder langen
+Aktivitäts­
+phase Ihres Diskettenlaufwerks erscheint dann die Archivübersicht.
+Das Erscheinungsbild mit dem markierten Editorbalken in der ober­
+sten Zeile kommt Ihnen vielleicht bekannt vor. Sie haben nämlich
+nichts anderes als das EUMEL-Kommando 'list (archive)' ausgeführt.
+Neu ist lediglich die Statuszeile: 
+ 
+___________________________________________________________________________________________ 
+ 
+      ZEIGEN:    Blättern: HOP OBEN, HOP UNTEN    Beenden: ESC q    Hilfe: ESC ? 
+___________________________________________________________________________________________ 
+ 
+ 
+Wenn Sie sich die Übersicht angeschaut haben, verlassen Sie den
+Editor wieder mit ESC 'q'. 
+    Beachten Sie, daß Sie unter EUDAS das Archiv nicht extra an­
+melden müssen; dies geschieht automatisch, wenn Sie eine Funktion
+aufrufen. Bei Leseoperationen müssen Sie nicht einmal den Archiv­
+namen wissen. Das Archiv wird automatisch wieder abgemeldet,
+wenn Sie das Archivmenü verlassen. 
+ 
+#on("b")#Archiv lesen#off("b")# Unter den in der Übersicht aufgelisteten
+Dateien
+sollten Sie auch die Datei finden, die Sie brauchen. Sie heißt
+'Adressen'. An dieser Stelle ein kleiner Hinweis: An vielen Stellen
+werden Sie sehen, daß Dateinamen in Anführungsstriche einge­
+schlossen sind. Die Anführungsstriche gehören jedoch #on("i")#nicht#off("i")# zum
+Namen. Sie dienen nur zur Abgrenzung, da in Dateinamen beliebige
+Zeichen erlaubt sind. Wenn Sie aufgefordert werden, einen Datei­
+namen einzugeben, müssen Sie dies immer ohne Anführungsstriche
+tun. 
+    Hoffentlich haben Sie in der ganzen Diskussion nicht das Ziel
+aus den Augen verloren: Sie sollten eine Datei ins System holen, um
+nachher mit ihr zu experimentieren. Zu diesem Zweck gibt es im
+Archivmenü die Funktion 
+#free (0.2)# 
+ 
+        K Kopieren 
+          (vom Archiv) 
+ 
+#free (0.2)# 
+Wählen Sie diese Funktion jetzt mit den Pfeiltasten aus und drücken
+Sie zum Ausführen die Leertaste. 
+ 
+#on("b")#Eingabezustand#off("b")# Nach kurzem 'Bitte warten..'-Zustand werden
+Sie
+im rechten Bildschirmteil nach dem Namen der Datei gefragt. Gleich­
+zeitig erscheint eine neue Statuszeile. Es ergibt sich folgendes Bild: 
+ 
+___________________________________________________________________________________________ 
+ 
+      EINGABE:   Bestätigen: RETURN   Zeigen: ESC z   Abbrechen: ESC h   Hilfe: ESC ? 
+      --------------:Dateiname: 
+      Dateien Archiv: 
+      U Übersicht   : 
+      D Üb. drucken : 
+      --------------: 
+      Datei         : 
+      * Kopieren    : 
+        vom Archiv  : 
+          ... 
+ 
+___________________________________________________________________________________________ 
+ 
+ 
+Sie können in diesem Zustand den Namen der gewünschten Datei
+eingeben. Außer den in der Statuszeile genannten Funktionen kön­
+nen Sie die aus dem Editor bekannten Tasten benutzen, um den
+Text in der Zeile gegebenenfalls zu korrigieren (Pfeiltasten LINKS
+und RECHTS, RUBOUT, RUBIN). Die Schreibmarke (Cursor) zeigt Ihnen
+an, wo das nächste Zeichen plaziert wird. 
+ 
+#on("b")#Abbruch#off("b")# Eine Tastenkombination verdient noch besondere
+Beach­
+tung: Mit ESC 'h' können Sie in vielen Situationen eine Funktion
+noch abbrechen - zum Beispiel wenn Sie irrtümlich die falsche
+Funktion gewählt haben. 
+    Im Gegensatz zu ESC 'q' erfolgt hier die sofortige Rückkehr aus
+der Funktion ins Menü, möglichst ohne daß die Funktion Auswir­
+kungen hinterläßt. Bei einem Abbruch bleibt also in der Regel das
+System unverändert. 
+ 
+#on("b")#Fehlerzustand#off("b")# Um auch die Fehlerbehandlung von EUDAS
+auszu­
+probieren, sollten Sie hier einen falschen Namen eingeben, zum
+Beispiel: 
+#free (0.2)# 
+ 
+            Dateiname: #on("i")#Adresen#off("i")#<RET> 
+ 
+#free (0.2)# 
+EUDAS sucht jetzt auf der Diskette nach einer Datei dieses Namens,
+findet sie aber nicht. Als Reaktion erscheint dann die Meldung: 
+ 
+___________________________________________________________________________________________ 
+ 
+       !!! FEHLER !!!       Quittieren: ESC q     Hilfe zur Meldung: ESC ? 
+      --------------:Dateiname: Adresen 
+      Dateien Archiv:>>> "Adresen" gibt es nicht 
+      U Übersicht   : 
+      D Üb. drucken : 
+      --------------: 
+          ... 
+ 
+___________________________________________________________________________________________ 
+ 
+ 
+Im Normalfall sollten Sie die Fehlermeldung mit ESC 'q' quittieren,
+damit Sie den Befehl erneut versuchen können. Auch hier haben Sie
+die Möglichkeit, eine besondere Information zu dem Fehler abzurufen
+(es liegen jedoch nicht für alle möglichen Fehler spezielle Texte
+vor). 
+    Nach dem Quittieren des Fehlers befinden Sie sich wieder im
+Menüzustand. Wiederholen Sie jetzt die Funktion, indem Sie die
+Leertaste tippen. Sie werden dann erneut nach dem Namen gefragt. 
+ 
+#on("b")#Auswahlzustand#off("b")# Um endlich ans Ziel zu kommen, benutzen Sie
+diesmal eine sehr komfortable Abkürzung, die EUDAS Ihnen bietet.
+Durch Drücken von ESC 'z' können Sie sich nämlich alle möglichen
+Namen anzeigen lassen und den gewünschten einfach ankreuzen. 
+    Anschließend sieht der Bildschirm wie in Abb. 4-4 aus. In die­
+sem Zustand können Sie mit den Pfeiltasten den Cursor zur ge­
+wünschten Datei bewegen und diese ankreuzen. Da Sie auch meh­
+rere Dateien in beliebiger Folge ankreuzen können, erscheint eine
+'1' vor der Datei zur Anzeige der Reihenfolge. Sie wollen aber nur
+diese eine Datei 'Adressen' holen und beenden die Auswahl daher
+mit ESC 'q'. Wenn alles glattgeht, wird jetzt die Datei vom Archiv
+ins System kopiert. 
+ 
+#on("b")#Archiv schreiben#off("b")# Auf nahezu gleiche Weise können Sie mit
+der Funktion 
+ 
+ 
+        S Schreiben 
+          auf Archiv 
+ 
+ 
+eine Datei wieder auf die Diskette schreiben. Als erstes müssen Sie
+dann den Namen der Archivdiskette eingeben, damit Sie nicht aus
+Versehen auf eine falsche Archivdiskette schreiben. 
+    Auch hier können Sie die gewünschten Dateien ankreuzen (na­
+türlich bietet EUDAS dann die Dateien des Systems an). Sie brau­
+chen keine Angst zu haben, aus Versehen eine Datei mit gleichem
+Namen zu überschreiben - EUDAS fragt in solchen Fällen immer
+nochmal an. 
+ 
+___________________________________________________________________________________________ 
+ 
+      AUSWAHL:  Ankreuzen: 'x'  Durchstreichen: 'o'  Beenden: ESC q  Hilfe: ESC ? 
+      --------------:-------------------------------------------------------------- 
+      Dateien Archiv: Auswahl der Dateien auf dem Archiv. 
+      U Übersicht   : Gewuenschte Datei(en) bitte ankreuzen: 
+      D Üb. Drucken :-------------------------------------------------------------- 
+      --------------:     o  "eudas.1" 
+      Datei         :     o  "eudas.2" 
+      * Kopieren    :     o  "eudas.3" 
+        vom Archiv  :     o  "eudas.4" 
+      S Schreiben   :     o  "eudas.init" 
+        auf Archiv  :     o  "eudas.generator" 
+      L Löschen     :     o  "Adressen" 
+        auf Archiv  :-------------------------------------------------------------- 
+      --------------: 
+      Archivdiskette: 
+      I Init        : 
+      --------------: 
+      Z Zielarchiv  : 
+      P Paßwort     : 
+      - Reservieren : 
+      --------------: 
+                    : 
+                    : 
+      Akt.Datei:                    Ziel: "ARCHIVE"                Datum: 22.07.87 
+___________________________________________________________________________________________ 
+ 
+ 
+#center#Abb. 4-4   Dateiauswahl 
+ 
+ 
+ 
+4.4 Dateiverwaltung
+ 
+So: nach dieser anstrengenden Arbeit sollen Sie sich überzeugen,
+daß die Datei 'Adressen' nun wirklich im System zur Verfügung
+steht. Dazu gehen Sie mit LINKS ein Menü zurück. Dieses Menü
+beschäftigt sich mit Dateien im System und ist in Abb. 4-5 gezeigt. 
+    Auch hier finden Sie eine Funktion "Übersicht". Rufen Sie diese
+auf. Ganz analog zum Archiv erscheint eine Übersicht aller Dateien
+im Editor. Verlassen Sie die Übersicht wieder mit ESC 'q'. 
+ 
+___________________________________________________________________________________________ 
+ 
+      EUDAS:   Öffnen   Einzelsatz   Gesamtdatei   Drucken   Dateien   Archiv 
+      --------------: 
+      Dateien System: 
+      U Übersicht   : 
+      --------------: 
+      Datei         : 
+      L Löschen     : 
+      N Umbenennen  : 
+      K Kopieren    : 
+      P Platzbedarf : 
+      A Aufräumen   : 
+      --------------: 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+                    : 
+      Akt.Datei:                    Task: "arbeit"                 Datum: 22.07.87 
+___________________________________________________________________________________________ 
+ 
+ 
+#center#Abb. 4-5   Menü 'Dateien' 
+ 
+ 
+#on("b")#Datei löschen#off("b")# Eine weitere Funktion aus diesem Menü werden
+Sie ebenfalls noch öfter brauchen, nämlich 
+#free (0.2)# 
+ 
+        L Löschen 
+ 
+#free (0.2)# 
+Mit dieser Funktion können Sie eine Datei wieder aus dem System
+entfernen - zum Beispiel wenn Sie sich die Adressen angesehen
+haben und danach den Speicherplatz nicht weiter verschwenden
+wollen. Als letztes Beispiel sollen Sie auch diese Funktion aufrufen
+(keine Angst, wir löschen die Datei nicht wirklich, es gibt vorher
+noch eine Notbremse). 
+ 
+#on("b")#Fragezustand#off("b")# Als erstes werden Sie wieder nach dem
+Dateinamen
+gefragt (dies ist Ihnen schon bekannt). Hier haben Sie jetzt die
+Wahl, ob Sie den Namen eingeben oder mit ESC 'z' ankreuzen. Da das
+Löschen unwiederbringlich ist, werden Sie anschließend zur Sicher­
+heit gefragt, ob Sie die Datei wirklich löschen wollen: 
+ 
+___________________________________________________________________________________________ 
+ 
+      FRAGE:  Bejahen: j,J   Verneinen: n,N   Abbrechen: ESC h    Hilfe: ESC ? 
+      --------------:Dateiname: Adressen 
+      Dateien System:"Adressen" im System loeschen (j/n) ? 
+      U Übersicht   : 
+      --------------: 
+           ... 
+ 
+___________________________________________________________________________________________ 
+ 
+ 
+Diese Frage können Sie bejahen oder verneinen (oder die Funktion
+ohne Auswirkungen abbrechen). In diesem Fall sollten Sie die Frage
+verneinen - es sei denn, Ihnen hat das Spielen mit EUDAS so gut
+gefallen, daß Sie die ganze Prozedur wiederholen und die Datei
+nochmal vom Archiv holen wollen. 
+ 
+ 
+4.5 Bedienungsregeln
+ 
+Mit dieser letzten Demonstration haben Sie jetzt schon fast alle
+Arten des Umgangs mit EUDAS kennengelernt. Sicher ist dies beim
+ersten Mal sehr verwirrend. Mit vier Regeln können Sie jedoch
+EUDAS immer bedienen: 
+ 
+#limit (12.0)# 
+    1. Achten Sie darauf, welche möglichen Tastendrücke
+       in der Statuszeile stehen. Richten Sie sich danach! 
+#free (0.2)# 
+    2. Sind Sie sich unsicher, rufen Sie Hilfsfunktion mit
+       ESC '?' auf. Damit erhalten Sie weitere Informatio­
+       nen. 
+#free (0.2)# 
+    3. Funktioniert diese Tastenkombination nicht (geben
+       Sie dem Rechner eine kurze Zeit zum Reagieren),
+       versuchen Sie die Tastenkombinationen ESC 'h' (Ab­
+       bruch) oder ESC 'q' (Verlassen). Falls sich daraufhin
+       etwas verändert, fangen Sie wieder mit 1. an. 
+#free (0.2)# 
+    4. Erfolgt darauf keine Reaktion, drücken Sie die SV-
+       Taste und versuchen Sie das Programm mit 'halt' zu
+       stoppen. Führt auch das nicht zum Erfolg, hat sich
+       Ihr Rechner "aufgehängt". Sie müssen den Rechner
+       dann neu starten. Wenn Sie keine Erfahrung mit
+       einer solchen Situation haben, wenden Sie sich an
+       Ihren Händler oder Systembetreuer. 
+#limit (13.5)# 
+ 
+Im Zusammenhang mit dem letzten Punkt sei nochmal auf die Wich­
+tigkeit einer regelmäßigen Datensicherung auf Archivdisketten
+hingewiesen. Im Normalfall sollten Sie aber mit den Punkten 1 bis 3
+zurechtkommen. 
+ 
+#on("b")#Zustände#off("b")# Im letzten Abschnitt haben Sie eine ganze Reihe
+von
+Zuständen kennengelernt, die EUDAS einnehmen kann. In jedem
+Zustand haben Sie verschiedene Möglichkeiten zur Reaktion. Glück­
+licherweise erscheinen diese Möglichkeiten zum großen Teil in der
+Statuszeile. 
+    Damit Sie die verwirrenden Erfahrungen des letzten Abschnitts
+etwas ordnen können, wollen wir an dieser Stelle die verschiedenen
+Zustände noch einmal zusammenfassen. Der Beschreibung vorange­
+stellt ist die jeweilige Kennzeichnung am Beginn der Statuszeile. 
+ 
+EUDAS: #on("b")# Sie können mit ESC 'w' und ESC 'z' im Hilfstext blättern. Mit
+    ESC 'q' kommen Sie in den alten Zustand. 
+ 
+AUSWAHL: Hier können Sie die gewünschten Namen mit 'x' ankreuzen
+    und mit 'o' wieder entfernen. Normales Beenden mit ESC 'q'.
+    Hilfestellung durch ESC '?'. Abbruch der gesamten Funktion mit
+    ESC 'h'. 
+ 
+EINGABE: Hier können Sie eine einzelne Zeile eingeben oder ändern
+    (wie im Editor). Einfügen und Löschen mit RUBIN und RUBOUT.
+    Abbruch und Hilfestellung möglich. 
+ 
+FRAGE: Beantworten Sie die gestellte Frage mit 'j' oder 'n'. Abbruch
+    (ESC 'h') und Hilfestellung (ESC '?') möglich. 
+ 
+ZEIGEN: Mit HOP OBEN und HOP UNTEN können Sie in der Übersicht
+    blättern. Ende der Übersicht mit ESC 'q'. Hilfestellung möglich. 
+ 
+!!! FEHLER !!! Quittieren Sie die Meldung mit ESC 'q'. Hilfestellung
+    möglich. 
+ 
+Bitte warten.. In diesem Zustand keine Taste drücken, der Rechner
+    ist beschäftigt. 
+ 
+Drei weitere Zustände, die Sie noch nicht kennengelernt haben, sind
+hier schon mal der Vollständigkeit halber aufgeführt: 
+ 
+SATZ ÄNDERN: 
+SATZ EINFÜGEN: 
+SUCHMUSTER EINGEBEN: Satzeditor zum Eingeben von Feldinhalten.
+    Normales Verlassen mit ESC 'q'. Abbruch und Hilfestellung mög­
+    lich. Beschreibung s. 6.2. 
+ 
+EDITIEREN: EUMEL-Editor mit Änderungsmöglichkeit für beliebige
+    Texte. Normales Verlassen mit ESC 'q'. Hilfestellung möglich.
+    Beschreibung der Möglichkeiten siehe EUMEL-Benutzerhand­
+    buch. 
+ 
+Gib Kommando: Hier können Sie ein beliebiges ELAN-Kommando ein­
+    geben und mit RETURN bestätigen. Abbruch und Hilfestellung
+    möglich. Kann im Menü durch ESC ESC aufgerufen werden. 
+ 
+Wie Sie sehen, werden auch hier wieder die gleichen Tastenkombi­
+nationen verwendet, die Sie schon kennen. 
+    In dieser Übersicht sind jeweils nur die wichtigsten Tastenkom­
+binationen aufgeführt. Informieren Sie sich gegebenenfalls mit ESC
+'?'. Einige weitere Tastenfunktionen werden Sie im folgenden noch
+kennenlernen. Eine vollständige Übersicht finden Sie im Referenz­
+handbuch. 
+
diff --git a/doc/graphic/Altes Handbuch - Teil 10 - Graphik b/doc/graphic/Altes Handbuch - Teil 10 - Graphik
new file mode 100644
index 0000000..36fa31e
--- /dev/null
+++ b/doc/graphic/Altes Handbuch - Teil 10 - Graphik	
@@ -0,0 +1,831 @@
+#type ("trium10")##limit (13.5)# 
+#block##start(2.5,2.5)##pagelength(21.0)##pagenr("%",418)##setcount(22)# 
+#headeven# 
+%                       EUMEL-Benutzerhandbuch 
+ 
+ 
+ 
+#end# 
+#headodd# 
+                              TEIL 10: Graphik                       % 
+ 
+ 
+ 
+#end# 
+#type("triumb14")# 
+#ib(9)##center#TEIL 10: Graphik#ie(9)# 
+#type("trium10")# 
+#free(2.0)# 
+#on("bold")##ib(9)##type("triumb14")#1. Übersicht#ie(9)# 
+#type("trium10")# 
+ 
+       #limit(12.0)##on("italics")#Dieser Teil des Benutzer-Handbuchs beschreibt die Graphik-
+       Möglichkeiten des EUMEL-Systems. Die Graphik-Pakete ge­
+       hören nicht zum EUMEL-Standard, sondern sind Anwender­
+       pakete, die im Quellcode ausgeliefert und von jeder Installation
+       in das System aufgenommen werden können. Unter Umständen
+       müssen Programme erstellt werden, die die Anpassungen für
+       spezielle graphische Geräte einer Installation vornehmen. 
+#limit(13.5)##off("italics")# 
+ 
+Das Graphik-System ermöglicht es, durch ELAN-Programme geräteunab­
+hängige Informationen für Zeichnungen ("#ib#Graphiken#ie#") zu erstellen. Die Graphik
+erzeugenden Programme brauchen dabei keine gerätespezifischen Größen sowie
+gerätespezifischen Unterprogramme zu enthalten. Sie befassen sich somit
+ausschließlich mit der Erzeugung der problemorientierten Information für die
+Konstruktion einer Zeichnung. Nach der geräteunabhängigen Erzeugung einer
+Graphik kann diese auf unterschiedlichen Geräten ausgegeben werden (z.B. erst
+auf einem Terminal zur Kontrolle und dann auf einem Plotter). 
+ 
+Die EUMEL-Graphik umfaßt zwei- und dreidimensionale Graphik. Dabei
+entspricht die Y-Achse bei der zweidimensionalen Graphik der Z-Achse (Höhe)
+bei der dreidimensionalen Graphik. Im dreidimensionalen Fall sind perspektivi­
+sche, orthografische und schiefwinklige Projektionen mit beliebigen Betrach­
+tungswinkeln möglich. 
+ 
+Bei der EUMEL-Graphik wird streng zwischen Erzeugung und Manipulation von
+Graphiken (Bildern) auf der einen und Darstellung der erzeugten Bilder auf der
+anderen Seite unterschieden. Für die Erzeugung und Manipulation der Graphi­
+ken existiert der Typ PICTURE, für die Darstellung der Bilder gibt es den Typ
+PICFILE. Dabei müssen Ausschnitt, Maßstab, Betrachtungswinkel und Pro­
+jektionsart erst bei der Darstellung festgelegt werden. Diese Konstruktion des
+Graphik-Systems hat folgende Vorteile: 
+ 
+a) Programme, die Graphik-Informationen erzeugen, sind geräteunabhängig.
+   Das bedeutet, daß Programmierer sich ausschließlich mit einem logischen
+   Problem zu befassen brauchen und nicht mit gerätespezifischen Besonder­
+   heiten. 
+ 
+b) Graphiken können auf mehreren unterschiedlich gearteten Geräten mehrmals
+   dargestellt werden, ohne daß das erzeugende Programm geändert oder neu
+   gestartet werden muß. Z.B. kann ein Programmierer eine Graphik erst auf
+   dem Terminal auf Richtigkeit und Größenverhältnisse überprüfen, bevor er die
+   Zeichnung auf einem Plotter zeichnen läßt. 
+ 
+c) Graphiken können leicht geändert (z.B. vergrößert oder in eine Richtung
+   gestreckt) werden, ohne daß das erzeugende Programm erneut durchlaufen
+   werden muß. Zudem können Graphiken aneinander oder übereinander gelegt
+   werden. 
+ 
+d) Graphiken mit unterschiedlichen Farben, Strichen usw. können leicht erzeugt
+   werden. 
+ 
+e) Der Anschluß von neuen Graphik-Geräten durch Benutzer ist leicht möglich,
+   ohne daß die Graphik erzeugenden Programme modifiziert werden müssen. 
+ 
+f) Plotter können wie Drucker an einen SPOOLER gehängt werden. 
+ 
+g) Bilder können als PICFILEs gespeichert und versandt werden. 
+#free(2.0)# 
+#ib(9)##type("triumb14")#Erzeugung von Bildern#ie(9)# 
+#type("trium10")# 
+ 
+Bilder entstehen in Objekten vom Datentyp 
+ 
+#type("modern12")# 
+     PICTURE 
+#type("trium10")# 
+ 
+Diese müssen mit der Prozedur 
+ 
+#type("modern12")# 
+     nilpicture 
+#type("trium10")# 
+ 
+initialisiert werden. Sie enthalten dann ein leeres Bild, dessen Dimension noch
+nicht festgelegt ist. Die Dimension eines PICTUREs wird mit dem ersten
+Schreibzugriff ('move' oder 'draw') festgelegt. Ein PICTURE kann immer nur
+entweder zwei- oder dreidimensional sein. Außerdem kann einem PICTURE mit
+der Prozedur 
+ 
+#type("modern12")# 
+     pen 
+#type("trium10")# 
+ 
+genau ein virtueller Stift zugeordnet oder der aktuelle Stift erfragt werden. 
+ 
+Die Erzeugung eines Bildes basiert auf dem Modell eines Plotters. Der (virtuelle)
+Zeichenstift kann mit 
+ 
+#type("modern12")# 
+     move 
+#type("trium10")# 
+ 
+ohne zu zeichnen an beliebige Stellen gefahren werden (reine Positionierung).
+Mit 
+ 
+#type("modern12")# 
+     draw 
+#type("trium10")# 
+ 
+wird der Stift veranlaßt, eine Linie von der aktuellen zur angegebenen Zielposi­
+tion zu zeichnen. 'move' löst also Bewegungen mit gehobenem, 'draw' solche mit
+gesenktem Stift aus. Um auch 'relatives' Zeichnen zu ermöglichen, existiert die
+Prozedur 
+ 
+#type("modern12")# 
+     where 
+#type("trium10")# 
+ 
+die die aktuelle Stiftposition liefert. 
+#free(2.0)# 
+#ib(9)##type("triumb14")#Manipulation von Bildern#ie(9)# 
+#type("trium10")# 
+ 
+Erstellte Bilder können als Ganzes manipuliert werden. Die Prozeduren 
+ 
+#type("modern12")# 
+    translate            (* verschieben            *) 
+    stretch              (* strecken bzw. stauchen *) 
+    rotate               (* drehen                 *) 
+    reflect              (* spiegeln               *) 
+#type("trium10")# 
+ 
+verändern jeweils das ganze Bild. Es ist aber auch möglich, mehrere Bilder
+zusammenzufügen. Mit 
+ 
+#type("modern12")# 
+     CAT 
+#type("trium10")# 
+ 
+kann ein weiteres Bild angefügt werden. Dabei müssen allerdings beide
+PICTURE die gleiche Dimension haben. In solchen als ganzes manipulierten
+Bildern kann man ohne Einschränkung mit 'draw' und 'move' weiterzeichnen. 
+#free(2.0)# 
+#ib(9)##type("triumb14")#Darstellung#ie(9)# 
+#type("trium10")# 
+ 
+Für die Darstellung der erzeugten Bilder existiert der Typ 
+ 
+#type("modern12")# 
+     PICFILE 
+#type("trium10")# 
+ 
+Dieser besteht aus max. 128 PICTUREs, die mit den Prozeduren 
+ 
+#type("modern12")# 
+     put 
+     get 
+#type("trium10")# 
+ 
+eingegeben bzw. ausgegeben werden können. PICFILE wird durch Datenräume
+realisiert, deshalb erfolgt die Assoziation an einen benannten Datenraum ähnlich
+wie beim FILE. Dafür wird die Prozedur 
+ 
+#type("modern12")# 
+     picture file 
+#type("trium10")# 
+ 
+verwandt. Ein neuer PICFILE enthält genau ein leeres PICTURE. Die Darstellung
+der PICFILEs auf Zeichengeräten erfolgt mit der Prozedur 
+ 
+#type("modern12")# 
+     plot 
+#type("trium10")# 
+ 
+Da die Graphiken aber in "Weltkoordinaten" erzeugt werden und die spätere
+Darstellung vollkommen unbeachtet bleibt, müssen gewisse Darstellungspara­
+meter für die Zeichnung gesetzt werden. Diese Parameter werden im PICFILE
+abgelegt und gelten jeweils für den gesamten PICFILE. Dadurch ist es möglich,
+einen PICFILE mit spezifizierter Darstellungsart über einen SPOOLER an einen
+Plotter zu senden oder die bei der letzten Betrachtung gewählte Darstellung mit
+in dem PICFILE gespeichert zu halten. Für die Darstellung können den virtuellen
+Stiften mit der Prozedur 
+ 
+#type("modern12")# 
+     select pen 
+#type("trium10")# 
+ 
+reale Stifte zugeordnet werden. Voreingestellt ist für alle virtuellen Stifte:
+Standardfarbe, Standardstärke, durchgängige Linie. 
+ 
+Indem man einigen virtuellen Stiften den leeren Stift als realen Stift zuordnet,
+kann man einzelne PICTUREs ausblenden. Sowohl bei der Darstellung von
+zwei- als auch dreidimensionaler Graphik kann die gewählte Zeichenfläche auf
+dem Endgerät mit der Prozedur 
+ 
+#type("modern12")# 
+     viewport 
+#type("trium10")# 
+ 
+festgelegt werden. Voreingestellt ist das Quadrat mit der größtmöglichen Seiten­
+länge, d.h. der kürzeren Seite der hardwaremäßigen Zeichenfläche. 
+#free(2.0)# 
+#ib(9)##type("triumb14")#Darstellung zweidimensionaler Graphik#ie(9)# 
+#type("trium10")# 
+ 
+Bei der Darstellung zweidimensionaler Bilder muß der zu zeichnende Ausschnitt
+(das 'Fenster') angegeben werden. Mit der Prozedur 
+ 
+#type("modern12")# 
+     window 
+#type("trium10")# 
+ 
+wird durch Angabe der minimalen und maximalen X- bzw. Y-Koordinaten ein
+Fenster definiert. Da das so definierte Fenster auf die ganze (mit 'viewport'
+definierbare) Zeichenfläche abgebildet wird, ist der Abbildungsmaßstab durch das
+Zusammenspiel von 'viewport' und 'window' bestimmt. Da bei 'viewport' stan­
+dardmäßig das maximale Zeichenquadrat voreingestellt ist, wird in diesem Fall
+durch gleiche X- und Y-Fenstergröße eine winkeltreue Darstellung erreicht. 
+#free(2.0)# 
+#ib(9)##type("triumb14")#Darstellung dreidimensionaler Graphik#ie(9)# 
+#type("trium10")# 
+ 
+Im dreidimensionalen Fall wird das Fenster ebenfalls mit 
+ 
+#type("modern12")# 
+     window 
+#type("trium10")# 
+ 
+definiert, wobei dann allerdings auch der Bereich der dritten Dimension
+(Z-Koordinaten) zu berücksichtigen ist. Da die dreidimensionale Graphik auf
+eine zweidimensionale Fläche projiziert wird, können aber noch weitere Darstel­
+lungsparameter angegeben werden. Der Betrachtungswinkel wird mit Hilfe der
+Prozedur 
+ 
+#type("modern12")# 
+     view 
+#type("trium10")# 
+ 
+angegeben. Zur Spezifikation der gewünschten Projektionsart gibt es 
+ 
+#type("modern12")# 
+    orthographic          (* orthographische Projektion       *) 
+    perspective           (* perspektivische Projektion, 
+                             der Fluchtpunkt ist frei wählbar *) 
+    oblique               (* schiefwinklige Projektion        *) 
+#type("trium10")# 
+#free(2.0)# 
+#ib(9)##type("triumb14")#Beispiel (Sinuskurve)#ie(9)# 
+#type("modern12")# 
+ 
+  funktion zeichnen; 
+  bild darstellen  . 
+ 
+funktion zeichen : 
+  PICTURE VAR pic :: nilpicture; 
+  REAL VAR x := -pi; 
+  move (pic, x, sin (x)); 
+  REP x INCR 0.1; 
+      draw (pic, x, sin (x)) 
+  UNTIL x >= pi PER  . 
+ 
+bild darstellen : 
+  PICFILE VAR p :: picture file ("sinus"); 
+  window (p, -pi, pi, -1.0, 1.0); 
+  put (p, pic); 
+  plot (p)  . 
+#type("trium10")# 
+#free(2.0)# 
+#ib(9)##type("triumb14")#Beispiel (Würfel)#ie(9)# 
+#type("modern12")# 
+ 
+  wuerfel zeichen; 
+  wuerfel darstellen. 
+ 
+wuerfel zeichnen : 
+  zeichne vorderseite; 
+  zeichne rueckseite; 
+  zeichne verbindungskanten. 
+ 
+zeichne vorderseite : 
+  PICTURE VAR vorderseite :: nilpicture; 
+  move (vorderseite, 0.0, 0.0, 0.0); 
+  draw (vorderseite, 1.0, 0.0, 0.0); 
+  draw (vorderseite, 1.0, 0.0, 1.0); 
+  draw (vorderseite, 0.0, 0.0, 1.0); 
+  draw (vorderseite, 0.0, 0.0, 0.0). 
+ 
+zeichne rueckseite : 
+  PICTURE VAR rueckseite :: translate 
+                              (vorderseite, 0.0, 1.0, 0.0). 
+ 
+zeichne verbindungskanten : 
+  PICTURE VAR verbindungskanten :: nilpicture; 
+  move (verbindungskanten, 0.0, 0.0, 0.0); 
+  draw (verbindungskanten, 0.0, 1.0, 0.0); 
+ 
+  move (verbindungskanten, 1.0, 0.0, 0.0); 
+  draw (verbindungskanten, 1.0, 1.0, 0.0); 
+ 
+  move (verbindungskanten, 1.0, 0.0, 1.0); 
+  draw (verbindungskanten, 1.0, 1.0, 1.0); 
+ 
+  move (verbindungskanten, 0.0, 0.0, 1.0); 
+  draw (verbindungskanten, 0.0, 1.0, 1.0). 
+ 
+wuerfel darstellen : 
+  PICFILE VAR p := picture file ("wuerfel"); 
+  put (p, vorderseite); 
+  put (p, rueckseite); 
+  put (p, verbindungskanten); 
+  window (p, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0); 
+  view (p, 0.0, 40.0, 20.0); 
+  orthographic (p); 
+  plot (p). 
+#type("trium10")# 
+#free(2.0)# 
+#ib(9)##type("triumb14")#Beschreibung der Graphik-Prozeduren#ie(9)# 
+#type("trium10")# 
+ 
+       #limit(12.0)##on("italics")#Zweidimensionale PICTUREs brauchen weniger Speicherplatz
+       als dreidimensionale. Daher werden in einigen Fehlermeldun­
+       gen unterschiedliche Größen angegeben. 
+#limit(13.5)##off("italics")# 
+ 
+:= 
+    OP := (PICTURE VAR dest, PICTURE CONST source) 
+    Zweck: Zuweisung 
+ 
+    OP := (PICFILE VAR dest, DATASPACE CONST source) 
+    Zweck: Assoziiert die PICFILE Variable 'dest' mit der DATASPACE CONST
+           'source' und initialisiert die PICFILE Variable sofern nötig. 
+    Fehlerfall: 
+        * dataspace is no PICFILE 
+          Der anzukoppelnde Datenraum hat einen falschen Typ. 
+ 
+#ib#CAT#ie# 
+    OP CAT (PICTURE VAR dest, PICTURE CONST source) 
+    Zweck: Aneinanderfügen von zwei PICTURE's. 
+    Fehlerfälle: 
+        * OP CAT: left dimension <> right dimension 
+          Es können nur PICTUREs mit gleicher Dimension angefügt werden. 
+        * OP CAT: Picture overflow 
+          Die beiden PICTURE überschreiten die maximale Größe eines
+          Pictures. 
+ 
+#ib#act picture#ie# 
+    PICTURE PROC act picture (PICFILE VAR p) 
+    Zweck: Liefert das PICTURE des PICFILEs 'p', auf das mit 'backward' o.ä.
+           positioniert wurde. 
+ 
+#ib#backward#ie# 
+    PROC backward (PICFILE VAR p) 
+    Zweck: Positioniert den PICFILE 'p' um ein PICTURE zurück. 
+    Fehlerfall: 
+        * backward at begin of file 
+          Es wurde versucht vor den Anfang des PICFILEs zu positionieren. 
+ 
+#ib#draw#ie# 
+    PROC draw (PICTURE VAR pic, REAL CONST x, y) 
+    Zweck: Die Prozedur zeichnet in dem (zweidimensionalen) Bild 'pic' eine
+           Linie von der aktuellen Position zur Position (x, y). 
+    Fehlerfälle: 
+        * picture overflow 
+          Zu viele Befehle in einem PICTURE (z. Zeit max. 1927) 
+        * picture is three dimensional 
+          Ein PICTURE kann nur entweder zwei- oder dreidimensional sein. 
+ 
+    PROC draw (PICTURE VAR pic, REAL CONST x, y, z) 
+    Zweck: Die Prozedur zeichnet in dem (dreidimensionalen) Bild 'pic' eine
+           gerade Linie von der aktuellen Position zur Position (x, y, z). 
+    Fehlerfälle: 
+        * picture overflow 
+          Zu viele Befehle in einem PICTURE (z. Zeit max. 1310) 
+        * picture is only two dimensional 
+          Ein PICTURE kann nur entweder zwei- oder dreidimensional sein. 
+ 
+    PROC draw (PICTURE VAR pic, TEXT CONST text) 
+    Zweck: Der angegebene Text wird in das Bild 'pic' eingetragen. Der Anfang
+           ist dabei die aktuelle Stiftposition. Diese wird nicht verändert. 
+    Fehlerfall: 
+        * picture overflow 
+          Der Text paßt nicht mehr in das PICTURE. 
+ 
+    PROC draw (PICTURE VAR pic, TEXT CONST text, 
+               REAL CONST angle, height) 
+    Zweck: Der angegebene Text wird unter dem Winkel 'angle' gegenüber der
+           Waagerechten und in der Größe 'height' in das PICTURE 'pic'
+           eingetragen. Der Anfang ist dabei die aktuelle Stiftposition. Diese
+           wird nicht verändert. 
+    Fehlerfall: 
+        * picture overflow 
+          Der Text paßt nicht mehr in das PICTURE. 
+ 
+    PROC draw (PICFILE VAR pic, REAL CONST x, y) 
+    Zweck: Die Prozedur zeichnet in dem aktuellen (zweidimensionalen)
+           PICTURE des PICFILEs 'p' eine gerade Linie. Der (virtuelle) Stift wird
+           von der aktuellen Position zur Position (x, y) gefahren. Falls das
+           aktuelle PICTURE zu voll ist, wird automatisch auf das nächste
+           umgeschaltet. 
+    Fehlerfälle: 
+        * picfile overflow 
+          Das letzte PICTURE ist voll (z. Zeit max. 128 PICTURE) 
+        * picture is threedimensional 
+          Das aktuelle PICTURE ist dreidimensional. 
+ 
+    PROC draw (PICTFILE VAR pic, REAL CONST x, y, z) 
+    Zweck: s. o. 
+    Fehlerfälle: 
+        * picfile overflow 
+          Das letzte PICTURE ist voll (z. Zeit max. 128) 
+        * picfile is only twodimensional 
+          Das aktuelle PICTURE ist zweidimensional. 
+ 
+    PROC draw (PICTFILE VAR pic, TEXT CONST text) 
+    Zweck: Der angegebene Text wird in das aktuelle PICTURE des PICFILEs 'p'
+           eingetragen. Falls das aktuelle PICTURE zu voll ist, wird automatisch
+           auf das nächste umgeschaltet. Der Anfang ist dabei die aktuelle
+           Stiftposition. Diese wird nicht verändert. 
+    Fehlerfall: 
+        * picfile overflow 
+          Das letzte PICTURE ist voll (z. Zeit max. 128) 
+ 
+    PROC draw (PICFILE VAR pic, TEXT CONST text, 
+               REAL CONST angle, height) 
+    Zweck: Der angegebene Text wird unter dem Winkel 'angle' gegenüber der
+           Waagerechten und in der Größe 'height' in das aktuelle PICTURE
+           des PICFILES 'p' eingetragen. Falls das aktuelle PICTURE zu voll ist,
+           wird automatisch auf das nächste umgeschaltet. Der Anfang ist
+           dabei die aktuelle Stiftposition. Diese wird nicht verändert. 
+    Fehlerfall: 
+        * picfile overflow 
+          Das letzte PICTURE ist voll (z. Zeit max. 128) 
+ 
+#ib#eof#ie# 
+    BOOL PROC eof (PICFILE CONST p) 
+    Zweck: Liefert 'TRUE' wenn hinter das Ende des PICFILEs positioniert
+           wurde. 
+ 
+#ib#extrema#ie# 
+    PROC extrema (PICTURE CONST p, 
+                  REAL VAR x min, x max, y min, y max) 
+    Zweck: Die Prozedur liefert die größten und kleinsten X- und Y-Koordi­
+           naten des PICTUREs 'p'. Diese werden in die Parameter 'x min', 'x
+           max', 'y min' und 'y max' eingetragen. 
+ 
+    PROC extrema (PICTURE CONST p, 
+                  REAL VAR x min, x max, y min, y max, z min, z max) 
+    Zweck: s.o. 
+ 
+    PROC extrema (PICFILE VAR p, REAL VAR x min, x max, y min, y max) 
+    Zweck: s.o. 
+ 
+    PROC extrema (PICFILE VAR p, 
+                  REAL VAR x min, x max, y min, y max, z min, z max) 
+    Zweck: s.o. 
+ 
+#ib#forward#ie# 
+    PROC forward (PICFILE VAR p) 
+    Zweck: Positioniert den PICFILE um ein PICTURE weiter. 
+    Fehlerfall: 
+        * picfile overflow 
+          Es sollte hinter das Ende des PICFILEs positioniert werden. 
+ 
+#ib#get#ie# 
+    PROC get (PICFILE VAR p, PICTURE VAR pic) 
+    Zweck: Liest ein PICTURE aus einem PICFILE und positioniert auf das
+           Nächste. 
+    Fehlerfall: 
+        * input after end of picfile 
+          Es sollte nach dem Ende des Picfiles gelesen werden. 
+ 
+#ib#move#ie# 
+    PROC move (PICTURE VAR pic, REAL CONST x, y) 
+    Zweck: Der (virtuelle) Stift wird zur Position (x, y) gefahren. 
+    Fehlerfälle: 
+        * picture overflow 
+          Zu viele Befehle in einem PICTURE (z. Zeit max. 1927 'moves') 
+        * picture is three dimensional 
+          Ein PICTURE kann nur entweder zwei- oder dreidimensional sein. 
+ 
+    PROC move (PICTURE VAR pic, REAL CONST x, y, z) 
+    Zweck: Der (virtuelle) Stift wird zur Position (x, y, z) gefahren. 
+    Fehlerfälle: 
+        * picture overflow 
+          Zu viele Befehle in einem PICTURE (z. Zeit max. 1310) 
+        * picture is only twodimensional 
+          Ein PICTURE kann nur entweder zwei- oder dreidimensional sein. 
+ 
+    PROC move (PICFILE VAR p, REAL CONST x, y) 
+    Zweck: Der (virtuelle) Stift wird zur Position (x, y) gefahren. Falls das aktuelle
+           PICTURE des PICFILEs 'p' zu voll ist, wird automatisch auf das
+           nächste umgeschaltet. 
+    Fehlerfall: 
+        * picfile overflow 
+          Das letzte PICTURE ist voll (z. Zeit max. 128 PICTUREs) 
+ 
+    PROC move (PICFILE VAR p, REAL CONST x, y, z) 
+    Zweck: Der (virtuelle) Stift wird zur Position (x, y, z) gefahren. Falls das
+           aktuelle PICTURE des PICFILEs 'p' zu voll ist, wird automatisch auf
+           das nächste umgeschaltet. 
+    Fehlerfall: 
+        * picfile overflow 
+          Das letzte PICTURE ist voll (z. Zeit max. 128 PICTUREs) 
+ 
+#ib#nilpicture#ie# 
+    PICTURE PROC nilpicture 
+    Zweck: Die Prozedure liefert ein leeres PICTURE zur Initialisierung. 
+ 
+#ib#oblique#ie# 
+    PROC oblique (PICFILE VAR p, REAL CONST a, b) 
+    Zweck: Bei dem (dreidimensionalen!) Bild 'p' wird 'schiefwinklig' als
+           gewünschte Projektionsart eingestellt. Dabei ist (a, b) der Punkt in
+           der X-Y-Ebene, auf den der Einheitsvector in Z-Richtung
+           abgebildet werden soll. 
+ 
+#ib#orthographic#ie# 
+    PROC orthographic (PICFILE VAR p) 
+    Zweck: Bei dem (dreidimensionalen!) Bild 'p' wird "orthografisch" als Pro­
+           jektionsart eingestellt. Bei der orthografischen Projektion wird ein
+           dreidimensionaler Körper mit parallelen Strahlen senkrecht auf die
+           Projektionsebene abgebildet. 
+ 
+#ib#pen#ie# 
+    INT PROC pen (PICTURE CONST pic) 
+    Zweck: Liefert die Nummer des 'virtuellen Stifts'. 
+ 
+    PICTURE PROC pen (PICTURE CONST pic, INT CONST pen) 
+    Zweck: Liefert ein PICTURE mit dem Inhalt 'pic' und dem 'virtuellen Stift' mit
+           der Nummer 'pen'. Möglich sind die Nummern 1 - 16. 
+    Fehlerfälle: 
+        * PROC pen: pen [No] < 1 
+          Der gewünschte Stift ist kleiner als 1. 
+        * PROC pen: pen [No] > 16 
+          Der gewünschte Stift ist größer als 16. 
+ 
+#ib#perspective#ie# 
+    PROC perspective (PICFILE VAR p, REAL CONST cx, cy, cz) 
+    Zweck: Bei den dreidimensionalen PICTUREs des PICFILE's 'p' wird
+           "perspektivisch" als gewünschte Projektionsart eingestellt. Der Punkt
+           (cx, cy, cz) ist der Fluchtpunkt der Projektion, d.h. alle Parallelen zur
+           Blickrichtung schneiden sich in diesem Punkt. 
+ 
+#ib#pic no#ie# 
+    INT PROC pic no (PICFILE CONST p) 
+    Zweck: Liefert die Nummer des aktuellen PICTUREs. 
+ 
+#ib#picture file#ie# 
+    DATASPACE PROC picture file (TEXT CONST name) 
+    Zweck: Die Prozedur dient zur Assoziation eines benannten Datenraumes mit
+           einem PICFILE (s. Operator ':='). 
+ 
+#ib#plot#ie# 
+    PROC plot (TEXT CONST name) 
+    Zweck: Der PICFILE mit dem Namen 'name' wird entspechend der angege­
+           benen Darstellungsart gezeichnet. Diese Parameter ('perspective',
+           'orthographic', 'oblique', 'view', 'window' etc.) müssen vorher
+           eingestellt werden. 
+    Fehlerfall: 
+        * FILE does not exist 
+          Es existiert kein PICFILE mit dem Namen 'name' 
+ 
+    PROC plot (PICFILE VAR p) 
+    Zweck: Der PICFILE 'p' wird entspechend der angegebenen Darstellungsart
+           gezeichnet. Diese Parameter müssen vorher eingestellt werden. 
+ 
+           #on("bold")#Zweidimensional: 
+#off("bold")# 
+           obligat:      'window'     (zweidimensional) 
+           optional:     'view'       (zweidimensional) 
+                         'select pen' 
+                         'viewport' 
+ 
+           #on("bold")#Dreidimensional: 
+#off("bold")# 
+           obligat:      'window'     (dreidimensional) 
+           optional:     'view'       (dreidimensional) 
+                         'orthographic', 'perspective', 'oblique' 
+                         'viewport' 
+                         'select pen' 
+ 
+#ib#put#ie# 
+    PROC put (PICFILE VAR p, PICTURE CONST pic) 
+    Zweck: Schreibt ein PICTURE in einen PICFILE und positioniert um eins
+           vor. 
+    Fehlerfall: 
+        * picfile overflow 
+          Der PICFILE ist voll. (z. Z. max. 128 PICTURE) 
+ 
+#ib#reset#ie# 
+    PROC reset (PICFILE VAR p) 
+    Zweck: Positioniert auf den Anfang eines Picfiles. 
+ 
+#ib#rotate#ie# 
+    PICTURE PROC rotate (PICTURE CONST pic, REAL CONST alpha) 
+    Zweck: Das PICTURE 'pic' wird um den Punkt (0, 0) um den Winkel 'alpha'
+           (im Gradmaß) im mathematisch positiven Sinn gedreht. 
+ 
+    PICTURE PROC rotate (PICTURE CONST pic, 
+                         REAL CONST alpha, beta, gamma) 
+    Zweck: Das dreidimensionale PICTURE 'pic' wird um den Winkel 'alpha',
+           'beta' oder 'gamma' im mathematisch positiven Sinn gedreht. Der
+           Winkel 'alpha' dreht um die X-Achse, der Winkel 'beta' um die
+           Y-Achse und 'gamma' um die Z-Achse. Es darf dabei nur jeweils
+           ein Winkel von 0.0 verschieden sein. Alle Winkel werden im
+           Gradmaß angegeben. 
+ 
+#ib#select pen#ie# 
+    PROC select pen (PICFILE VAR p, 
+                     INT CONST pen, colour, thickness, linetype) 
+    Zweck: Für die Darstellung des Bildes 'p' soll dem "virtuellen Stift" 'pen' ein
+           realer Stift zugeordnet werden, der möglichst die Farbe 'colour' und
+           die Dicke 'thickness' hat und dabei Linien mit dem Typ 'line type'
+           zeichnet. Es wird die beste Annäherung für das Ausgabegerät für
+           diese Parameter genommen. Dabei gelten folgende Vereinbarun­
+           gen: 
+ 
+           Farbe: negative Farben setzten den Hintergrund, positive Farben
+                  zeichnen im Vordergrund. 
+ 
+                    0   Löschstift (falls vorhanden) 
+                    1   Standardfarbe des Endgeräts (schwarz oder weiß) 
+                    2   rot 
+                    3   blau 
+                    4   grün 
+                    5   schwarz 
+                    6   weiß > 20   nicht normierte Sonderfarben 
+ 
+           Dicke: 0 
+                  Standardstrichstärke des Endgerätes > 0 
+                  Strichstärke in 1/10 mm 
+ 
+           Typ: 
+                    0   keine sichtbare Linie 
+                    1   durchgängige Linie 
+                    2   gepunktete Linie 
+                    3   kurz gestrichelte Linie 
+                    4   lang gestrichelte Linie 
+                    5   Strichpunktlinie 
+ 
+           Die hier aufgeführten Möglichkeiten müssen nicht an allen grafischen
+           Endgeräten vorhanden sein. Der geräteabhängige Graphik-Treiber
+           wählt jeweils die für ihn bestmögliche Annäherung. 
+ 
+    Fehlerfälle: 
+        * pen < 1 
+        * pen > 16 
+ 
+#ib#size#ie# 
+    INT PROC size (PICFILE CONST p) 
+    Zweck: Liefert die aktuelle Größe eines PICFILEs in Bytes. 
+ 
+#ib#stretch#ie# 
+    PICTURE PROC stretch (PICTURE CONST pic, REAL CONST xc, yc) 
+    Zweck: Das PICTURE 'pic' wird in X-Richtung um den Faktor 'xc', in
+           Y-Richtung um den Faktor 'yc' gestreckt (bzw. gestaucht). Dabei
+           bewirkt der Faktor 
+                   c > 1     eine Streckung 
+               0 < c < 1     eine Stauchung 
+                   c < 0     zusätzlich eine Achsenspiegelung 
+ 
+    PICTURE PROC stretch (PICTURE CONST pic, REAL CONST xc, yc, zc) 
+    Zweck: Das dreidimensionale PICTURE 'pic' wird entsprechend den
+           angegeben Faktoren 'xc', 'yc' und 'zc' gestreckt. Wirkung s.o. 
+ 
+#ib#translate#ie# 
+    PICTURE PROC translate (PICTURE CONST pic, REAL CONST dx, dy) 
+    Zweck: Das PICTURE 'pic' wird um 'dx' und 'dy' verschoben. 
+    Fehlerfall: 
+        * picture is threedimensional 
+          'pic' ist dreidimensional. 
+ 
+    PICTURE PROC translate (PICTURE CONST pic, REAL CONST dx, dy, dz) 
+    Zweck: Das PICTURE 'pic' wird um 'dx', 'dy' und 'dz' verschoben. 
+    Fehlerfall: 
+        * picture is twodimensional 
+          Das PICTURE 'pic' ist zweidimensional 
+ 
+#ib#two dimensional#ie# 
+    PROC two dimensional (PICFILE VAR p) 
+    Zweck: Setzt als Projektionsart zweidimensional. 
+ 
+#ib#view#ie# 
+    PROC view (PICFILE VAR p, REAL CONST alpha, phi, theta) 
+    Zweck: Dreidimensionale Bilder werden häufig nicht direkt von vorne
+           dargestellt, sondern für die Betrachtung gedreht. Mit der Prozedur
+           'view' kann diese Betrachtungsrichtung durch die Polarwinkel 'phi'
+           und 'theta' angegeben werden. Mit dem Winkel 'alpha' kann dann
+           das Bild um den Mittelpunkt der Zeichenfläche gedreht werden.
+           Dadurch kann ein Bild auch auf einem Terminal hochkant gestellt
+           werden. Voreingestellt ist 'phi = 0, theta = 0 und alpha = 0', d.h.
+           direkt von oben. 
+ 
+           Im Gegensatz zu 'rotate' hat 'view' keine Wirkung auf das eigentli­
+           che Bild (PICFILE), sondern nur auf die gewählte Darstellung. So
+           addieren sich zwar aufeinanderfolgende "Rotationen", 'view' aber
+           geht immer von der Nullstellung aus. Auch kann das Bild durch eine
+           "Rotation" ganz oder teilweise aus oder in das Darstellungsfenster
+           ('window') gedreht werden. Bei 'view' verändern sich die Koordina­
+           ten der Punkte nicht, d.h. das Fenster wird mitgedreht. 
+ 
+#ib#viewport#ie# 
+    PROC viewport (PICFILE VAR p, 
+                   REAL CONST hormin, hormax, vertmin, vertmax) 
+    Zweck: Die Zeichenfläche auf dem Endgerät, auf dem das Bild dargestellt
+           werden soll, wird spezifiziert. Dabei wird sowohl die Größe als auch
+           die relative Lage der Zeichenfläche definiert. Der linke untere
+           Eckpunkt der physikalischen Zeichenfläche des Gerätes hat die
+           Koordinaten (0.0, 0.0). Die definierte Zeichenfläche erstreckt sich 
+ 
+#type("modern12")# 
+                'hormin'  - 'hormax'     in der Horizontalen, 
+                'vertmin' - 'vertmax'    in der Vertikalen. 
+#type("trium10")# 
+ 
+           So liegt der linke untere Eckpunkt dann bei (hormin, vertmin), der
+           rechte obere bei (hormax, vertmax). 
+ 
+           Damit sowohl geräteunabhängige als auch maßstabsgerechte
+           Zeichnungen möglich sind, können die Koordinaten in zwei Arten
+           spezifiziert werden : 
+ 
+           a) Gerätekoordinaten 
+              Die Koordinaten können Werte von 0.0 bis 2.0 annehmen. Dabei
+              hat die kürzere Seite der physikalischen Zeichenfläche defini­
+              tionsgemäß die Länge 1.0. 
+ 
+           b) absolute Koordinaten 
+              Die Werte werden in cm angegeben. Für die Maximalwerte sind
+              nur Werte größer als 2.0 möglich. 
+ 
+           Voreingestellt ist 
+ 
+#type("modern12")# 
+                viewport (0.0, 1.0, 0.0, 1.0), 
+#type("trium10")# 
+ 
+           d.h. das größtmöglichste Quadrat, beginnend in der linken unteren
+           Ecke der physikalischen Zeichenfläche. In vielen Fällen wird diese
+           Einstellung ausreichen, so daß der Anwender kein eigenes 'viewport'
+           definieren muß. 
+ 
+           Der Abbildungsmaßstab wird durch das Zusammenspiel von 'view­
+           port' und 'window' festgelegt (siehe dort). Dabei ist insbesondere
+           darauf zu achten, daß winkeltreue Darstellungen nur bei gleichem
+           X- und Y-Maßstab möglich sind. Da man oft quadratische Fenster
+           ('window') verwendet, wurde als Standardfall auch ein quadratisches
+           'viewport' gewählt. 
+ 
+#ib#where#ie# 
+    PROC where (PICTURE CONST pic, REAL VAR x, y) 
+    Zweck: Die aktuelle Stiftposition wird in 'x' und 'y' eingetragen. 
+    Fehlerfall: 
+        * picture is threedimensional 
+          Das PICTURE 'pic' ist dreidimensional 
+ 
+    PROC where (PICTURE CONST pic, REAL VAR x, y, z) 
+    Zweck: Die aktuelle Stiftposition wird in 'x', 'y' und 'z' eingetragen. 
+    Fehlerfall: 
+        * picture is twodimensional 
+          Das PICTURE 'pic' ist zweidimensional 
+ 
+#ib#window#ie# 
+    PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max) 
+    Zweck: Für die Darstellung eines zweidimensionalen Bildes wird das
+           darzustellende Fenster definiert. Alle Bildpunkte, deren X-Koordi­
+           naten im Intervall [x min, x max] und deren Y-Koordinaten im
+           Intervall [y min, y max] liegen, gehören zum definierten Fenster.
+           Vektoren, die über dieses Fenster hinausgehen, werden abge­
+           schnitten. Dieses Fenster wird auf die spezifizierte Zeichenfläche
+           abgebildet. (Das ist standardmäßig das größtmögliche Quadrat auf
+           dem ausgewählten Gerät). 
+ 
+           Der Darstellungsmaßstab ergibt sich als 
+ 
+#type("modern12")# 
+                                x max - x min 
+                  ----------------------------------------- 
+                  horizontale Seitenlänge der Zeichenfläche 
+ 
+                                y max - y min 
+                  ----------------------------------------- 
+                   vertikale Seitenlänge der Zeichenfläche 
+#type("trium10")# 
+ 
+            Für eine winkeltreue Darstellung müssen X- und Y-Maßstab
+            gleich sein! Einfach können winkeltreue Darstellung erreicht
+            werden, wenn das Fenster eine quadratische Form hat. Die
+            Zeichenfläche ('viewport') ist dementsprechend als Quadrat vorein­
+            gestellt. 
+ 
+    PROC window (PICFILE VAR p, 
+                 REAL CONST x min, x max, y min, y max, z min, z max) 
+    Zweck: Für die Darstellung eines dreidimensionalen Bildes wird das darzu­
+           stellende Fenster definiert. Alle Bildpunkte, deren X-Koordinaten im
+           Intervall [x min, x max] und deren Y-Koordinaten im Intervall [y min,
+           y max] und deren Z-Koordinaten im Intervall [z min, z max] liegen,
+           gehören zum definierten Fenster. Dieses dreidimensionale Fenster
+           (Quader) wird entsprechend der eingestellten Projektionsart (ortho­
+           grafisch, perspektivisch oder schiefwinklig) und den Betrachtungs­
+           winkeln (s. 'view') auf die spezifizierte Zeichenfläche abgebildet. (Das
+           ist standardmäßig das größtmögliche Quadrat auf dem ausgewählten
+           Gerät.) Linien, die außerhalb dieses Quadrates liegen, werden
+           abgeschnitten. 
+ 
+           Anders als im zweidimensionalen Fall ist das Problem der Maßstäbe
+           nicht mehr nur durch das Zusammenspiel von 'window' und 'view­
+           port' zu beschreiben. Hier spielen auch Projektionsart und Dar­
+           stellungswinkel eine Rolle. Falls alle Darstellungswinkel den Wert 0.0
+           haben, gilt das für den zweidimensionalen Fall gesagte für die Ebene
+           (y = 0.0) entsprechend. 
+ 
+#ib#write is possible#ie# 
+    BOOL PROC write is possible (PICTURE CONST pic, INT CONST space) 
+    Zweck: Liefert 'TRUE', falls 'space' Bytes Platz in 'pic' vorhanden ist. 
+ 
+ 
+ 
+ 
+ 
+
diff --git a/doc/graphic/GRAPHIK.book b/doc/graphic/GRAPHIK.book
new file mode 100644
index 0000000..435d9e4
--- /dev/null
+++ b/doc/graphic/GRAPHIK.book
@@ -0,0 +1,897 @@
+#type ("times8")##limit (11.0)##start (2.2, 1.5)##pagelength (17.4)##block# 
+ 
+#head# 
+#type ("triumb14")# 
+#center#EUMEL-Grafik-System 
+ 
+#type ("times8")# 
+#end# 
+#type ("triumb14")# Teil 10: Graphik#type ("times8")# 
+ 
+ 
+#type ("trium12")# 
+#on("b")#1. Übersicht#off("b")# 
+#type ("times8")# 
+ 
+#limit (7.0)##type("times6")# 
+            #on("i")#Dieser Teil des Benutzer-Handbuchs beschreibt die Graphik-
+            Fähigkeiten des EUMEL-Systems. Die Graphik-Pakete gehö­
+            ren nicht zum Eumel-Standard, sondern sind Anwenderpake­
+            te, die im Quellcode ausgeliefert und von jeder Installation in das
+            System aufgenommen werden können. #off("i")# 
+#limit (11.0)# 
+#foot#
+    Eventuell müssen Programme erstellt werden, die die Anpassungen für spezielle graphische Geräte einer Installation
+    vornehmen, soweit diese nicht von den EUMEL-Anbietern bezogen werden können. 
+#end# 
+ 
+#type("times8")# 
+    Das #on("b")#Graphik-System#off("b")# ermöglicht es, durch ELAN-Programme geräteunabhängige Infor­
+    mationen für Zeichnungen (#on("i")#Graphiken#off("i")#) zu erstellen. Die Graphik erzeugenden Programme
+    brauchen dabei keine geräteabhängigen Größen oder Unterprogramme zu enthalten. Sie
+    befassen sich somit ausschließlich mit der Erzeugung der problemorientierten Information
+    für die Konstruktion einer Zeichnung. Nach der geräteunabhängigen Erzeugung einer
+    Graphik kann diese auf unterschiedlichen Geräten ausgegeben werden (z.B. erst auf einem
+    Terminal zur Kontrolle und dann auf einem Plotter). 
+ 
+    Die EUMEL-Graphik umfaßt zwei- und dreidimensionale Graphik. Im dreidimensiona­
+    len Fall sind perspektivische, orthografische und schiefwinklige Projektionen mit beliebi­
+    gen Betrachtungswinkeln möglich. 
+ 
+    Bei der EUMEL-Graphik wird streng zwischen Erzeugung und Manipulation von Gra­
+    phiken auf der einen und der Darstellung der erzeugten Bilder auf der anderen Seite
+    unterschieden. Für die Erzeugung und Manipulation der Graphiken wird von den Paketen
+    #on("i")#picture#off("i")# und #on("i")#picfile#off("i")# der Datentype #on("b")#PICTURE#off("b")# bzw. #on("b")#PICFILE#off("b")# zur Verfügung gestellt. Dabei
+    müssen Ausschnitt, Maßstab, Betrachtungswinkel und Projektionsart erst bei der Darstel­
+    lung festgelegt werden. Diese Konstruktion des Graphik-Systems hat folgende Vorteile: 
+ 
+    a)  Programme, die Graphik-Information erzeugen, sind geräteunabhängig. Das bedeu­
+        tet, das der Programmierer sich ausschließlich mit einem logischen Problem befassen
+        muß und nicht mit gerätespezifischen Besonderheiten. 
+ 
+    b)  Graphiken können auf mehreren unterschiedlich gearteten Geräten mehrmals darge­
+        stellt werden, ohne daß das erzeugende Programm geändert oder neu gestartet werden
+        muß. Z.B. kann ein Programmierer eine Graphik erst auf dem Terminal überprüfen,
+        bevor er die Graphik auf einem Plotter zeichnen läßt. 
+ 
+    c)  Graphiken können leicht geändert (z. B. vergrößert oder in eine Richtung gestreckt
+        o.ä.) werden, ohne daß sie erneut erzeugt werden müssen. Zudem können Graphiken
+        aneinander oder übereinander gelegt werden. 
+ 
+    d)  Graphiken mit unterschiedlichen Farben, Strichen usw. können leicht erzeugt werden. 
+ 
+    e)  Der Anschluß von neuen Graphik.Geräten durch Benutzer ist leicht möglich, ohe daß
+        die Graphik-Programme geändert werden müssen. 
+ 
+    f)  Plotter können wie Drucker an einen Spooler gehängt werden. 
+ 
+    g)  Bilder können als PICFILEs gespeichert und versandt werden. 
+ 
+    h)  Es können auch auf Systemen ohne graphische Ausgabegeräte Graphiken erzeugt
+        werden. 
+ 
+    i)  Es können mit einfachen Mitteln universelle Unterprogrammpakete erstellt werden,
+        um die Standardzeichnungen (Darstellen einer Funktion, Balken oder Liniendiagram­
+        me, Achsen etc.) zu erstellen. 
+ 
+ 
+#type ("trium12")# 
+#on("b")#2. Erzeugung von Bildern#off("b")# 
+#type ("times8")# 
+ 
+    Bilder entstehen in Objektion vom Datentyp #on("b")#PICTURE#off("b")#. Diese müssen mit der Prozedur
+    #on("i")#nilpicture#off("i")# initialisiert werden. Sie enthalten dann ein leeres Bild, dessen Dimension noch
+    nicht festgelegt ist. Die Dimension eines #on("i")#PICTURE#off("i")#s wird mit dem ersten Schreibzugriff
+    (#on("i")#move, draw#off("i")# o.ä.) festgelegt. Ein #on("i")#PICTURE#off("i")# kann immer nur entweder zwei- oder
+    dreidimensional sein. 
+    Außerdem kann einem #on("i")#PICTURE#off("i")# mit der Prozedur #on("i")#pen#off("i")# genau ein virtueller Stift zugeord­
+    net oder der aktuelle Stift erfragt werden (Standardeinstellung: 1). 
+ 
+    Für Erzeugung eines Bildes wird ein virtueller Zeichenstift benutzt, dem bei der Darstel­
+    lung jeweils genau ein realer Stift zugeordnet wird. Dieser Stift kann mit der Prozedur
+    #on("b")#move#off("b")# oder #on("b")#move r #off("b")#auf eine bestimmte Stelle positioniert werden ohne zu zeichnen. Mit
+    #on("b")#draw#off("b")# oder #on("b")#draw r#off("b")# wird eine Linie von der letzten Position zur angegebene Position
+    gezeichnet. Die aktuelle Stiftposition kann dabei mit #on("b")#where#off("b")# abgefragt werden. 
+    Außerdem existiert noch die Prozedur #on("b")#draw#off("b")# die einen Text zur Beschriftung der Zeich­
+    nung darstellt, sowie #on("b")#bar#off("b")# zum Zeichnen eines Balkens für Balkendiagramme, #on("b")#circle#off("b")# zum
+    Zeichnen eines Kreisbogens für Kreisdiagramme und #on("b")#mark#off("b")# zum Markiern von Positionen.
+    Dabei wird die aktuelle Stiftposition aber nicht verändert. 
+ 
+#type ("trium12")# 
+#on("b")#3. Manipulation von PICTUREs#off("b")# 
+#type ("times8")# 
+ 
+    Erstellte PICTUREs können auch als Ganzes manipuliert werde. Dazu dienen die Prozedu­
+    ren #on("b")#translate, stretch#off("b")# und #on("b")#rotate#off("b")#. Es ist auch möglich mehrere PICTURE mit dem Opera­
+    tor #on("b")#CAT#off("b")# aneinanderzufügen, wenn beide PICTURE die gleiche Dimension haben. In
+    solcherart manipulierten Bildern kann ohne Einschränkung weitergezeichnet werden,
+    solange die maximale Größe nicht überschritten wird. 
+ 
+#type ("trium12")# 
+#on("b")#4. Darstellung und Speicherung #off("b")# 
+#type ("times8")# 
+ 
+    Für die Darstellung und Speicherung der erzeugten Bilder existiert der Typ #on("b")#PICFILE#off("b")#.
+    Dieser besteht aus eienm Datenraum mit max. 1024 PICTUREs, die mit den Prozeduren #on("b")#
+    delete picture, insert picture, read picture, write picture, get picture#off("b")# und #on("b")#put picture#off("b")# einge­
+    geben bzw. ausgegeben werden können. 
+    Für die Positionierung innerhalb eines PICFILES stehen die Prozeduren #on("b")#to pic, up, down,
+    eof, picture no, pictures#off("b")# zur Verfügung. 
+    Für die Assoziation mit einem benannten Datenraum existiert ähnlich wie beim Datentyp
+    FILE die Prozedur #on("b")#picture file#off("b")#; unbenannte Datenräume können mit dem Operator #on("b")#:=#off("b")#
+    assoziert werden. 
+    Die Darstellung des PICFILES auf einem Zeichengerät erfolgt mit der Prozdur #on("b")#plot#off("b")#. 
+    Da die Graphiken aber in #on("i")#Weltkoordinaten#off("i")# erzeugt werden und die spätere Darstellung
+    vollkommen unbeachtet bleibt, müssen gewisse Darstellungsparameter für die Zeichnung
+    gesetzt werden. Dies Parameter werden im PICFILE abgelegt und gelten jeweils für alle
+    darin enthaltenen PICTURE. Dadurch ist es möglich, einen PICFILE mit spezifierter
+    Darstellungsart über einen SPOOLER an einen Plotter zu senden oder die bei der letzten
+    Betrachtung gewählte Darstellung beizubehalten oder zu ändern. 
+    Für die Darstellung können den virtuellen Stiften mit der Prozedur #on("b")#select pen#off("b")# reale Stifte
+    zugeordnet werden. Voreingestellt ist für alle virtuellen Stifte die Standardfarbe, Standard­
+    stärke und durchgängige Linie. Mit #on("b")#background#off("b")# kann eine bestimmte Hintergrundfarbe
+    gewählt werden. 
+    Indem man einem PICTURE den Stift 0 zuordnet, kann man dieses auch Ausblenden
+    wenn es bei dieser Darstellung stört. 
+    Die Größe der realen Zeichenfläche kann mit #on("b")#viewport#off("b")# eingestellt werden, wobei die
+    gesamte Zeichenfäche voreingestellt ist. Dadurch können auch mehrere PICFILE auf ein
+    Blatt oder einen Bildschirm gezeichnet werden, wenn man durch Angabe von #on("i")#background
+     (0)#off("i")# das Löschen der Zeichenfläche unterdrückt. 
+ 
+ 
+#type ("trium12")# 
+#on("b")#5. Darstellung zweidimensionaler Graphik#off("b")# 
+#type ("times8")# 
+ 
+    Bei der Darstellung zweidimensionaler Bilder muß der zu zeichnende Ausschnitt (das
+    #on("i")#Fenster#off("i")#) angegeben werden. Mit der Prozedur #on("b")#window#off("b")# wird durch Angabe der minimalen
+    und maximalen X- bzw. Y-Koordinaten ein Fenster definiert. Linien, die über dieses
+    Fenster hinausgehen, werden abgeschnitten. Dadurch kann man einen beliebigen Detailaus­
+    schnitt eines Bildes ausgeben, ohne das Bild neu generieren zu müssen. 
+    Da das so definierte Fenster auf die mit #on("i")#viewport#off("i")# definierte Zeichenfläche abgebildet wird,
+    ist der Abbildungsmaßstab durch das Zusammenspiel von #on("i")#viewport#off("i")# und #on("i")#window#off("i")# bestimmt.
+    Wenn eine Winkeltreue Darstellung erreicht werdenn soll, muß das Verhältnis der durch
+    #on("i")#viewport#off("i")# eingestellten Breite und Höhe und das Verhältnis des durch #on("i")#window#off("i")# eingestellten
+    Ausschnitts gleich sein. 
+ 
+#type ("trium12")# 
+#on("b")#6. Darstellung dreidimensionaler Graphik#off("b")# 
+#type ("times8")# 
+ 
+    Bei dreidimensionalen Zeichnungen wird das Fenster ebenfalls mit #on("b")#window#off("b")# definiert,
+    wobei dann allerdings auch der Wertebereich der dritten Dimension (Z-Koordinaten) zu
+    berücksichtigen ist. Auch hierbei werden Linien, die über die spezifierte Darstellungs­
+    fläche hinausgehen abgeschnitten. Das Abschneiden erfolgt allerdings erst nach der Projek­
+    tion auf die Darstellungsfläche, so daß auch Vektoren zu sehen sind, die über das mit
+    #on("i")#window#off("i")# angegebene Quader hinausgehen, wenn ihre Projektion innerhalb der Zeichen­
+    fläche liegt. 
+    Da die dreidimensionale Graphik auf eine zweidimensionale Fläche projeziert wird,
+    können aber noch weitere Darstellungsparameter angegeben werden. Der Betrachtungswin­
+    kel wird mit Hilfe der Prozedur #on("b")#view#off("b")# angegeben. Ebenfalls kann mit #on("b")#view#off("b")# der Winkel der
+    Y-Achse zur Horizontalen angegeben werden. 
+    Zur Spezifikation der gewünschten Projektionsart existieren #on("b")#orthographic#off("b")# (orthographische
+    Projektion), #on("b")#perspective#off("b")# (perspektivische Projektion, der Fluchtpunkt ist frei wählbar) und
+    #on("b")#oblique#off("b")# (schiefwinklige Projektion). 
+ 
+#page# 
+#type ("trium12")# 
+#on("b")#7. Beispiele#off("b")# 
+#type ("times8")# 
+ 
+    #on("u")#Sinuskurve#off("u")# 
+ 
+#type("micro")# 
+initialisiere picfile; 
+zeichne überschrift; 
+zeichne achsen; 
+zeichne sinuskurve; 
+wähle darstellung; 
+plot (p)  . 
+ 
+initialisiere picfile: 
+  PICFILE VAR p :: picture file ("SINUS")  . 
+ 
+zeichne überschrift: 
+  PICTURE VAR überschrift :: nilpicture; 
+  move (überschrift, -pi/2.0, 1.0); 
+  draw (überschrift, "sinus (x)  [-pi, +pi]", 0.0, 1.0, 0.6); 
+  put picture (p, überschrift)  . 
+ 
+ zeichne achsen: 
+  PICTURE VAR achsen :: nilpicture; 
+  zeichne x achse; 
+  zeichne y achse; 
+  put picture (p, achsen)  . 
+ 
+  zeichne x achse: 
+  move (achsen, -pi, 0.0); 
+  draw (achsen,  pi, 0.0)  . 
+ 
+  zeichne y achse: 
+  move (achsen, 0.0, -1.0); 
+  draw (achsen, 0.0, +1.0)  . 
+ 
+  zeichne sinuskurve: 
+  PICTURE VAR sinus :: nilpicture; 
+  REAL VAR x :: -pi; 
+ 
+   move (sinus, x, sin (x)); 
+  REP x INCR 0.1; 
+      draw (sinus, x, sin (x)) 
+  UNTIL x >= pi PER; 
+ 
+    put picture (p, sinus)  . 
+ 
+  wähle darstellung: 
+  window (p, -pi, pi, -1.0, 1.3); 
+  viewport (p, 0.0, 0.0, 0.0, 0.0)  . 
+ 
+#page# 
+#type ("times8")# 
+    #on("u")#Achsenkreuz#off("u")# 
+ 
+#type("micro")# 
+initialisiere picfile; 
+zeichne die x achse; 
+zeichne die y achse; 
+zeichne die z achse; 
+stelle das achsenkreuz dar  . 
+ 
+initialisiere picfile: 
+  PICFILE VAR p :: picture file ("KREUZ")  . 
+ 
+ zeichne die x achse: 
+  PICTURE VAR x achse := nilpicture; 
+  move (x achse, -1.0, 0.0, 0.0); 
+  draw (x achse, "-X", 0.0, 0.0, 0.0); 
+  draw (x achse,  1.0, 0.0, 0.0); 
+  draw (x achse, "+X", 0.0, 0.0, 0.0); 
+  put picture (p, x achse)  . 
+ 
+ zeichne die y achse: 
+  PICTURE VAR y achse := nilpicture; 
+  move (y achse, 0. 0, -1.0, 0.0); 
+  draw (y achse, "-Y", 0.0, 0.0, 0.0); 
+  draw (y achse, 0.0, 1.0, 0.0); 
+  draw (y achse, "+Y", 0.0, 0.0, 0.0); 
+  put picture (p, y achse)  . 
+ 
+ zeichne die z achse: 
+  PICTURE VAR z achse := nilpicture; 
+  move (z achse, 0. 0, 0.0, -1.0); 
+  draw (z achse, "-Z", 0.0, 0.0, 0.0); 
+  draw (z achse,  0.0, 0.0, 1.0); 
+  draw (z achse, "+Z", 0.0, 0.0, 0.0); 
+  put picture (p, z achse)  . 
+ 
+ stelle das achsenkreuz dar: 
+  viewport (p, 0. 0, 1.0, 0.0, 1.0); 
+  window (p, -1.1, 1.1, -1.1, 1.1); 
+  oblique (p, 0.25, 0.15); 
+  plot (p)  . 
+ 
+#foot# 
+  #type("times6")# 
+  Diese beiden Beispielprogramme befinden sich ebenfalls auf dem STD-Archive unter dem Namen #on("i")#Beispiel.Sinus#off("i")# und
+  #on("i")#Beispiel.Kreuz#off("i")#. 
+#end# 
+ 
+#page# 
+#type ("triumb14")# Beschreibung der Graphik-Prozeduren 
+#type ("times8")# 
+ 
+ 
+#type ("trium12")# 
+#on("b")#1. PICTURE-Prozeduren#off("b")# 
+#type ("times8")# 
+ 
+#limit (7.0)##type("times6")# 
+             #on("i")#Zweidimensionale PICTURES brauchen weniger Speicherplatz
+             als dreidimensionale. Daher werden in einigen Fehlermeldungen
+             unterschiedliche Größen angegeben. 
+ 
+#limit (11.0)##type("times8")# 
+ 
+#type("times10")##on("b")#:=#off("b")##type("times8")# 
+   OP := (PICTURE VAR l, PICTURE CONST r) 
+   Zweck:  Zuweisung 
+ 
+#type("times10")##on("b")#CAT#off("b")##type("times8")# 
+   OP CAT (PICTURE VAR l, PICTURE CONST r) 
+   Zweck:  Aneinanderfügen von zwei PICTURE. 
+   Fehlerfälle: 
+       * left dimension <> right dimension 
+         Es können nur PICTURE mit gleicher Dimension angefügt werden. 
+       * Picture overflow 
+         Die beiden PICTURE überschreiten die maximale Größe eines PICTURE. 
+ 
+#type("times10")##on("b")#nilpicture#off("b")##type("times8")# 
+   PICTURE PROC nilpicture 
+   Zweck:  Die Prozedur liefert ein leeres PICTURE zur Initialisierung. 
+ 
+   PICTURE PROC nilpicture (INT CONST pen) 
+   Zweck:  Die Prozedur liefert ein leeres PICTURE mit dem Stift #on("i")#pen#off("i")# zur Initialisierung. 
+ 
+#type("times10")##on("b")#draw#off("b")##type("times8")# 
+   PROC draw (PICTURE VAR p, TEXT CONST text, REAL CONST angle, height, ­
+              width) 
+   Zweck:  Der angegebene Text wird unter dem Winkel #on("i")#angle#off("i")# gegenüber der Waagerech­
+           ten mit der Zeichenhöhe #on("i")#hight#off("i")# und der Breite #on("i")#width#off("i")# gezeichnet. #on("i")#angle#off("i")# wird in
+           Winkelgrad angegeben. #on("i")#height#off("i")# und #on("i")#width#off("i")# werden in #on("i")#Prozenten#off("i")# der Breite bzw.
+           Höhe der Zeichenfläche angegeben, bei 0 wird 
+           die Standardhöhe- und breite angenommen. 
+           Der Anfang ist dabei die aktuelle Stiftposition, die nicht verändert wird. Es könne
+           auch die Steuerzeichen ""1"", ""2"", ""3"", ""10"", ""13"" benutzt werden,
+           wobei sie immer in der Richtung #on("i")#angle#off("i")# wirken. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Der Text paßt nicht mehr in das PICTURE. 
+ 
+#type("times10")##on("b")#draw#off("b")##type("times8")# 
+   PROC draw (PICTURE VAR p, REAL CONST x, y, z) 
+   Zweck:  Zeichnen einer Linie von der aktuellen Position zur Position (x, y, z). 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is two dimensional 
+ 
+   PROC draw (PICTURE VAR p, REAL CONST x, y) 
+   Zweck:  Zeichnen einer Linie von der aktuellen Position zur Position (x, y). 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+ 
+#type("times10")##on("b")#draw r#off("b")##type("times8")# 
+   PROC draw r (PICTURE VAR p, REAL CONST x, y, z) 
+   Zweck:  Zeichnen einer Linie der Länge (x, y, z) relativ zur aktuellen Position. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is two dimensional 
+ 
+   PROC draw r (PICTURE VAR p, REAL CONST x, y) 
+   Zweck:  Zeichnen einer Linie der Länge (x, y) relativ zur aktuellen Position. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+ 
+#type("times10")##on("b")#move#off("b")##type("times8")# 
+   PROC move (PICTURE VAR p, REAL CONST x, y, z) 
+   Zweck:  Die aktuelle Position wird auf (x, y, z) gesetzt. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is two dimensional 
+ 
+   PROC move (PICTURE VAR p, REAL CONST x, y) 
+   Zweck:  Die aktuelle Position wird auf (x, y) gesetzt. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+ 
+#type("times10")##on("b")#move r#off("b")##type("times8")# 
+   PROC move r (PICTURE VAR p, REAL CONST x, y, z) 
+   Zweck:  Die aktuelle Position wird um (x, y, z) erhöht. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is two dimensional 
+ 
+   PROC move r (PICTURE VAR p, REAL CONST x, y) 
+   Zweck:  Die aktuelle Position wird um (x, y) erhöht. 
+           Position. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+ 
+ 
+#type("times10")##on("b")#bar#off("b")##type("times8")# 
+   PROC bar (PICTURE VAR p, REAL CONST width, hight, INT CONST pattern): 
+   Zweck:  Die Prozedur zeichnet an der aktuellen Position einen Balken mit dem Muster
+              #on("i")#pattern#off("i")#: 
+              0  =  Leerer Balken 
+              1  =  Gepunkteter Balken 
+              2  =  Gefüllter Balken 
+              3  =  Horizontale Linien 
+              4  =  Vertikale Linien 
+              5  =  Gekreuzte Linien 
+              6  =  Diagonale Linien von Links nach Rechts 
+              7  =  Diagonale Linien von Rechts nach Links 
+              8  =  Gekreuzte diagonale Linien 
+            > 8  =  nicht normiertes Sondermuster 
+          Die aktuelle Stiftposition wird dabei nicht verändert. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+ 
+   PROC bar (PICTURE VAR p, REAL CONST from, to, hight, INT CONST pattern): 
+   Zweck:  Die Prozedur zeichnet einen Balken von der Position #on("i")#from#off("i")# zur Position #on("i")#to#off("i")# und der
+           Höhe #on("i")#height#off("i")# mit dem Muster #on("i")#pattern#off("i")#. 
+           s.o. 
+ 
+#type("times10")##on("b")#circle#off("b")##type("times8")# 
+   PROC circle (PICTURE VAR p, REAL CONST radius, from, to, INT CONST pattern) 
+   Zweck:  Die Prozedur zeichnet an der aktuellen Position ein Kreissegment vom Winkel
+           #on("i")#from#off("i")# bis #on("i")#to#off("i")# (im Gradmaß) mit dem Muster #on("i")#pattern#off("i")# (s.o.). Der #on("i")#radius#off("i")# wird in
+           Prozenten der Diagonalen der Zeichenfläche angegeben. 
+           Die aktuelle Stiftposition wird dabei nicht verändert. Dieses Kreissegment ist in
+           jedem Fall 2-dimensional, so das es durch Drehungen nicht verändert wird. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+ 
+#type("times10")##on("b")#mark#off("b")##type("times8")# 
+   PROC mark (PICTURE VAR p, REAL CONST size, INT CONST no) 
+   Zweck:  Es wird ein Marker mit der Größe #on("i")#size#off("i")# in Prozenten der Diagonalen der Zeichen­
+           fläche an der aktuellen Stiftposition ausgegeben, ohne diese zu verändern. Es
+           sollten dabei mindestens 10 verschiedene Marker gewählt werden können. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+ 
+#type("times10")##on("b")#dim#off("b")##type("times8")# 
+   INT PROC dim (PICTURE CONST pic) 
+   Zweck:  Liefert die Dimension eines PICTURE. 
+ 
+#type("times10")##on("b")#pen#off("b")##type("times8")# 
+   INT PROC pen (PICTURE CONST p) 
+   Zweck:  Liefert den virtuellen Stift des PICTURE 
+ 
+   PICTURE PROC pen (PICTURE CONST p, INT CONST pen) 
+   Zweck:  Setzen des (virtuellen) Stiftes eines PICTURE. 
+           Bei #on("i")#pen#off("i")# = 0 wird das Picture nicht gezeichnet. 
+   Fehlerfälle: 
+       * pen out of range 
+         Der gewünschte Stift ist kleiner als 0 oder größer als 16. 
+ 
+#type("times10")##on("b")#extrema#off("b")##type("times8")# 
+   PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y max) 
+   Zweck:  Die Prozedur liefert die größten und kleinsten Werte des PICTURE. 
+   Fehlerfälle: 
+       * Picture is three dimensional 
+ 
+   PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y max,  
+   z min, z max) 
+   Zweck:  Die Prozedur liefert die größten und kleinsten Werte des PICTURE. 
+   Fehlerfälle: 
+       * Picture is two dimensional 
+ 
+#type("times10")##on("b")#where#off("b")##type("times8")# 
+   PROC where (PICTURE CONST p, REAL VAR x, y, z) 
+   Zweck:  Die Prozedur liefert die aktuelle Stiftposition. 
+   Fehlerfälle: 
+       * Picture is two dimensional 
+ 
+   PROC where (PICTURE CONST p, REAL VAR x, y, z) 
+   Zweck:  Die Prozedur liefert die aktuelle Stiftposition. Fehlerfälle: 
+       * Picture is three dimensional 
+ 
+#type("times10")##on("b")#rotate#off("b")##type("times8")# 
+   PROC rotate (PICTURE VAR p, REAL CONST angle) 
+   Zweck:  Das PICTURE wird um den Punkt (0, 0) um den Winkel #on("i")#angle#off("i")# (im Gradmaß) im
+           mathematisch positiven Sinn gedreht. 
+ 
+   PROC rotate (PICTURE CONST p, REAL CONST phi, theta, lambda) 
+   Zweck:  Das PICTURE wird um den Winkel #on("i")#lambda#off("i")# um die Drehachse #on("i")#(phi, theta)#off("i")# ge­
+           dreht. 
+ 
+#type("times10")##on("b")#stretch#off("b")##type("times8")# 
+   PROC stretch (PICTURE VAR pic, REAL CONST sx, sy) 
+   Zweck:  Das PICTURE wird in X-Richtung um den Faktor #on("i")#sx#off("i")#, in Y-Richtung um den
+           Faktor #on("i")#sy#off("i")# gestreckt (bzw. gestaucht). Dabei bewirkt der Faktor 
+                 s   >  1    eine Streckung 
+           0  <  s   <  1    eine Stauchung 
+                 s   <  0    zusätzlich eine Achsenspiegelung. 
+   Fehlerfälle: 
+       * Picture is three dimensional 
+ 
+   PROC stretch (PICTURE VAR p, REAL CONST sx, sy, sz) 
+   Zweck:  s. o. 
+   Fehlerfälle: 
+       * Picture is two dimensional 
+ 
+#type("times10")##on("b")#translate#off("b")##type("times8")# 
+   PROC translate (PICTURE VAR p, REAL CONST dx, dy) 
+   Zweck:  Das PICTURE wird um #on("i")#dx#off("i")# und #on("i")#dy#off("i")# verschoben. Fehlerfälle: 
+       * Picture is three dimensional 
+ 
+   PROC translate (PICTURE VAR p, REAL CONST dx, dy, dz) 
+   Zweck:  Das PICTURE wird um #on("i")#dx, dy#off("i")# und #on("i")#dz#off("i")# verschoben. Fehlerfälle: 
+       * Picture is two dimensional 
+ 
+ 
+#type ("trium12")# 
+#on("b")#2. PICFILE-Prozeduren#off("b")# 
+#type ("times8")# 
+ 
+#type("times10")##on("b")#plot#off("b")##type("times8")# 
+   PROC plot (TEXT CONST name) 
+   Zweck:  Der PICFILE mit dem Namen #on("i")#name#off("i")# wird entsprechend der angegebenen Dar­
+           stellungsart gezeichnet. Diese Parameter (#on("i")#perspective, orthographic, oblique, view,
+           window etc.#off("i")#) müssen vorher eingestellt werden. 
+   Fehlerfälle: 
+       * PICFILE does not exist 
+         Es existiert kein PICFILE mit dem Namen #on("i")#name#off("i")# 
+ 
+   PROC plot (PICFILE VAR p) 
+   Zweck:  Der PICFILE #on("i")#p#off("i")# wird entsprechend der angegebenen Darstellungsart gezeichnet.
+           Diese Parameter müssen vorher eingestellt werden: 
+ 
+           #on("b")#zweidimensional:#off("b")# 
+           obligat:        #on("i")#window#off("i")#            (zweidimensional) 
+           optional:       #on("i")#view#off("i")#              (zweidimensional) 
+                           #on("i")#viewport#off("i")# 
+                           #on("i")#select pen#off("i")# 
+ 
+           #on("b")#dreidimensional:#off("b")# 
+           obligat:        #on("i")#window#off("i")#            (dreidimensional) 
+           optional:       #on("i")#view#off("i")#              (dreidimensional) 
+                           #on("i")#orthographic | perspective | oblique#off("i")# 
+                           #on("i")#viewport#off("i")# 
+                           #on("i")#select pen#off("i")# 
+ 
+ 
+#type("times10")##on("b")#select pen#off("b")##type("times8")# 
+   PROC select pen (PICFILE VAR p, INT CONST pen, colour, thickness, line type) 
+   Zweck:  Für die Darstellung des Bildes #on("i")#p#off("i")# soll dem #on("i")#virtuellen#off("i")# Stift #on("i")#pen#off("i")# ein realer Stift
+           zugeordnet werden, der möglichst die Farbe #on("i")#colour#off("i")# und die Dicke #on("i")#thickness#off("i")# hat
+           und dabei Linien mit dem Typ #on("i")#line type#off("i")# zeichnet. Es wird die beste Annäherung
+           für das Ausgabegerät genommen. 
+           Dabei gelten folgende Vereinbarungen: 
+ 
+           #on("b")#Farbe:#off("b")# Negative Farben werden XOR gezeichnet (dunkel wird hell und hell wird
+                  dunkel), Farbe 0 ist der Löschstift und positive Farben überschreiben
+                  (ersetzen) den alten Punkt mit folgenden Werten: 
+ 
+                  1      Standardfarbe des Endgerätes 
+                  2      rot 
+                  3      blau 
+                  4      grün 
+                  5      schwarz 
+                  6      weiß 
+                  >  6    nicht normierte Sonderfarben 
+ 
+ 
+           #on("b")#Dicke:#off("b")#  0   Standardstrichstärke des Endgerätes 
+                  > 0   Strichstärke in 1/10 mm. 
+ 
+ 
+           #on("b")#Linientyp:#off("b")# 
+                  0      keine sichtbare Linie 
+                  1      durchgängige Linie 
+                  2      gepunktete Linie 
+                  3      kurz gestrichelte Linie 
+                  4      lang gestrichelte Linie 
+                  5      Strichpunktlinie 
+                  > 5    nicht normierte Linie 
+ 
+ 
+           Die hier aufgeführten Möglichkeiten müssen nicht an allen graphischen Endge­
+           räten vorhanden sein. Der geräteabhängige Graphik-Treiber wählt jeweils die
+           bestmögliche Annäherung. 
+ 
+   Fehlerfälle: 
+       * pen out of range 
+         #on("i")#pen#off("i")# muss im Bereich 1-16 sein. 
+ 
+#type("times10")##on("b")#background#off("b")##type("times8")# 
+   PROC background (PICFILE VAR p, INT CONST colour) 
+   Zweck:  Der Hintergrund wird auf die Farbe #on("i")#colour#off("i")# (s.o.) gesetzt wenn möglich. 
+           Bei der Angabe #on("i")#background (p, 0)#off("i")# wird das Löschen des Bildschirms unterdrückt,
+           so daß das Zeichen mehrerer PICFILE auf einem Blatt möglich wird. 
+ 
+   INT PROC background (PICFILE CONST p): 
+   Zweck:  Liefert die eingestellte Hintergrundfarbe. 
+ 
+#type("times10")##on("b")#view#off("b")##type("times8")# 
+   PROC view (PICFILE VAR p, REAL CONST alpha) 
+   Zweck:  Setzt den Winkel der Y-Achse zur Senkrechten auf #on("i")#alpha#off("i")# Grad, falls diese nicht
+           senkrecht auf der Betrachtungsebene steht. 
+ 
+   PROC view (PICFILE VAR p, REAL CONST phi, theta) 
+   Zweck:  Dreidimensionale Bilder werden häufig nicht direkt von vorne dargestellt, son­
+           dern für die Betrachtung gedreht. Mit der Prozedur #on("i")#view#off("i")# kann die Betrachtungs­
+           richtung durch die Polarwinkel #on("i")#phi#off("i")# und #on("i")#theta#off("i")# (im Gradmass) angegeben werden.
+           Voreingestellt ist #on("i")#phi#off("i")# = 0 und #on("i")#theta#off("i")# = 0, d.h. senkrecht von oben (Die #on("i")#X-
+           Achse#off("i")# bildet die Horizontale und die #on("i")#Y-Achse#off("i")# bildet die Vertikale). 
+           Im Gegensatz zu #on("i")#rotate#off("i")# hat #on("i")#view#off("i")# keine Wirkung auf das eigentliche Bild (die
+           PICTURE werden nicht verändert), sondern nur auf die gewählte Darstellung. So
+           addieren sich zwar aufeinanderfolgende #on("i")#Rotationen#off("i")#, #on("i")#view#off("i")# aber geht immer von der
+           Nullstellung aus. Auch kann das Bild durch eine #on("i")#Rotation#off("i")# ganz oder teilweise aus
+           oder in das Darstellungsfenster (#on("i")#window#off("i")# gedreht werden. Bei #on("i")#view#off("i")# verändern sich
+           die Koordinaten der Punkte nicht, d. h. das Fenster wird mitgedreht. 
+ 
+   PROC view (PICFILE VAR p, REAL CONST x, y, z) 
+   Zweck:  Wie oben, nur werden die Winkel nicht in Polarkoordinaten angegeben, sondern
+           es wird die Blickrichtung als Vektor in Karthesischen Koordinaten angegeben.
+           (Der Betrachtungsvektor muß nicht normiert sein). 
+ 
+#type("times10")##on("b")#viewport#off("b")##type("times8")# 
+   PROC viewport (PICFILE VAR p, REAL CONST hormin, hormax, vertmin, vertmax) 
+   Zweck:  Die Zeichenfläche auf dem Endgerät, auf dem das Bild dargestellt werden soll,
+           wird spezifiziert. Dabei wird sowohl die Größe als auch die relative Lage der
+           Zeichenfläche definiert. Der linke untere Eckpunkt der physikalischen Zeichen­
+           fläche des Gerätes hat die Koordinaten (0, 0). Die definierte Zeichenfläche er­
+           streckt sich 
+ 
+                  #on("i")#hormin   -  hormax#off("i")#        in der Horizontalen, 
+                  #on("i")#vertmin  -  vertmax#off("i")#       in der Vertikalen. 
+ 
+           So liegt der linke untere Eckpunkt dann bei (#on("i")#hormin, hormax#off("i")#), der rechte obere
+           Eckpunkt bei (#on("i")#hormax, vertmax#off("i")#). 
+ 
+           Damit sowohl geräteunabhängige als auch maßstabgetreue Zeichnungen möglich
+           sind, können die Koordinaten in drei Arten spezifiziert werden: 
+           a)  #on("b")#Gerätekoordinaten#off("b")# 
+               Die Koordinaten können Werte von 0.0 bis 2.0 annehmen. Dabei hat die
+               kürzere Seite der physikalischen Zeichenfläche definitionsgemäß die Länge
+               1.0. 
+           b)  #on("b")#Absolute Koordinaten#off("b")# 
+               Die Werte werden in #on("i")#cm#off("i")# angegeben. Dabei müssen die Maximalwerte aber
+               größer als 2.0 sein, da sonst Fall a) angenommen wird. 
+           c)  #on("b")#Maximale Zeichenfläche#off("b")# Bei der Angabe (0.0, 0.0, 0.0, 0.0) wird die maxi­
+               male physikalische Zeichenfläche eingestellt. 
+ 
+           Voreingestellt ist 
+                  viewport (0.0, 0.0, 0.0, 0.0) 
+           d.h. die größtmögliche physikalische Zeichenfläche, beginnend mit der linken
+                unteren Ecke. 
+           Der Abbildungsmaßstab wird durch das Zusammenspiel von #on("i")#viewport#off("i")# und
+           #on("i")#window#off("i")# festgelegt (s. dort). Dabei ist insbesondere darauf zu achten, daß winkel­
+           treue Darstellung nur bei gleichen Verhältnissen von X-Bereich und Breite bzw.
+           von Y-Bereich und Höhe möglich ist. 
+ 
+ 
+#type("times10")##on("b")#window#off("b")##type("times8")# 
+   PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max) 
+   Zweck:  Für die Darstellung eines zweidimensionalen Bildes wird das darzustellende
+           Fenster definiert. Alle Bildpunkte, deren X-Koordinaten im Intervall [#on("i")#x min, x
+           max#off("i")#] und deren Y-Koordinaten im Bereich [#on("i")#y min, y max#off("i")#] liegen, gehören zum
+           definierten Fenster.Vektoren, die außerhalb dieses Fensters liegen, gehen über die
+           durch #on("i")#viewport#off("i")# Fläche hinaus und werden abgeschnitten. 
+ 
+           Der Darstellungsmaßstab ergibt sich als 
+ 
+           #ub#               x max - x min               #ue# 
+            horizontale Seitenlänge der Zeichenfläche 
+ 
+ 
+           #ub#               y max - y min               #ue# 
+             vertikale Seitenlänge der Zeichenfläche 
+ 
+   PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max,  
+                                                        z min, z max) 
+ 
+   Zweck:  Für die darstellung eines dreidimensionalen Bildes wird das darzustellende Fenster
+           definiert. Alle Bildpunkte, deren X-Koordinaten im Intervall [#on("i")#x min, x max#off("i")#],
+           deren Y-Koordinaten im Bereich [#on("i")#y min, y max#off("i")#] und deren Z-Koordinaten im
+           Bereich [#on("i")#z min, z max#off("i")#] liegen, gehören zum definierten Fenster. Dieses dreidi­
+           mensionale Fenster (#on("i")#Quader#off("i")#) wird entsprechend der eingestellten Projektionsart
+           (orthographisch, perspektivisch oder schiefwinklig) und den Betrachtungswinkeln
+           (s. #on("i")#view#off("i")#) auf die spezifizierte Zeichenfläche abgebildet. 
+           Anders als im zweidimensionalen Fall ist das Problem der Maßstaäbe nicht mehr
+           nur durch das Zusammenspiel von #on("i")#window#off("i")# und #on("i")#viewport#off("i")# zu beschreiben. Hier
+           spielen auch die Projektionsart und Darstellungswinkel herein. 
+ 
+#type("times10")##on("b")#oblique#off("b")##type("times8")# 
+   PROC oblique (PICFILE VAR p, REAL CONST a, b) 
+   Zweck:  Bei dem (dreidimensionalen) Bild #on("i")#p#off("i")# wird #on("u")#schiefwinklig#off("u")# als gewünschte Projek­
+           tionsart eingestellt. Dabei ist (#on("i")#a, b#off("i")#) der Punkt auf der X-Y-Ebene, auf den der
+           EinheitsVektor der Z-Richtung abgebildet werden soll. 
+ 
+#type("times10")##on("b")#orthographic#off("b")##type("times8")# 
+   PROC orthographic (PICFILE VAR p) 
+   Zweck:  Bei dem (dreidimensionalen) Bild #on("i")#p#off("i")# wird #on("u")#orthographisch#off("u")# als gewünschte Projek­
+           tionsart eingestellt. Bei der orthographischen Projektion wird ein dreidimensio­
+           naler Körper mit parallelen Strahlen senkrecht auf der Projektionsebene abge­
+           bildet. 
+ 
+#type("times10")##on("b")#perpective#off("b")##type("times8")# 
+   PROC perspective (PICFILE VAR p, REAL CONST cx, cy, cz) 
+   Zweck:  Bei dem (dreidimensionalen) Bild #on("i")#p#off("i")# wird #on("u")#perspektivisch#off("u")# als gewünschte Projek­
+           tionsart eingestellt. Der Punkt (#on("i")#cx, 1/cy, cz#off("i")#) ist der Fluchtpunkt der Projektion,
+           d. h. alle Parallen zur Z-Achse schneiden sich in diesem Punkt. 
+ 
+#type("times10")##on("b")#extrema#off("b")##type("times8")# 
+   PROC extrema (PICFILE VAR p, REAL VAR x min, x max, y min, y max) 
+   Zweck:  Die Prozedur liefert die größten und kleinsten Werte des PICFILE. 
+ 
+   PROC extrema (PICFILE VAR p, REAL VAR x min,x max,y min,y max,z min,z max) 
+   Zweck:  Die Prozedur liefert die größten und kleinsten Werte des PICFILE. 
+ 
+#type ("trium12")# 
+#on("b")#3. Prozeduren zur Manipulation von PICFILE#off("b")# 
+#type("times 8")# 
+ 
+#type("times10")##on("b")#:=#off("b")##type("times8")# 
+   OP := (PICFILE VAR l, PICFILE CONST r) 
+   Zweck:  Zuweisung des PIFILEs #on("i")#r#off("i")# an das PICFILE #on("i")#l#off("i")# 
+ 
+   OP := (PICFILE VAR p, DATASPACE CONST d) 
+   Zweck:  Assoziert die PICFILE Variable #on("i")#p#off("i")# mit dem Datenraum #on("i")#d#off("i")# und initialisiert die
+           Variable, wenn nötig. 
+   Fehlerfälle: 
+       * dataspace is no PICFILE 
+         Der anzukoppelnde Datenraum hat einen unzulässigen Typ 
+ 
+#type("times10")##on("b")#picture file#off("b")##type("times8")# 
+   DATASPACE PROC picture file (TEXT CONST name) 
+   Zweck:  Assoziaten eines benannten Datenraumes mit einem PICFILE (s.o.). 
+ 
+#type("times10")##on("b")#to pic#off("b")##type("times8")# 
+   PROC to pic (PICFILE VAR p, INT CONST pos) 
+   Zweck:  Positioniert auf das PICTURE Nummer #on("i")#pos#off("i")#. 
+   Fehlerfälle: 
+       *  Position underflow 
+          Es wurde eine Position kleiner Null angegeben. 
+       *  Position after eof 
+          Es wurde versucht, hinter das Ende eines PICFILE zu positionieren. Die letzte
+          erlaubte Position ist #on("i")#pictures (p)+1#off("i")#. 
+ 
+#type("times10")##on("b")#up#off("b")##type("times8")# 
+   PROC up (PICFILE VAR p) 
+   Zweck:  Positioniert genau ein PICTURE zurück. 
+   Fehlerfall: 
+       *  Position underflow 
+          Es wurde versucht, vor das erste PICTURE zu positionieren 
+ 
+   PROC up (PICFILE VAR p, INT CONST n) 
+   Zweck:  Positioniert genau #on("i")#n#off("i")# Picture zurück. 
+   Fehlerfall: 
+       *  Position underflow 
+          Es wurde versucht, vor das erste PICTURE zu positionieren 
+ 
+#type("times10")##on("b")#down#off("b")##type("times8")# 
+   PROC down (PICFILE VAR p) 
+   Zweck:  Positioniert genau ein PICTURE vorwärts. 
+   Fehlerfall: 
+       *  Position after eof 
+          Es wurde versucht, hinter das Ende eines PICFILE zu positionieren. Die letzte
+          erlaubte Position ist #on("i")#pictures (p)+1#off("i")#. 
+ 
+   PROC down (PICFILE VAR p, INT CONST n) 
+   Zweck:  Positioniert genau #on("i")#n#off("i")# Picture vorwärts. 
+   Fehlerfall: 
+       *  Position after eof 
+          Es wurde versucht, hinter das Ende eines PICFILE zu positionieren Die letzte
+          erlaubte Position ist #on("i")#pictures (p)+1#off("i")#. 
+ 
+#type("times10")##on("b")#delete picture#off("b")##type("times8")# 
+   PROC delete picture (PICFILE VAR p) 
+   Zweck:  Löscht das aktuelle PICTURE 
+ 
+#type("times10")##on("b")#insert picture#off("b")##type("times8")# 
+   PROC insert picture (PICFILE VAR p) 
+   Zweck:  Fügt ein PICTURE #on("u")#vor#off("u")# der aktuellen Position ein. 
+ 
+#type("times10")##on("b")#read picture#off("b")##type("times8")# 
+   PROC read picture (PICFILE CONST p, PICTURE VAR pic) 
+   Zweck:  Liest das aktuelle PICTURE. 
+ 
+#type("times10")##on("b")#write picture#off("b")##type("times8")# 
+   PROC write picture (PICFILE VAR p, PICTURE CONST pic) 
+   Zweck:  Schreibt das PICTURE #on("i")#pic#off("i")# auf der aktuellen Position. 
+ 
+#type("times10")##on("b")#put picture#off("b")##type("times8")# 
+   PROC put picture (PICFILE VAR p, PICTURE CONST pic) 
+   Zweck:  Schreibt das PICTURE #on("i")#pic#off("i")# an die aktuelle Position und erhöht diese um 1. 
+ 
+#type("times10")##on("b")#get picture#off("b")##type("times8")# 
+   PROC get picture (PICFILE VAR p, PICTURE VAR pic) 
+   Zweck:  Liest das PICTURE #on("i")#pic#off("i")# an dir aktuellen Position und erhöht diese um 1. 
+ 
+#type("times10")##on("b")#eof#off("b")##type("times8")# 
+   BOOL PROC eof (PICFILE CONST p) 
+   Zweck:  Liefert genau dann #on("i")#TRUE#off("i")#, wenn das Ende eines PICFILE erreicht ist. 
+ 
+#type("times10")##on("b")#picture no#off("b")##type("times8")# 
+   INT PROC picture no (PICFILE CONST p) 
+   Zweck:  Liefert die Nummer des aktuellen PICTURE. 
+ 
+#type("times10")##on("b")#pictures#off("b")##type("times8")# 
+   INT PROC pictures (PICFILE CONST p) 
+    Zweck:  Liefert die Anzahl PICTURE eines PICFILE. 
+ 
+ 
+#page# 
+#type ("trium12")# 
+#on("b")#4. Auslieferungsumfang#off("b")# 
+#type ("times8")# 
+ 
+   Die EUMEL-GRAPHIK wird auf einer Diskette mit folgendem Inhalt ausgeliefert. 
+   Archive #on("i")#Graphik#off("i")#: 
+ 
+       "gen Graphik" 
+       "gen Plotter" 
+       "GRAPHIK.book" 
+       "GRAPHIK.Picfile" 
+       "GRAPHIK.Transform" 
+       "GRAPHIK.Plot" 
+       "GRAPHIK.Plotter" 
+       "GRAPHIK.Server" 
+       "GRAPHIK.vektor plot" 
+       "ZEICHENSATZ" 
+       "PC.plot" 
+       "HP7475.plot" 
+       "Beispiel.Kreuz" 
+       "Beispiel.Sinus" 
+ 
+ 
+ 
+    #on("u")#Dateiinhalte#off("u")# 
+ 
+    1. "gen Graphik"           Installationsprogramm für Terminals 
+    2. "gen Plotter"           Installationsprogramm für Plotter 
+    3. "GRAPHIK.book"          enthält diese Beschreibung. 
+    4. "GRAPHIK.Picfile"       enthält die Pakete #on("i")#picture#off("i")# und #on("i")#picfile#off("i")#. 
+    5. "GRAPHIK.Transform"     stellt das Paket #on("i")#transformation#off("i")# zur Verfügung, in dem
+                               interne Prozeduren zur Projektion definiert werden. 
+    6. "GRAPHIK.Plot"          definiert die Prozedur #on("i")#plot#off("i")# zur Darstellung eines
+                               PICFILES auf dem Terminal 
+    7. "GRAPHIK.Plotter"       definiert die Prozedur #on("i")#plotter#off("i")# zur Darstellung eines
+                               PICFILES auf dem Plotter 
+    8. "GRAPHIK.Server"        Server für einen Plotter-Spool 
+    9. "GRAPHIK.vektor plot"   enthält Hilfsprogramme, die bei der Erstellung einer
+                               eigenen Terminalanpassung benutzt werden können. 
+   10. "ZEICHENSATZ"           enthält einen Zeichensatz für Terminals die im Graphik
+                               Modus keinen Text ausgeben können. 
+   11. "PC.plot"               Terminalanpassung für IBM-PC und ähnliche. 
+   12. "HP7475.plot"           Terminalanpassung für HP7474-Plotter und Geräte mit
+                               HP-GL. 
+   13. "Beispiel.Kreuz"        Beispielprogramm 
+   14. "Beispiel.Sinus"        Beispielprogramm 
+ 
+#type ("trium12")# 
+#on("b")#5. Installation#off("b")# 
+#type ("times8")# 
+ 
+ 
+    In der Datei #on("i")#gen Graphik#off("i")# ist ein Installationspragramm enthalten. Nach dem Starten des
+    Programms mit #on("i")#run ("gen Graphik")#off("i")# fragt es nach dem Dateinamen der Terminalanpas­
+    sung. 
+    Steht keine Terminalanpassung für ein Endgerät zur Verfügung (und kann auch nicht
+    beschafft werden) so kann man durch Insertieren der Datei #on("i")#GRAPHIK.Picfile#off("i")# lediglich die
+    Leistungen der Pakete #on("i")#Picture#off("i")# und #on("i")#Picfile#off("i")# nutzen, ohne die erzeugten Graphiken darstellen
+    zu können. 
+    Zur Benutzung eines #on("i")#Plotters#off("i")# über einen Spooler wird die Datei #on("i")#gen Plotter#off("i")# gestartet. 
+ 
+ 
+    Beispiel: 
+    1.  archive ("Graphik") 
+    2.  fetch all (archive) 
+    3.  release (archive) 
+    4.  run ("gen Graphik") 
+            <--     PC.Plot 
+ 
+ 
+#type ("trium12")# 
+#on("b")#6. Besonderheiten der PC.plot-Anpassung#off("b")# 
+#type ("times8")# 
+ 
+ 
+  Da der IBM-PC verschiedene Graphik- und Text-Modi kennt, wird durch das Pro­
+  gramm #on("i")#PC.plot#off("i")# die Prozedur #on("i")#graphik#off("i")# zusätzlich zur Verfügung gestellt. Sie erlaubt es den
+  PC in verschiedenen Graphik-Modi zu betreiben. 
+ 
+  PROC graphik (INT CONST modus, pause) 
+ 
+  Modus:  0    ---    Keine Graphik (normaler Textmodus) 
+          1    ---    hochauflösende Graphik, 50 Zeilen, 
+                      640 * 400 Punkte, einfarbig 
+          2    ---    hochauflösende Graphik, 25 Zeilen, 
+                      640 * 400 Punkte, einfarbig 
+          3    ---    mittlere Auflösung, 640 * 200 Punkte, 3 Farben 
+          4    ---    IBM-PC Auflösung, 320 * 200 Punkte, 3 Farben. 
+ 
+  Pause:  Da der PC bei #on("i")#end plot#off("i")# wieder in den Normalmodus umschaltet und die Graphik
+          dann nicht mehr zu sehen ist, kann man eine #on("i")#pause#off("i")# angeben. Die hier eingestellte
+          Zeit ist aber nicht die Länge der Pause, sondern der Kehrwert der Blinkfrequenz
+          proportional. 
+ 
+
diff --git a/doc/graphic/graphik beschreibung b/doc/graphic/graphik beschreibung
new file mode 100644
index 0000000..53ebe49
--- /dev/null
+++ b/doc/graphic/graphik beschreibung	
@@ -0,0 +1,661 @@
+#type ("basker12")##limit (16.0)##block# 
+ 
+#head# 
+#type ("triumb18")# 
+#center#EUMEL-Grafik-System 
+#type ("basker12")# 
+#end# 
+                                               #on("italics")#gescheit, gescheiter, 
+                                               gescheitert#off("italics")# 
+ 
+#type ("basker14")# 
+#on("bold")#Beschreibung der Graphik-Prozeduren#off("bold")# 
+#type ("basker12")# 
+ 
+      #on("italics")#Zweidimensionale PICTURE brauchen weniger Speicherplatz als dreidimen­
+      sionale. Daher werden in einigen Fehlermeldungen unterschiedliche Größen
+      angegeben.#off("italics")# 
+ 
+#on("underline")#Picture-Prozeduren#off("underline")# 
+PICTURE 
+ 
+ 
+:= 
+   OP := (PICTURE VAR l, PICTURE CONST r) 
+   Zweck: Zuweisung 
+ 
+CAT 
+   OP CAT (PICTURE VAR l, PICTURE CONST r) 
+   Zweck: Aneinanderfügen von zwei PICTURE. 
+   Fehlerfälle: 
+       * left dimension <> right dimension 
+         Es können nur PICTURE mit gleicher Dimension angefügt werden. 
+       * Picture overflow 
+         Die beiden PICTURE überschreiten die maximale Größe eines
+         PICTURE. 
+ 
+nilpicture 
+   PICTURE PROC nilpicture 
+   Zweck: Die Prozedur liefert ein leeres PICTURE zur Initialisierung. 
+ 
+draw 
+   PROC draw (PICTURE VAR p, TEXT CONST text) 
+   Zweck: Der angegebene Text wird gezeichnet. Der Anfang ist dabei die aktuelle
+          Stiftposition, die nicht verändert wird. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Der Text paßt nicht mehr in das PICTURE. 
+ 
+  PROC draw (PICTURE VAR p, TEXT CONST text, REAL CONST angle,
+  height, bright) 
+   Zweck: Der angegebene Text wird unter dem Winkel #on("italics")#angle#off("italics")# gegenüber der
+          Waagerechten mit der Zeichenhöhe #on("italics")#hight#off("italics")# und der Breite #on("italics")#bright#off("italics")# gezeich­
+          net. Der Anfang ist dabei die aktuelle Stiftposition, die nicht verändert
+          wird. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Der Text paßt nicht mehr in das PICTURE. 
+ 
+   PROC draw (PICTURE VAR p, REAL CONST x, y, z) 
+   Zweck: Zeichnen einer Linie von der aktuellen Position zur Position (x, y, z). 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is two dimensional 
+ 
+   PROC draw (PICTURE VAR p, REAL CONST x, y) 
+   Zweck: Zeichnen einer Linie von der aktuellen Position zur Position (x, y). 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+ 
+draw r PROC draw r (PICTURE VAR p, REAL CONST x, y, z) 
+   Zweck: Zeichnen einer Linie der Länge (x, y, z) relativ zur aktuellen Position. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is two dimensional 
+ 
+   PROC draw r (PICTURE VAR p, REAL CONST x, y) 
+   Zweck: Zeichnen einer Linie der Länge (x, y) relativ zur aktuellen Position. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+ 
+draw cm 
+  PROC draw cm (PICTURE VAR p, REAL CONST x, y) 
+   Zweck: Zeichnen einer Linie von der aktuellen Position zur Position (x, y) cm.
+          Dabei werden die angegebenen Projektionsparameter nicht beachtet,
+          sondern die Angaben in #on("bold")#Zentimeter#off("bold")# berechnet. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+ 
+draw cm r 
+   PROC draw cm r (PICTURE VAR p, REAL CONST x, y) 
+   Zweck: Zeichnen einer Linie der Länge (x, y) cm relativ zur aktuellen Position.
+          Dabei werden die angegebenen Projektionsparameter nicht beachtet,
+          sondern die Angaben in #on("bold")#Zentimeter#off("bold")# berechnet. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+ 
+move 
+   PROC move (PICTURE VAR p, REAL CONST x, y, z) 
+   Zweck: Die aktuelle Position wird auf (x, y, z) gesetzt. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is two dimensional 
+ 
+   PROC move (PICTURE VAR p, REAL CONST x, y) 
+   Zweck: Die aktuelle Position wird auf (x, y) gesetzt. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+ 
+move r 
+   PROC move r (PICTURE VAR p, REAL CONST x, y, z) 
+   Zweck: Die aktuelle Position wird um (x, y, z) erhöht. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is two dimensional 
+ 
+   PROC move r (PICTURE VAR p, REAL CONST x, y) 
+   Zweck: Die aktuelle Position wird um (x, y) erhöht. 
+          Position. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+ 
+move cm 
+  PROC move cm (PICTURE VAR p, REAL CONST x, y) 
+   Zweck: Die aktuelle Position wird auf (x, y) cm gesetzt. Dabei werden die an­
+          gegebenen Projektionsparameter nicht beachtet, sondern die Angaben in #on("bold")#
+          Zentimeter#off("bold")# berechnet. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+ 
+move cm r 
+   PROC move cm r (PICTURE VAR p, REAL CONST x, y) 
+   Zweck: Die aktuelle Position wird um (x, y) cm erhöht. Dabei werden die an­
+          gegebenen Projektionsparameter nicht beachtet, sondern die Angaben in #on("bold")#
+          Zentimeter#off("bold")# berechnet. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+ 
+bar 
+   PROC bar (PICTURE VAR p, REAL CONST width, hight, INT CONST
+   pattern): 
+   Zweck: Die Prozedur zeichnet an der aktuellen Position einen Balken mit dem
+              Muster #on("italics")#pattern#off("italics")#: 0  =  Leerer Balken 
+              1  =  Gepunkteter Balken 
+              2  =  Gefüllter Balken 
+              3  =  Horizontale Linien 
+              4  =  Vertikale Linien 
+              5  =  Gekreuzte Linien 
+              6  =  Diagonale Linien von Links nach Rechts 
+              7  =  Diagonale Linien von Rechts nach Links 
+              8  =  Gekreuzte diagonale Linien. 
+          Die aktuelle Stiftposition wird dabei nicht verändert. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+       * Unknown pattern 
+         Das angegebene Muster liegt nicht im Bereich 0-8 
+ 
+circle 
+   PROC circle (PICTURE VAR p, REAL CONST from, to, INT CONST
+   pattern) 
+   Zweck: Die Prozedur zeichnet an der aktuellen Position ein Kreissegment vom
+          Winkel #on("italics")#from#off("italics")# bis #on("italics")#to#off("italics")# (im Gradmaß) mit dem Muster #on("italics")#pattern#off("italics")# (s.o.). Die
+          aktuelle Stiftposition wird dabei nicht verändert. 
+   Fehlerfälle: 
+       * Picture overflow 
+         Zu viele Befehle in einem PICTURE 
+       * Picture is three dimensional 
+       * Unknown pattern 
+         Das angegebene Muster liegt nicht im Bereich 0-8 
+ 
+dim 
+   INT PROC dim (PICTURE CONST pic) 
+   Zweck: Liefert die Dimension eines PICTURE. 
+ 
+pen 
+   INT PROC pen (PICTURE CONST p) 
+   Zweck: Liefert den virtuellen Stift des PICTURE 
+ 
+   PROC pen (PICTURE VAR p, INT CONST pen) 
+   Zweck: Setzen des (virtuellen) Stiftes eines PICTURE. Bei pen=0 wird das
+          Picture nicht gezeichnet. 
+   Fehlerfälle: 
+       * pen out of range 
+         Der gewünschte Stift ist kleiner als 0 oder größer als 16. 
+ 
+extrema 
+   PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y
+   max) 
+   Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICTURE. 
+   Fehlerfälle: 
+       * Picture is three dimensional 
+ 
+   PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y
+                                           max, z min, z max) 
+   Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICTURE. 
+   Fehlerfälle: 
+       * Picture is two dimensional 
+ 
+where 
+   PROC where (PICTURE CONST p, REAL VAR x, y, z) 
+   Zweck: Die Prozedur liefert die aktuelle Stiftposition (Angaben mit #on("italics")#cm#off("italics")# werden
+          dabei nicht berücksichtigt). 
+   Fehlerfälle: 
+       * Picture is two dimensional 
+ 
+   PROC where (PICTURE CONST p, REAL VAR x, y, z) 
+   Zweck: Die Prozedur liefert die aktuelle Stiftposition (Angaben mit #on("italics")#cm#off("italics")# werden
+          dabei nicht berücksichtigt). 
+   Fehlerfälle: 
+       * Picture is three dimensional 
+ 
+rotate: 
+   PROC rotate (PICTURE VAR p, REAL CONST angle) 
+   Zweck: Das PICTURE wird um den Punkt (0, 0) um den Winkel #on("italics")#angle#off("italics")# (im
+          Gradmaß) im mathematisch positiven Sinn gedreht. 
+          Dabei werden nur die Werte von #on("italics")#draw, draw r, move #off("italics")# und #on("italics")#move r#off("italics")#
+          verändert. 
+ 
+   PROC rotate (PICTURE CONST p, REAL CONST phi, theta, lambda ) :
+   PICTURE 1-397 
+   Zweck: Das PICTURE wird um den Winkel #on("italics")#lambda#off("italics")# um die Drehachse #on("italics")#(phi,
+          theta)#off("italics")# gedreht. 
+          Dabei werden nur die Werte von #on("italics")#draw, draw r, move #off("italics")# und #on("italics")#move r#off("italics")#
+          verändert. 
+ 
+stretch 
+   PROC stretch (PICTURE VAR pic, REAL CONST sx, sy) 
+   Zweck: Das PICTURE wird in X-Richtung um den Faktor #on("italics")#sx#off("italics")#, in Y-Rich­
+          tung um den Faktor #on("italics")#sy#off("italics")# gestreckt (bzw. gestaucht). Dabei bewirkt der
+          Faktor 
+              s > 1    eine Streckung 
+          0 < s < 1    eine Stauchung 
+              s < 0    zusätzlich eine Achsenspiegelung. 
+          Dabei werden nur die Werte von #on("italics")#draw, draw r, move #off("italics")# und #on("italics")#move r#off("italics")#
+          verändert. 
+   Fehlerfälle: 
+       * Picture is three dimensional 
+ 
+   PROC stretch (PICTURE VAR p, REAL CONST sx, sy, sz) 
+   Zweck: s. o. 
+   Fehlerfälle: 
+       * Picture is two dimensional 
+ 
+translate 
+   PROC translate (PICTURE VAR p, REAL CONST dx, dy) 
+   Zweck: Das PICTURE wird um #on("italics")#dx#off("italics")# und #on("italics")#dy#off("italics")# verschoben. 
+          Dabei werden nur die Werte von #on("italics")#draw, draw r, move #off("italics")# und #on("italics")#move r#off("italics")#
+          verändert. 
+   Fehlerfälle: 
+       * Picture is three dimensional 
+ 
+   PROC translate (PICTURE VAR p, REAL CONST dx, dy, dz) 
+   Zweck: s. o. 
+   Fehlerfälle: 
+       * Picture is two dimensional 
+ 
+plot PROC plot (PICTURE CONST p) 
+   Zweck: Das Picfile wird gezeichnet. 
+          Achtung: Es wird kein #on("italics")#begin plot#off("italics")# oder #on("italics")#end plot#off("italics")# durchgeführt. Es wird
+                   auch kein Stift gsetzt und die Projektionsparameter bleiben
+                   unverändert. 
+ 
+ 
+#on("underline")#Graphische PICFILE-Prozeduren#off("underline")# 
+plot 
+  PROC plot (TEXT CONST name) 
+  Zweck: Der PICFILE mit dem Namen #on("italics")#name#off("italics")# wird entsprechend der angegebenen
+         Darstellungsart gezeichnet. Diese Parameter (#on("italics")#perspective, orthographic,
+         oblique, view, window etc.#off("italics")#) müssen vorher eingestellt werden. 
+  Fehlerfälle: 
+      * PICFILE does not exist 
+        Es existiert kein PICFILE mit dem Namen #on("italics")#name#off("underline")# 
+ 
+  PROC plot (PICFILE VAR p) 
+  Zweck: Der PICFILE #on("italics")#p#off("italics")# wird entsprechend der angegebenen Darstellungsart ge­
+         zeichnet. Diese Parameter müssen vorher eingestellt werden: 
+ 
+         #on("bold")#zweidimensional:#off("bold")# 
+         obligat:        #on("italics")#window#off("italics")#            (zweidimensional) 
+         optional:       #on("italics")#view#off("italics")#              (zweidimensional) 
+                         #on("italics")#viewport#off("italics")# 
+                         #on("italics")#select pen#off("italics")# 
+ 
+         #on("bold")#dreidimensional:#off("bold")# 
+         obligat:        #on("italics")#window#off("italics")#            (dreidimensional) 
+         optional:       #on("italics")#view#off("italics")#              (dreidimensional) 
+                         #on("italics")#orthographic | perspective | oblique#off("italics")# 
+                         #on("italics")#viewport#off("italics")# 
+                         #on("italics")#select pen#off("italics")# 
+ 
+ 
+select pen 
+  PROC select pen (PICFILE VAR p, INT CONST pen, colour, thickness, line
+  type, 
+                                  BOOL VAR hidden lines) Zweck: Für die
+         Darstellung des Bildes #on("italics")#p#off("italics")# soll dem #on("italics")#virtuellen#off("italics")# Stift #on("italics")#pen#off("italics")# ein realer Stift
+         zugeordnet werden, der möglichst die Farbe #on("italics")#colour#off("italics")# und die Dicke #on("italics")#thick­
+         ness#off("italics")# hat und dabei Linien mit dem Typ #on("italics")#line type#off("italics")# zeichnet. Es wird die
+         beste Annäherung für das Ausgabegerät genommen. 
+         Wenn #on("italics")#hidden lines#off("italics")# auf TRUE gesetzt wird, werden bei dreidimensionalen
+         Zeichnungen die verdeckten Linien mitgezeichnet, ansonsten werden sie
+         unterdrückt. Um sicherzustellen, das der Algorithmus auch funktioniert,
+         müssen die Linien allerdings von vorn nach hinten gezeichnet werden. Es
+         ist also nicht möglich, das Bild so zu drehen, das die hinteren Linien
+         zuerst gezeichnet werden. 
+         Dabei gelten folgende Vereinbarungen: 
+ 
+         #on("bold")#Farbe:#off("bold")# Negative Farben werden XOR gezeichnet (dunkel wird hell und
+                hell wird dunkel), Farbe 0 ist der Löschstift und positive Farben
+                überschreiben (ersetzen) den alten Punkt mit folgenden Werten: 
+ 
+                1      Standardfarbe des Endgerätes 
+                2      rot 
+                3      blau 
+                4      grün 
+                5      schwarz 
+                6      weiß 
+                > 6    nicht normierte Sonderfarben 
+ 
+ 
+         #on("bold")#Dicke:#off("bold")# 0 Standardstrichstärke des Endgerätes, ansonsten Strichstärke in
+                1/10 mm. 
+ 
+ 
+         #on("bold")#Linientyp:#off("bold")# 
+                0      keine sichtbare Linie 
+                1      durchgängige Linie 
+                2      gepunktete Linie 
+                3      kurz gestrichelte Linie 
+                4      lang gestrichelte Linie 
+                5      Strichpunktlinie 
+                > 5    nicht normierte Linie 
+ 
+         #on("bold")#Verdeckte Linien:#off("bold")# 
+                TRUE   Verdeckte Linien werden mitgezeichnet 
+                FALSE  Verdeckte Linien werden unterdrückt (nur bei drei­
+                       dimensionalen PICTURE) 
+ 
+         Die hier aufgeführten Möglichkeiten müssen nicht an allen graphischen
+         Endgeräten vorhanden sein. Der geräteabhängige Graphik-Treiber wählt
+         jeweils die bestmögliche Annäherung. 
+ 
+  Fehlerfälle: 
+      * pen out of range 
+        #on("italics")#pen#off("italics")# muss im Bereich 1-16 sein. 
+ 
+background 
+  PROC background (PICFILE VAR p, INT CONST colour) 
+  Zweck: Der Hintergrund wird auf die Farbe #on("italics")#colour#off("italics")# (s.o.) gesetzt wenn möglich. 
+ 
+  INT PROC background (PICFILE CONST p): 
+  Zweck: Liefert die eingestellte Hintergrundfarbe. 
+ 
+view 
+  PROC view (PICFILE VAR p, REAL CONST alpha) 
+  Zweck: Setzt den Winkel der Y-Achse zur Senkrechten auf #on("italics")#alpha#off("italics")# Grad, falls
+         diese nicht senkrecht zur Betrachtungsebene steht. 
+ 
+  PROC view (PICFILE VAR p, REAL CONST phi, theta) 
+  Zweck: Dreidimensionale Bilder werden häufig nicht direkt von vorne dargestellt,
+         sondern für die Betrachtung gedreht. Mit der Prozedur #on("italics")#view#off("italics")# kann die
+         Betrachtungsrichtung durch die Polarwinkel #on("italics")#phi#off("italics")# und #on("italics")#theta#off("italics")# (im Gradmass)
+         angegeben werden. Voreingestellt ist #on("italics")#phi#off("italics")# = 0 und #on("italics")#theta#off("bold")# = 0, d.h. senk­
+         recht von oben. 
+ 
+         Im Gegensatz zu #on("italics")#rotate#off("italics")# hat #on("italics")#view#off("italics")# keine Wirkung auf das eigentliche Bild
+         (PICFILE), sondern nur auf die gewählte Darstellung. So addieren sich
+         zwar aufeinanderfolgende #on("italics")#Rotationen#off("italics")#, #on("italics")#view#off("italics")# aber geht immer von der
+         Nullstellung aus. Auch kann das Bild durch eine #on("italics")#Rotation#off("italics")# ganz oder
+         teilweise aus oder in das Darstellungsfenster (#on("italics")#window#off("italics")# gedreht werden. Bei
+         #on("italics")#view#off("italics")# verändern sich die Koordinaten der Punkte nicht, d. h. das Fenster
+         wird mitgedreht. 
+ 
+  PROC view (PICFILE VAR p, REAL CONST x, y, z) 
+  Zweck: Wie oben, nur werden die Winkel nicht in Polarkoordinaten angegeben,
+         sondern es wird die Blickrichtung als Vektor in Karthesischen Koordina­
+         ten angegeben. (Die Länge darf ungleich 1 sein). 
+ 
+viewport 
+  PROC viewport (PICFILE VAR p, REAL CONST hormin, hormax, vertmin,
+  vertmax) : 1-709 
+  Zweck: Die Zeichenfläche auf dem Endgerät, auf dem das Bild dargestellt werden
+         soll, wird spezifiziert. Dabei wird sowohl die Größe als auch die relative
+         Lage der Zeichenfläche definiert. Der linke untere Eckpunkt der physi­
+         kalischen Zeichenfläche des Gerätes hat die Koordinaten (0, 0). Die
+         definierte Zeichenfläche erstreckt sich 
+ 
+                #on("italics")#hormin   -  hormax#off("italics")#        in der Horizontalen, 
+                #on("italics")#vertmin  -  vertmax#off("italics")#       in der Vertikalen. 
+ 
+         So liegt der linke untere Eckpunkt dann bei (#on("italics")#hormin, hormax#off("italics")#), der rechte
+         obere Eckpunkt bei (#on("italics")#hormax, vertmax#off("italics")#). 
+ 
+         Damit sowohl geräteunabhängige als auch maßstabgetreue Zeichnungen
+         möglich sind, können die Koordinaten in zwei Arten spezifiziert werden: 
+         a)  #on("bold")#Gerätekoordinaten#off("bold")# 
+             Die Koordinaten können Werte von 0.0 bis 2.0 annehmen. Dabei
+             hat die kürzere Seite der physikalischen Zeichenfläche definitionsge­
+             mäß die Länge 1.0. 
+         b)  #on("bold")#Absolute Koordinaten#off("bold")# 
+             Die Werte werden in #on("italics")#cm#off("italics")# angegeben. Dabei müssen die Maximal­
+             werte aber größer als 2.0 sein, da sonst Fall a) angenommen wird. 
+ 
+         Voreingestellt ist 
+ 
+                viewport (0.0, 1.0, 0.0, 1.0) 
+ 
+         d.h. das größtmögliche Quadrat, beginnend mit der linken unteren Ecke
+         der physikalischen Zeichenfläche. In vielen Fällen wird diese Einstellung
+         ausreichen, so daß der Anwender kein eigenes #on("italics")#viewport#off("italics")# definieren muss. 
+ 
+         Der Abbildungsmaßstab wird durch das Zusammenspiel von #on("italics")#viewport#off("italics")# und
+         #on("italics")#window#off("italics")# festgelegt (s. dort). Dabei ist insbesondere darauf zu achten, daß
+         winkeltreue Darstellung nur bei gleichen X- und Y-Maßstab möglich
+         ist. Da man oft quadratische Fenster (#on("italics")#window#off("italics")#) verwendet, wurde als
+         Standardeinstellung auch ein quadratisches #on("italics")#viewport#off("italics")# gewählt. 
+ 
+  Hinweis: Mit der Prozedur #on("italics")#check limit#off("italics")# aus dem PACKET #on("italics")#basis plot#off("italics")# kann die
+           Überprüfung der Grenzen des eingestellten #on("italics")#viewport#off("italics")#-Bereiches ein-
+           bzw. ausgeschaltet werden. Bei eingeschateter Überprüfung, werden
+           Linien, die den Bereich überschreiten, am Rand abgetrennt. 
+ 
+ 
+window 
+  PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max) 
+  Zweck: Für die Darstellung eines zweidimensionalen Bildes wird das darzustel­
+         lende Fenster definiert. Alle Bildpunkte, deren X-Koordinaten im In-
+         tervall [#on("italics")#x min, x max#off("italics")#] und deren Y-Koordinaten im Bereich [#on("italics")#y min, y
+         max#off("italics")#] liegen, gehören zum definierten Fenster.Vektoren, die außerhalb
+         dieses Fensters liegen, gehen über die durch #on("italics")#viewport#off("italics")# Fläche hinaus
+         (s.dort). 
+ 
+         Der Darstellungsmaßstab ergibt sich als 
+ 
+         #ub#               x max - x min               #ue# 
+          horizontale Seitenlänge der Zeichenfläche 
+ 
+ 
+         #ub#               y max - y min               #ue# 
+           vertikale Seitenlänge der Zeichenfläche 
+ 
+  PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max,
+                                                       z min, z max) 
+ 
+  Zweck: Für die darstellung eines dreidimensionalen Bildes wird das darzustellende
+         Fenster definiert. Alle Bildpunkte, deren X-Koordinaten im Intervall [#on("italics")#x
+         min, x max#off("italics")#], deren Y-Koordinaten im Bereich [#on("italics")#y min, y max#off("italics")#] und
+         deren Z-Koordinaten im Bereich [#on("italics")#z min, z max#off("italics")#] liegen, gehören zum
+         definierten Fenster. Dieses dreidimensionale Fenster (#on("italics")#Quader#off("italics")#) wird ent­
+         sprechend der eingestellten Projektionsart (orthographisch, perspektivisch
+         oder schiefwinklig) und den Betrachtungswinkeln (s. #on("italics")#view#off("italics")#) auf die spezi­
+         fizierte Zeichenfläche abgebildet. 
+         Anders als im zweidimensionalen Fall ist das Problem der Maßstaäbe
+         nicht mehr nur durch das Zusammenspiel von #on("italics")#window#off("italics")# und #on("italics")#viewport#off("italics")# zu
+         beschreiben. Hier spielen auch die Projektionsart und Darstellungswinkel
+         herein. 
+ 
+oblique: 
+  PROC oblique (PICFILE VAR p, REAL CONST a, b) 
+  Zweck: Bei dem (dreidimensionalen) Bild #on("italics")#p#off("italics")# wir #on("underline")#schiefwinklig#off("underline")# als gewünschte
+         Projektionsart eingestellt. Dabei ist (#on("italics")#a, b#off("italics")#) der Punkt auf der X-Y-
+         Ebene, auf den der Einheitsvektor der Z-Richtung abgebildet werden
+         soll. 
+ 
+orthographic 
+  PROC orthographic (PICFILE VAR p) 
+  Zweck: Bei dem (dreidimensionalen) Bild #on("italics")#p#off("italics")# wir #on("underline")#orthographisch#off("underline")# als gewünschte
+         Projektionsart eingestellt. Bei der orthographischen Projektion wird ein
+         dreidimensionaler Körper mit parallelen Strahlen senkrecht auf der Pro­
+         jektionsebene dabgebildet. 
+ 
+perpective 
+  PROC perspective (PICFILE VAR p, REAL CONST cx, cy, cz) 
+  Zweck: Bei dem (dreidimensionalen) Bild #on("italics")#p#off("italics")# wir #on("underline")#perspectivisch#off("underline")# als gewünschte
+         Projektionsart eingestellt. Der Punkt (#on("italics")#cx, 1/cy, cz#off("underline")#) ist der Fluchtpunkt der
+         Projektion, d. h. alle Parallen zur Z-Achse schneiden sich in diesem
+         Punkt. 
+ 
+extrema 
+  PROC extrema (PICFILE VAR p, REAL VAR x min, x max, y min, y max) 
+  Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICFILE. 
+ 
+  PROC extrema (PICFILE VAR p, REAL VAR x min,x max,y min,y max,z
+  min,z max) : 1-651 
+  Zweck: Die Prozedur liefert die größten und kleinsten Werte des PICFILE. 
+ 
+ 
+#on("underline")#Prozeduren zur Manipulation von PICFILE#off("underline")# 
+:= 
+  OP := (PICFILE VAR p, DATASPACE CONST d) 
+  Zweck: Assoziert die PICFILE Variable #on("italics")#p#off("italics")# mit dem Datenraum #on("italics")#d#off("italics")# und initialisiert
+         die Variable, wenn nötig. 
+  Fehlerfälle: 
+      * dataspace is no PICFILE 
+        Der anzukoppelnde Datenraum hat einen unzulässigen Typ 
+ 
+picture file 
+  DATASPACE PROC picture file (TEXT CONST name) 
+  Zweck: Assoziaten eines benannten Datenraumes mit einem PICFILE (s.o.). 
+ 
+put 
+  PROC put (FILE VAR f, PICFILE VAR p) 
+  Zweck: Schreibt den Inhalt eines PICFILE in ein FILE. Die Informationen
+         werden im internen Format abgelegt. 
+ 
+get 
+  PROC get (PICFILE VAR p, FILE VAR f) 
+  Zweck: Liest den Inhalt eines PICFILE aus einem FILE. Die Informationen
+         müssen mit #on("italics")#put#off("italics")# geschrieben worden sein. 
+  Fehlerfall: 
+      *  Picfile overflow 
+         Es können nur maximal 1024 Picture (Sätze) in einem PICFILE abgelegt
+         werden. 
+ 
+to first pic 
+  PROC to first pic (PICFILE VAR p) 
+  Zweck: Positioniert auf das erste PICTURE. 
+ 
+to eof 
+  PROC to last pic (PICFILE VAR p) 
+  Zweck: Positioniert hinter das letzte PICTURE. 
+ 
+to pic 
+  PROC to pic (PICFILE VAR p, INT CONST pos) 
+  Zweck: Positioniert auf das PICTURE Nummer #on("italics")#pos#off("italics")#. 
+  Fehlerfälle: 
+      *  Position underflow 
+         Es wurde eine Position kleiner Null angegeben. *  Position after
+         eof Es wurde versucht, hinter das Ende eines PICFILE zu positionieren 
+ 
+up 
+  PROC up (PICFILE VAR p) 
+  Zweck: Positioniert genau ein PICTURE zurück. 
+  Fehlerfall: 
+      *  Position underflow 
+         Es wurde versucht, vor das erste PICTURE zu positionieren 
+ 
+  PROC up (PICFILE VAR p, INT CONST n) 
+  Zweck: Positioniert genau #on("italics")#n#off("italics")# Picture zurück. 
+  Fehlerfall: 
+      *  Position underflow 
+         Es wurde versucht, vor das erste PICTURE zu positionieren 
+ 
+down 
+  PROC down (PICFILE VAR p) 
+  Zweck: Positioniert genau ein PICTURE vorwärts. 
+  Fehlerfall: 
+      *  Position after eof 
+         Es wurde versucht, hinter das Ende eines PICFILE zu positionieren 
+ 
+  PROC down (PICFILE VAR p, INT CONST n) 
+  Zweck: Positioniert genau #on("italics")#n#off("italics")# Picture vorwärts. 
+  Fehlerfall: 
+      *  Position after eof 
+         Es wurde versucht, hinter das Ende eines PICFILE zu positionieren 
+ 
+is first picture 
+  BOOL PROC is first picture (PICFILE CONST p) 
+  Zweck: Liefert genau dann #on("italics")#TRUE#off("italics")#, wenn das erste PICTURE erreicht ist. 
+ 
+eof 
+  BOOL PROC eof (PICFILE CONST p) 
+  Zweck: Liefert genau dann #on("italics")#TRUE#off("italics")#, wenn das Ende eines PICFILE erreicht ist. 
+ 
+picture no 
+  INT PROC picture no (PICFILE CONST p) 
+  Zweck: Liefert die Nummer des aktuellen PICTURE. 
+ 
+pictures 
+  INT PROC pictures (PICFILE CONST p) 
+  Zweck: Liefert die Anzahl PICTURE eines PICFILE. 
+ 
+delete picture 
+  PROC delete picture (PICFILE VAR p) 
+  Zweck: Löscht das aktuelle PICTURE 
+ 
+insert picture 
+  PROC insert picture (PICFILE VAR p) 
+  Zweck: Fügt ein PICTURE #on("underline")#vor#off("underline")# der aktuellen Position ein. 
+ 
+read picture 
+  PROC read picture (PICFILE CONST p, PICTURE VAR pic) 
+  Zweck: Liest das aktuelle PICTURE. 
+ 
+write picture 
+  PROC write picture (PICFILE VAR p, PICTURE CONST pic) 
+  Zweck: Schreibt das PICTURE #on("italics")#pic#off("italics")# auf der aktuellen Position. 
+ 
+put picture 
+  PROC write picture (PICFILE VAR p, PICTURE CONST pic) 
+  Zweck: Schreibt das PICTURE #on("italics")#pic#off("italics")# hinter das letzte PICTURE des PICFILE.
+         Die aktuelle Position wird nicht verändert. 
+ 
+#page# 
+                                    #on("italics")#Wo wir sind, da klappt nichts, 
+                                    aber wir können nicht überall sein !#off("italics")# 
+ 
+#type ("basker14")# 
+#on("bold")#Kurzbeschreibung des Graphik-Editors#off("bold")# 
+#type ("basker12")# 
+ 
+In der Kommondozeile werden folgende Informationen angezeigt: 
+ 
+#on("revers")#LEN nnnnn                <...Name...>      DIM n  PEN nn    Picture nnnn
+#off("revers")# 
+ 
+ 
+Folgende Kommandos stehen zur Verfügung: 
+ 
+  PICTURE PROC pic neu 
+  PICFILE PROC picfile neu 
+  PROC neu zeichnen 
+ 
+  OP UP n         (n PICTURE up) 
+  OP DOWN n       (n PICTURE down) 
+  OP T n          (to PICTURE n) 
+ 
+  PROC oblique (REAL CONST a, b) 
+  PROC orthographic 
+  PROC perspective (REAL CONST cx, cy, cz) 
+  PROC window (BOOL CONST dev) 
+  PROC window (REAL CONST x min, x max, y min, y max) 
+  PROC window (REAL CONST x min, x max, y min, y max, z min, z max) 
+  PROC viewport (REAL CONST h min, h max, v min, v max) 
+  PROC view (REAL CONST alpha) 
+  PROC view (REAL CONST phi, theta) 
+  PROC view (REAL CONST x, y, z) 
+ 
+  PROC pen (INT CONST n) 
+  PROC select pen (INT CONST pen, colour, thickness, line type, BOOL CONST
+  hidden) 
+  PROC background (INT CONST colour) 
+ 
+  PROC extrema pic 
+  PROC extrema picfile 
+  PROC selected pen 
+ 
+  PROC rotate (REAL CONST angle) 
+  PROC rotate (REAL CONST phi, theta, lambda ) 
+  PROC stretch (REAL CONST sx, sy) 
+  PROC stretch (REAL CONST sx, sy, sz) 
+  PROC translate (REAL CONST dx, dy) 
+  PROC translate (REAL CONST dx, dy, dz) 
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Inhaltsverzeichnis b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Inhaltsverzeichnis
new file mode 100644
index 0000000..5726636
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Inhaltsverzeichnis	
@@ -0,0 +1,45 @@
+#limit (11.5)##pagelength (16.5)#
+#start (1.8,1.0)# 
+Inhaltsverzeichnis 
+ 
+ 
+ 
+1      Was kann gs-Herbert und Robbi                 3 
+ 
+2      Allgemeines zum Hamster-/Robotermodell        6 
+2.1    Entstehung                                    6 
+2.2    Kurzbeschreibung des Hamster-/Roboter- 
+       Modells                                       7 
+2.2.1  Befehle und Tests                             7 
+2.2.2  Landschafts-/Arbeitsfeldgestaltung            9 
+2.3    Einsatzbereich                               11 
+2.4    Hinweise für den Einsatz in der Ausbildung   12 
+2.5    Aufgabenmaterial                             14 
+2.6    Erfahrungen mit dem Hamster-/Roboter-Modell  14 
+ 
+3      Installation von gs-Herbert und Robbi        17 
+3.1    Voraussetzungen                              17 
+3.2    Lieferumfang                                 17 
+3.3    Installation                                 18 
+3.4    Direktstart des Medells                      20 
+ 
+4      Beschreibung der Menufunktionen              22 
+4.1    Kurzhinweise zur Bedienung des Menus         23 
+4.2    Menufunktionen zum Oberbegriff 'Info'        27 
+4.3    Menufunktionen zum Oberbegriff 'Landschaft'  29 
+       Menufunktionen zum Oberbegriff 'Arbeitsfeld' 29 
+4.4    Menufunktionen zum Oberbegriff  'Programm'   35 
+4.5    Menufunktionen zum Oberbegriff  'Lauf'       41 
+4.6    Menufunktionen zum Oberbegriff  'Archiv'     46 
+ 
+5      Detailbeschreibung der Basisbefehle          61 
+ 
+6      Zusätzliche Kommandos                        66 
+ 
+
+
+
+
+
+
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 1 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 1
new file mode 100644
index 0000000..73c95f9
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 1	
@@ -0,0 +1,93 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (3)# 
+#headodd# 
+#center#gs-Herbert und Robbi#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Herbert und Robbi 
+ 
+#end# 
+#center#1 
+ 
+#center#Was 
+#center#kann 
+#center#gs-Herbert und Robbi 
+ 
+ 
+   Mit #on("b")#gs-Herbert und Robbi#off("b")# liegt das von Lothar Oppor
+entwickelte und von Wolfgang Weber weiterentwickelte
+Hamster-Modell nun eingebettet in die komfortable,
+menuorientierte Benutzerschnittstelle #on("b")#gs-DIALOG#off("b")# vor. Das
+Programm stellt eine wesentliche Erweiterung des 'alten'
+Hamster - Modells dar. Neben einer zweiten Modellvarian­
+te (Roboter) wurden eine Reihe nützlicher Funktionen in
+das Modell integriert. Sämtlich Funktionen werden über
+ein übersichtliches Menu angeboten, was gerade dem An­
+fänger die Arbeit mit dem Computer erleichtert. 
+ 
+   #on("b")#gs-Herbert und Robbi#off("b")# kann zur Einführung in das al­
+gorithmische Problemlösen eingesetzt werden und soll
+dazu dienen, Programmierung #on("u")#einfach#off("u")# und #on("u")#spielerisch#off("u")# zu
+erlernen - ohne Ablenkung durch Betriebssystem oder gar
+Hardware-Eigenheiten. 
+ 
+   Das Modell ist so einfach und überschaubar, daß ein
+Anfänger schon nach einer halben Stunde in der Lage ist,
+sich selbst kleine Aufgaben zu stellen und diese zu lösen.
+Die Modellumgebung ist so komfortabel, daß der Anfänger
+nach einer kurzen Einweisung selbständig mit dem Compu­
+termodell umgehen kann. 
+ 
+-  Durch die Menuführung sind nur noch wenige Be­
+   triebssystemkommandos zur Bedienung des Systems
+   notwendig. 
+ 
+-  Der Benutzer kann jederzeit Informationen anfordern
+   über: 
+     -  den zur Verfügung stehenden Befehlsumfang, 
+     -  die Möglichkeiten, den Lauf des Hamsters/Robo­
+        ters zu beeinflussen, 
+     -  die Möglichkeiten hinsichtlich der Landschafts­
+        gestaltung/Arbeitsfeldgestaltung 
+     -  die Bedienung des Menusystems 
+     -  die Wirkung der einzelnen Menufunktionen 
+     -  die Möglichkeiten/Bedienung des Editors 
+ 
+-  Neben der Steuerung des Hamsters/Roboters durch
+   Programme kann der Hamster/Roboter auch interaktiv
+   gesteuert werden; dabei wird ein Protokoll der ausge­
+   führten Aktionen in Form eines ablauffähigen ELAN-
+   Programms angelegt. Dieses Protokoll (Programm) kann
+   jederzeit eingesehen werden. Natürlich kann anschlie­
+   ßend der Hamster/Roboter die gleichen Aktionen, die
+   zuvor von Hand ausgeführt wurden, auch nach diesem
+   Programm ausführen. 
+ 
+-  Durch den (optional) erweiterbaren Befehlssatz kann
+   #on("b")#gs-Herbert und Robbi#off("b")# den Erfordernissen und der Lei­
+   stungsfähigkeit der Lernenden leicht angepaßt wer­
+   den. 
+ 
+-  Auch das Editieren und Drucken von Programmen sowie
+   Landschaften/Arbeitsfeldern erfolgt vom Menu aus. 
+ 
+-  Die Archivoperationen, die gerade Anfängern zunächst
+   große Probleme bereiten, können sämtlichst komforta­
+   bel vom Menu aus gehandhabt werden. Dabei werden
+   Anfragen an den Benutzer gestellt, die zumeist nur
+   mit 'ja' oder 'nein' zu beantworten sind; oder der Be­
+   nutzer hat in einer Auswahlliste die gewünschten Da­
+   teinamen anzukreuzen. 
+ 
+-  Die Archivoperationen stehen dem Benutzer auch unab­
+   hängig vom Hamster-/Robotermodell unter #on("b")#gs-DIALOG#off("b")#
+   zur Verfügung, so daß beim Verlassen der Modellum­
+   gebung "kein Bruch zu befürchten ist". 
+ 
+-  Die Fehlermeldungen sind detailliert und leicht ver­
+   ständlich, so daß auch Anfänger die Fehlerquelle(n)
+   zumeist ohne zusätzliche Hilfen lokalisieren und be­
+   seitigen können. 
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 2 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 2
new file mode 100644
index 0000000..52526d6
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 2	
@@ -0,0 +1,389 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (6)# 
+#headodd# 
+#center#gs-Herbert und Robbi#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Herbert und Robbi 
+ 
+#end# 
+#center#2 
+ 
+#center#Allgemeines 
+#center#zum 
+#center#Hamster-/Robotermodell 
+ 
+ 
+2.1  Entstehung 
+ 
+   Das Hamster - Modell wurde in der Gesellschaft für
+Mathematik und Datenverarbeitung (GMD), einer Großfor­
+schungseinrichtung des Bundes und des Landes Nord­
+rhein-Westfalen, von Lothar Oppor in Anlehnung an das
+Modell 'Karel the Robot' von Richard E. Pattis (Stanford
+University, USA) entwickelt und zunächst innerhalb der
+GMD und schon bald im Schulbereich eingesetzt. 
+   Wolfgang Weber, Lehrer an der Gesamtschule Leopolds­
+höhe bei Bielefeld, entwickelte in Zusammenhang mit sei­
+ner Arbeit am Landesinstitut für Schule und Weiterbil­
+dung in Soest dieses Modell seit 1984 weiter. Sein Ziel war
+es, das Modell um solche Komponenten zu erweitern, daß es
+auch für Schüler der Sekundarstufe I im Anfangsunter­
+richt eingesetzt werden kann. Besondere Bedeutung kam
+dabei der Entwicklung einer komfortablen, einfach zu be­
+dienenden Benutzerschnittstelle zu, die es dem Anfänger
+ermöglicht, sich von Beginn an mit der eigentlichen Pro­
+blemstellung auseinanderzusetzen, ohne von Betriebssy­
+stem oder gar Hardware-Eigenheiten abgelenkt zu werden. 
+   Mit dem vorliegenden Programm #on("b")#gs-Herbert und Robbi#off("b")#,
+das in die komfortable, menuorientierte  Benutzer­
+schnittstelle #on("b")#gs-DIALOG#off("b")# eingebettet ist, dürfte diese Ar­
+beit vorerst zu einem Abschluß gebracht sein. Mit diesem
+Programm liegt nun eine Modellumgebung vor, die den
+gestellten Anforderungen gerecht wird. 
+ 
+ 
+2.2  Kurzbeschreibung des Hamster-/Roboter-Modells 
+ 
+   Das Hamster- und das Roboter - Modell sind analog
+aufgebaut und in Art und Umfang der Befehle identisch.
+Im ersten Modell kann 'Herbert der Hamster', im zweiten
+Modell 'Robbi der Roboter' auf dem Bildschirm durch vier
+sogenannte Basisbefehle gesteuert werden - 'Herbert' in
+einer 'Landschaft', 'Robbi' auf einem 'Arbeitsfeld' - beides
+Ebenen, die aus 23 x 40 Kacheln bestehen. 
+   Auf dieser Ebene können sich noch Hindernisse und
+'Körner' (für Herbert) oder 'Werkstücke' (für Robbi) befin­
+den. Die Hindernisse stellen auf dem Bildschirm Barrieren
+dar, die umgangen werden müssen. Die Körner bzw. Werk­
+stücke können von Herbert in seinen 'Backentaschen' bzw.
+von Robbi in seinem 'Behälter' aufgenommen oder daraus
+(wieder) abgelegt werden. 
+ 
+ 
+2.2.1  Befehle und Tests 
+ 
+   Für die Steuerung von Herbert bzw.Robbi stehen vier
+Basisbefehle zur Verfügung (die in beiden Modellvarian­
+ten gleich sind): 
+ 
+#on("u")#vor#off("u")# 
+  Gehe eine Kachel (einen Schritt) in Laufrichtung vor. 
+ 
+#on("u")#links um#off("u")# 
+  Drehe Dich, wo Du stehst, um 90 Grad nach links. 
+ 
+#on("u")#nimm#off("u")# 
+  Nimm da, wo Du stehst, ein Korn/Werkstück auf. 
+ 
+#on("u")#gib#off("u")# 
+  Lege da, wo Du stehst, aus den Backentaschen/dem Be­
+  hälter ein Korn/Werkstück ab. 
+ 
+   Da nur dort ein Korn/Werkstück aufgenommen werden
+kann, wo auch eines vorhanden ist oder nur vorgegangen
+werden kann, wenn die nächste Kachel noch zur Land­
+schaft/zum Arbeitsfeld gehört und nicht blockiert ist,
+sind die Befehle 'nimm', 'gib' und 'vor' nicht uneinge­
+schränkt ausführbar. Aus diesem Grunde sind noch die
+folgenden #on("u")#Basistests#off("u")# definiert: 
+ 
+#on("u")#vorn frei#off("u")# 
+  testet, ob die vor ihm liegende Kachel frei ist. 
+ 
+#on("u")#korn da / werkstueck da#off("u")# 
+  testet, ob auf der Kachel, auf der er steht, mindestens
+  ein Korn/Werkstück liegt. 
+ 
+#on("u")#backen leer /behaelter leer#off("u")# 
+  testet, ob kein Korn/Werkstück in den Backentaschen/im
+  Behälter ist. 
+ 
+   Darüberhinaus können Sie bei der Installation des
+Systems noch festlegen, ob die folgenden #on("u")#Zusatztests#off("u")# zur
+Verfügung stehen sollen oder nicht: 
+ 
+#on("u")#links frei#off("u")# 
+  testet, ob die Kachel links neben ihm frei ist. 
+ 
+#on("u")#rechts frei#off("u")# 
+  testet, ob die Kachel rechts neben ihm frei ist. 
+ 
+#on("u")#hinten frei#off("u")# 
+  testet, ob die Kachel hinter ihm frei ist. 
+ 
+#on("u")#korn vorn / werkstueck vorn#off("u")# 
+  testet, ob auf der Kachel vor ihm mindestens ein Korn/
+  Werkstück liegt. 
+ 
+#on("u")#korn links / werkstueck links#off("u")# 
+  testet, ob auf der Kachel links neben ihm mindestens
+  ein Korn/ Werkstück liegt. 
+ 
+#on("u")#korn rechts / werkstueck rechts#off("u")# 
+  testet, ob auf der Kachel rechts neben ihm mindestens
+  ein Korn/Werkstück liegt 
+ 
+#on("u")#korn hinten / werkstueck hinten#off("u")# 
+  testet, ob auf der Kachel hinter ihm mindestens ein
+  Korn/Werkstück liegt. 
+ 
+   Es gibt #on("u")#keinen#off("u")# Testbefehl, mit dem überprüft werden
+kann, ob der Rand der Ebene erreicht ist. 
+ 
+ 
+2.2.2  Landschaftsgestaltung/Arbeitsfeldgestaltung 
+ 
+   Der Benutzer kann selber Landschaften/Arbeitsfelder
+erstellen, auf denen Herbert bzw. Robbi bewegt werden
+kann. Es können aber auch fertige Ebenen verändert wer­
+den. 
+   Eine Landschaft/ein Arbeitsfeld ist eine Ebene aus
+23 x 40 Kacheln. Eine Kachel kann auf dem Bildschirm so
+aussehen: 
+ 
+    Leere Kachel  :    Blank und Punkt       (" .") 
+    Kornkachel    :    Blank und kleines o   (" o") 
+    Hindernis     :    zwei Nummernzeichen   ("\#\#") 
+ 
+   In dieser Landschaft steht auf einer der Kacheln Her­
+bert bzw. Robbi: 
+ 
+    "A"   mit Blickrichtung nach oben 
+    ">"   mit Blickrichtung nach rechts 
+    "V"   mit Blickrichtung nach unten 
+    "<"   mit Blickrichtung nach links 
+ 
+ 
+#on("u")#Beispiel:#off("u")# Ausschnitt aus einer Landschaft: 
+ 
+#on("b")# 
+             . . . . . . . . . . . . . . . . . . . . 
+             . . o o o o o o o o o o . . . . . . . . 
+             . . o . . . . . . . . o . . . . . . . . 
+             . . o . . . . . . . . o . . . . . . . . 
+             . o o .\#\#\#\#\#\#\#\#\#\#\#\# . o . . . . . . . . 
+             . o . .\#\# .V. . .\#\# . o o o o o o o . . 
+             . o . .\#\# . o . .\#\# . . . . . . . o . . 
+             . o o o o o o . .\#\# . . . o o o o o . . 
+             . . . .\#\# . . . .\#\# . . . o . . . . . . 
+             . . . .\#\# . . . .\#\# . . . o o o o . . . 
+             . . . .\#\#\#\#\#\#\#\#\#\#\#\# . . . . . . o o . . 
+             . . . . . . . . . . . . . . . . . . . . 
+ 
+Während der Landschaftsgestaltung wirken folgende
+Tasten: 
+ 
+<h>          halt, beende die Landschafts-/Arbeitsfeld­
+             gestaltung 
+<\#>          setze ein Hindernis und gehe ein Feld
+             weiter 
+<LEERTASTE>  leere das Feld und gehe ein Feld weiter 
+<g>          lege hier ein Korn/Werkstück ab 
+<n>          nimm ein Korn/Werkstück auf (falls hier
+             welche liegen) 
+<z>          zeige, wie viele Körner/Werkstücke hier
+             liegen 
+<k>          ersetze diese Landschaft/diese Arbeitsfeld
+             durch die Kopie einer bereits vorhandenen
+             anderen Landschaft/eines bereits vorhan­
+             denen anderen Arbeitsfeldes 
+ 
+-  Durch Drücken der Fragezeichentaste (<?>) während der
+   Landschafts-/Arbeitsfeldgestaltung, können Sie sich
+   diese Hinweise auch auf dem Bildschirm einblenden
+   lassen. 
+ 
+-  Mit den Pfeiltasten kann Herbert/Robbi bewegt und
+   seine Richtung verändert werden. 
+ 
+-  Die Landschaftsgestaltung wird durch Tippen der
+   Taste <h> abgeschlossen. Die Position und die Blick­
+   richtung, die Herbert bzw. Robbi zu diesem Zeitpunkt
+   innehat, wird als Startposition vermerkt. 
+ 
+-  Auf dem Bildschirm wird dann noch die Zahl der Kör­
+   ner/Werkstücke erfragt, die Herbert bzw.Robbi zu Be­
+   ginn des Laufes in seinen Backentaschen/in seinem
+   Behälter haben soll. Hier muß eine Zahl zwischen 0 und
+   32767 eingegeben werden. 
+ 
+ 
+2.3  Einsatzbereich 
+ 
+   Das Hamster-/Roboter-Modell soll dazu dienen, die
+Grundelemente des algorithmischen Problemlösens (Folge,
+Auswahl, Wiederholung etc.) #on("u")#einfach#off("u")# und #on("u")#spielerisch#off("u")# zu
+erlernen und sie in der Programmiersprache ELAN zu co­
+dieren. In der Bildschirmdarstellung erinnert das Ham­
+ster-/Roboter-Modell zunächst an ein einfaches Tele­
+spiel, eine Anwendung des Computers, die sicher bekannt
+ist. Darüberhinaus lassen sich leicht Bezüge zur Steue­
+rung von Industrierobotern herstellen. 
+   Durch die komfortable Benutzerschnittstelle wird dem
+Anwender in der Anfangsphase eine Auseinandersetzung
+mit dem Betriebssystem "erspart". Die Arbeit mit dem Mo­
+dell setzt #on("u")#keine Vorerfahrungen und Kenntnisse#off("u")# voraus.
+Das Modell ist schon nach weniger als einer halben Stun­
+de für den Anfänger überschaubar. Er kann dann schon
+Aufgaben lösen, sich selbst Aufgaben stellen bzw. die
+gegebene Aufgabenstellung erweitern. 
+   Das Modell zielt auf die Aktivierung des Lernenden
+und die Mitarbeit in allen Punkten: Aufgabenstellung,
+Lösungsgestaltung, Lösungstest und -verifizierung. Der
+Lernfortschritt kann in stärkerem Maße als im "herkömm­
+lichen Programmierunterricht" von den Lernenden selbst
+bestimmt werden. Der spielerische Anfang, die Veran­
+schaulichung der Programmausführung auf dem Bild­
+schirm, die Möglichkeit Fehler direkt und eigenständig
+zu erkennen, fördern die Motivation, die Kreativität und
+die Fehler- und Frustrationstoleranz. 
+ 
+ 
+2.4  Hinweise für den Einsatz in der Ausbildung 
+ 
+   Das Hamster-/Roboter-Modell ist angelegt für "Pro­
+grammieren" mit Bleistift und (kariertem) Papier. Für die
+Überlegungen, die anzustellen sind, ist der Computer
+selbst in der Anfangsphase #on("u")#nicht notwendig#off("u")#. Man kann
+Kachel-Landschaften / Kachel-Arbeitsfelder aufzeich­
+nen und vorgegebene oder sich selbst gestellte Aufgaben
+lösen. Die erstellten Programme werden ausgeführt, indem
+man z.B. eine kleine Büroklammer als Hamster/Roboter auf
+dem Papier oder der Folie dem Programm entsprechend ver­
+schiebt. Heftzwecken oder Pfennigstücke können als Kör­
+ner/ Werkstücke und Streichholzstücke als Hindernisse
+dienen. 
+   #on("b")#gs-Herbert und Robbi#off("b")# verfügt auch über die Möglich­
+keit, den Hamster/Roboter interaktiv zu steuern. Auch
+hierüber ist ein Einstieg in den Umgang mit dem Modell
+möglich. Bei der interaktiven Steuerung kann der Ham­
+ster/Roboter von Hand durch Tastendruck auf dem Bild­
+schirm bewegt werden. Dabei können nur die vier Basisbe­
+fehle ('vor', 'links um', 'nimm' und 'gib') verwendet werden.
+Während der Steuerung von Hand wird ein "Protokoll" der
+ausgeführten Befehle angelegt - und zwar gleich in Form
+eines ablauffähigen ELAN-Programms. Dadurch hat der
+Benutzer einerseits die Möglichkeit, die Anweisungen, die
+durch Tastendruck gegeben wurden, zu kontrollieren,
+andererseits kann anschließend die Folge der eingegebe­
+nen Anweisungen auch als Programm vom Computer ausge­
+führt werden ('Teach in'). 
+ 
+   Nach diesem "ersten Kennenlernen des Modells" sollte
+man dann aber bei Problemstellungen, die ein systemati­
+sches Vorgehen erfordern, die Arbeit mit dem Computer
+unterbrechen und die Algorithmen jeweils auf dem Papier
+entwerfen. Auf die Ausführung der erstellten Anwei­
+sungsfolgen von Hand auf Papier/Folie sollte man #on("u")#auf
+keinen Fall gänzlich verzichten#off("u")# - auch, um den Lernen­
+den zu verdeutlichen, daß die Befehlsfolgen sowohl vom
+"Prozessor Mensch" als auch vom "Prozessor Computer"
+ausgeführt werden können; der Computer also nur ein
+Hilfswerkzeug ist. 
+   Erst wenn das Bilden eigener benannter Anweisungen
+(Refinements/Prozeduren) den Lernenden hinreichend ver­
+traut ist, ist es sinnvoll, umfangreichere Problemstel­
+lungen anzugehen. Da dann auch die Programmausführung
+von Hand mühsam wird und ihren Reiz verliert, sollte man
+(wieder) zum Computermodell übergehen, um mit dessen Hil­
+fe die Programme auszuführen und zu überprüfen. 
+   Nachdem die Lernenden die Basisbefehle sicher beherr­
+schen und eigene benannte Anweisungen unter Verwendung
+der Basisbefehle konstruieren können, können dann nach
+und nach die vorgegebenen Tests und damit auch die ande­
+ren Elemente der Algorithmenentwicklung (Auswahl, Wie­
+derholung etc.) in den Unterricht eingebracht werden. 
+   Als notwendig hat es sich erwiesen, von Anfang an auf
+eine saubere Strukturierung und Modularisierung der
+Algorithmen zu achten. Gerade Lernende mit "Program­
+miererfahrung" neigen dazu, möglichst "kurze" Program­
+me schreiben zu wollen. Besonderen Wert sollten Sie auf
+eine treffende Namensgebung der einzelnen Module legen,
+selbst wenn die Lernenden das oft als "lästige Schreibar­
+beit" empfinden. Aufgaben können ein Einzel-, Partner-
+und Gruppenarbeit bearbeitet werden. Dabei hat sich die
+Arbeit in kleinen Gruppen als besonders effektiv erwie­
+sen. Die Lernenden sind untereinander zumeist sehr kri­
+tisch und fordern sich gegenseitig auf, "lesbare" Pro­
+gramme zu schreiben. Ein Austausch der Programme unter
+den Gruppen kann diesen Anspruch noch zusätzlich för­
+dern. 
+ 
+ 
+2.5  Aufgabenmaterial 
+ 
+   Zum Hamster-Roboter-Modell sind inzwischen eine Rei­
+he von Aufgaben / Aufgabensystemen enstanden. An dieser
+Stelle soll auf zwei Veröffentlichungen hingewiesen
+werden, in denen Sie solche Aufgaben / Aufgabensysteme
+finden können: 
+ 
+Weber, Wolfgang et al., Das Hamster-/Roboter-Modell, 
+   in:  Landesinstitut für Schule und Weiterbildung
+        (Hrsg.), Materialien zur Lehrerfortbildung in
+        Nordrhein-Westfalen, Heft 1, Neue Technologien
+        - Informations- und Kommunikationstechnologi­
+        sche Inhalte im Wahlpflichtunterricht der Klas­
+        sen 9/10, Soest, 1986 
+ 
+Ambros, Wolfgang, Der Hamster, Programmieren lernen in
+        einer Modellwelt, J.B. Metzlersche Verlagsbuch­
+        handlung, Stuttgart, 1987 
+ 
+ 
+2.6  Erfahrungen mit dem Hamster-/Roboter-Modell 
+ 
+   Seit 1982 wird das Hamster - Modell in der GMD zur
+Programmierausbildung eingesetzt. Die Ergebnisse sind
+hervorragend: Die Teilnehmer bewältigen in derselben
+Zeit erheblich mehr Inhalte als früher ohne Modell. Moti­
+vation, Selbständigkeit und Initiative prägen sich er­
+heblich früher und merklich stärker aus. Außerdem sind
+die am Modell erworbenen Kenntnisse tiefer und sicherer. 
+   Seit 1983 wird das Hamster - Modell auch in mehreren
+Schulen mit sehr gutem Erfolg eingesetzt. Der Erfolg ist
+am größten im Blockunterricht (3 - 5 Tage z.B. in Projekt­
+wochen, Schullandheimaufenthalten etc.). Aber auch im
+stundenweisen Unterricht wird das Hamster-/Roboter-
+Modell mit gutem Erfolg eingesetzt. 
+   Beide Zugänge, der Einstieg über das Arbeiten mit
+Bleistift und Papier und der Einstieg über die interakti­
+ve Steuerung des Hamsters/Roboters, haben sich als prak­
+tikabel erwiesen. Der Zugang über die interaktive Steue­
+rung bietet den Vorteil, die zumeist sehr hohe Motivation
+der Lernenden, "endlich mit dem Computer arbeiten zu
+können", auszunutzen. Sie lernen dabei das Computermo­
+dell auf einfache Weise kennen und haben einen ersten
+Umgang mit Bildschirm und Tastatur. Kleine, einfache
+Problemstellungen können von ihnen durch die interak­
+tive Steuerung schnell und sicher bearbeitet werden.
+"Nebenbei" lernen sie, neben der Wirkung der Basisbefeh­
+le, durch das mitgeführte Protokoll auch die Codierung
+in der Programmiersprache kennen. Allerdings verliert
+die interaktive Steuerung relativ schnell ihren Reiz,
+wenn die Lernenden erkennen, daß nur sehr einfache Pro­
+blemstellungen damit bearbeitet werden können. Dann
+sollte aber zur Arbeit mit Papier und Bleistift überge­
+gangen werden. 
+   Die Entscheidung, ganz auf das Arbeiten mit Papier
+und Bleistift zu verzichten, hat sich als sehr nachteilig
+erwiesen. Die Lernenden "hacken" die Programme in die
+Maschine und handeln eher nach dem "Prinzip von Versuch
+und Irrtum" als nach sorgfältigen Überlegungen. Bei
+komplexeren Problemstellungen scheitern diese Teilneh­
+mer zumeist. 
+   Erfahrungsgemäß nimmt nach einiger Zeit der Wunsch
+stark zu, eigene Ausgaben auf dem Bildschirm zu erzeugen
+und andere Problembereiche zu bearbeiten (zum "richtigen
+Programmieren" überzugehen). Sie sollten diesen Schritt
+dann auch nicht zu lange hinauszögern und das Modell
+auf keinen Fall überstrapazieren. Da das Modell selbst
+und auch der Umgang damit sehr einfach ist, besteht auch
+später die Möglichkeit, zum Modell zurückzukehren, um
+hieran weitere Elemente der Algorithmenentwicklung in
+einfacher und anschaulicher Form einzuführen. 
+ 
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 3 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 3
new file mode 100644
index 0000000..c34b752
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 3	
@@ -0,0 +1,199 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (17)# 
+#headodd# 
+#center#gs-Herbert und Robbi#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Herbert und Robbi 
+ 
+#end# 
+#center#3 
+ 
+#center#Installation 
+#center#von 
+#center#gs-Herbert und Robbi 
+ 
+ 
+   Bevor Sie #on("b")#gs-Herbert und Robbi#off("b")# auf Ihrem Computer
+benutzen können, müssen Sie das Programm zunächst in­
+stallieren. Wenn #on("b")#gs-Herbert und Robbi#off("b")# auf Ihrem System
+schon zur Verfügung steht, können Sie dieses Kapitel
+ruhig überspringen. 
+ 
+ 
+3.1  Voraussetzungen 
+ 
+   Um #on("b")#gs-Herbert und Robbi#off("b")# auf Ihrem Computer betreiben
+zu können, muß das EUMEL-Betriebssystem installiert
+sein. #on("b")#gs-Herbert und Robbi#off("b")# setzt die Multi-User-Version
+voraus und ist lauffähig ab Version 1.7.5. #on("b")#gs-Herbert und
+Robbi#off("b")# setzt weiterhin voraus, daß auf Ihrem Computer
+bereits das Programm #on("b")#gs-DIALOG#off("b")# installiert ist. 
+ 
+ 
+3.2  Lieferumfang 
+ 
+   #on("b")#gs-Herbert und Robbi#off("b")# wird auf einer Diskette gelie­
+fert, die alle notwendigen Programme enthält (die Instal­
+lation von #on("b")#gs-DIALOG#off("b")# wird dabei vorausgesetzt!). Um den
+Inhalt der Diskette feststellen zu können, starten Sie
+Ihr System und bringen es dazu, daß 'gib kommando:' er­
+scheint. Dann legen Sie die Diskette ein und geben das
+Kommando: 
+ 
+archive("gs-Herbert und Robbi");list(archive); 
+release(archive) <RETURN> 
+ 
+   Anschließend erscheint eine Übersicht der auf dem
+Archiv vorhandenen Programme. Folgende Programme soll­
+ten sich in der Übersicht befinden: 
+ 
+         "gs-Herbert und Robbi 1" 
+         "gs-Herbert und Robbi 2" 
+         "gs-Herbert und Robbi 3" 
+         "gs-MENUKARTE:Herbert und Robbi" 
+         "gs-Herbert und Robbi/gen" 
+ 
+   Eventuell können noch weitere Namen auf der Diskette
+vorhanden sein. Wenn Sie den Inhalt der Diskette kon­
+trolliert haben und diese Programme auf der Diskette
+vorhanden sind, können Sie #on("b")#gs-Herbert und Robbi#off("b")# instal­
+lieren. 
+   Sollten Sie statt der Übersicht eine Fehlermeldung
+erhalten, überprüfen Sie bitte, ob die Diskette das rich­
+tige Format besitzt oder ob Ihr Diskettenlaufwerk Pro­
+bleme macht. Sollten dagegen Programme fehlen, so rekla­
+mieren Sie die Diskette. 
+ 
+ 
+3.3  Installation 
+ 
+   #on("b")#gs-Herbert und Robbi#off("b")# muß in einer Task installiert
+werden, in der bereits das Programm #on("b")#gs-DIALOG#off("b")# zur Ver­
+fügung steht. Alle Söhne und Enkel der neuen Task kön­
+nen anschließend das Hamster-/ Roboter-Modell aufrufen.
+Richten Sie also eine Task als Sohn der Task ein, in der
+auf Ihrem Computer bereits #on("b")#gs-DIALOG#off("b")# installiert ist. Wir
+nehmen hier an, daß #on("b")#gs-DIALOG#off("b")# in der Task 'MENU' instal­
+liert ist und die neue Task den Namen 'HAMSTER' erhalten
+soll. (Sie können für die Task auch einen beliebigen an­
+deren Namen wählen): 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+ 
+#off("b")# 
+  -->     gib supervisor kommando: 
+#on("b")# 
+          begin ("HAMSTER","MENU") <RETURN> 
+#off("b")# 
+ 
+  -->     gib kommando: 
+ 
+   (Arbeiten mehrere Personen mit dem Computer, dann ist
+es sinnvoll, diese Task vor unbefugtem Zugriff durch ein
+Passwort zu schützen. Wie das gemacht wird, können Sie in
+Ihrem EUMEL-Benutzerhandbuch erfahren.) 
+ 
+   Legen Sie dann die Archivdiskette ein, auf der sich
+#on("b")#gs-Herbert und Robbi#off("b")# befindet, und geben Sie das folgen­
+de Kommando: 
+ 
+#on("b")# 
+   archive("gs-Herbert und Robbi") <RETURN> 
+ 
+   fetch("gs-Herbert und Robbi/gen",archive) <RETURN> 
+ 
+   run <RETURN> 
+#off("b")# 
+ 
+   Sie haben damit das Generatorprogramm gestartet.
+Zunächst werden Sie gefragt, ob Sie den erweiterten Be­
+fehlssatz (mit Zusatztests) für den Hamster und Roboter
+zur Verfügung gestellt haben möchten. Beantworten Sie
+diese Frage je nach Wunsch mit 'ja' oder 'nein' durch Tip­
+pen der Taste <j> bzw. <n>. 
+   Daraufhin wird die Installation automatisch durchge­
+führt. Lassen Sie während des gesamten Vorgangs die Ar­
+chivdiskette eingelegt. Die Generierung ist beendet, wenn
+der EUMEL-Eingangsbildschirm erscheint. Die Task, in der
+die Generierung stattfindet, wird automatisch zur Mana­
+gertask, das heißt, daß Söhne von ihr eingerichtet werden
+können. 
+   Richten Sie sich gleich eine Sohntask (z.B mit dem Na­
+men 'hamster1') ein, dann können Sie das System sofort
+ausprobieren. Gehen Sie dazu folgendermaßen vor: 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+ 
+#off("b")# 
+  -->     gib supervisor kommando: 
+#on("b")# 
+          begin ("hamster1","HAMSTER") <RETURN> 
+#off("b")# 
+ 
+  -->     gib kommando: 
+ 
+ 
+Mit dem Kommando 
+ 
+#center##on("b")#hamster <RETURN>  bzw.  roboter <RETURN>#off("b")# 
+ 
+rufen Sie nun das 
+ 
+#center#Hamster-Modell  bzw. Roboter-Modell 
+ 
+auf. 
+ 
+ 
+3.4  Direktstart des Modells 
+     (Steht erst ab gs-DIALOG Version 1.1 zur Verfügung) 
+ 
+   In Kapitel 3.3 haben wir Ihnen gezeigt, wie sie eine
+Sohntask einrichten und hier durch das Kommando 'ham­
+ster' bzw. 'roboter' das System aufrufen können. Wenn Sie
+immer nur mit einer Modellvariante arbeiten oder vor dem
+Benutzer die 'gib kommando:'-Ebene verbergen wollen,
+können Sie das System auch so einrichten, daß sich sofort
+nach Einrichten des Arbeitsbereichs das Menusystem mel­
+det. Für den Anfänger kann das die Arbeit durchaus er­
+leichtern. 
+  Gehen Sie dazu in die Task, unterhalb der die Sohntasks
+eingerichtet werden sollen: 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+ 
+#off("b")# 
+  -->     gib supervisor kommando: 
+#on("b")# 
+          continue ("HAMSTER") <RETURN> 
+#off("b")# 
+ 
+  -->     gib kommando: 
+#on("b")# 
+          direktstart ("hamster", TRUE) <RETURN> 
+#off("b")# 
+ 
+   Durch das Kommando haben Sie festgelegt, daß sich
+alle Sohntasks direkt mit dem Hamstermenu melden. Möch­
+ten Sie lieber mit dem Roboter-Modell arbeiten, ist nur
+'hamster' durch 'roboter' zu ersetzen. 
+   Durch den zweiten Parameter 'TRUE' legen Sie fest, daß
+in den Sohntasks nach Verlassen des Menus die jeweilige
+Task automatisch gelöscht wird. Statt 'TRUE' können Sie
+hier auch den Wert 'FALSE' eintragen. Dann wird nach Ver­
+lassen des Menus angefragt, ob die Task gelöscht werden
+soll. Wird die Frage bejaht, wird gelöscht - sonst wird die
+Task abgekoppelt (break) und kann durch 'continue' wieder
+angekoppelt werden. 
+   Anmerkung: In der Task, in der Sie das Kommando
+'direktbefehl' gegeben haben, sollte nicht das Kommando
+'monitor' gegeben werden, da Sie durch dieses Kommando
+auch diese Task zu einer Task machen, die sich direkt mit
+dem Menu meldet und ggf. bei Verlassen des Menus automa­
+tisch gelöscht wird! 
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 4 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 4
new file mode 100644
index 0000000..4f2d79a
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 4	
@@ -0,0 +1,1312 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (22)# 
+#headodd# 
+#center#gs-Herbert und Robbi#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Herbert und Robbi 
+ 
+#end# 
+#center#4 
+ 
+#center#Beschreibung 
+#center#der 
+#center#Menufunktionen 
+ 
+ 
+   Nach Aufruf meldet sich #on("b")#gs-Herbert und Robbi mit
+#on("u")#einem#off("u")# der folgenden Menus: 
+ 
+ 
+#on("b")# 
+HAMSTER:  Info  Landschaft  Programm  Lauf  Archiv 
++---------------------------+-------------------------------------------- 
+|  l Landschaftsgestaltung  | 
+|  b Befehlsvorrat          | 
+|  s Steuerung des Laufs    | 
++---------------------------+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+#on("u")#oder#off("u")# 
+ 
+#on("b")# 
+ROBOTER:  Info  Arbeitsfeld  Programm  Lauf  Archiv 
++----------------------------+-------------------------------------------- 
+|  a  Arbeitsfeldgestaltung  | 
+|  b Befehlsvorrat           | 
+|  s Steuerung des Laufs     | 
++----------------------------+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+   Beide Varianten sind, wie schon gesagt, analog auf­
+gebaut. Aus diesem Grunde werden wir uns in den folgen­
+den Ausführungen auf die Beschreibung der Hamster -
+Variante beschränken. 
+ 
+ 
+4.1  Kurzhinweise zur Bedienung des Menus 
+ 
+   Die Bedienung des Menus ist sehr einfach. Eine aus­
+führliche Beschreibung dazu finden Sie in den Unterla­
+gen zum Programmsystem #on("b")#gs-DIALOG#off("b")#. An dieser Stelle sol­
+len nur die wesentlichen Bedienungsvorgänge beschrieben
+werden. 
+ 
+-  Mit der Tastenfolge <ESC><?> können Sie sich Informa­
+   tionen zur Bedienung des Menusystems in das Menu
+   einblenden lassen 
+ 
+-  Mit den Pfeiltasten <rechts> und <links> können Sie
+   zwischen den "Oberbegriffen" in der Kopfzeile wählen.
+   Der aktuelle Oberbegriff ist jeweils invers darge­
+   stellt. Das ausgeklappte 'Pull-Down-Menu' bezieht sich
+   auf diesen invers dargestellten Oberbegriff. 
+ 
+-  Mit den Pfeiltasten <hoch> und <runter> können Sie
+   zwischen den Menufunktionen wählen, die Ihnen im
+   aktuellen Pull-Down-Menu zur Auswahl angeboten
+   werden. Die aktuell angewählte Menufunktion wird
+   jeweils invers dargestellt. Die Trennlinien, die in
+   einigen Pull-Down-Menus sichtbar sind, dienen nur
+   der optischen Untergliederung; sie können nicht an­
+   gewählt werden und werden deshalb automatisch über­
+   sprungen. Die einzelnen Menupunkte sind "zyklisch
+   miteinander verknüpft", das heißt, man gelangt vom
+   untersten Menupunkt wieder zum obersten und umge­
+   kehrt. Menupunkte, vor denen ein Minuszeichen steht
+   ('-'), sind (zur Zeit) nicht aktivierbar; auch sie können
+   nicht angewählt werden und werden einfach über­
+   sprungen. 
+ 
+-  Durch Tippen der Fragezeichentaste (<?>) können Sie
+   sich jeweils zur aktuellen Menufunktion (invers im
+   Pull-Down-Menu) Informationen in das Menu einblen­
+   den lassen. 
+ 
+-  Um eine Menufunktion ausführen zu lassen, bewegen
+   Sie sich mit den Pfeiltasten auf die gewünschte Menu­
+   funktion im aktuellen Pull-Down-Menu und tippen
+   dann die <RETURN>-Taste. Steht vor dem gewünschten
+   Menupunkt ein einzelner Buchstabe oder eine Ziffer,
+   so kann durch Tippen der entsprechenden Taste diese
+   Menufunktion dadurch direkt aufgerufen werden. So­
+   bald eine Menufunktion aufgerufen worden ist, er­
+   scheint davor ein Stern ('*'). Daraus können Sie ent­
+   nehmen, daß das System bereits den Auftrag ausführt. 
+ 
+-  An verschiedenen Stellen werden Fragen an Sie ge­
+   richtet, die Sie mit 'ja' oder 'nein' beantworten müssen.
+   Tippen Sie dazu entsprechend der Entscheidung die
+   Taste <j> (für 'ja') bzw. <n> (für 'nein'). 
+ 
+-  Werden Ihnen vom Menu aus Dateinamen zur Auswahl
+   angeboten, so können Sie den auf dem Bildschirm
+   sichtbaren Pfeil vor den gewünschten Namen positio­
+   nieren. Mit den Tasten <x> oder <RETURN> können Sie
+   den Namen ankreuzen. Ist die Auswahl mehrerer Datein­
+   amen möglich, so können Sie den Vorgang wiederholen.
+   Mit den Tasten <o> oder <RUBOUT> können Sie auch ein
+   Kreuz vor einem Namen wieder löschen. Daneben gibt es
+   noch einige Tastenfunktionen, die für die Bedienung
+   recht hilfreich sein können. Tippen Sie während der
+   Auswahl die Fragezeichentaste (<?>), so werden Ihnen
+   alle Bedienungsmöglichkeiten auf dem Bildschirm an­
+   gezeigt. Eine Auswahl, in der mehrere Dateien ange­
+   kreuzt werden dürfen, wird durch die Tastenfolge
+   <ESC><q> verlassen. Anschließend wird die eingestellte
+   Operation mit den angekreuzten Dateien ausgeführt.
+   Sind Sie versehentlich in eine solche Auswahl ge­
+   langt, so können Sie den Vorgang durch die Tasten­
+   kombination <ESC><h> abbrechen. 
+ 
+-  An einigen Stellen werden Sie aufgefordert, eine Ein­
+   gabe zu machen (z.B. einen Dateinamen einzugeben). Wird
+   Ihnen hier ein Vorschlag gemacht, den Sie akzeptieren,
+   so brauchen Sie zur Bestätigung nur die <RETURN>-
+   Taste zu tippen. Gefällt Ihnen der Vorschlag nicht
+   oder wird Ihnen kein Vorschlag gemacht, so machen Sie
+   bitte die gewünschte Eingabe. Zum Schreiben stehen
+   Ihnen alle aus dem Editor bekannten Funktionen zur
+   Verfügung. Mit der Taste <RUBOUT> können Sie Buch­
+   staben löschen, mit <RUBIN> einfügen. Die Eingabe wird
+   durch Tippen der <RETURN>-Taste abgeschlossen. Ist
+   der von Ihnen gewünschte Name schon in Ihrer Task
+   vorhanden und steht in der Fußzeile der Hinweis 'Zei­
+   gen: <ESC><z>', dann können Sie sich auch alle vorhan­
+   denen Namen zur Auswahl anbieten lassen und durch
+   Ankreuzen den beabsichtigten Namen auswählen. 
+ 
+-  Ihnen können auch mehrere Alternativen angeboten
+   werden, zwischen denen Sie wählen müssen. In der un­
+   tersten Zeile eines solchen Kastens, in denen Ihnen die
+   Alternativen auf dem Bildschirm eingeblendet werden,
+   sind die Möglichkeiten aufgeführt, die darüber be­
+   schrieben sind. Mit den Pfeiltasten können sie die
+   Markierung auf die gewünschte Alternative positio­
+   nieren und dann durch die <RETURN>-Taste zur Aus­
+   führung bringen. (Manchmal ist das auch durch Tippen
+   der den Alternativen vorangestellten Buchstaben oder
+   Ziffern möglich). 
+ 
+-  Durch die Tastenfolge <ESC><q> kann das Menu insge­
+   samt verlassen werden. Damit das nicht versehentlich
+   geschieht, wird jeweils die Frage gestellt, ob Sie das
+   Menu tatsächlich verlassen wollen. Diese Frage beant­
+   worten Sie bitte je nach Wunsch mit 'ja' oder 'nein'
+   durch Tippen der Tasten <j> bzw. <n>. 
+ 
+#page# 
+4.2  Menufunktionen zum Oberbegriff 'Info' 
+ 
+   Das auf dem Bildschirm sichtbare Pull-Down-Menu ist
+oben abgebildet. 
+ 
+#on("u")##on("b")#l Landschaftsgestaltung (a Arbeitsfeldgestaltung)#off("b")##off("u")# 
+        Mit dieser Funktion können Sie sich alle Tasten,
+     die bei der Landschafts-/Arbeitsfeldgestaltung
+     wirksam sind, anzeigen lassen. 
+        In der Anzeige wird die jeweilige Tastenfunktion
+     erläutert. Während der Landschafts-/Arbeitsfeld­
+     gestaltung können Sie sich diese Informationen
+     durch Tippen der Fragezeichentaste (<?>) ebenfalls
+     einblenden lassen. 
+ 
+#on("u")##on("b")#b Befehlsvorrat#off("b")##off("u")# 
+        Mit dieser Funktion können Sie sich die Befehle,
+     die Ihnen vom jeweiligen Modell zur Verfügung ge­
+     stellt werden, auf dem Bildschirm anzeigen lassen. 
+        Anhand dieser Informationen können Sie auch
+     feststellen, ob in dem System, das Ihnen zur Verfü­
+     gung steht, der "eingeschränkte" oder "erweiterte"
+     Befehlssatz hinsichtlich der Tests realisiert ist. 
+ 
+#on("u")##on("b")#s Steuerung des Laufs#off("b")##off("u")# 
+        Mit dieser Funktion können Sie sich die Möglich­
+     keiten anzeigen lassen, wie Sie auf einen Hamster-
+     /Roboterlauf durch Tastendruck Einfluß nehmen
+     können: 
+ 
+     <ESC>    :  beende den Lauf (Programmabbruch
+                 durch Tastendruck) 
+     <?>      :  zeige diese Information (während des
+                 Programmablaufs!) 
+ 
+     0        :  Einzelschritt (dazu beliebige Taste
+                 drücken) 
+     1        :  geringste Geschwindigkeit 
+     9        :  höchste  Geschwindigkeit 
+     2 ... 8  :  dazwischenliegende Geschwindigkeiten 
+ 
+     <+>      :  laufe schneller 
+     <->      :  laufe langsamer 
+ 
+     Zu Beginn eines Laufes ist die Geschwindigkeit '5'
+     eingestellt. 
+#page# 
+4.3  Menufunktionen zum Oberbegriff 'Landschaft'(Ar­
+     beitsfeld) 
+ 
+#on("b")# 
+HAMSTER:  Info  Landschaft  Programm  Lauf  Archiv 
+----------+--------------------+------------------------------------------ 
+          |  n Neu erstellen   | 
+          |  a Ansehen/Ändern  | 
+          |  ----------------  | 
+          |  v Verzeichnis     | 
+          |  ----------------  | 
+          |  l Löschen         | 
+          |  d Drucken         | 
+          |  ----------------  | 
+          |  k Kopieren        | 
+          |  u Umbenennen      | 
+          +--------------------+ 
+ 
+ 
+ 
+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+#on("u")##on("b")#n Neu erstellen#off("b")##off("u")# 
+        Mit dieser Funktion können Sie eine neue Land­
+     schaft/ein neues Arbeitsfeld unter einem neuen
+     Namen anlegen und gestalten. 
+        Sie werden zunächst nach einem Namen für die
+     #on("u")#neue#off("u")# Landschaft/das #on("u")#neue#off("u")# Arbeitsfeld gefragt. Ge­
+     ben Sie einen beliebigen Namen (#on("u")#ohne Anführungs­
+     zeichen (!)#off("u")# und #on("u")#ohne das Präfix 'Flaeche:' (!)#off("u")#) ein und
+     schließen Sie die Eingabe durch <RETURN> ab. Dar­
+     aufhin wird Ihnen auf dem Bildschirm eine leere
+     Landschaft/ein leeres Arbeitsfeld angeboten. 
+        Sollte schon eine Landschaft/ein Arbeitsfeld
+     mit diesem Namen in der Task vorhanden sein, so
+     werden Sie darauf aufmerksam gemacht. Sie können
+     sich während der Landschaftsgestaltung auch je­
+     derzeit eine Aufstellung der wirksamen Tasten mit
+     Beschreibung der Funktionen auf den Bildschirm
+     ausgeben lassen. Drücken Sie dazu die Fragezeichen­
+     taste (<?>). 
+ 
+     Fehlerfälle: 
+     -  Eine Landschaft/ein Arbeitsfeld mit dem vorge­
+        schlagenen Namen existiert schon. 
+ 
+#on("u")##on("b")#a Ansehen/Ändern#off("b")##off("u")# 
+        Mit dieser Funktion können Sie schon in Ihrer
+     Task existierende Landschaften/Arbeitsfelder zur
+     Ansicht oder zur Überarbeitung anfordern. 
+        Sie werden zunächst gefragt, ob Sie #on("u")#die zuletzt
+     bearbeitete Landschaft#off("u")#/#on("u")#das zuletzt bearbeitete Ar­
+     beitsfeld#off("u")# ansehen bzw. verändern möchten (sofern
+     Sie schon vorher mit dem Modell in der Task gear­
+     beitet haben). 
+        Bejahen Sie diese Frage, dann wird Ihnen diese
+     Landschaft/dieses Arbeitsfeld zur Bearbeitung
+     angeboten. Verneinen Sie die Frage dagegen, so ge­
+     langen Sie in die 'Auswahl' (d.h es werden Ihnen alle
+     Landschaften/Arbeitsfelder in der Task zur Auswahl
+     angeboten). Nachdem Sie einen der Namen angekreuzt
+     haben, wird Ihnen die ausgewählte Landschaft/das
+     ausgewählte Arbeitsfeld zur Bearbeitung auf dem
+     Bildschirm angeboten. Ihnen stehen die Tastenfunk­
+     tionen wie bei der Neuerstellung zur Verfügung. 
+ 
+     Fehlerfälle: 
+     - In der Task existiert noch keine Landschaft/kein
+       Arbeitsfeld. 
+ 
+#on("u")##on("b")#v Verzeichnis#off("b")##off("u")# 
+        Mit dieser Funktion können Sie sich einen Über­
+     blick über die in Ihrer Task vorhandenen Land­
+     schaften/Arbeitsfelder verschaffen. 
+        Nach Aufruf dieser Funktion wird eine Liste der
+     Landschaften/Arbeitsfelder auf dem Bildschirm
+     ausgegeben, die sich in Ihrer Task befinden. Da die
+     Liste selbst eine Datei ist, kann Sie mit der Tasten­
+     kombination <ESC><q> verlassen werden - hierauf
+     wird auch in der Kopfzeile der Datei hingewiesen.
+     Falls nicht alle Namen auf den Bildschirm passen,
+     können Sie das Fenster mit <HOP><runter> und
+     <HOP><hoch> verschieben. 
+ 
+#on("u")##on("b")#l Löschen#off("b")##off("u")# 
+        Mit dieser Funktion können Sie Landschaften/
+     Arbeitsfelder, die Sie nicht mehr benötigen, die
+     unnötig Platz belegen, löschen. Aber Vorsicht! Die
+     Landschaften/Arbeitsfelder verschwinden durch
+     diese Funktion unwiederbringlich! 
+        Nach Aufruf dieser Funktion werden Ihnen alle
+     Landschaften/Arbeitsfelder, die sich in Ihrer Task
+     befinden, zur Auswahl angeboten. Hier können Sie
+     die gewünschten Namen ankreuzen. Die Auswahl wird
+     dann durch die Tastenfolge <ESC><q> verlassen. 
+        Für jede einzelne Landschaft/jedes einzelne Ar­
+     beitsfeld wird noch einmal zur Sicherheit gefragt,
+     ob sie/es auch tatsächlich gelöscht werden soll. Zur
+     Bestätigung tippen Sie bitte die Taste <j> ('ja') - zur
+     Verhinderung <n> ('nein'). 
+ 
+     Fehlerfälle: 
+     -  In der Task exsitiert noch keine Landschaft/
+        kein Arbeitsfeld. 
+ 
+#on("u")##on("b")#d Drucken#off("b")##off("u")# 
+        Mit dieser Funktion können Sie Landschaften/
+     Arbeitsfelder über einen angeschlossenen Drucker
+     ausgeben lassen. 
+        Nach Aufruf dieser Funktion werden Ihnen alle
+     Landschaften/Arbeitsfelder, die sich in Ihrer Task
+     befinden, zur Auswahl angeboten. Hier können Sie
+     die gewünschten Namen ankreuzen. Die Auswahl wird
+     dann durch die Tastenfolge <ESC><q> verlassen. 
+        Die angekreuzten Landschaften/Arbeitsfelder
+     werden anschließend zum Drucker geschickt. Der
+     Vorgang wird auf dem Bildschirm protokolliert. 
+ 
+     Fehlerfälle: 
+     -  In der Task existiert noch keine Landschaft/
+        kein Arbeitsfeld. 
+     -  Der Drucker ist nicht funktionsbereit. 
+     -  Der Drucker wird nicht über die Task 'PRINTER'
+        betrieben. 
+     -  Auf Ihrem System werden die Druckkosten abge­
+        rechnet. Sie müssen sich mit einer Codenummer
+        identifizieren. 
+
+#on("u")##on("b")#k Kopieren#off("b")##off("u")# 
+        Mit dieser Funktion können Sie sich eine Kopie
+     einer/eines bereits in der Task vorhandenen Land­
+     schaft/Arbeitsfeldes anlegen. Das ist z.B. dann
+     sinnvoll, wenn Sie sich einen bestimmten 'Stand'
+     aufbewahren wollen oder wenn Sie eine Land­
+     schaft/ein Arbeitsfeld gestalten wollen, das einem
+     bereits vorhandenen ähnelt. 
+        Nach Aufruf dieser Funktion werden Ihnen alle
+     Landschaften/Arbeitsfelder, die sich in Ihrer Task
+     befinden, zur Auswahl angeboten. Nach Ankreuzen
+     eines Namens wird die Auswahl automatisch verlas­
+     sen. 
+        Anschließend wird der angekreuzte Name ange­
+     zeigt und der Name für die Kopie erfragt. Es muß ein
+     Name eingetragen werden, der in dieser Task noch
+     nicht für eine Landschaft/ein Arbeitsfeld verge­
+     ben wurde - ansonsten erfolgt ein Hinweis darauf
+     und es wird nicht kopiert! 
+        Da man aber oft für die Kopie einen ähnlichen
+     Namen wie für das Original wählt, wird der 'alte'
+     Name vorgeschlagen. Aus genannten Gründen muß er
+     aber verändert werden. Sie können diesen Namen mit
+     den üblichen Editierfunktionen verändern oder mit
+     <HOP><RUBOUT> löschen und ganz neu eingeben. Sie
+     sparen aber eine Menge Tipparbeit, wenn Sie einen
+     langen Namen nur an einer Stelle ändern wollen. 
+ 
+     Fehlerfälle: 
+     -  Eine Landschaft/ein Arbeitsfeld mit dem ge­
+        wünschten Namen existiert bereits in der Task. 
+ 
+#on("u")##on("b")#u Umbenennen#off("b")##off("u")# 
+        Mit dieser Funktion können Sie einer bereits
+     vorhandenen Landschaft/einem bereits vorhandenen
+     Arbeitsfeld einen neuen Namen geben. 
+        Nach Aufruf dieser Funktion werden Ihnen alle
+     Landschaften/Arbeitsfelder, die sich in Ihrer Task
+     befinden, zur Auswahl angeboten. Nach Ankreuzen
+     eines Namens wird die Auswahl automatisch verlas­
+     sen. 
+        Anschließend wird dieser Name angezeigt und der
+     zukünftige Name für die Landschaft/das Arbeitsfeld
+     erfragt. Es muß ein Name eingetragen werden, der in
+     dieser Task noch nicht für eine Landschaft/ein Ar­
+     beitsfeld vergeben wurde - ansonsten erfolgt ein
+     Hinweis darauf und die Landschaft/das Arbeitsfeld
+     wird nicht umbenannt! 
+        Da man aber oft den 'neuen' Namen in Anlehnung
+     an den 'alten' Namen wählt, wird der 'alte' Name vor­
+     geschlagen. Aus genannten Gründen muß er aber
+     verändert werden. Sie können diesen Namen mit den
+     üblichen Editierfunktionen verändern oder mit
+     <HOP><RUBOUT> löschen und ganz neu eingeben. Sie
+     sparen aber eine Menge Tipparbeit, wenn Sie einen
+     langen Namen nur an einer Stelle ändern wollen. 
+ 
+     Fehlerfälle: 
+     -  Eine Datei mit dem gewünschten Namen existiert
+        bereits in der Task. 
+#page# 
+4.4  Menufunktionen zum Oberbegriff 'Programm' 
+ 
+#on("b")# 
+HAMSTER:  Info  Landschaft  Programm  Lauf  Archiv 
+---------------------+--------------------+------------------------------- 
+                     |  n Neu erstellen   | 
+                     |  a Ansehen/Ändern  | 
+                     |  ----------------  | 
+                     |  v Verzeichnis     | 
+                     |  ----------------  | 
+                     |  l Löschen         | 
+                     |  d Drucken         | 
+                     |  ----------------  | 
+                     |  k Kopieren        | 
+                     |  u Umbenennen      | 
+                     +--------------------+ 
+ 
+ 
+ 
+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+#on("u")##on("b")#n Neu erstellen#off("b")##off("u")# 
+        Mit dieser Funktion können Sie eine neue Pro­
+     grammdatei anlegen und beschreiben. 
+        Sie werden zunächst nach einem Namen für die
+     #on("u")#neue#off("u")# Programmdatei gefragt. Geben Sie einen belie­
+     bigen Namen (#on("u")#ohne Anführungszeichen (!)#off("u")#) ein und
+     schließen Sie die Eingabe durch <RETURN> ab. Dar­
+     aufhin wird Ihnen auf dem Bildschirm eine neue Da­
+     tei zum Beschreiben angeboten. 
+        Sollte schon eine Programmdatei mit diesem Na­
+     men in der Task vorhanden sein, so werden Sie dar­
+     auf aufmerksam gemacht. 
+        Sie können sich während des Schreibens die
+     wichtigsten Tastenfunktionen des Editers einblen­
+     den lassen. Tippen Sie dazu die Tastenfolge <ESC><?>.
+     Es erscheint dann das folgende Angebot aus dem Sie
+     auswählen können: 
+ 
+ #on("b")# 
+            +--------------------------------------------------+ 
+            |                Der EUMEL - Editor                | 
+            |                                                  | 
+            |    b ... Beschreibung des Editors                | 
+            |    w ... Wichtige Tasten                         | 
+            |    p ... Positionieren der Schreibmarke          | 
+            |    k ... Korrigieren im Text (Einfügen/Löschen)  | 
+            |    m ... Markierte Textpassagen bearbeiten       | 
+            |    l ... Lernen im Editor                        | 
+            |    a ... Anweisungen im Editor (Kommandodialog)  | 
+            |                                                  | 
+            |    z ... Zurück in den Schreibmodus              | 
+            |                                                  | 
+            |        b   w   p   k   m   l   a   z             | 
+            +--------------------------------------------------+ 
+#off("b")# 
+ 
+     Fehlerfälle: 
+     -  Eine Datei mit dem vorgeschlagenen Namen exi­
+        stiert schon. 
+ 
+#on("u")##on("b")#a Ansehen/Ändern#off("b")##off("u")# 
+        Mit dieser Funktion können Sie sich Dateien, die
+     schon in Ihrer Task existieren, ansehen oder auch
+     verändern. 
+        Sie werden zunächst gefragt, ob Sie #on("u")#die zuletzt
+     bearbeitete Programmdatei#off("u")# ansehen bzw. verändern
+     möchten (sofern Sie schon vorher mit dem Modell in
+     der Task gearbeitet haben). 
+        Bejahen Sie diese Frage, dann wird Ihnen diese
+     Programmdatei zur Bearbeitung angeboten. Vernei­
+     nen Sie die Frage dagegen, so gelangen Sie in die
+     'Auswahl' (d.h es werden Ihnen alle Programmdateien
+     in der Task zur Auswahl angeboten). Nachdem Sie
+     einen der Namen angekreuzt haben, wird Ihnen die
+     ausgewählte Programmdatei zur Bearbeitung auf dem
+     Bildschirm angeboten. 
+ 
+     Fehlerfälle: 
+     - In der Task existiert noch keine Programmdatei. 
+ 
+#on("u")##on("b")#v Verzeichnis#off("b")##off("u")# 
+        Mit dieser Funktion können Sie sich einen Über­
+     blick über die in Ihrer Task vorhandenen Programm­
+     dateien verschaffen. 
+        Nach Aufruf dieser Funktion wird eine Liste der
+     Programmdateien auf dem Bildschirm ausgegeben, die
+     sich in Ihrer Task befinden. Da die Liste selbst eine
+     Datei ist, kann Sie mit der Tastenkombination
+     <ESC><q> verlassen werden - hierauf wird auch in
+     der Kopfzeile der Datei hingewiesen. Falls nicht
+     alle Namen auf den Bildschirm passen, können Sie
+     das Fenster mit <HOP><runter> und <HOP><hoch> ver­
+     schieben. 
+ 
+#on("u")##on("b")#l Löschen#off("b")##off("u")# 
+        Mit dieser Funktion können Sie Programmdateien,
+     die Sie nicht mehr benötigen, die unnötig Platz be­
+     legen, löschen. Aber Vorsicht! Die Programmdateien
+     verschwinden durch diese Funktion unwieder­
+     bringlich! 
+        Nach Aufruf dieser Funktion werden Ihnen alle
+     Programmdateien, die sich in Ihrer Task befinden,
+     zur Auswahl angeboten. Hier können Sie die ge­
+     wünschten Namen ankreuzen. Die Auswahl wird dann
+     durch die Tastenfolge <ESC><q> verlassen. 
+        Für jede einzelne Programmdatei wird noch ein­
+     mal zur Sicherheit gefragt, ob sie auch tatsächlich
+     gelöscht werden soll. Zur Bestätigung tippen Sie
+     bitte die Taste <j> ('ja') - zur Verhinderung <n>
+     ('nein'). 
+ 
+     Fehlerfälle: 
+     -  In der Task exsitiert noch keine Programmdatei 
+ 
+#on("u")##on("b")#d Drucken#off("b")##off("u")# 
+        Mit dieser Funktion können Sie Programmdateien
+     über einen angeschlossenen Drucker ausgeben las­
+     sen. 
+        Nach Aufruf dieser Funktion werden Ihnen alle
+     Programmdateien, die sich in Ihrer Task befinden,
+     zur Auswahl angeboten. Hier können Sie die ge­
+     wünschten Namen ankreuzen. Die Auswahl wird dann
+     durch die Tastenfolge <ESC><q> verlassen. 
+        Die angekreuzten Programmdateien werden an­
+     schließend zum Drucker geschickt. Der Vorgang wird
+     auf dem Bildschirm protokolliert. 
+ 
+     Fehlerfälle: 
+     -  In der Task existiert noch keine Programmdatei. 
+     -  Der Drucker ist nicht funktionsbereit. 
+     -  Der Drucker wird nicht über die Task 'PRINTER'
+        betrieben. 
+     -  Auf Ihrem System werden die Druckkosten abge­
+        rechnet. Sie müssen sich mit einer Codenummer
+        identifizieren. 
+ 
+#on("u")##on("b")#k Kopieren#off("b")##off("u")# 
+        Mit dieser Funktion können Sie sich eine Kopie
+     einer bereits in der Task vorhandenen Programmda­
+     tei anlegen. Das ist z.B. dann sinnvoll, wenn Sie sich
+     einen bestimmten 'Stand' aufbewahren wollen oder
+     wenn Sie ein Programm schreiben wollen, das einem
+     bereits vorhandenen ähnelt. 
+        Nach Aufruf dieser Funktion werden Ihnen alle
+     Programmdateien, die sich in Ihrer Task befinden,
+     zur Auswahl angeboten. Nach Ankreuzen eines Na­
+     mens wird die Auswahl automatisch verlassen. 
+        Anschließend wird der angekreuzte Name ange­
+     zeigt und der Name für die Kopie erfragt. Es muß ein
+     Name eingetragen werden, der in dieser Task noch
+     nicht für eine Programmdatei vergeben wurde; an­
+     sonsten erfolgt ein Hinweis darauf und es wird
+     nicht kopiert! 
+        Da man aber oft für die Kopie einen ähnlichen
+     Namen wie für das Original wählt, wird der 'alte'
+     Name vorgeschlagen. Aus genannten Gründen muß er
+     aber verändert werden. Sie können diesen Namen mit
+     den üblichen Editierfunktionen verändern oder mit
+     <HOP><RUBOUT> löschen und ganz neu eingeben. Sie
+     sparen aber eine Menge Tipparbeit, wenn Sie einen
+     langen Namen nur an einer Stelle ändern wollen. 
+ 
+     Fehlerfälle: 
+     -  Eine Programmdatei mit dem gewünschten Namen
+        existiert bereits in der Task. 
+ 
+#on("u")##on("b")#u Umbenennen#off("b")##off("u")# 
+        Mit dieser Funktion können Sie einer bereits
+     vorhandenen Programmdatei einen neuen Namen ge­
+     ben. 
+        Nach Aufruf dieser Funktion werden Ihnen alle
+     Programmdateien, die sich in Ihrer Task befinden,
+     zur Auswahl angeboten. Nach Ankreuzen eines Na­
+     mens wird die Auswahl automatisch verlassen. 
+        Anschließend wird dieser Name angezeigt und der
+     zukünftige Name für die Programmdatei erfragt. Es
+     muß ein Name eingetragen werden, der in dieser Task
+     noch nicht für eine Programmdatei vergeben wurde -
+     ansonsten erfolgt ein Hinweis darauf und die Pro­
+     grammdatei wird nicht umbenannt! 
+        Da man aber oft den 'neuen' Namen in Anlehnung
+     an den 'alten' Namen wählt, wird der 'alte' Name vor­
+     geschlagen. Aus genannten Gründen muß er aber
+     verändert werden. Sie können diesen Namen mit den
+     üblichen Editierfunktionen verändern oder mit
+     <HOP><RUBOUT> löschen und ganz neu eingeben. Sie
+     sparen aber eine Menge Tipparbeit, wenn Sie einen
+     langen Namen nur an einer Stelle ändern wollen. 
+ 
+     Fehlerfälle: 
+     -  Eine Programmdatei mit dem gewünschten Namen
+        existiert bereits in der Task. 
+#page# 
+4.5  Menufunktionen zum Oberbegriff 'Lauf' 
+ 
+#on("b")# 
+HAMSTER:  Info  Landschaft  Programm  Lauf  Archiv 
+---------------------------+------------------------+--------------------- 
+                           |  l Lauf nach Programm  | 
+                           |  h Handsteuerung       | 
+                           +------------------------+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+#on("u")##on("b")#l Lauf nach Programm#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie den Ham­
+     ster/Roboter nach einem Programm in einer Land­
+     schaft/einem Arbeitsfeld laufen lassen. Sowohl das
+     Programm als auch die Landschaft/das Arbeitsfeld
+     müssen bereits existieren. 
+        Sie werden zunächst gefragt, ob der Hamster/
+     Roboter #on("u")#das zuletzt bearbeitete Programm#off("u")# ausführen
+     soll. Bejahen Sie die Frage, so wird dieses Programm
+     ausgeführt; verneinen Sie die Frage dagegen, so
+     gelangen Sie in die 'Auswahl'. Nach Ankreuzen des
+     gewünschten Programmnamens wird das ausgewählte
+     Programm ausgeführt. 
+        Nach der Abfrage bezüglich des Programmnamens
+     erfolgt dann eine weitere Abfrage nach dem Namen
+     der Landschaft/ des Arbeitsfeldes, in der/dem der
+     Hamster/Roboter nach dem zuvor ausgewählten Pro­
+     gramm laufen soll. Auch hier werden Sie zunächst
+     gefragt, ob Sie #on("u")#die zuletzt benutzte Landschaft/das
+     zuletzt benutzte Arbeitsfeld#off("u")# verwenden möchten. 
+        Bejahen Sie die Frage, so wird das Programm in
+     dieser Landschaft/in diesem Arbeitsfeld ausge­
+     führt; verneinen Sie dagegen die Frage, so werden
+     Ihnen alle in der Task vorhandenen Landschaften/
+     Arbeitsfelder zur Auswahl angeboten. Durch An­
+     kreuzen eines Landschafts-/Arbeitsfeldnamens wird
+     die betreffende Landschaft/das betreffende Ar­
+     beitsfeld ausgewählt und das Programm in dieser
+     Landschaft/in diesem Arbeitsfeld ausgeführt. 
+        Daneben haben Sie auch die Möglichkeit, im Pro­
+     gramm selbst als erste Anweisung den Befehl 'lands­
+     chaft ("Name");' oder 'arbeitsfeld ("Name");' anzuge­
+     ben. Für 'Name' muß dann natürlich der gewünschte
+     Landschafts-/Arbeitsfeldname eingetragen sein. Ist
+     eine solche Anweisung #on("u")#am Programmanfang#off("u")# vorhan­
+     den, so wird an Sie #on("u")#keine#off("u")# Abfrage bezüglich des
+     Landschafts-/Arbeitsfeldnamens gestellt; das Pro­
+     gramm wird in der #on("u")#angegebenen#off("u")# Landschaft/im #on("u")#ange­
+     gebenen#off("u")# Arbeitsfeld ausgeführt. 
+        Sind im Programm noch Fehler enthalten, so wer­
+     den das Programm und die Fehlermeldungen gleich­
+     zeitig auf dem Bildschirm dargestellt (Paralleledi­
+     tor) und zur Korrektur angeboten. Für die Pro­
+     grammkorrektur stehen ebenfalls alle Editorfunk­
+     tionen zur Verfügung. 
+        Während des Hamster-/Roboterlaufs können Sie
+     durch Tastendruck Einfluß nehmen (Geschwindigkeit
+     verändern, Programm abbrechen etc). Sehen Sie dazu
+     auch die Menufunktion 's Steuerung des Laufs' unter
+     dem Oberbegriff 'Info'. Standardmäßig beginnt ein
+     solcher Lauf immer mit einer mittleren Geschwin­
+     digkeit. 
+        Ist der Hamster-/Roboterlauf ohne Fehler been­
+     det worden, werden Sie gefragt, ob Sie die Land­
+     schaft/das Arbeitsfeld in dem zuletzt angezeigten
+     Zustand aufbewahren wollen. Bejahen Sie diese Fra­
+     ge, so wird die Landschaft/das Arbeitsfeld in eine
+     Datei geschrieben. Die neue Landschaft/das neue
+     Arbeitsfeld erhält den Namen der alten Land­
+     schaft/des alten Arbeitsfeldes und das Zusatzkenn­
+     zeichen '.x'. 
+        Sollte Ihnen beim Programmieren ein Fehler un­
+     terlaufen sein (z.B. eine Endlosschleife, so kann mit
+     der Taste <ESC> der Hamster-/Roboterlauf abgebro­
+     chen werden ("Notbremse"). 
+ 
+#on("u")##on("b")#h Handsteuerung#off("b")##off("u")# 
+        Mit dieser Funktion können Sie den Hamster/
+     Roboter in einer/einem vorbereiteten Landschaft/
+     Arbeitsfeld durch Tasten steuern. Alle gültigen
+     Tastenbefehle werden in einem Protokoll festgehal­
+     ten. Da das entstehende Protokoll ein ELAN-
+     Programm ist, kann der Hamster/Roboter anschlie­
+     ßend die gleichen Aktionen anhand des Programms
+     wiederholt ausführen ('Teach In'). 
+        Sie werden zunächst gefragt, ob die Land­
+     schaft/das Arbeitsfeld, in dem der Hamster/Roboter
+     gesteuert werden soll, schon existiert. Beantworten
+     Sie die Frage mit 'nein', so werden Sie aufgefordert,
+     zunächst die Landschaft/das Arbeitsfeld zu gestal­
+     ten. Bejahen Sie die Frage, werden Ihnen alle in Ih­
+     rer Task vorhandenen Landschaften/Arbeitsfelder
+     zur Auswahl angeboten. Sie brauchen nur die ge­
+     wünschte Landschaft/das gewünschte Arbeitsfeld
+     anzukreuzen. Die/das angekreuzte Landschaft/Ar­
+     beitsfeld erscheint dann in folgender Darstellung
+     auf dem Bildschirm: 
+ 
+#on("b")# 
+#on("u")#Beispiel#off("u")#: 
+ 
+  <v>or    <l>inks um    <n>imm  <g>ib    <p>rotokoll    <e>nde 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . V . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . o\#\# o . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . .\#\# . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . o\#\# . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . .\#\# o . . . o . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . o\#\#\#\#\#\#\#\#\#\#\#\# o . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . o . o .\#\# . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . o\#\# . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . .\#\# . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . o\#\#o. . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+Gib Hamster-Befehl:                     letzter Befehl: 
+ 
+#off("b")# 
+        Durch Tastendruck können Sie nun den Hamster/
+     Roboter steuern (<v> - vor, <l> - links um, <n> -
+     nimm, <g> - gib). Sofern die Aktion ausführbar ist,
+     wird sie auf dem Bildschirm auch ausgeführt. Wird
+     dagegen eine Aktion verlangt, die nicht ausgeführt
+     werden kann (z.B. <v>, wenn der Hamster/Roboter
+     direkt vor einem Hindernis steht), so erscheint eine
+     entsprechende Fehlermeldung in der untersten Zeile
+     des Bildschirms. Nach einer kurzen Pause können
+     dann weitere Eingaben gemacht werden. Eine Fehlbe­
+     dienung führt also #on("u")#nicht#off("u")# zu einem Programmabbruch!
+     In der untersten Bildschirmzeile wird auch jeweils
+     der letzte Befehl zur Kontrolle angezeigt. 
+        Alle korrekten Eingaben werden protokolliert.
+     Durch Drücken der Taste <p> (- protokoll) können Sie
+     sich jederzeit das während der Ausführung angeleg­
+     te Protokoll zeigen lassen. Es entsteht nämlich
+     automatisch im Hintergrund ein ablauffähiges
+     ELAN-Programm. Im Anschluß an eine solche Hand­
+     steuerung können Sie den Hamster/Roboter dann in
+     der gleichen Landschaft/im gleichen Arbeitsfeld
+     nach diesem Protokoll (Dateiname: PROTOKOLL) vom
+     Programm aus gesteuert laufen lassen. 
+#page# 
+4.6  Menufunktionen zum Oberbegriff 'Archiv' 
+ 
+#on("b")# 
+HAMSTER:  Info  Landschaft  Programm  Lauf  Archiv 
+---------------------------------+-------------------------+-------------- 
+                                 |  r Reservieren          | 
+                                 |  - Neue Diskette        | 
+                                 |  ---------------------  | 
+                                 |  - Schreiben            | 
+                                 |  - Checken              | 
+                                 |  - Kombination          | 
+                                 |  - Holen/Lesen          | 
+                                 |  - Löschen              | 
+                                 |  ---------------------  | 
+                                 |  - Verzeichnis          | 
+                                 |  - Drucken              | 
+                                 |  ---------------------  | 
+                                 |  i Initialisieren       | 
+                                 |  z Zieltask einstellen  | 
+  +---------------------+        +-------------------------+ 
+  | Dateiaustausch mit: | 
+  |  Archiv             | 
+  | Archivname:         | 
+  |  ---                | 
+  +---------------------+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+   In diesem Kapitel werden alle die Menufunktionen be­
+schrieben, die Ihnen unter dem Oberbegriff 'Archiv' im
+Menu angeboten werden. Mit den Funktionen in diesem
+Menu können Sie aber nicht nur Dateien auf dem Archiv
+behandeln, sondern auch in anderen Tasks im Multi-
+User-System oder über das EUMEL-Netz sogar auf anderen
+Rechnern! 
+   Wenn Sie dieses Pull-Down-Menu gerade aufgeschlagen
+haben, sind nicht alle Funktionen aktivierbar! Um weitere
+Funktionen zu aktivieren, muß erst einer der aktivierba­
+ren Menupunkte gewählt werden. 
+   Bei der Archivbehandlung werden Ihnen jeweils alle in
+der Task vorhandenen Dateien zur Auswahl angeboten. Das
+System unterscheidet nicht von sich aus - wie unter den
+Oberbegriffen 'Landschaft'/'Arbeitsfeld' und 'Programm' -
+zwischen Landschaften/Arbeitsfeldern und Programmda­
+teien. In den hier gezeigten Listen können Sie aber Land­
+schaften/Arbeitsfelder daran erkennen, daß ihnen das
+Präfix 'Flaeche:' vorangestellt ist. 
+ 
+#on("u")##on("b")#r Reservieren#off("b")##off("u")# (des Archivlaufwerks) 
+        Im EUMEL-Multi-User-System haben normalerwei­
+     se mehrere Personen das Zugriffsrecht auf das Ar­
+     chivlaufwerk. Allerdings muß der Zugriff so gere­
+     gelt werden, daß sich die Beteiligten dabei nicht
+     gegenseitig "in die Quere kommen". Ein Zugriff auf
+     das Archivlaufwerk erfordert zunächst eine Anmel­
+     dung. Ist diese Anmeldung erfolgt, kann von den an­
+     deren Beteiligten so lange nicht mehr auf das Lauf­
+     werk zugegriffen werden - bis es wieder freigege­
+     ben worden ist. 
+        Diese Anmeldung des Archivlaufwerkes erfolgt
+     über die Menufunktion 'r Reservieren'. Greift be­
+     reits eine andere Task auf das Laufwerk zu, so er­
+     halten Sie darüber einen Hinweis auf dem Bild­
+     schirm. Ansonsten wird an Sie die Frage gestellt, ob
+     die Diskette eingelegt und das Laufwerk geschlos­
+     sen ist. 
+        Erst zu diesem Zeitpunkt ist sichergestellt, daß
+     Sie den alleinigen Zugriff auf das Laufwerk haben.
+     Deshalb sollten Sie, wenn Sie mit mehreren Personen
+     am Computer arbeiten, erst zum Zeitpunkt der Frage­
+     stellung die Diskette ins Laufwerk einlegen. 
+        Nachdem Sie die Diskette eingelegt und die Frage
+     bejaht haben, ermittelt das System selbständig den
+     Namen der eingelegten Diskette, zeigt den Namen auf
+     dem Bildschirm (im kleinen Kasten links unten) an
+     und aktiviert die anderen Menupunkte des Pull-
+     Down-Menus. 
+        Beim Verlassen des Pull-Down-Menus, wenn eine
+     andere Zieltask eingestellt wird oder wenn das Menu
+     gänzlich verlassen wird, wird die Reservierung au­
+     tomatisch aufgehoben! 
+ 
+     Fehlerfälle: 
+     -  Das Laufwerk ist von einer anderen Task belegt. 
+     -  Die Diskette ist falsch eingelegt oder das Lauf­
+        werk ist nicht richtig geschlossen. 
+     -  Die Diskette ist nicht formatiert bzw. initiali­
+        siert. 
+     -  Die Diskette kann nicht gelesen werden (keine
+        EUMEL-Diskette, Diskette hat ein falsches For­
+        mat, Diskette ist verschmutzt...). 
+ 
+#on("u")##on("b")#n Neue Diskette#off("b")##off("u")# (anmelden) 
+        Der Dateiaustausch mit einer Diskette ist nur
+     dann möglich, wenn der im System eingestellte Dis­
+     kettenname (auf dem Bildschirm im kleinen Kasten
+     unten links sichtbar) mit dem tatsächlichen Namen
+     der Diskette übereinstimmt. Nach einem Disketten­
+     wechsel ist das aber in der Regel nicht mehr der
+     Fall. Greift man dann auf die neu eingelegte Dis­
+     kette zu, so erscheint die Fehlermeldung: 'Falscher
+     Archivname! Bitte neue Diskette anmelden!'. 
+        Das Anmelden einer neuen Diskette - ohne einen
+     neuen Reserviervorgang - wird durch diese Menu­
+     funktion ermöglicht. Nach Aktivieren dieses Menu­
+     punktes wird der Name der eingelegten Diskette er­
+     mittelt, im System eingestellt und auf dem Bild­
+     schirm angezeigt. 
+        Im Gegensatz zur Menufunktion 'r Reservieren'
+     greift das System ohne Anfrage an den Benutzer auf
+     das Archivlaufwerk zu (die Reservierung bleibt ja
+     bestehen). Ist das Archivlaufwerk reserviert, so ist
+     die Neuanmeldung einer Diskette über diese Menu­
+     funktion weniger zeitaufwendig. 
+ 
+     Fehlerfälle: 
+     -  wie unter 'r Reservieren'. 
+ 
+#on("u")##on("b")#s Schreiben#off("b")##off("u")# (Kopieren) 
+        Alle Dateien der eigenen Task werden zur Aus­
+     wahl angeboten. Wenn Sie die Auswahl durch die
+     Tastenfolge <ESC><q> verlassen, überprüft das Sy­
+     stem zunächst, ob die Dateien in der eingestellten
+     Zieltask schon vorhanden sind. Ist das der Fall,
+     wird erfragt, ob die dort vorhandenen Dateien über­
+     schrieben, d.h. gelöscht werden dürfen (s.u.). An­
+     schließend werden alle angekreuzten Dateien in der
+     Reihenfolge, in der Sie sie angekreuzt haben, in die
+     eingestellte Zieltask kopiert. Der Vorgang wird auf
+     dem Bildschirm protokolliert. Die Originaldateien
+     in der eigenen Task bleiben dabei erhalten. 
+        Wenn in der Zieltask schon eine Datei existiert,
+     die den gleichen Namen hat wie eine Datei, die Sie
+     dorthin kopieren möchten, so wird angefragt, ob die
+     vorher schon existierende Datei überschrieben (ge­
+     löscht!) werden soll. Bejahen Sie diese Frage, so wird
+     die bereits in der Zieltask existierende Datei (un­
+     wiederbringlich) gelöscht und die gewünschte Datei
+     dorthin transportiert. Ein Überschreiben aus Ver­
+     sehen ist nicht möglich, wenn Sie die an Sie gestell­
+     te Frage sorgfältig beantworten. 
+        Verneinen Sie die Frage, so wird die Datei auch
+     nicht hinübertransportiert! Sie können die Datei
+     aber umbenennen (Menufunktion 'u Umbenennen' un­
+     ter den Oberbegriffen 'Landschaft'/Arbeitsfeld' bzw.
+     'Programm') und anschließend mit anderem Namen
+     hinüberschreiben. 
+        Beachten Sie, daß beim Überschreiben einer Datei
+     auf einer Archivdiskette der Speicherplatz der al­
+     ten (überschriebenen) Version im allgemeinen nicht
+     wiederverwendet werden kann. In einem solchen Fall
+     könnte die Diskette voll geschrieben werden, obwohl
+     eigentlich genügend Platz vorhanden wäre. Zur Op­
+     timierung wird deshalb zuerst überprüft, ob die
+     angekreuzten Dateien schon in der Zieltask vorhan­
+     den sind und löscht diese, wenn Sie Ihr Einver­
+     ständnis geben. Erst anschließend werden die Datei­
+     en insgesamt kopiert. 
+        Normalerweise ist als Zieltask das Archivlauf­
+     werk der eigenen Station eingestellt. Mit der Menu­
+     funktion 'z Zieltask einstellen' kann diese Einstel­
+     lung aber verändert werden. 
+ 
+     Fehlerfälle: 
+     -  Die Diskette ist falsch eingelegt oder beschä­
+        digt. 
+     -  Die Diskette kann nicht beschrieben werden
+        (Schreibfehler). 
+     -  Die Diskette ist voll. 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              'z Zieltask einstellen'. 
+ 
+#on("u")##on("b")#c Checken#off("b")##off("u")# 
+        Diese Menufunktion kann nur ausgeführt werden,
+     wenn der Dateiaustausch mit einem Archiv(manager)
+     erfolgt - ansonsten ist diese Menufunktion auch
+     nicht aktivierbar. Die Menufunktion dient dazu, auf
+     Diskette geschriebene Dateien auf Lesefehler hin zu
+     prüfen. Es empfiehlt sich, diese Prüfroutine auf
+     neu auf die Diskette geschriebene Dateien anzuwen­
+     den. Sehen Sie dazu auch 'k Kombination'. 
+        Alle Dateien der eingestellten Zieltask (Archiv)
+     werden zur Auswahl angeboten. Wenn Sie die Auswahl
+     durch die Tastenfolge <ESC><q> verlassen, werden
+     alle angekreuzten Dateien in der Reihenfolge, in
+     der Sie sie angekreuzt haben, "gecheckt", d.h. auf
+     Lesefehler hin überprüft. Der Vorgang wird auf dem
+     Bildschirm protokolliert. 
+ 
+     Fehlerfälle: 
+     -  Lesefehler auf dem Archiv. 
+     -  Sehen Sie auch unter  'r Reservieren'. 
+ 
+#on("u")##on("b")#k Kombination#off("b")##off("u")# 
+        Diese Menufunktion ist eine Kombination aus den
+     beiden Menufunktionen 's Schreiben' und 'c Checken'
+     (Sehen Sie weitere Informationen auch dort!). 
+        Alle Dateien der eigenen Task werden zur Aus­
+     wahl angeboten. Wenn Sie die Auswahl durch die Ta­
+     stenfolge <ESC><q> verlassen, werden alle ange­
+     kreuzten Dateien in der Reihenfolge, in der Sie sie
+     angekreuzt haben, in die eingestellte Zieltask ko­
+     piert (gegebenenfalls müssen bereits vorhandene
+     Dateien gleichen Namens in der Zieltask gelöscht
+     werden). Anschließend werden alle Dateien, die gera­
+     de geschrieben wurden, gecheckt, d.h. auf Lesefehler
+     hin untersucht. Beide Vorgänge werden auf dem
+     Bildschirm protokolliert. 
+        Da die 'Check' - Operation nur bei Archivmana­
+     gern zulässig ist, ist diese Menufunktionen eben­
+     falls nur bei Archivmanagern aktivierbar. Zur Er­
+     läuterung sehen Sie bitte auch unter 'z Zieltask
+     einstellen'. 
+ 
+#on("u")##on("b")#h Holen/Lesen#off("b")##off("u")# 
+        Die Menufunktion dient dazu, Dateien, die bereits
+     auf einer Archivdiskette oder in einer anderen Task
+     existieren, in die eigene Task zu kopieren. 
+        Alle Dateien der eingestellten Zieltask werden
+     zur Auswahl angeboten. Anschließend werden Kopien
+     der angekreuzten Dateien in der Reihenfolge des
+     Ankreuzens in die eigene Task geholt. Das Original
+     in der Zieltask bleibt dabei unverändert! Der Vor­
+     gang wird auf dem Bildschirm protokolliert. 
+        Sind in der eigenen Task schon Dateien mit glei­
+     chem Namen vorhanden, so wird gefragt, ob die 'al­
+     ten' Dateien überschrieben (gelöscht) werden dürfen.
+     Nur wenn Sie zustimmen, werden die in Ihrer Task
+     existierenden Dateien (unwiederbringlich!) gelöscht
+     und Kopien der gleichnamigen Dateien aus der Ziel­
+     task angefertigt. 
+        Stimmen Sie dem Löschvorgang nicht zu, dann
+     bleiben die bisherigen Dateien in Ihrer Task erhal­
+     ten - die Dateien aus der Zieltask werden dann aber
+     auch nicht in Ihre Task kopiert! Um dennoch die Ko­
+     pien zu erhalten, können Sie die namensgleichen
+     Dateien in Ihrer Task umbenennen und dann erst die
+     Dateien aus der anderen Task anfordern. 
+        Normalerweise werden die Dateien vom Archiv der
+     eigenen Station geholt. Mit dem Menupunkt 'z Ziel­
+     task einstellen' kann diese Einstellung verändert
+     werden. 
+ 
+     Fehlerfälle: 
+     -  Lesefehler auf dem Archiv. 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              's Schreiben' 
+                              'z Zieltask einstellen'. 
+ 
+#on("u")##on("b")#l Löschen#off("b")##off("u")# 
+        Die Menufunktion dient dazu, Dateien in der
+     Zieltask (unwiederbringlich!) zu löschen. Dazu wer­
+     den alle Dateien der eingestellten Zieltask zur Aus­
+     wahl angeboten. Anschließend werden die angekreuz­
+     ten Dateien in der Reihenfolge ihres Ankreuzens
+     gelöscht. Zur Sicherheit muß noch einmal für jede
+     einzelne Datei bestätigt werden, daß sie auch tat­
+     sächlich gelöscht werden soll. 
+        Beachten Sie, daß beim Löschen einer Datei auf
+     einer Archivdiskette der Speicherplatz im allgemei­
+     nen nicht wieder verwendet werden kann. In einem
+     solchen Fall könnte die Diskette voll geschrieben
+     werden, obwohl eigentlich genügend Platz vorhan­
+     den wäre. Diese Probleme treten bei anderen Tasks,
+     die keine Archivmanager sind, nicht auf, da deren
+     Speicherplatz intelligenter verwaltet wird. 
+        Normalerweise ist als Zieltask das Archiv der
+     eigenen Station eingestellt. Mit dem Menupunkt 'z
+     Zieltask einstellen' kann diese Einstellung verän­
+     dert werden. 
+ 
+     Fehlerfälle: 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              's Schreiben' 
+                              'z Zieltask einstellen'. 
+ 
+#on("u")##on("b")#v Verzeichnis#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie sich einen
+     Überblick über die in der Zieltask (z.B. auf dem Ar­
+     chiv) vorhandenen Dateien verschaffen. 
+        Nach Aufruf der Funktion wird eine Liste der
+     Dateien auf dem Bildschirm ausgegeben, die sich in
+     der Zieltask (z.B. auf dem Archiv) befinden. Ist die
+     Zieltask ein Archiv(manager), so wird auch ange­
+     zeigt, wieviel Platz auf der Diskette belegt ist. Da
+     die Liste selbst eine Datei ist, kann sie mit der Ta­
+     stenkombination <ESC><q> verlassen werden. Falls
+     nicht alle Dateinamen auf den Bildschirm passen,
+     können Sie das Fenster mit <HOP><hoch> und
+     <HOP><runter> verschieben. 
+ 
+     Fehlerfälle: 
+     -  Sehen Sie unter  'z Zieltask einstellen'. 
+ 
+#on("u")##on("b")#d Drucken#off("b")##off("u")# 
+        Das Verzeichnis der Dateien in der Zieltask, das
+     man mit der Menufunktion 'v Verzeichnis' auf dem
+     Bildschirm angezeigt bekommt, kann mit dieser Me­
+     nufunktion ausgedruckt werden. 
+        Zur Sicherheit wird angefragt, ob wirklich ein
+     solches Dateiverzeichnis der Zieltask gedruckt wer­
+     den soll. Bejaht man die Frage, so wird ein Dateiver­
+     zeichnis erstellt und zum Drucker geschickt. 
+ 
+     Fehlerfälle: 
+     -  Der Drucker ist nicht funktionsbereit. 
+     -  Der Drucker wird nicht über die Task 'PRINTER'
+        betrieben. 
+     -  Auf Ihrem System werden die Druckkosten abge­
+        rechnet. Sie müssen sich mit einer Codenummer
+        identifizieren. 
+ 
+#on("u")##on("b")#i Initialisieren#off("b")##off("u")# 
+        Diese Menufunktion gestattet es, frische Disket­
+     ten zu formatieren, zu initialisieren bzw. be­
+     schriebene Disketten vollständig zu löschen und
+     ggf. dabei umzubenennen. Bei Aufruf dieser Menu­
+     funktion wird - sofern noch nicht geschehen - das
+     Archivlaufwerk automatisch reserviert. 
+        Wenn Sie eine fabrikneue Diskette aus der Ver­
+     packung nehmen, müssen Sie diese zunächst #on("u")#forma­
+     tieren#off("u")#. Dabei wird die Diskette auf ein festgelegtes
+     physikalisches Format eingestellt. Ohne daß diese
+     Operation vorausgegangen ist, kann eine Diskette
+     weder beschrieben noch gelesen werden. 
+        Prinzipiell braucht eine Diskette nur ein einzi­
+     ges Mal formatiert zu werden. Sie können Sie jedoch
+     jederzeit wieder formatieren - z.B. wenn Sie Disket­
+     ten haben, von denen Sie nicht genau wissen, für
+     welche Zwecke sie zuvor verwendet wurden. 
+        Wenn Sie diese Menufunktion aktivieren, werden
+     Sie so zunächst gefragt, ob Sie die Diskette auch
+     formatieren wollen. Bejahen Sie die Frage, so werden
+     Ihnen mehrere Formate zur Auswahl angeboten: 
+ 
+#on ("b")# 
+                     +------------------------------------+ 
+                     |     Formatieren einer Diskette     | 
+                     |                                    | 
+                     |  Dies sind die möglichen Formate:  | 
+                     |                                    | 
+                     |     1 ..... 40 Spur   -  360 KB    | 
+                     |     2 ..... 80 Spur   -  720 KB    | 
+                     |     3 ..... 5 1/4"    -  1,2 MB    | 
+                     |     4 ..... 3 1/2"    -  1,4 MB    | 
+                     |     s ..... Standard  -  Format    | 
+                     |                                    | 
+                     |         1   2   3   4   s          | 
+                     +------------------------------------+ 
+#off("b")# 
+ 
+        Erkundigen Sie sich bei Ihrem Händler, welches
+     Format Sie bei Ihrem Rechner und den von Ihnen
+     verwendeten Disketten einstellen müssen. Manche
+     Rechner unterstützen diese Operation innerhalb des
+     EUMEL-Systems auch gar nicht, das Formatieren muß
+     dann irgendwie anders außerhalb des EUMEL-Systems
+     geschehen. 
+        Wenn Sie die Formatierung abgeschlossen oder
+     auch übersprungen haben, beginnt die eigentliche
+     Initialisierung der Diskette. Dabei wird als erstes
+     der Archivname auf die Diskette geschrieben. Alle
+     alten Daten, die sich ggf. auf der Diskette befinden,
+     werden bei diesem Vorgang unwiederbringlich (!)
+     gelöscht. 
+        Zur Sicherheit überprüft das System in jedem
+     Falle, ob es sich um eine EUMEL - Diskette handelt,
+     und erfragt Ihr Einverständnis, ob die Diskette
+     wirklich initialisiert werden soll. Geben Sie hierzu
+     Ihr Einverständnis, dann wird noch der (neue) Ar­
+     chivname erfragt. Hatte die Diskette schon einen
+     Namen, dann wird dieser zum Überschreiben angebo­
+     ten. Wollen Sie den alten Archivnamen beibehalten,
+     so brauchen Sie nur die <RETURN>-Taste zu tippen,
+     ansonsten können Sie den Namen auch zuvor verän­
+     dern oder einen ganz neuen Namen hinschreiben.
+     Anhand des ausgegebenen Namens können Sie auch
+     überprüfen, ob Sie die richtige Diskette eingelegt
+     haben. 
+        Das Initialisieren funktioniert natürlich nur,
+     wenn Sie als Zieltask einen Archivmanager einge­
+     stellt haben - ansonsten ist diese Menufunktion
+     gesperrt (nicht aktivierbar!). 
+ 
+     Fehlerfälle: 
+     -  Formatieren ist nicht auf dem System möglich. 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              'z Zieltask einstellen'. 
+ 
+#on("u")##on("b")#z Zieltask einstellen#off("b")##off("u")# 
+       Mit dieser Menufunktion können Sie festlegen,
+    mit welcher Zieltask Sie kommunizieren, d.h. z.B. Da­
+    teien austauschen möchten. Normalerweise ist hier
+    das Archiv am eigenen Rechner eingestellt. Das wird
+    auch nach Aufklappen des Pull-Down-Menus im Ka­
+    sten links unten angezeigt. 
+       Diese Menufunktion kann im Unterricht z.B. dazu
+    genutzt werden, um fertiggestellte Hausaufgaben in
+    eine bestimmte Task zu schicken (Vatertask) oder um
+    von dort z.B. vorgefertigte Landschaften oder/und
+    Programme abzuholen. 
+       Sie können aber auch eine andere Task einstellen
+    (z.B. die Vatertask oder die Task 'PUBLIC'), um mit die­
+    sen Dateien auszutauschen oder um sich auch nur ei­
+    nen Überblick über die dort vorhandenen Dateien zu
+    verschaffen. Wenn Sie mit Ihrem Rechner in ein
+    EUMEL-Netz integriert sind, können Sie auch auf
+    Tasks anderer Rechner zugreifen oder auch Disketten
+    von Laufwerken anderer Rechner einlesen (z.B. wenn
+    Sie Disketten anderer Formate haben, die von Ihrem
+    Rechner nicht gelesen werden können). 
+        Dabei werden zwei Anforderungen an die Zieltask
+    gestellt: Sie muß existieren und bereit für den Da­
+    teiaustausch sein, d.h es muß eine Managertask sein,
+    auf die Sie Zugriff haben. Versuchen Sie auf andere
+    Tasks zuzugreifen, so erhalten Sie entsprechende
+    (Fehler-)Meldungen. 
+       Zu beachten ist noch, daß es im EUMEL-System ver­
+    schiedene Arten von Managertasks gibt - Archivma­
+    nager und normale Dateimanager. Der Unterschied
+    besteht darin, daß ein Archivmanager vom Benutzer
+    vor dem Zugriff reserviert werden muß - anschlie­
+    ßend hat nur dieser Benutzer (bis zur Aufgabe der
+    Reservierung) ein Zugriffsrecht auf den Manager.
+    Normale Dateimanager können dagegen von mehreren
+    Benutzern in beliebiger Reihenfolge angesprochen
+    werden. 
+       Ein Archivmanager kann auch auf bestimmte Dis­
+    kettenformate spezialisert sein (z.B. auf das Lesen
+    von DOS-Disketten). Manche Rechner haben auch meh­
+    rere Archivmanager für verschiedene Laufwerke etc.
+    Durch Einstellen unterschiedlicher Archivmanager
+    können Sie dann auf verschiedenen Laufwerken ar­
+    chivieren. 
+       Nach Aktivieren dieses Menupunktes werden Ihnen
+    die folgenden Alternativen angeboten: 
+ 
+#on ("b")# 
+                  +-------------------------------------------+ 
+                  |       Dateiaustausch gewünscht mit:       | 
+                  |                                           | 
+                  |      a ... Archiv    (Eigene Station)     | 
+                  |                                           | 
+                  |      v ... Vatertask                      | 
+                  |                                           | 
+                  |      p ... 'PUBLIC'  (Eigene Station)     | 
+                  |                                           | 
+                  |      s ... Sonstige Task                  | 
+                  |                                           | 
+                  |                                           | 
+                  |   Archiv   Vatertask   PUBLIC   Sonstige  | 
+                  +-------------------------------------------+ 
+ 
+        Da der Dateiaustausch mit dem Standardarchiv
+     der eigenen Station (Task: 'ARCHIVE'), mit der Vater­
+     task und der Task 'PUBLIC' recht häufig in Anspruch
+     genommen wird, sind diese drei Optionen unter den
+     Alternativen direkt angegeben. Entscheiden Sie sich
+     für eine dieser drei Tasks, so nimmt das System alle
+     notwendigen Einstellungen vor. Möchten Sie dage­
+     gen in Kontakt mit einer anderen Task treten, so
+     wählen Sie die Alternative 's ... Sonstige Task'. 
+     In diesem Falle haben Sie noch 3 Angaben zu machen: 
+ 
+     -  Zunächst werden Sie nach dem Namen der Zieltask
+        gefragt. Geben Sie den Namen der Zieltask - ohne
+        Anführungsstriche (!) - ein und schließen Sie die
+        Eingabe mit der <RETURN>-Taste ab. (Den ausge­
+        gebenen Namen der z.Z. eingestellten Task können
+        Sie dabei verändern bzw. überschreiben.) 
+ 
+     -  Dann wird die Nummer der Station im EUMEL-Netz
+        erfragt, auf der sich die Zieltask befindet. Die
+        Nummer Ihrer Station wird als Vorschlag ausge­
+        geben. Wollen Sie mit einer Task auf Ihrem Rech­
+        ner kommunizieren, so brauchen Sie diesen Vor­
+        schlag nur durch Drücken der <RETURN>-Taste
+        bestätigen - ansonsten tragen Sie zuvor die ent­
+        sprechende Stationsnummer ein. Ist Ihr Rechner
+        nicht in ein EUMEL-Netz integriert, so wird die
+        Stationsnummer 0 (Null) ausgegeben. Bitte bestä­
+        tigen Sie diese Stationsnummer durch Tippen der
+        <RETURN>-Taste. 
+ 
+     -  Zum Abschluß müssen Sie noch angeben, ob die
+        eingestellte Zieltask ein Archivmanager ist oder
+        nicht. 
+ 
+        Das System versucht dann den Kontakt herzu­
+     stellen. Je nachdem, welche Einstellung Sie vorge­
+     nommen haben, sind bestimmte Funktionen innerhalb
+     des Menus nicht aktivierbar. Das System läßt nur
+     die Funktionen zu, die aufgrund Ihrer Einstellun­
+     gen zulässig sind. 
+        Im Kasten links unten auf dem Bildschirm wird
+     jeweils angezeigt, welche Zieltask eingestellt ist.
+     Erscheint in diesem Kasten auch ein Hinweis auf den
+     Archivnamen, so haben Sie einen Archivmanager ein­
+     gestellt. Ist dagegen vor dem Namen der Zieltask
+     noch eine Zahl und ein Schrägstrich angegeben, so
+     haben Sie eine Zieltask auf einem anderen Rechner
+     eingestellt. 
+        Bedenken Sie, daß Operationen mit Tasks auf an­
+     deren Stationen länger andauern können - werden
+     Sie nicht ungeduldig! 
+        Sie können die Einstellung der Zieltask jeder­
+     zeit wieder verändern! 
+ 
+     Fehlerfälle: 
+     -  Die eingestellte Zieltask existiert nicht. 
+     -  Die eingestellte Zieltask existiert zwar, ist aber
+        nicht empfangsbereit, d.h. ein Zugriff von Ihrer
+        Task aus ist nicht möglich! 
+     -  Das Netz ist nicht funktionsbereit (Collector-
+        Task fehlt). 
+     -  Die Kommunikation war nicht erfolgreich. 
+     -  Die gewünschte Operation kann mit der einge­
+        stellten Zieltask nicht ausgeführt werden (Ziel­
+        task ist z.B. gar kein Archivmanager - Sie aber
+        versuchen, das Laufwerk zu reservieren). 
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 5 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 5
new file mode 100644
index 0000000..bb4a67b
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 5	
@@ -0,0 +1,167 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (61)# 
+#headodd# 
+#center#gs-Herbert und Robbi#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Herbert und Robbi 
+ 
+#end# 
+#center#5 
+ 
+#center#Detailbeschreibung 
+#center#der 
+#center#Basisbefehle 
+ 
+ 
+#on("u")#'vor' bewirkt:#off("u")# 
+  -  ein Eingabezeichen wird von der Tastatur gelesen
+     und ausgewertet. 
+  -  es wird je nach Verzögerungsfaktor (eine vorgege­
+     bene Wartezeit, die auch während des Programmlaufs
+     verändert werden kann) gewartet. 
+  -  falls die Kachel vor dem Hamster/Roboter noch frei
+     ist und zur Landschaft/zum Arbeitsfeld gehört,
+     geht der Hamster/ Roboter um eine Kachel in der
+     augenblicklichen Richtung vorwärts. 
+  -  falls vor dem Hamster/Roboter ein Hindernis liegt,
+     oder wenn er im Begriff ist, aus der Landschaft/aus
+     dem Arbeitsfeld herauszulaufen, wird das Programm
+     mit entsprechender Fehlermeldung abgebrochen. 
+ 
+#on("u")#'links um' bewirkt:#off("u")# 
+  -  wie bei 'vor': Annahme eines Tastendruckes und
+     Warten. 
+  -  eine Drehung des Hamsters/Roboters um 90 Grad ge­
+     gen den Uhrzeigersinn. 
+ 
+#on("u")#'nimm' bewirkt:#off("u")# 
+  -  wie bei 'vor': Annahme eines Tastendruckes und
+     Warten. 
+  -  falls auf der Kachel, auf der der Hamster/Roboter
+     steht, kein Korn/Werkstück liegt, wird das Programm
+     mit entsprechender Fehlermeldung abgebrochen. 
+  -  falls dort genau ein Korn/ein Werkstück liegt, wird
+     dieses auf dem Bildschirm entfernt. Es wird zu denen
+     in den Backentaschen/im Behälter addiert. Auf dem
+     Bildschirm erscheint an der Stelle (" ."). 
+  -  falls mehrere Körner/Werkstücke dort liegen, wird
+     eines zu denen in den Backentaschen/im Behälter
+     addiert und von denen auf der Kachel subtrahiert.
+     Auf dem Bildschirm erscheint weiterhin an der Stel­
+     le (" o"). 
+ 
+#on("u")#'gib' bewirkt:#off("u")# 
+  -  wie bei 'vor': Annahme eines Tastendruckes und
+     Warten. 
+  -  falls die Backentaschen/der Behälter leer sind/ist,
+     wird das Programm mit entsprechender Fehlermel­
+     dung abgebrochen. 
+  -  falls auf der Kachel schon ein Korn/Werkstück oder
+     mehrere Körner/Werkstücke liegen, wird zu ihnen
+     eines addiert und von denen in den Backentaschen/
+     im Behälter subtrahiert. Der Bildschirm ändert sich
+     nicht. 
+  -  falls noch kein Korn/Werkstück auf dieser Kachel
+     liegt, wird auf dem Bildschirm ein (" o") ausgegeben
+     und von den Körnern/Werkstücken in den Backenta­
+     schen/im Behälter ein Korn/Werkstück subtrahiert. 
+ 
+#on("u")#'vorn frei'#off("u")# 
+  -  liefert den Wahrheitswert TRUE, wenn vor dem Ham­
+     ster/ Roboter keine Hinderniskachel liegt, #on("u")#also
+     auch dann, wenn der Hamster/Roboter im Begriff ist,
+     über die Landschafts-/Arbeitsfeldgrenze (den
+     Bildschirmrand) hinauszulaufen!#off("u")# Wenn vor dem Ham­
+     ster/Roboter eine Hinderniskachel liegt, wird der
+     Wahrheitswert FALSE geliefert. 
+ 
+#on("u")#'links frei'#off("u")# 
+  -  liefert den Wahrheitswert TRUE, wenn in Laufrich­
+     tung links vom Hamster/ Roboter keine Hindernis­
+     kachel liegt, #on("u")#also auch dann, wenn links vom Ham­
+     ster/Roboter die Landschafts-/Arbeitsfeldgrenze
+     (der Bildschirmrand) ist!#off("u")# Wenn links vom Hamster/
+     Roboter eine Hinderniskachel liegt, wird der Wahr­
+     heitswert FALSE geliefert. 
+ 
+#on("u")#'rechts frei'#off("u")# 
+  -  liefert den Wahrheitswert TRUE, wenn in Laufrich­
+     tung rechts vom Hamster/Roboter keine Hindernis­
+     kachel liegt, #on("u")#also auch dann, wenn rechts vom Ham­
+     ster/Roboter die Landschafts-/Arbeitsfeldgrenze
+     (der Bildschirmrand) ist!#off("u")# Wenn rechts vom Hamster/
+     Roboter eine Hinderniskachel liegt, wird der Wahr­
+     heitswert FALSE geliefert. 
+ 
+#on("u")#'hinten frei'#off("u")# 
+  -  liefert den Wahrheitswert TRUE, wenn in Laufrich­
+     tung hinter dem Hamster/Roboter keine Hindernis­
+     kachel liegt, #on("u")#also auch dann, wenn hinter dem Ham­
+     ster/Roboter die Landschafts-/Arbeitsfeldgrenze
+     (der Bildschirmrand) ist!#off("u")# Wenn hinter dem Hamster/
+     Roboter eine Hinderniskachel liegt, wird der Wahr­
+     heitswert FALSE geliefert. 
+ 
+#on("u")#'korn da' und 'werkstueck da'#off("u")# 
+  -  liefern den Wahrheitswert TRUE, wenn auf der
+     Kachel, auf der der Hamster/Roboter steht, minde­
+     stens ein Korn/Werkstück liegt. Ansonsten wird der
+     Wahrheitswert FALSE geliefert. 
+ 
+#on("u")#'korn vorn' und 'werkstueck vorn'#off("u")# 
+  -  liefern den Wahrheitswert TRUE, wenn auf der
+     Kachel, die in Laufrichtung vor dem Hamster/Robo­
+     ter liegt, mindestens ein Korn/Werkstück liegt. An­
+     sonsten wird der Wahrheitswert FALSE geliefert. 
+  -  Zur "Untersuchung" wird die vor ihm liegende
+     Kachel - sofern dort kein Hindernis ist - von ihm
+     betreten. Wenn er im Begriff ist, aus der Land­
+     schaft/dem Arbeitsfeld herauszulaufen, wird das
+     Programm mit entsprechender Fehlermeldung abge­
+     brochen. 
+ 
+#on("u")#'korn links' und 'werkstueck links'#off("u")# 
+  -  liefern den Wahrheitswert TRUE, wenn auf der
+     Kachel, die in Laufrichtung links vom Hamster/
+     Roboter liegt, mindestens ein Korn/Werkstück liegt.
+     Ansonsten wird der Wahrheitswert FALSE geliefert. 
+  -  Zur "Untersuchung" wird die links neben ihm lie­
+     gende Kachel - sofern dort kein Hindernis ist - von
+     ihm betreten. Wenn er im Begriff ist, aus der Land­
+     schaft/dem Arbeitsfeld herauszulaufen, wird das
+     Programm mit entsprechender Fehlermeldung abge­
+     brochen. 
+ 
+#on("u")#'korn rechts' und 'werkstueck rechts'#off("u")# 
+  -  liefern den Wahrheitswert TRUE, wenn auf der
+     Kachel, die in Laufrichtung rechts vom Hamster/
+     Roboter liegt, mindestens ein Korn/Werkstück liegt.
+     Ansonsten wird der Wahrheitswert FALSE geliefert. 
+  -  Zur "Untersuchung" wird die rechts neben ihm lie­
+     gende Kachel - sofern dort kein Hindernis ist - von
+     ihm betreten. Wenn er im Begriff ist, aus der Land­
+     schaft/dem Arbeitsfeld herauszulaufen, wird das
+     Programm mit entsprechender Fehlermeldung abge­
+     brochen. 
+ 
+#on("u")#'korn hinten' und 'werkstueck hinten'#off("u")# 
+  -  liefern den Wahrheitswert TRUE, wenn auf der
+     Kachel, die in Laufrichtung hinter dem Hamster/
+     Roboter liegt, mindestens ein Korn/Werkstück liegt.
+     Ansonsten wird der Wahrheitswert FALSE geliefert. 
+  -  Zur "Untersuchung" wird die hinter ihm liegende
+     Kachel - sofern dort kein Hindernis ist - von ihm
+     betreten. Wenn er im Begriff ist, aus der Land­
+     schaft/dem Arbeitsfeld herauszulaufen, wird das
+     Programm mit entsprechender Fehlermeldung abge­
+     brochen. 
+ 
+#on("u")#'backen leer' und 'behaelter leer'#off("u")# 
+  -  liefern den Wahrheitswert TRUE, wenn kein Korn/
+     kein Werkstück in den Backentaschen/im Behälter
+     notiert ist. Ansonsten wird der Wahrheitswert FALSE
+     geliefert. 
+
diff --git a/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 6 b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 6
new file mode 100644
index 0000000..0aeeff0
--- /dev/null
+++ b/doc/hamster/A5 - Doku: gs-Herbert und Robbi - Kapitel 6	
@@ -0,0 +1,73 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (66)# 
+#headodd# 
+#center#gs-Herbert und Robbi#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Herbert und Robbi 
+ 
+#end# 
+#center#6 
+ 
+#center#Zusätzliche Kommandos 
+ 
+ 
+PROC landschaft   (TEXT CONST landschaftsname) 
+PROC arbeitsfeld  (TEXT CONST arbeitsfeldname) 
+     Steht einer dieser Prozeduraufrufe innerhalb eines
+  Hamster-/ Roboterprogramms vor dem ersten Befehl (am
+  Anfang der Datei), so wird die Anfrage nach einem Land­
+  schafts-/Arbeitsfeldnamen zu Beginn des Laufs über­
+  gangen. Außerdem ist es möglich, den Hamster/Roboter
+  in einem Programm durch meherere Landschaften/Ar­
+  beitsfelder laufen zu lassen. Beachten Sie bitte, daß
+  der Landschaftsname / Arbeitsfeldname hier in Anfüh­
+  rungszeichen, aber #on("u")#ohne#off("u")# das Präfix 'Flaeche:' angegeben
+  werden muß! 
+ 
+PROC geschwindigkeit (INT CONST wert) 
+     Möchte man von einem Programm aus eine bestimmte
+  Geschwindigkeit des Hamsters/Roboters bei der Pro­
+  grammausführung festlegen oder die Geschwindigkeit
+  vom Programm aus verändern, so kann man diese Proze­
+  dur verwenden. Zulässig sind für 'wert' nur Werte zwi­
+  schen 0 und 9. Dabei bedeuten: 
+    0:   Einzelschrittmodus - Ausführung des nächsten
+         Schritts auf Tastendruck 
+    1:   geringste  Geschwindigkeit  (Wartezeit : ca.
+         50 Zehntelsekunden  ) 
+    9:   höchste    Geschwindigkeit  (Wartezeit :
+         keine) 
+    2 - 8 sind dazwischenliegende Geschwindigkeiten 
+ 
+TEXT PROC taste 
+     Diese Prozedur liefert jeweils ein eingetipptes
+  Zeichen. Die Taste <ESC>, welche zum Programmabbruch
+  dient, wirkt sich schon aus, bevor hier ein Zeichen ge­
+  liefert werden könnte. 
+ 
+PROC druckereinstellung fuer flaechenausdruck 
+     Für den Landschafts-/Arbeitsfeldausdruck ist der
+  Standardschrifttyp des Druckers voreingestellt. Dabei
+  müssen 80 Druckpositionen in einer Zeile Platz haben.
+  Außerdem sind voreingestellt : \#limit (20.5)\#, \#on("b")\#
+  (Fettdruck) und \#start (0.0,0.0)\#. Zur Darstellung der
+  Hinderniskacheln wird das Zeichen '\#\#' (Code 222) ver­
+  wendet. Kann Ihr Drucker dieses Zeichen nicht darstel­
+  len (z.B. Typenraddrucker mit deutschem Zeichenzatz), so
+  können Sie hier ein #on("u")#anderes Zeichen#off("u")# auswählen. Weiter­
+  hin können Sie mit dieser Prozedur einen #on("u")#anderen
+  Schrifttyp#off("u")# und eine #on("u")#andere Startposition#off("u")# (linker obe­
+  rer Eckpunkt des Druckfeldes) einstellen. Nachdem Sie
+  das Kommando gegeben haben, wird zunächst der ge­
+  wünschte Schrifttyp erfragt. Geben Sie hier einen in
+  Ihrer Installation vorhandenen Schrifttyp an (nur den
+  Namen - ohne Anführungszeichen!). Anschließend werden
+  Sie nacheinander nach den beiden Startwerten (erst die
+  x-Richtung und dann die y-Richtung) gefragt. Geben
+  Sie hier jeweils einen Wert (als REAL) ein. Bedenken Sie
+  dabei, daß die 80 Druckpositionen nebeneinander Platz
+  haben müssen! 
+
diff --git a/doc/hamster/gs-Herbert und Robbi handbuch.impressum b/doc/hamster/gs-Herbert und Robbi handbuch.impressum
new file mode 100644
index 0000000..4c8e79d
--- /dev/null
+++ b/doc/hamster/gs-Herbert und Robbi handbuch.impressum	
@@ -0,0 +1,87 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#gs-Herbert und Robbi 
+ 
+ 
+ 
+ 
+#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# 
+ 
+#free (4.0)##on("b")# 
+#center#gs-Herbert und Robbi
+ 
+ 
+#center#Benutzerhandbuch 
+ 
+ 
+#center#Version 1.0 
+ 
+ 
+#off("b")##center#copyright 
+#center#Eva Latta-Weber 
+#center#Software- und Hardware-Systeme, 1988 
+#center#ERGOS GmbH, 1990 
+#page# 
+#block# 
+#center#____________________________________________________________________________ 
+ 
+ 
+Copyright:  ERGOS GmbH   März 1990 
+ 
+             Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+             maschinenlesbare Form sowie das Speichern in Informations­
+             systemen, auch auszugsweise, nur mit schriftlicher Einwilliging
+             Einwilligung der ERGOS GmbH gestattet.                   
+ 
+#center#____________________________________________________________________________ 
+ 
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender. 
+ 
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden. 
+ 
+Texterstellung   :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+                   erstellt und aufbereitet und auf einem Kyocera Laser­
+                   drucker gedruckt. 
+ 
+ 
+ 
+ 
+#center#___________________________________________________________________________ 
+ 
+ 
+ 
+Ergonomic Office Software GmbH 
+ 
+Bergstr. 7              Telefon: (02241) 63075 
+5200 Siegburg           Teletex: 2627-2241413=ERGOS 
+                        Telefax: (02241) 63078 
+ 
+ 
+#center#____________________________________________________________________________ 
+
diff --git a/doc/lisp/lisp handbuch b/doc/lisp/lisp handbuch
new file mode 100644
index 0000000..022c561
--- /dev/null
+++ b/doc/lisp/lisp handbuch	
@@ -0,0 +1,2260 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#Lisp 
+ 
+ 
+ 
+ 
+#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# 
+#free(7.0)# 
+#center#LISP - Handbuch 
+#free(2.0)# 
+Stand: 08.08.86 
+ 
+Installation von LISP 
+ 
+begin ("LISP") 
+reserve ("sprachen",archive) 
+fetch all(archive) 
+insert ("lisp.1") 
+insert ("lisp.2") 
+insert ("lisp.3") 
+insert ("lisp.4") 
+global manager 
+begin ("lisp","LISP") 
+fetch ("lisp.bootstrap") 
+lisp 
+#page# 
+#start(2.5,1.5)# 
+#block# 
+#pageblock# 
+#head# 
+#center#LISP-Handbuch 
+#center#% 
+ 
+ 
+#end# 
+ 
+ 
+#center#L I S P   H a n d b u c h 
+ 
+ 
+#center#Autor: John Mc.Carthy (M.I.T.1962) 
+#center#übersetzt und angepaßt von J.Durchholz, P.Heyderhoff 
+#center#Gesellschaft für Mathematik und Datenverarbeitung Sankt Augustin 
+ 
+ 
+ 
+Inhaltsverzeichnis 
+ 
+ 
+ 
+1. Die Sprache LISP                               #right##topage("p1")# 
+ 
+1.1  Symbolische Ausdrücke                        #right##topage("p1.1")# 
+1.2  Elementare Funktionen                        #right##topage("p1.2")# 
+1.3  Listen Notation                              #right##topage("p1.3")# 
+1.4  Syntax und Semantik der Sprache              #right##topage("p1.4")# 
+ 
+2.   Das LISP-Interpreter-System                  #right##topage("p2")# 
+ 
+2.1  Die universelle LISP-Funktion "evalquote"    #right##topage("p2.1")# 
+2.2  Anwendungsregeln und Beispiele               #right##topage("p2.2")# 
+2.3  Variablen                                    #right##topage("p2.3")# 
+2.4  Konstanten                                   #right##topage("p2.4")# 
+2.5  Funktionen                                   #right##topage("p2.5")# 
+ 
+3.   Erweitertes LISP                             #right##topage("p3")# 
+ 
+3.1  Gequotete Parameter                          #right##topage("p3.1")# 
+3.2  Funktionen mit beliebig vielen Parametern    #right##topage("p3.2")# 
+3.3  Funktionale Parameter                        #right##topage("p3.3")# 
+3.4  Prädikate und boolesche Konstanten           #right##topage("p3.4")# 
+3.5  Unbenannte Atome                             #right##topage("p3.5")# 
+3.6  Aufruf von EUMEL aus                         #right##topage("p3.6")# 
+ 
+4.   Detailbeschreibungen                         #right##topage("p4")# 
+ 
+4.1  Grundfunktionen                              #right##topage("p4.1")# 
+4.2  Weitere Funktionen sowie Eingabe und Ausgabe #right##topage("p4.2")# 
+4.3  Interpreter                                  #right##topage("p4.3")# 
+4.4  Kommandoprozeduren                           #right##topage("p4.4")# 
+#page# 
+ 
+1. Die Sprache LISP#goalpage("p1")# 
+ 
+ 
+ 
+Die Sprache LISP ist primär für die Symbolmanipulation entworfen. Sie wurde für
+symbolische Berechnungen in verschiedenen Gebieten der künstlichen Intelligenz
+eingesetzt, u.a. für Differential- und Integralrechnung, Schaltkreistheorie, Mathemati­
+sche Logik, Spiele, etc.. 
+ 
+LISP ist eine formale mathematische Sprache. Daher ist es möglich, eine genaue und
+vollständige Beschreibung zu geben. Das ist der Sinn des ersten Abschnitts dieses
+Handbuchs. Andere Abschnitte werden Möglichkeiten zum vorteilhaften Einsatz von
+LISP und die Erweiterungen, die die Benutzung erleichtern, beschreiben. 
+ 
+LISP unterscheidet sich von den meisten Programmiersprachen in drei Punkten. 
+ 
+Der erste Punkt liegt in der Natur der Daten. In der Sprache LISP haben alle Daten
+die Form symbolischer Ausdrücke, die wir verkürzend LISP-Ausdrücke nennen wer­
+den. LISP-Ausdrücke haben keine Längenbegrenzung und eine verzweigte Baum­
+struktur, so daß Unterausdrücke leicht isoliert werden können. In LISP wird der meiste
+Speicherplatz für das Abspeichern der LISP-Ausdrücke in Form von Listenstruktu­
+ren gebraucht. 
+ 
+Der zweite wichtige Teil der Sprache LISP ist die Quellsprache, die festlegt, wie die
+LISP-Ausdrücke verarbeitet werden sollen. 
+ 
+Drittens kann LISP als LISP-Ausdrücke geschriebene Programme interpretieren und
+ausführen. Deshalb kann man die Sprache analog zu Assemblersprachen und im
+Gegensatz zu den meisten anderen höheren Programmiersprachen einsetzen, um
+Programme zu generieren, die gleich ausgeführt werden sollen. 
+ 
+ 
+#page# 
+ 
+1.1 Symbolische Ausdrücke #goalpage("p1.1")# 
+ 
+ 
+ 
+Ein elementarer Ausdruck ist ein Atom. 
+ 
+Definition: Ein Atom ist eine Zeichenkette bestehend aus Großbuchstaben und
+            Ziffern. 
+ 
+ 
+Beispiele:  A 
+            APFEL 
+            TEIL2 
+            EXTRALANGEZEICHENKETTEAUSBUCHSTABEN 
+            A4B66XYZ2 
+ 
+ 
+Diese Symbole werden atomar genannt, weil sie als Ganzes aufgefaßt werden, das
+durch die LISP-Funktionen nicht weiter geteilt werden kann. A, B, und AB haben
+keinerlei Beziehung zueinander, außer der, daß sie alle verschiedene Atome sind. 
+ 
+Alle LISP-Ausdrücke werden aus Atomen und den Satzzeichen "(", ")" und "."
+aufgebaut. Die grundlegende Operation zum Aufbau von LISP-Ausdrücken ist die,
+zwei LISP-Ausdrücke zusammenzufassen, um einen größeren herzustellen. Aus den
+zwei Atomen A und B kann man so den LISP-Ausdruck (A.B) bilden. 
+ 
+Definition: Ein LISP-Ausdruck ist entweder ein Atom, oder aus folgenden Elemen­
+            ten in dieser Reihenfolge aufgebaut: Eine öffnende Klammer, ein
+            LISP-Ausdruck, ein Punkt, ein LISP-Ausdruck, eine schließende
+            Klammer. Zwischen den Bestandteilen eines nichtatomaren LISP-Aus­
+            druck können beliebig viele Leerzeichen eingestreut sein. 
+ 
+Diese Definition ist rekursiv. 
+ 
+ 
+Beispiele:  ATOM 
+            (A . B) 
+            (A . (B . C)) 
+            ((A1 . A2) . B) 
+            ((U . V) . (X . Y)) 
+            ((U . V) . (X . (Y . Z))) 
+ 
+ 
+Um die Struktur solcher Ausdrücke zu verdeutlichen, wird in diesem Handbuch oft
+eine graphische Darstellung gewählt. In dieser Darstellung sind die Atome weiterhin
+Zeichenketten, statt der Paare steht jetzt aber ein Kasten 
+ 
+ 
+                     +-----+-----+ 
+                     |  o  |  o  | 
+                     +-----+-----+ 
+ 
+ 
+von dem zwei Zeiger ausgehen, die auf die graphische Darstellung des ersten bzw.
+zweiten Elements des Paars zeigen. 
+ 
+ 
+ 
+Beispiele:   (A . B)                      +-----+-----+ 
+                                          |  o  |  o  | 
+                                          +--+--+--+--+ 
+                                             |     | 
+                                             V     V 
+                                             A     B 
+ 
+             (A . (B . C))                +-----+-----+ 
+                                          |  o  |  o  | 
+                                          +--+--+--+--+ 
+                                             |     | 
+                                             V     V 
+                                             A  +-----+-----+ 
+                                                |  o  |  o  | 
+                                                +--+--+--+--+ 
+                                                   |     | 
+                                                   V     V 
+                                                   B     C 
+ 
+            ((U . V) . (X . (Y . Z)))    +-----+-----+ 
+                                         |  o  |  o  | 
+                                         +--+--+--+--+ 
+                                            |     | 
+                                            V     V 
+                                  +-----+-----+ +-----+-----+ 
+                                  |  o  |  o  | |  o  |  o  | 
+                                  +--+--+--+--+ +--+--+--+--+ 
+                                     |     |       |     | 
+                                     V     V       V     V 
+                                     U     V       X   +-----+-----+ 
+                                                       |  o  |  o  | 
+                                                       +--+--+--+--+ 
+                                                          |     | 
+                                                          V     V 
+                                                          Y     Z 
+ 
+ 
+ 
+ 
+ 
+ 
+#page#
+ 
+1.2 Elementare Funktionen #goalpage("p1.2")#  
+ 
+ 
+Wir werden einige elementare Funktionen auf LISP-Ausdrücken einführen. Um die
+Funktionen von den LISP-Ausdrücken zu unterscheiden, werden wir Funktionsnamen
+mit Klein- statt Großbuchstaben schreiben. Außerdem steht der Funktionsname
+gefolgt von den Argumenten, auf die die Funktion angewendet werden soll, in Klam­
+mern eingeschlossen in einer Liste. Dabei sind die Argumente durch Blanks vonein­
+ander getrennt. 
+ 
+Die erste Funktion, die wir einführen, heißt "cons". Sie hat zwei Argumente und wird
+dafür benutzt, LISP-Ausdrücke aus kleineren LISP-Ausdrücken aufzubauen. 
+ 
+ 
+             Funktionsaufruf:         Ergebnis: 
+ 
+Beispiele:   (cons A B)            =  (A . B) 
+             (cons (A . B) C)      =  ((A . B) . C) 
+             (cons (cons A B) C)   =  ((A . B) . C) 
+ 
+ 
+Die Beispiele zeigen Funktionsaufrufe. Ein Funktionsaufruf ist eine Liste beginnend
+mit einem Funktionsnamen, gefolgt von Argumenten. Alle Funktionsaufrufe haben ein
+Ergebnis, das im Fall von LISP-Funktionen immer ein LISP-Ausdruck ist. 
+ 
+In diesen Beispielen kommt nur die Funktion "cons" vor. Das letzte Beispiel ist ein
+Fall von Funktionsverkettung, das heißt, als Argument steht ein Funktionsaufruf. Um
+das Ergebnis eines Funktionsaufrufs zu berechnen, das Funktionsaufrufe als Argu­
+mente enthält, muß man statt dieser Argumente die Ergebnisse dieser Funktionsaufru­
+fe einsetzen, so daß man den äußeren Funktionsaufruf in einen Aufruf ohne Funk­
+tionsaufrufe als Argumente umwandelt. 
+ 
+ 
+Beispiel: (cons (cons A B) C) = (cons (A . B) C) = ((A . B) . C) 
+ 
+ 
+Es ist möglich, durch Verkettung der Funktion "cons" jeden LISP-Ausdruck aus
+seinen atomaren Komponenten aufzubauen. 
+ 
+Die folgenden beiden Funktionen tun das genaue Gegenteil von "cons": sie liefern
+die Unterausdrücke eines gegebenen LISP-Ausdrucks. 
+ 
+Die Funktion "head" hat ein Argument. Ihr Wert ist der erste Unterausdruck des
+zusammengesetzen Arguments. Der "head" eines Atoms ist nicht definiert. 
+ 
+ 
+Beispiele: (head (A . B))         = A 
+           (head (A . (B1 . B2))) = A 
+           (head ((A1 . A2) . B)) = (A1 . A2) 
+           (head A)                 ist nicht definiert 
+ 
+ 
+Die Funktion "tail" hat ebenfalls ein Argument, und sie liefert das Argument bis auf
+dessen "head". 
+ 
+ 
+Beispiele: (tail (A . B))                = B 
+           (tail (A . (B1 . B2)))        = (B1 . B2) 
+           (tail ((A1 . A2) . B))        = B 
+           (tail A)                        ist nicht definiert 
+           (head (tail (A . (B1 . B2)))) = B1 
+           (head (tail (A . B)))           ist nicht definiert 
+           (head (cons A B))             = A 
+ 
+ 
+Es ist bei jedem LISP-Ausdruck möglich, durch eine geeignete Verkettung von
+"head" und "tail" zu jedem Atom im Ausdruck zu gelangen. 
+ 
+Wenn "x" und "y" irgendwelche LISP-Ausdrücke repräsentieren, gelten die folgen­
+den Gleichungen immer: 
+ 
+ 
+           (head (cons x y)) = x 
+           (tail (cons x y)) = y 
+ 
+ 
+Außerdem gilt die folgende Gleichung für jeden nichtatomaren LISP-Ausdruck "z": 
+ 
+ 
+           (cons (head z) (tail z)) = z 
+9 
+ 
+Die Symbole "x", "y" und "z", die wir in diesen Gleichungen benutzt haben, nennt
+man Variablen. In LISP werden Variable benutzt, um LISP-Ausdrücke zu repräsentie­
+ren, und zwar repräsentiert eine Variable in einer Gleichung immer denselben
+LISP-Ausdruck. Variablennamen werden wie Funktionsnamen gebildet, d.h. sie
+können Kleinbuchstaben und Ziffern enthalten. 
+ 
+Eine Funktion, deren Wert "wahr" oder "falsch" sein kann, wird Prädikat genannt. In
+LISP werden die Werte "wahr" und "falsch" durch die Atome "T" (true) und "F"
+(false) vertreten. Ein LISP-Prädikat ist also eine Funktion, deren Wert entweder "T"
+oder "F" ist. 
+ 
+Das Prädikat "eq" ist ein Gleichheitstest für Atome. Es ist bei nicht atomaren Argu­
+menten nicht definiert. 
+ 
+ 
+Beispiele: (eq A A)            = T 
+           (eq A B)            = F 
+           (eq A (A . B))       ist nicht definiert 
+           (eq (A . B) B)       ist nicht definiert 
+           (eq (A . B) (A . B)) ist nicht definiert 
+ 
+ 
+Das Prädikat "atom" hat das Ergebnis ("liefert") "T", wenn sein Argument atomar ist,
+und "F", wenn sein Argument zusammengesetzt ist. 
+ 
+ 
+Beispiele: (atom EXTRALANGEZEICHENKETTE) = T 
+           (atom (U . V))                = F 
+           (atom (head (U . V)))         = T 
+ 
+#page# 
+ 
+1.3 Listen-Notation #goalpage("p1.3")# 
+ 
+ 
+ 
+Alle LISP-Ausdrücke, die wir bisher gesehen haben, waren in Punkt-Notation
+geschrieben. Normalerweise ist es allerdings einfacher, statt der vielen Punkte und
+Klammern Listen von LISP-Ausdrücken zu schreiben, etwa in der Art (A B C XYZ). 
+ 
+LISP bietet eine solche Alternative zur Punkt-Notation an: 
+ 
+Definition: Die Liste (a1 a2 ... an) ist äquivalent zum LISP-Ausdruck 
+            (a1 . (a2 . (... . (an . NIL) ... ))). 
+ 
+Graphisch ausgedrückt heißt das: 
+ 
+ 
+    +-----+-----+ 
+    |  o  |  o  | 
+    +--+--+--+--+ 
+       |     | 
+       V     V 
+      a1   +-----+-----+ 
+           |  o  |  o  | 
+           +--+--+--+--+ 
+              |     | 
+              V     V 
+             a2 
+                        . 
+                          . 
+                            . 
+ 
+                                +-----+-----+ 
+                                |  o  |  o  | 
+                                +--+--+--+--+ 
+                                   |     | 
+                                   V     V 
+                                  an    NIL 
+ 
+ 
+ 
+Oft werden wir für Listen auch die graphische Form 
+ 
+ 
+  +-----+-----+   +-----+-----+             +-----+-----+ 
+  |  o  |  o--+-->|  o  |  o--+-->  . . .   |  o  |  o--+--> NIL 
+  +--+--+-----+   +--+--+-----+             +--+--+-----+ 
+     |               |                         | 
+     V               V                         V 
+    a1              a2                        an 
+ 
+ 
+benutzen. 
+ 
+Aus der Graphik wird deutlich, daß NIL als eine Art Abschlußmarkierung für Listen
+dient. 
+ 
+Eine leere Liste wird durch das Atom NIL dargestellt. Das Prädikat "null" liefert "T",
+wenn sein Argument eine leere Liste ist, sonst "F". 
+ 
+ 
+Beispiele: (null NIL)   = T 
+           (null () )   = T 
+           (null (A B)) = F 
+ 
+ 
+Die Listenelemente können selbst wieder Listen oder Paare in Punkt-Notation sein,
+so daß Listen- und Punkt-Notation beliebig kombinierbar sind. 
+ 
+ 
+ Beispiele:  (A B C) = (A . (B . (C . NIL))) 
+ 
+             +-----+-----+   +-----+-----+   +-----+-----+ 
+             |  o  |  o--+-->|  o  |  o--+-->|  o  |  o--+--> NIL 
+             +--+--+-----+   +--+--+-----+   +--+--+-----+ 
+                |               |               | 
+                V               V               V 
+                A               B               C 
+
+           ((A . B) C) = ((A . B) . (C . NIL)) 
+ 
+             +-----+-----+   +-----+-----+ 
+             |  o  |  o--+-->|  o  |  o--+--> NIL 
+             +--+--+-----+   +--+--+-----+ 
+                |               | 
+                V               V 
+             +-----+-----+      C 
+             |  o  |  o  | 
+             +--+--+--+--+ 
+                |     | 
+                V     V 
+                A     B 
+ 
+           ((A B) C) = ((A . (B . NIL)) . (C . NIL)) 
+ 
+                 +-----+-----+                +-----+-----+ 
+                 |  o  |  o--+--------------->|  o  |  o--+--> NIL 
+                 +--+--+-----+                +--+--+-----+ 
+                    |                            | 
+                    |                            V 
+                    V                            C 
+                 +-----+-----+   +-----+-----+ 
+                 |  o  |  o--+-->|  o  |  o--+--> NIL 
+                 +--+--+-----+   +--+--+-----+ 
+                    |               | 
+                    V               V 
+                    A               B 
+ 
+           (A) = (A . NIL) 
+ 
+                 +-----+-----+ 
+                 |  o  |  o--+--> NIL 
+                 +--+--+-----+ 
+                    | 
+                    V 
+                    A 
+ 
+           ((A)) = ((A . NIL) . NIL) 
+ 
+                 +-----+-----+ 
+                 |  o  |  o--+--> NIL 
+                 +--+--+-----+ 
+                    | 
+                    V 
+                 +-----+-----+ 
+                 |  o  |  o--+--> NIL 
+                 +--+--+-----+ 
+                    | 
+                    V 
+                    A 
+ 
+ 
+ 
+ 
+ 
+Es ist sehr hilfreich, mit den Ergebnissen der elementaren Funktionen vertraut zu
+sein, wenn diese Listen als Argumente erhalten. Zwar können die Ergebnisse notfalls
+immer durch Übersetzung in Punkt-Notation bestimmt werden, aber ein direktes
+Verständnis ist einfacher. 
+ 
+ 
+Beispiele: (head (A B C)) = A 
+           (tail (A B C)) = (B C) 
+ 
+ 
+           (Daher auch die Namen "head" und "tail"! Frei übersetzt heißen die
+            beiden Funktionen "anfang" und "rest".) 
+ 
+ 
+           (cons A (B C)) = (A B C) 
+ 
+#page# 
+ 
+1.4 Syntax und Semantik der Sprache #goalpage("p1.4")# 
+ 
+ 
+ 
+Wir haben bisher einen Datentyp (LISP-Ausdrücke) und fünf elementare Funktionen
+eingeführt. Außerdem haben wir die folgenden Eigenschaften der Sprache beschrie­
+ben: 
+ 
+1. Funktions- und Variablennamen werden wie die Namen von Atomen geschrie­
+   ben, außer, daß dafür Klein- statt Großbuchstaben verwendet werden. 
+2. Die Argumente einer Funktion folgen dieser in der Liste. Eine solche Liste von
+   Funktion und folgenden Argumenten heißt Funktionsaufruf und hat einen LISP-
+   Ausdruck als Ergebnis. 
+3. Funktionen können dadurch verkettet werden, daß ein Argument aus einem Funk­
+   tionsaufruf selbst wieder ein Funktionsaufruf ist, dessen Argumente selbst wieder
+   Funktionsaufrufe sein können, usw. 
+ 
+Diese Regeln erlauben es, Funktionsdefinitionen wie 
+ 
+ 
+   (third x) = (head (tail (tail x))) 
+ 
+ 
+zu schreiben. "third" holt das dritte Element aus einer Liste. 
+ 
+Die Klasse der Funktionen, die man auf diese Weise bilden kann, ist ziemlich be­
+schränkt und nicht sehr interessant. Eine viel größere Funktionenklasse kann man mit
+Hilfe des bedingten Ausdrucks schreiben; es handelt sich dabei um eine Möglichkeit,
+Verzweigungen in Funktionsdefinitionen einzubauen. 
+ 
+Ein bedingter Ausdruck hat die Form 
+ 
+ 
+  (cond (p1 a1) (p2 a2) ... (pn an) ) 
+ 
+ 
+Jedes pi ist ein Ausdruck, dessen Wert "T" oder "F" ist, also ein Prädikat. Die ai
+sind beliebige LISP-Ausdrücke. 
+ 
+Die Bedeutung eines bedingten Ausdrucks ist folgende: Wenn p1 wahr ist, ist a1 der
+Wert des ganzen Ausdrucks. Wenn p1 falsch ist, wird getestet, ob p2 wahr ist; wenn
+das der Fall ist, ist a2 der Wert des Ausdrucks. Die pi werden also von links nach
+rechts durchgegangen, bis ein wahrer Ausdruck gefunden ist; das zugehörige ai ist
+dann der Wert des bedingten Ausdrucks. Wenn kein wahres pi gefunden ist, ist der
+bedingte Ausdruck nicht definiert. 
+Jedes pi oder ai kann selbst wieder ein LISP-Ausdruck, ein Funktionsaufruf oder ein
+bedingter Ausdruck sein. 
+ 
+ 
+Beispiel: (cond ((eq (head x) A) (cons B (tail x))) (T x) ) 
+ 
+ 
+Das Prädikat "T" ist immer wahr. Man liest es am besten als "SONST". Den Wert
+dieses Ausdruck erhält man, wenn man "head" von x durch B ersetzt, wenn der
+gerade gleich mit A ist, und sonst erhält man x. 
+ 
+Der Hauptzweck von bedingten Ausdrücken ist die rekursive Definition von Funktio­
+nen. 
+ 
+ 
+Beispiel: (firstatom x) = (cond ((atom x) x) 
+                                ( T  (firstatom (head x))) 
+                          ) 
+ 
+ 
+Dies Beispiel definiert die Funktion "firstatom", die das erste Atom jedes LISP-Aus­
+drucks bestimmt. Diesen Ausdruck kann man so lesen: wenn "x" ein Atom ist, ist "x"
+selbst die Antwort; sonst muß "firstatom" auf "head" von "x" angewandt werden. 
+ 
+Wenn also "x" ein Atom ist, wird der erste Zweig gewählt, der "x" liefert; sonst wird
+der zweite Zweig "firstatom (head x)" gewählt, weil "T" immer wahr ist. 
+ 
+Die Definition von "firstatom" ist rekursiv, d.h. "firstatom" ist mit durch sich selbst
+definiert. Allerdings, wenn man immerzu den "head" von irgendeinem LISP-Aus­
+druck nimmt, errreicht man irgendwann ein Atom, so daß der Prozeß immer wohlde­
+finiert ist. 
+ 
+Es gibt rekursive Funktionen, die nur für bestimmte Argumente wohldefiniert sind, für
+bestimmte andere dagegen unendlich rekursiv. Wenn das EUMEL-LISP-System
+einen Funktionsionsaufruf mit einer solchen Funktion und "kritischen" Argumenten
+interpretiert, gerät es in unendliche Rekursion, bis entweder der zur Verfügung ste­
+hende Platz im LISP-Heap ausgeschöpft ist (im Heap werden die LISP-Ausdrücke
+gespeichert) oder bis der Laufzeitstack überläuft (der Laufzeitstack ist ein normaler­
+weise unsichtbarer Bestandteil des ELAN-Systems). 
+Wir werden jetzt die Berechnung von "(firstatom ((A . B) . C))" durchführen. Zunächst
+ersetzen wir die Variable x in der Funktionsdefinition durch ((A . B) . C) und erhalten 
+ 
+ 
+ (firstatom ((A . B) . C)) = 
+    (cond ( (atom ((A . B) . C))  ((A . B) . C) ) 
+          ( T  (firstatom (head ((A . B) . C))) ) 
+    ) 
+ 
+((A . B) . C) ist kein Atom, deshalb wird daraus 
+ 
+                  = (cond ( T (firstatom (head ((A . B) . C)))) ) 
+                  = (firstatom (head ((A . B) . C)) ) 
+                  = (firstatom (A . B)) 
+ 
+ 
+ 
+An diesem Punkt müssen wir wieder die Definition von "firstatom" benutzen, diesmal
+aber für "x" überall "(A . B)" einsetzen. 
+ 
+ 
+  (firstatom (A . B)) = (cond ( (atom (A . B)) (A . B) ) 
+                              (T (firstatom (head (A . B))) ) 
+                        ) 
+                      = (cond (T (firstatom (head (A . B))) ) ) 
+                      = (firstatom (head (A . B)) ) 
+                      = (firstatom A) 
+                      = (cond ((atom A) A) 
+                              (T (firstatom (head A)) ) 
+                        ) 
+                      = A 
+ 
+ 
+Wenn in den bedingten Ausdrücken statt der LISP-Ausdrücke arithmetische Aus­
+drücke verwendet würden, könnte man damit auch numerische Rechenvorschriften
+definieren, wie z.B. den Betrag einer Zahl durch 
+ 
+ 
+  (abs x) = (cond ((x < 0) -x) (T x) ) 
+ 
+ 
+oder die Fakultät durch 
+ 
+ 
+  (fak n) = (cond ((n = 0) 1) 
+                  (T (x * (fak (n - 1)))) 
+            ) 
+ 
+ 
+Die Fakultät terminiert bei negativen Argumenten nicht. 
+ 
+Es ist bei den meisten Mathematikern (außer den Logikern) üblich, das Wort "Funk­
+tion" nicht präzise zu verwenden und auf Ausdrücke wie "2x+y" anzuwenden. Da wir
+Ausdrücke benutzen werden, die Funktionen repräsentieren, benötigen wir eine
+Notation, die Funktionen und Ausdrücke unterscheidet. Dafür ist die Lambda-Nota­
+tion von Alonzo Church geeignet. 
+"f" soll ein Ausdruck sein, der für eine Funktion zweier ganzzahliger Variablen steht.
+ 
+Dann sollte es sinnvoll sein, den Funktionsaufruf 
+ 
+ 
+         (f 3 4) 
+ 
+ 
+zu schreiben, so daß man dadurch den Wert dieses Funktionsaufrufs berechnen kann;
+z.B. könnte "(summe 3 4) = 7" gelten. 
+ 
+Wenn man "2x + y" als Funktion ansieht, kann man den Funktionsaufruf 
+ 
+ 
+        ((2x + y) 3 4) 
+ 
+ 
+schreiben. Der Wert dieses Ausdrucks ist aber nicht eindeutig bestimmt, denn es ist
+überhaupt nicht klar, ob nun "2*3+4" oder 2*4+3" gemeint ist. Eine Zeichenfolge
+wie "2x + y" werden wir deshalb Ausdruck und nicht Funktion nennen. Ein Ausdruck
+kann in eine Funktion umgewandelt werden, indem man die Zuordnung von Argumen­
+ten und Variablen festlegt. Bei "2x + y" könnte man beispielsweise festlegen, daß
+"x" immer das erste und "y" immer das zweite Argument sein soll. 
+Wenn "a" ein Ausdruck in den Variablen x1, ... xn ist, dann ist 
+ 
+ 
+        (lambda (x1 ... xn) a) 
+ 
+ 
+eine Funktion mit n Argumenten. Den Wert der Funktionsaufrufe mit dieser Funktion
+(also der Ausdrücke der Form 
+ 
+ 
+        ((lambda (x1 ... xn) a) (b1 ... bn)) 
+ erhält man, indem man die Variablen x1 ... xn durch die n Argumente des Aufrufs
+ersetzt. Beispielsweise ist 
+ 
+ 
+        ((lambda (x y) (2*x + y)) (3 4)) = 2*3 + 4 = 10 , 
+ 
+ 
+während 
+ 
+ 
+        ((lambda (y x) (2*x + y)) (3 4)) = 2*4 + 3 = 11 
+ 
+ 
+ist. 
+ 
+Die Variablen in einem Lambdaausdruck sind sogenannte Parameter (oder gebundene
+Variable). Interessant ist, daß eine Funktion sich nicht ändert, wenn man eine Variable
+systematisch durch eine andere Variable ersetzt, die nicht bereits im Lambdaausdruck
+vorkommt. 
+ 
+ 
+        (lambda (x y) (2*y + x)) 
+ 
+ 
+ist also dasselbe wie 
+ 
+ 
+        (lambda (u v) (2*v + u)) . 
+ 
+ 
+Manchmal werden wir Ausdrücke benutzen, in denen eine Variable nicht durch das
+Lambda gebunden ist. Beispielsweise ist das n in 
+ 
+ 
+  (lambda (x y) (x*n + y*n)) 
+ 
+ 
+nicht gebunden. Eine solche nicht gebundene Variable nennt man frei. 
+Wenn für eine freie Variable vor der Benutzung kein Wert vereinbart wurde, ist der
+Wert des Funktionsaufrufs nicht definiert, falls der Wert der Variablen auf das Ergeb­
+nis einen Einfluß hat. 
+ 
+Die Lambdanotation reicht allein für die Definition rekursiver Funktionen nicht aus.
+Neben den Variablen muß auch der Name der Funktion gebunden werden, weil er
+innerhalb der Funktion für eine Zeichenfolge steht. 
+ 
+Wir hatten die Funktion "firstatom" durch die Gleichung 
+ 
+ 
+  (firstatom x) = (cond ((atom x) x) 
+                        (T (firstatom (head x))) 
+                  ) 
+ 
+ 
+definiert. Mit der Lambda-Notation können wir schreiben: 
+ 
+ 
+  firstatom = (lambda (x) (cond ((atom x) x) 
+                                (T (firstatom (head x))) 
+              )           ) 
+ 
+ 
+ 
+Das Gleichheitszeichen ist in Wirklichkeit nicht Teil der LISP-Sprache, sondern eine
+Krücke, die wir nicht mehr brauchen, wenn wir die richtige Schreibweise eingeführt
+haben. 
+ 
+Die rechte Seite der obigen Gleichung ist als Funktion nicht vollständig, da dort nichts
+darauf hinweist, daß das "firstatom" im einem bedingten Ausdruck für eben die rechte
+Seite steht. Deshalb ist die rechte Seite als Definition für die linke Seite ("firstatom")
+noch nicht geeignet. 
+ 
+Damit wir Definitionen schreiben können, in denen der Name der gerade definierten
+Funktion auftaucht, führen wir die Label-Notation ein (engl. label = Marke, (Preis-)
+Schildchen). Wenn "a" eine Funktion ist, und "n" ihr Name, schreiben wir "(label n
+a)". 
+ 
+Nun können wir die Funktion "firstatom" ohne Gleichheitszeichen schreiben: 
+ 
+ 
+  (label firstatom (lambda (x) (cond ((atom x) x) 
+                                     (T (firstatom (head x))) 
+  )                )           ) 
+ 
+ 
+In dieser Definition ist "x" eine gebundene Variable und "firstatom" ein gebundener
+Funktionsname. 
+#page# 
+ 
+2. Das LISP-Interpreter-System#goalpage("p2")# 
+ 
+ 
+ 
+2.1  Die universelle LISP-Funktion 
+     "evalquote" #goalpage("p2.1")# 
+ 
+ 
+ 
+Ein Interpreter oder eine allgemeine Funktion ist eine Funktion, die den Wert jedes
+gegebenen Ausdrucks berechnen kann, wenn der Ausdruck in einer geeigneten Form
+vorliegt. (Wenn der zu interpretierende Ausdruck einen Aufruf einer unendlich rekur­
+siven Funktion enthält, wird der Interpreter natürlich ebenfalls unendlich rekursiv.) 
+Wir sind jetzt in der Lage, eine allgemeine LISP-Funktion 
+ 
+ 
+        (evalquote function arguments) 
+ 
+ 
+zu definieren. "evalquote" muß als erstes Argument ein LISP-Ausdruck übergeben
+werden. Dieser wird als Funktion aufgefasst und auf die folgenden Argumente ange­
+wendet. 
+ 
+Im Folgenden sind einige nützliche Funktionen zur Manipulation von LISP-Aus­
+drücken angegeben. Einige von ihnen werden als Hilfsfunktionen für die Definition von
+"evalquote" gebraucht, die wir uns vorgenommen haben. 
+ 
+ 
+        (equal x y) 
+ 
+ 
+ist ein Prädikat, das wahr ist, wenn seine Argumente gleiche LISP-Ausdrücke sind.
+(Das elementare Prädikat "eq" ist ja nur für Atome definiert.) 
+ 
+Die Definition von "equal" ist ein Beispiel für einen bedingten Ausdruck innerhalb
+eines bedingten Ausdrucks. 
+ 
+ 
+(label equal 
+  (lambda (x y) 
+    (cond 
+      ((atom x) (cond 
+                  ((atom y) (eq x y)) 
+                  (T F) 
+                ) 
+      ) 
+      ((equal (head x) (head y)) (equal (tail x) (tail y))) 
+      (T F) 
+    ) 
+  ) 
+) 
+ 
+ 
+ 
+Folgende Funktion liefert einen LISP-Ausdruck, der gleich mit "destination" ist,
+außer daß darin überall statt "old" "new" steht. 
+ 
+ 
+(changeall (destination old new)) 
+ 
+=   (cond ((equal destination old) new) 
+          ((atom destination) destination) 
+          (T (cons (changeall (head destination) old new) 
+                   (changeall (tail destination) old new) 
+             ) 
+          ) 
+    ) 
+ 
+ 
+Beispielsweise gilt 
+ 
+ 
+(changeall ((A . B) . C) B (X . A)) = ((A . (X . A)) . C) 
+ 
+ 
+Die folgenden Funktionen sind nützlich, wenn Listen verarbeitet werden sollen. 
+ 
+1. (append x y) 
+   hängt an die Liste "x" den LISP-Ausdruck "y". 
+ 
+ 
+     (append x y) = 
+       (cond ((null x) y) 
+             (T (cons (head x) (append (tail x) y) )) 
+       ) 
+ 
+ 
+2. (member list pattern) 
+   Dies Prädikat testet, ob der LISP-Ausdruck "pattern" in der Liste "list" vor­
+   kommt. 
+ 
+ 
+     (member list pattern) = 
+       (cond ((null list) F) 
+             ((equal (head list) pattern) T) 
+             (T (member (tail list) pattern)) 
+       ) 
+ 
+ 
+3. (pairlist list1 list2 oldpairlist) 
+   Diese Funktion liefert eine Liste von Paaren, die die sich entsprechenden Elemen­
+   te der Listen "list1" und "list2" enthalten, und an der noch die Liste "oldpairlist"
+   hängt. 
+ 
+ 
+ 
+     (pairlist list1 list2 oldpairlist) = 
+       (cond ((null list1) oldpairlist) 
+             (T (cons (cons (head list1) (head list2)) 
+                      (pairlist (tail list1) (tail list2) oldpairlist) 
+                ) 
+             ) 
+       ) 
+ 
+ 
+Beispiel: 
+   (pairlist (A B C) (U V W) ((D . X) (E . Y)) ) = 
+             ((A . U) (B . V) (C . W) (D . X) (E . Y)) 
+ 
+ 
+Eine solche Liste von Paaren wird auch Assoziationsliste genannt, wenn das erste
+Element jedes Paars ein Atom ist, das über diese Liste mit dem zweiten Element
+assoziiert ist. 
+ 
+5. (association pattern associationlist) 
+   Wenn "association list" eine Assoziationsliste wie oben beschrieben ist, liefert
+   "association" das Paar der Liste, dessen erstes Element "pattern" ist. Es ist also
+   eine Funktion zum Durchsuchen von Tabellen. 
+ 
+ 
+     (association pattern alist) = 
+       (cond ((eq (head (head alist)) pattern) (head alist)) 
+             (T (association pattern (tail alist))) 
+       ) 
+ 
+Beispiel: 
+ 
+(association B ( (A . (M N)) 
+                 (B . (HEAD X)) 
+                 (C . (QUOTE M)) 
+                 (B . (TAIL X)) 
+               )                  ) = (B . (HEAD X)) 
+ 
+ 
+(replace expr alist) 
+   "alist" muß eine Assoziationsliste sein. "replace" produziert einen Ausdruck, der
+   "expr" sehr ähnlich ist, nur sind alle Atome darin durch den LISP-Ausdruck
+   ersetzt, mit dem sie in "alist" assoziiert sind. 
+ 
+ 
+     (replace expr alist) = 
+       (cond ((atom expr) (association expr alist)) 
+             (T (cons (replace (head expr) alist) 
+                      (replace (tail expr) alist) 
+                ) 
+             ) 
+       ) 
+ 
+Beispiel: 
+ 
+  (replace (X SCHRIEB Y) 
+           ((Y . (GOETZ VON BERLICHINGEN)) (X . GOETHE)) 
+  ) 
+ 
+  =        (GOETHE SCHRIEB (GOETZ VON BERLICHINGEN)) 
+ 
+ 
+ 
+Die allgemeine Funktion "evalquote", die wir jetzt definieren wollen, gehorcht der
+folgendem Beispiel zugrundeliegenden Regel: 
+ 
+ 
+Beispiel: 
+                 (evalquote 
+Funktion:          (LAMBDA (X Y) (CONS (HEAD X) Y) ) 
+Argumente:         (A B)  (C D) 
+                 ) 
+= 
+                 (apply 
+Funktion:          (LAMBDA (X Y) (CONS (HEAD X) Y)) 
+Argumentliste:     ((QUOTE (A B)) (QUOTE (C D))) 
+Bindung:           NIL 
+                 ) 
+ 
+ 
+Die Argumente von "evalquote" werden also zu einer gequoteten Argumentliste von
+"apply". Die QUOTE-Funktion bewirkt, daß das Argument der QUOTE-Funktion
+wörtlich genommen, also nicht weiter evaluiert wird. Das dritte Argument von "apply",
+das NIL ist eine leere Bindeliste zur Bindung von Parametern und Argumenten im
+nächsten Schritt: 
+ 
+ 
+= 
+                 (eval 
+Argumente:         (CONS (HEAD X) Y) 
+Bindung:           ((X.(A B)) (Y . (C D))) 
+                 ) 
+= 
+                 (cons (head (A B)) (C D)) 
+= 
+                 (A C D)            =  Ergebnis von "evalquote" . 
+ 
+ 
+"evalquote" wird hauptsächlich durch die Hilfsfunktion "apply" definiert. "apply"
+berechnet Funktionsaufrufe, indem es die Argumente und die Parameter der Funktion
+bindet und den Funktionsrumpf berechnet. Die Bindungen werden in einer Assozia­
+tionsliste, der Bindeliste, gespeichert. Da bedingte Ausdrücke und Konstanten formal
+wie Funktionsaufrufe von Funktionen "cond" und "quote" aussehen, werden sie auch
+so behandelt. 
+ 
+Wir definieren also: 
+ 
+ 
+  (evalquote fkt expr) = (apply fkt (quote expr) NIL) . 
+ 
+ 
+sowie : 
+ 
+ 
+  (eval expr binding) = 
+    (cond ((atom expr) (tail (association expr binding))) 
+          (T (apply (head expr) (tail expr) binding)) 
+    ) 
+ 
+ 
+"eval" stellt also erst fest, ob es sich um ein Atom oder um einen Funktionsaufruf
+handelt. Da es nur diese beiden Möglichkeiten gibt, ist diese Einteilung vollständig. 
+ 
+Atome sind immer Übersetzungen von Variablen, für die eine Bindung existieren muß,
+so daß ihr Wert aus der Bindeliste geholt wird. 
+ 
+Funktionsaufrufe sind immer Listen; im zweiten Zweig werden die Funktion und die
+Parameterliste getrennt und an "apply" übergeben. 
+ 
+Um sich die Aktionen in diesem zweiten Zweig von "eval" genauer vorstellen zu
+können, ist vielleicht die in Abschnitt 1.1 beschriebene graphische Darstellungsmetho­
+de hilfreich; beispielsweise würde sich ein Lambda-Ausdruck so ausnehmen: 
+ 
+ 
+  +-----+-----+   +-----+-----+   +-----+-----+ 
+  |  o  |  o--+-->|  o  |  o--+-->|  o  |  o--+-->NIL 
+  +--+--+-----+   +--+--+-----+   +--+--+-----+ 
+     |               |               | 
+     V               V               V 
+  LAMBDA      Parameterliste     Ausdruck 
+ 
+ 
+"apply" bekommt nun von "eval" eine Funktion und eine Parameterliste sowie die
+Bindeliste übergeben. Mit diesen beiden macht es folgendes: 
+ 
+ 
+ (apply fn args binding) = 
+(cond 
+  ((atom fn) 
+     (cond ((eq fn HEAD)  (head (eval (head args) binding))) 
+           ((eq fn TAIL)  (tail (eval (head args) binding))) 
+           ((eq fn CONS)  (cons (eval (head args) binding) 
+                                (eval (head (tail args)) binding) 
+           )              ) 
+           ((eq fn ATOM)  (atom (eval (head args) binding))) 
+           ((eq fn EQ)    (eq   (eval (head args) binding) 
+                                (eval (head (tail args)) binding) 
+           )              ) 
+           ((eq fn QUOTE) (head args)) 
+           ((eq fn COND) (evalcond args binding)) 
+           (T (apply (tail (association fn binding)) args binding)) 
+     ) 
+  ((eq (head fn) LABEL) 
+     (apply (head (tail (tail fn))) 
+             args (cons (cons (head (tail fn)) 
+                              (head (tail (tail fn))) 
+                        ) 
+                        binding) 
+  )  ) 
+  ((eq (head fn) LAMBDA) (eval (head (tail (tail fn))) 
+                               (pairlist (head (tail fn)) 
+                                         args binding) 
+  )                      ) 
+) 
+ 
+ 
+ 
+ 
+ 
+ 
+Das erste Argument von "apply" ist eine Funktion (unter der Voraussetzung, daß
+"quote" und "cond" als Funktionen anerkannt werden). 
+ 
+Wenn es eine der elementaren Funktionen "head", "tail", "cons", "atom" oder "eq"
+ist, wird die jweilige Funktion auf die Argumente angewandt, die vorher berechnet
+werden. Diese Berechnung erfolgt mit "eval", das ja für Variablen Werte aus der
+Bindeliste liefert und für Funktionsaufrufe das, was "apply" mit ihnen machen kann. 
+ 
+Wenn es sich um "quote" handelt, wird das erste Argument unverändert geliefert
+"quote" heißt ja "dies ist eine Konstante, die so, wie sie da steht, übernommen wer­
+den soll". 
+ 
+Wenn es sich um "cond" handelt, wird die Funktion "eval cond" aufgerufen, doch
+auch ihre Argumente werden nicht berechnet, außerdem gehört die Assoziationsliste
+zu den Argumenten: 
+ 
+ 
+ eval (cond condlist, binding) = 
+    (cond ((eval (head (head condlist)) binding) 
+           (eval (head (tail (head condlist))) binding) 
+          ) 
+          (T (cond (tail condlist) binding)) 
+    ) 
+ 
+ 
+ 
+Hier empfiehlt es sich, einen bedingten Ausdruck in graphischer Form hinzuschreiben
+und die Auswertung anhand der Zeichnung nachzuvollziehen. 
+ 
+Wenn die Funktion nichts von alledem ist, wird in der Bindeliste nachgesehen, ob
+dies Atom nicht an eine Funktion gebunden ist; falls ja, wird eine Auswertung dieser
+Funktion mit den gleichen Argumenten versucht. 
+ 
+Wenn das erste Argument von "apply" kein Atom ist, muß es ein LABEL- oder ein
+LAMBDA-Ausdruck sein. 
+ 
+Ein LABEL-Ausdruck hat die Form 
+ 
+ 
+  +-----+-----+   +-----+-----+   +-----+-----+ 
+  |  o  |  o--+-->|  o  |  o--+-->|  o  |  o--+--> NIL 
+  +--+--+-----+   +--+--+-----+   +--+--+-----+ 
+     |               |               | 
+     V               V               V 
+   LABEL           Name           Funktion 
+ 
+ 
+Funktionsname und Definition werden in einem funktionalen Eintrag in die Bindeliste
+eingefügt, so daß der Name an die Funktion gebunden ist. 
+ 
+Ein LAMBDA-Ausdruck hat die Form 
+ 
+ 
+  +-----+-----+   +-----+-----+   +-----+-----+ 
+  |  o  |  o--+-->|  o  |  o--+-->|  o  |  o--+--> NIL 
+  +--+--+-----+   +--+--+-----+   +--+--+-----+ 
+     |               |               | 
+     V               V               V 
+   LAMBDA      Parameterliste    Ausdruck 
+ 
+ 
+Dabei ist die Parameterliste eine Liste von Atomen, den Parametern. Die Auswertung
+läuft so ab, daß die Parameter durch "pairlist" an die Argumente gebunden werden
+und mit dieser neuen Bindeliste der Ausdruck berechnet wird. 
+ 
+Das EUMEL-LISP bietet eine Reihe weiterer Möglichkeiten, die erst später beschrie­
+ben werden. Hier können wir allerdings schon die folgenden Punkte abhandeln: 
+ 
+1. Jede LISP-Eingabe ist ein LISP-Ausdruck. Der "head" dieses Ausdrucks wird
+   als Funktion aufgefaßt und auf den gequoteten "tail" des Ausdrucks, nämlich die
+   nicht zu evaluierenden Argumente angewandt. Die Übersetzung von Kleinbuchsta­
+   ben in Großbuchstaben wird vom LISP-System übernommen. 
+ 
+2. In der Theorie des reinen LISP müssen alle Funktionen außer den fünf Basisfunk­
+   tionen an allen Stellen wieder definiert werden, an denen sie aufgerufen werden.
+   Das ist eine für die Praxis äußerst unhandliche Regelung; das EUMEL-LISP-
+   System kennt weitere vordefinierte Funktionen und bietet die Möglichkeit, beliebig
+   viele weitere Standardfunktionen einzuführen, auch solche Funktionen, deren
+   Argumente nicht berechnet werden (wie "quote") oder solche, die beliebig viele
+   Argumente haben dürfen (wie "cond"). 
+ 
+3. Die Basisfunktion "eq" hat immer einen wohldefinierten Wert, dessen Bedeutung
+   im Fall, daß Nicht-Atome verglichen werden, im Kapitel über Listenstrukturen
+   erklärt wird. 
+ 
+4. Außer in sehr seltenen Fällen schreibt man nicht (quote T), (quote F) oder (quote
+   NIL), sondern T, F und NIL. 
+ 
+5. Es besteht die Möglichkeit, mit Ganzzahlen zu rechen, die als weiterer Typ von
+   Atomen gelten. Außerdem können TEXTe und Einzelzeichen (CHARACTERs)
+   gespeichert werden. 
+ 
+6. Es besteht die Möglichkeit der Ein- und Ausgabe von LISP-Ausdrücken, Ganz­
+   zahlen, TEXTen und CHARACTERs. 
+ 
+WARNUNG:   Die oben angegebenen Definitionen von "eval" und "apply" dienen nur
+           pädagogischen Zwecken und sind nicht das, was wirklich im Interpreter
+           abläuft. 
+           Um zu entscheiden, was wirklich vor sich geht, wenn der Interpreter
+           aufgerufen wird, sollte man sich an die ELAN-Quellprogramme halten. 
+#page# 
+ 
+2.2  Anwendungsregeln und Beispiele #goalpage("p2.2")# 
+ 
+ 
+ 
+Die Funktionsweise des LISP-Interpreteres kann bequem unter Verwendung der
+Funktion "trace" verfolgt werden. Der Aufruf: 
+ 
+ 
+               (trace) 
+ 
+ 
+schaltet den Trace-Protokollmodus des Interpreters ein bzw. aus. 
+ 
+Das folgende Beispiel ist ein LISP-Programm, das die drei Funktionen "union",
+"intersection" und "member" als Standardfunktionen einführt Die Funktionen lauten
+folgendermaßen: 
+ 
+ 
+  (member pattern list) = (cond ((null list) F) 
+                                ((eq (head list) pattern) T) 
+                                (T (member pattern (tail list))) 
+                          ) 
+ 
+  (union x y) = (cond ((null x) y) 
+                      ((member (head x) y) (union (tail x) y)) 
+                      (T (cons (head x) (union (tail x) y))) 
+                ) 
+ 
+  (intersection x y) = (cond ((null x) NIL) 
+                             ((member (head x) y) 
+                                 (cons (head x) (intersection
+                                 (tail x) y)) 
+                             ) 
+                             (T (intersection (tail x) y)) 
+                       ) 
+ 
+ 
+Um die Funktionen als neue Standardfunktionen einzuführen, benutzen wir die Pseu­
+dofunktion "define": 
+ 
+ 
+  (DEFINE 
+    (MEMBER . (LAMBDA (PATTERN LIST) 
+                 (COND ((NULL LIST) F) 
+                       ((EQ (HEAD LIST) PATTERN) T) 
+                       (T (MEMBER PATTERN (TAIL LIST))) 
+    )          ) ) 
+    (UNION . (LAMBDA (X Y) 
+                (COND ((NULL X) Y) 
+                      ((MEMBER (HEAD X) Y) (UNION (TAIL X) Y)) 
+                      (T (CONS (HEAD X) (UNION (TAIL X) Y))) 
+    )         ) ) 
+    (INTERSECTION . (LAMBDA (X Y) 
+                      (COND ((NULL X) NIL) 
+                            ((MEMBER (HEAD X) Y) 
+                              (CONS (HEAD X) (INTERSECTION (TAIL
+                              X) Y)) 
+                            ) 
+                            (T (INTERSECTION (TAIL X) Y)) 
+    )               ) ) 
+  ) 
+ 
+ 
+Die Funktion DEFINE, liefert als Pseudofunktion nicht nur einen LISP-Ausdruck als
+Ergebnis, sondern hat auch einen bleibenden Effekt, nämlich eine Veränderung im
+LISP-Heap. 
+ 
+DEFINE hat beliebig viele Parameter der Form (Name . Funktion) und bewirkt, daß die
+Funktionen unter dem jeweiligen Namen im System verfügbar werden, also für die
+weitere Programmausführung definiert werden. Das Ergebnis von DEFINE ist eine
+Liste der neuen Funktionsnamen, also hier 
+ 
+ 
+  (MEMBER UNION INTERSECTION) 
+ 
+ 
+Der Wert den der LISP-Interpreter bei Eingabe von 
+ 
+ 
+  (intersection (a1 a2 a3) (a1 a3 a5)) 
+ 
+ 
+liefert ist     (A1 A3) , 
+ 
+ 
+Die Funktion 
+ 
+ 
+   (union (x y z) (u v w x)) 
+ 
+ 
+liefert       (Y Z U V W X) . 
+ 
+ 
+ 
+Es folgen einige elementare Regeln für LISP-Programme: 
+ 
+1. Ein LISP-Programm besteht aus einem Funktionsaufruf. Im Beispiel ist das die
+   Funktion DEFINE, die ihre Parameter (beliebig viele) berechnet und ausgibt. Die
+   Berechnung der Parameter erfolgt dabei in der Reihenfolge der Parameter (norma­
+   le LISP-Funktionen mit mehreren Parametern berechnen standardmäßig alle
+   Parameter, allerdings in irgendeiner Reihenfolge). 
+ 
+2. LISP ist formatfrei, d.h. jedes Symbol kann in jeder Spalte stehen. Für die Bedeu­
+   tung des Programms ist nur die Reihenfolge der Symbole maßgeblich. Zeilen­
+   wechsel wird als Leerzeichen aufgefaßt. 
+ 
+3. Atome müssen mit einem Buchstaben anfangen, damit sie nicht mit Zahlen ver­
+   wechselt werden. 
+ 
+4. Ein LISP-Ausdruck der Form (A B C . D) ist eine Abkürzung für (A.(B.(C.D))).
+   Jede andere Plazierung des Punkts ist ein Fehler (falsch wäre z.B. (A . B C) ). 
+ 
+5. Eine Anzahl von Basisfuntionen existiert von Anfang an, ohne daß sie durch
+   DEFINE eingeführt wurden. Der  Programmierer kann weitere Funktionen bleibend
+   oder für die Dauer eines Programmlaufs einführen; dabei ist die Reihenfolge der
+   neuen Funktionen gleichgültig. 
+#page# 
+ 
+2.3 Variablen#goalpage("p2.3")# 
+ 
+ 
+ 
+Eine Variable ist ein Symbol, das ein Argument einer Funktion repräsentiert. Man
+kann also schreiben: "a + b, wobei a = 3 und b = 4". In dieser Situation ist keine
+Verwechslung möglich, so daß klar ist, daß das Ergebnis 7 ist. Um zu diesem Ergeb­
+nis zu kommen, muß man die Zahlen anstelle der Variablen einsetzen und die Opera­
+tion ausführen, d.h. die Zahlen addieren. 
+ 
+Ein Grund, weshalb das eindeutig ist, liegt darin, daß "a" und "b" nicht "direkt"
+addiert werden können, so daß etwa "ab" entsteht. In LISP kann die Situation viel
+komplizierter sein. Ein Atom kann eine Variable oder ein Atom sein. 
+ 
+Sollte der zukünftige LISP-Benutzer an dieser Stelle entmutigt sein, sei ihm gesagt,
+daß hier nichts Neues eingeführt wird. Dieser Abschnitt ist nur eine Wiederholung der
+Überlegungen aus Abschnitt 1.4. Alles, was wir in diesem Abschnitt sagen, kann man
+aus den Regeln für LISP-Ausdrücke oder aus der allgemeinen Funktion "evalquote"
+ableiten. 
+ 
+Der Formalismus, der in LISP die Variablen kennzeichnet, ist die Lambdanotation von
+Church. Der Teil des Interpreters, der die Variablen an Werte bindet, heißt "apply".
+Wenn "apply" auf eine Funktion stößt, die mit LAMBDA anfängt, wird die Variablenli­
+ste (Argumentliste) mit der Parameterliste gepaart und am Anfang der Bindeliste
+eingefügt. 
+ 
+Während der Berechnung des Funktionsrumpfs müssen manchmal Variablen durch
+ihre Werte ersetzt werden. Das geschieht dadurch, daß ihr Wert in der Bindeliste
+nachgesehen wird. Wenn eine Variable mehrmals gebunden wurde, wird die zuletzt
+etablierte Bindung verwendet. Der Teil des Interpreters, der diese "Berechnungen"
+und die Berechnung von Funktionsaufrufen durchführt, heißt "eval". 
+ 
+ 
+ 
+#page#
+ 
+2.4 Konstanten#goalpage("p2.4")# 
+ 
+ 
+ 
+Manchmal heißt es, eine Konstante stehe für sich selbst, im Gegensatz zu einer
+Variablen, die für etwas anderes, nämlich ihren Wert, steht. 
+Dies Konzept funktioniert in LISP nicht so ohne weiteres; es ist hier sinnvoller, zu
+sagen, eine Variable ist konstanter als die andere, wenn sie in einer höheren Ebene
+gebunden ist und ihren Wert seltener ändert. 
+In LISP bleibt eine Variable im Bereich des LAMBDA konstant, von dem sie gebunden
+ist. Wenn eine Variable einen festen Wert hat, unabhängig davon, was in der Bindeli­
+ste steht, wird sie (echte) Konstante genannt. Dies wird mit Hilfe der Eigenschaftsliste
+(E-Liste) des Atoms erreicht. 
+Jedes Atom hat eine E-Liste, in der Paare von Atomen und beliebigen Strukturen
+gespeichert sind. Ein Atom hat die Eigenschaft A, wenn in seiner E-Liste ein Paar
+mit dem Atom A enthält; die dazugehörige "beliebige Struktur" heißt Wert dieser
+Eigenschaft. 
+Wenn ein Atom die Eigenschaft APVAL besitzt, ist es eine Konstante, deren Wert der
+Wert der Eigenschaft ist. 
+Konstanten können durch die Pseudofunktion 
+ 
+ 
+       (set atom wert) 
+ 
+ 
+gesetzt werden; nach der Auswertung eines solchen Aufrufs hat das Atom "atom"
+immer den Wert "wert" - bis zum nächsten "set". Eine interessante Klasse von
+Konstanten sind solche Konstanten, die sich selbst als Wert haben. Ein Beispiel dafür
+ist NIL. Der Wert dieser Konstanten ist wieder NIL. Daher kann NIL nicht als Variable
+benutzt werden, da es ja eine Konstante ist. (T und F gehören ebenfalls zu dieser
+Klasse). 
+ 
+#page#
+ 
+2.5 Funktionen#goalpage("p2.5")# 
+ 
+ 
+ 
+Wenn ein LISP-Ausdruck für eine Funktion steht, ist die Situation ähnlich der, in der
+ein Atom für einen Wert steht. Wenn die Funktion rekursiv ist, muß sie einen Namen
+bekommen. Das geht mit einem LABEL-Ausdruck, der den Namen mit der Funk­
+tionsdefinition in der Bindeliste paart. Dadurch wird der Name an die Funktionsdefini­
+tion gebunden, so wie eine Variable an ihren Wert gebunden wird. In der Praxis setzt
+man LABEL selten ein. Normalerweise ist es einfacher, Name und Definition wie bei
+den Konstanten zu verknüpfen. Dies geschieht mit der Pseudofunktion DEFINE, die
+wir am Anfang des Kapitels benutzt haben. 
+Diese Funktion kann beliebig viele Parameter der Form 
+ 
+ 
+        (atom . funktion) 
+ 
+ 
+haben, wobei "atom" der Name der zu definierenden Funktion "funktion" werden soll.
+Sie bewirkt, daß die Definition unter der Eigenschaft FUNCTION in der E-Liste des
+Atoms abgelegt wird. 
+#page# 
+ 
+3. Erweitertes LISP#goalpage("p3")#  
+ 
+ 
+In diesem Kapitel werden wir einige Erweiterungen zum reinen LISP einführen. Zu
+diesen Erweiterungen gehören Möglichkeiten für Arithmetik, Zeichenkettenverarbei­
+tung, Funktionen, die spezielle Argumente erwarten, und Ein- und Ausgabe. 
+ 
+In allen Fällen handelt es sich bei den Erweiterungen um zusätzliche Funktionen. So
+heißt das Kommando für die Ausgabe eines LISP-Ausdrucks PUT. Syntaktisch ist
+PUT nichts anderes als eine Funktion mit einem Argument. Sie kann mit anderen
+Funktionen verkettet werden, und diese Verkettung wird ganz auf die übliche Art
+behandelt, zuerst Berechnung der innern, dann der äußeren Funktionsaufrufe. Ein
+Ergebnis ist nur in dem trivialen Sinn vorhanden, daß PUT sein Argument wieder
+liefert, also die Identität ist. 
+ 
+Funktionen, die eine Aktion wie Ein- oder Ausgabe bewirken, oder die Langzeitwir­
+kung (gesehen auf die Ausführungsdauer des Programms) haben, wie DEFINE und
+SET, heißen Pseudofunktionen. Es ist eine Besonderheit von LISP, daß alle Funktio­
+nen einschließlich den Pseudofunktionen ein Ergebnis haben müssen. In einigen
+Fällen ist das Ergebnis trivial und kann ignoriert werden. 
+ 
+In diesem Kapitel beschreiben wir verschiedene Erweiterungen der Sprache LISP, die
+im System fest enthalten sind. 
+ 
+ 
+#page#
+ 
+3.1 Gequotete Parameter #goalpage("p3.1")# 
+ 
+ 
+ 
+Bevor ein Argument an eine Funktion übergeben wird, wird erst sein Wert in der
+Bindeliste nachgesehen, d.h. es wird nicht der Name der Variablen übergeben, son­
+dern ihr Wert. Wenn das Argument als Konstante behandelt werden soll, muß es
+ge"quotet" werden, d.h. statt "argument" steht (quote argument). Wenn ein Argument
+einer Funktion immer als Konstante behandelt werden soll, ist es bequemer, das
+Argument nicht jedesmal zu quoten. Das EUMEL-LISP-System erlaubt, in diesem
+Fall den formalen Parameter in der Funktionsdefinition bereits zu quoten. 
+ 
+Dieser Mechanismus wurde auch benutzt, um QUOTE zu implementieren; die Funk­
+tion lautet 
+ 
+ 
+    quote = (lambda ((QUOTE x)) x) 
+ 
+ 
+ 
+ 
+#page# 
+ 
+3.2  Funktionen mit beliebig vielen 
+     Argumenten #goalpage("p3.2")# 
+ 
+ 
+ 
+Ein Beispiel ist "list", das beliebig viele Argumente haben kann, die zu einer Liste
+zusammengefaßt werden. Da eine Funktion nur eine feste Anzahl von Parametern
+haben kann, eine Funktion mit beliebig vielen Argumenten aber gewiß keine feste
+Anzahl von Argumenten hat, werden die beliebig vielen Argumente zu einer Liste
+zusammengefaßt und ein einziger Parameter wird an diese Liste gebunden. Da "list"
+genau diese Liste liefern soll, wird diese Funktion ebenfalls zu einer "Identität": 
+ 
+ 
+   list = (lambda ((INDEFINITE x)) x) 
+ 
+ 
+Solche Parameter werden durch INDEFINITE gekennzeichnet. Sie können auch ge­
+quotet werden, indem man (INDEFINITE QUOTE parameter) schreibt; das wirkt so, als
+wären alle Argumente, die diesem Parameter zugeordnet werden, einzeln gequotet
+worden. 
+ 
+ 
+   evalquote = (lambda (fkt (INDEFINITE QUOTE expr)) 
+                       (apply fkt expr NIL) ) 
+ 
+ 
+
+#page# 
+ 
+3.3 Funktionale Parameter #goalpage("p3.3")# 
+ 
+ 
+ 
+In der Mathematik gibt es Funktionen, die andere Funktionen als Argument haben. In
+der Algebra könnte man die Funktion "(operation operator a b)" definieren, wobei
+"operator" ein funktionales Argument ist, das die Operation festlegt, die auf "a" und
+"b" ausgeführt werden soll. Beispielsweise gilt 
+ 
+ 
+  operation (+ 3 4) = 7 
+  operation (* 3 4) = 12 
+ 
+ 
+In LISP sind funktionale Argumente sehr nützlich. Eine wichtige Funktion mit einem
+Argument ist MAPLIST. Ihre Definition ist 
+ 
+ 
+  (LAMBDA (LIST (FUNCTION FN)) 
+    (COND ((NULL LIST) NIL) 
+          (T (CONS (FN (HEAD LIST)) (MAPLIST (TAIL LIST) FN))) 
+  ) ) 
+ 
+ 
+Diese Funktion nimmt eine Liste und eine Funktion als Argument und wendet die
+Funktion auf die Listenelemente an. 
+ 
+ 
+#page# 
+ 
+3.4 Prädikate und boolesche Konstanten #goalpage("p3.4")# 
+ 
+ 
+ 
+Die booleschen Werte sind, wie in Kapitel 1 gesagt, T und F. Bei LISP-Ausdrücken
+müßte daraus (quote T) und (quote F) werden, aber da die APVALs dieser Atome
+wieder den Wert T und F haben, ist das quoten nicht nötig. 
+ 
+Prädikate sind Funktionen, die T oder F als Ergebnis haben; es gibt also keine forma­
+len Unterschiede zwischen anderen Funktionen und Prädikaten. 
+ 
+Daher ist es durchaus möglich, daß eine Funktion einen Wert liefert, der weder T
+noch F ist, daß aber durch einen bedingten Ausdruck an dieser Stelle ein boolescher
+Ausdruck verlangt wird. In diesem Fall ist die Wirkung des Ausdrucks nicht definiert. 
+ 
+Das Prädikat EQ hat folgendes Verhalten: 
+1. Wenn seine Argumente verschieden sind, ist das Ergebnis F. 
+2. Wenn die Argumente dasselbe Atom sind, ist das Ergebnis T. 
+3. Wenn die Argumente gleich, aber nicht atomar sind, ist das Ergebnis T oder F, je
+   nachdem, ob sie ein und dasselbe Objekt im Heap sind oder nicht. 
+ 
+#page# 
+ 
+3.5 Unbenannte Atome #goalpage("p3.5")# 
+ 
+ 
+ 
+Die meisten Atome im EUMEL-LISP haben einen Namen, der sie bei Ein- und
+Ausgabeoperationen identifiziert. 
+Es gibt aber auch Atome, die keinen Namen haben und stattdessen durch ihre Werte
+repräsentiert werden. Momentan sind das Ganzzahlen und Zeichenketten (TEXTe);
+auch die booleschen Werte kann man in einem weiteren Sinn dazurechnen. 
+ 
+ 
+ 
+ 
+3.5.1 Ganzzahlen 
+ 
+ 
+ 
+Im EUMEL-LISP gibt es Funktionen, die Basisoperationen und Tests durchführen. 
+ 
+Ganzzahlen haben folgende Eigenschaften: 
+ 
+1. Eine Ganzzahl besteht aus einem optionalen Vorzeichen und einer Folge von
+   Ziffern; zwischen Vorzeichen und Ziffern können Leerzeichen stehen. 
+2. Der Wert einer Ganzzahl liegt zwischen -32768 und 32767 (minint und maxint). 
+3. Eine Ganzzahl kann überall dort stehen, wo ein Atom stehen kann, außer als
+   Parameter. 
+4. Ganzzahlen sind Konstanten; sie brauchen also nicht gequotet werden. 
+#page# 
+ 
+3.5.2 Arithmetische Funktionen und Prädikate 
+ 
+ 
+ 
+Es folgt eine Liste aller arithmetischen Funktionen. 
+Wenn ein Argument einer dieser Zahlen keine Ganzzahl ist, erfolgt eine Fehlermel­
+dung. 
+ 
+  (sum x1 ... xn)        liefert die Summe der xi; wenn keine Argumente gege­
+                         ben werden, wird 0 geliefert. 
+  (difference x y)       liefert die Differenz von x und y. 
+  (product x1 ... xn)    liefert das Produkt seiner Argumente; wenn 
+                         keine Argumente gegeben werden, wird 1 
+                         geliefert. 
+  (quotient x y)         liefert den Quotienten von x und y, ohne den 
+                         Rest zu berücksichtigen. 
+  (remainder x y)        liefert den Rest der Division von  x und y. 
+  (getint)               liest eine Zahl vom Bildschirm ein und 
+                         liefert sie. 
+  (putint x)             gibt x auf den Bildschirm aus. Identitäts funktion. 
+ 
+ 
+ 
+ 
+ 
+3.5.3 Zeichenkettenverarbeitung 
+ 
+ 
+ 
+Im Moment ist nur Zeichenketten-Ein- und Ausgabe implementiert. 
+Die Ausgabe löst bei Argumenten, die keine Zeichenketten sind, eine Fehlermeldung
+aus. 
+ 
+  (gettext)    liest eine Zeichenkette ein und liefert sie. 
+  (puttext x)  gibt eine Zeichenkette aus. 
+ 
+ 
+ 
+ 
+3.5.4 Test auf Gleichheit 
+ 
+ 
+ 
+  (equal x y)  testet, ob x und y vom gleichen Typ sind, und wenn ja, ob sie gleich
+               sind. 
+#page# 
+ 
+3.6 Aufruf von EUMEL aus #goalpage("p3.6")# 
+ 
+ 
+Bevor man den LISP-Interpreter benutzen kann, muß er folgendermaßen implemen­
+tiert werden: 
+ 
+archive ("lisp") 
+fetch all (archive) 
+release (archive) 
+check off 
+insert ("lisp.1") 
+insert ("lisp.2") 
+insert ("lisp.3") 
+insert ("lisp.4") 
+check on 
+ 
+ 
+Das LISP-System verfügt über einen Heap, in dem alle LISP-Ausdrücke gespei­
+chert sind. Standardmäßig enthält der Heap eine Reihe von Funktionen, die nicht in
+den LISP-Programmen definiert werden müssen (Übersichten über die Standardfunk­
+tionen siehe Kapitel 3.5). 
+ 
+Mit 
+        lisp 
+ 
+wird das LISP-System im EUMEL-Dialog gestartet. In einem Eingabefenster wird
+mit Hilfe des Paralleleditors eine LISP-EINGABE-Möglichkeit angeboten. Die Aus­
+gabe erfolgt in dem LISP-AUSGABE-Fenster. 
+Das LISP-System kann folgendermaßen verlassen werden: 
+<ESC> <ESC> break lisp <RETURN>. 
+ 
+Statt dieser direkten Art der Benutzung der LISP-Maschine ist auch eine an ELAN
+angelehnte Art mit den Prozeduren "run lisp", insert lisp" usw. vorgesehen: 
+ 
+Mit 
+ 
+        run lisp (TEXT CONST dateiname) 
+ 
+wird eine Kopie des Heaps angelegt, das Programm aus der Datei "dateiname" in die
+Kopie eingelesen und gestartet. Durch diesen Kopiermechanismus wird der Original­
+heap vor Zusammenbrüchen des LISP-Systems geschützt. 
+ 
+        insert lisp (TEXT CONST dateiname) 
+ 
+bewirkt dasselbe wie "run lisp"; allerdings wird jetzt direkt auf dem Originalheap
+gearbeitet. Dadurch sind alle Änderungen im Heap, die das Programm verursacht
+(meist Definition von Funktionen durch DEFINE) bleibend, aber auch ein Zusammen­
+bruch ist insoweit endgültig, als das LISP-System jetzt neu gestartet werden muß.
+Das geschieht mit 
+ 
+        start lisp system (DATASPACE CONST dsname) 
+ 
+"dsname" gibt dabei den Datenraum an, der die zum Hochfahren notwendigen Daten
+enthält. Solche Daten im richtigen Format enthält der Datenraum "lisp.bootstrap". 
+Wenn der zuletzt benutzte Heap mit nicht mehr durch LISP-Programme erreich­
+bare Strukturen vollgestopft ist, schafft die Prozedur 
+ 
+        collect lisp heap garbage 
+ 
+Abhilfe; mit 
+ 
+        lisp storage info 
+ 
+kann man den Erfolg kontrollieren. 
+#page# 
+ 
+4. Detailbeschreibungen#goalpage("p4")# 
+ 
+ 
+ 
+ 
+ 
+4.1 Grundfunktionen #goalpage("p4.1")# 
+ 
+ 
+ 
+Die Datei "lisp.1" enthält ein Paket, das die Grundlage des LISP-Systems bildet. Es
+implementiert 
+ 
+ -  die primitiven LISP-Funktionen wie "cons", "null", etc., 
+ -  die Verwaltung des Heaps, in dem die LISP-Strukturen und die Objektliste
+    (Oblist) gespeichert sind, 
+ -  einen Datentyp SYM, dessen Wertevorrat aus Zeigern auf die im Heap gespei­
+    cherten Strukturen besteht, 
+ -  Funktionen zur Konversion allgemeiner Daten in LISP-Strukturen (bisher reali­
+    siert: TEXT <--> SYM und INT <--> SYM). 
+ 
+Durch die Implementation der Basisoperationen als exportierte und damit allgemein
+verfügbare ELAN-Prozeduren ist es möglich, LISP-Strukturen durch ELAN-Prog­
+ramme zu manipulieren; insbesonders können ELAN- und LISP-Programme über
+diese Strukturen miteinander kommunizieren. 
+ 
+Anmerkung: 
+Wenn Eigenschaften von "SYM"-Objekten beschrieben werden, sind immer die
+Eigenschaften der Strukturen gemeint, auf die die Objekte zeigen, wenn nichts ande­
+res angegeben wird. 
+ 
+ 
+Es werden folgende Prozeduren exportiert: 
+ 
+  PROC initialize lisp system (DATASPACE CONST new heap): 
+    "new heap" ist der neue Datenraum, in dem der LISP-Heap ab sofort geführt
+    wird. 
+    Vorsicht: Beim Wechsel zu einem neuen Datenraum sind die Werte der
+    SYM-Variablen, die auf Strukturen im alten Heap zeigen, natürlich wertlos! 
+ 
+  PROC dump lisp heap (FILE VAR f): 
+    In "f" wird ein Dump des Heaps erstellt. Dieser Dump ist nur mit Kenntnis des
+    Programmtextes aus "lisp 1" verständlich; er wird hier nicht beschrieben. 
+ 
+  PROC lisp storage (INT VAR size, used): 
+    Nach dem Aufruf gibt "size" die maximal verfügbare Anzahl von Knoten an,
+    während "used" die Anzahl der tatsächlich von LISP-Strukturen belegten
+    Knoten enthält. Zu diesen Strukturen können auch solche zählen, die nicht mehr
+    durch "head" oder "tail" etc. erreichbar sind. 
+ 
+  PROC collect lisp heap garbage: 
+    Löscht die im LISP-Heap nicht mehr durch "atom (TEXT CONST)", "proper­
+    ty", "head" und "tail" erreichbaren Strukturen. Es werden auch alle nur von
+    ELAN-Programmen aus über SYM-Variable erreichbare Strukturen gelöscht, so
+    daß die Werte dieser Variablen undefiniert werden. 
+    Die Müllabfuhr wird von keiner Prozedur dieses Pakets aufgerufen, d.h. der
+    Benutzer, der ELAN-Programme einsetzt, braucht nicht alle Strukturen in den
+    Eigenschaftslisten von Atomen aufzubauen, um sie vor einer versehentlichen
+    Löschung durch die Müllabfuhr zu schützen, vorausgesetzt, er ruft sie nicht
+    selbst auf. Er muß allerdings darauf achten, daß im Heap noch genug Platz
+    bleibt. 
+ 
+  OP := (SYM VAR left, SYM CONST right): 
+    Nach der Zuweisung zeigt "left" auf die gleiche Struktur wie vorher "right". 
+ 
+  SYM CONST nil, pname; 
+    Zwei Konstanten, die dem LISP-System ständig zur Verfügung stehen müs­
+    sen. Ihre Drucknamen sind "NIL" bzw. "PNAME" (vgl. Schlußbemerkungen) 
+ 
+  SYM PROC head (SYM CONST sym): 
+    Entspricht der im Handbuch beschriebenen Funktion "head". 
+ 
+  SYM PROC tail (SYM CONST sym): 
+    Entspricht der im Handbuch beschriebenen Funktion "tail". 
+ 
+  SYM PROC cons (SYM CONST head, tail): 
+    Liefert einen SYM-Wert "zeiger" auf eine neue Struktur. Es gilt: 
+    head ("zeiger") = "head" und tail ("zeiger") = "tail". 
+ 
+  BOOL PROC eq (SYM CONST sym 1, sym 2): 
+    Prüft, ob "sym 1" und "sym 2" auf dieselbe Struktur zeigen. Das ist genau dann
+    der Fall, wenn sie durch Zuweisung auseinander hervorgegangen sind oder wenn
+    sie auf das gleiche benannte Atom zeigen. 
+ 
+  BOOL PROC equal (SYM CONST sym 1, sym 2): 
+    Prüft, ob "sym 1" und "sym 2" dieselbe Struktur haben; "dieselbe Struktur"
+    braucht aber nicht "Identität" zu bedeuten, wie "eq" das verlangt. 
+    Umgewandelte TEXTe und INTs werden richtig verglichen (siehe "sym (INT
+    CONST)" und "sym (TEXT CONST)"). 
+ 
+  BOOL PROC null (SYM CONST sym): 
+    Prüft, ob "sym" gleich der Konstanten "NIL" ist (entspricht 
+    eq ("sym", "NIL"), ist aber schneller). 
+ 
+  BOOL PROC atom (SYM CONST sym): 
+    Prüft, ob "sym" ein ( benanntes oder unbenanntes) Atom ist. 
+ 
+  BOOL PROC is named atom (SYM CONST sym): 
+    Prüft, ob "sym" ein benanntes Atom ist. 
+ 
+  PROC begin oblist dump: 
+    Vorbereitung für "next atom". 
+ 
+  SYM PROC next atom: 
+    Liefert das nächste Atom aus der Objektliste. In der Objektliste sind alle benann­
+    ten Atome, die der Heap enthält, aufgeführt (bis auf Ausnahmen; s."delete
+    atom"). "NIL" wird immer als letzte Atom geliefert. 
+ 
+  SYM PROC atom (TEXT CONST name): 
+    Liefert einen Zeiger auf das Atom mit dem Namen "name". Wenn kein solches
+    Atom in der Objektliste vorhanden ist, wird "NIL" geliefert. 
+ 
+  SYM PROC new atom (TEXT CONST name): 
+    Liefert einen Zeiger auf das Atom mit dem Namen "name". Wenn kein solches
+    Atom in der Objektliste vorhanden ist, wird ein neues mit diesem Namen in sie
+    eingefügt. 
+ 
+  PROC create atom (TEXT CONST name): 
+    Fügt ein Atom mit dem Namen "name" in die Objektliste ein. Wenn ein solches
+    Atom bereits existiert, wird stattdessen eine Fehlermeldung ausgegeben. 
+ 
+  PROC delete atom (SYM CONST atom): 
+    Streicht das Atom "atom" aus der Objektliste. 
+ 
+  PROC begin property list dump (SYM CONST atom): 
+    Vorbereitung für "next property". 
+ 
+  PROC next property (SYM VAR property id, property): 
+    Liefert die nächste Eigenschaft aus der Eigenschaftsliste des zuletzt durch
+    "begin property list dump" vorbereiteten Atoms. Wenn es sich bei der Eigen­
+    schaft um eine Flagge handelt, wird "property" auf "NIL" gesetzt; wenn es keine
+    nächste Eigenschaft mehr gibt, werden "property" und "property id" auf "NIL"
+    gesetzt. 
+    Der Dump der Eigenschaftsliste beeinträchtigt die "Verwendbarkeit" des Atoms in
+    keiner Weise; es ist während des Dumps sogar möglich, Eigenschaften und
+    Flaggen zu lesen. Wenn während des Dumps Eigenschaften oder Flaggen geän­
+    dert oder geschrieben werden, ist mit fehlerhaften Dumpergebnissen zu rechnen. 
+ 
+  PROC add property (SYM CONST atom, property id, property): 
+    "property id" muß ein benanntes Atom sein. Führt eine neue Eigenschaft mit der
+    Bezeichnung "property id" und dem Wert "property" ein. Wenn bereits eine
+    Eigenschaft mit der gleichen Bezeichnung existiert, wird die alte Version über­
+    deckt, ist aber weiter vorhanden. 
+ 
+  PROC alter property (SYM CONST atom, property id, property): 
+    Bringt die Eigenschaft mit der Bezeichnung "property id" auf den neuen Wert
+    "property". Wenn eine Eigenschaft mit dieser Bezeichnung noch nicht existiert,
+    wird eine Fehlermeldung ausgegeben. 
+ 
+  BOOL PROC property exists (SYM CONST atom, property id): 
+    Prüft, ob das Atom eine Eigenschaft mit der Bezeichnung "property id" besitzt. 
+ 
+  SYM PROC property (SYM CONST atom, property id): 
+    Liefert den Wert der gerade sichtbaren Eigenschaft des Atoms, die die Bezeich­
+    nung "property id" hat. Falls die Eigenschaft nicht existiert, wird "NIL" geliefert. 
+ 
+  PROC delete property (SYM CONST atom, property id): 
+    Löscht den gerade sichtbaren Wert der Eigenschaft des Atoms, die die Bezeich­
+    nung "property id" hat. Wenn eine ältere Version dieser Eigenschaft durch "add
+    property" überdeckt wurde, wird diese jetzt wieder sichtbar. Jede Eigenschaft
+    bildet also für jedes Atom einen Stapel (Stack). 
+ 
+  PROC add flag (SYM CONST atom, flag id): 
+    Das Atom "atom" erhält die Flagge "flag id". Ein Atom kann dieselbe Flagge
+    durchaus mehrmals haben. 
+ 
+  BOOL PROC flag (SYM CONST atom, flag id): 
+    Prüft, ob "atom" mindestens eine Flagge "flag id" hat. 
+ 
+  PROC delete flag (SYM CONST atom, flag id): 
+    Löscht eine Flagge "flag id" von "atom". Wenn keine Flagge existiert, wird
+    nichts getan. 
+ 
+  SYM PROC sym (TEXT CONST text): 
+    Konvertiert "text" in ein unbenanntes Atom und liefert einen Zeiger auf dies
+    Atom. 
+ 
+  TEXT PROC text (SYM CONST sym): 
+    Konvertiert "sym" in einen TEXT zurück, wenn es sich um einen konvertierten
+    TEXT handelt; wenn nicht, wird eine Fehlermeldung ausgegeben. 
+ 
+  BOOL PROC is text (SYM CONST sym): 
+    Prüft, ob "sym" ein konvertierter TEXT ist. 
+ 
+  SYM PROC sym character (TEXT CONST text): 
+    "text" muß genau ein Zeichen enthalten. Das Zeichen wird in ein
+    CHARACTER-Objekt im Heap konvertiert und ein Zeiger auf dies Objekt gelie­
+    fert. 
+ 
+  INT PROC character (SYM CONST sym): 
+    "sym" muß auf ein CHARACTER-Objekt zeigen. Geliefert wird der Code des
+    dort gespeicherten Zeichens. 
+ 
+  SYM PROC sym (INT CONST i 1, i 2): 
+    Konvertiert "i 1" und "i 2" in ein unbenanntes Atom und liefert einen Zeiger
+    darauf. 
+ 
+  INT PROC int 1 (SYM CONST sym): 
+  INT PROC int 2 (SYM CONST sym): 
+    Holt die Werte der ersten bzw. zweiten Ganzzahl aus "sym", wenn es sich um
+    ein konvertiertes INT-Paar handelt; wenn nicht, wird eine Fehlermeldung ausge­
+    geben. 
+ 
+  BOOL PROC is int pair (SYM CONST sym): 
+    Prüft, ob "sym" ein konvertiertes INT-Paar ist. 
+ 
+ 
+Prozedurübergreifende Aussagen über das Paket "lisp.1": 
+ 
+ -  Es gibt benannte und unbenannte Atome. 
+ 
+ -  Die unbenannten Atome sind Konversionsprodukte. 
+ 
+ -  Vor dem ersten Aufruf von "delete atom" sind alle benannten Atome in der Ob­
+    jektliste enthalten; d.h. sie können alle durch "begin oblist dump" und wiederhol­
+    ten Aufruf von "next atom" erreicht werden. 
+ 
+ -  Jedes benannte Atom hat genau einen Namen, der immer gleich bleibt. Der
+    Name ist als Eigenschaft mit der Bezeichnung "pname" in der Eigenschaftsliste
+    gespeichert. "add property", "alter property" und "delete property" geben des­
+    halb eine Fehlermeldung aus, statt ihre normalen Aktionen durchzuführen, wenn
+    ihnen als Eigenschaftsbezeichnung "pname" übergeben wird. 
+ 
+ -  Es gibt keine zwei Atome, die denselben Namen haben; dadurch reduziert sich
+    die bei "eq" angegebene Fallunterscheidung auf einen Fall. 
+ 
+ -  Es kann durchaus zwei unbenannte Atome mit gleichen Werten geben, die von
+    "eq" nicht als gleich anerkannt werden, weil sie in verschiedenen Strukturen
+    gespeichert sind. "equal" achtet nicht auf die Position, sondern auf die Werte
+    der zu vergleichenden Strukturen. 
+ 
+ -  Mehrfache Zugriffe auf die gleiche Eigenschaft desselben Atoms werden so opti­
+    miert, daß die Eigenschaftsliste nur beim ersten Zugriff (meist durch "property
+    exists") durchsucht werden muß. 
+ 
+ 
+ 
+#page# 
+ 
+4.2  Weitere Funktionen sowie Eingabe und 
+     Ausgabe #goalpage("p4.2")# 
+ 
+ 
+ 
+Die Datei "lisp.2" enthält diverse Pakete, die die Verbindung vom LISP-System zur
+normalen EUMEL-Umgebung bilden. Momentan sind das Ein- und Ausgabe und
+(exemplarisch) die fünf Grundrechenarten für Ganzzahlen. 
+ 
+Die Ein- und Ausgabe von LISP-Strukturen wird durch das Paket namens "lisp io"
+mit den folgenden Prozeduren ermöglicht: 
+ 
+  PROC get (FILE VAR f, SYM VAR sym): 
+    Nach dem Aufruf zeigt "sym" auf eine neue aus "f" eingelesene Struktur. 
+    In der ersten und hinter der letzten Zeile des S-Ausdrucks dürfen keine weiteren
+    Daten stehen. 
+ 
+  PROC get all (FILE VAR f, SYM VAR sym): 
+    Wie "get (FILE V, SYM V)", nur daß die Datei nichts als den S-Ausdruck ent­
+    halten darf. 
+ 
+  PROC get (SYM VAR sym): 
+    Es wird mit "get all" ein S-Audruck von einer Scratch-Datei eingelesen, die
+    dem Benutzer vorher zum Editieren angeboten wird. Bei Einlesefehlern wird die
+    Datei zu Korrigieren angeboten, bis keine Fehler mehr auftreten. 
+ 
+  PROC put (FILE VAR f, SYM CONST sym): 
+    Wenn "sym" ein Ganzzahlpaar ist, wird die erste Zahl ausgegeben; wenn es ein
+    konvertierter TEXT ist, wird der ursprüngliche TEXT wieder ausgegeben; bei
+    einem benannten Atom oder einer allgemeinen LISP-Struktur wird ein S-Aus­
+    druck ausgegeben. 
+ 
+  PROC put (SYM CONST sym): 
+    Wie "put (FILE V, SYM CONST), außer daß die Augabe direkt auf den Bildschirm
+    erfolgt. 
+ 
+ 
+Das Paket "lisp int" enthält die Prozeduren 
+ 
+  SYM PROC sum (SYM CONST summandenliste); 
+    Erwartet eine Liste von "int pair"-Summanden und liefert deren Summe. 
+ 
+  SYM PROC difference (SYM CONST minuend, subtrahend): 
+    Liefert die Differenz der Parameter. 
+ 
+  SYM PROC product (SYM CONST faktorenliste): 
+    Liefert das Produkt der Listenelemente. 
+ 
+  SYM PROC quotient (SYM CONST dividend, divisor): 
+    Liefert den Quotienten der Parameter. 
+ 
+  SYM PROC remainder (SYM CONST dividend, divisor): 
+    Liefert den Rest. 
+ 
+#page# 
+ 
+4.3 Interpreter #goalpage("p4.3")#  
+ 
+ 
+Die Datei "lisp.3" enthält das Paket "lisp interpreter", das die Prozedur 
+ 
+        SYM PROC evalquote (SYM CONST expression) 
+ 
+exportiert. Es handelt sich dabei um den im EUMEL-LISP-Handbuch beschriebe­
+nen Interpreter. 
+ 
+Wenn "expression" ein LISP-Ausdruck ist, liefert die Prozedur den Wert des Aus­
+drucks (vorausgesetzt, der LISP-Heap ist vorbereitet, siehe lisp.1). 
+ 
+Wirkungsweise: 
+"evalquote" ruft im Wesentlichen die Prozedur "eval" auf. 
+"eval" erwartet als Argumente einen solchen LISP-Ausdruck wie "evalquote", benö­
+tigt aber zusätzlich eine sog. Bindeliste. In einer Bindeliste sind durch LAMBDA- und
+LABEL-Ausdrücke bereits gebundene Variable und ihre Werte gespeichert. Die
+Manipulation der Bindeliste ist durch eine Reihe von Refinements, die am Schluß des
+Pakets stehen, realisiert. 
+ 
+Da bisher noch keine LAMBDA- oder LABEL-Ausdrücke verarbeitet wurden, über­
+gibt "evalquote" die leere Bindeliste. 
+ 
+Wirkungsweise von 
+ 
+        SYM PROC eval (SYM CONST expression, association list): 
+ 
+"eval" kann als erstes Argument ein Atom oder eine zusammengesetzte Struktur
+erhalten. 
+ 
+Atome werden als Variable aufgefaßt, deren Wert in der Bindeliste aufzusuchen ist.
+Vor der Konsultation der Bindeliste wird allerdings noch nach der Eigenschaft APVAL
+des Atoms gesehen; wenn sie vorhanden ist, handelt es sich um eine Konstante wie
+NIL, T oder F, die einen festen Wert hat, nämlich den Wert dieser Eigenschaft. Da
+diese Konstanten sich selbst als Wert haben, gilt "eval (NIL, Bindeliste) = NIL"
+(entsprechend für "T" und "F"). 
+ 
+Wenn das erste Arugment von "eval" zusammengesetzt ist, wird angenommen, daß
+es sich um einen Funktionsaufruf der Form 
+ 
+ 
+  +-----+-----+ 
+  |  o  |  o--+--> Argumentliste 
+  +--+--+-----+ 
+     | 
+     V 
+    Funktion 
+ 
+ 
+handelt. Die Bestandteile "Funktion" und "Argumentliste" werden mit der Bindeliste
+übergeben an: 
+ 
+  SYM PROC apply (SYM CONST function, arguments, association list): 
+ 
+"apply" hat die Aufgabe, die Argumente durch "eval" berechnen zu lassen (das
+unterbleibt allerdings unter bestimmten Umständen) und die Berechnungergebnisse an
+die Parameter der Funktion zu binden; zum Schluß muß der Wert des Funktions­
+rumpfs in Abhängigkeit von diesen neuen Bindungen als Ergebnis der gesamten
+Prozedur "apply" berechnet werden; diese Berechnung geschieht wieder durch
+"eval". 
+ 
+Nur in einem LAMBDA-Ausdruck ist direkt bekannt, wo die Parameterliste steht.So­
+lange das nicht der Fall ist, muß entweder ein LABEL-Ausdruck oder ein Atom
+vorliegen. 
+Ein LABEL-Ausdruck hat die Form 
+ 
+ 
+  +-----+-----+    +-----+-----+    +-----+-----+ 
+  |  o  |  o--+--->|  o  |  o--+--->|  o  | NIL | 
+  +--+--+-----+    +--+--+-----+    +--+--+-----+ 
+     |                |                | 
+     V                V                V 
+   LABEL             Name           Funktion 
+ 
+ 
+Da der Name für die Dauer der Auswertung des Funktionsrumpfs an die Funktion
+gebunden sein muß, wird dis Paar als funktionaler Bindelisteneintrag gespeichert.
+Funktionale und nichtfunktionale Bindelisteneinträge sind eindeutig unterschieden. 
+ 
+Nach dem Abspeichern wird wieder getestet, ob die Funktion diesmal ein
+LAMBDA-Ausdruck ist; wenn nicht, wird ein weiterer Schritt zum "Ablättern" von
+LABELs und Atomen versucht, usw. 
+ 
+Wenn die Funktion ein Atom ist, werden analog zu den Vorgängen in "eval" erst die
+Eigenschaftsliste und dann die Bindeliste durchsucht. 
+ 
+Ist die Eigenschaft FUNCTION in der Eigenschaftsliste vorhanden, ist der Wert der
+Eigenschaft die (evtl. weiter "abzublätternde") Funktion; ist die Eigenschaft nicht
+vorhanden, muß das Atom an eine Funktion gebunden sein, die dann aus der Binde­
+liste geholt werden kann. 
+ 
+Da alle Funktionen (auch die Standardfunktionen) letztendlich als LAMBDA-Aus­
+drücke definiert sind, kommt "apply" auf diese Weise zuletzt zu einem LAMBDA-
+Ausdruck. 
+ 
+Ein LAMBDA-Ausdruck hat die Form 
+ 
+ 
+  +-----+-----+    +-----+-----+    +-----+-----+ 
+  |  o  |  o--+--->|  o  |  o--+--->|     |     | 
+  +--+--+-----+    +--+--+-----+    +-----+-----+ 
+     |                | 
+     V                V 
+   LAMBDA          Parameterliste 
+ 
+ 
+Als nächster Schritt werden die Argumente für die zu berechnende Funktion an die
+Parameter der Parameterliste gebunden, d.h. es werden Parameter-Argument-Paare
+in die Bindeliste eingetragen. 
+ 
+Die Methode des Eintrags ist je nach Art des Parameters unterschiedlich. Es gibt die
+folgenden Arten von Parametern: 
+ 
+ 
+  1.       | 
+           | 
+           V 
+          Name 
+ 
+ 
+     "Name" ist hier - wie bei den restlichen Fällen - der Name des Parame­
+     ters. Diese Art von Parametern ist der Normalfall; die Argumente, die einem
+     solchen Parameter entsprechen, werden durch "eval" berechnet und zusammen
+     mit dem Parameter in einem Bindelisteneintrag gespeichert. 
+ 
+ 
+  2.       | 
+           | 
+           V 
+        +-----+-----+    +-----+-----+ 
+        |  o  |  o--+--->|  o  | NIL + 
+        +--+--+-----+    +--+--+-----+ 
+           |                | 
+           V                V 
+         QUOTE             Name 
+ 
+ 
+     In diesem Fall wird das Argument ohne weitere Verarbeitung in die Bindeliste
+     übernommen. Die Wirkung ist die gleiche, als wäre das Argument durch
+     "(QUOTE ... )" eingeschlossen. 
+ 
+ 
+  3.       | 
+           | 
+           V 
+        +-----+-----+    +-----+-----+ 
+        |  o  |  o--+--->|  o  | NIL | 
+        +--+--+-----+    +--+--+-----+ 
+           |                | 
+           V                V 
+        FUNCTION           Name 
+ 
+ 
+     Hier wird ein funktionaler Bindelisteneintrag erzeugt, so daß "Name" im Funk­
+     tionsrumpf als Name einer Funktion auftreten kann. 
+ 
+ 
+  4.       | 
+           | 
+           V 
+        +-----+-----+    +-----+-----+ 
+        |  o  |  o--+--->|  o  | NIL | 
+        +--+--+-----+    +--+--+-----+ 
+           |                | 
+           V                V 
+        INDEFINITE         Name 
+ 
+ 
+     Dies ist ein Parameter, der beliebig viele berechnete Argumente aufnehmen
+     kann. Der Einfachheit halber werden die Ergebnisse zu einer Liste zusammen­
+     gefaßt und mit "Name" in einen Bindelisteneintrag gesteckt. 
+ 
+ 
+  5.       | 
+           | 
+           V 
+        +-----+-----+    +-----+-----+    +-----+-----+ 
+        |  o  |  o--+--->|  o  |  o--+--->|  o  | NIL | 
+        +--+--+-----+    +--+--+-----+    +--+--+-----+ 
+           |                |                | 
+           V                V                V 
+        INDEFINITE        QUOTE             Name 
+ 
+ 
+     Dieser Parameter kann wie der in Fall 4. aufgeführte beliebig viele Argumente
+     aufnehmen, die zu einer Liste zusammengefaßt werden. Im Gegensatz zu 4.
+     wird aber wie bei 2. nichts durch "eval" berechnet, sondern die Argumente so
+     wie sie vorkommen übernommen. 
+ 
+Auf einen Parameter der Form 4. oder 5. darf kein weiterer Parameter folgen, weil
+solch ein Parameter alle restlichen Argumente verbraucht. Solchen Parametern darf -
+als Ausnahme - auch kein Argument entsprechen; dann werden sie an die leere
+Liste (d.h. NIL) gebunden. 
+ 
+Der letzte Kasten in der Beschreibung des LAMBDA-Ausdrucks ist mit Absicht leer
+geblieben; er kann eine der Formen 
+ 
+ 
+  +-----+-----+               +----------+----------+ 
+  |  o  | NIL |      oder     | Ganzzahl | XXXXXXXX | 
+  +--+--+-----+               +----------+----------+ 
+     | 
+     V 
+   Funktionsrumpf 
+ 
+ 
+annehmen. 
+ 
+Die erste Form heißt, daß die Funktion durch Berechnung des Funktionsrumpfs mittels
+"eval" berechnet werden soll; die zweite Form bewirkt den Aufruf einer der Standard­
+funktionen, je nachdem, welche Funktionsnummer bei "Ganzzahl" steht. In diesem
+zweiten Fall werden die Argumente aber nicht durch den Namen des Parameters
+identifiziert, sondern durch die Position des Eintrags in der Bindeliste. Dieser Pro­
+grammteil hängt also wesentlich von der Reihenfolge ab, in der die Bindelisteneinträ­
+ge, die bei der Parameter-Argument-Zuordnung entstehen, in die Bindeliste einge­
+fügt werden. Zur Zeit ist das die Umkehrung der Reihenfolge der Parameter. 
+ 
+Die Namen der Refinements "arg 1", "arg 2", "arg 3" beziehen sich auch nicht auf
+die Position des Arguments in der Argumentsliste, sondern auf die Position des
+Eintrags in der Bindeliste. 
+ 
+#page# 
+ 
+4.4 Kommandoprozeduren #goalpage("p4.4")# 
+ 
+ 
+ 
+Die Datei "lisp.4" enthält eine Reihe von Prozeduren, mit denen der LISP-Interpre­
+ter ähnlich wie der ELAN-Compiler aufgerufen werden kann. 
+ 
+Die Prozedur 
+ 
+        start lisp system 
+ 
+ermöglicht das erneute Starten des LISP-Systems, oder wenn "übersetzte" Pro­
+gramme, die in einem Heap einer anderen Task liegen, in dieser Task verarbeitet
+werden sollen. 
+ 
+Die Prozedur 
+ 
+        lisp 
+ 
+stellt die LISP-Maschine in einem Doppelfenster im Bildschirmdialog zur Verfügung.
+Bei der erstmaligen Benutzung muß die Datei "lisp.bootstrap" vorhanden sein. 
+ 
+Die Prozedur 
+ 
+        break lisp 
+ 
+koppelt die LISP-Task vom Benutzer-Terminal ab und baut das Doppelfenster für
+den Bildschirmdialog neu auf. 
+ 
+ 
+Die Prozedur 
+ 
+        run lisp 
+ 
+bewirkt, daß ein LISP-Programm eingelesen und ausgeführt wird; nach der Ausfüh­
+rung wird das Ergebnis der Berechnung ausgegeben. Diese Operationen werden auf
+einer Kopie des Heaps ausgeführt, so daß Änderungen keine Dauerwirkung haben.
+Mit 
+ 
+        run lisp again 
+ 
+wird das zuletzt eingelesene Programm noch einmal gestartet; da dafür die gleiche
+Kopie des Heaps wie bei "run" benutzt wird, kann das Ergebnis diesmal anders sein. 
+ 
+        insert lisp 
+ 
+wirkt wie "run lisp", außer daß diesmal alle Änderungen, die durch das Einlesen und
+Ausführen im Heap entstehen, dauerhaft sind. 
+ 
+ 
+  PROC start lisp system (DATASPACE CONST heap): 
+    Eine Kopie von "heap" wird der neue LISP-Heap. Wenn es sich um "nilspa­
+    ce" handelt, werden einige organisatorische Strukturen im Heap aufgebaut und
+    die Atome "NIL" und "PNAME" erzeugt. 
+ 
+  PROC start lisp system (DATASPACE CONST heap, FILE VAR f): 
+    Zunächst wird "start lisp system (heap)" gegeben. 
+    Danach werden die Eigenschaftsbeschreibungen aus "f" in Strukturen im Heap
+    umgesetzt. 
+ 
+    Jede Beschreibung in "f" muß mit dem Zeilenanfang beginnen und kann sich
+    über mehrere Zeilen erstrecken. Jede Beschreibung besteht aus den Elementen 
+      <Atom> <Eigenschaft> <Wert> 
+    wobei <Eigenschaft> der Name einer Eigenschaft (i.a. APVAL oder FUNCTION)
+    und <Wert> ein beliebiger S-Ausdruck sein müssen. Die drei Elemente müs­
+    sen jeweils durch mindestens ein Leerzeichen getrennt sein. 
+ 
+    Wenn das Atom <Atom> nicht existiert, wird es erzeugt; danach wird <Wert>
+    unter <Eigenschaft> in der Eigenschaftsliste eingetragen. 
+ 
+    Wenn <Eigenschaft> NIL ist, muß <Wert> wegfallen; dann wird nichts in die
+    Eigenschaftsliste eingetragen. 
+ 
+  DATASPACE PROC lisp heap: 
+    Liefert den LISP-Heap. Das ist manchmal für Sicherheitskopien etc. nützlich.
+    Die durch "run lisp" erzeugten Kopien sind nicht zugänglich. 
+ 
+  PROC run lisp: 
+    Ruft "run lisp (last param)" auf. 
+ 
+  PROC run lisp (TEXT CONST file name): 
+    Das in der Datei "file name" stehende LISP-Programm (d.h. der dort stehende
+    in einen S-Ausdruck übersetzte M-Ausdruck) wird in eine neue Kopie des
+    LISP-Heaps eingelesen und ausgeführt. Evtl. vorher durch "run lisp" erzeugte
+    Kopien des Heaps werden vorher gelöscht. 
+ 
+    Wenn das Programm syntaktisch nicht korrekt ist, wird es im Paralleleditor zur
+    Korrektur angeboten. 
+ 
+  PROC run lisp again: 
+    Führt das zuletzt eingelesene Programm noch einmal im gleichen Heap aus. 
+ 
+  PROC insert lisp: 
+    Ruft "insert lisp (last param)" auf. 
+ 
+  PROC insert lisp (TEXT CONST file name): 
+    Wirkt wie "run lisp (file name)", nur daß alle Operationen auf dem Originalheap
+    ausgeführt werden. Auch "run lisp again" wirkt nun nicht mehr auf der Kopie. 
+
diff --git a/doc/menugenerator/menu-generator handbuch.1 b/doc/menugenerator/menu-generator handbuch.1
new file mode 100644
index 0000000..c190c0a
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.1	
@@ -0,0 +1,100 @@
+#type ("prop.lq")##limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (3)# 
+#headodd# 
+#center#ls-Menu-Generator#right#% 
+ 
+#end# 
+#headeven# 
+%#center#ls-Menu-Generator 
+ 
+#end# 
+#type ("prop.breit.lq")# 
+#center#1 
+ 
+#center#Was 
+#center#kann 
+#center#ls-Menu-Generator 
+#type ("prop.lq")# 
+ 
+ 
+   In diesem Kapitel wollen wir Ihnen erläutern, was Sie
+mit #on("b")#ls-Menu-Generator#off("b")# anfangen können. Wir gehen davon
+aus, daß Ihnen die Benutzerschnittstelle #on("b")#ls-DIALOG#off("b")# be­
+kannt ist und daß Sie bereits mit einigen Anwendungen
+unter #on("b")#ls-DIALOG#off("b")# gearbeitet haben. Weiterhin setzen wir
+voraus, daß Sie Programmierkenntnisse (EUMEL/ELAN) be­
+sitzen. 
+   Bisher war es Ihnen nur möglich, von uns fertigge­
+stellte Programme unter der komfortablen Benutzer­
+schnittstelle #on("b")#ls-DIALOG#off("b")# laufen zu lassen. Sie haben aber
+sicher erkannt, welche Vorteile es bietet, Programme un­
+ter einer einheitlichen Benutzeroberfläche zu realisie­
+ren: 
+   Zunächst profitiert natürlich der Anwender von der
+einfachen und immer einheitlichen Bedienung solcher
+Programme. Der Aufwand, sich in neue Programmsysteme
+einzuarbeiten, wird erheblich reduziert. #on("b")#ls-DIALOG#off("b")# wurde
+ja auch speziell für den Unterricht konzipiert und ent­
+wickelt: Ziel war es, Computerlaien einen Zugang zum
+Computer zu verschaffen und den Umgang mit dem Compu­
+ter zu vereinfachen. 
+ 
+   #on("b")#ls-Menu-Generator#off("b")#ist nun aber kein weiteres Anwen­
+dungsprogramm! #on("b")#ls-Menu-Generator#off("b")# ist stattdessen für
+den Programmierer gedacht, der selbst unter #on("b")#ls-DIALOG#off("b")#
+Anwendungssysteme entwickeln möchte. #on("u")#Wir erhoffen uns
+durch die Bereitstellung dieses Werkzeuges, daß sich auch
+andere engagierte Personen daran beteiligen, qualitativ
+hochwertige Software insbesondere für den Schulbereich
+unter #on("b")#ls-DIALOG#off("b")# zu entwickeln.#off("u")# 
+ 
+   Mit #on("b")#ls-Menu-Generator#off("b")# haben Sie zwei Komponenten
+erworben: Das Generator-Programm zur Erzeugung von
+Menukarten und eine umfangreichen Dokumentation. Dabei
+enthält die Dokumentation nicht nur Informationen dar­
+über, wie Sie mit dem Generator-Programm arbeiten kön­
+nen - das natürlich auch. Darüberhinaus werden Ihnen
+alle Möglichkeiten, die #on("b")#ls-DIALOG#off("b")# zur Programmgestal­
+tung bietet, ausführlich erläutert - das macht den we­
+sentlichen Teil der Dokumentation aus! 
+ 
+   #on("b")#ls-DIALOG#off("b")# ist eigentlich ein "Baukastensystem", auf
+das andere Programme zugreifen können. Sie wissen si­
+cherlich, wieviel Arbeit bei jedem Programm aufzuwen­
+den ist, um die Benutzerschnittstelle zu realisieren. Die
+Gestaltung und Pflege der Benutzerschnittstelle kann
+bis zu 50% der Gesamtarbeit an einem Programm ausmachen.
+#on("b")#ls-Menu-Generator#off("b")# soll Ihnen helfen, diese Arbeit zu
+verringern. 
+ 
+   Alle Informationen, die ein Menu betreffen, sind in
+der sogenannten 'Menukarte' abgelegt. Wird nun ein Pro­
+gramm unter #on("b")#ls-DIALOG#off("b")# aufgerufen, so wird die entspre­
+chende Menukarte aus der "Menukarten - Sammeltask" ('ls-
+MENUKARTEN') geholt und an das System angekoppelt. An­
+schließend wird dem Anwender das Menu auf dem Bildschirm
+angeboten. 
+   Das Erstellen solcher Menukarten ist mit dem Genera­
+torprogramm sehr einfach - es wird in Kapitel 4 beschrie­
+ben. Allerdings sollten Sie nicht die Arbeit unterschät­
+zen, die Sie für eine sorgfältig erstellte, mit allen In­
+formationtexten gefüllte Menukarte aufwenden müssen! 
+ 
+   Bei den meisten Programmmen reicht aber ein einfaches
+Menu nicht aus. Bei vielen Verarbeitungsfunktionen ist
+es notwendig, mit dem Anwender einen Dialog zu führen:
+z.B. muß ein Dateiname erfragt, eine Information ausgege­
+ben und bestätigt, eine Auswahl oder eine Entscheidung
+getroffen werden. Alle Möglichkeiten, die #on("b")#ls-DIALOG#off("b")# dazu
+bereitstellt, sind in Kapitel 5 dokumentiert. 
+ 
+   Einige Reihe von Verarbeitungsfunktionen treten in
+nahezu jeder Anwendung auf (Datei- und Archivhandling).
+Hier stellt #on("b")#ls-DIALOG#off("b")# schon vorgefertigte Module zur
+Verfügung. In Kapitel 6 zeigen wir Ihnen, wie Sie auf die­
+se Module zugreifen und sie in Ihr Programmsystem ein­
+binden können. In Kapitel 7 zeigen wir Ihnen außerdem,
+wie Sie eigene Fenster definieren können und welche Ope­
+rationen auf diesen Fenstern zur Verfügung stehen. 
+
diff --git a/doc/menugenerator/menu-generator handbuch.2 b/doc/menugenerator/menu-generator handbuch.2
new file mode 100644
index 0000000..696ed28
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.2	
@@ -0,0 +1,87 @@
+#type ("prop.lq")##limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (6)# 
+#headodd# 
+#center#ls-Menu-Generator#right#% 
+ 
+#end# 
+#headeven# 
+%#center#ls-Menu-Generator 
+ 
+#end# 
+#type ("prop.breit.lq")# 
+#center#2 
+ 
+#center#Installation 
+#center#von 
+#center#ls-Menu-Generator 
+#type ("prop.lq")# 
+ 
+ 
+   Bevor Sie #on("b")#ls-Menu-Generator#off("b")# auf Ihrem System benut­
+zen können, müssen Sie das Programm zunächst installie­
+ren. Wenn #on("b")#ls-Menu-Generator#off("b")# auf Ihrem System schon zur
+Verfügung steht, können Sie dieses Kapitel ruhig über­
+springen. 
+ 
+ 
+2.1  Voraussetzungen 
+ 
+   Um #on("b")#ls-Menu-Generator#off("b")# auf Ihrem Computer betreiben
+zu können, muß das EUMEL-Betriebssystem (Multi-User-
+Version) installiert und das Programmpaket #on("b")#ls-DIALOG#off("b")#
+(Version 1.1) bereits insertiert sein. 
+ 
+ 
+2.2  Lieferumfang 
+ 
+   #on("b")#ls-Menu-Generator#off("b")# wird auf einer Diskette geliefert,
+die alle notwendigen Programme enthält. Folgende Dateien
+sollten sich auf der Diskette befinden: 
+ 
+         "fonttab.ls-Menu-Generator" 
+         "ls-MENUBASISTEXTE" 
+         "Generatordatei: Archivmenu" 
+         "ls-Menu-Generator 1" 
+         "ls-Menu-Generator 2" 
+         "ls-Menu-Generator/gen" 
+ 
+   Eventuell können noch weitere Namen auf der Diskette
+vorhanden sein. 
+ 
+ 
+2.3  Installation 
+ 
+Die Installation erfolgt in #on("u")#zwei Schritten#off("u")#: 
+ 
+   #on("u")#Zunächst#off("u")# muß die mitgelieferte Fonttabelle
+('fonttab.ls-Menu-Generator') in die Task 'configurator'
+geholt werden. Da Sie aus dem 'UR-Zweig' des EUMEL-
+Systems keinen schreibenden Zugriff auf die Task
+'configurator' haben, müssen Sie die Task 'configurator'
+an Ihr Terminal koppeln und die Datei 'fonttab.ls-Menu-
+Generator' von der Diskette in die Task kopieren. 
+   #on("u")#Anschließend#off("u")# kann #on("b")#ls-Menu-Generator#off("b")# in einer Task
+installiert werden, in der bereits das Programm #on("b")#ls-DIALOG#off("b")#
+zur Verfügung steht. Richten Sie also eine Task als Sohn
+der Task ein, in der auf Ihrem Computer bereits #on("b")#ls-DIALOG#off("b")#
+installiert ist. Legen Sie dann die Archivdiskette ein,
+auf der sich #on("b")#ls-Menu-Generator#off("b")# befindet und geben Sie
+die folgenden Kommandos: 
+ 
+   archive("ls-Menu-Generator") <RETURN> 
+ 
+   fetch("ls-Menu-Generator/gen",archive) <RETURN> 
+ 
+   run <RETURN> 
+ 
+   Sie haben damit das Generatorprogramm gestartet; die
+Installation wird automatisch durchgeführt. Lassen Sie
+während des gesamten Vorgangs die Archivdiskette einge­
+legt. Die Generierung ist beendet, wenn der EUMEL-Ein­
+gangsbildschirm erscheint. Die Task, in der die Generie­
+rung stattfindet, wird automatisch zur Managertask, das
+heißt, daß Söhne von ihr eingerichtet werden können. 
+ 
+ 
+
diff --git a/doc/menugenerator/menu-generator handbuch.3 b/doc/menugenerator/menu-generator handbuch.3
new file mode 100644
index 0000000..e982988
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.3	
@@ -0,0 +1,155 @@
+#block##pageblock# 
+#pagenr("%",1)##setcount(1)##count per page# 
+#headeven# 
+gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#right#gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+3 - % #right#ERGOS 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+ERGOS #right# 3 - % 
+#end# 
+#ib#3 Die Arbeitsweise von gs-DIALOG#ie# 
+ 
+ 
+In diesem Kapitel soll die grundsätzliche Arbeitsweise von gs-DIALOG erläutert
+werden. Sie erfahren, wie das Menusystem aufgebaut ist, wie man Menukarten an­
+koppelt und Menus zur Ausführung bringt. Ebenso wird erläutert, wie eine Menukarte
+aufgebaut ist. 
+Wenn Sie die hier beschriebenen Vorgänge auf ihrem System nachvollziehen wollen,
+so muß in Ihrer Task das Programm 'gs-DIALOG' zur Verfügung stehen! 
+ 
+ 
+#ib#3.1  Ankoppeln einer Menukarte - Ausführen eines Menus#ie# 
+ 
+Vereinfacht gesagt ist eine Menukarte ein Datenraum, in dem alle Informationen, die
+zum Menu (zu den Menus) gehören, abgelegt sind. Der genaue Aufbau einer solchen
+Menukarte wird in Kapitel 3.2 beschrieben. 
+Alle Menukarten, die auf einem System zur Verfügung stehen, werden in einer zentra­
+len Task ('gs-MENUKARTEN') bereitgehalten. Die Menukarten können von hier
+angefordert werden. 
+Lassen Sie sich in Ihrem System eine Übersicht der vorhandenen Menukarten geben
+(list (/"gs-MENUKARTEN") <RETURN> ). Darauf wird Ihnen gegebenenfalls folgen­
+de Übersicht angeboten: 
+ 
+  01.09.87       "gs-MENUKARTE:Archiv" 
+  01.09.87       "gs-MENUKARTE:Herbert und Robbi" 
+  01.09.87       "gs-MENUKARTE:MP-BAP" 
+  ... 
+ 
+Zumindest die erste Menukarte müßte - sofern die gs-DIALOG-Basissoftware instal­
+liert ist - auf Ihrem System vorhanden sein. Die beiden anderen Menukarten sind
+natürlich nur dann vorhanden, wenn Sie die Programme 'gs-Herbert und Robbi'
+und 'gs-MP BAP' installiert haben. 
+ 
+In einer weiteren Task (z.B. 'DIALOG') sind die Programme installiert, die es ermög­
+lichen, diese Menukarten zu handhaben. Alle Sohntasks dieser Task "erben" natür­
+lich diese Fähigkeiten. Von einer solchen Task aus kann nun eine Menukarte ange­
+fordert und ein darin enthaltenes Menu zur Ausführung gebracht werden. Das haben
+Sie sicher schon oft gemacht, z.B. wenn Sie den Befehl 'archiv' gegeben haben. Was
+hinter diesem Befehl steckt, sollen Sie sich jetzt klar machen: 
+ 
+Wenn Sie den Befehl 'archiv' geben, wird zunächst die Menukarte
+'gs-MENUKARTE:Archiv' aus der Task 'gs-MENUKARTEN' angefordert und in Ihre
+Task kopiert. Davon merken Sie normalerweise nichts, denn nachdem die Ankopp­
+lung des Datenraumes (als unbenannter Datenraum) erfolgt ist, wird die Daten­
+raumkopie gelöscht; daher taucht der Name auch nie in Ihrer Dateiliste auf. Intern
+vermerkt das System, welche Menukarte aktuell angekoppelt ist. Soll wiederholt
+dieselbe Menukarte angekoppelt werden, so erübrigt sich das Kopieren aus der zen­
+tralen Bereitstellungstask. 
+ 
+Nach dem Ankoppeln der Menukarte können Sie auf die in der Menukarte enthalte­
+nen Informationen zugreifen. Da in einer Menukarte mehrere Menus enthalten sein
+können, müssen Sie dem System noch mitteilen, welches Menu aktiviert werden soll.
+In der Menukarte 'gs-MENUKARTE:Archiv' ist nur ein Menu enthalten, das den
+Namen 'ARCHIV' hat (der Name des Menus erscheint übrigens bei der Präsentation
+immer oben links in der Kopfzeile). 
+ 
+Sie sollen jetzt, ohne den Befehl 'archiv' zu verwenden, das Menu zur Ausführung
+bringen. Geben Sie dazu die folgenden Kommandos in der 'gib kommando:'- Ebene: 
+ 
+   #ib#install menu#ie# ("gs-MENUKARTE:Archiv"); 
+   #ib#handle menu#ie# ("ARCHIV") 
+ 
+Mit dem ersten Befehl koppeln Sie die genannte Menukarte an, mit dem zweiten
+Befehl bringen Sie das darin enthaltene Menu 'ARCHIV' zur Ausführung. 
+Allerdings stellen Sie sicher auch einen Unterschied zur Ausführung des Befehls
+'archiv' fest, denn dort erscheint nicht erst unser "Software - Emblem" auf dem
+Bildschirm, sondern direkt das Menu. 
+ 
+Wenn Ihnen eines der Programme 'gs-Herbert und Robbi' oder 'gs-MP BAP'
+bekannt ist, haben Sie unser Emblem aber sicher schon gesehen - wir verwenden es
+immer, um unsere Softwareprodukte kenntlich zu machen. Da man aber das Archiv­
+programm sehr häufig benötigt und es dann nur störend wirkt kann die Ausgabe
+unterdrückt werden. Daher gibt es den Befehl 'install menu' in zwei Versionen.
+Versuchen Sie es gleich einmal: 
+ 
+   install menu ("gs-MENUKARTE:Archiv", FALSE); 
+   handle menu ("ARCHIV") 
+ 
+Die Präsentation des Menus erfolgt gleich aus zwei Gründen schneller als beim ersten
+Mal: einerseits wurde auf die Ausgabe unseres Software - Emblems verzichtet, ande­
+rerseits brauchte die Menukarte nicht erneut aus der Task 'gs-MENUKARTEN' kopiert
+zu werden, da sie ja schon angekoppelt war. 
+Damit sind Sie nun in der Lage, Menukarten anzukoppeln und Menus zur Ausfüh­
+rung zu bringen. 
+ 
+ 
+#ib#3.2    Aufbau/Inhalt einer Menukarte#ie# 
+ 
+Eine Menukarte ist eine komplexe Datenstruktur, die bis zu 6 vollständige Menus
+aufnehmen kann. Weiterhin sind eine Reihe von Texten in jeder Menukarte abgelegt,
+auf die gs-DIALOG zurückgreift. Darüberhinaus kann der Anwendungsprogram­
+mierer bis zu 2000 Texte in die Menukarte auslagern, um so beim Insertieren seiner
+Programme den Umfang an Paketdaten geringer zu halten. 
+Auf den ersten Blick scheint es wenig Sinn zu machen, mehrere Menus in einer
+Menukarte zu verwalten. Nehmen wir aber als Beispiel das Programmsystem
+gs-Herbert und Robbi. Hier ist ein Programm in zwei unterschiedlichen Ausprä­
+gungen zu behandeln. Sowohl das Hamster- als auch das Robotermenu befinden sich
+in einer Menukarte. Bei einem Wechsel zwischen den Modellen braucht also keine
+neue Menukarte angefordert, sondern nur ein neues Menu aus der aktuellen Menu­
+karte aktiviert zu werden. 
+Zum anderen ist gs-DIALOG schon auf umfangreichere Programmsysteme vorberei­
+tet: Es ist nämlich möglich, von einem Menu aus ein weiteres Menu aus der aktuellen
+Menukarte zu aktivieren. Auf dem Bildschirm werden die beiden Menus dann ge­
+schachtelt (das zuletzt aktivierte vor dem aufrufenden Menu) angezeigt. Nach Verlas­
+sen der zweiten Menuebene gelangt der Benutzer automatisch in das Ausgangsmenu
+zurück. 
+Zwar ist es nicht möglich, mehr als zwei Menus gleichzeitig zu aktivieren (geschach­
+telt auf dem Bildschirm darzustellen), doch können an verschiedenen Stellen des
+Ausgangsmenus ja unterschiedliche Menus aus der aktuellen Menukarte aktiviert
+werden. 
+ 
+Jedes Menu in der Menukarte wird durch einen Namen gekennzeichnet. Dieser Name
+erscheint in der Kopfzeile oben links. Über diesen Namen kann das Menu aktiviert
+werden. 
+Ein Menu besteht aus den sogenannten 'Oberbegriffen', die in der Kopfzeile angezeigt
+werden. In einer Kopfzeile können bis zu 10 Oberbegriffe verwaltet werden. Da zu
+jedem Oberbegriff bis zu 15 Verarbeitungsfunktionen (in den Pull-Down-Menus)
+verwaltet werden können, ist es möglich, in einem Menu bis zu 150 Verarbeitungs­
+funktionen abzulegen. Nutzt man alle 6 Menus einer Menukarte, so können maximal
+bis zu 900 Verarbeitungsfunktionen in einer Menukarte verwaltet werden. 
+ 
+Eine Verarbeitungsfunktion besteht aus der/dem 
+ 
+ - 'Ein-Zeichen-Kennung'   -  die angibt, durch welche Taste die Verarbei­
+                              tungsfunktion ggf. aktiviert werden kann; 
+ - 'Menupunktbezeichnung'  -  die im Pull-Down-Menu als Name für die
+                              Verarbeitungsfunktion erscheint; 
+ - 'Funktionsaufruf'       -  dem Namen der Prozedur, die bei der Aktivie­
+                              rung des Menupunktes zur Ausführung ge­
+                              bracht wird; 
+ - 'Informationstext'      -  der zur aktuellen Verarbeitungsfunktion durch
+                              Tippen der <?>-Taste abgerufen werden
+                              kann. 
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.4 b/doc/menugenerator/menu-generator handbuch.4
new file mode 100644
index 0000000..97e7491
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.4	
@@ -0,0 +1,424 @@
+#block##pageblock# 
+#pagenr("%",1)##setcount(1)##count per page# 
+#headeven# 
+gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#right#gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+4 - % #right#ERGOS 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+ERGOS #right# 4 - % 
+#end# 
+#ib#4 Erstellen einer neuen Menukarte#ie# 
+ 
+ 
+Aus Kapitel 3 wissen Sie, wie man eine fertige Menukarte ankoppelt und wie man ein
+darin enthaltenes Menu zur Ausführung bringen kann. Außerdem wissen Sie bereits,
+welche Informationen in einer Menukarte untergebracht werden können. In diesem
+Kapitel nun wollen wir Ihnen zeigen, wie Sie eine eigene Menukarte entwickeln
+können. 
+Damit Sie sich die Abläufe besser vorstellen können, werden wir die Vorgänge an
+einem Beispiel aufzeigen: Wir wollen eine 'kleine Textverarbeitung' schaffen, deren
+Verarbeitungsfunktionen über ein Menu angeboten werden. 
+Es sei aber darauf hingewiesen, daß es nicht darum geht, eine voll funktionsfähige
+Textverarbeitung auszuarbeiten - vielmehr sollen die Erstellung der Menukarte und
+das Nutzen der durch gs-DIALOG bereitgestellten Werkzeuge exemplarisch auf
+gezeigt werden. 
+ 
+ 
+#ib#4.1  Eintragen der Menupunkte#ie# 
+ 
+Unsere Menukarte soll den Namen 'Kleine Textverarbeitung' erhalten, das darin
+enthaltene Menu den Namen 'SCRIPT'. Unter dem Oberbegriff 'Bearbeiten' sollen 5
+Verarbeitungsfunktionen angeboten werden. Insgesamt soll unser neues Menu fol
+genden Aufbau haben: 
+ 
+SCRIPT:  Bearbeiten 
+ 
+    n Neu erstellen 
+    a Ansehen/Ändern 
+    ---------------- 
+    v Verzeichnis 
+    ---------------- 
+    z Zeilenformtierung 
+    s Seitenformatierung 
+ 
+ 
+ 
+Zur Erzeugung der zugehörigen Menukarte schreiben Sie folgendes Pro­
+gramm in eine Datei: 
+ 
+ 
+oeffne menukarte  ("Kleine Textverarbeitung"); 
+oeffne menu    ("SCRIPT"); 
+ 
+oberbegriff    ("Bearbeiten"); 
+ 
+menufunktion   ("n", "Neu erstellen", "neue datei editieren",""); 
+menufunktion   ("a", "Ansehen/Ändern", "alte datei editieren",""); 
+trennlinie; 
+menufunktion   ("v", "Verzeichnis", "verzeichnis ausgeben",""); 
+trennlinie; 
+menufunktion   ("z", "Zeilenformatierung", "zeilen formatieren",""); 
+menufunktion   ("s", "Seitenformatierung", "seiten formatieren",""); 
+ 
+schliesse menu; 
+schliesse menukarte; 
+ 
+ 
+Bevor wir Ihnen die Einzelheiten erklären, sollten Sie zuerst einmal Ihr neu erstelltes
+Menu ausprobieren. Verlassen Sie dazu die Datei und geben Sie das Kommando 'run'.
+Nachdem das von Ihnen geschriebene Programm übersetzt worden ist, meldet sich
+der Menu-Generator. 
+Die an Sie gestellte Frage 'Sollen auch Anwendungs texte in die Menukarte aufge­
+nommen werden (j/n)?' beantworten Sie einfach mit n(ein). Auf dem Bildschirm
+wird angezeigt, wie die Menukarte erstellt wird. Auf das Ende der Menukartengenerie­
+rung wird hingewiesen. Wenn Sie sich jetzt die Dateiliste Ihrer Task anzeigen lassen,
+taucht dort eine Datei mit Namen 'gs-MENUKARTE:Kleine Textverarbeitung' auf - das
+ist die neue Menukarte. 
+Sie möchten sicher gleich ausprobieren, ob das Menu Ihren Vorstellungen entspricht.
+Geben Sie dazu das Kommando 'testinstallation ("gs-MENUKARTE:Kleine Textver­
+arbeitung")'. Bitte geben Sie den Text genauso ein wie hier angegeben! 
+Nach kurzer Zeit erscheint der Hinweis 'Installation abgeschlossen!'. Geben Sie nun
+den Befehl 'handle menu ("SCRIPT")'; hierdurch aktivieren Sie das von Ihnen neu
+erstellte Menu - es erscheint auf dem Bildschirm. 
+ 
+Über den Befehl '#ib#testinstallation#ie#' haben Sie sich sicher gewundert. Ihnen ist ja
+schon der Befehl '#ib#install menu#ie#' bekannt. Dieser Befehl aber kann hier nicht ein­
+fach angewendet werden - er ist für den (späteren) "regulären Betrieb" vorgesehen.
+Bedenken Sie bitte zweierlei: Die Menukarte befindet sich nur in Ihrer Task, 'install
+menu' fordert die Menukarte aber aus der Task 'gs-MENU KARTEN' an. Ist eine
+Menukarte schon angekoppelt gewesen, so wird nicht erneut angekoppelt, sondern
+auf die angekoppelte Menukarte zurückgegriffen. Dies alles können wir bei der
+Menukartenerstellung nicht gebrauchen! 
+Der Befehl 'testinstallation' sendet automatisch die Menukarte zur Task
+'gs-MENUKARTEN' und kennzeichnet Sie noch durch den eigenen Tasknamen (da
+durch können sich beim Multiuserbetrieb unterschiedliche Anwender mit gleichem
+Menukartennamen nicht gegenseitig stören). Die Menukarte wird anschließend in
+jedem Falle 'frisch' angekoppelt, so daß Sie nach dem Befehl immer die aktuelle
+Menukarte angekoppelt haben. Außerdem bleibt die Menukarte in Ihrer Task erhal­
+ten! 
+ 
+Doch nun zur Erläuterung des oben notierten Programms: 
+ 
+Ein Programm zur Erstellung einer Menukarte muß immer mit dem Befehl '#ib#oeffne
+menukarte#ie#' beginnen und mit dem Befehl '#ib#schliesse menukarte#ie#' abgeschlos­
+sen werden. Der Befehl 'oeffne menukarte' hat einen Parameter (TEXT CONST) -
+hierdurch wird festgelegt, welchen Namen die Menukarte haben soll. Durch das
+Kommando 'oeffne menu karte ("Menu 1")' entsteht also die Menukarte 'gs-MENU
+KARTE:Menu 1". 
+In die Menukarte können jetzt bis zu 6 Menus eingetragen werden. Jeder Eintrag
+eines Menus beginnt mit dem Befehl '#ib#oeffne menu#ie#' und endet mit dem Befehl
+'#ib#schliesse menu#ie#'. Der Befehl 'oeffne menu' hat hier einen Parameter (TEXT
+CONST) - hierdurch wird festgelegt, welchen Namen das Menu erhalten soll. Unter
+diesem Namen kann später das Menu angesprochen werden (z.B. 'handle menu
+("SCRIPT")'. 
+ 
+Den Befehl 'oeffne menu' gibt es noch in zwei weiteren Ausführungen: 
+Mit drei Textparametern - neben dem Namen des Menus können hier noch zwei
+Prozedurnamen angegeben werden. Diese Prozeduren werden beim Einstieg in das
+Menu bzw. beim Verlassen des Menus aufgerufen. Hiervon wird z.B. Gebrauch ge­
+macht, wenn das Archiv-Menu in eine Menukarte integriert ist: Wenn das Menu
+verlassen wird, soll sichergestellt sein, daß das Archiv automatisch freigege ben wird.
+Mehr hierüber erfahren Sie im Kapitel 6.1, in dem aufgezeigt wird, wie das Archiv-
+Menu in andere Menus eingebunden wird. 
+Mit sechs Textparametern - neben den eben genannten drei Parametern können noch
+drei Texte übergeben werden. Diese Texte werden beim Aufruf des Menus unten
+rechts auf dem Bildschirm ausgegeben. Bei unseren Software-Produkten (z.B.
+'gs-Herbert und Robbi') machen wir davon Gebrauch, um Hinweise auf das
+Produkt, die Versionsnummer etc. zu geben. Die Hinweise bleiben nur kurz auf dem
+Bildschirm und verschwinden nach kurzer Zeit automatisch, oder wenn Sie irgen
+deine Taste tippen. Bei der Notation der Texte müssen Sie sich allerdings an einige
+Regeln halten (sehen Sie dazu Kapitel 5.12). 
+ 
+Zwischen den Befehlen 'oeffne menu' und 'schliesse menu' werden nun die Oberbe­
+griffe (Kopfzeile) und die zugehörigen Verarbeitungsfunktionen eingetragen. Dabei
+müssen Sie sich genau an folgende Abfolge halten: 
+Zuerst wird jeweils der Oberbegriff genannt, der in der Kopfzeile auftauchen soll.
+Direkt unter dem jeweiligen Oberbegriff werden die Menufunktionen eingetragen, die
+im zugehörigen 'Pull-Down-Menu' als Verarbeitungsfunktionen angeboten werden
+sollen. Die einzelnen Oberbegriffe mit Ihren zugehörigen Verarbeitungsfunktionen
+werden blockweise hintereinander notiert. Dadurch ergibt sich die folgende Struktur: 
+ 
+ 
+oeffne menu   ("Menuname"); 
+ 
+oberbegriff   ("Oberbegriff 1"); 
+ 
+menufunktion  ("1", "Verarbeitungsfunktion 1", "", ""); 
+menufunktion  ("2", "Verarbeitungsfunktion 2", "", ""); 
+... 
+ 
+oberbegriff   ("Oberbegriff 2"); 
+ 
+menufunktion  ("1", "Verarbeitungsfunktion 1", "", ""); 
+menufunktion  ("2", "Verarbeitungsfunktion 2", "", ""); 
+... 
+ 
+oberbegriff   ("Oberbegriff 3"); 
+ 
+menufunktion  ("1", "Verarbeitungsfunktion 1", "", ""); 
+menufunktion  ("2", "Verarbeitungsfunktion 2", "", ""); 
+... 
+ 
+... schliesse menu; 
+ 
+ 
+Die Oberbegriffe werden in die Kopfzeile von links nach rechts eingetragen. Maximal
+können 10 Oberbegriffe eingetragen werden. Wählen Sie die Bezeichnungen nicht zu
+lang, denn sie müssen alle neben dem Namen des Menus in der Kopfzeile Platz
+finden (Ansonsten erhalten Sie hierauf bei der Menukartengenerierung einen Hin­
+weis, die Generierung wird abgebrochen!)! 
+ 
+Den Befehl '#ib#oberbegriff#ie#' gibt es in zwei Versionen: 
+In der hier aufgezeigten Version mit einem (TEXT-) Parameter: Hierdurch wird der
+Oberbegriff in der Kopfzeile festgelegt. In der zweiten Version hat der Befehl drei
+(TEXT-)Parameter: Durch den ersten wird - wie eben - die Kopfzeilenbezeichnung
+festgelegt. Daneben können noch zwei Prozedurnamen angegeben werden. Die
+Prozedur mit dem erstgenannten Namen wird beim Einstieg (vor dem "Ausklappen"
+des Pull-Down-Menus) ausgeführt, die Prozedur mit dem zweitgenannten Namen vor
+dem Ausstieg ("Einklappen"). Beim 'Archiv-Pull-Down-Menu' machen wir hiervon
+Gebrauch. Beim Einstieg wird dafür gesorgt, daß nur bestimmte Verarbeitungsfunk­
+tionen aktivierbar sind; beim Ausstieg wird sichergestellt, daß das Archivlaufwerk
+automatisch freigegeben wird. 
+ 
+Unter einem Oberbegriff können Sie bis zu 15 Verarbeitungsfunktionen in ein Pull-
+Down-Menu eintragen. Die Verarbeitungsfunktionen können Sie optisch vonein ander
+trennen. Dafür steht der Befehl '#ib#trennlinie#ie#' zur Verfügung. Aber beachten Sie, er
+belegt den gleichen Platz wie eine Verarbeitungsfunktion. 
+ 
+Zum Eintragen einer Verarbeitungsfunktion steht der Befehl '#ib#menufunktion#ie#' zur
+Verfügung. Der Befehl besitzt vier (TEXT-)Parameter. Die ersten beiden Parameter
+werden auch auf dem Bildschirm ausgegeben. 
+Der erste Parameter legt fest, über welche Taste diese Verarbeitungsfunktion direkt
+zur Ausführung gebracht werden kann. Wenn eine Eintragung erfolgt, muß diese aus
+genau einem Zeichen bestehen. Innerhalb eines Pull-Down-Menus muß dieses
+Zeichen eindeutig sein, d.h. es darf nur einmal verwendet werden. Ansonsten er­
+scheint bei der Menugenerierung eine Fehlermeldung. 
+Der zweite Parameter ist die Bezeichnung der Verarbeitungsfunktion, die dem Be­
+nutzer im Pull-Down-Menu angeboten wird. Wählen Sie die Bezeichnung bitte immer
+prägnant und möglichst mit dem Buchstaben beginnend, den Sie auch als ersten
+Parameter angegeben haben! Der Länge dieser Bezeichnung ist nur durch die Bild­
+schirmbreite (nicht mehr als 60 Zeichen) begrenzt, allerdings wählt  gs-DIALOG die
+Breite des Pull-Down-Menus nach der längsten Bezeichnung, die im jeweiligen Pull-
+Down-Menu auftritt. Wenn die Bezeichnungen ganz unterschiedlich lang sind, sieht
+das nicht sonderlich gut aus, aber probieren Sie es ruhig einmal aus und entscheiden
+Sie selbst. 
+ 
+Der dritte Parameter ist der Name der Prozedur, die bei der Aktivierung der Verarbei­
+tungsfunktion ausgewählt werden soll. Zum Zeitpunkt der Erstellung und des Testens
+des Menusystems braucht diese Prozedur noch nicht zu existieren. Damit ist es
+möglich, die Menuentwicklung völlig unabhängig von der Entwicklung der Verarbei­
+tungsfunktionen zu betreiben; Sie brauchen nur die späteren Namen der aufzurufen­
+den Prozeduren festzulegen! Aktivieren Sie eine solche Verarbeitungsfunktion im
+Pull-Down-Menu, die noch nicht fertiggestellt ist, so erscheint der Hinweis 'unbe­
+kanntes Kommando' - das kann aber auch geschehen, wenn die Verarbeitungsfunk­
+tion schon existiert, Sie aber bei der Eintragung einen (Schreib-)Fehler gemacht
+haben! 
+ 
+Der vierte Parameter ist der Text, der als sogenannter Infotext ausgegeben wird wenn
+Sie auf die entsprechende Verarbeitungsfunktion positioniert haben und hier die
+<?>-Taste tippen. In unserem Beispiel haben wir keinen Infotext eingetragen.
+Versuchen Sie im Menu jetzt die <?>-Taste zu tippen, so erscheint der Hinweis
+'Leider ist zu diesem Menupunkt kein Info-Text eingetragen!'. Für die Handhabung
+des Menus sind diese Informationstexte nicht wichtig, sie dienen ausschließlich der
+Information des Benutzers. 
+Die Arbeit zur Formulierung/Abfassung dieser Texte sollten Sie nicht unterschätzen.
+Sie sollten sich bei einer ernsthaften Anwendung aber diese Arbeit machen. Gerade
+der Anfänger, der mit Ihrem Menusystem arbeitet, wird Ihnen diese Arbeit danken.
+Wie Sie diese Texte komfortabel erstellen und in die Menutafel einbinden können,
+erklären wir Ihnen im nächsten Kapitel. 
+ 
+ 
+#ib#4.2  Erstellung und Einbinden von Informationstexten#ie# 
+ 
+Bisher haben wir noch keine Informationstexte zu den Menupunkten in die Menu­
+karte eingetragen. Diese Eintragung erfolgt über den vierten Parameter des Befehls
+'menufunktion'. Möchten Sie dort nur einige wenige Worte eintragen, so kann das
+direkt geschehen. Meist aber sind die Informationen zu einem Menupunkt doch
+länger, sie erstrecken sich über mehrere Zeilen. 
+Zur Übergabe des Informationstextes steht aber nur ein Textparameter zur Verfügung.
+Würde man längere Texte direkt eintragen, wäre das bei der Menukartenerstellung
+sicher sehr unübersichtlich. Zum anderen benötigt gs-DIALOG den Text schon in
+aufbereiteter Form, d.h. es müssen z.B. Zeilenenden etc. kenntlich gemacht wer den. 
+Damit Sie sich nun nicht alle Regeln der Texterstellung für gs-DIALOG merken
+müssen, bietet Ihnen gs-Menu-Generator eine komfortable Möglichkeit, diese
+Informationstexte zu entwickeln. Wir wollen das an einem Beispiel verdeutlichen: 
+ 
+Erzeugen Sie sich eine Datei mit dem Namen 'Textprobe' und schreiben Sie z.B.
+folgenden Text, der ein Informationstext zum Menupunkt 'Neu erstellen' sein könnte,
+hinein: 
+ 
+Text neu erstellen 
+ 
+Das System erfragt zunächst den Namen für die Datei, in die 
+der neue Text geschrieben werden soll. Anschließend wird eine 
+leere Datei mit dem gewünschten Namen zum Beschreiben 
+angeboten. 
+Das Schreiben in eine solche Datei wird durch viele Hilfen 
+erleichtert. Deshalb ist es ratsam, sich nach und nach mit 
+den Möglichkeiten, die der Editor bietet, vertraut zu machen. 
+Die Möglichkeiten sind im EUMEL-Benutzerhandbuch ausführlich 
+beschrieben. 
+ 
+Verlassen Sie nun die Datei und geben Sie in der 'gib kommando:'-Ebene folgendes
+Kommando: 
+ 
+    #ib#textprozedur#ie# ("Textprobe", "mein erster infotext") 
+ 
+Auf dem Bildschirm erscheint zunächst der Hinweis 'Bitte warten ...', anschließend
+werden Sie - wie aus der Textverarbeitung (lineform) bekannt - aufgefordert, entspre­
+chende Trennungen vorzunehmen. 
+Das eben eingegebene Kommando bewirkt nämlich, daß der in der Datei 'Textprobe'
+enthaltene Text für gs-DIALOG so aufbereitet wird, daß er in einer Box innerhalb des
+Menus eingeblendet werden kann. Die Zeilen werden auf die entsprechende Länge
+zugeschnitten und der Text in den Zeilen wird geblockt, soweit Sie keine Absatzmarke
+(<RETURN>) gesetzt haben. 
+Der so den Regeln von gs-DIALOG entsprechend aufbereitete Text wird automatisch
+in eine Textprozedur "verpackt", die den von Ihnen als zweiten Parameter übergebe­
+nen Namen erhält. Beachten Sie deshalb bei der Festlegung des Namens, daß er mit
+einem Kleinbuchstaben beginnt und weiterhin nur Kleinbuchstaben, Ziffern und
+Leerzeichen enthält! 
+Diese Textprozedur finden Sie anschließend in der Datei 'Textprobe.a'. An der En­
+dung '.a' können Sie erkennen, daß in dieser Datei ein "aufbereiteter" Text enthalten
+ist. 
+Wenn Sie sich, nachdem auf dem Bildschirm der Hinweis 'Textprozedur ist erstellt!'
+erschienen ist, die Datei 'Textprobe.a' ansehen, so hat diese folgenden Inhalt: 
+ 
+ 
+TEXT PROC mein erster infotext: 
+" Text neu erstellen "13"" + 
+"   "13"" + 
+" Das System erfragt zunächst den Namen für die Datei, in die der "13""+ 
+" neue Text geschrieben werden soll. Anschließend wird eine leere "13""+ 
+" Datei mit dem gewünschten Namen zum Beschreiben angeboten. "13""+ 
+" Das Schreiben in eine solche Datei wird durch viele Hilfen er-"13""+ 
+" leichtert. Deshalb ist es ratsam, sich nach und nach mit den Mög-"13""+ 
+" lichkeiten, die der Editor bietet, vertraut zu machen. "13"" + 
+" Die Möglichkeiten sind im EUMEL-Benutzerhandbuch ausführlich be-"13""+ 
+" schrieben.  " 
+END PROC mein erster infotext; 
+ 
+ 
+Kopieren Sie nun den Inhalt der Datei 'Textprobe.a' in die Datei, in die Sie das Pro­
+gramm zur Generierung Ihrer Menukarte geschrieben haben und ergänzen Sie die
+Ein tragung beim ersten Menupunkt in folgender Weise: 
+ 
+ 
+TEXT PROC mein erster infotext: 
+" Text neu erstellen "13"" + 
+"   "13"" + 
+" Das System erfragt zunächst den Namen für die Datei, in die der"13""+ 
+" neue Text geschrieben werden soll. Anschließend wird eine leere"13""+ 
+" Datei mit dem gewünschten Namen zum Beschreiben angeboten. "13""+ 
+" Das Schreiben in eine solche Datei wird durch viele Hilfen er-"13""+ 
+" leichtert. Deshalb ist es ratsam, sich nach und nach mit den Mög-"13""+ 
+" lichkeiten, die der Editor bietet, vertraut zu machen. "13""+ 
+" Die Möglichkeiten sind im EUMEL-Benutzerhandbuch ausführlich be-"13""+ 
+" schrieben. " 
+END PROC mein erster infotext; 
+ 
+oeffne menukarte ("Kleine Textverarbeitung"); 
+oeffne menu ("SCRIPT"); 
+ 
+oberbegriff ("Bearbeiten"); 
+ 
+menufunktion ("n", "Neu erstellen", "neue datei editieren", 
+                                     mein erster infotext); 
+menufunktion ("a", "Ansehen/Ändern","alte datei editieren", ""); 
+trennlinie; 
+menufunktion ("v", "Verzeichnis", "verzeichnis ausgeben", ""); 
+trennlinie; 
+menufunktion ("z", "Zeilenformatierung", "zeilen formatieren", ""); 
+menufunktion ("s", "Seitenformatierung", "seiten formatieren", ""); 
+ 
+schliesse menu; 
+schliesse menukarte; 
+ 
+ 
+Starten Sie erneut das Programm mit 'run' und erstellen Sie dadurch eine neue
+Menukarte. Installieren Sie anschließend die neue Menukarte mit dem Kommando
+'test installation ("gs-MENUKARTE:Kleine Textverarbeitung")' und bringen Sie das
+Menu mit dem Kommando 'handle menu ("SCRIPT")' zur Ausführung. Wenn Sie jetzt
+auf dem Menu punkt 'n Neu erstellen' die <?>-Taste tippen, erscheint der von
+Ihnen eingegebene Infotext in einer Box innerhalb des Menus. Die Größe der Box
+wird automatisch durch den Text bestimmt. Die Box ist maximal 65 Zeichen breit
+und 14 Zeilen hoch. 
+ 
+Nachdem Sie nun in der Lage sind, solche Informationstexte zu erstellen und sie in
+die Menukarte einzubinden, möchten wir Ihnen noch einige Möglichkeiten der
+"Kosmetik solcher Informationstexte" aufzeigen. 
+Häufig möchte man die Überschrift eines solchen Informationstextes zentriert über
+dem Text dargestellt haben. Das läßt sich auch hier einfach bewerkstelligen: Schrei­
+ben Sie dazu als erstes Zeichen der Zeile, die zentriert werden soll, das Zeichen '%'
+und schließen Sie die Zeile mit einer Absatzmarke (<RETURN>) ab. 
+Möchten Sie innerhalb des Textes eine Textpassage invers dargestellt haben, so kenn­
+zeichnen Sie den Anfang der Inversdarstellung durch das Zeichen '$' und das Ende
+der Inversdarstellung durch das Zeichen '&'. Der Text wird anschließend entspre­
+chend aufbereitet. Allerdings sollte die Textpassage nicht über Zeilengrenzen hinaus­
+gehen! 
+Möchten Sie in unserem Beispiel die Überschrift zentriert und invers dargestellt
+haben, so ersetzen Sie die erste Zeile der Datei 'Textprobe' durch die Zeile: %$Text
+neu erstellen&. Wenn Sie anschließend den gesamten oben beschriebenen Vorgang
+wiederholen, erscheint die Überschift zentriert und invers dargestellt innerhalb der
+Box im Menu. 
+ 
+ 
+#ib#4.3  Auslagerung von anwendungsbezogenen Texten in die
+Menukarte#ie# 
+ 
+Wie schon in Kapitel 3.2 erwähnt, kann der Anwendungsprogrammierer bis zu 2000
+Texte aus seinen Programmen in die Menukarte auslagern, um so den Umfang an
+Paketdaten geringer zu halten, allerdings darf die Gesamtkapazität einer Menukarte
+(eines Datenraumes) dabei nicht überschritten werden. 
+ 
+Die Texte müssen in einer Datei zeilenweise notiert sein. Sie müssen (wie TEXT-Deno­
+ter) in Anführungsstriche eingefaßt sein, allerdings dürfen die Texte länger als
+(normale) TEXT-Denoter (255 Zeichen) sein. Innerhalb der Textzeile dürfen auch die
+Ausgabecodes "4", "5", "7", "10", "13", "14", und "15" verwendet werden. Innerhalb
+der Textzeile darzustellende Anführungszeichen unterliegen den gleichen Besonder­
+heiten wie sonst auch bei TEXT-Denotern. 
+Machen wir ein Beispiel! Schreiben Sie in eine Datei mit Namen 'Neue Texte' die
+folgenden Zeilen: 
+ 
+"Dieses ist der erste eingetragene Text!" 
+"Hier ist eine "15"Markierung"14" im Text!" 
+"Dieses ist die letzte Zeile!" 
+ 
+Um diese Texte in die Menukarte einzubinden, starten Sie jetzt noch einmal Ihr
+Generierungprogramm für die Menukarte. Auf die Frage 'Sollen auch Anwendungstex­
+te in die Menukarte aufgenommen werden (j/n) ?' antworten Sie jetzt allerdings mit
+j(a). Daraufhin werden Ihnen die in Ihrer Task vorhandenen Dateien zur Auswahl
+angeboten. Kreuzen Sie die Datei 'Neue Texte' an, in der ja die eben genannten Texte
+eingetragen sind. 
+Bei der Menukartengenerierung werden die Texte aus der Datei in die Menukarte
+eingebunden. Sollten Sie bei Notierung der Texte in der Datei formale Fehler gemacht
+haben, so werden Sie darauf hingewiesen. 
+Um nun auf die eingelagerten Texte zurückgreifen zu können, muß erst einmal die
+neue Menukarte angekoppelt werden. Wie das geht, wissen Sie ja schon ('testin stalla­
+tion'). 
+Mit dem Befehl '#ib#anwendungstext#ie# (INT CONST zeilennummer)' (1 <= zeilen­
+nummer <= 2000) wird Ihnen nun der Text, der in der angegebenen Zeile steht,
+geliefert. Probieren Sie es doch gleich an Ihrer Menukarte aus: 'put (anwendungs­
+text (1))', 'put (anwendungstext (2))' usw.. Die eingelagerten Texte müßten jetzt auf
+dem Bildschirm erscheinen. Geben Sie eine Zeilennummer an, die nicht belegt ist, so
+wird der Text 'Kein Text vorhanden!' geliefert. 
+ 
+Es können natürlich auch Texte abgelegt werden, die von gs-DIALOG aus aufgegrif­
+fen werden. Zur Konvertierung von Informationstexten steht die Prozedur '#ib#text zeile#ie#
+(TEXT CONST dateiname)' zur Verfügung. Diese Prozedur arbeitet genauso wie die
+Prozedur 'textprozedur', nur wird in der Ausgabedatei ('dateiname.a') der formatierte
+Text nicht als Textprozedur, sondern als einzeiliger Text geliefert. Sie können aber
+auch für gs-DIALOG Texte "von Hand" gestalten. Dazu müssen Sie sich an die
+Regeln für die Texte für gs-DIALOG halten, die in Kapitel 5.12 erläutert sind. 
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.5 b/doc/menugenerator/menu-generator handbuch.5
new file mode 100644
index 0000000..c002f1a
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.5	
@@ -0,0 +1,975 @@
+#block##pageblock# 
+#pagenr("%",1)##setcount(1)##count per page# 
+#headeven# 
+gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#right#gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+5 - % #right#ERGOS 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+ERGOS #right# 5 - % 
+#end# 
+#ib#5  Dialoge innerhalb des Menus#ie# 
+ 
+ 
+In Kapitel 4 haben Sie erfahren, wie Sie eine eigene Menukarte entwickeln können;
+sicher haben Sie das schon ausprobiert und sich Ihr selbstgestaltetes Menu auf dem
+Bildschirm angesehen. Bislang erscheint aber noch der Hinweis 'unbekanntes Kom­
+mando', wenn Sie eine Menufunktion aktivieren - denn die Prozeduren, die Sie bei
+der Aktivierung der Menufunktion aufrufen, sind ja noch nicht fertiggestellt! 
+Bei vielen Menufunktionen ist es notwendig, mit dem Benutzer noch einen Dialog zu
+führen: z.B. muß ein Dateiname erfragt, eine Information ausgegeben und bestätigt,
+eine Auswahl oder eine Entscheidung getroffen werden. In diesem Kapitel sollen
+Ihnen nun die Möglichkeiten vorgestellt werden, die Ihnen zur Verfügung stehen, um
+einen solchen Dialog mit dem Benutzer zu führen. Dieser Dialog wird innerhalb des
+Menus geführt. Alle Prozeduren, die sich auf diesen Menu-Dialog beziehen, enthalten
+deshalb den Wortbestandteil 'menu'. 
+ 
+Hier noch einige Tips! Damit Sie Ihre Menu-Dialoge testen können, empfiehlt
+sich folgendes Vorgehen: Sie erstellen zuerst Ihre Menukarte und tragen schon die
+Namen für die jeweils aufzurufenden Prozeduren ein - wie wir es in Kapitel 4 ge­
+macht haben. Mit 'testinstallation' installieren Sie dann in Ihrer Task die neue Menu­
+karte. 
+Nun schreiben Sie Ihre Prozeduren, die Sie unter das Menu legen wollen. Ist eine
+Prozedur "testreif", so müssen Sie sie zunächst insertieren, denn das Menusystem gs-
+DIALOG kann nur auf insertierte Prozeduren zugreifen. Anschließend rufen Sie das
+Menu (z.B. 'SCRIPT') aus der Menukarte mit dem Befehl 'handle menu ("SCRIPT")'
+(Hier ist der jeweilige Menuname einzusetzen!) auf. Wenn Sie den entsprechenden
+Menupunkt aktivieren, müßte Ihr Programm ablaufen. 
+Es ist günstig, eine eigene Task zum Testen der Prozeduren anzulegen, damit diese
+hin und wieder gelöscht werden kann. 
+ 
+ 
+#ib#5.1  Eingabe eines Textes/Namens#ie# ('#ib#menuanswer#ie#') 
+ 
+Wenn der Benutzer in unserem Beispiel die Menufunktion 'Neu erstellen' aktiviert
+hat, muß der Name der Datei erfragt werden, die neu erstellt werden soll. Dafür steht
+die Prozedur 'menuanswer' zur Verfügung. Die in die Menukarte eingetragene Proze­
+dur 'neue datei editieren' (Siehe Kapitel 4.1) könnte dann folgendermaßen aussehen: 
+ 
+ 
+PROC neue datei editieren: 
+  TEXT VAR dateiname := menuanswer ("Bitte den gewünschten Dateinamen:", 
+                                    "", 5); 
+  IF dateiname <> "" AND NOT exists (dateiname) 
+     THEN command dialogue (FALSE); #ib#cursor on#ie#; 
+          edit (dateiname); 
+          #ib#cursor off#ie#; command dialogue (TRUE); 
+          regenerate menuscreen      (* sehen Sie dazu Kapitel 5.10 *) 
+  FI 
+END PROC neue datei editieren; 
+ 
+ 
+Schauen wir uns zuerst die Prozedur 'menuanswer' an. Die Prozedur hat drei Para­
+meter. Mit dem ersten Parameter legen Sie den Text fest, der innerhalb der Box
+ausgegeben wird, die auf dem Bildschirm erscheint. Der Text dient ausschließlich der
+Information des Anwenders. 
+Mit dem zweiten Parameter können Sie dem Benutzer einen Vorschlag für die Einga­
+be machen, der zum Editieren ausgegeben wird. Da eine solche Vorgabe aber in die­
+ser Situation sinnlos wäre, verzichten wir darauf (""). 
+ 
+Die auf dem Bildschirm erscheinende Box hat folgendes Aussehen: 
+ 
+       +-------------------------------------+ 
+       I  Bitte den gewünschten Dateinamen:  I 
+       I                                     I 
+       I                                     I 
+       I  Eingabe:                           I 
+       +-------------------------------------+ 
+ 
+ 
+Die Boxbreite und -höhe wird vom System automatisch anhand des von Ihnen als
+ersten Parameter übergebenen Textes festgelegt. Sie haben noch verschiedene Mög­
+lichkeiten, diesen Text zu gestalten (mehrere Zeilen, Inversdarstellung etc.) - auf
+diese Möglichkeiten gehen wir in Kapitel 5.13 detailliert ein. 
+In unserem Beispiel erscheint die Box in der Mitte des Menubildschirms. Diese
+Festlegung treffen wir durch die Angabe der Position '5' als dritten Parameter. Sie
+können hier zwischen 5 verschiedenen Positionen wählen: 1 - oben links, 2 - oben
+rechts, 3 - unten links, 4 - unten rechts, 5 - zentral im Menubildschirm - mehr dazu
+in Kapitel 5.12. 
+ 
+Mit dem Erscheinen der obigen Box auf dem Bildschirm ändert sich automatisch
+auch die Fußzeile im Menu, über die der Benutzer Informationen zur Bedienung
+erhält. Hier erscheint der Hinweis: 'Fertig: <RETURN>  Abbruch: <ESC><h>'.
+Um diese Hinweise brauchen Sie sich aber nicht zu kümmern , da sie alle automa­
+tisch gesetzt werden. 
+Die Prozedur 'menuanswer' hat noch folgende Besonderheit: Es ist nicht möglich,
+den Namen 'break' einzugeben! Diese Eingabe wird automatisch abgefangen. Es hat
+sich gezeigt, daß Anwender manchmal versuchen, über <ESC><q> die Eingabe
+zu verlassen. In diesem Falle entstünde hier eine Datei mit Namen 'break' - was aber
+nicht sinnvoll wäre. 
+Nach der Eingabe liefert die Prozedur 'menuanswer' als Wert den vom Benutzer
+eingegebenen Text - dabei sind führende und folgende Leerzeichen schon abgeschnit­
+ten ('compress'). Wurde die Prozedur mit <ESC><h> verlassen, so wird niltext
+geliefert. 
+ 
+Wird in obiger Prozedur die Eingabe mit <ESC><h> abgebrochen oder existiert
+bereits eine Datei mit dem eingegebenen Namen, so verschwindet die Box, und der
+Menubildschirm wird automatisch in den alten Zustand gebracht. 
+Wenn schon eine Datei mit dem Namen existiert, dann wäre es sinnvoll, den Benutzer
+darauf aufmerksam zu machen. Wie ein solcher Hinweis in das Menu eingeblendet
+werden kann, erklären wir im Kapitel 5.2. 
+ 
+gs-DIALOG ist so geschrieben, daß der Cursor möglichst wenig störend wirkt. Aus
+diesem Grunde wird der Cursor immer an einer Stelle "geparkt". Sofern Ihr System es
+zuläßt und eine entsprechende Anpassung vorliegt, wird der Cursor ganz ausgeschal­
+tet. Denken Sie bitte daran, auch wenn er auf Ihrem Bildschirm ständig sichtbar ist! 
+Wenn also jetzt eine Eingabe erfolgen soll, ist es notwendig, den Cursor anzuschalten.
+Wenn Sie wieder in das Menu zurückkehren, sollte der Cursor wieder ausgeschal­
+tet werden, damit er dort nicht stört. 
+Wenn Sie die Prozedur 'edit' mit einem neuen Namen als Parameter aufrufen, erfragt
+das System, ob die Datei neu eingerichtet werden soll. Diese Anfrage muß hier unter­
+drückt werden, damit nicht irgendwelche Texte in den Menubildschirm geschrieben
+werden. Das Unterdrücken der Abfrage erreichen Sie durch Ausschalten des Kom­
+mandodialoges. Nach Einrichten der Datei muß der Kommandodialog aber wieder
+eingeschaltet werden, da gs-DIALOG das Eingeschaltetsein für eine fehlerfreie Funk­
+tion voraussetzt! 
+ 
+Mit dem Befehl '#ib#regenerate menuscreen#ie#' (sehen Sie dazu auch Kapitel 5.10) wird der
+aktuelle Menubildschirm erneut vollständig auf den Bildschirm geschrieben (repro­
+duziert). Das ist notwendig, weil die Prozedur 'edit' den Bildschirm benutzt hat.
+Durch diesen Befehl wird der Menubildschirm exakt in der Form hergestellt, wie er
+zuletzt ausgesehen hat. Auch wenn Sie geschachtelte Menubildschirme haben, wer­
+den diese durch den einen Befehl reproduziert. So können Sie in Ihren Verarbei­
+tungsfunktionen mit dem Bildschirm "machen was Sie wollen" - Sie kehren mit dem
+letztgenannten Befehl immer wieder so in das Menu zurück, wie Sie es verlassen
+haben. 
+ 
+ 
+#ib#5.2  Ausgabe einer Information#ie# ('#ib#menuinfo#ie#') 
+ 
+In der Prozedur 'neue datei editieren' (Kapitel 5.1) wäre es sinnvoll, den Benutzer zu
+informieren, wenn bereits eine Datei mit dem eingegebenen Namen existiert. Hierfür
+steht die Prozedur 'menuinfo' zur Verfügung. 
+ 
+Beispiel: 
+ 
+menuinfo (" Eine Datei mit dem Namen "13"     existiert schon!"); 
+ 
+Dadurch wird folgende Box ins Menu geschrieben: 
+ 
+          +----------------------------+ 
+          I                            I 
+          I  Eine Datei mit dem Namen  I 
+          I      existiert schon       I 
+          I                            I 
+          +----------------------------+ 
+ 
+Die Box erscheint in der Mitte des Menus (Position 5); in der Fußzeile wird der Hin­
+weis ausgegeben 'Zum Weitermachen bitte irgendeine Taste tippen!'. Dann wartet das
+System so lange, bis eine Taste gedrückt wird. Anschließend wird der aktuelle Menu­
+schirm wiederhergestellt. 
+Die Prozedur 'menuinfo' gibt es noch in zwei weiteren Versionen, nämlich mit zwei
+bzw. drei Parametern. Im ersten Fall kann über den zweiten Parameter noch die
+Position (1, 2, 3, 4, 5) innerhalb des Menubildschirmes  festgelegt werden (sehen Sie
+dazu Kapitel 5.12). Mit dem dritten Parameter kann ggf. noch die Wartezeit festgelegt
+werden, die das System maximal verstreichen läßt, bevor es von sich aus das Pro­
+gramm fortsetzt. 
+ 
+'menuinfo (" Eine Datei mit dem Namen "13" existiert schon!", 3, 40)' 
+ 
+gibt die oben gezeigte Box aus, aber links unten in der Ecke des Menubildschirms
+(Position 3). Das System wartet (maximal) 4 Sekunden (40 Zehntel) und setzt dann -
+auch ohne Tastendruck - das Programm fort. Diese Prozedur mit gesondert angege­
+bener Wartezeit verwendet man dann, wenn man nicht unbedingt die Kenntnisnahme
+der Information durch den Benutzer bestätigt haben möchte. 
+ 
+ 
+#ib#5.3  Auswahl eines Namen durch Ankreuzen#ie# ('#ib#menuone#ie#') 
+ 
+Während bei der Neuerstellung einer Datei ein Name neu erfragt werden muß, kann
+man beim Menupunkt 'Ansehen/Ändern' auf schon vorhandene Dateien zugreifen.
+Sie können dem Benutzer z.B. alle Dateien in der Task zur Auswahl anbieten. Sobald
+der Benutzer einen Namen angekreuzt hat, soll die entsprechende Datei geöffnet wer­
+den. Dafür steht der Befehl 'menuone' zur Verfügung: 
+ 
+ 
+PROC alte datei editieren: 
+  TEXT CONST kopf      :: "Textdatei ansehen/ändern", 
+             hinweis   :: "Bitte gewünschte Datei ankreuzen"; 
+  TEXT VAR   dateiname := menuone (ALL myself, kopf, hinweis, FALSE); 
+  IF dateiname <> "" 
+     THEN #ib#cursor on#ie#; 
+          edit (dateiname); 
+          #ib#cursor off#ie#; 
+  FI; 
+  regenerate menuscreen 
+END PROC alte datei editieren; 
+ 
+ 
+Die Prozedur 'menuone' hat 4 Parameter: Als erster Parameter ist ein Thesaurus zu
+übergeben, in dem die zur Auswahl stehenden Namen enthalten sind. Zum Thesau­
+rushandling werden noch einige zusätzliche Funktionen zur Verfügung gestellt (z.B.
+daß nur Dateien eines bestimmten Typs zur Auswahl angeboten werden können) -
+diese Funktionen werden in Kapitel 5.14 erläutert. In unserem Beispiel werden alle
+Dateien zur Auswahl angeboten, die in der Task zur Verfügung stehen. 
+Die beiden Texte, die als 2. und 3. Parameter übergeben werden, erscheinen zur
+Kennzeichnung im Kopf der Auswahlliste. Der als zweiter Parameter übergebene Text
+erscheint zentriert und invers dargestellt auf dem Bildschirm, der als dritter Parame­
+ter übergebene Text nur zentriert. Es ist sinnvoll, mit dem ersten Text (2.Parame­
+ter) die zur Zeit aktivierte Menufunktion anzuzeigen, denn der Menubildschirm wird
+ja durch die Auswahlliste überschrieben. So kann sich der Benutzer besser im Menu­
+system orientieren. 
+Mit dem 4. Parameter wird festgelegt, ob der Bildschirm nach der Auswahl "ge­
+reinigt", d.h. der alte Menubildschirm wiederhergestellt werden soll. Da in unserem
+Falle normalerweise im Anschluß an die Auswahl eine Datei auf dem Bildschirm
+editiert wird, verzichten wir auf die "automatische Regenerierung" des Menubild­
+schirms. Dieses besorgen wir nach dem Editieren durch das Kommando 'regenerate
+menuscreen' "von Hand". 
+Auf das Fenster, das für die Auswahl auf dem Bildschirm angezeigt wird, können Sie
+keinen Einfluß nehmen - es wird vom System selbständig festgelegt. Dadurch können
+Sie die Auswahl, wie auch die anderen Dialogkomponenten ebenso in geschachteleten
+Menus aufrufen, ohne daß es zu Problemen kommt. 
+ 
+ 
+#ib#5.4  Auswahl mehrerer Namen durch Ankreuzen#ie# ('#ib#menusome#ie#') 
+ 
+Es ist nicht immer sinnvoll, daß der Benutzer nur einen Namen auswählen, d.h.
+ankreuzen kann. Bei der Zeilenformatierung könnte man z.B. zulassen, daß gleich
+mehrere Dateinamen angekreuzt werden können. Im Anschluß an die Auswahl sollen
+dann alle angekreuzten Dateien mit 'lineform' bearbeitet werden. Für diesen Zweck
+steht die Prozedur 'menusome' zur Verfügung. Sie hat die gleichen Parameter wie die
+in 5.3 erläuterte Prozedur 'menuone' - nur daß hier die Auswahl mehrerer Namen
+möglich ist. Verläßt der Benutzer die Auswahl durch <ESC><q>, so wird ein
+Thesaurus mit allen angekreuzten Namen geliefert; bei Verlassen mit <ESC><h>
+ein leerer Thesaurus. Beispiel: 
+ 
+ 
+PROC zeilen formatieren: 
+  TEXT CONST kopf          :: "Textdateien zeilenweise formatieren", 
+             hinweis       :: "Bitte gewünschte Dateien ankreuzen"; 
+  THESAURUS VAR dateinamen := menusome (ALL myself, kopf, hinweis,
+  FALSE); 
+  cursor on; 
+  formatiere dateien; 
+  cursor off; 
+  regenerate menuscreen. 
+ 
+  formatiere dateien: 
+    INT VAR zaehler; 
+    FOR zaehler FROM 1 UPTO highest entry (dateinamen) REP 
+      IF name (dateinamen, zaehler) <> "" 
+         THEN lineform (name (dateinamen, zaehler)) 
+      FI 
+    PER 
+END PROC zeilen formatieren; 
+ 
+ 
+ 
+#ib#5.5  Eingabe eines Textes/Namens - alternativ: Auswahl 
+     durch Ankreuzen#ie# ('#ib#menuanswerone#ie#','#ib#menuanswersome#ie#') 
+ 
+Sehr häufig kommt es vor, daß der Benutzer auf die zuletzt bearbeitete Datei zurück­
+greifen will. In Kapitel 5.3 haben wir dem Benutzer bei der Menufunktion 'Anse­
+hen/Ändern' gleich alle Dateien zur Auswahl angeboten. Hier wäre es vielleicht gün­
+stiger gewesen, ihm die zuletzt bearbeitete Datei anzubieten und erst auf Wunsch die
+Liste aller Dateien zum Ankreuzen. Das läßt sich auf verschiedene Weise realisieren -
+wir werden Ihnen in diesem und in den folgenden Kapiteln verschiedene Möglich­
+keiten aufzeigen: 
+ 
+Sie können z.B. mit der Prozedur 'menuanswerone' arbeiten. Wie Sie schon aus dem
+Namen entnehmen können, handelt es sich dabei um eine Prozedur, die eigentlich
+aus zwei Prozeduren, nämlich 'menuanswer' und 'menuone' zusammengesetzt ist. 
+Stellen Sie sich vor, sie führen den Namen der zuletzt bearbeiteten Datei in Ihrem
+Programm unter der Variablen 'letzte datei'. Dann könnte die Prozedur 'alte datei
+editieren' aus Kapitel 5.3 auch folgendermaßen geschrieben werden: 
+ 
+ 
+TEXT VAR letzte datei; 
+... 
+ 
+ 
+PROC alte datei editieren: 
+  TEXT CONST hinweis letzte :: "Zuletzt bearbeitete Datei:", 
+             kopf           :: "Textdatei ansehen/ändern", 
+             hinweis        :: "Bitte gewünschte Datei ankreuzen"; 
+  TEXT VAR   dateiname      :=  menuanswerone (hinweis letzte, 
+                                               letzte datei, 
+                                               ALL myself, kopf, 
+                                               hinweis, FALSE); 
+  IF dateiname <> "" 
+     THEN cursor on; 
+          edit (dateiname); 
+          letzte datei := dateiname; 
+          cursor off; 
+  FI; 
+  regenerate menuscreen 
+END PROC alte datei editieren; 
+ 
+ 
+Insgesamt hat die Prozedur 6 Parameter: Die ersten beiden Parameter beziehen sich
+auf die Eingabe ('menuanswer'). Wie dort kann auch hier der Text festgelegt werden,
+der in der Box auf dem Bildschirm erscheint. 
+Der zweite Parameter ist der Text, der dem Benutzer zum Editieren angeboten wird -
+hier der zuletzt benutzte Dateiname. Möchte der Benutzer auf die Datei mit dem an­
+gebotenen Namen zugreifen, braucht er nur mit <RETURN> zu bestätigen. 
+Möchte er die Auswahl zum Ankreuzen angeboten bekommen, so braucht er nur die
+Tastenfolge <ESC><z> (für 'Zeigen') zu tippen. Auf diese Auswahl beziehen sich
+die letzten 4 Parameter, die die gleiche Bedeutung haben wie bei der Prozedur
+'menuone'. Auf die Möglichkeit, durch <ESC><z> eine Auswahl angeboten zu
+bekommen, wird in der Fußzeile des Menus hingewiesen. 
+ 
+Aber Achtung! Sie sollten sich einer "Gefahr" bei diesem Vorgehen bewußt sein. Der
+Benutzer hat natürlich so die Möglichkeit, auch einen anderen Namen als den vorge­
+schlagenen anzugeben - einen Namen, der noch nicht in der Dateiliste enthalten ist.
+In einem solchen Falle würde Ihnen bei obiger Prozedur der Menubildschirm "ka­
+puttgeschrieben", denn das System fragt (bei eingeschaltetem Kommandodialog) an,
+ob eine Datei mit dem Namen eingerichtet werden soll. Für diesen Fall sollten Sie also
+unbedingt eine Vorsorge treffen (z.B. indem Sie den Benutzer darauf hinweisen, daß
+der eingegebene Name nicht akzeptiert wird)! 
+ 
+Sie vermuten sicher schon ganz richtig, daß es entsprechend auch die Prozedur
+'menuanswersome' gibt, die zunächst einen Dateinamen erfragt und auf Wunsch
+eine Auswahl anbietet, in der mehrere Dateinamen angekreuzt werden können. Die
+Prozedur hat ebenfalls 6 Parameter, die identisch zur Prozedur 'menuanswerone'
+sind. Allerdings liefert die Prozedur 'menuanswersome' in jedem Fall einen Thesau­
+rus; wurde die Auswahl mit <ESC><h> abgebrochen, so liefert sie einen leeren
+Thesaurus. 
+ 
+ 
+#ib# 5.6  Die Ja/Nein - Entscheidung#ie# ('#ib#menuyes#ie#','#ib#menuno#ie#') 
+ 
+In Kapitel 5.5 trat das Problem auf, daß der Benutzer einen "unzulässigen" Namen
+eingeben konnte. Dieses Problem können wir umgehen: Wir fragen den Benutzer ein­
+fach, ob er mit der zuletzt bearbeiteten Datei arbeiten will und lassen Ihm nur die
+Chance, mit 'Ja' oder 'Nein' zu antworten. Im ersten Fall bieten wir ihm eben diese
+Datei an - ansonsten die Auswahl zum Ankreuzen. 
+ 
+Hierfür stehen die Prozeduren 'menuyes' und 'menuno' zur Verfügung, die von Ihrer
+Funktion her den Ihnen bekannten Prozeduren 'yes' und 'no' gleichen. Die beiden
+Menu-Prozeduren haben jeweils zwei Parameter: 
+ 
+ 
+TEXT VAR letzte datei; 
+... 
+ 
+PROC alte datei editieren: 
+  TEXT CONST kopf    :: "Textdatei ansehen/ändern", 
+             hinweis :: "Bitte gewünschte Datei ankreuzen"; 
+  TEXT VAR dateiname; 
+  IF menuyes (" Wollen Sie mit der Datei "13"" + 
+              " '" +letzte datei+ "'"13" arbeiten", 5) 
+     THEN editiere letzte datei 
+     ELSE dateiname  :=  menuone (ALL myself, kopf, hinweis, FALSE); 
+          editiere ausgewaehlte datei 
+  FI; 
+  regenerate menuscreen. 
+ 
+  editiere letzte datei: 
+    cursor on; edit (letzte datei); cursor off. 
+ 
+  editiere ausgewaehlte datei: 
+    IF dateiname <> "" 
+       THEN cursor on; edit (dateiname); cursor off; 
+            letzte datei := dateiname 
+    FI 
+END PROC alte datei editieren; 
+ 
+ 
+Über den zweiten Parameter legen Sie die Position auf dem Bildschirm innerhalb des
+Menus fest (1, 2, 3, 4, 5; sehen Sie auch Kapitel 5.12). Der erste Parameter ist ein
+Text, welcher der gs-DIALOG-Syntax gehorchen muß (die Codes "13" bewirken
+einen Zeilenvorschub; sehen Sie auch Kapitel 5.13). Er wird in einer Box auf den
+Bildschirm geschrieben und durch 'Ja  Nein' ergänzt: 
+ 
+ 
+          +-----------------------------+ 
+          I                             I 
+          I   Wollen Sie mit der Datei  I 
+          I   'Dateiname'               I 
+          I   arbeiten?                 I 
+          I                             I 
+          I          Ja    Nein         I 
+          I                             I 
+          +-----------------------------+ 
+ 
+Für 'Dateiname' ist auf Ihrem Bildschirm dann natürlich der aktuelle Inhalt von
+'letzte datei' eingetragen. 
+Die Prozedur 'menuyes' liefert TRUE, wenn mit 'Ja' geantwortet wurde und FALSE,
+wenn mit 'Nein' geantwortet wurde. Die Prozedur 'menuno' wirkt wie 'NOT menuyes'.
+Nach Eingabe von 'Ja', 'Nein' (durch Tippen der Anfangsbuchstaben oder Positionie­
+rung auf die Antwort und anschließendem <RETURN>) wird der Menubildschirm
+automatisch regeneriert. Auch die entsprechenden Hinweise in der Fußzeile werden
+natürlich automatisch gesetzt. 
+ 
+ 
+#ib#5.7  Die Alternativentscheidung#ie# ('#ib#menualternative#ie#') 
+ 
+Im letzten Kapitel haben wir Ihnen die Prozeduren 'menuyes' und 'menuno' in Ihrer
+Wirkungsweise erläutert. Eigentlich sind die beiden Prozeduren nur ein (häufig
+benötigter) Spezialfall der Prozedur 'menualternative'. Die Funktionsweise der Proze­
+dur 'menualternative' dürfte Ihnen schon aus dem 'Archivmenu' bekannt sein: Wenn
+Sie eine neue Zieltask einstellen, werden Ihnen nämlich vier Alternativen zur Auswahl
+angeboten (Archiv, Vatertask, PUBLIC, Sonstige Task). 
+Auf unsere Textverarbeitung bezogen könnten wir z.B. vor der Zeilenformatierung
+(lineform) über die Alternativentscheidung den gewünschten Schrifttyp abfragen. Wir
+wollen dem Benutzer in diesem Beispiel fünf Schrifttypen (schmal, elite, pica, letter,
+groß) zur Auswahl anbieten: 
+ 
+ 
+ 
+TEXT VAR schrifttyp; 
+... 
+ 
+PROC schrifttyp waehlen: 
+  TEXT CONST info :: "        Auswahl der Schrifttypen: "13""13"" 
+                   + "    s ... schmal (17 Zeichen pro Zoll) "13"" 
+                   + "    e ... elite  (12 Zeichen pro Zoll) "13"" 
+                   + "    p ... pica   (10 Zeichen pro Zoll) "13"" 
+                   + "    l ... letter (Proportionalschrift) "13"" 
+                   + "    g ... groß   ( 5 Zeichen pro Zoll)   ", 
+ 
+           liste  :: "schmal"13"elite"13"pica"13"letter"13"groß", 
+           tasten :: "seplgSEPLG"; 
+ 
+  INT VAR auswahl := menualternative (info, liste, tasten, 5, TRUE); 
+  SELECT auswahl OF 
+     CASE 1, 101, 106: schrifttyp := "17" 
+     CASE 2, 102, 107: schrifttyp := "12" 
+     CASE 3, 103, 108: schrifttyp := "10" 
+     CASE 4, 104, 109: schrifttyp := "prop" 
+     CASE 5, 105, 110: schrifttyp := "5" 
+     OTHERWISE (* behalte alten Schrifttyp bei *) 
+  END SELECT 
+END PROC schrifttyp waehlen; 
+ 
+ 
+Hätten wir diese Prozedur in unsere Prozedur 'zeilen formatieren' eingebunden, so
+zeigte sich bei Aktivierung folgende Einblendung in den Menubildschirm: 
+ 
+ 
+ 
+    +---------------------------------------+ 
+    I                                       I 
+    I       Auswahl der Schrifttypen:       I 
+    I                                       I 
+    I   s ... schmal (17 Zeichen pro Zoll)  I 
+    I   e ... elite  (12 Zeichen pro Zoll)  I 
+    I   p ... pica   (10 Zeichen pro Zoll)  I 
+    I   l ... letter (Proportionalschrift)  I 
+    I   g ... groß   ( 5 Zeichen pro Zoll)  I 
+    I                                       I 
+    I schmal   elite   pica   letter   groß I 
+    I                                       I 
+    +---------------------------------------+ 
+ 
+Die Prozedur 'menualternative' besitzt insgesamt 5 Parameter. Wie Ihnen schon von
+von anderen Prozeduren bekannt ist, wird mit dem vorletzten (4.) Parameter die
+Position innerhalb des Menubildschirms bestimmt - hier also die Plazierung in die
+Mitte des Menubildschirms. 
+Mit dem 5. Parameter können Sie noch festlegen, ob der Benutzer die Möglichkeit
+haben soll, die Alternativauswahl mit <ESC><h> abzubrechen (bei TRUE, wie im
+Beispiel) oder eben nicht. 
+ 
+Mit dem 1. Parameter wird der Informationstext festgelegt, der auf dem Bildschirm
+innerhalb der Box erscheinen soll. Für die Funktion der Alternativauswahl ist die­
+ser Inhalt völlig belanglos - er dient ausschließlich der Information des Benutzers.
+Der Text kann - wie hier - z.B. durch eine Einteilung in Zeilen gestaltet werden
+(durch den Code "13"). 
+Der Text in den Zeilen sollte nicht zu breit sein, da er noch in eine Box innerhalb des
+Menubildschirms hineinpassen muß! Damit es auch bei geschachtelten Menus zu
+keinen Problemen kommt, sollte eine Zeile nicht breiter als 64 Zeichen sein. Aber
+keine Angst: Sie können gs-DIALOG durch zu lange Texte nicht durcheinanderbrin­
+gen - wenn Ihr Text zu breit ist, wird er rigoros abgeschnitten und einfach nicht
+angezeigt. 
+ 
+Mit dem 2. Parameter übergeben Sie die Auswahlliste, die in der letzten Zeile der Box
+dargestellt wird. Hier dürfen insgesamt bis zu 10 Alternativen angegeben werden -
+bedenken Sie dabei aber unbedingt, daß diese Liste ebenfalls nicht zu lang werden
+darf (ebenfalls höchstens 64 Zeichen). 
+Zwischen jeder von Ihnen notierten Alternative muß zur Kennung der Code "13"
+eingetragen werden - wie oben im Beispiel gezeigt. Da nachher in der Box zwischen
+den einzelnen Alternativen je drei Leerzeichen eingefügt werden, können Sie sich
+immer an der von Ihnen übergebenen Zeichenkette orientieren. Hat Ihre Auswahlliste
+nicht mehr als 64 Zeichen, dann ist sie in jedem Falle auf dem Bildschirm darstell­
+bar. 
+Über diese Auswahlliste erfolgt normalerweise die Auswahl. Mit den Cursortasten links
+und rechts kann der Benutzer auf die gewünschte Alternative positionieren (auf dem
+Bildschirm invers dargestellt) und dann die <RETURN>-Taste tippen. 
+Die Prozedur 'menualternative liefert dann einen Zahlenwert, nämlich die Position
+der gewählten Alternative in der als 2. Parameter übergebenen Liste (wird in unse­
+rem Beispiel die Alternative 'letter' gewählt, so liefert die Prozedur den Wert 4).
+Haben Sie den Abbruch durch <ESC><h> zugelassen (5. Parameter), so wird im
+Falle eines solchen Abbruchs der Wert '0' geliefert. 
+ 
+Mit dem 3. Parameter können Sie noch festlegen, über welche Tasten eine Auswahl
+erfolgen soll. Wenn Sie hier niltext ("") angeben, ist eine Auswahl über die Tasten
+nicht möglich. Im Beispiel haben wir hier die Anfangsbuchstaben der im Text ge­
+nannten Schrifttypen gewählt und als Eingabe sowohl Klein- als auch Großbuchsta­
+ben gestattet. Erfolgt nun die Auswahl über das Tippen einer zugelassenen Taste,
+dann wird Ihre Position in der im 3. Parameter übergebenen Zeichenkette ermittelt
+und der Wert '100' dazuaddiert. Tippt in unserem Falle der Benutzer die Taste
+<L>, wird der Wert '109' geliefert. 
+ 
+Es erfolgt übrigens kein Hinweis in der Fußzeile, ob eine Auswahl über das Tippen
+einer Taste möglich ist! Wenn Sie von der Möglichkeit Gebrauch machen, sollten Sie
+dieses durch die Gestaltung Ihres Informationstextes andeuten - wie wir es im Bei­
+spiel auch getan haben. 
+ 
+ 
+#ib#5.8  Die Menunotiz#ie# ('#ib#write menunotice#ie#', '#ib#erasemenunotice#ie#') 
+ 
+Innerhalb des Menus können Sie für den Benutzer auch eine Notiz ablegen. Wir
+machen z.B. bei der Archivverwaltung Gebrauch davon. Dort wird nämlich ständig
+angezeigt, mit welcher Task kommuniziert wird und - sofern es sich um einen Ar­
+chivmanager handelt - wie die (angemeldete) Diskette heißt. Wenn Sie z.B. dem
+Benutzer das aktuelle Datum im Menu anzeigen wollen, insertieren Sie die folgende
+Prozedur: 
+ 
+ 
+PROC datum anzeigen: 
+  write menunotice ("Datum: " + date, 4) 
+END PROC datum anzeigen; 
+ 
+ 
+Die Prozedur 'write menunotice' besitzt zwei Parameter. Mit dem ersten Parameter
+wird der Text übergeben, der in der Box ausgegeben werden soll. Er unterliegt eben­
+falls der gs-DIALOG-Syntax für Texte. Durch den zweiten Parameter wird wieder die
+Position innerhalb des Menus festgelegt (hier rechts unten: Position 4). 
+ 
+Wenn Sie jetzt in Ihrer Menukarte die Prozedur 'oberbegriff  ("Bearbeiten")' in fol­
+gender Weise abändern: 
+ 
+ 
+   oberbegriff ("Bearbeiten", "datum anzeigen", "erase menunotice") 
+ 
+ 
+dann wird jedesmal, wenn das Pull-Down-Menu unter dem Oberbegriff 'Bearbeiten'
+aufgefaltet wird, unten rechts (Position 4) das aktuelle Datum in einer Box ange­
+zeigt. Diese Notiz verschwindet, wenn in ein anderes Pull-Down-Menu gewechselt
+wird. 
+ 
+Auf den ersten Eindruck scheinen die Prozeduren 'write menunotice' und 'menuinfo'
+gleich zu sein - das ist aber nicht der Fall: Bei 'menuinfo' wird der Text in einer Box
+ausgegeben und so lange gewartet, bis der Benutzer eine Taste getippt hat (oder die
+angegebene Zeit verstrichen ist). Bei 'write menunotice' wird ebenfalls ein Text in
+einer Box auf den Menubildschirm geschrieben. Diese Box bleibt aber über längere
+Zeit bestehen (auf Erscheinen und Verschwinden kann der Benutzer selbst keinen
+Einfluß nehmen!) - und zwar solange, bis die Notiz gelöscht wird (mit 'erase menu­
+notice'; in unserem Beispiel, wenn das Pull-Down-Menu gewechselt wird) oder durch
+ein neues 'write menunotice' überschrieben wird. In einem Menu kann nämlich zu
+einem Zeitpunkt nur eine Menunotiz abgelegt werden. 
+Wenn der Bildschirm durch gs-DIALOG-Prozeduren überschrieben wird, wird die
+Menunotiz ebenfalls ständig mitaufgefrischt, und auch, wenn Sie den Befehl 'regene­
+rate menuscreen' oder 'refresh submenu' geben. 
+ 
+ 
+#ib#5.9  Fußzeilen im Menu#ie# ('#ib#menufootnote#ie#', '#ib#oldmenufootnote#ie#') 
+ 
+In den Fußzeilen innerhalb des Menus werden dem Benutzer Bedienhinweise ange­
+zeigt. Die Fußzeile wird aber auch dazu benutzt, den Benutzer über Prozesse zu
+informieren, die im Hintergrund ablaufen - erst recht dann, wenn Sie einige Zeit in
+Anspruch nehmen. Sie zeigen dem Benutzer an, daß er nicht "unruhig" zu werden
+braucht, sondern das System "mit sich" beschäftigt ist. 
+Im allgemeinen braucht sich der Programmierer um diese Fußnoten nicht zu küm­
+mern, denn sie werden von den einzelnen Komponenten des Systems automatisch
+gesetzt. Wir können aber z.B. dem Benutzer einen Hinweis geben, wenn unter dem
+Menupunkt 'Verzeichnis' eine Liste erstellt wird. Die Prozedur könnte dann folgen­
+dermaßen notiert werden: 
+ 
+ 
+PROC verzeichnis ausgeben: 
+  menufootnote ("Bitte warten... Ich erstelle eine Dateiliste"); 
+  FILE VAR f :: sequential file (output, "Dateiliste"); 
+  list (f); modify (f); 
+  old menufootnote; 
+  entferne eigenen namen; 
+  zeige liste an; 
+  forget ("Dateiliste", quiet). 
+ 
+  entferne eigenen namen: 
+    TEXT VAR zeile :: ""; INT VAR i; 
+    FOR i FROM lines (f) DOWNTO 1 REP 
+      to line (f, i); 
+      read record (f, zeile); 
+    UNTIL pos (zeile, "Dateiliste") > 0 PER; 
+    delete record (f). 
+ 
+  zeige liste an: 
+    to line (f, 1); 
+    menuwindowshow (f)         (* Sehen Sie Kapitel 5.11.1*) 
+END PROC verzeichnis ausgeben; 
+ 
+ 
+Beachten Sie, daß der Text nicht länger als 64 Zeichen ist, damit er auch bei ge­
+schachtelten Menus vollständig ausgegeben werden kann. Sollte der Text dennoch zu
+lang sein, wird er vom System auf die entsprechende Länge gestutzt. 
+Haben Sie mit 'menufootnote' eine eigene Fußzeile gesetzt, so können Sie die da­
+durch gelöschte Zeile durch den Befehl 'old menufootnote' wieder hinschreiben.
+Ansonsten wird Ihre Fußzeile von der nächsten automatisch (d.h. vom System) ge­
+setzten Fußnote überschrieben. In dem obigen Beispiel hätten Sie also gut auf den
+Befehl 'old menufootnote' verzichten können. 
+ 
+Durch 'old menufootnote' wird die letzte Fußnote, die automatisch vom System ge­
+setzt wurde, reproduziert. Der in der obigen Prozedur verwendete Befehl 'menuwin­
+dowshow' ist bisher noch nicht erläutert. Sehen Sie dazu bitte das Kapitel 5.11.1. 
+ 
+ 
+#ib#5.10  Wiederherstellung des Menubildschirms#ie# ('#ib#regenerate
+      menuscreen#ie#','#ib#refresh submenu#ie#') 
+ 
+Der Befehl 'regenerate menuscreen' ist Ihnen schon aus diversen Beispielprogram­
+men dieses Handbuches bekannt. Ist der Menubildschirm "kaputtgeschrieben" oder
+der Bildschirm für andere Zwecke benutzt worden, so läßt sich durch diesen Befehl
+der Menubildschirm in seinem letzten Zustand reproduzieren (auch bei geschachtel­
+ten Menus!). Durch den Befehl wird der Bildschirm gelöscht und komplett neu
+aufgebaut. 
+ 
+Ein vollständiger Bildschirmaufbau ist aber gar nicht immer nötig. Wenn Sie sicher
+sind, daß durch Ihre Operationen nur der Bereich zwischen den beiden durchgezo­
+genen Linien, die die Kopf- und Fußzeile abtrennen, betroffen ist, brauchen Sie nur
+den Befehl 'refresh submenu' zu geben. Hierdurch wird das aktuelle Pull-Down-
+Menu neu aufgebaut und - sofern gesetzt - die Menunotiz. Wenn möglich, ist er dem
+Befehl 'regenerate menuscreen vorzuziehen, da hierfür weniger Zeit benötigt wird
+und weniger "Unruhe" auf dem Bildschirm entsteht. 
+Sorgen Sie aber unbedingt dafür, daß der von Ihnen benutzte Bildschirmbereich
+zuvor "gereinigt" wird, denn das besorgt 'refresh subnmenu' nicht! 
+ 
+ 
+#ib#5.11  Arbeiten im Menufenster#ie# 
+ 
+Neben den vorab aufgezeigten Möglichkeiten können Sie innerhalb des Menus auch
+noch ein Fenster öffnen. Innerhalb dieses Fensters stehen Ihnen alle Möglichkei­
+ten zur Verfügung, die Sie auch sonst zum Beschreiben des gesamten Bildschirms
+haben - und noch einiges mehr. 
+Wir machen z.B. intensiv beim Archivhandling Gebrauch davon. So werden Ihnen
+Verzeichnisse angezeigt, Sie können verfolgen, wie die einzelnen Dateien vom Archiv
+geholt werden oder dorthin geschrieben werden und einiges mehr. In diesem Kapitel
+wollen wir Ihnen die Möglichkeiten aufzeigen, die Sie innerhalb des Menufensters
+haben. 
+ 
+Auf die Größe des Menufensters haben Sie keinen Einfluß, sie wird vom System ge­
+setzt ("normales" Menu: 77 Zeichen breit und 20 Zeichen hoch; geschachteltes
+Menu: 71 Zeichen breit und 16 Zeichen hoch). Hierdurch ist sichergestellt, daß alle
+Operationen auch in geschachtelten Menus ohne Probleme ausführbar sind. Alle
+Prozeduren, die sich auf Aktionen im Menufenster beziehen, enthalten die Silbe
+'menuwindow'. 
+Sie können mit den hier beschriebenen Prozeduren ähnlich arbeiten, wie mit den
+entsprechenden Prozeduren ohne den Wortbestandteil 'menuwindow' auf dem
+ganzen Bildschirm. Allerdings gibt es einige Unterschiede, auf die Sie achten sollten! 
+ 
+ 
+5.11.1  Datei anzeigen/editieren 
+        ('#ib#menuwindowshow#ie#', '#ib#menuwindowedit#ie#') 
+ 
+Von der Prozedur 'menuwindowshow (FILE VAR f)' haben wir im letzten Kapitel
+schon Gebrauch gemacht, um das Verzeichnis der Dateien in der Task innerhalb des
+Menus anzuzeigen. Die Prozedur gibt es in zwei Versionen mit je einem Parameter. 
+Einmal kann, wie im vorigen Kapitel, ein FILE angegeben werden, andererseits kann
+auch der Name der anzuzeigenden Datei als Text übergeben werden ('menuwindow­
+show (TEXT CONST dateiliste)'). Durch den Befehl wird innerhalb des Menus ein
+umrandetes Fenster geöffnet, in der das angegebene File/die Datei angezeigt wird. Bei
+'menuwindowshow' kann die Datei nur eingesehen, nicht aber schreibend verändert
+werden. 
+Die Prozedur 'menuwindowedit' gibt es ebenfalls in den zwei Ausprägungen. Sie
+verhält sich zur vorgenannten identisch - nur kann hier auch die Datei schreibend
+verändert werden. 
+ 
+ 
+5.11.2  Menufenster öffnen/anzeigen ('#ib#show menuwindow#ie#') 
+ 
+Wenn Sie eigene Operationen in einem Fenster im Menu ausführen lassen wollen,
+muß dieses Fenster zunächst auf dem Bildschirm angezeigt werden. Durch den
+Befehl 'show menuwindow' wird ein entsprechender Rahmen innerhalb des Menus
+ausgegeben und der Bereich innerhalb dieses Rahmens (das Fenster) gelöscht. 
+Auf die Größe des Fensters innerhalb des aktuellen Menus können Sie - wie bereits
+eingangs gesagt - keinen Einfluß nehmen. 
+Zu einem Zeitpunkt kann immer nur ein Menufenster geöffnet sein, da das Fenster
+schon den größtmöglichen sinnvollen Bereich des aktuellen Menus belegt. Ein er­
+neutes 'show menuwindow' hätte die gleiche Wirkung wie das nachfolgend beschrie­
+bene 'menuwindowpage' - nur wird hier zusätzlich noch der Rahmen des Fensters
+mitausgegeben. 
+ 
+ 
+5.11.3  Menufenster löschen (putzen) ('#ib#menuwindowpage#ie#') 
+ 
+Durch den Befehl 'menuwindowpage' wird das Fenster innerhalb des aktuellen
+Menus gelöscht; der Rahmen des Fensters bleibt bestehen, da er nicht mit zum ei­
+gentlichen Fenster gehört. Durch den Befehl wird der Menubildschirm nicht(!)
+rekonstruiert! 
+ 
+ 
+5.11.4  Positionierungen im Menufenster 
+        ('#ib#menuwindowline#ie#', '#ib#menuwindowcursor#ie#') 
+ 
+Mit 'menuwindowline' wird, wie auch sonst auf dem Bildschirm, an den Anfang der
+nächsten Zeile positioniert. Diesen Befehl gibt es, ebenso wie den Befehl 'line' (der
+auf dem Gesamtbildschirm operiert) ohne und mit einem Parameter. Durch 'menu­
+windowline (3)' wird an den Anfang der "drittnächsten" Zeile innerhalb des Menu­
+fensters positioniert. 
+ 
+Aber Achtung! Der Befehl 'menuwindowline' weist einen deutlichen Unterschied zum
+Ihnen bekannten Befehl 'line' auf. Wird nämlich die untere Fenstergrenze überschrit­
+ten, so rollt (scrollt) der Bildschirm nicht um die entsprechenden Zeilen nach oben,
+wie Sie es von 'line' gewohnt sind - statt dessen wird der Fensterinhalt gelöscht und
+wieder oben im Fenster zu schreiben begonnen. Es erscheint, als ob auf ein neues
+Fenster positioniert würde. 
+Innerhalb des Fensters können Sie auch den Cursor positionieren, wie Sie es vom
+Bildschirm gewohnt sind - allerdings nur innerhalb der aktuell gültigen Grenzen. In
+einem Menu ist das Fenster 77 Zeichen breit und 20 Zeichen hoch; in einem ge­
+schachtelten Menu 71 Zeichen breit und 16 Zeichen hoch. 
+Wird außerhalb des aktuellen Menufensters positioniert, wird das Fenster gelöscht
+und die Fensterposition (1, 1) angenommen. 
+ 
+ 
+5.11.5  Informationen über die aktuelle Menu-Fenster position ('#ib#get
+menuwindowcursor#ie#', '#ib#remaining menuwindowlines#ie#') 
+ 
+Mit der Prozedur 'get menuwindowcursor (INT VAR spalte, zeile)' kann die aktuelle
+Position des Cursors innerhalb des Menufensters erfragt werden. Die Prozedur hat
+zwei Parameter, die als 'INT VAR' deklariert sein müssen. Der erste Parameter enthält
+anschließend die aktuelle Spalte, der zweite die aktuelle Zeile. 
+ 
+Mit der werteliefernden Prozedur 'remaining menuwindowlines' kann die Anzahl der
+noch verbleibenden Zeilen innerhalb des aktuellen Menufensters erfragt werden. Die
+Prozedur wurde deshalb zur Verfügung gestellt, weil der Fensterinhalt - im Gegensatz
+zum normalen Bildschirm - nicht gescrollt werden kann. So können Sie sich vorab
+informieren, ob der Text, der von Ihnen ausgegeben werden soll, noch Platz findet, so
+daß während der Ausgabe nicht plötzlich der Fensterinhalt gelöscht wird. 
+ 
+ 
+5.11.6  Ausgabe/Eingabe innerhalb des Menufensters 
+        ('#ib#menuwindowout#ie#', '#ib#menuwindowget#ie#', 
+         '#ib#menuwindoweditget#ie#', '#ib#menuwindowyes#ie#', 
+         '#ib#menuwindowno#ie#') 
+ 
+Innerhalb des Menufensters können mit der Prozedur 'menuwindowout' Texte ausge­
+geben werden - die Prozedur hat einen TEXT-Parameter. Sollen INTEGER- oder REAL-
+Werte ausgegeben werden, so müssen diese Werte zuerst in Texte konvertiert werden. 
+Bitte beachten Sie unbedingt, daß innerhalb des Fensters nicht gescrollt wird und
+auch kein Zeilenumbruch stattfindet! Ist ein Text länger als die verbleibende Restzei­
+le, so wird der Text bis zum Fensterende ausgegeben und die Ausgabe am Anfang der
+nächsten Zeile fortgesetzt. So ist sichergestellt, daß in keinem Falle die Fenstergren­
+zen überschritten werden. 
+Sobald die letzte Position des aktuellen Menufensters beschrieben ist (unten rechts in
+der Fensterecke), wird der Fensterinhalt komplett gelöscht und die Ausgabe in der
+ersten Zeile des "neuen" Fensters fortgesetzt. Auf Zeilenumbruch und Scrolling wurde
+verzichtet, da der Realisierungsaufwand dafür zu hoch gewesen wäre. 
+ 
+Mit der Prozedur 'menuwindowget (TEXT VAR text)' können Sie auch Texte innerhalb
+des Menufensters einlesen - INTEGER-/ REAL-Werte müssen ggf. von Hand konvertiert
+werde. Die Eingabe wird durch <RETURN> abgeschlossen. Es muß mindestens ein
+Zeichen (ungleich Leerzeichen) eingegeben werden. Von der Eingabe werden die
+führenden Leerzeichen abgeschnitten. 
+Ist der einzugebende Text länger als die noch verbleibende Restzeile, so wird der Text
+in der Restzeile gescrollt. Sind in der aktuellen Zeile weniger als 7 Zeichen für die
+Eingabe vorhanden, so wird automatisch für die Eingabe an den Anfang der nächsten
+Zeile positioniert. 
+ 
+Ab gs-DIALOG-Version 1.1 steht auch die Prozedur 'menuwindoweditget (TEXT VAR
+text)' zur Verfügung, durch die ein Text zum Editieren vorgegeben werden kann. Es
+ist allerdings darauf zu achten, daß der Text in jedem Falle initialisiert wird! 
+ 
+Die beiden Prozeduren 'menuwindowyes' und 'menuwindowno' ähneln den Ihnen
+bekannten Prozeduren 'yes' und 'no'. Sie operieren nur auf dem Menufenster. Be­
+denken Sie aber bitte, daß, wenn bei der Ausgabe des Textes die Fenstergrenze über­
+schritten wird, der Resttext in der nächsten Zeile ausgegeben wird. Wird dabei sogar
+die untere Fenstergrenze überschritten, so wird der komplette Fensterinhalt gelöscht
+und die Ausgabe in der linken oberen Ecke des "neuen Fensters" fortgesetzt! 
+ 
+ 
+5.11.7  Weiter Prozeduren  ('#ib#menuwindowcenter#ie#', 
+                            '#ib#menuwindowstop#ie#') 
+ 
+Es werden noch zwei weitere Prozeduren für das Menufenster zur Verfügung gestellt,
+die bei der Programmentwicklung ganz nützlich sein können. 
+Mit 'menuwindowcenter (TEXT CONST text)' werden vor und hinter dem übergebe­
+nen Text so viele Leerzeichen angefügt, daß der Text zentriert in der Menufenster-Zei­
+le ausgegeben wird. Bevor Sie den Text mit 'menuwindowout' ausgeben, müssen Sie
+an den Anfang einer Zeile positionieren, denn die Anzahl der vorangestellten Blanks
+wird unter Annahme dieser Zeilenposition ermittelt! Innerhalb der Zeile werden ggf.
+vorhandene Texte überschrieben. 
+ 
+Durch die Prozedur 'menuwindowstop' wird an den Anfang der übernächsten Zeile
+positionert und der Text 'Zum Weitermachen bitte irgendeine Taste tippen!' ausgege­
+ben. Danach wird so lange gewartet, bis eine Taste getippt wird. Mit 'menuwindow­
+stop (INT CONST zeilenzahl) kann auch noch die Anzahl der Zeilen bestimmt wer­
+den, die vorwärtspositioniert werden soll (Standard: 2 Zeilen). 
+ 
+ 
+#ib#5.12  Festlegung der Boxpositionen innerhalb des Menus#ie# 
+ 
+In vielen Fällen kann der Programmierer noch entscheiden, an welcher Position
+innerhalb des Menus die Box erscheinen soll (z. B. bei 'menuanswer', 'menuinfo',
+'menuyes', 'menuno', 'menunotice' etc.). Die Positionen sind von 1 bis 5 durchnu­
+meriert und haben folgende Bedeutung: 
+ 
++----------------------------------------+ 
+I                                        I 
++----------------------------------------+ 
+I                                        I 
+I   +-----+                   +-----+    I 
+I   I  1  I                   I  2  I    I 
+I   +-----+                   +-----+    I 
+I                                        I 
+I                +-----+                 I 
+I                I  5  I                 I 
+I                +-----+                 I 
+I                                        I 
+I   +-----+                   +-----+    I 
+I   I  3  I                   I  4  I    I 
+I   +-----+                   +-----+    I 
+I                                        I 
++----------------------------------------+ 
+I                                        I 
++----------------------------------------+ 
+#page# 
+#ib#5.13 gs-DIALOG-Syntax (Regeln zur Erstellung von Texten)#ie# 
+ 
+Werden Texte als Parameter übergeben, die in einer Box ausgegeben werden sollen,
+so kann dieser Text durch Einfügen von Steuerzeichen noch gestaltet werden, z.B.
+kann der Programmierer so den Zeilenaufbau bestimmen. 
+Das System analysiert den eingegebenen Text. Jedesmal, wenn innerhalb des Textes
+der Code "13" erscheint, wird innerhalb der Box auf den nächsten Zeilenanfang
+positioniert. So ist eine Einteilung eines Textes in Zeilen leicht möglich. Soll eine
+Leerzeile eingefügt werden, so geben Sie einfach zweimal den Code "13" ("13""13"). 
+Bei der Textanalyse wird die jeweilige Zeilenlänge vermerkt. Die Box wird vom System
+gerade so breit gewählt, daß die längste vorkommende "Zeile" im Text gerade noch in
+die Box paßt. 
+Aber Vorsicht! Die jeweilige Box kann innerhalb des Menus nur eine Maximalgröße
+annehmen (64 Zeichen breit und 14 Zeilen hoch). Wird von einer "Zeile" diese
+Maximalgröße überschritten, so wird die Zeile abgeschnitten und nur bis zur Maxi­
+malbreite der Box ausgegeben. 
+ 
+Ein Text für eine solche Box könnte z.B. so aussehen: 
+ 
+ 
+menuinfo ("  Informationstexte  "13"      sind meist"13"       zu
+lang!") 
+ 
+ 
+das ergibt folgende Ausgabe in der Box: 
+ 
+ 
+           +-----------------------+ 
+           I                       I 
+           I   Informationstexte   I 
+           I       sind meist      I 
+           I        zu lang        I 
+           I                       I 
+           +-----------------------+ 
+ 
+Es ist auch möglich, in solchen Texten Textpassagen invers darzustellen. Dazu wer­
+den in den Text die Codes zum Ein- ("15") und Ausschalten ("14") der Markierung
+eingefügt. Solche markierten Textpassagen dürfen aber nicht über interne Zeilen­
+grenzen (Code "13") hinausgehen. Sie müßten dann am Zeilenende aus- und am
+nächsten Zeilenanfang wiedereingeschaltet werden. 
+Soll in der obigen Box das Wort 'Informationstexte' invers dargestellt werden, so wäre
+z.B. folgendes Kommando zu geben: 
+ 
+ 
+menuinfo (" "15"Informationstexte"14" "13"" + 
+          "      sind meist"13"       zu lang!") 
+ 
+ 
+#ib#5.14  Thesaurushandling#ie# 
+ 
+Neben den allgemein zur Verfügung gestellten Thesaurusoperationen stellt
+gs-DIALOG einige weitere bereit. Mit der Prozedur 'THESAURUS PROC #ib#infix namen#ie#
+(THESAURUS CONST thes, TEXT CONST infix)' werden aus allen Dateinamen des
+angegebenen Thesaurus die herausgefiltert, die den Wortbestandteil 'infix' enthalten -
+und zwar gleichgültig, an welcher Position! Die herausgefilterten Dateinamen werden
+in einem Thesaurus geliefert. Im Programmsystem 'gs-Herbert und Robbi' mach­
+en wir z.B. Gebrauch davon, wenn wir nur die Landschaften der eigenen Task zur
+Auswahl anbieten wollen: 
+ 
+ 
+THESAURUS VAR thes :: infix namen (ALL myself, "Flaeche:") 
+ 
+ 
+Daneben gibt es eine ähnliche Prozedur, mit der man die Dateien eines bestimmten
+Dateityps herausfiltern kann. Mit 
+ 
+ 
+THESAURUS VAR thes :: infix namen (ALL myself, 1003) 
+ 
+ 
+werden alle Dateien mit dem Typ '1003' (normale Textfiles) herausgefiltert. Neben
+den beiden gibt es auch noch eine Prozedur, die beide Fälle miteinander koppelt: 
+ 
+ 
+THESAURUS VAR thes :: infix namen (ALL myself, "gs-MENUKARTE:", 1954) 
+ 
+ 
+Mit der folgenden Prozedur: 
+ 
+ 
+THESAURUS VAR thes :: #ib#ohne praefix#ie# (ALL myself, "Flaeche:") 
+ 
+ 
+wird aus den Dateinamen im angegebenen Thesaurus jeweils der führende Wortbe­
+standteil entfernt. Wir machen z.B. in gs-Herbert und Robbi davon Gebrauch, um
+die Landschaften/Arbeitsfelder anbieten zu können, ohne jeweils den Wortbestandteil
+'Flaeche:' miterscheinen zu lassen. 
+ 
+Ganz nützlich ist auch noch die folgende Informationsprozedur '#ib#not empty#ie#
+(THESAURUS CONST thes)', mit der man z.B. feststellen kann, ob eine Auswahl ohne
+Ankreuzen oder mit <ESC><h> abgebrochen wurde: 
+ 
+ 
+ 
+PROC zeilen formatieren: 
+  TEXT CONST kopf          :: "Textdateien zeilenweise formatieren", 
+             hinweis       :: "Bitte gewünschte Dateien ankreuzen"; 
+  THESAURUS VAR dateinamen := menusome (ALL myself, kopf, hinweis,
+  FALSE); 
+ 
+  IF not empty (dateinamen) 
+     THEN cursor on; 
+          formatiere dateien; 
+          cursor off; 
+  FI; 
+  regenerate menuscreen. 
+ 
+  formatiere dateien: 
+    INT VAR zaehler; 
+    FOR zaehler FROM 1 UPTO highest entry (dateinamen) REP 
+      IF name (dateinamen, zaehler) <> "" 
+         THEN lineform (name (dateinamen, zaehler)) 
+      FI 
+    PER 
+END PROC zeilen formatieren; 
+ 
+ 
+ 
+#ib#5.15  Aktivieren und Deaktivieren von Menupunkten#ie# 
+ 
+Daß Verarbeitungsfunktionen aktiviert und deaktiviert werden können, haben Sie
+schon in unserem Archiv-Pull-Down-Menu gesehen. Deaktivierte Menupunkte sind
+durch ein vorgestelltes '-'-Zeichen gekennzeichnet; diese Menufunktionen werden
+übersprungen, wenn Sie versuchen, darauf zu positionieren. 
+ 
+Zur Aktivierung und Deaktivierung von Menupunkten stehen die Prozeduren '#ib#activate#ie#
+(TEXT CONST menupunktname)' und '#ib#deactivate#ie# (TEXT CONST menupunktname)'
+zur Verfügung. Zu beachten ist, daß diese Prozeduren nicht ständig aufrufbar sind -
+der jeweils angegebene 'menupunktname' muß sich nämlich auf das aktuelle Pull-
+Down-Menu beziehen! Als Menupunktname muß jeweils der Name angegeben wer­
+den, der bei der entsprechenden Menufunktion als 2. Parameter übergeben wurde.
+Ist der angegebene 'menupunktname' im aktuellen Pull-Down-Menu nicht enthalten,
+so wird die Anweisung ignoriert! 
+ 
+Auch bei den Prozeduren' activate (INT CONST punktnummer)' und 'deactivate (INT
+CONST punktnummer)' gilt diese Einschränkung. Die beiden Prozeduren arbeiten
+schneller als die eben aufgezeigten, denn es muß im aktuellen Pull-Down-menu
+nicht mehr nach der jeweiligen Position gesucht werden. Die Positionen werden von
+oben nach unten durchgezählt. Beachten Sie aber unbedingt, daß die Trennlinien
+mitgezählt werden müssen! 
+Die Prozeduren "zeigen nur dann Wirkung", wenn sie von einer Verarbeitungsfunk­
+tion des aktuell entfalteten Pull-Down-Menus aus aufgerufen werden (das geschieht
+im Archivmenu z.B. aus den beiden Menufunktionen 'Reservieren' und 'Initialisieren'
+heraus) oder wenn Sie beim Einstieg in ein Pull-Down-Menu bzw. beim Ausstieg
+daraus aufgerufen werden; d.h. aus einer Prozedur heraus, die bei 'oberbegriff' als
+2./3. Parameter in das Menukarten-Generierungsprogramm eingetragen ist. Beim
+Archiv-Pull-Down-Menu besorgt das die Prozedur 'menu archiv grundeinstellung'
+(sehen Sie dazu auch Kapitel 6.1). 
+ 
+
diff --git a/doc/menugenerator/menu-generator handbuch.6 b/doc/menugenerator/menu-generator handbuch.6
new file mode 100644
index 0000000..a0dd3b5
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.6	
@@ -0,0 +1,235 @@
+#block##pageblock# 
+#pagenr("%",1)##setcount(1)##count per page# 
+#headeven# 
+gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#right#gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+6 - % #right#ERGOS 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+ERGOS #right# 6 - % 
+#end# 
+#ib#6  Einbinden der Datei- und Archivoperationen#ie# 
+ 
+ 
+Sie haben bereits erfahren, wie Sie eine Menukarte generieren und ankoppeln kön­
+nen. Im letzten Kapitel haben wir Ihnen die Möglichkeiten aufgezeigt, innerhalb des
+Menus einen Dialog mit dem Benutzer zu führen. Sie sind somit in der Lage, Ihre
+eigenen Anwendungen unter der Benutzeroberfläche gs-DIALOG zu erstellen. 
+Wie sich gezeigt hat, treten eine Reihe von Verarbeitungsfunktionen in nahezu jeder
+Anwendung auf. Im EUMEL-System benötigt man bei fast allen Anwendungspro­
+grammen auch die Möglichkeiten, Dateien auf dem Archiv zu sichern oder von dort
+zu holen; auch Umbenennen, Kopieren, Drucken, Reorganisieren ... von Dateien
+zählen sicher zu den häufig benötigten Verarbeitungsfunktionen. Wünschenswert ist
+es natürlich, daß in allen Programmen unter einer Benutzeroberfläche die "Stan­
+dard-Verarbeitungsfunktionen" in immer gleicher Weise zur Verfügung stehen! 
+ 
+Dieser Vorteil liegt sogar nicht nur auf der Seite des Anwenders - auch der Anwen­
+dungsprogrammierer profitiert davon: Dann nämlich, wenn er diese Standard-Verar­
+beitungsfunktionen nicht immer neu schreiben muß, sondern auf vorgefertigte
+Prozeduren und natürlich auch auf die zugehörigen Informationstexte zurückgreift. 
+ 
+Wir haben uns deshalb entschlossen, diese Standard-Verarbeitungsfunktionen zum
+Datei- und Archivhandling bereits in das Basissystem gs-DIALOG zu integrieren und
+Ihnen mit gs-Menu-Generator Dateien zur Verfügung zu stellen, in denen die
+Programme zur Einbindung dieser Prozeduren in Ihre eigenen Programmsysteme
+ebenso enthalten sind wie alle dazugehörigen Informationstexte. 
+In diesem Kapitel soll nun beschrieben werden, wie Sie diese vorgefertigten Module in
+Ihre Menukarten/Programme einbinden können und was Sie dabei beachten müs­
+sen. 
+ 
+ 
+#ib#6.1  Einbinden der Archivoperationen#ie# 
+ 
+Auf der von uns gelieferten Diskette 'gs-Menu-Generator', befindet sich auch die
+Datei 'Generatordatei: Archivmenu'. Darin ist das vollständige Menukarten-Generie­
+rungs-Programm zur Generierung der Menukarte 'gs-MENUKARTE: Archiv' inclusive
+aller Informationstexte enthalten. U.a. befindet sich darin eben das folgende Pro­
+gramm: 
+ 
+ 
+oeffne menukarte ("Archiv"); 
+oeffne menu   ("ARCHIV", "", "menu archiv reservierung aufgeben"); 
+ 
+ 
+oberbegriff  ("Dateien"); 
+ 
+menufunktion ("v", "Verzeichnis",         "menu dateien verzeichnis", 
+                                           dateiverzeichnistext); 
+trennlinie; 
+menufunktion ("l", "Löschen",             "menu dateien loeschen", 
+                                           dateiloeschentext); 
+menufunktion ("d", "Drucken",             "menu dateien drucken", 
+                                           dateidruckentext); 
+trennlinie; 
+menufunktion ("k", "Kopieren",            "menu dateien kopieren", 
+                                           dateikopierentext); 
+menufunktion ("u", "Umbenennen",          "menu dateien umbenen­
+                                           nen", 
+                                           dateiumbenennentext); 
+trennlinie; 
+menufunktion ("s", "Speicherplatz",       "menu dateien speicherplatz", 
+                                           dateispeicherplatztext); 
+menufunktion ("a", "Aufräumen",           "menu dateien aufraeumen", 
+                                           dateiaufraeumtext); 
+ 
+ 
+oberbegriff  ("Archiv", "menu archiv grundeinstellung (4)", 
+                         "menu archiv reservierung aufgeben"); 
+ 
+menufunktion ("r", "Reservieren",         "menu archiv reservieren", 
+                                           archivreserviertext); 
+menufunktion ("n", "Neue Diskette",       "menu archiv neue diskette", 
+                                           neuediskettetext); 
+trennlinie; 
+menufunktion ("s", "Schreiben",           "menu archiv schreiben", 
+                                           archivschreibtext); 
+menufunktion ("c", "Checken",             "menu archiv checken", 
+                                           archivchecktext); 
+menufunktion ("k", "Kombination",         "menu archiv schreibcheck", 
+                                           archivkombinationstext); 
+menufunktion ("h", "Holen/Lesen",         "menu archiv holen", 
+                                           archivholtext); 
+menufunktion ("l", "Löschen",             "menu archiv loeschen", 
+                                           archivloeschtext); 
+trennlinie; 
+menufunktion ("v", "Verzeichnis",         "menu archiv verzeichnis", 
+                                           archivverzeichnistext); 
+menufunktion ("d", "Drucken",             "menu archiv verzeichnis
+                                           drucken", 
+                                           archivdruckentext); 
+trennlinie; 
+menufunktion ("i", "Initialisieren",      "menu archivinitialisieren", 
+                                           archivinitialisiertext); 
+menufunktion ("z", "Zieltask einstellen",  "menu archiv zieltask
+                                            einstellen", 
+                                            archivzieltasktext); 
+schliesse menu; 
+schliesse menukarte; 
+ 
+ 
+Wie schon oben erwähnt, sind auch alle Informationstexte in der Datei enthalten, die
+jeweils über den 4. Parameter der Prozeduren 'menufunktion' in die Menukarte
+eingebunden werden. Wir haben Sie hier nicht extra abgedruckt; Sie können ja die
+entsprechende Datei auf der Diskette einsehen! 
+ 
+Zu dem Programm möchten wir jedoch noch einige wichtige Anmerkungen machen,
+damit Sie die entsprechenden Verarbeitungsfunktionen in Ihre Menukarte einbinden
+können. 
+ 
+Wenden wir uns zunächst den Archivoperationen zu. gs-DIALOG stellt die folgenden
+Verarbeitungsfunktionen bereit: 
+ 
+ 
+          PROC #ib#menu archiv reservieren#ie#, 
+          PROC #ib#menu archiv neue diskette#ie#, 
+          PROC #ib#menu archiv schreiben#ie#, 
+          PROC #ib#menu archiv checken#ie#, 
+          PROC #ib#menu archiv schreibcheck#ie#, 
+          PROC #ib#menu archiv holen#ie#, 
+          PROC #ib#menu archiv loeschen#ie#, 
+          PROC #ib#menu archiv verzeichnis#ie#, 
+          PROC #ib#menu archiv verzeichnis drucken#ie#, 
+          PROC #ib#menu archiv initialisieren#ie#, 
+          PROC #ib#menu archiv zieltask einstellen#ie#, 
+ 
+ 
+Durch diese elf Prozeduren werden die entsprechenden Menufunktionen ausgeführt. 
+ 
+Außerdem werden noch folgende Prozeduren bereitgestellt: 
+ 
+ 
+          PROC #ib#menu archiv grundeinstellung#ie# (INT CONST ort) 
+          PROC #ib#menu archiv reservierung aufgeben#ie# 
+ 
+ 
+Diesen beiden Prozeduren sollten Sie bei der Einbindung der Archivfunktionen in
+Ihre Menukarten besondere Beachtung schenken. Wie Sie im Programm auf der Seite
+zuvor sehen, taucht die Prozedur 'menu archiv reservierung aufgeben' gleich zweimal
+auf: einmal als 3.Parameter der Prozedur 'oberbegriff' und einmal als 3.Parameter
+der Prozedur 'oeffne menu' - und das aus folgendem Grund: 
+ 
+Wenn der Benutzer die Archivoperationen verläßt, dann sollte automatisch das Archiv
+freigegeben werden, um so - auch bei Multi-User-Betrieb - ein einwandfreies Archiv­
+handling zu gewährleisten. Nun kann der Benutzer das Pull-Down-Menu 'Archiv' aber
+eben auf zweierlei Weise verlassen: Einmal durch den Wechsel in ein anderes Pull-
+Down-Menu der gleichen Menukarte - oder aber er verläßt insgesamt das Menu. Im
+ersten Falle wird das Archiv abgemeldet, weil ja die als 3.Parameter bei 'oberbegriff'
+eingetragene Prozedur ausgeführt wird - im zweiten Falle, weil die als 3.Parameter
+bei 'oeffne menu' eingetragene Prozedur ausgeführt wird. Diese Eintragungen sollten
+Sie auf keinen Fall bei der Einbindung der Archivoperationen vergessen. 
+ 
+Die Prozedur 'menu archiv grundeinstellung (INT CONST ort)' sollte bei den Archiv­
+operationen immer als 2. Parameter in der Prozedur 'oberbegriff' übergeben wer­
+den. Nur wenn diese Prozedur beim Entfallten des Archiv-Pull-Down-Menus ausge­
+führt wird, ist die einwandfreie Funktion des Archivsystems sichergestellt. Dadurch
+geschieht nämlich folgendes: 
+ 
+   1)  Als Zieltask wird das Archiv der eigenen Station eingestellt - unabhängig
+       davon, mit welcher Einstellung das Menu zuvor verlassen wurde. 
+ 
+   2)  Es wird die Zieltask auf dem Bildschirm angezeigt. 
+ 
+   3)  Die entsprechenden Menupunkte werden aktiviert bzw. deaktiviert. 
+ 
+   4)  Es wird festgelegt, an welcher Stelle innerhalb des Menus die Menunotiz zur
+       Anzeige der Zieltask (und ggf. des Archivnamens) ausgegeben wird. 
+ 
+Im Programm oben ist hierfür die Position 4 (rechts unten in der Ecke) gewählt. Wir
+haben diese Festlegung deswegen so getroffen, weil das Archiv-Pull-Down-Menu
+ziemlich weit links auf dem Bildschirm erscheint (es sind nur zwei Oberbegriffe
+eingetragen!). So stören sich Archiv-Pull-Down-Menu und die Menunotiz nicht gegen­
+seitig. In unseren Anwendungssystemen 'gs-Herbert und Robbi' und
+'gs-MP-BAP' haben wir dagegen die Position '3' eingetragen, damit die Menunotiz
+unten links in der Ecke erscheint, weil das Archiv-Pull-Down-Menu ganz rechts auf
+dem Bildschirm entfaltet wird. 
+ 
+Achtung! Uns ist es sehr, sehr wichtig, daß zumindest die Archivfunktionen in allen
+Anwendungen unter gs-DIALOG in gleicher Weise zur Verfügung gestellt werden. Um
+das sicherzustellen, sind die Funktionen so in gs-DIALOG integriert, daß das System
+nur dann reibungslos funktioniert, wenn Sie sich an die eben aufgezeigten Regeln für
+die Einbindung in Ihr Anwendungssystem halten! Für die korrekte Funktionsweise
+muß im Archiv-Pull-Down-Menu auch immer exakt die Reihenfolge (der Aufbau) der
+Verarbeitungsfunktionen eingehalten werden. Auch die Namen sollten immer gleich
+gewählt werden! 
+ 
+Wir hoffen, daß Sie als Programmierer für diese doch etwas rigorose Maßnahme
+Verständnis haben - dafür versichern wir Ihnen, daß wir sehr viel Gedanken und
+Arbeit in die Konstruktion des Archivsystems investiert haben! 
+ 
+Auf eine Einschränkung muß allerdings noch hingewiesen werden:Das Archiv-
+Pull-Down-Menu kann aus technischen Gründen nicht das erste, ganz links in einem
+Menu stehende sein; es kann frühestens unter dem zweiten Oberbegriff in das Menu
+aufgenommen werden! Es ist z.Z. nicht möglich, im ganz links stehenden Pull-
+Down-Menu deaktivierte Menupunkte zu behandeln. 
+ 
+ 
+#ib#6.2  Einbinden der Dateiopertionen#ie# 
+ 
+gs-DIALOG stellt neben den Archivoperationen standardmäßig auch einige Dateiope­
+rationen bereit. Folgende Prozeduren stehen zur Verfügung: 
+ 
+ 
+          PROC #ib#menu dateien verzeichnis#ie#, 
+          PROC #ib#menu dateien loeschen#ie#, 
+          PROC #ib#menu dateien drucken#ie#, 
+          PROC #ib#menu dateien kopieren#ie#, 
+          PROC #ib#menu dateien umbenennen#ie#, 
+          PROC #ib#menu dateien speicherplatz#ie#, 
+          PROC #ib#menu dateien aufraeumen#ie#. 
+ 
+ 
+Die Prozeduren bedürfen in Ihrer Wirkung sicher kaum einer Erklärung. Die Wir­
+kungsweise können Sie einfach ausprobieren, indem Sie die entsprechenden Ver­
+arbeitungsfunktionen im Archiv-Menu einfach einmal aktivieren. 
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.7 b/doc/menugenerator/menu-generator handbuch.7
new file mode 100644
index 0000000..2e6f0ba
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.7	
@@ -0,0 +1,367 @@
+#block##pageblock# 
+#pagenr("%",1)##setcount(1)##count per page# 
+#headeven# 
+gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#right#gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+7 - % #right#ERGOS 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+ERGOS #right# 7 - % 
+#end# 
+#ib#7  Eigene Fenster und Fensteroperationen #ie# 
+ 
+ 
+In Kapitel 5.11 haben wir Ihnen gezeigt, wie Sie innerhalb des Menus ein Fenster
+(das Menufenster) öffnen können. Innerhalb dieses Bereichs stehen Ihnen die
+wesentlichen Ein- und Ausgabeoperationen zur Verfügung, die Sie auch sonst vom
+Bildschirm her kennen. Auf die Größe des Menufensters können Sie allerdings keinen
+Einfluß nehmen, da die Fenstergröße automatisch vom System (gs-DIALOG) festge­
+legt wird - je nachdem, ob Sie mit einem Menu oder mit geschachtelten Menus
+arbeiten. 
+Auf die Einschränkungen bzw. Abweichungen gegenüber den Möglichkeiten, die Sie
+bei Benutzung des ganzen Bildschirms haben, haben wir Sie ausdrücklich hingewie­
+sen: So ist es nicht möglich, den Text innerhalb eines Fensters zu rollen (scrolling);
+statt dessen wird bei Überschreiten der unteren Fenstergrenze der Fensterinhalt
+gelöscht und die Ausgabe oben im "neuen" Fenster fortgesetzt. 
+Als wir gs-DIALOG konzipierten und die ersten Anwendungen unter dieser Benutzer­
+schnittstelle entwarfen, fiel uns auf, daß es sehr günstig für die Strukturierung des
+Bildschirms innerhalb der Anwendungsprogramme ist, wenn man den Bildschirm in
+Bereiche (Fenster) einteilen und den Fenstern entsprechende Funktionen zuweisen
+kann (z.B. Eingabe-, Informations-, Kontroll-Fenster etc.). Sinnvoll ist es dann, auch
+die entsprechenden Ein-/Ausgaberoutinen zur Verfügung zu haben, die sich auf die
+einzelnen Fenster beziehen. 
+ 
+In diesem Kapitel werden wir Ihnen zeigen, wie Sie eigene Fenster definieren und
+darin Ein- und Ausgaben realisieren können. Für die Fenster gelten die gleichen
+Einschränkungen wie für das Menufenster - d.h. ein Rollen des Textes (scrolling) ist
+nicht möglich. Die Fensterposition und -größe innerhalb des Bildschirms können Sie
+aber festlegen. 
+ 
+ 
+#ib#7.1  Definition von Fenstern ('window')#ie# 
+ 
+Das Fensterkonzept in gs-DIALOG ist sehr einfach gehalten: Durch die Definition
+des Fenters werden nur Bereiche auf dem Bildschirm festgelegt, auf die sich
+bestimmte Ein-/Ausgabeprozeduren beziehen. 
+ 
+Wir wollen Ihnen die Verwendung von Fenstern wieder an einem kleinen Beispiel
+verdeutlichen - bleiben wir dazu bei unserer Textverarbeitung: Für die Seitenforma­
+tierung müßte der Benutzer den oberen und linken Rand, die Schreibfeldbreite und
+die Schreibfeldlänge festlegen. Dazu wollen wir dem Benutzer die aktuellen Werte
+anzeigen und ggf. eine Neueinstellung vornehmen lassen. Ein Programm dazu könnte
+so aussehen: 
+ 
+ 
+WINDOW VAR info      :: window ( 2, 2, 32,  9), 
+           frage     :: window (36, 2, 40,  3), 
+           daten     :: window (36, 7, 40,  4); 
+ 
+TEXT VAR oberer rand :: " 2.54", 
+         linker rand :: " 2.54", 
+         feldbreite  :: "16.00", 
+         feldlaenge  :: "24.50"; 
+ 
+ 
+zeige aktuelle werte an; 
+frage nach neueinstellung. 
+ 
+zeige aktuelle werte an: 
+  page; show (info); 
+  out (info, center (info, invers ("Aktuell eingestellte Werte:"))); 
+  cursor (info, 2, 4); 
+  out (info, "Oberer Rand        : " + oberer rand + " cm"); 
+  cursor (info, 2, 5); 
+  out (info, "Linker Rand        : " + linker rand + " cm"); 
+  cursor (info, 2, 7); 
+  out (info, "Schreibfeldbreite  : " + feldbreite  + " cm"); 
+  cursor (info, 2, 8); 
+  out (info, "Schreibfeldlänge   : " + feldlaenge  + " cm"). 
+ 
+frage nach neueinstellung: 
+  show (frage); 
+  cursor (frage, 1, 1); 
+  out (frage, center (frage, invers ("Papierformat einstellen:"))); 
+  cursor (frage, 2, 3); 
+  IF yes ("Neueinstellung vornehmen") 
+     THEN neue werte erfragen 
+  FI. 
+ 
+neue werte erfragen: 
+  show (daten); 
+  erfrage oberen rand; 
+  erfrage linken rand; 
+  erfrage feldbreite; 
+  erfrage feldlaenge. 
+ 
+erfrage oberen rand: 
+  REAL VAR neuer oberer rand; 
+  cursor (daten, 1, 1); 
+  out (daten, center (daten, invers ("Oberen Rand einstellen:"))); 
+  cursor (daten, 2, 3); 
+  out (daten, "Bitte den neuen Wert: "); 
+  get (daten, neuer oberer rand); 
+  oberer rand := text (neuer oberer rand, 5, 2); 
+  cursor (info, 23, 4); 
+  out (info, oberer rand). 
+ 
+erfrage linken rand: 
+  (* analog zu 'erfrage oberen rand *). 
+ 
+erfrage feldbreite: 
+  (* analog zu 'erfrage oberen rand *). 
+ 
+erfrage feldlaenge: 
+  (* analog zu 'erfrage oberen rand *). 
+ 
+ 
+ 
+Am Anfang des Programms werden drei Fenster definiert. Das "Infofenster" erscheint
+links oben auf dem Bildschirm, in ihm werden die aktuell eingestellten Werte ange­
+zeigt. Das "Fragefenster" erscheint neben dem ersten Fenster oben rechts auf dem
+Bildschirm. 
+Beantwortet der Benutzer die dort ausgegebene Frage 'Neueinstellung vornehmen
+(j/n)?' mit 'ja', dann erscheint unter dem zweiten Fenster ein drittes
+("Datenfenster"). Innerhalb dieses Fensters können nacheinander die neuen Werte
+eingelesen werden (nicht alle Prozeduren sind hier ausgeführt!). 
+ 
+Die Definition eines Fensters erfolgt in folgender Weise: 
+ 
+    #ib#WINDOW#ie# VAR fenstername :: #ib#window#ie# ( x, y, xsize, ysize); 
+ 
+Der Fenstervariablen wird durch 'window' eine Größe zugeordnet. Mit den ersten
+beiden Werten legen Sie die linke obere Ecke des Fensters ('x' bezeichnet die Spalten,
+'y' die Zeilen) auf dem Gesamtbildschirm fest. Mit 'xsize' bestimmen Sie die Fenster­
+breite (Spaltenzahl), mit 'ysize' die Höhe des Fensters (Zeilenzahl). Der Fenster­
+cursor hat die Position (1,1). 
+Die linke obere Ecke des ersten Fensters im Programm hat also die Position ( 2, 2).
+Das Fenster ist 32 Spalten breit und 9 Zeilen hoch; es kann unter dem Namen 'info'
+angesprochen werden. 
+Bei der Festlegung der Fenstermaße ist der Rahmen des Fensters nicht berücksich­
+tigt - er gehört nicht zum Fenster dazu! Haben Sie die Absicht, das Fenster mit
+Rahmen auszugeben, dann sollten Sie das bei der Fensterdefinition berücksichtigen.
+Wir haben es im Beispielprogramm auch gemacht: Die linke obere Ecke hat gerade
+die Position (2,2) erhalten, damit noch der Rahmen Platz hat. Mit Rahmen ist unser
+Fenster also 34 Spalten breit und 11 Zeilen hoch. Die linke obere Ecke des zweiten
+Fensters ('frage') legen wir deshalb in die 36. Spalte und 2. Zeile, damit auch hier
+Platz für den Rahmen bleibt. 
+Eine wichtige Einschränkung sollten Sie unbedingt berücksichtigen: Da manche
+Terminals mit Beschreiben der Position (80,24) automatisch den Bildschirm
+löschen, haben wir die maximale Ausdehnung eines umrandeten Fensters auf (2, 2,
+77, 22) festgelegt. Überschreiten Sie irgendwo diese Grenzen, dann wird kein Rah­
+men mehr erzeugt. Der Rahmen wird auch dann nicht erzeugt, wenn er in der 0.
+Zeile, 0.Spalte, 25 Zeile oder 80 Spalte zu liegen käme - erst recht natürlich nicht,
+wenn diese Werte noch unter- bzw. überschritten werden. 
+ 
+ 
+#ib#7.2  Anzeigen/Löschen von Fenstern#ie# 
+     ('#ib#show#ie#', '#ib#page#ie#', '#ib#erase#ie#', '#ib#out frame#ie#') 
+ 
+Mit dem Befehl 'show (WINDOW VAR w)' wird das Fenster 'w' angezeigt. Der Fenster­
+variablen müssen natürlich zuvor die Maße des Fensters zugewiesen sein. Durch den
+Befehl wird um den angegebenen Fensterbereich ein Rahmen gezogen und der
+"Innenbereich" des Fensters gelöscht. Möchten Sie das Fenster ohne Rahmen ange­
+zeigt haben, so verwenden Sie nur den Befehl 'page (WINDOW VAR w)'. Durch die­
+sen Befehl wird nur der "Innenbereich" des Fensters gelöscht. 
+Haben Sie das Fenster einmal mit 'show' ausgegeben und wollen den Fensterinhalt
+löschen, so verwenden Sie auch hier den Befehl 'page (WINDOW VAR w)', denn der
+Rahmen braucht ja nicht erneut ausgegeben zu werden. 
+Möchten Sie ein Fenster und den zugehörigen Rahmen löschen, dann steht Ihnen der
+Befehl 'erase (WINDOW VAR w) zur Verfügung: Durch den Befehl wird sowohl der
+"Innenbereich" des Fensters als auch der Rahmen gelöscht. 
+Sie können natürlich auch selbst einen Rahmen um ein Fenster setzen. Dafür steht
+der Befehl 'out frame (WINDOW VAR w)' zur Verfügung. Der Rahmen wird ebenfalls
+um den durch 'w' bestimmten Fensterbereich gezogen - der "Innenbereich" bleibt
+unberührt! 
+ 
+Sollten Sie ein Fenster mit dem Befehl 'show' ausgeben (oder mit 'out frame' einen
+Rahmen erzeugen) wollen, aber kein Rahmen auf dem Bildschirm erscheint, so
+haben Sie die zulässigen Fenstergrenzen überschritten. Sehen Sie dazu auch Kapitel
+7.1. 
+ 
+ 
+#ib#7.3  Operationen innerhalb des Fensters#ie# 
+ 
+Innerhalb des selbstdefinierten Fensters stehen Ihnen die gleichen Operationen zur
+Verfügung wie innerhalb des Menufensters. Bezieht sich eine Operation auf ein
+Fenster, so wird der interne Fensterbezeichner als erster Parameter übergeben. 
+ 
+ 
+#ib#7.3.1  Datei anzeigen/editieren #ie#('#ib#edit#ie#', '#ib#show#ie#') 
+ 
+Zum Anzeigen einer Datei steht die Prozedur 'show' zur Verfügung. Dabei kann
+einmal ein FILE angegeben werden ('show (WINDOW VAR w, FILE VAR f)') oder aber
+der Name der anzuzeigenden Datei ('show (WINDOW VAR w, TEXT VAR dateiname)').
+Die Datei kann nur eingesehen, nicht aber schreibend verändert werden. 
+Die Prozedur 'edit' gibt es ebenfalls in den zwei Ausprägungen. Hier kann die Datei
+im Gegensatz zu 'show' auch schreibend verändert werden. 
+Durch diesen Befehl wird jeweils innerhalb des angegebenen Fensters die Datei
+ausgegeben. Sofern die Lage des Fensters es zuläßt, wird automatisch ein Rahmen
+um das Dateifenster gezogen. 
+ 
+ 
+#ib#7.3.2  Positionierungen im Fenster#ie# 
+       ('#ib#cursor#ie#', '#ib#get cursor#ie#', '#ib#line#ie#', '#ib#remaining lines#ie#') 
+ 
+Mit 'cursor (WINDOW VAR w, INT CONST spalte, zeile)' können Sie den Cursor inner­
+halb des angegebenen Fensters positionieren. Werden dabei die Fenstergrenzen über-
+oder unterschritten, so wird der Fensterinhalt gelöscht und auf die Position (1, 1)
+innerhalb des Fensters positioniert. 
+Mit der Prozedur 'get cursor (WINDOW VAR w, INT VAR spalte, zeile)' können Sie die
+aktuelle Cursorposition innerhalb des angegebenen Fensters erfragen. 
+Wollen Sie an den Anfang der nächsten Zeile positionieren, dann verwenden Sie den
+Befehl 'line (WINDOW VAR w)' - wollen Sie gleich mehrere Zeilen vorwärtspositionie­
+ren, dann benutzen Sie den Befehl 'line (WINDOW VAR w, INT VAR anzahl zeilen)'. 
+Wird allerdings bei einem der beiden letzten Befehle die untere Fenstergrenze über­
+schritten, so wird der Fensterinhalt gelöscht und die Operation in der ersten Zeile des
+neuen Fensters fortgesetzt. 
+Die Informations-Prozedur 'remaining lines (WINDOW VAR w)' liefert Ihnen die
+Anzahl der unterhalb der aktuellen Zeile noch im Fenster vorhanden Zeilen. 
+ 
+ 
+#ib#7.3.3  Ein- und Ausgaben innerhalb des Fensters#ie# 
+       ('#ib#out#ie#', '#ib#put#ie#', '#ib#putline#ie#', '#ib#get#ie#', '#ib#getline#ie#', '#ib#yes#ie#', '#ib#no#ie#') 
+ 
+Mit der Prozedur 'out (WINDOW VAR w, TEXT CONST text)' können Sie einen Text
+innerhalb des angegebenen Fensters ausgeben. Paßt der Text nicht mehr in die
+aktuelle Zeile, so wird er in der nächsten Zeile fortgesetzt. 
+Bedenken Sie, daß innerhalb der Fenster kein Wortumbruch realisiert ist. Ebenso­
+wenig ist das Rollen (scrolling) des Fensterinhalts möglich: Erfolgt die Ausgabe eines
+Textes über die untere Fenstergrenze hinaus, so wird der Fensterinhalt gelöscht und
+die Ausgabe an der Position (1, 1) des Fensters fortgesetzt. 
+Zur Ausgabe von Texten stehen noch die beiden Prozeduren 'put (WINDOW VAR w,
+TEXT CONST text)' und 'putline (WINDOW VAR w, TEXT CONST text)' zur Verfügung.
+Bei erstgenannter Prozedur wird gegenüber 'out' an die Ausgabe noch ein Leerzei­
+chen angehängt, bei der zweiten wird zusätzlich an den Anfang der nächsten Zeile
+positioniert. 
+Zahlenwerte können mit den Prozeduren 'put (WINDOW VAR w, INT CONST intwert)'
+und 'put (WINDOW VAR w, REAL CONST realwert)' ausgegeben werden. An die
+Zahlenwerte wird jeweils ein Leerzeichen angehängt. 
+ 
+Für das Einlesen von Werten steht die Prozedur 'get' in mehreren Varianten zur
+Verfügung. Mit 'get (WINDOW VAR w, TEXT VAR text)' kann ein Text an der aktuellen
+Position des Fensters eingelesen werden. Stehen in der aktuellen Zeile des Fensters
+weniger als 5 Zeichenpositionen für die Eingabe zur Verfügung, so wird automatisch
+auf den Anfang der nächsten Zeile innerhalb des Fensters positioniert. 
+Über einen dritten Parameter können noch zusätzliche Festlegungen getroffen wer­
+den: Soll die Eingabe noch durch weitere Zeichen (außer Positionierungszeichen)
+abgeschlossen werden können, so werden die Zeichen als TEXT übergeben( 'get
+(WINDOW VAR w, TEXT VAR text, TEXT CONST separator)'), soll die Maximallänge des
+einzugebenden Textes festgelegt sein, so wird diese als INT übergeben ('get (WINDOW
+VAR w, TEXT VAR text, INT CONST laenge)'). 
+ 
+Mit den Prozeduren 'get (WINDOW VAR w, INT VAR intwert)' und 'get (WINDOW VAR
+w, INT VAR realwert)' können auch Zahlenwerte innerhalb des Fensters eingelesen
+werden. 
+ 
+Damit dem Anwender auch Vorschläge für der Eingabe gemacht werden können,
+steht die Prozedur 'editget' in zwei Variationen zur Verfügung. Bei 'editget' (WINDOW
+VAR w, TEXT VAR ausgabe) wird 'ausgabe zum Editieren ausgegeben. Daneben
+existiert noch ein 'editget' mit 7 Parametern, der detailliert bei der Zusammenstel­
+lung der Befehle erläutert ist. 
+ 
+Ebenso wie auf dem Gesamtbildschirm und innerhalb des Menufensters stehen auch
+hier die beiden Prozeduren 'yes (WINDOW VAR w, TEXT CONST frage)' und 'no
+(WINDOW VAR w, TEXT CONST frage)' zur Verfügung. 
+ 
+ 
+#ib#7.3.4  Weitere Prozeduren #ie#('#ib#center#ie#', '#ib#stop#ie#') 
+ 
+Mit 'center (WINDOW VAR w, TEXT CONST text)' werden vor dem angegebenen Text
+so viele Leerzeichen angehängt, daß der Text zentriert in der aktuellen Fensterzeile
+ausgegeben wird - wenn der Cursur bei der Ausgabe auf der ersten Position der Zeile
+steht. Dabei werden aber bereits vorhandene Zeileninhalte überschrieben. 
+ 
+Durch die Prozedur 'stop (WINDOW VAR w)' wird innerhalb des angegebenen Fen­
+sters an den Anfang der übernächsten Zeile positioniert und der Text " Zum Weiter­
+machen bitte irgendeine Taste tippen!" ausgegeben. Möchten Sie nicht an den Anfang
+der übernächsten Zeile positionieren, so können Sie die Anzahl der Zeilen auch
+explizit festlegen durch 'stop (WINDOW VAR w, INT CONST zeilenzahl). 
+ 
+ 
+#ib#7.4  Boxoperationen#ie# 
+ 
+Innerhalb des Menufensters (sehen Sie Kapitel 5) stehen Ihnen die Prozeduren
+'menuanswer', 'menuinfo', 'menuone', 'menusome', 'menuanswerone',
+'menuanswersome', 'menuyes', 'menuno', 'menualternative', 'write menunotice' und
+'menufootnote' zur Verfügung. Alle diese Prozeduren bezogen sich auf das von
+gs-DIALOG automatisch gesetzte Menufenster. 
+Auch innerhalb der von Ihnen selbst definierten Fenster können Sie auf ähnliche
+Prozeduren zurückgreifen. Da wir die eben genannten Prozeduren in Kapitel 5 sehr
+detailliert beschrieben haben, werden wir hier nur auf die entsprechenden
+Beschreibungen verweisen und ggf. die Besonderheiten/Abweichnungen erwähnen. 
+Zu beachten ist, daß innerhalb des Fensters weder die oberen noch die unteren zwei
+Zeilen von der "Box" beschrieben werden. Die oberen bleiben ständig frei - die unter­
+en werden zur Ausgabe der zugehörigen Benutzerinformation (Fußnote) benutzt -
+das sollten Sie bei der Festlegung der Fenstergröße bzw. bei der Länge der zu über­
+gebenden Texte berücksichtigen. Bei der Übergabe der Texte müssen Sie sich an die
+gs-DIALOG Syntax-Regeln halten, die in Kapitel 5.12 beschrieben sind. 
+ 
+Die Prozedur '#ib#boxanswer#ie# (WINDOW VAR w, TEXT CONST ausgabetext, antwortvorgabe,
+INT CONST position)' arbeitet wie die Prozedur 'menuanswer (TEXT CONST ausgabe­
+text, antwortvorgabe, INT CONST position)' nur innerhalb des Fensters 'w' (sehen Sie
+auch Kapitel 5.1). 
+ 
+Die Prozedur '#ib#boxinfo#ie#' gibt es in zwei Ausführungen: 'boxinfo (WINDOW VAR w, TEXT
+CONST text)' arbeitet wie 'menuinfo (TEXT CONST text)', allerdings auf dem angege­
+benen Fenster. Bei 'boxinfo (WINDOW VAR w, TEXT CONST text, INT CONST position,
+timelimit)' kann über den dritten Parameter noch die relative Position im angegebe­
+nen Fenster (sehen Sie dazu Kapitel 5.12) und über den vierten Parameter die Zeit­
+spanne festgelegt werden, für die die Information erscheint (sehen Sie auch Kap.
+5.2). 
+ 
+Die Prozedur '#ib#boxone#ie# (WINDOW VAR w, THESAURUS CONST thesaurus, TEXT CONST
+text1, text2, BOOL CONST mit reinigung)' arbeitet wie die Prozedur 'menuone
+(THESAURUS CONST thesaurus, TEXT CONST text1, text2, BOOL CONST mit reini­
+gung)'. Zu bedenken ist hier, daß die Auswahl innerhalb des Fensters Platz finden
+muß. Der Aufruf dieser Prozedur ist daher nur möglich, wenn das angegebene Fen­
+ster mindestens 60 Spalten breit und 17 Zeilen hoch ist. Ansonsten kommt es zu
+einer Fehlermeldung (sehen Sie auch Kap. 5.3). 
+ 
+Die Prozedur '#ib#boxsome#ie# (WINDOW VAR w, THESAURUS CONST thesaurus, TEXT
+CONST text1, text2, BOOL CONST mit reinigung)' arbeitet wie die Prozedur
+'menusome (THESAURUS CONST thesaurus, TEXT CONST text1, text2, BOOL CONST
+mit reinigung)'. Hinsichtlich der Fenstergröße gelten die gleichen Einschränkungen
+wie bei 'boxone' (sehen Sie auch Kap. 5.4). 
+ 
+Die Prozeduren '#ib#boxanswerone#ie#' und '#ib#boxanswersome#ie#' entsprechen den Prozeduren
+'menuanswerone' und 'menuanswersome'; es wird nur zusätzlich jeweils als erster
+Parameter das aktuelle Fenster übergeben. Hinsichtlich der Fenstergröße gelten die
+gleichen Einschränkungen wie bei 'boxone' (sehen Sie auch Kap. 5.5). 
+ 
+Die Prozeduren '#ib#boxyes#ie#', '#ib#boxno#ie#' und '#ib#boxalternative#ie#' entsprechen den Prozeduren
+'menuyes', 'menuno' und 'menualternative'; es wird nur zusätzlich jeweils als erster
+Parameter das aktuelle Fenster übergeben (sehen Sie auch Kap. 5.6 und 5.7). 
+ 
+Die Prozedur '#ib#boxnotice#ie#' unterscheidet sich von der Prozedur 'write menunotice'
+erheblich: Letztgenannte Prozedur hat zwei Parameter. Durch den ersten wird der
+Ausgabetext übergeben, mit dem zweiten wird die relative Position innerhalb des
+Menubildschirms festgelegt. Sowohl Text als auch Position werden vom System ge­
+speichert. Bei jedem Neuaufbau eines Pull-Down-Menus oder des Menubildschirms
+wird die Notiz neu mitaufgebaut. 
+Die Prozedur 'boxnotice (WINDOW VAR w, TEXT CONST text, INT CONST position, INT
+VAR x, y, xsize, ysize) dagegen hat sieben Parameter. Über den ersten wird das aktuel­
+le Fenster festgelegt. Die beiden nächsten Parameter entsprechen den beiden Para­
+metern von 'write menunotice'. Über die letzten vier Parameter werden die Posi­
+tion/Maße der Box geliefert, die ja erst durch das Aussehen der übergebenen Texte
+festgelegt werden. Weder Text noch Position der Boxnotiz werden vermerkt. Wollen Sie
+die Notiz löschen, so verwenden Sie eine der Prozeduren '#ib#page#ie# (INT CONST x, y, xsize,
+ysize)' oder '#ib#page up#ie# (INT CONST x, y, xsize, ysize)'. Im ersten Falle erscheint es dem
+Betrachter, als ob die Box von oben nach unten "aufgerollt" würde, im zweiten Falle
+von unten nach oben. 
+ 
+Mit den Prozeduren '#ib#out footnote#ie# (WINDOW VAR w, TEXT CONST text)' wird in der
+untersten Zeile des Fensters 'w' der angegebene Text ausgegeben. In der vorletzten
+Zeile des Fensters wird eine Trennlinie ausgegeben. Die Fußnote incl. der Trennline
+kann durch den Befehl '#ib#erase footnote#ie#' gelöscht werden. 
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.8 b/doc/menugenerator/menu-generator handbuch.8
new file mode 100644
index 0000000..66eb6cf
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.8	
@@ -0,0 +1,1676 @@
+#block##pageblock# 
+#pagenr("%",1)##setcount(1)##count per page# 
+#headeven# 
+gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#right#gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+8 - % #right#ERGOS 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+ERGOS #right# 8 - % 
+#end# 
+#ib#8  Kurzbeschreibung der Befehle #ie# 
+ 
+ 
+Durch #u#(*)#e# gekennzeichnete Prozeduren stehen (zumindest in der hier dokumentier­
+ten Form) erst ab gs-DIALOG Version 1.1 zur Verfügung! 
+ 
+ 
+#ib#activate#ie# 
+PROC activate (TEXT CONST punktname): 
+ 
+Zweck:   Mit der Prozedur kann ein (deaktivierter) Menupunkt im aktuellen
+         Pull-Down-Menu aktiviert, d.h. zur Ausführung freigegeben werden. Das
+         '-'-Zeichen vor der Punktbezeichnung verschwindet auf dem Bildschirm,
+         statt dessen erscheint das Zeichen, über den die Menufunktion direkt
+         aktivierbar ist. 'punktname' muß eine Punktbezeichnung sein, die genau
+         in der angegebenen Schreibweise im aktuellen Pull-Down-Menu vorhan­
+         den ist (über den 2. Parameter der Prozedur 'menufunktion' in die
+         Menukarte eingetragen wurde) - ansonsten wird diese Anweisung igno­
+         riert. Die Prozedur "zeigt nur dann Wirkung", wenn sie aus einer Verar­
+         beitungsfunktion des aktuell entfalteten Pull-Down-Menus heraus oder
+         durch die "Startprozedur"/"Leaveprozedur" des aktuellen Pull-Down-
+         Menus (sehen Sie auch 'oberbegriff') aufgerufen wird. 
+         Die Veränderung wird nicht sofort auf dem Bildschirm angezeigt, sondern
+         erst, wenn das Pull-Down-Menu das nächste Mal vom System regeneriert
+         wird; ansonsten muß das Kommando 'refresh submenu' gegeben werden. 
+ 
+ 
+PROC activate (INT CONST punktposition):#u#(*)#e# 
+Zweck:   arbeitet wie obiges 'activate', allerdings werden die Menupunkte nicht
+         über ihre Bezeichnung, sondern über ihre Position im (aktuellen) Pull-
+         Down-Menu identifiziert. Die Positionen sind von oben nach unten durch­
+         numeriert. Beachten Sie, daß Trennlinien eine Position belegen und
+         mitgezählt werden. Die Prozedur arbeitet schneller als obige! 
+ 
+ 
+#ib#anwendungstext#ie# 
+TEXT PROC anwendungstext (INT CONST zeilennummer): 
+ 
+Zweck:   Mit diesem Befehl können Texte angesprochen (geholt) werden, die in die
+         Menukarte ausgelagert wurden. Es wird der Text aus der angekoppelten
+         Menukarte geliefert, der bei der "Einlagerung" in der Zeile 'zeilen­
+         nummer' stand. 
+Fehler:  Kein Text vorhanden! (In der angekoppelten Menukarte ist unter der
+         'zeilennummer' kein Anwendungstext eingetragen.) 
+         Bitte achten Sie auf folgendes: Wenn Sie eine neue Menukarte generiert
+         haben, muß diese erst an die aktuelle Task gekoppelt werden, bevor Sie
+         auf die dort eingetragenen (Anwendungs-)Texte zugreifen können (z.B.
+         mit 'testinstallation'). 
+ 
+ 
+#ib#areax#ie# 
+INT PROC areax (WINDOW VAR w)  
+Zweck:   Liefert den Wert 'x' des Fensters w. 
+ 
+ 
+#ib#areaxsize#ie# 
+INT PROC areaxsize (WINDOW VAR w)  
+Zweck:   Liefert den den Wert 'xsize' des Fensters w. 
+ 
+ 
+#ib#areay#ie# 
+INT PROC areay (WINDOW VAR w)  
+Zweck:   Liefert den den Wert 'y' des Fensters w. 
+ 
+ 
+#ib#areaysize#ie# 
+INT PROC areaysize (WINDOW VAR w)  
+Zweck:   Liefert den den Wert 'ysize' des Fensters w. 
+ 
+ 
+#ib#balken links#ie# 
+TEXT PROC balken links: 
+ 
+Zweck:   Liefert das Zeichen, das bei der Darstellung der "Kästen" als "linker
+       Balken" (̄) ausgegeben wird. 
+ 
+ 
+PROC balken links (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" als "linker Balken" ausgegeben werden soll. 
+ 
+ 
+#ib#balken oben#ie# 
+TEXT PROC balken oben: 
+ 
+Zweck:   Liefert das Zeichen, das bei der Darstellung der "Kästen" als "oberer
+         Balken" (�) ausgegeben wird. 
+ 
+ 
+PROC balken oben (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" als "oberer Balken" ausgegeben werden soll. 
+ 
+ 
+#ib#balken rechts#ie# 
+TEXT PROC balken rechts: 
+ 
+Zweck:   Liefert das Zeichen, das bei der Darstellung der "Kästen" als "rechter
+         Balken" (̃) ausgegeben wird. 
+ 
+ 
+PROC balken rechts (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" als "rechter Balken" ausgegeben werden soll. 
+ 
+ 
+#ib#balken unten#ie# 
+TEXT PROC balken unten: 
+ 
+Zweck:   Liefert das Zeichen, das bei der Darstellung der "Kästen" als "unterer
+         Balken" (̂) ausgegeben wird. 
+ 
+ 
+PROC balken unten (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" als "unterer Balken" ausgegeben werden soll. 
+ 
+ 
+#ib#boxalternative#ie# 
+INT PROC boxalternative (WINDOW VAR w, 
+                         TEXT CONST infotext, 
+                                    auswahlliste, 
+                                    zusatztasten, 
+                         INT  CONST position, 
+                         BOOL CONST mit abbruch): 
+ 
+Zweck:   Vergl. 'menualternative'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menualternative' automatisch gesetzt wird. Der 'infotext' muß
+         den gs-DIALOG-Syntax-Regel gehorchen! Die 'auswahlliste' muß nach
+         festen Regeln erstellt werden (sehen Sie Kap. 5.7) 
+ 
+ 
+#ib#boxanswer#ie# 
+TEXT PROC boxanswer (WINDOW VAR w, 
+                     TEXT CONST infotext, 
+                                vorgabe, 
+                     INT CONST  position): 
+ 
+Zweck:   Vergl. 'menuanswer'. Hier wird nur zusätzlich das Fenster festgelegt, das
+         bei 'menuanswer' automatisch gesetzt wird. Der 'infotext' muß den
+         gs-DIALOG-Syntax-Regel gehorchen! 
+ 
+ 
+#ib#boxanswerone#ie# 
+TEXT PROC boxanswerone (WINDOW VAR w, 
+                        TEXT CONST infotext, 
+                                   vorgabe, 
+                        THESAURUS CONST thes, 
+                        TEXT CONST ueberschrift, 
+                                   hinweis, 
+                        BOOL CONST mit reinigung): 
+ 
+Zweck:   Vergl. 'menuanswerone'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuanswerone' automatisch gesetzt wird. 
+Fehler:  Fenster für Auswahl zu klein (x < 56, y < 15) 
+ 
+ 
+#ib#boxanswersome#ie# 
+THESAURUS PROC boxanswersome (WINDOW VAR w, 
+                       TEXT CONST infotext, 
+                                  vorgabe, 
+                       THESAURUS CONST thes, 
+                       TEXT CONST ueberschrift, 
+                                  hinweis, 
+                       BOOL CONST mit reinigung): 
+ 
+Zweck:   Vergl. 'menuanswersome'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuanswersome' automatisch gesetzt wird. 
+Fehler:  Fenster für Auswahl zu klein (x < 56, y < 15) 
+ 
+ 
+#ib#boxinfo#ie# 
+PROC boxinfo (WINDOW VAR w, TEXT CONST infotext, 
+              INT CONST position, timelimit): 
+ 
+Zweck:   Vergl. 'menuinfo'. Hier wird nur zusätzlich das Fenster festgelegt, das bei
+         'menuinfo' automatisch gesetzt wird. Der 'infotext' muß den gs-DIALOG-
+         Syntax-Regel gehorchen! 
+ 
+ 
+PROC boxinfo (WINDOW VAR w, TEXT CONST infotext): 
+ 
+  wirkt wie: boxinfo (w, infotext, 5, maxint) 
+ 
+ 
+#ib#boxno#ie# 
+BOOL PROC boxno (WINDOW VAR w, 
+                 TEXT CONST frage, 
+                 INT CONST  position): 
+ 
+  wirkt wie: NOT boxyes (w, frage, position) 
+ 
+ 
+#ib#boxnotice#ie# 
+PROC boxnotice (WINDOW VAR w, 
+                TEXT CONST infotext, 
+                INT CONST  position 
+                INT VAR x, y, xsize, ysize): 
+ 
+Zweck:   Mit 'w' wird das aktuelle Fenster festgelegt. In 'infotext' wird der Text
+         übergeben, der als Notiz ausgegeben werden soll, der Text muß den
+         gs-DIALOG-Syntax-Regeln entsprechen. Mit 'position' wird die relative
+         Lage innerhalb des Fensters 'w' bestimmt. Über die letzten vier Parameter
+         werden die Position/Maße der Box geliefert. Weder Text noch Position
+         werden vermerkt. 
+ 
+ 
+#ib#boxone#ie# 
+TEXT PROC boxone (WINDOW VAR w, 
+                  THESAURUS CONST thes, 
+                  TEXT CONST ueberschrift, 
+                             hinweis, 
+                  BOOL CONST mit reinigung): 
+ 
+Zweck:   Vergl. 'menuone'. Hier wird nur zusätzlich das Fenster festgelegt, das bei
+         'menuone' automatisch gesetzt wird. 
+Fehler:  Fenster für Auswahl zu klein (x < 56, y < 15) 
+ 
+ 
+#ib#boxsome#ie# 
+THESAURUS PROC boxsome (WINDOW VAR w, 
+                        THESAURUS CONST thes, 
+                        TEXT CONST ueberschrift, 
+                                   hinweis, 
+                        BOOL CONST mit reinigung): 
+ 
+Zweck:   Vergl. 'menusome'. Hier wird nur zusätzlich das Fenster festgelegt, das
+         bei 'menusome' automatisch gesetzt wird. 
+Fehler:  Fenster für Auswahl zu klein (x < 56, y < 15) 
+ 
+ 
+#ib#boxyes#ie# 
+BOOL PROC boxyes (WINDOW VAR w, 
+                  TEXT CONST frage, 
+                  INT CONST  position): 
+ 
+Zweck:   Vergl. 'menuyes'. Hier wird nur zusätzlich das Fenster festgelegt, das bei
+         'menuyes' automatisch gesetzt wird. Die 'frage' muß den gs-DIALOG-
+         Syntax-Regel gehorchen! 
+ 
+ 
+#ib#center#ie# 
+TEXT PROC center (WINDOW VAR w, TEXT CONST text): 
+ 
+Zweck:   Vergl. 'menuwindowcenter'. Hier wird nur zusätzlich das Fenster festge­
+         legt, das bei 'menuwindowcenter' automatisch gesetzt wird. 
+ 
+ 
+TEXT PROC center (INT CONST laenge, 
+                  TEXT CONST text): 
+ 
+Zweck:   "Ummantelt" 'text' mit Leerzeichen, so daß 'text' etwa in der Mitte zu
+         stehen kommt. Der gelieferte Text hat die Länge 'laenge'. 
+ 
+ 
+TEXT PROC center (TEXT CONST text): 
+ 
+  wirkt wie: center (79, text) 
+ 
+ 
+#ib#clear buffer#ie# 
+PROC clear buffer 
+ 
+Zweck:   Leert den Zeichenpuffer 
+ 
+ 
+#ib#clear buffer and count#ie# 
+INT PROC clear buffer and count (TEXT CONST 
+                                 zeichen): 
+ 
+Zweck:   Leert den Zeichenpuffer und liefert die Häufigkeit des Vorkommens von
+         'zeichen' im Zeichenpuffer. 
+ 
+ 
+#ib#current menuwindow#ie# 
+WINDOW PROC current menuwindow: 
+ 
+Zweck:   liefert das aktuelle Menufenster (die Einzelwerte können dann mit
+         'areax', 'areay', 'areaxsize' und 'areaysize' erfragt werden). 
+ 
+ 
+#ib#cursor#ie# 
+PROC cursor (WINDOW VAR w, INT CONST spalte, 
+                                     zeile): 
+ 
+Zweck:   Vergl. 'menuwindowcursor'. Hier wird nur zusätzlich das Fenster festge­
+         legt, das bei 'menuwindowcursor' automatisch gesetzt wird. 
+ 
+ 
+#ib#cursor off#ie# 
+PROC cursor off: 
+ 
+Zweck:   Sofern die EUMEL-Installation die Möglichkeit bietet, wird der Cursor aus
+         dem Bildschirm ausgeblendet. 
+         Wenn neue Verarbeitungsfunktionen entwickelt werden, sollte zu Beginn
+         der Cursor eingeschaltet und nach Abschluß der Cursor wieder ausge­
+         schaltet werden (sehen Sie auch Kap. 5.1). 
+ 
+ 
+PROC cursor off (TEXT CONST zeichenkette): 
+ 
+Zweck:   Neufestlegung der 'zeichenkette', die ausgegeben werden soll, um bei der
+         aktuellen EUMEL-Installation den Cursor auf den Befehl 'cursor off' hin
+         auszuschalten. 
+ 
+ 
+#ib#cursor on#ie# 
+PROC cursor on: 
+ 
+Zweck:   Sofern die EUMEL-Installation die Möglichkeit bietet, wird der Cursor auf
+         dem Bildschirm angezeigt. Wenn neue Verarbeitungsfunktionen entwik­
+         kelt werden, sollte zu Beginn der Cursor eingeschaltet und nach Abschluß
+         der Cursor wieder ausgeschaltet werden (sehen Sie auch Kap. 5.1). 
+ 
+ 
+PROC cursor on (TEXT CONST zeichenkette): 
+ 
+Zweck:   Neufestlegung der 'zeichenkette', die ausgegeben werden soll, um bei der
+         aktuellen EUMEL-Installation den Cursor auf den Befehl 'cursor on' hin
+         anzuschalten. 
+ 
+ 
+#ib#deactivate#ie# 
+PROC deactivate (TEXT CONST punktname): 
+ 
+Zweck:   Vergl. 'activate (TEXT CONST punktname)'. 
+         Im Gegensatz zu der Prozedur wird hier 'punktname' deaktiviert und
+         beim (nächsten) Erscheinen der Menupunktbezeichnung ein '-'Zeichen
+         vorangestellt. Es gelten die gleichen Einschränkungen wie bei 'activate'! 
+ 
+ 
+PROC deactivate (INT CONST punktposition):#u#(*)#e# 
+Zweck:   arbeitet wie obiges 'deactivate', allerdings werden die Menupunkte nicht
+         über ihre Bezeichnung, sondern über ihre Position im (aktuellen) Pull-
+         Down-Menu identifiziert. Die Positionen sind von oben nach unten durch­
+         numeriert. Beachten Sie, daß Trennlinien eine Position belegen und
+         mitgezählt werden. Die Prozedur arbeitet schneller als obige! 
+ 
+ 
+#ib#direktstart#ie# 
+PROC direktstart (TEXT CONST prozedurname, 
+                  BOOL CONST mit loeschen):#u#(*)#e# 
+Zweck:   Macht aus der aktuellen Task eine Manager-Task ('global manager').
+         Werden neue Sohntasks eingerichtet, so melden sich diese nicht - wie
+         gewohnt - mit der 'gib kommando:'-Ebene. Statt dessen wird die Prozedur
+         'prozedurname' ausgeführt. Das Kommando ist dann sinnvoll, wenn sich
+         die Sohntask gleich mit einem Menu melden soll. In der Prozedur
+         'prozedurname' muß dann die entsprechende Menukarte angekoppelt
+         und das gewünschte Menu zur Ausführung gebracht werden. Hat 'mit
+         loeschen den Wert 'TRUE', so wird nach Verlassen der Menuebene die
+         Task automatisch gelöscht; bei 'FALSE' wird noch angefragt, ob die Task
+         gelöscht werden soll. Wird die Frage bejaht, wird gelöscht; sonst wird die
+         Task abgekoppelt (break) und kann durch 'continue' wieder angekoppelt
+         werden. 
+         In der Task, in der das Kommando 'direktbefehl' gegeben wurde, sollte
+         nicht das Kommando 'monitor' gegeben werden, da dadurch auch die­
+         se Task zu einer Task gemacht würde, die sich direkt mit dem Menu
+         meldet und ggf. bei Verlassen des Menus automatisch gelöscht wird! Die
+         'gib kommando:'-Ebene ist dadurch unzugänglich! 
+ 
+ 
+#ib#ecke oben links#ie# 
+TEXT PROC ecke oben links: 
+ 
+Zweck:   Liefert das Zeichen, das bei der Darstellung der "Kästen" links oben in der
+         Ecke (ω) ausgegeben wird. 
+ 
+ 
+PROC ecke oben links (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" links oben in der Ecke ausgegeben werden soll. 
+ 
+ 
+#ib#ecke oben rechts#ie# 
+TEXT PROC ecke oben rechts: 
+ 
+Zweck:   Liefert das Zeichen, das bei der Darstellung der "Kästen" rechts oben in
+         der Ecke (�) ausgegeben wird. 
+ 
+ 
+PROC ecke oben rechts (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" rechts oben in der Ecke ausgegeben werden soll. 
+ 
+ 
+#ib#ecke unten links#ie# 
+TEXT PROC ecke unten links: 
+ 
+Zweck:   Liefert das Zeichen, das bei der Darstellung der "Kästen" links unten in
+         der Ecke (�) ausgegeben wird. 
+ 
+ 
+PROC ecke unten links (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" links unten in der Ecke ausgegeben werden soll. 
+ 
+ 
+#ib#ecke unten rechts#ie# 
+TEXT PROC ecke unten rechts: 
+ 
+Zweck:   Liefert das Zeichen, das bei der Darstellung der "Kästen" rechts unten in
+         der Ecke (�) ausgegeben wird. 
+ 
+ 
+PROC ecke unten rechts (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" rechts unten in der Ecke ausgegeben werden soll. 
+ 
+ 
+#ib#edit#ie# 
+PROC edit (WINDOW VAR w, TEXT CONST dateiname): 
+ 
+Zweck:   Vergl. 'menuwindowedit'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuwindowedit' automatisch gesetzt wird. 
+ 
+ 
+PROC edit (WINDOW VAR w, FILE VAR f): 
+ 
+Zweck:   Vergl. 'menuwindowedit'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuwindowedit' automatisch gesetzt wird. 
+ 
+ 
+#ib#editget#ie# 
+PROC editget (WINDOW VAR w, TEXT VAR text):#u#(*)#e# 
+Zweck:   Eingabe mit Editiermöglichkeit von 'text'. 'text' wird ausgegeben. Die
+          Eingabe wird mit RETURN beendet. 'text' darf höchstens 79 Zeichen
+         lang sein! Fehler:  Text nicht initialisiert. 
+ 
+ 
+PROC editget (WINDOW VAR w, TEXT VAR text, 
+              INT CONST max laenge, scroll, 
+              TEXT CONST sep, res, 
+              TEXT VAR exit char):#u#(*)#e# 
+Zweck:   Wie oben. Über 'max laenge' kann festgelegt werden , wie lang der einzu­
+         gebende Text ('text') maximal sein darf. Über 'scroll' wird die Breite des
+         Zeilenfensters festgelegt, bevor gerollt wird (jedoch nicht über die rech­
+         te Fenstergrenze hinaus). Über 'sep' können Zeichen bestimmt werden,
+         bei denen die Eingabe (zusätzlich zu RETURN) beendet werden soll. Über
+         'res' können reservierte Tasten angegeben werden. Wird eine dieser
+         Tasten mit ESC betätigt, wird die Eingabe beendet. In 'exit char' steht
+         dann ESC und das Zeichen, mit dem der Editor verlassen wurde. 
+Fehler:  Text nicht initialisiert. 
+ 
+ 
+#ib#erase#ie# 
+PROC erase (WINDOW VAR fenster): 
+ 
+Zweck:   Der durch 'fenster' beschrieben Bildschirmbereich wird gelöscht - ein­
+         schließlich des Rahmens, der den Fensterbereich umgibt (vergl. Sie auch
+         'page')! 
+ 
+ 
+#ib#erase footnote#ie# 
+PROC erase footnote (WINDOW VAR fenster): 
+ 
+Zweck:   Die letzten beiden Zeilen in 'fenster' (in der die Fußnote nebst Trennlinie
+         eingetragen sind) werden gelöscht (vergl. Sie auch 'out footnote')! 
+ 
+ 
+#ib#erase menunotice#ie# 
+PROC erase menunotice: 
+ 
+Zweck:   Sofern zuvor mit 'write menunotice' (sehen Sie auch dort) eine Menunotiz
+         gesetzt wurde, wird diese gelöscht, ansonsten hat die Prozedur keine
+         Wirkung. 
+ 
+ 
+#ib#get#ie# 
+PROC get (WINDOW VAR w, TEXT CONST eingabe): 
+ 
+Zweck:   Vergl. 'menuwindowget'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuwindowget' automatisch gesetzt wird. 
+ 
+ 
+PROC get (WINDOW VAR w, INT CONST wert): 
+ 
+Zweck:   Vergl. 'get (WINDOW VAR w, TEXT CONST eingabe)'. Der eingelesene Wert
+         wird anschließend entsprechend konvertiert. 
+ 
+ 
+ 
+PROC get (WINDOW VAR w, REAL CONST wert): 
+ 
+Zweck:   Vergl. 'get (WINDOW VAR w, TEXT CONST eingabe)'. Der eingelesene Wert
+         wird anschließend entsprechend konvertiert. 
+ 
+ 
+PROC get (WINDOW VAR w, TEXT CONST eingabe, 
+                        INT CONST laenge): 
+ 
+Zweck:   Vergl. 'get (WINDOW VAR w, TEXT CONST eingabe)'. Zusätzlich wird die
+         Eingabe beendet, wenn der eingegebene Text die Länge 'laenge' erreicht
+         hat. 
+ 
+ 
+PROC get (WINDOW VAR w, TEXT CONST eingabe, 
+                        TEXT CONST separator): 
+ 
+Zweck:   Vergl. 'get (WINDOW VAR w, TEXT CONST eingabe)'. Zusätzlich werden
+         über 'separtor' die Zeichen festgelegt, die zusätzlich zu den Positionie­
+         rungszeichen die Eingabe beenden. 
+ 
+ 
+#ib#get cursor#ie# 
+PROC get cursor (WINDOW VAR w, INT VAR spalte, 
+                                       zeile): 
+ 
+Zweck:   Vergl. 'get menuwindowcursor'. Hier wird nur zusätzlich das Fenster
+         festgelegt, das bei 'get menuwindowcursor' automatisch gesetzt wird. 
+ 
+ 
+#ib#getline#ie# 
+PROC getline (WINDOW VAR w, TEXT CONST eingabe): 
+ 
+Zweck:   Vergl. 'get (WINDOW VAR w, TEXT CONST eingabe). Nur wird hier die
+         Eingabe ausschließlich über die Positionierungstasten - nicht aber über
+         das Leerzeichen beendet. 
+ 
+ 
+#ib#get menuwindowcursor#ie# 
+PROC get menuwindowcursor (INT VAR spalte, zeile): 
+ 
+Zweck:   Mit der Prozedur wird die aktuelle Cursorposition innerhalb des Menu­
+         fensters erfragt. 
+ 
+ 
+#ib#handle menu#ie# 
+PROC handle menu (TEXT CONST menuname): 
+ 
+Zweck:   Bringt das in der angekoppelten Menukarte enthaltene Menu mit dem
+         Namen 'menuname' zur Ausführung, d.h. das entsprechende Menu wird
+         auf dem Bildschirm präsentiert und kann mit den üblichen Tastenfunk­
+         tionen gehandhabt werden. 
+         (Anmerkung: Die Menufunktionen können natürlich nur dann ausge­
+         führt werden, wenn die zugehörigen Programme in der aktuellen Task
+         zuvor insertiert wurden - ansonsten erscheint auf dem Bildschirm jeweils
+         der Hinweis 'unbekanntes Kommando'!) 
+Fehler:  Das Menu 'menuname' ist nicht in der angekoppelten Menukarte! 
+ 
+ 
+#ib#infix namen#ie# 
+THESAURUS PROC infix namen (THESAURUS CONST thes, 
+                            TEXT CONST infix): 
+ 
+Zweck:   Die Prozedur liefert einen Thesaurus, in dem alle Namen enthalten sind,
+         die in 'thes' übergeben wurden und die den Wortbestandteil 'infix' enthal­
+         ten (gleichgültig an welcher Position). 
+ 
+ 
+THESAURUS PROC infix namen (THESAURUS CONST thes, 
+                            INT CONST dateityp): 
+ 
+Zweck:   Die Prozedur liefert einen Thesaurus, in dem alle Dateinamen enthalten
+         sind, die in 'thes' übergeben wurden und die den Dateityp 'dateityp'
+         haben. 
+ 
+ 
+THESAURUS PROC infix namen (THESAURUS CONST thes, 
+                            TEXT CONST infix, 
+                            INT CONST dateityp): 
+ 
+  wirkt wie: infix namen (infix namen (thes, infix), dateityp) 
+ 
+ 
+#ib#install menu#ie# 
+PROC install menu (TEXT CONST menukartenname, 
+                   BOOL CONST mit emblem): 
+ 
+Zweck:   Mit diesem Befehl wird die Menukarte mit dem Namen 'menukarten­
+         name' aus der Task 'gs-MENUKARTEN' in die aktuelle Task kopiert. Die
+         Menukarte wird als unbenannter Datenraum an die Task gekoppelt. Der
+         benannte Datenraum wird gelöscht. Der Name der angekoppelten Menu­
+         karte wird vermerkt. 
+         Stimmt der Name der angekoppelten Menukarte mit dem Namen der
+         angeforderten Menukarte überein, dann wird nicht erneut eine Kopie
+         angefordert, sondern auf der bereits angekoppelten Menukarte gearbeitet. 
+         Hat 'mit emblem' den Wert 'TRUE', dann wird unser 'Software-Emblem'
+         während des Ankoppelvorgangs auf dem Bildschirm ausgegeben, bei
+         'FALSE' nicht. 
+Fehler:  Die Menukarte 'menukartenname' existiert nicht in der Task
+         'gs-MENUKARTEN'. 
+ 
+ 
+PROC install menu (TEXT CONST menukartenname): 
+ 
+  wirkt wie: install menu (TEXT CONST menukartenname, TRUE) 
+ 
+ 
+#ib#invers#ie# 
+TEXT PROC invers (TEXT CONST text): 
+ 
+Zweck:   Liefert den Text 'text' invers dargestellt. An den Text wird zuvor ein Leer­
+         zeichen angehängt. 
+ 
+ 
+#ib#kreuz#ie# 
+TEXT PROC kreuz: 
+ 
+Zweck:   Liefert das Zeichen, das bei der Darstellung der "Kästen" als "Kreuz" (̗)
+         ausgegeben wird. 
+ 
+ 
+PROC kreuz (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" als "Kreuz" ausgegeben werden soll. 
+ 
+ 
+#ib#line#ie# 
+PROC line (WINDOW VAR w, INT CONST anzahl): 
+ 
+Zweck:   Vergl. 'menuwindowline'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuwindowline' automatisch gesetzt wird. 
+ 
+ 
+PROC line (WINDOW VAR w): 
+ 
+  wirkt wie: line (w, 1) 
+ 
+ 
+#ib#menualternative#ie# 
+INT PROC menualternative (TEXT CONST infotext, 
+                                     auswahlliste, 
+                                     zusatztasten, 
+                          INT  CONST position, 
+                          BOOL CONST mit abbruch): 
+ 
+Zweck:   Mit der Prozedur können dem Benutzer innerhalb des Menubildschirms
+         mehrere Alternativen zur Entscheidung angeboten werden, von denen er
+         sich für eine entscheiden kann. 
+         Auf dem Bildschirm wird innerhalb des Menus eine Box ausgegeben.
+         Boxbreite und -höhe werden vom System automatisch anhand des über­
+         gebenen 'infotext'es (bzw. der 'auswahlliste') festgelegt. Der in 'infotext'
+         übergebene Text wird innerhalb der Box angezeigt. Der Text muß den
+         gs-DIALOG-Syntax-Regeln (sehen Sie Kap. 5.13) entsprechen - er dient
+         ausschließlich der Information des Benutzers. 
+         In der letzten Zeile der Box wird die 'auswahlliste' angeboten. Zwischen
+         jeder notierten Alternative muß in 'auswahlliste' der code "13" eingetra­
+         gen sein. In der Box werden zwischen den Alternativen je drei Leerzei­
+         chen eingefügt. Es können maximal 10 Alternativen angegeben werden,
+         die aber incl. der eingefügten Leerzeichen eine Gesamtbreite von 64
+         Zeichen nicht überschreiten dürfen. Über diese Liste erfolgt durch Posi­
+         tionierung und anschließendem <RETURN> die Entscheidung für eine
+         Alternative. Die Prozedur liefert dann als Zahlenwert die Position der
+         gewählten Alternative in der übergebenen Auswahlliste. 
+         Über 'mit abbruch' wird festgelegt, ob die Alternativentscheidung durch
+         die Tastenfolge <ESC><h> abgebrochen werden kann oder nicht. Ist
+         das zulässig und geschehen, dann wird der Wert 0 geliefert. 
+         Über 'zusatztasten' kann noch festgelegt werden, ob die Entscheidung
+         auch durch Tippen bestimmter Tasten angegeben werden kann. Sind hier
+         Zeichen angegeben und erfolgt die Entscheidung über das Tippen einer
+         zugelassenen Taste, dann wird die Position der getippten Taste in der
+         unter 'zusatztasten' übergebenen Zeichenkette ermittelt und der Wert 100
+         hinzuaddiert (sehen Sie dazu auch Kap. 5.7). 
+         Nach der Entscheidung wird der Menubildschirm automatisch in den
+         Ausgangszustand versetzt. 
+ 
+ 
+#ib#menuanswer#ie# 
+TEXT PROC menuanswer (TEXT CONST infotext, 
+                                 vorgabe, 
+                      INT CONST position): 
+ 
+Zweck:   Die Prozedur ermöglicht den Dialog mit dem Benutzer innerhalb des
+         Menus. Sie liefert einen vom Benutzer eingegebenen (bzw. modifizierten)
+         Text/Namen. 
+         Auf dem Bildschirm wird innerhalb des Menus eine Box ausgegeben.
+         Boxbreite und -höhe werden vom System automatisch anhand des über­
+         gebenen 'infotext'es festgelegt. Der in 'infotext' übergebene Text wird
+         innerhalb der Box angezeigt. Der Text muß den gs-DIALOG-Syntax-Regeln
+         (sehen Sie Kap. 5.13) entsprechen. 
+         In der letzten Zeile der ausgegebenen Box erscheint der Text "Eingabe:".
+         Über 'vorgabe' kann dem Benutzer ein Text zum Editieren angeboten
+         werden. Mit 'position' wird die relative Lage der Box innerhalb des Menu­
+         bildschirms festgelegt (1, 2, 3, 4, 5: sehen Sie dazu Kap. 5.12). 
+         Die Eingabe kann durch <RETURN> abgeschlossen oder durch
+         <ESC><h> abgebrochen werden, in letzterem Falle wird niltext ("")
+         geliefert. 
+         Der gelieferte Wert ist von führenden und folgenden Leerzeichen befreit
+         (compress). Es ist nicht möglich, den Namen 'break' einzugeben (sehen
+         Sie dazu Kap.5.1). 
+ 
+ 
+#ib#menuanswerone#ie# 
+TEXT PROC menuanswerone (TEXT CONST infotext, 
+          vorgabe, THESAURUS CONST thesaurus, 
+          TEXT CONST ueberschrift, hinweis, 
+          BOOL CONST mit reinigung): 
+ 
+Zweck:   Die Prozedur ist aus den zwei Prozeduren 'menuanswer' und 'menuone'
+         zusammengesetzt (sehen Sie auch dort). In einer Box innerhalb des
+         Menus wird der 'infotext' ausgegeben und eine Eingabe erwartet; ggf.
+         kann ein Text in 'vorgabe' zum Editieren ausgegeben werden. Wird die
+         Eingabe mit <RETURN> abgeschlossen, wird der eingegebene Text
+         geliefert. Statt der Eingabe kann der Benutzer sich durch die Tastenfolge
+         <ESC><z> auch die in 'thesaurus' übergebenen Namen zur Auswahl
+         anbieten lassen. Wird ein Name angekreuzt, wird dieser geliefert; wird die
+         Auswahl durch <ESC><h> abgebrochen, wird niltext ("") geliefert. 
+Fehler:  Fenster für Auswahl zu klein (x < 56, y < 15) 
+ 
+ 
+#ib#menuanswersome#ie# 
+THESAURUS PROC menuanswersome (TEXT CONST 
+               infotext, vorgabe, 
+               THESAURUS CONST thesaurus, 
+               TEXT CONST ueberschrift, hinweis, 
+               BOOL CONST mit reinigung): 
+ 
+Zweck:   Die Prozedur ist aus den zwei Prozeduren 'menuanswer' und 'menusome'
+         zusammengesetzt (sehen Sie auch dort). In einer Box innerhalb des
+         Menus wird der 'infotext' ausgegeben und eine Eingabe erwartet; ggf.
+         kann ein Text in 'vorgabe' zum Editieren ausgegeben werden. Wird die
+         Eingabe mit <RETURN> abgeschlossen, wird der eingegebene Text in
+         einem Thesaurus geliefert. Statt der Eingabe kann der Benutzer sich
+         durch die Tastenfolge <ESC><z> auch die in 'thesaurus' übergebenen
+         Namen zur Auswahl anbieten lassen. Werden Namen angekreuzt, werden
+         diese in einem Thesaurus geliefert; wird die Auswahl durch
+         <ESC><h> abgebrochen, wird ein leerer Thesaurus geliefert. 
+Fehler:  Fenster für Auswahl zu klein (x < 56, y < 15) 
+ 
+ 
+#ib#menu archiv checken#ie# 
+PROC menu archiv checken: 
+ 
+Zweck:   Über diese Prozedur kann das "Checken" von Dateien auf dem Archiv in
+         das Archiv-Pull-Down-Menu eingebunden werden. Sehen Sie dazu unbe­
+         dingt Kap. 6.1! 
+ 
+ 
+#ib#menu archiv grundeinstellung#ie# 
+PROC menu archiv grundeinstellung (INT CONST ort): 
+ 
+Zweck:   Hierüber wird die Grundeinstellung des Archivpakets vorgenommen: Dazu
+         wird als Zieltask das Archiv der eigenen Station eingestellt. Dieses wird
+         auch über eine Menunotiz im Menu angezeigt. Die entsprechenden Menu­
+         punkte werden aktiviert bzw. deaktiviert. Sehen Sie dazu unbedingt Kap.
+         6.1! 
+         Über 'ort' wird festgelegt, an welcher Stelle innerhalb des Menus die
+         Menunotiz zur Anzeige der Zieltask (und ggf. des Archivnamens) ausge­
+         geben wird (sehen Sie dazu Kap. 5.12). 
+ 
+ 
+#ib#menu archiv holen#ie# 
+PROC menu archiv holen: 
+ 
+Zweck:   Über diese Prozedur kann das Holen von Dateien vom Archiv in das
+         Archiv-Pull-Down-Menu eingebunden werden. Sehen Sie dazu unbedingt
+         Kap. 6.1! 
+ 
+ 
+#ib#menu archiv initialisieren#ie# 
+PROC menu archiv initialisieren: 
+ 
+Zweck:   Über diese Prozedur kann das Formatieren/ Initialisieren eines Archivs in
+         das Archiv-Pull-Down-Menu eingebunden werden. Sehen Sie dazu unbe­
+         dingt Kap. 6.1! 
+ 
+ 
+#ib#menu archiv loeschen#ie# 
+PROC menu archiv loeschen: 
+ 
+Zweck:   Über diese Prozedur kann das Löschen von Dateien auf dem Archiv in das
+         Archiv-Pull-Down-Menu eingebunden werden. Sehen Sie dazu unbedingt
+         Kap. 6.1! 
+ 
+ 
+#ib#menu archiv neue diskette#ie# 
+PROC menu archiv neue diskette: 
+ 
+Zweck:   Über diese Prozedur kann das Anmelden einer neuen Diskette bei schon
+         reserviertem Archiv in das Archiv-Pull-Down-Menu eingebunden werden.
+         Sehen Sie dazu unbedingt Kap. 6.1! 
+ 
+ 
+#ib#menu archiv reservieren#ie# 
+PROC menu archiv reservieren: 
+ 
+Zweck:   Über diese Prozedur kann die Archivreservierung in das Archiv-Pull-
+         Down-Menu eingebunden werden. Sehen Sie dazu unbedingt Kap. 6.1! 
+ 
+ 
+#ib#menu archiv reservierung aufgeben#ie# 
+PROC menu archiv reservierung aufgeben: 
+ 
+Zweck:   Über diese Prozedur kann eine bestehende Archivreservierung aus dem
+         Menu heraus aufgegeben werden. Sehen Sie dazu unbedingt Kap. 6.1! 
+ 
+ 
+#ib#menu archiv schreibcheck#ie# 
+PROC menu archiv schreibcheck: 
+ 
+Zweck:   Über diese Prozedur kann das Schreiben von Dateien auf das Archiv und
+         das sich automatisch daran anschließende "Checken" der zuvor geschrie­
+         benen Dateien in das Archiv-Pull-Down-Menu eingebunden werden.
+         Sehen Sie dazu unbedingt Kap. 6.1! 
+ 
+ 
+#ib#menu archiv schreiben#ie# 
+PROC menu archiv schreiben: 
+ 
+Zweck:   Über diese Prozedur kann das Schreiben von Dateien auf das Archiv in
+         das Archiv-Pull-Down-Menu eingebunden werden. Sehen Sie dazu unbe­
+         dingt Kap. 6.1! 
+ 
+ 
+#ib#menu archiv verzeichnis#ie# 
+PROC menu archiv verzeichnis: 
+ 
+Zweck:   Über diese Prozedur kann die Ausgabe eines Inhaltsverzeichnisses des
+         Archivs auf dem Bildschirm in das Archiv-Pull-Down-Menu eingebunden
+         werden. Sehen Sie dazu unbedingt Kap. 6.1! 
+ 
+ 
+#ib#menu archiv verzeichnis drucken#ie# 
+PROC menu archiv verzeichnis drucken: 
+ 
+Zweck:   Über diese Prozedur kann die Ausgabe eines Inhaltsverzeichnisses des
+         Archivs über den Drucker in das Archiv-Pull-Down-Menu eingebunden
+         werden. Sehen Sie dazu unbedingt Kap. 6.1! 
+ 
+ 
+#ib#menu archiv zieltask einstellen#ie# 
+PROC menu archiv zieltask einstellen: 
+ 
+Zweck:   Über diese Prozedur kann die Festlegung der Zieltask, mit der die Inter­
+         taskkommunikation abgewickelt werden soll, in das Archiv-Pull-Down-
+         Menu eingebunden werden. Sehen Sie dazu unbedingt Kap. 6.1! 
+ 
+ 
+#ib#menu dateien aufraeumen#ie# 
+PROC menu dateien aufraeumen: 
+ 
+Zweck:   Durch diese Prozedur wird innerhalb des aktuellen Menus der Name der
+         Datei erfragt, die aufgeräumt, d.h. reorganisiert werden soll. Existiert
+         keine Datei mit dem angegebenen Namen, so erfolgt ein Hinweis darauf.
+         Statt der Eingabe des Dateinamens kann auch die Tastenfolge
+         <ESC><z> getippt werden. Daraufhin werden alle Dateinamen der
+         Task zur Auswahl angeboten. Hier können die gewünschten Dateinamen
+         angekreuzt werden. Anschließend werden die angekreuzten Dateien
+         reorganisiert. Der Vorgang wird auf dem Bildschirm protokolliert. Am
+         Ende des Vorgangs wird der Menubildschirm automatisch regeneriert. Es
+         können natürlich nur Dateien des Typs 1003 (Textfiles) reorganisiert
+         werden; sofern andere Dateien ausgewählt werden, erfolgt ein Hinweis
+         darauf. 
+ 
+ 
+#ib#menu dateien drucken#ie# 
+PROC menu dateien drucken: 
+ 
+Zweck:   Durch diese Prozedur wird innerhalb des aktuellen Menus (auch bei
+         geschachtelten(!)) der Name der Datei erfragt, die gedruckt werden soll.
+         Anschließend wird die Datei mit dem angegebenen Namen gedruckt.
+         Existiert keine Datei mit dem angegebenen Namen, so erfolgt ein Hinweis
+         darauf. 
+         Statt der Eingabe des Dateinamens kann auch die Tastenfolge
+         <ESC><z> getippt werden. Daraufhin werden alle Dateinamen der
+         Task zur Auswahl angeboten. Alle angekreuzten Dateien werden an­
+         schließend gedruckt. Der Vorgang wird auf dem Bildschirm protokolliert.
+         Am Ende wird der Menubildschirm automatisch regeneriert. 
+ 
+ 
+#ib#menu dateien kopieren#ie# 
+PROC menu dateien kopieren: 
+ 
+Zweck:   Durch diese Prozedur wird innerhalb des aktuellen Menus der Name der
+         Datei erfragt, die kopiert werden soll. Existiert keine Datei mit dem
+         angegebenen Namen, so erfolgt ein Hinweis darauf. Statt der Eingabe des
+         Dateinamens kann auch die Tastenfolge <ESC><z> getippt werden.
+         Daraufhin werden alle Dateinamen der Task zur Auswahl angeboten. Hier
+         kann ein Dateiname angekreuzt werden. Nun wird der Name erfragt, den
+         die Kopie erhalten soll. Existiert der Name bereits, erfolgt ein Hinweis
+         darauf, sonst wird die Datei kopiert. Der Menubildschirm wird automa­
+         tisch regeneriert. 
+ 
+ 
+#ib#menu dateien loeschen#ie# 
+PROC menu dateien loeschen: 
+ 
+Zweck:   Durch diese Prozedur wird innerhalb des aktuellen Menus der Name der
+         Datei erfragt, die gelöscht werden soll. Anschließend wird die Datei mit
+         dem angegebenen Namen gelöscht, sofern die Sicherheitsabfrage zum
+         Löschen mit 'Ja' beantwortet wurde. Existiert keine Datei mit dem ange­
+         gebenen Namen, so erfolgt ein Hinweis darauf. Statt der Eingabe des
+         Dateinamens kann auch die Tastenfolge <ESC><z> getippt werden.
+         Daraufhin werden alle Dateinamen der Task zur Auswahl angeboten. Alle
+         angekreuzten Dateien werden anschließend (nach jeweiliger Sicherheits­
+         anfrage) gelöscht. Der Vorgang wird auf dem Bildschirm protokolliert. Am
+         Ende wird der Menubildschirm automatisch regeneriert. 
+ 
+ 
+#ib#menu dateien speicherplatz#ie# 
+PROC menu dateien speicherplatz: 
+ 
+Zweck:   Durch diese Prozedur wird innerhalb des aktuellen Menus der Name der
+         Datei erfragt, deren Speicherplatz ermittelt werden soll. Existiert keine
+         Datei mit dem angegebenen Namen, so erfolgt ein Hinweis darauf. Statt
+         der Eingabe des Dateinamens kann auch die Tastenfolge <ESC><z>
+         getippt werden. Daraufhin werden alle Dateinamen der Task zur Aus­
+         wahl angeboten. Hier können die gewünschten Dateinamen angekreuzt
+         werden. Anschließend wird der Speicherplatz der angekreuzten Datei(en)
+         ermittelt und im Menufenster ausgegeben. Im Anschluß an die Anzeige
+         wird der Menubildschirm automatisch regeneriert. 
+ 
+ 
+#ib#menu dateien umbenennen#ie# 
+PROC menu dateien umbenennen: 
+ 
+Zweck:   Durch diese Prozedur wird innerhalb des aktuellen Menus der Name der
+         Datei erfragt, die umbenannt werden soll. Existiert keine Datei mit dem
+         angegebenen Namen, so erfolgt ein Hinweis darauf. Statt der Eingabe des
+         Dateinamens kann auch die Tastenfolge <ESC><z> getippt werden.
+         Daraufhin werden alle Dateinamen der Task zur Auswahl angeboten. Hier
+         kann ein Dateiname angekreuzt werden. Nun wird der Name erfragt, den
+         die Datei anschließend erhalten soll. Existiert der Name bereits, erfolgt ein
+         Hinweis darauf, sonst wird die Datei umbenannt. Der Menubildschirm
+         wird automatisch regeneriert. 
+ 
+ 
+#ib#menu dateien verzeichnis#ie# 
+PROC menu dateien verzeichnis 
+ 
+Zweck:   Mit der Prozedur kann innerhalb des aktuellen Menus ein Verzeichnis der
+         Dateien der eigenen Task ausgegeben werden. Nach Verlassen des Ver­
+         zeichnisses durch <ESC><q> wird der Menubildschirm automatisch
+         regeneriert. 
+ 
+ 
+#ib#menufootnote#ie# 
+PROC menufootnote (TEXT CONST fussnotentext): 
+ 
+Zweck:   Mit der Prozedur kann der Text in der "Fußzeile" des aktuellen Menubild­
+         schirms (zumeist Hinweise an den Benutzer) ersetzt werden. Der vorhan­
+         dene Text wird gelöscht und stattdessen 'fussnotentext' notiert. Der Text
+         bleibt so lange erhalten, bis er durch eine andere selbstgesetzte Fußnote
+         ('menufootnote') oder durch die alte vom System gesetzte Fußnote ('old
+         menufootnote'; sehen Sie auch dort) überschrieben wird. Sofern
+         gs-DIALOG-Prozeduren aufgerufen werden, die selbst Ausgaben in der
+         Fußzeile machen, wird die durch 'menufootnote' gesetzte Fußnote eben­
+         falls überschrieben. Wenn der Text länger als die aktuelle Menubild­
+         schirmbreite ist,wird der Text abgeschnitten. Damit der Text auch in
+         geschachtelten Menus vollständig ausgegeben werden kann, sollte er nicht
+         länger als 69 Zeichen sein. 
+ 
+ 
+#ib#menufunktion#ie# 
+PROC menufunktion (TEXT CONST kuerzel, 
+                              punktbezeichnung, 
+                              prozedurname, 
+                              infotext): 
+ 
+Zweck:   Der Befehl wird für die Generierung von Menukarten benötigt. Mit diesem
+         Befehl wird in das aktuell geöffnete Menu unter dem aktuellen Oberbe­
+         griff eine Verarbeitungsfunktion eingetragen. Mit 'kuerzel' wird die Taste
+         bestimmt, über die die Verarbeitungsfunktion direkt aktiviert werden
+         kann. 'kuerzel' muß innerhalb eines Pull-Down-Menus eindeutig gewählt
+         sein! Unter 'punktbezeichnung' wird der Text eingetragen, der im Pull-
+         Down-Menu ausgegeben werden soll. In 'prozedurname' steht der Name
+         der Prozedur (als Text(!)), die bei Aktivierung des Menupunktes ausge­
+         führt werden soll. In 'infotext' steht der Text, der als Information zu
+         diesem Menupunkt bei Tippen der <?>-Taste angezeigt werden soll. 
+Fehler:  Menupunkt-Kürzel ist länger als ein Zeichen. 
+         Menupunktkürzel kommt mehrfach vor. 
+         Menupunktbezeichnung ist zu lang (> 60 Zeichen). 
+         Zu viele Menupunkte in einem Pull-Down-Menu (> 15). 
+ 
+ 
+#ib#menuinfo#ie# 
+PROC menuinfo (TEXT CONST infotext, INT CONST 
+               position, timelimit): 
+ 
+Zweck:   Die Prozedur ermöglicht es, innerhalb des Menus einen Hinweis (Infor­
+         mationstext) auszugeben. Im Menubildschirm erscheint der 'infotext' in
+         einer Box. Boxbreite und -höhe werden vom System automatisch anhand
+         des übergebenen 'infotext'es festgelegt. 'infotext' muß den gs-DIALOG-
+         Syntax-Regeln (sehen Sie Kap. 5.13) entsprechen. Mit 'position' wird die
+         relative Lage der Box innerhalb des Menubildschirms festgelegt (1, 2, 3,
+         4, 5: sehen Sie dazu Kap. 5.12). Mit 'timelimit' kann die Zeitdauer (in
+         Zehntelsekunden) festgelegt werden, für die der Hinweis höchstens er­
+         scheint. Die Anzeige kann vom Benutzer durch Tippen einer beliebigen
+         Taste abgebrochen werden. 
+ 
+ 
+PROC menuinfo (TEXT CONST infotext, 
+               INT CONST position): 
+ 
+  wirkt wie: menuinfo (infotext, position, maxint) 
+ 
+ 
+PROC menuinfo (TEXT CONST infotext): 
+ 
+  wirkt wie: menuinfo (infotext, 5) 
+ 
+ 
+#ib#menukartenname#ie# 
+TEXT PROC menukartenname:#u#(*)#e# 
+Zweck:   Liefert den Namen der zur zeit angekoppelten Menukarte. Ist keine
+         Menukarte angekoppelt, wird niltext ("") geliefert. 
+ 
+ 
+#ib#menuno#ie# 
+BOOL PROC menuno (TEXT CONST frage, 
+                  INT CONST position): 
+ 
+  wirkt wie: NOT menuyes (frage, position) 
+ 
+ 
+#ib#menuone#ie# 
+TEXT PROC menuone (THESAURUS CONST thesaurus, 
+                   TEXT CONST ueberschrift, 
+                              hinweis, 
+                   BOOL CONST mit reinigung): 
+ 
+Zweck:   Durch die Prozedur werden dem Benutzer innerhalb des Menubild­
+         schirms Namen zur Auswahl angeboten. Nach Ankreuzen eines Namens
+         wird die Auswahl automatisch verlassen. Der angekreuzte Name wird
+         geliefert. Wird die Auswahl durch <ESC><h> abgebrochen, so wird
+         niltext ("") geliefert. In 'thesaurus' wird ein THESAURUS mit den Namen
+         übergeben, die zur Auswahl angeboten werden sollen (sehen Sie dazu
+         auch Kap. 5.14). Die beiden Texte 'ueberschrift' und 'hinweis' erscheinen
+         zur Kennzeichnung im Kopf der Auswahlliste: 'ueberschrift' zentriert und
+         invers dargestellt, 'hinweis' nur zentriert. Hat 'mit reinigung' den Wert
+         TRUE, so wird nach der Auswahl der Menubildschirm automatisch wie­
+         deraufgebaut, bei FALSE wird darauf verzichtet. 
+Fehler:  Fenster für Auswahl zu klein (x < 56, y < 15) 
+ 
+ 
+#ib#menusome#ie# 
+THESAURUS PROC menusome (THESAURUS CONST 
+                         thesaurus, 
+                   TEXT CONST ueberschrift, 
+                              hinweis, 
+                   BOOL CONST mit reinigung): 
+ 
+Zweck:   Durch die Prozedur werden dem Benutzer innerhalb des Menubild­
+         schirms Namen zur Auswahl angeboten. Die Auswahl kann durch die
+         Tastenfolge <ESC><q> verlassen werden. Der/ die angekreuzte(n)
+         Name(n) wird/werden in einem Thesaurus geliefert. Wird die Auswahl
+         durch die Tastenfolge <ESC><h> abgebrochen oder wurde kein Name
+         angekreuzt, dann wird ein leerer Thesaurus geliefert. In 'thesaurus' wird
+         ein Thesaurus mit den Namen übergeben, die zur Auswahl angeboten
+         werden sollen (sehen Sie dazu auch Kap. 5.14). Die beiden Texte
+         'ueberschrift' und 'hinweis' erscheinen zur Kennzeichnung im Kopf der
+         Auswahlliste: 'ueberschrift' zentriert und invers dargestellt, 'hinweis' nur
+         zentriert. Hat 'mit reinigung' den Wert TRUE, so wird nach der Auswahl
+         der Menubildschirm automatisch wiederaufgebaut, bei FALSE wird darauf
+         verzichtet. 
+Fehler:  Fenster für Auswahl zu klein (x < 56, y < 15) 
+ 
+ 
+#ib#menuwindowcenter#ie# 
+TEXT PROC menuwindowcenter (TEXT CONST text): 
+ 
+Zweck:   Die Prozedur liefert einen Text, der so lang ist, wie das aktuelle Menufen­
+         ster breit ist. Dazu wird 'text' so mit Leerzeichen "ummantelt" daß 'text'
+         etwa in der Mitte zu stehen kommt. Steht der Cursor bei Ausgabe dieses
+         Textes am Anfang der Zeile, erscheint der Text zentriert in der Zeile
+         (vorhandene Zeileninhalte werden dadurch überschrieben (der Cursor
+         steht dann auf dem rechten Fensterrand!). 
+ 
+ 
+#ib#menuwindowcursor#ie# 
+PROC menuwindowcursor (INT CONST spalte, zeile): 
+ 
+Zweck:   Mit diesem Befehl kann der Cursor innerhalb des aktuellen Menufensters
+         positioniert werden. Ein "normales" Menufenster ist 77 Zeichen breit und
+         20 Zeichen hoch; ein Menufenster in einem geschachtelten Menu ist 71
+         Zeichen breit und 16 Zeichen hoch). (Sehen Sie auch die Informations­
+         prozeduren 'get menuwindowcursor' und 'remaining menuwindowlines'). 
+Fehler:  Wird außerhalb des aktuellen Menufensters positioniert, wird der Fenster­
+         inhalt gelöscht und die Fensterposition (1,1) angenommen. 
+ 
+ 
+#ib#menuwindowedit#ie# 
+PROC menuwindowedit (TEXT CONST dateiname): 
+ 
+Zweck:   Durch den Befehl wird innerhalb des Menus ein umrandetes Fenster
+         geöffnet und die Datei mit dem Namen 'dateiname' zum Editieren ausge­
+         geben. Auf die Größe des Menufensters kann kein Einfluß genommen
+         werden - sie wird selbständig vom System gesetzt ("normales" Menu: 77
+         Zeichen breit und 20 Zeichen hoch; geschachteltes Menu 71 Zeichen
+         breit und 16 Zeichen hoch). 
+Fehler:  Die Datei mit dem Namen 'dateiname' existiert nicht. 
+ 
+ 
+PROC menuwindowedit (FILE VAR f): 
+ 
+Zweck:   Vergl. obige 'menuwindowedit'-Prozedur. Die Datei 'f' muß mit der Verar­
+         beitungsart 'modify' assoziiert worden sein. 
+ 
+ 
+#ib#menuwindoweditget#ie# 
+PROC menuwindoweditget (TEXT VAR text):#u#(*)#e# 
+Zweck:   Vergl. 'menuwindowget (TEXT VAR text)' Zusätzlich kann hier in 'text' ein
+         Text zum Editieren vorgegeben werden. 
+Fehler:  Text nicht initialisiert. 
+ 
+ 
+#ib#menuwindowget#ie# 
+PROC menuwindowget (TEXT VAR text): 
+ 
+Zweck:   Mit der Prozedur können Texte innerhalb des Menufensters eingelesen
+         werden (INTEGER- und REAL-Werte müssen ggf. "von Hand" konvertiert
+         werden). Die Eingabe wird durch <RETURN> abgeschlossen. Es muß
+         mindestens ein Zeichen (ungleich Leerzeichen) eingegeben werden. Von
+         der Eingabe werden die führenden Leerzeichen abgeschnitten. Ist der
+         einzugebende Text länger als die noch verbleibende Restzeile, so wird der
+         Text in der Restzeile gescrollt. Sind in der aktuellen Zeile weniger als 7
+         Zeichenpositionen für die Eingabe vorhanden, so wird automatisch für die
+         Eingabe an den Anfang der nächsten Zeile positioniert. 
+ 
+ 
+#ib#menuwindowline#ie# 
+PROC menuwindowline (INT CONST anzahl): 
+ 
+Zweck:   Die Prozedur 'menuwindowline' hat innerhalb des Menubildschirms eine
+         ähnliche Wirkung wie die Prozedur 'line' auf dem Gesamtbildschirm. Es
+         werden 'anzahl' Zeilenwechsel vorgenommen. Wird allerdings die untere
+         Grenze des Menubildschirms überschritten, dann rollt (scrollt) der Bild­
+         schirm nicht die entsprechende Anzahl Zeilen nach oben, statt dessen
+         wird der Fensterinhalt gelöscht und die Operation oben im Fenster fort­
+         gesetzt. 
+ 
+ 
+PROC menuwindowline: 
+ 
+  wirkt wie: menuwindowline (1) 
+ 
+ 
+#ib#menuwindowout#ie# 
+PROC menuwindowout (TEXT CONST text): 
+ 
+Zweck:   Mit der Prozedur können innerhalb des aktuellen Menufensters Texte
+         ausgegeben werden. Sollen INTEGER- oder REAL-Werte ausgegeben wer­
+         den, müssen diese zunächst in Texte konvertiert werden. Ist der Text
+         länger als die verbleibende Restzeile innerhalb des aktuellen Menufen­
+         sters, so wird der Text bis zum Fensterende (rechts) ausgegeben und die
+         Ausgabe am Anfang der nächsten Zeile fortgesetzt. Sobald die letzte Posi­
+         tion des aktuellen Menufensters (unten rechts in der Fensterecke) be­
+         schrieben wurde, wird der Fensterinhalt gelöscht und die Ausgabe an der
+         Position (1,1) des Fensters fortgesetzt. 
+ 
+ 
+#ib#menuwindowpage#ie# 
+PROC menuwindowpage: 
+ 
+Zweck:   Durch den Befehl 'menuwindowpage' wird der Inhalt des Fensters inner­
+         halb des aktuellen Menus gelöscht (das "Menufenster") (vergleichen Sie
+         auch 'show menuwindow'). Der Rahmen des Fensters (der bei 'show
+         menuwindow' ausgegeben wurde), bleibt bestehen, da er nicht mit zum
+         eigentlichen Fenster gehört. Durch den Befehl wird der Menubildschirm
+         nicht rekonstruiert! Soll das Fenster geschlossen werden, ist der Befehl
+         'regenerate menuscreen' zu geben. 
+ 
+ 
+#ib#menuwindowshow#ie# 
+PROC menuwindowshow (TEXT CONST dateiname): 
+ 
+Zweck:   Vergl. 'menuwindowedit'-Prozedur. Die Datei 'dateiname' kann nicht
+         schreibend verändert werden. 
+ 
+ 
+PROC menuwindowshow (FILE VAR f): 
+ 
+Zweck:   Vergl. obige 'menuwindowshow'-Prozedur. Die Datei 'f' muß mit der
+         Verarbeitungsart 'modify' assoziiert worden sein. 
+ 
+ 
+#ib#menuwindowstop#ie# 
+PROC menuwindowstop (INT CONST zeilenzahl): 
+ 
+Zweck:   Innerhalb des Menufensters werden 'zeilenzahl' Zeilenwechsel vorge­
+         nommen und der Text " Zum Weitermachen bitte irgendeine Taste tip­
+         pen!" ausgegeben. Danach wird so lange gewartet, bis eine Taste getippt
+         wird. 
+ 
+ 
+PROC menuwindowstop: 
+ 
+  wirkt wie: menuwindowstop (2) 
+ 
+ 
+#ib#menuyes#ie# 
+BOOL PROC menuyes (TEXT CONST frage, 
+                   INT CONST position): 
+ 
+Zweck:   Die Prozedur dient dazu, innerhalb des Menus eine Ja/Nein-Entscheidung
+         des Benutzers einzuholen. Im Gegensatz zur Standardprozedur 'yes'
+         arbeitet diese Prozedur unabhängig davon, ob der Kommandodialog ein-
+         oder ausgeschaltet ist. Auf dem Bildschirm wird innerhalb des Menus eine
+         Box ausgegeben. Boxbreite und -höhe werden vom System automatisch
+         anhand der übergebenen 'frage' festgelegt. Der in 'frage' übergebene Text
+         wird um ein Fragezeichen (?) ergänzt und innerhalb der Box angezeigt.
+         Der Text muß den gs-DIALOG-Syntax-Regeln (sehen Sie Kap. 5.13)
+         entsprechen. In der letzten Zeile der ausgegebenen Box erscheint der Text
+         "Ja    Nein". Die Prozedur 'menuyes' liefert TRUE, wenn mit 'Ja' geantwor­
+         tet wurde und FALSE, wenn mit 'Nein' geantwortet wurde (durch Tippen
+         der Anfangsbuchstaben oder Positionierung auf die Antwort und ab­
+         schließendes <RETURN>). Der Menubildschirm wird automatisch
+         regeneriert. Mit 'position' wird die relative Lage der Box innerhalb des
+         Menubildschirms festgelegt (1, 2, 3, 4, 5: sehen Sie dazu Kap. 5.12). 
+ 
+ 
+#ib#no#ie# 
+BOOL PROC no (WINDOW VAR w, TEXT CONST frage): 
+ 
+  wirkt wie: NOT yes (w, frage). 
+ 
+ 
+#ib#not empty#ie# 
+BOOL PROC not empty (THESAURUS CONST thes): 
+ 
+Zweck:   Dient der Prüfung, ob ein Thesaurus Namen enthält oder nicht. Die
+         Prozedur liefert TRUE, wenn Namen in 'thes' enthalten sind, sonst FALSE. 
+ 
+ 
+#ib#oberbegriff#ie# 
+PROC oberbegriff (TEXT CONST punktname, 
+                             startprocname, 
+                             leaveprocname): 
+ 
+Zweck:   Der Befehl wird bei der Generierung von Menukarten benötigt. Mit diesem
+         Befehl wird die Bezeichnung 'punktname' in die Kopfzeile des aktuell
+         geöffneten Menus eingetragen. Die in 'startprocname' übergebene Proze­
+         dur wird ausgeführt, bevor das zugehörige Pull-Down-Menu auf dem
+         Bildschirm "ausgeklappt" wird; die in 'leaveprocname' übergebene Pro­
+         zedur, wenn in ein anderes Pull-Down-Menu gewechselt wird (beachten
+         Sie, daß die Prozedurnamen als Texte(!) übergeben werden). 
+Fehler:  Menukarte noch nicht geöffnet ('oeffne menukarte' fehlt). 
+         Menu noch nicht geöffnet ('oeffne menu' fehlt). 
+         Zu viele Oberbegriffe im Menu (> 10). 
+         Die Kopfzeile ist zu lang (> 70 Zeichen). 
+ 
+ 
+PROC oberbegriff (TEXT CONST punktname): 
+ 
+  wirkt wie: oberbegriff (punktname, "", "") 
+ 
+ 
+#ib#oeffne menu#ie# 
+PROC oeffne menu (TEXT CONST menuname, 
+                  einstiegsproc, 
+                  ausstiegsproc, infotext1, 
+                  infotext2, infotext3): 
+ 
+Zweck:   Der Befehl wird für die Generierung von Menukarten benötigt. Durch den
+         Befehl wird innerhalb der Menukarte ein Menu mit dem Namen
+         'menuname' angelegt. Über diesen Namen kann das Menu auch später
+         angesprochen werden (mit 'handle menu'). Die unter 'einstiegsproc'
+         übergebene Prozedur wird bei der Aktivierung des Menus ausgeführt, die
+         unter 'ausstiegsproc' übergebene Prozedur, wenn das Menu (mit
+         <ESC><q>) verlassen wird (beachten Sie, daß die Prozedurnamen als
+         Texte(!) übergeben werden!). In 'infotext1', 'infotext2' und 'infotext3'
+         können Hinweise eingetragen werden, die bei Erscheinen des Menus auf
+         dem Bildschirm für kurze Zeit in einer Box rechts unten angezeigt wer­
+         den. Die Erstellung der Boxtexte ist an genaue Regeln gebunden (sehen
+         Sie dazu Kap. 5.13). Sehen Sie auch bei 'schliesse menu'. 
+ 
+ 
+PROC oeffne menu (TEXT CONST menuname, 
+                             einstiegsproc, 
+                             ausstiegsproc): 
+ 
+  wirkt wie: oeffne menu (menuname, einstiegsproc, 
+                         ausstiegsproc, "", "", "") 
+ 
+ 
+PROC oeffne menu (TEXT CONST menuname): 
+ 
+  wirkt wie: oeffne menu (menuname, "", "") 
+ 
+ 
+#ib#oeffne menukarte#ie# 
+PROC oeffne menukarte (TEXT CONST menukartenname): 
+ 
+Zweck:   Der Befehl wird bei der Generierung von Menukarten benötigt. Ein Pro­
+         gramm zur Erstellung einer Menukarte muß immer mit diesem Befehl
+         beginnen. Durch den Befehl wird ein Datenraum mit dem Namen
+         'gs-MENUKARTE:menukartenname' eingerichtet; der Wortbestandteil
+         'gs-MENUKARTE:' wird dabei automatisch vor den angegebenen Namen
+         gesetzt (sehen Sie auch 'schliesse menukarte'). 
+Fehler:  Eine Menukarte mit dem angegebenen Namen existiert bereits in der
+         Task. Bei der Generierung wird dann angefragt, ob die alte Menukarte
+         gelöscht werden darf. 
+ 
+ 
+#ib#ohne praefix#ie# 
+THESAURUS PROC ohne praefix (THESAURUS CONST thes, 
+                             TEXT CONST praefix): 
+ 
+Zweck:   Liefert in einem Thesaurus alle Namen aus dem übergebenen Thesaurus
+         'thes', die mit  dem Wortbestandteil 'praefix' beginnen. Bei den gelie­
+         ferten Namen ist dieser führende Wortbestandteil entfernt. 
+ 
+ 
+#ib#old menufootnote#ie# 
+PROC old menufootnote: 
+ 
+Zweck:   Der aktuelle Text in der Fußzeile des aktuellen Menubildschirms wird
+         durch den hier zuletzt vom System gesetzten Text überschrieben. Die
+         Prozedur wird benutzt, um eine selbstgesetzte Fußnote (sehen Sie auch
+         'write menunotice') zu löschen. 
+ 
+ 
+#ib#out#ie# 
+PROC out (WINDOW VAR w, TEXT CONST text): 
+ 
+Zweck:   Vergl. 'menuwindowout'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuwindowout' automatisch gesetzt wird. 
+ 
+ 
+#ib#out frame#ie# 
+PROC out frame (WINDOW VAR fenster): 
+ 
+Zweck:   Um den durch 'fenster' angegebenen Bildschirmbereich wird ein Rahmen
+         gezogen. 
+ 
+ 
+#ib#out footnote#ie# 
+PROC out footnote (WINDOW VAR fenster, 
+                   TEXT CONST textzeile): 
+ 
+Zweck:   In der untersten Zeile des Fensters 'fenster' wird 'textzeile' ausgegeben, in
+         der vorletzten Zeile eine Trennzeile. Sehen Sie auch 'erase footnote'. 
+ 
+ 
+#ib#page#ie# 
+PROC page (WINDOW VAR fenster, 
+           BOOL CONST mit rahmen): 
+ 
+Zweck:   Der durch 'fenster' beschriebene Fensterbereich wird gelöscht. Hat 'mit
+         rahmen' den Wert TRUE, wird der Rahmenbereich ebenfalls gelöscht. 
+ 
+ 
+PROC page (WINDOW VAR fenster): 
+ 
+  wirkt wie: page (fenster, FALSE). 
+ 
+ 
+#ib#put#ie# 
+PROC put (WINDOW VAR w, TEXT CONST text): 
+ 
+  wirkt wie: out (w, text + " ") 
+ 
+ 
+PROC put (WINDOW VAR w, INT CONST zahl): 
+ 
+  wirkt wie: put (w, text (zahl)) 
+ 
+ 
+PROC put (WINDOW VAR w, REAL CONST zahl): 
+ 
+  wirkt wie: put (w, text (zahl)) 
+ 
+ 
+#ib#putline#ie# 
+PROC putline (WINDOW VAR w, TEXT CONST text): 
+ 
+  wirkt wie: put (w, text); line (w) 
+ 
+ 
+#ib#regenerate menuscreen#ie# 
+PROC regenerate menuscreen: 
+ 
+Zweck:   Der Befehl wird verwendet, um den Menubildschirm (z.B. nach der
+         Nutzung für anwendungsbezogene Ausgaben) in seinem letzten Zustand
+         zu reproduzieren. Der Bildschirm wird gelöscht. Anschließend wird der
+         aktuelle Menubildschirm vollständig neu aufgebaut - auch bei geschach­
+         telten Menus. (sehen Sie auch 'refresh submenu') 
+ 
+ 
+#ib#refresh submenu#ie# 
+PROC refresh submenu: 
+ 
+Zweck:   Der Befehl dient dazu, das aktuelle Pull-Down-Menu (z.B. nach Über­
+         schreiben) und ggf. eine gesetzte Menunotiz erneut auf den Bildschirm zu
+         schreiben. Betroffen ist nur der Bereich zwischen den Trennlinien der
+         Kopf- und Fußzeile. Für das vorausgehende Löschen verwendeter Bild­
+         schirmbereich ist der Programmierer verantwortlich. Im Gegensatz zu
+         'regenerate menuscreen' findet hier kein kompletter Bildschirmaufbau
+         statt. Wenn möglich, dann ist dieser Befehl dem Befehl 'regenerate
+         menuscreen' wegen des geringeren Zeitaufwandes vorzuziehen. 
+ 
+ 
+#ib#remaining lines#ie# 
+INT PROC remaining lines (WINDOW VAR w): 
+ 
+Zweck:   Die Prozedur liefert die Anzahl der Zeilen im Fenster 'w', die noch
+         zwischen Cursor und unterer Fenstergrenze vorhanden sind. 
+ 
+ 
+#ib#remaining menuwindowlines#ie# 
+INT PROC remaining menuwindowlines 
+ 
+Zweck:   Die Prozedur liefert die Anzahl der Zeilen im aktuellen Menufenster, die
+         noch zwischen Cursor und unterer Fenstergrenze vorhanden sind. 
+ 
+ 
+#ib#reset dialog#ie# 
+PROC reset dialog: 
+ 
+Zweck:   Das Menusystem wird in den Anfangszustand versetzt. (Keine Menukarte
+         angekoppelt; Anzahl der geöffneten Menus: 0) 
+ 
+ 
+#ib#schliesse menu#ie# 
+PROC schliesse menu: 
+ 
+Zweck:   Der Befehl wird bei der Generierung von Menukarten benötigt. Durch den
+         Befehl wird ein Menu in einer Menukarte abgeschlossen (sehen Sie auch
+         'oeffne menu') 
+ 
+ 
+#ib#schliesse menukarte#ie# 
+PROC schliesse menukarte 
+ 
+Zweck:   Der Befehl wird bei der Generierung von Menukarten benötigt. Durch den
+         Befehl wird eine Menukarte abgeschlossen (sehen Sie auch 'oeffne
+         menukarte') 
+ 
+ 
+#ib#senkrecht#ie# 
+TEXT PROC senkrecht: 
+ 
+ Zweck:  Liefert das Zeichen, das bei der Darstellung der "Kästen" als senkrechter
+         Strich (�) ausgegeben wird. 
+ 
+ 
+PROC senkrecht (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" als senkrechter Strich ausgegeben werden soll. 
+ 
+ 
+#ib#show#ie# 
+PROC show (WINDOW VAR fenster): 
+ 
+Zweck:   Das Fenster 'fenster' wird auf dem Bildschirm angezeigt (das Fenster
+         muß zuvor durch 'window' initialisiert worden sein). Um den angegebe­
+         nen Fensterbereich wird automatisch ein Rahmen gezogen. Der Rahmen
+         gehört nicht zum Fenster dazu! (Soll das Fenster ohne Rahmen ausgege­
+         ben werden, dann muß der Befehl 'page' verwendet werden.) Der Bereich
+         innerhalb des Rahmens (Fensterbereich) wird gelöscht. 
+ 
+ 
+#ib#show#ie# 
+PROC show (WINDOW VAR w, TEXT CONST dateiname): 
+ 
+Zweck:   Vergl. 'menuwindowshow'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuwindowshow' automatisch gesetzt wird. 
+ 
+ 
+PROC show (WINDOW VAR w, FILE VAR f): 
+ 
+Zweck:   Vergl. 'menuwindowshow'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuwindowshow' automatisch gesetzt wird. 
+ 
+ 
+#ib#show menuwindow#ie# 
+PROC show menuwindow: 
+ 
+Zweck:   Durch den Befehl 'show menuwindow' wird ein entsprechender Rahmen
+         innerhalb des Menubildschirms ausgegeben und der Bereich innerhalb
+         dieses Rahmens (das Fenster) gelöscht (sehen Sie auch 'menuwindow­
+         page'). Innerhalb des Fensters können anschließend verschiedene Opera­
+         tionen ausgeführt werden. Auf die Größe des Menufensters kann kein
+         Einfluß genommen werden - sie wird selbständig vom System gesetzt
+         ("normales" Menu: 77 Zeichen breit und 20 Zeichen hoch; geschachteltes
+         Menu 71 Zeichen breit und 16 Zeichen hoch). 
+ 
+ 
+#ib#stdinfoedit#ie# 
+PROC stdinfoedit (TEXT CONST dateiname):#u#(*)#e# 
+Zweck:   Löscht den Bildschirm und bietet die Datei 'dateiname' in einem festge­
+         legten zum Editieren an. In der Fußzeile wird die Information "Info:
+         <ESC><?>  Verlassen: <ESC><q>" angezeigt. Nach Tippen von
+         <ESC><?> werden Editorinformationen in den Bildschirm einge­
+         blendet. 
+ 
+ 
+PROC stdinfoedit (FILE VAR f):#u#(*)#e# 
+Zweck:   Wie obige 'stdinfoedit'-Prozedur'. Die Datei 'f' muß mit der Verarbei­
+         tungsart 'modify' assoziiert worden sein. 
+ 
+ 
+PROC stdinfoedit (TEXT CONST dateiname, 
+                  INT CONST oberste zeile):#u#(*)#e# 
+Zweck:   Wie obige Prozedur (die wie 'stdwinfoedit (w, 1)' wirkt). Allerdings kön­
+         nen bis zu zwei Zeilen oben auf dem Bildschirm unbenutzt bleiben (z.B.
+         um die Kopfzeile des Menus weiterhin anzuzeigen). 'oberste zeile' gibt an,
+         welche Bildschirmzeile die erste von dieser Prozedur benutzte ist
+         (1<= oberste zeile<=3). 
+ 
+ 
+PROC stdinfoedit (FILE VAR f, 
+                  INT CONST oberste zeile):#u#(*)#e# 
+Zweck:   Wie obige 'stdinfoedit'-Prozedur'. Die Datei 'f' muß mit der Verarbei­
+         tungsart 'modify' assoziiert worden sein. 
+ 
+ 
+#ib#stop#ie# 
+PROC stop (WINDOW VAR w, INT CONST zeilenzahl): 
+ 
+Zweck:   Vergl. 'menuwindowstop'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuwindowstop' automatisch gesetzt wird. 
+ 
+ 
+PROC stop (WINDOW VAR w): 
+ 
+  wirkt wie: stop (w, 1). 
+ 
+ 
+#ib#testinstallation#ie# 
+PROC testinstallation (TEXT CONST menutafelname): 
+ 
+Zweck:   Die Menutafel mit dem Namen 'menutafelname' (muß mit dem
+         'gs-MENUKARTE:' beginnen!) wird als aktuelle Menutafel an gs-DIALOG
+         gekoppelt. Durch den Befehl wird die angegebene Menutafel zur Task
+         'gs-MENUAKRTEN' geschickt. Dem Namen wird zur Kennzeichnung noch
+         der Taskname der Sendertask angehängt (dadurch können sich bei
+         Multi-User-Betrieb verschiedene Anwender mit gleichen Menukarten­
+         namen nicht stören). Die Menukarte wird anschließend in jedem Fall
+         "frisch" angekoppelt. Außerdem bleibt die Menukarte (als benannter
+         Datenraum) in der Task erhalten! 
+         (Mit dem Befehl 'handle menu' kann nun ein Menu aus der Menukarte
+         zur Ausführung gebracht werden oder mit 'anwendungstext' auf in die
+         Menukarte ausgelagerte Texte zugegriffen werden.) 
+         Hinweis: Von Zeit zu Zeit muß der Systembetreuer die überflüssigen
+         Menukarten aus der Task 'gs-MENUKARTEN' entfernen, da die Anwender
+         aus Ihrer Task die Karten nicht löschen können! 
+Fehler:  'menutafelname' gibt es nicht! 
+         'menutafelname' hat falsche(n) Typ/Bezeichnung (keine
+         gs-MENUKARTE)! 
+ 
+ 
+#ib#trennlinie#ie# 
+PROC trennlinie: 
+ 
+Zweck:   Der Befehl wird bei der Generierung von Menukarten benötigt. Durch den
+         Befehl wird unter dem aktuellen Oberbegriff eine Trennlinie zur opti­
+         schen Trennung einzelner Menupunkte eingetragen. Die Trennlinie belegt
+         den gleichen Platz wie eine Verarbeitungsfunktion. 
+Fehler:  Zu viele Menupunkte in einem Pull-Down-Menu (maximal 15 incl. der
+         Trennlinien!). 
+ 
+ 
+#ib#textprozedur#ie# 
+PROC textprozedur (TEXT CONST dateiname, 
+                              prozedurname): 
+ 
+Zweck:   Der Befehl wird benötigt, um Texte entsprechend der gs-DIALOG-Syntax
+         aufzuarbeiten. Der in die Datei 'dateiname' geschrieben Text wird bear­
+         beitet. Die Prozedur eignet sich insbesondere dafür, Informationstexte
+         aufzuarbeiten, die zu den einzelnen Menufunktionen ausgegeben werden,
+         wenn der Benutzer die Tastenfolge <ESC><?> tippt (sehen Sie auch
+         'textzeile'). Der aufbereitete Text steht anschließend in der Datei 'datei­
+         name.a'. Der Text ist in eine Textprozedur "verpackt", die den Namen hat,
+         der als zweiter Parameter übergeben wird. 
+         Die Zeilen werden dabei so zugeschnitten, daß Sie in einer Box in das
+         aktuelle Menu eingeblendet werden können. Boxbreite und -höhe werden
+         automatisch gesetzt (max. 65 Zeichen breit und 14 Zeichen hoch)); die
+         Zeilen werden geblockt, sofern in der Datei keine Absatzmarkierung
+         (<RETURN>) am Ende der Zeile vorhanden ist. Soll eine Zeile zentriert
+         werden, so muß als erstes Zeichen der Zeile das Zeichen '%' notiert sein -
+         die Zeile muß durch eine Absatzmarke abgeschlossen sein. Textpassagen,
+         die invers (markiert) dargestellt werden sollen, müssen duch das Zeichen
+         '$' eingeleitet und durch das Zeichen '&' abgeschlossen werden. Markier­
+         te Textpassagen dürfen (nach dem Zuschnitt!) nicht über Zeilengrenzen
+         hinausgehen! 
+Fehler:  Datei 'dateiname' existiert nicht! 
+         Fonttabelle 'fonttab.gs-Menu-Generator' existiert nicht! (Fonttabelle von
+         gs-Menu-Generator-Diskette in die Task 'configurator' laden!) 
+         Text ist zu lang - bitte kürzen! (Text darf in aufbereiteter Form maximal
+         14 Zeilen umfassen!) 
+         Zeilenformatierung mit <ESC> abgebrochen! 
+ 
+ 
+ 
+#ib#textzeile#ie# 
+PROC textzeile (TEXT CONST dateiname): 
+ 
+Zweck:   Der Befehl wird benötigt, um Texte entsprechend der gs-DIALOG-Syntax
+         aufzuarbeiten. Der in die Datei 'dateiname' geschrieben Text wird bear­
+         beitet. Die Prozedur eignet sich insbesondere dafür, anwendungsbezogene
+         Texte aufzuarbeiten, die in die Menukarte ausgelagert werden sollen
+         (sehen Sie auch 'textprozedur'). Der aufbereitete Text steht anschließend
+         in der Datei 'dateiname.a' in einer Zeile notiert. 
+ 
+ 
+#ib#waagerecht#ie# 
+TEXT PROC waagerecht: 
+ 
+Zweck:   Liefert das Zeichen, das bei der Darstellung der "Kästen" als waagerechter
+         Strich (̇) ausgegeben wird. 
+ 
+ 
+PROC waagerecht (TEXT CONST zeichen): 
+ 
+Zweck:   Durch diese Prozedur kann das Zeichen festgelegt werden, das bei Dar­
+         stellung der "Kästen" als waagerechter Strich ausgegeben werden soll. 
+ 
+ 
+#ib#window#ie# 
+WINDOW PROC window (INT CONST x, y, xsize, ysize): 
+ 
+Zweck:   Einer Fenstervariablen (WINDOW VAR name) wird die Lage und Größe
+         zugeordnet (über den Zuweisungsoperator ':='). Gleichzeitig wird das
+         Fenster initialisiert. 
+         Mit den ersten beiden Parametern wird die Lage der linken oberen Ecke
+         des Fensters bestimmt (x: Spalte; y: Zeile). Mit 'xsize' wird die Fenster­
+         breite, mit 'ysize' die Fensterhöhe festgelegt. 
+         Das Fenster wird noch nicht(!) angezeigt (sehen Sie dazu 'show' und
+         'page'). Ein Rahmen wird nicht zum Fenster gezählt; er kann aber mit
+         der Prozedur 'show' ausgegeben werden. Ein Fenster darf nicht breiter als
+         80 und höher als 24 Zeichen sein. Umrahmte Fenster unterliegen weite­
+         ren Einschränkungen (sehen Sie auch 'show'). Ein Fenster muß min­
+         destens 6 Zeichen breit und 3 Zeichen hoch sein. 
+Fehler:  'Window' ungültig 
+ 
+ 
+#ib#write menunotice#ie# 
+PROC write menunotice (TEXT CONST notiztext, 
+                       INT CONST position): 
+ 
+Zweck:   Die Prozedur dient dazu, innerhalb des Menus in einer Box einen "dauer­
+         haften Informationstext" auszugeben. Die Box bleibt nämlich so lange
+         bestehen, bis sie explizit gelöscht (sehen Sie auch 'erase menunotice')
+         oder durch einen neuen Notiztext überschrieben wird. Wenn der Bild­
+         schirm durch gs-DIALOG-Prozeduren überschrieben wird, wird die
+         Menunotiz ebenfalls ständig mitaufgefrischt und auch, wenn der Befehl
+         'regenerate menuscreen' oder 'refresh submenu' gegeben wird (Sehen Sie
+         im Gegensatz dazu auch 'menuinfo' ("kurzzeitiger Informationstext"). 
+         Im Menubildschirm erscheint der 'infotext' in einer Box. Boxbreite und
+         -höhe werden vom System automatisch anhand des übergebenen 'notiz­
+         text'es festgelegt. 'notiztext' muß den gs-DIALOG-Syntax-Regeln (sehen Sie
+         Kap. 5.13) entsprechen. Mit 'position' wird die relative Lage der Box
+         innerhalb des Menubildschirms festgelegt (1, 2, 3, 4, 5: sehen Sie dazu
+         Kap. 5.12). In einem Menu kann zu einem Zeitpunkt nur eine Menunotiz
+         abgelegt werden. Durch ein erneutes 'write menunotice' wir eine beste­
+         hende Menunotiz überschrieben. 
+ 
+ 
+#ib#yes#ie# 
+BOOL PROC yes (WINDOW VAR w, TEXT CONST frage): 
+ 
+Zweck:   Vergl. 'menuwindowyes'. Hier wird nur zusätzlich das Fenster festgelegt,
+         das bei 'menuwindowyes' automatisch gesetzt wird. 
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.impressum b/doc/menugenerator/menu-generator handbuch.impressum
new file mode 100644
index 0000000..404826d
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.impressum	
@@ -0,0 +1,88 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#ls Menü-Generator 
+ 
+ 
+ 
+ 
+#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# 
+ 
+#free (4.0)##on("b")# 
+#center#gs-Menu-Generator 
+ 
+ 
+#center#Benutzerhandbuch 
+ 
+ 
+#center#Version 1.0 
+ 
+ 
+#off("b")##center#copyright 
+#center#Eva Latta-Weber 
+#center#Software- und Hardware-Systeme, 1988 
+#center#ERGOS GmbH, 1990 
+#page# 
+#block# 
+#center#____________________________________________________________________________ 
+ 
+ 
+Copyright:  ERGOS GmbH   März 1990 
+ 
+                     Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+                     maschinenlesbare Form sowie das Speichern in Informations­
+                     systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+                     der ERGOS GmbH gestattet. 
+ 
+ 
+#center#____________________________________________________________________________ 
+ 
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender. 
+ 
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden. 
+ 
+Texterstellung   :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+                   erstellt und aufbereitet und auf einem Kyocera Laser­
+                   drucker gedruckt. 
+ 
+ 
+ 
+ 
+#center#___________________________________________________________________________ 
+ 
+ 
+ 
+Ergonomic Office Software GmbH 
+ 
+Bergstr. 7              Telefon: (02241) 63075 
+5200 Siegburg           Teletex: 2627-2241413=ERGOS 
+                        Telefax: (02241) 63078 
+ 
+ 
+#center#____________________________________________________________________________ 
+
diff --git a/doc/menugenerator/menu-generator handbuch.index b/doc/menugenerator/menu-generator handbuch.index
new file mode 100644
index 0000000..0aacd97
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.index	
@@ -0,0 +1,258 @@
+#block##pageblock# 
+#pagenr("%",1)##setcount(1)##count per page# 
+#headeven# 
+gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#right#gs-Menu-Generator 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+I - % #right#ERGOS 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+ERGOS #right# I - % 
+#end# 
+Index 
+ 
+ 
+activate                                            5 - 28 
+activate                                            8 - 1 
+anwendungstext                                      4 - 13 
+anwendungstext                                      8 - 2 
+areax                                               8 - 2 
+areaxsize                                           8 - 2 
+areay                                               8 - 2 
+areaysize                                           8 - 2 
+balken links                                        8 - 2 
+balken oben                                         8 - 3 
+balken rechts                                       8 - 3 
+balken unten                                        8 - 3 
+boxalternative                                      8 - 4 
+boxalternative                                      7 - 10 
+boxanswer                                           8 - 4 
+boxanswer                                           7 - 9 
+boxanswerone                                        8 - 4 
+boxanswerone                                        7 - 10 
+boxanswersome                                       8 - 5 
+boxanswersome                                       7 - 10 
+boxinfo                                             8 - 5 
+boxinfo                                             7 - 9 
+boxno                                               8 - 5 
+boxno                                               7 - 10 
+boxnotice                                           8 - 6 
+boxnotice                                           7 - 10 
+boxone                                              8 - 6 
+boxone                                              7 - 10 
+boxsome                                             8 - 6 
+boxsome                                             7 - 10 
+boxyes                                              8 - 7 
+boxyes                                              7 - 10 
+center                                              8 - 7 
+center                                              7 - 8 
+clear buffer                                        8 - 7 
+clear buffer and count                              8 - 7 
+current menuwindow                                  8 - 8 
+cursor                                              8 - 8 
+cursor                                              7 - 6 
+cursor off                                          8 - 8 
+cursor off                                          5 - 6 
+cursor off                                          5 - 2 
+cursor on                                           8 - 8 
+cursor on                                           5 - 6 
+cursor on                                           5 - 2 
+deactivate                                          8 - 9 
+deactivate                                          5 - 28 
+direktstart                                         8 - 9 
+ecke oben links                                     8 - 10 
+ecke oben rechts                                    8 - 10 
+ecke unten links                                    8 - 10 
+ecke unten rechts                                   8 - 10 
+edit                                                8 - 11 
+edit                                                7 - 6 
+editget                                             8 - 11 
+erase                                               7 - 5 
+erase                                               8 - 11 
+erase footnote                                      8 - 12 
+erase footnote                                      7 - 11 
+erase menunotice                                    8 - 12 
+erasemenunotice                                     5 - 15 
+get                                                 8 - 12 
+get                                                 7 - 7 
+get cursor                                          8 - 13 
+get cursor                                          7 - 6 
+getline                                             7 - 7 
+getline                                             8 - 13 
+get menuwindowcursor                                5 - 21 
+get menuwindowcursor                                8 - 13 
+handle menu                                         3 - 2 
+handle menu                                         8 - 13 
+infix namen                                         8 - 14 
+infix namen                                         5 - 26 
+install menu                                        3 - 2 
+install menu                                        4 - 3 
+install menu                                        8 - 14 
+invers                                              8 - 15 
+kreuz                                               8 - 15 
+line                                                8 - 15 
+line                                                7 - 6 
+menualternative                                     8 - 15 
+menualternative                                     5 - 12 
+menuanswer                                          8 - 17 
+menuanswer                                          5 - 2 
+menuanswerone                                       8 - 17 
+menuanswerone                                       5 - 8 
+menuanswersome                                      5 - 8 
+menuanswersome                                      8 - 18 
+menu archiv checken                                 8 - 18 
+menu archiv checken                                 6 - 4 
+menu archiv grundeinstellung                        6 - 4 
+menu archiv grundeinstellung                        8 - 18 
+menu archiv holen                                   8 - 19 
+menu archiv holen                                   6 - 4 
+menu archiv initialisieren                          8 - 19 
+menu archiv initialisieren                          6 - 4 
+menu archiv loeschen                                8 - 19 
+menu archiv loeschen                                6 - 4 
+menu archiv neue diskette                           8 - 19 
+menu archiv neue diskette                           6 - 4 
+menu archiv reservieren                             6 - 4 
+menu archiv reservieren                             8 - 19 
+menu archiv reservierung aufgeben                   6 - 4 
+menu archiv reservierung aufgeben                   8 - 19 
+menu archiv schreibcheck                            8 - 20 
+menu archiv schreibcheck                            6 - 4 
+menu archiv schreiben                               6 - 4 
+menu archiv schreiben                               8 - 20 
+menu archiv verzeichnis                             8 - 20 
+menu archiv verzeichnis                             6 - 4 
+menu archiv verzeichnis drucken                     6 - 4 
+menu archiv verzeichnis drucken                     8 - 20 
+menu archiv zieltask einstellen                     6 - 4 
+menu archiv zieltask einstellen                     8 - 20 
+menu dateien aufraeumen                             8 - 21 
+menu dateien aufraeumen                             6 - 6 
+menu dateien drucken                                6 - 6 
+menu dateien drucken                                8 - 21 
+menu dateien kopieren                               6 - 6 
+menu dateien kopieren                               8 - 22 
+menu dateien loeschen                               8 - 22 
+menu dateien loeschen                               6 - 6 
+menu dateien speicherplatz                          6 - 6 
+menu dateien speicherplatz                          8 - 22 
+menu dateien umbenennen                             8 - 23 
+menu dateien umbenennen                             6 - 6 
+menu dateien verzeichnis                            6 - 6 
+menu dateien verzeichnis                            8 - 23 
+menufootnote                                        5 - 17 
+menufootnote                                        8 - 23 
+menufunktion                                        4 - 6 
+menufunktion                                        8 - 24 
+menuinfo                                            5 - 4 
+menuinfo                                            8 - 24 
+menukartenname                                      8 - 25 
+menuno                                              8 - 25 
+menuno                                              5 - 10 
+menuone                                             5 - 6 
+menuone                                             8 - 25 
+menusome                                            5 - 7 
+menusome                                            8 - 26 
+menuwindowcenter                                    8 - 26 
+menuwindowcenter                                    5 - 23 
+menuwindowcursor                                    5 - 21 
+menuwindowcursor                                    8 - 27 
+menuwindowedit                                      8 - 27 
+menuwindowedit                                      5 - 19 
+menuwindoweditget                                   8 - 27 
+menuwindoweditget                                   5 - 22 
+menuwindowget                                       8 - 28 
+menuwindowget                                       5 - 22 
+menuwindowline                                      8 - 28 
+menuwindowline                                      5 - 21 
+menuwindowno                                        5 - 22 
+menuwindowout                                       5 - 22 
+menuwindowout                                       8 - 28 
+menuwindowpage                                      8 - 29 
+menuwindowpage                                      5 - 20 
+menuwindowshow                                      5 - 19 
+menuwindowshow                                      8 - 29 
+menuwindowstop                                      5 - 23 
+menuwindowstop                                      8 - 29 
+menuwindowyes                                       5 - 22 
+menuyes                                             5 - 10 
+menuyes                                             8 - 30 
+no                                                  8 - 30 
+no                                                  7 - 7 
+not empty                                           5 - 27 
+not empty                                           8 - 30 
+oberbegriff                                         8 - 31 
+oberbegriff                                         4 - 5 
+oeffne menu                                         8 - 31 
+oeffne menu                                         4 - 3 
+oeffne menukarte                                    8 - 32 
+oeffne menukarte                                    4 - 3 
+ohne praefix                                        5 - 26 
+ohne praefix                                        8 - 32 
+oldmenufootnote                                     5 - 17 
+old menufootnote                                    8 - 32 
+out                                                 7 - 7 
+out                                                 8 - 33 
+out footnote                                        7 - 11 
+out footnote                                        8 - 33 
+out frame                                           8 - 33 
+out frame                                           7 - 5 
+page                                                8 - 33 
+page                                                7 - 11 
+page                                                7 - 5 
+page up                                             7 - 11 
+put                                                 8 - 33 
+put                                                 7 - 7 
+putline                                             8 - 34 
+putline                                             7 - 7 
+refresh submenu                                     5 - 18 
+refresh submenu                                     8 - 34 
+regenerate menuscreen                               8 - 34 
+regenerate menuscreen                               5 - 18 
+regenerate menuscreen                               5 - 4 
+remaining lines                                     8 - 34 
+remaining lines                                     7 - 6 
+remaining menuwindowlines                           5 - 21 
+remaining menuwindowlines                           8 - 34 
+reset dialog                                        8 - 35 
+schliesse menu                                      4 - 3 
+schliesse menu                                      8 - 35 
+schliesse menukarte                                 8 - 35 
+schliesse menukarte                                 4 - 3 
+senkrecht                                           8 - 35 
+show                                                8 - 35 
+show                                                7 - 5 
+show                                                8 - 36 
+show                                                7 - 6 
+show menuwindow                                     8 - 36 
+show menuwindow                                     5 - 20 
+stdinfoedit                                         8 - 36 
+stop                                                7 - 8 
+stop                                                8 - 37 
+testinstallation                                    8 - 37 
+testinstallation                                    4 - 3 
+textprozedur                                        4 - 8 
+textprozedur                                        8 - 38 
+text zeile                                          4 - 13 
+textzeile                                           8 - 39 
+trennlinie                                          4 - 6 
+trennlinie                                          8 - 38 
+waagerecht                                          8 - 39 
+WINDOW                                              7 - 2 
+window                                              7 - 4 
+window                                              8 - 40 
+write menunotice                                    8 - 40 
+write menunotice                                    5 - 15 
+yes                                                 7 - 7 
+yes                                                 8 - 41 
+
+
diff --git a/doc/menugenerator/menu-generator handbuch.inhalt b/doc/menugenerator/menu-generator handbuch.inhalt
new file mode 100644
index 0000000..8b1aef4
--- /dev/null
+++ b/doc/menugenerator/menu-generator handbuch.inhalt	
@@ -0,0 +1,72 @@
+#type ("elite.lq")##limit (11.5)##pagelength (16.5)##pageblock# 
+#start (1.8,0.0)# 
+#type ("prop.breit.lq")# 
+Inhaltsverzeichnis 
+#type ("elite.lq")# 
+ 
+ 
+1       Was kann ls-Menu-Generator                   3 
+ 
+2       Installation von ls-Menu-Generator           6 
+2. 1    Voraussetzungen                              6 
+2. 2    Lieferumfang                                 6 
+2. 3    Installation                                 7 
+ 
+3       Die Arbeitsweise von ls-DIALOG               8 
+3. 1    Ankoppeln einer Menukarte/                   8 
+        Ausführen eines Menus 
+3. 2    Aufbau/Inhalt einer Menukarte               11 
+ 
+4.      Erstellen einer neuen Menukarte             13 
+4. 1    Eintragen der Menupunkte                    13 
+4. 2    Erstellung und Einbinden von                20 
+        Informationstexten 
+4. 3    Auslagerung von anwendungsbezogenen         24 
+        Texten in die Menukarte 
+ 
+5.      Dialoge innerhalb des Menus                 27 
+5. 1    Eingabe eines Textes/Namens                 28 
+5. 2    Ausgabe einer Information                   31 
+5. 3    Auswahl eines Namen durch Ankreuzen         32 
+5. 4    Auswahl mehrerer Namen durch Ankreuzen      34 
+5. 5    Eingabe eines Textes/Namens - alternativ:   35 
+        Auswahl durch Ankreuzen 
+5. 6    Die Ja/Nein - Entscheidung                  37 
+5. 7    Die Alternativentscheidung                  39 
+5. 8    Die Menunotiz                               43 
+5. 9    Fußzeilen im Menu                           44 
+5.10    Wiederherstellung des Menubildschirms       46 
+5.11    Arbeiten im Menufenster                     47 
+5.11.1  Datei anzeigen/editieren                    48 
+5.11.2  Menufenster öffnen/anzeigen                 48 
+5.11.3  Menufenster löschen(putzen)                 49 
+5.11.4  Positionierungen im Menufenster             49 
+5.11.5  Informationen über die aktuelle             50 
+        Menu-Fensterposition 
+5.11.6  Aus-/Eingabe innerhalb des Menufensters     51 
+5.11.7  Weitere Prozeduren                          52 
+5.12    Festlegung der Boxpositionen innerhalb      53 
+        des Menus 
+5.13    ls-DIALOG-Syntax                            54 
+        (Regeln zur Erstellung von Texten) 
+5.14    Thesaurushandling                           55 
+5.15    Aktivieren/Deaktivieren von Menupunkten     57 
+ 
+6.      Einbinden der Datei- und Archivoperationen  59 
+6. 1    Einbinden der Archivoperationen             60 
+6. 2    Einbinden der Dateioperationen              65 
+ 
+7.      Eigene Fenster und Fensteroperationen       66 
+7. 1    Definition von Fenstern                     67 
+7. 2    Anzeigen/Löschen von Fenstern               70 
+7. 3    Operationen innerhalb des Fensters          71 
+7. 3.1  Datei anzeigen/editieren                    71 
+7. 3.2  Positionierungen im Fenster                 72 
+7. 3.3  Ein- und Ausgaben innerhalb des Fensters    73 
+7. 3.4  Weitere Prozeduren                          74 
+7. 4    Boxoperationen                              75 
+ 
+8.      Kurzbeschreibung der Befehle                78 
+ 
+9.      Register                                   125 
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Inhaltsverzeichnis b/doc/mp-bap/A5 - Doku: gs-MP BAP - Inhaltsverzeichnis
new file mode 100644
index 0000000..9507802
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Inhaltsverzeichnis	
@@ -0,0 +1,50 @@
+#limit (11.5)##pagelength (16.5)##pageblock# 
+#start (1.8,0.0)# 
+Inhaltsverzeichnis 
+ 
+ 
+1     Was kann gs-MP BAP                             3 
+ 
+2     Allgemeines zum Simulationsprogramm            6 
+2.1   Entstehung                                     6 
+2.2   Beschreibung des Programmkerns                 7 
+      - ein Simulationslauf                            
+2.3   Das Teilprogramm 'Materialprüfung'             9 
+2.4   Das Teilprogramm 'Bildschirmarbeitsplatz'     10 
+2.5   Hinweise zum Einsatz des Programmsystems      12 
+2.6   Erfahrungen mit dem Programmsystem            13 
+2.7   Hinweise auf Arbeitsmaterial                  14 
+ 
+3     Installation von gs-MP BAP                    16 
+3.1   Voraussetzungen                               16 
+3.2   Lieferumfang                                  16 
+3.3   Installation                                  17 
+3.4   Organisation des Task - Systems               19 
+3.5   Direktstart des Systems                       20 
+ 
+4     Eine kleine Beispielsitzung                   22 
+4.1   Aufruf von 'Bildschirmarbeitsplatz' (BAP)     22 
+4.2   Einstellung von Simulationsparametern         23 
+4.3   Ein Simulationslauf                           26 
+4.4   Die Simulationsauswertung/das Protokoll       28 
+4.5   Hinweise zur Protokollauswertung              36 
+4.5.1 Der Bewertungsfaktor                          36 
+4.5 2 Fehlerzeichenhäufigkeit in den Werkstücken    38 
+4.5 3 Fehlerhafte Auswertungen                      38 
+ 
+5     Beschreibung der Menufunktionen               40 
+5.1   Kurzhinweise zur Bedienung der Menus          40 
+5.2   Menufunktionen z. Oberbegriff 'Simulation'    44 
+5.3   Menufunktionen z. Oberbegriff 'Parameter'     48 
+5.4   Menufunktionen z. Oberbegriff 'Konfiguration' 56 
+5.5   Menufunktionen z. Oberbegriff 'Dateien'       58 
+5.6   Menufunktionen z. Oberbegriff 'Archiv'        60 
+ 
+6     Hinweise für den Systembetreuer               61 
+
+
+
+
+
+
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1
new file mode 100644
index 0000000..e418764
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 1	
@@ -0,0 +1,119 @@
+#type ("12.lq")##limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (3)# 
+#headodd# 
+#center#gs-MP BAP#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-MP BAP 
+ 
+#end# 
+#center#1 
+ 
+#center#Was 
+#center#kann 
+#center#gs-MP BAP 
+ 
+ 
+   #on("b")#gs-MP BAP#off("b")# ist ein Programm, mit dem die Arbeit
+an einem Bildschirmarbeitsplatz unter ganz unter­
+schiedlichen Aspekten simuliert werden kann. Vom
+Benutzer wird dabei verlangt, eine Art "Kontrolltä­
+tigkeit am Bildschirm" auszuüben. Während dieser
+Arbeit werden Daten über den Arbeitsverlauf erfaßt,
+die (später) ausgewertet werden können. 
+   #on("b")#gs-MP BAP#off("b")# ist so gestaltet, daß es für ganz un­
+terschiedliche Zwecke eingesetzt werden kann. Es
+ist möglich, sämtliche Simulationsparameter den
+eigenen Wünschen und der jeweiligen Situation an­
+zupassen. Daneben besteht die Möglichkeit, die Si­
+mulationsprotokolle offensichtlich oder "heimlich"
+zu erfassen. 
+   #on("b")#gs-MP BAP#off("b")# kann dazu benutzt werden, um Anwendern
+lediglich die Belastungen eines Bildschirmarbeits­
+platzes an einem Beispiel darzulegen; es ist aber
+genauso möglich, ihm eindrucksvoll aufzuzeigen, wie
+eine Kontrolle am Bildschirmarbeitsplatz - ohne
+sein Wissen - erfolgen kann. Auf der Basis dieser
+Erfahrungen lassen sich dann ganz neue Fragestel­
+lungen thematisieren (Möglichkeiten/Befugnis der/
+zur Kontrolle am (Bildschirm-) Arbeitsplatz; Daten­
+schutz; Betriebsvereinbarungen zu Computerarbeits­
+plätzen und vieles mehr). 
+   Durch die Möglichkeit, die Simulationsparameter
+vielfältig zu variieren, können verschiedenste Un­
+tersuchungen mit dem Programm durchgeführt werden:
+Angefangen von Untersuchungen zur Konzentrations­
+fähigkeit bei unterschiedlichen Umgebungsbedingun­
+gen (z.B. Lichtverhältnisse, Musik am Arbeitsplatz,
+etc.), über Untersuchungen zum optimalen Arbeits­
+phasen - Pausen - Rhythmus (z.B. zur Fragestellung,
+ob lange Arbeitsphasen mit langen Pausen günstiger
+sind als kurze Arbeitsphasen mit immer wieder ein­
+gestreuten kleineren Pausen oder umgekehrt - wenn
+die Gesamtzeit konstant ist), bis hin zu Untersu­
+chungen zur Ergonomie von Computerarbeitsplätzen
+(z.B. hinsichtlich der Tastaturbelegung, Nützlich­
+keit eines eigenen Cursorblockes, etc.). 
+   Anhand der aufgezeigten Möglichkeiten wird
+sicher deutlich, daß der Einsatz des Programms
+nicht auf den Informatikunterricht beschränkt ist.
+Ebensogut ist, bei entsprechender Fragestellung,
+ein Einsatz im gesellschafts- / sozialwissenschaft­
+lichen Unterricht, im Biologieunterricht, in den
+kaufmännischen Lernbereichen oder im Technikunter­
+richt denkbar. Das Programm ist auch für die Aufar­
+beitung verschiedener Fragestellungen bei der Vor-
+und Nachbereitung von Betriebspraktika geeignet. 
+   Um all diese Möglichkeiten auch den Ausbildern
+offenzuhalten, die keinerlei Vorerfahrungen mit
+Computern haben, aber dieses Programm einsetzen
+möchten, ist die Simulationsumgebung so komforta­
+bel, daß jeder Benutzer innerhalb weniger Minuten
+das gesamte Programmsystem überblicken und bedienen
+kann. 
+ 
+-  Durch die Einbettung in die komfortable Benut­
+   zerschnittstelle #on("b")#gs-DIALOG#off("b")#, sind nur noch wenige
+   Betriebssystemkommandos zur Bedienung des Sy­
+   stems notwendig. 
+ 
+-  Der Benutzer kann jederzeit Informationen über
+   die Bedienung des Menusystems und die Wirkung
+   der einzelnen Menufunktionen anfordern, die ihm
+   daraufhin in den aktuellen Bildschirm eingeblen­
+   det werden. 
+ 
+-  Dem Benutzer wird ständig angezeigt, welche Mög­
+   lichkeiten der Bedienung bestehen, welche Tasten
+   wirksam sind und welche Wirkung deren Betätigung
+   hat. Menufunktionen, deren Wirkungen zu bestimm­
+   ten Zeitpunkten sinnlos oder fehlerhaft wären,
+   werden "inaktiviert", d.h. sind dem Benutzer gar
+   nicht erst zugänglich. 
+ 
+-  Die Auswertung der Simulationsprotokolle erfolgt
+   vom Menu aus durch einfaches Ankreuzen der ge­
+   wünschten Protokolldateien. Es besteht sowohl
+   die Möglichkeit, die Auswertungen auf dem Bild­
+   schirm anzeigen als auch über den Drucker ausge­
+   ben zu lassen. 
+ 
+-  Die Festlegung der Simulationsparameter ist kin­
+   derleicht. Die aktuell eingestellten Werte kön­
+   nen jederzeit eingesehen werden. Zur Einstellung
+   werden umfangreiche Informationen und Hilfen
+   ausgegeben. Eine Fehlbedienung ist ausgeschlos­
+   sen. 
+ 
+-  In das System ist eine komfortable Archivbehand­
+   lung integriert, so daß auch für den Computer­
+   laien die Konservierung der Simulationsergebnis­
+   se auf einfachste Weise möglich ist. 
+ 
+-  Bei auftretenden Fehlern erhält der Benutzer
+   konkrete, verständliche Fehlermeldungen, die
+   zumeist mit einem Zusatz versehen sind, wie die
+   "Situation bereinigt werden kann". 
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2
new file mode 100644
index 0000000..b063ea3
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 2	
@@ -0,0 +1,302 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (6)# 
+#headodd# 
+#center#gs-MP BAP#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-MP BAP 
+ 
+#end# 
+#center#2 
+ 
+#center#Allgemeines 
+#center#zum 
+#center#Simulationsprogramm 
+ 
+ 
+2.1  Entstehung 
+ 
+  Das Simulationsprogramm #on("b")#gs-MP BAP#off("b")# basiert auf
+einer Idee von Hartmut Spenn und Mene Wolf, die
+eine Unterrichtsreihe mit dem Titel "Der gläserne
+Arbeiter" im Rahmen der Materialien zur Lehrerfort­
+bildung in Nordrhein Westfalen (Neue Technologien,
+informations- und kommunikationstechnologische In­
+halte im Wahlpflichtunterricht der Klassen 9/10)
+beschrieben und dazu ein Grundprogramm für den C64
+in COMAL geschrieben haben. 
+   Dieses Grundprogramm diente einmal als Ausgangs­
+punkt für #on("b")#gs-MP BAP#off("b")#. Allerdings wuchsen die An­
+sprüche an das System immer mehr, so daß eine Reihe
+weiterer Funktionen hinzugefügt wurden. Ein wesent­
+liches Ziel war es, ein Simulationsprogramm zur
+Verfügung zu stellen, daß umfangreiche Variations­
+möglichkeiten - ohne jegliche Programmierkenntnisse
+- bietet; ein Programm, das selbst von einem völli­
+gen Computerlaien innerhalb weniger Minuten über­
+blickt und sicher bedient werden kann. 
+ 
+   Erst als die komfortable Benutzerschnittstelle
+#on("b")#gs-DIALOG#off("b")# zur Verfügung stand, konnte dieses Ziel
+erreicht werden. Heute präsentiert sich Ihnen ein
+Programmsystem, in dem Sie jede Programmfunktion
+von einem Menu aus wählen können. Durch Informa­
+tionstexte, die Sie jederzeit abrufen können, und
+durch die Bedienungshinweise werden Sie sicher
+durch das Programmsystem geführt. Sie haben komfor­
+table Möglichkeiten, die Simulationsparameter zu
+variieren. Das Programmsystem ist gegen Fehlbedie­
+nungen mehrfach abgesichert. 
+ 
+ 
+2.2  Beschreibung des Programmkerns 
+      - ein Simulationslauf 
+ 
+   Mit #on("b")#gs-MP BAP#off("b")# kann die Arbeit an einem Bild­
+schirmarbeitsplatz simuliert werden. Der Benutzer
+übt am Bildschirm eine Art "Kontrolltätigkeit" aus.
+Die Interpretation dieser Tätigkeit ist offen: So
+kann man sich vorstellen, daß "Werkstücke" auf dem
+Bildschirm angezeigt werden, die auf Fehler hin
+untersucht werden sollen; dabei muß jeder gefundene
+Fehler markiert werden. Der Benutzer kann sich auch
+vorstellen, er sei bei einer Tageszeitung beschäf­
+tigt und habe die aus der Redaktion eingehenden
+Artikel auf Tippfehler hin zu untersuchen - natür­
+lich müssen die Tippfehler "verbessert" werden.
+Andere Interpretationen sind denkbar. 
+   Das Grundprinzip des Simulationslaufes ist recht
+einfach - ein typischer Bildschirm könnte so ausse­
+hen: 
+#free (9.5)# 
+   Im oberen Bereich des Bildschirms werden alle
+Daten angezeigt, die der Benutzer während des Simu­
+lationslaufes benötigt. Links oben sind alle Tasten
+angegeben, die für die Handhabung des Programms
+notwendig sind. Rechts oben wird der Benutzer über
+die Simulationszeiten und das festgelegte 'Fehler­
+zeichen' informiert. 
+   Im unteren Bereich des Bildschirms wird ein
+rechteckiger Block ausgegeben, der sich aus ver­
+schiedenen Zeichen (z.B. Buchstaben, Ziffern, Son­
+derzeichen) zusammensetzt. Der Benutzer hat jetzt
+die Aufgabe, die Blöcke daraufhin zu untersuchen,
+ob in ihnen das angegebene Fehlerzeichen auftaucht. 
+   Entdeckt er solche Zeichen im Block auf dem
+Bildschirm, so ist es seine Aufgabe, den Cursor
+(Lichtfleck) auf dem Bildschirm mit Hilfe festge­
+legter Tasten an die entsprechende Position zu
+steuern und eine 'Ausbesserung' (Kennzeichnung/
+Korrektur) vorzunehmen. Ist der Benutzer der Mei­
+nung, alle Fehlerzeichen bearbeitet zu haben, so
+kann er den nächsten Block (das nächste Werkstück/
+den nächsten Artikel) durch Tippen einer festgeleg­
+ten Taste anfordern. 
+   Die Arbeit ist dabei streng in 'Arbeitsphasen'
+und 'Pausen' eingeteilt - der Rhythmus wird aber
+vom Programm und nicht vom Benutzer bestimmt. Wäh­
+rend des Simulationslaufes werden alle wesentlichen
+Kenndaten protokolliert. Diese können später ausge­
+wertet werden. 
+   In unserem konkreten Beispiel hat der Benutzer
+nach dem Fehlerzeichen 'F' zu suchen. Er hat insge­
+samt 34 Minuten zu arbeiten; dabei ist seine Ar­
+beitszeit eingeteilt in 3 Arbeitsphasen zu je 10
+Minuten mit zwei dazwischenliegenden Pausen von je
+2 Minuten. 
+   Zur Bedienung des Systems kann er die (Cursor-)
+Pfeiltasten <rechts>, <links>, <hoch> und <runter>
+benutzen; damit kann er den Lichtfleck innerhalb
+des Zeichen-Blocks bewegen. Zur Ausbesserung dient
+die <HOP>-Taste. Mit der <ESC>-Taste kann er je­
+weils die neuen Werkstücke (Artikel) zur Bearbei­
+tung anfordern. 
+ 
+ 
+2.3  Das Teilprogramm 'Materialprüfung' (MP) 
+ 
+   Gemeinsamer Bestandteil beider Programmteile ist
+der sogenannte "Simulationslauf" - ein eben ge­
+schilderter Arbeitsprozeß am Bildschirm. Diesem
+Simulationslauf gehen im Teilprogramm 'Materialprü­
+fung' (MP) jedoch noch umfangreiche Informationen
+voraus, die dem Benutzer die anschließend zu ver­
+richtende Tätigkeit detailliert erläutern. Gleich
+nach Aufruf des Programmteils wird der Benutzer
+noch nach einer "Identifikation" gefragt und aufge­
+fordert, z.B. den Vor- und Nachnamen einzugeben.
+Die hier eingegebene Kennung ist auch Bestandteil
+des Namens des Protokolls, das über den dann fol­
+genden Simulationslauf angelegt wird. 
+   Am Ende des Simulationslaufes wird dem Benutzer,
+sofern das System entsprechend konfiguriert ist,
+eine 'Kurzauswertung' seiner Arbeit auf dem Bild­
+schirm präsentiert. Zusätzlich wird - ohne daß der
+Benutzer es merkt - das angelegte Protokoll in die
+Vatertask geschickt und in der eigenen Task ge­
+löscht. 
+ 
+ 
+2.4  Das Teilprogramm 'Bildschirmarbeitsplatz'
+     (BAP) 
+ 
+   Nach Aufruf des Teilprogramms erscheint auf dem
+Bildschirm ein Menu, von dem aus eine Vielzahl von
+Funktionen gewählt werden kann. Natürlich ist es
+auch von hier aus möglich, einen oben beschriebenen
+Simulationslauf zu starten. Im Gegensatz zum Pro­
+grammteil 'Materialprüfung' wird hier aber auf die
+umfangreichen Informationen zur Handhabung des
+Systems verzichtet und zum Abschluß auch keine Pro­
+tokolldatei zur Vatertask geschickt - die Proto­
+kolldatei verbleibt in der eigenen Task. 
+   Daneben können vom Menu aus auch Protokolldatei­
+en ausgewertet werden. Sie können dabei noch ent­
+scheiden, ob Sie die Auswertungen auf dem Bild­
+schirm angezeigt oder aber auf dem angeschlossenen
+Drucker ausgegeben haben möchten. 
+   Weiterhin können Sie sämtliche Simulationspara­
+meter vom Menu aus Ihren Wünschen gemäß einstellen.
+So ist es möglich, die Breite und Höhe des Werk­
+stücks zu variieren und zu entscheiden, ob die
+Werkstücke "normal" oder "invers" dargestellt wer­
+den sollen. Sie können das 'Fehlerzeichen' festle­
+gen und überhaupt die Zeichen bestimmen, aus denen
+die Werkstücke aufgebaut werden. Daneben haben Sie
+noch die Möglichkeit, zu bestimmen, welche Tasten
+auf der Tastatur welche Funktion beim Simulations­
+lauf haben sollen. 
+   Sie legen von hier aus auch fest, in wie viele
+Arbeitsphasen die Arbeitszeit unterteilt wird und
+wie lange eine einzelne Arbeitsphase und die zwi­
+schen den Arbeitsphasen liegende Pause dauern sol­
+len. Auch hinsichtlich der Bewertung können Sie
+Festlegungen treffen - nach dem von Ihnen hier ein­
+gestellten Wertungsschlüssel werden nämlich die
+Protokolldateien ausgewertet. 
+   Ihnen obliegt es auch, zu bestimmen, ob mit je­
+der Protokollauswertung die umfangreichen Erläute­
+rungen ausgegeben werden sollen und ob der Benutzer
+am Ende eines Simulationslaufes eine 'Kurzauswer­
+tung' über seine Arbeit auf dem Bildschirm erhalten
+soll oder nicht. 
+   Zusätzlich werden Ihnen noch eine Reihe von Mög­
+lichkeiten zur Datei- und Archivbehandlung angebo­
+ten. So können Sie komfortabel Dateien löschen,
+kopieren, umbenennen, etc., Dateien auf Diskette
+konservieren oder gespeicherte Dateien von dort
+holen und vieles mehr. 
+ 
+ 
+2.5  Hinweise zum Einsatz des Programmsystems 
+ 
+   Aus den Beschreibungen in 2.3 und 2.4 ist Ihnen
+sicher schon die unterschiedliche Absicht, die hin­
+ter den beiden Programmteilen steckt, klar gewor­
+den. Die beiden Programmteile richten sich nämlich
+auch an ganz unterschiedliche Nutzergruppen. 
+   Das Teilprogramm 'Materialprüfung' (MP) ist vor­
+nehmlich für den 'unerfahrenen'/'unbefangenen' Be­
+nutzer gedacht. Ihm werden nämlich umfangreiche
+Informationen ausgegeben. Mit diesem Programmteil
+ist eben auch die "heimliche" Erfassung der Simula­
+tionsdaten möglich. Dieser Teil des Programms wird
+sicherlich dann Anwendung finden, wenn die Fragen
+um die Möglichkeiten und Gefahren der Kontrolle am
+(Bildschirm-) Arbeitsplatz im Vordergrund der Be­
+trachtungen stehen. 
+   Das Teilprogramm 'Bildschirmarbeitsplatz' (BAP)
+hat zumindest zwei ganz unterschiedliche Einsatz­
+aspekte: 
+ 
+   Einerseits dient es dem Lehrer/Ausbilder dazu,
+die gewünschten Simulationsparameter für das Teil­
+programm 'Materialprüfung' einzustellen. Die aktu­
+elle Einstellung, die mit dem Teilprogramm 'Bild­
+schirmarbeitsplatz' getroffen wurde, ist in der
+jeweilgen Task gültig, in der die Einstellung vor­
+genommen wurde. Die Einstellung wird aber auch von
+allen Sohntasks übernommen, die sich nach der je­
+weiligen Einstellung neu anmelden. Darüber hinaus
+dient dieses Teilprogramm dem Lehrer/Ausbilder
+dazu, die (ihm zugestellten) Simulationsprotokolle
+auszuwerten. 
+   Andererseits hat das Teilprogramm 'Bildschirm­
+arbeitsplatz' auch einen "eigenen Charakter":
+Gerade bei den schon oben angesprochenen Untersu­
+chungen (zur Konzentrationsfähigkeit in Abhängikeit
+von verschiedenen Faktoren, zur Bedeutung der Ar­
+beitsphasen-Pausen-Rhythmen, zur 'Ergonomie am Ar­
+beitsplatz', etc.) bietet sich hier ein schneller,
+komfortabler Wechsel zwischen Parametereinstellung
+und Simulationsläufen - ohne unnötigen Zeitverlust;
+erst recht, wenn mehrere Simulationsläufe aufeinan­
+der folgen. 
+ 
+ 
+2.6  Erfahrungen mit dem Programmsystem 
+ 
+   Das Programmsystem wurde bereits in verschiede­
+nen Klassen/ Kursen ab der Jahrgangsstufe 8 einge­
+setzt, und zwar in verschiedenen Fachbereichen und
+Schulformen. Die Akzeptanz ist sehr hoch; die Hand­
+habung des Programmsystems bereitete selbst Kolle­
+gen, die noch nie zuvor an einem Computer gesessen
+hatten, keinerlei Schwierigkeiten. Von der Hand­
+habung des Programms her ist deshalb sicher auch
+keine Alteruntergrenze hinsichtlich der "Eignung"
+anzugeben. 
+   Jedoch scheint eine Bearbeitung mit den oben
+angegebenen Zielsetzungen erst auf dem Erfahrungs­
+horizont der Jahrgangsstufe 8 sinnvoll zu sein.
+Eine Bearbeitung der Fragestellungen in der von
+Hartmut Spenn und Mene Wolf (siehe Kapitel 2.7)
+vorgeschlagenen Tiefe scheint allerdings erst am
+Ende der Jahrgangsstufe 9 bzw. in der Jahrgangsstu­
+fe 10 erreichbar. 
+   Besonders interessant scheint der Einsatz bei
+der Vor- bzw. Nachbereitung von Betriebspraktika zu
+sein. Durch die unmittelbare Berührung mit den
+"neuen Technologien am Arbeitsplatz" ist das Inter­
+esse an der Bearbeitung entsprechender Fragestel­
+lungen sehr hoch und eine Sensibilisierung für die
+angesprochenen Problematiken zu erreichen. 
+   Die angegebenen Fragestellungen im Zusammenhang
+mit diesem Programmsystem können auch Thema einer
+Projektwoche/von Projekttagen sein. Besonders be­
+währt hat sich hier die Zusammenarbeit mit Kollegen
+aus dem gesellschafts-/sozialwissenschaftlichen
+Bereich. Ein Unterrichtsgang, z.B. in einen Super­
+markt mit modernen Scannerkassen, bei einer Tages­
+zeitung (Kleinanzeigenaufnahme am Freitag-Vormit­
+tag) o.ä., bei dem die "im Hintergrund (möglicher­
+weise) ablaufenden Prozesse" bewußt gemacht werden,
+kann das Vorhaben noch abrunden. 
+   Zum Einsatz in der Sekundarstufe II liegen erst
+wenige Erfahrungen vor. Mit Sicherheit bietet das
+Programm einen "anderen", interessanten Einstieg in
+den Informatikunterricht der Jahrgangsstufe 11 und
+kann auch bei der Aufarbeitung entsprechender Fra­
+gestellungen zu späteren Zeitpunkten herangezogen
+werden. Erfahrungen aus anderen Fachbereichen lie­
+gen (noch) nicht vor. 
+ 
+ 
+2.7  Hinweise auf Arbeitsmaterial 
+ 
+   Ausdrücklich sei an dieser Stelle auf die Ausar­
+beitung von Hartmut Spenn und Mene Wolf hingewie­
+sen: 
+ 
+Spenn, Hartmut; Wolf, Mene; Der gläserne Arbeiter,
+        Elektronische Leistungs- und Verhaltenskon­
+        trolle am Arbeitsplatz 
+   in:  Landesinstitut für Schule und Weiterbildung
+        (Hrsg.), Materialien zur Lehrerfortbildung
+        in Nordrhein-Westfalen, Heft 4, Neue Tech­
+        nologien - Informations- und Kommunuika­
+        tionstechnologische Inhalte im Wahlpflicht­
+        unterricht der Klassen 9/10, Soest, 1986. 
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3
new file mode 100644
index 0000000..f589a93
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 3	
@@ -0,0 +1,237 @@
+#limit (11.0)##pagelength (16.5)##block##pageblock# 
+#start (2.0,0.0)# 
+#page (16)# 
+#headodd# 
+#center#gs-MP BAP#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-MP BAP 
+ 
+#end# 
+#center#3 
+ 
+#center#Installation 
+#center#von 
+#center#gs-MP BAP 
+ 
+ 
+   Bevor Sie #on("b")#gs-MP BAP#off("b")# auf Ihrem Computer benutzen
+können, müssen Sie das Programm zunächst installie­
+ren. Wenn #on("b")#gs-MP BAP#off("b")# auf Ihrem System schon zur Ver­
+fügung steht, können Sie dieses Kapitel ruhig über­
+springen. 
+ 
+ 
+3.1  Voraussetzungen 
+ 
+   Um #on("b")#gs-MP BAP#off("b")# auf Ihrem Computer betreiben zu
+können, muß das EUMEL-Betriebssystem installiert
+sein. #on("b")#gs-MP BAP#off("b")# setzt die Multi-User-Version voraus
+und ist lauffähig ab Version 1.7.5. #on("b")#gs-MP BAP#off("b")# setzt
+weiterhin voraus, daß auf Ihrem Computer bereits
+das Programm #on("b")#gs-DIALOG#off("b")# installiert ist. 
+ 
+ 
+3.2  Lieferumfang 
+ 
+   #on("b")#gs-MP BAP#off("b")# wird auf einer Diskette geliefert, die
+alle notwendigen Programme enthält (die Installa­
+tion von #on("b")#gs-DIALOG#off("b")# wird dabei vorausgesetzt!). Um
+den Inhalt der Diskette feststellen zu können,
+starten Sie Ihr System und bringen es dazu, daß
+'gib kommando:' erscheint. Dann legen Sie die Dis­
+kette ein und geben das Kommando: 
+ 
+   archive("gs-MP BAP");list(archive); 
+   release(archive) <RETURN> 
+ 
+   Anschließend erscheint eine Übersicht der auf
+dem Archiv vorhandenen Programme. Folgende Program­
+me sollten sich in der Übersicht befinden: 
+ 
+         "gs-MP BAP 1" 
+         "gs-MP BAP 2" 
+         "gs-MENUKARTE:MP-BAP" 
+         "gs-MP BAP/gen" 
+ 
+   Eventuell können noch weitere Namen auf der Dis­
+kette vorhanden sein. Wenn Sie den Inhalt der Dis­
+kette kontrolliert haben und diese Programme auf
+der Diskette vorhanden sind, können Sie #on("b")#gs-MP BAP#off("b")#
+installieren. 
+   Sollten Sie statt der Übersicht eine Fehlermel­
+dung erhalten, überprüfen Sie bitte, ob die Disket­
+te das richtige Format besitzt oder ob Ihr Disket­
+tenlaufwerk Probleme macht. Sollten dagegen Pro­
+gramme fehlen, so reklamieren Sie die Diskette. 
+ 
+ 
+3.3  Installation 
+ 
+   #on("b")#gs-MP BAP#off("b")# muß in einer Task installiert werden,
+in der bereits das Programm #on("b")#gs-DIALOG#off("b")# zur Verfügung
+steht. Alle Söhne und Enkel der neuen Task können
+anschließend auf die Programme (Materialprüfung /
+Bildschirmarbeitsplatz) zugreifen. Richten Sie also
+eine Task als Sohn der Task ein, in der auf Ihrem
+Computer bereits #on("b")#gs-DIALOG#off("b")# installiert ist. Wir
+nehmen hier an, daß #on("b")#gs-DIALOG#off("b")# in der Task 'MENU'
+installiert ist und die neue Task den Namen 'MP
+BAP' erhalten soll. (Sie können für die Task auch
+einen beliebigen anderen Namen wählen): 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+#off("b")# 
+ 
+  -->     gib supervisor kommando: 
+#on("b")# 
+          begin ("MP BAP","MENU") <RETURN> 
+#off("b")# 
+ 
+  -->     gib kommando: 
+ 
+   (Arbeiten mehrere Personen mit dem Computer,
+dann ist es sinnvoll, diese Task vor unbefugtem
+Zugriff durch ein Passwort zu schützen. Wie das
+gemacht wird, können Sie in Ihrem EUMEL-Benutzer­
+handbuch erfahren.) 
+ 
+   Legen Sie dann die Archivdiskette ein, auf der
+sich #on("b")#gs-MP BAP#off("b")# befindet, und geben Sie das folgende
+Kommando: 
+ 
+#on("b")# 
+          archive("gs-MP BAP") <RETURN> 
+ 
+          fetch("gs-MP BAP/gen",archive) <RETURN> 
+ 
+          run <RETURN> 
+#off("b")# 
+ 
+   Sie haben damit das Generatorprogramm gestartet.
+Beantworten Sie die Frage, ob Sie das Archiv ange­
+meldet und die Diskette eingelegt haben, mit 'ja'
+durch Tippen der Taste <j>. 
+   Daraufhin wird die Installation automatisch
+durchgeführt. Lassen Sie während des gesamten Vor­
+gangs die Archivdiskette eingelegt. Sie erhalten
+einen Hinweis, wenn die Diskette entnommen werden
+kann! Die Generierung ist beendet, wenn der EUMEL-
+Eingangsbildschirm erscheint. Die Task, in der die
+Generierung stattfindet, wird automatisch zur Mana­
+gertask, das heißt, daß Söhne von ihr eingerichtet
+werden können. 
+   Richten Sie sich gleich eine Sohntask (z.B mit
+dem Namen 'mp bap') ein, dann können Sie das System
+sofort ausprobieren. Gehen Sie dazu folgendermaßen
+vor: 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+#off("b")# 
+ 
+  -->     gib supervisor kommando: 
+#on("b")# 
+          begin ("mp bap","MP BAP") <RETURN> 
+#off("b")# 
+ 
+  -->     gib kommando: 
+ 
+Mit dem Kommando 
+ 
+#center##on("b")#mp <RETURN>  bzw. bap <RETURN>#off("b")# 
+ 
+können Sie nun das Programm 
+ 
+#center#'Materialprüfung'  bzw.  'Bildschirmarbeitsplatz' 
+ 
+aufrufen. 
+ 
+ 
+3.4  Organisation des Task - Systems 
+ 
+   Wollen Sie unter anderem das Teilprogramm 'Ma­
+terialprüfung' (MP) nutzen, so sollten Sie beden­
+ken, daß die dabei entstehenden Simulationsproto­
+kolle in die Vatertask geschickt werden. Die Vater­
+task sollte sich daher ständig im Wartezustand be­
+finden, um die Protokolle auch aufnehmen zu können.
+So kann es sinnvoll sein, eine 'Zwischentask' ein­
+zurichten, damit auch andere ungestört mit dem Si­
+mulationsprogramm arbeiten können. Gehen Sie dazu
+etwa folgendermaßen vor: 
+  In der Task 'mp bap', in der Sie bisher gearbei­
+tet haben, geben Sie bei 'gib kommando:' den Be­
+fehl: 
+ 
+   #on("b")#global manager <RETURN>#off("b")# 
+ 
+   Sie gestatten dadurch, daß Söhne dieser Task
+eingerichtet werden können. Auf dem Bildschirm er­
+scheint der EUMEL-Eingangsbildschirm. 
+   Alle Anwender (Schüler) melden sich dann als
+Sohn der Task 'mp bap' an: 
+ 
+   #on("b")#begin ("Anwender1", "mp bap") <RETURN>#off("b")# 
+   #on("b")#begin ("Anwender2", "mp bap") <RETURN>#off("b")# 
+   #on("b")#begin ("Anwender3", "mp bap") <RETURN>#off("b")# 
+   ... 
+ 
+   Die Simulationsprotokolle finden Sie dann an­
+schließend in der Task 'mp bap'. 
+ 
+ 
+3.5  Direktstart des Systems 
+     (Steht erst ab gs-DIALOG Version 1.1 zur Ver­
+     fügung) 
+ 
+   In den Kapitel 3.3/3.4 haben wir Ihnen gezeigt,
+wie sie Sohntasks einrichten und hier durch das
+Kommando 'mp' bzw. 'bap' das System aufrufen kön­
+nen. Wenn Sie immer nur mit einer Modellvariante
+arbeiten oder vor dem Benutzer die 'gib komman­
+do:'-Ebene verbergen wollen, können Sie das System
+auch so einrichten, daß sich sofort nach Einrichten
+des Arbeitsbereichs das Menusystem meldet. Für den
+Anfänger kann das die Arbeit durchaus erleichtern. 
+  Gehen Sie dazu in die Task, unterhalb der die
+Sohntasks eingerichtet werden sollen: 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+ 
+#off("b")# 
+  -->     gib supervisor kommando: 
+#on("b")# 
+          continue ("mp bap") <RETURN> 
+#off("b")# 
+ 
+  -->     gib kommando: 
+#on("b")# 
+          direktstart ("mp", TRUE) <RETURN> 
+#off("b")# 
+ 
+   Durch das Kommando haben Sie festgelegt, daß
+sich alle Sohntasks direkt mit dem Programm 'Mate­
+rialprüfung' melden. Möchten Sie lieber mit 'Bild­
+schirmarbeitsplatz' arbeiten, ist nur 'mp' durch
+'bap' zu ersetzen. In diesem Falle meldet sich das
+System gleich mit dem BAP-Menu. 
+   Durch den zweiten Parameter 'TRUE' legen Sie
+fest, daß in den Sohntasks nach Verlassen des Menus
+die jeweilige Task automatisch gelöscht wird. Statt
+'TRUE' können Sie hier auch den Wert 'FALSE' ein­
+tragen. Dann wird nach Verlassen des Menus ange­
+fragt, ob die Task gelöscht werden soll. Wird die
+Frage bejaht, wird gelöscht - sonst wird die Task
+abgekoppelt (break) und kann durch 'continue' wie­
+der angekoppelt werden. 
+   Anmerkung: In der Task, in der Sie das Kommando
+'direktbefehl' gegeben haben, sollte nicht das Kom­
+mando 'monitor' gegeben werden, da Sie durch dieses
+Kommando auch diese Task zu einer Task machen, die
+sich direkt mit dem Menu meldet und ggf. bei Ver­
+lassen des Menus automatisch gelöscht wird! 
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4
new file mode 100644
index 0000000..6236d91
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 4	
@@ -0,0 +1,638 @@
+#limit (11.0)##pagelength (16.5)##block##pageblock# 
+#start (2.0,0.0)# 
+#page (22)# 
+#headodd# 
+#center#gs-MP BAP#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-MP BAP 
+ 
+#end# 
+#center#4 
+ 
+#center#Eine 
+#center#kleine 
+#center#Beispielsitzung 
+ 
+ 
+4.1  Aufruf von 'Bildschirmarbeitsplatz' (BAP) 
+ 
+   Wenn Sie, wie in Kapitel 3 beschrieben, eine
+Sohntask der Task eingerichtet haben, in der #on("b")#gs-MP
+BAP#off("b")# installiert ist, und dort bei 'gib kommando:'
+den Befehl: 
+ 
+  #on("b")#bap <RETURN>#off("b")# 
+ 
+geben, erscheint - nach dem #on("b")#gs-DIALOG#off("b")#-Eingangsbild­
+schirm - das folgende Menu: 
+ 
+#on("b")# 
+BAP:  Simulation  Parameter  Konfiguration  Dateien  Archiv 
++-------------------------------+----------------------------------------- 
+|  s Simulation ausführen       | 
+|  ---------------------------  | 
+|  a Auswertung auf Bildschirm  | 
+|  d Drucken von Auswertungen   | 
++-------------------------------+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+4.2  Einstellung von Simulationsparametern 
+ 
+   Bevor Sie eine Neueinstellung von Simulations­
+parametern vornehmen, sollten Sie sich einen Über­
+blick über die zur Zeit eingestellten Werte ver­
+schaffen. Zwar wäre es möglich, gleich einen Simu­
+lationslauf zu starten, doch müßten Sie dann gleich
+34 Minuten arbeiten - denn standardmäßig ist das
+Simulationssystem auf 3 Arbeitsphasen von je 10
+Minuten Dauer und zwei dazwischenliegende Pausen
+von je 2 Minuten eingestellt. 
+   Wenn Sie sich die Einstellung anzeigen lassen
+wollen, müssen Sie das Pull-Down-Menu wechseln.
+Gehen Sie als durch Tippen der Pfeiltaste <rechts>
+zum Oberbegriff 'Parameter'. Dadurch wird das fol­
+gende Pull-Down-Menu aufgeschlagen: 
+ 
+#on("b")# 
+BAP:  Simulation  Parameter  Konfiguration  Dateien  Archiv 
+-------+---------------------------+-------------------------------------- 
+       |  e Einstellung anzeigen   | 
+       |  s Standardwerte          | 
+       |  -----------------------  | 
+       |  b Breite des Werkstücks  | 
+       |  h Höhe des Werkstücks    | 
+       |  i Invers-/Normal         | 
+       |  z Zeichensatz            | 
+       |  f Fehlerzeichen          | 
+       |  t Tastenbelegung         | 
+       |  -----------------------  | 
+       |  a Anzahl Arbeitsphasen   | 
+       |  d Dauer Arbeitsphase     | 
+       |  p Pausendauer            | 
+       |  -----------------------  | 
+       |  w Wertungsschlüssel      | 
+       +---------------------------+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+Nach Tippen der Taste <e> (für 'Einstellung anzei­
+gen') erscheint der folgende Bildschirm: 
+ 
+#on("b")# 
++-----------------------------------++-----------------------------------+ 
+|                                   ||         Wertungsschlüssel         | 
+| Breite       :  15 Zeichen        || Bewertungs-                       | 
+| Höhe         :  12 Zeichen        ||   faktor                          | 
+| Darstellung  :  normal            ||                                   | 
+| Zeichensatz  :  A...Z (26 Zeichen)||1.0|                             + | 
+| Fehlerzeichen:  F                 ||   |                          +    | 
+|                                   ||   |                       +       | 
+| Nach rechts  : <rechts>           ||   |                    +          | 
+| Nach links   : <links>            ||   |                 +             | 
+| Nach oben    : <hoch>             ||0.5|              +                | 
+| Nach unten   : <runter>           ||   |           +                   | 
+| Ausbesserung : <HOP>              ||   |        +                      | 
+| Nächstes     : <ESC>              ||   |     +                         | 
+|                                   ||   |  +                            | 
+| Anzahl der Arbeitsphasen:   3     ||0.0+--|--|--|--|--|--|--|--|--|--| | 
+| Dauer einer Arbeitsphase:  10 min ||  0.0            0.5            1.0| 
+| Dauer einer Pause       :   2 min ||                                   | 
+|                                   ||                  Ausbesserungsrate| 
+| Simulationsgesamtdauer  :  34 min ||                                   | 
++-----------------------------------++-----------------------------------+ 
+-------------------------------------------------------------------------- 
+Zum Weitermachen irgendeine Taste tippen! 
+#off("b")# 
+ 
+   Oben links wird das "Aussehen" der Werkstücke
+auf dem Bildschirm beschrieben. Nach diesen Angaben
+sind die Werkstücke 15 Zeichen breit und 12 Zeichen
+hoch. Sie werden auf dem Bildschirm normal (nicht
+invers) dargestellt. Die Werkstücke werden aus den
+Großbuchstaben 'A ... Z' zusammengesetzt, wobei 'F'
+das Fehlerzeichen ist, nach dem gesucht werden
+soll. 
+   Der Cursor kann mit den Pfeiltasten (<rechts>,
+<links>, <hoch> und <runter>) innerhalb des Werk­
+stücks bewegt werden. Steht der Cursor auf einem
+Fehlerzeichen, so verschwindet es, wenn die <HOP>-
+Taste getippt wird. Nach Tippen der <ESC>-Taste
+erscheint das nächste Werkstück auf dem Bildschirm. 
+   Darunter sind die Informationen angegeben, die
+uns eigentlich interessieren: Die Anzahl/Zeiten für
+Arbeitsphasen und Pausen. Sie sollen die Simula­
+tionszeiten jetzt so verändern, daß die Gesamtsimu­
+lationszeit 3 Minuten beträgt. Wählen Sie dazu zu­
+erst die Menufunktion 'Anzahl Arbeitsphasen' durch
+Tippen der Taste <a>. Dann erscheint auf dem Bild­
+schirm folgendes Bild: 
+ 
+#on("b")# 
++-------------------------++-------------------------------------------+ 
+|       Informationen     ||     Anzahl Arbeitsphasen festlegen:       | 
+|                         ||                                           | 
+| Kleinster     Wert:   2 || Anzahl Arbeitsphasen neu festlegen (j/n)? | 
+| Größter       Wert:  20 ||                                           | 
+|                         ||                                           | 
+| Eingestellter Wert:   3 ||                                           | 
++-------------------------++-------------------------------------------+ 
+ 
+ 
+ 
+               +-------------------------------------+ 
+               |         Simulationszeiten:          | 
+               |                                     | 
+               | Anzahl der Arbeitsphasen:   3       | 
+               | Dauer einer Arbeitsphase:  10 min   | 
+               | Dauer einer Pause       :   2 min   | 
+               |                                     | 
+               | Simulationsgesamtdauer  :  34 min   | 
+               +-------------------------------------+ 
+ 
+ 
+   Wenn Sie die im Fenster oben rechts gestellte
+Frage bejahen (Taste <j> tippen), ändert sich der
+Fensterinhalt: 
+ 
+#on("b")# 
++-------------------------++---------------------------------------------+ 
+|       Informationen     ||      Anzahl Arbeitsphasen festlegen:        | 
+|                         ||                                             | 
+| Kleinster     Wert:   2 ||Mit den Pfeilen <hoch>  und <runter> den Wert| 
+| Größter       Wert:  20 ||einstellen. Eingabe mit <RETURN> abschließen.| 
+|                         ||                                             | 
+| Eingestellter Wert:   3 ||Bitte die Anzahl der Arbeitsphasen:   3      | 
++-------------------------++---------------------------------------------+ 
+ 
+   Bestimmt ist Ihnen schon klar, was zu tun ist:
+Mit der Pfeiltaste <runter> stellen Sie den
+kleinstmöglichen Wert (2) ein - anschließend tippen
+Sie die <RETURN>-Taste. Schauen Sie auf das Fenster
+ganz unten - jetzt hätten Sie nur noch 24 Minuten
+zu arbeiten. Bevor Sie die anderen Parameter ein­
+stellen, bestätigen Sie bitte, daß Sie mit der An­
+zahl der Arbeitsphasen einverstanden sind. 
+   Gehen Sie jetzt ebenso vor, um die 'Dauer (ei­
+ner) Arbeitsphase' und die 'Pausendauer' einzustel­
+len - eine Beschreibung dazu ist sicher überflüs­
+sig. 
+   Rechts im Fenster ist noch der 'Wertungsschlüs­
+sel' angegeben - seine Bedeutung erläutern wir aber
+erst in Zusammenhang mit der Auswertung der Simula­
+tionsprotokolle. 
+ 
+ 
+4.3  Ein Simulationslauf 
+ 
+   So, jetzt können Sie zum Ausprobieren einen kur­
+zen Simulationslauf starten. Gehen Sie dazu zurück
+zum Pull-Down-Menu ganz links und wählen Sie hier
+die Menufunktion 'Simulation ausführen'. Zunächst
+werden Sie nach einer "Identifikation" gefragt.
+Geben Sie z.B. Ihren Namen ein und tippen Sie an­
+schließend die <RETURN>-Taste. Auf dem Bildschirm
+erscheinen oben alle Informationen, die Sie während
+der Simulation benötigen; darunter erscheint der
+Hinweis, daß mit dem nächsten Tastendruck die erste
+Arbeitsphase beginnt. Wenn das erste Werkstück auf
+dem Bildschirm erscheint, sieht das z.B. so aus: 
+ 
+#on("b")# 
++-------------------------------+ +-------------------------------------+ 
+| Nach rechts  : <rechts>       | | Anzahl der Arbeitsphasen:    3      | 
+| Nach links   : <links>        | | Dauer einer Arbeitsphase:   10 min  | 
+| Nach oben    : <hoch>         | | Dauer einer Pause       :    2 min  | 
+| Nach unten   : <runter>       | | Simulationsgesamtdauer  :   34 min  | 
+| Ausbesserung : <HOP>          | |                                     | 
+| Nächstes     : <ESC>          | | Fehlerzeichen           :    F      | 
++-------------------------------+ +-------------------------------------+ 
+ 
+                            GFMKLPDRFGTZQAL 
+                            RTWOJLMNVWQHTRS 
+                            PZBFVDDSWWAFGBD 
+                            EWWQAKGHHJINMPA 
+                            WSSDEKLJNHHGTFD 
+                            GGTEWLVCXFFRPTR 
+                            TREKGLMNTREFGTW 
+                            TRWFGLMBVCCDSAQ 
+                            HGFRWZTCXYAASWW 
+                            MNNBHGTREWQKJLO 
+                            CCXSDRFGHKLPOZR 
+                            RWPPKHJUUZTFDSE 
+ 
+ 
+   Nun dürfen Sie einmal zeigen, was Sie können.
+Bitte achten Sie darauf, daß Sie in jeder Arbeits­
+phase mindestens ein Werkstück bearbeiten - sonst
+könnte es später zu Fehlern bei der Auswertung kom­
+men. Sie sollen sich ja auch nicht ausruhen, son­
+dern arbeiten! 
+   Pausen werden Ihnen auf dem Bildschirm ange­
+zeigt. Auch wenn Sie weiterarbeiten wollen - um die
+Pausen kommen Sie nicht herum! Am Ende einer Pause
+wird ein Hinweis auf das Pausenende ausgegeben. 
+   Nach der letzten Arbeitsphase erhalten Sie eine
+Kurzauswertung des aktuellen Simualtionslaufes auf
+den Bildschirm (wenn Ihnen das nicht gefällt, kön­
+nen Sie das später auch abschalten). Zur Erläute­
+rung der angegebenen Daten in der 'Kurzauswertung'
+sehen Sie bitte das folgende Kapitel. 
+ 
+ 
+4.4  Die Simulationsauswertung/das Simulations­
+     protokoll 
+ 
+   Wenn Sie wollen, können Sie das Protokoll, das
+über Ihre Arbeit angefertigt wurde, gleich auswer­
+ten lassen. Wählen Sie dazu die Menufunktion 'Aus­
+wertung auf Bildschirm' (im gleichen Pull-Down-
+Menu). Ihnen werden jetzt alle Protokolle, die sich
+in Ihrer Task befinden, zur Auswahl angeboten.
+Wahrscheinlich ist es zur Zeit nur eine Protokoll­
+datei. 
+   Jetzt sehen Sie auch, warum von Ihnen vor Simu­
+lationsbeginn eine "Identifikation" erbeten wurde.
+Sie ist Bestandteil des Protokollnamens - danach
+können Sie nämlich die Protokolle zuordnen. Verwen­
+den Sie mehrfach die gleiche Identifikation, so
+werden die Protokolle in der Reihenfolge ihrer An­
+lage durchnumeriert. 
+   Wenn Sie den/die Dateinamen angekreuzt haben
+(z.B. mit <RETURN>) und die Auswahl durch <ESC><q>
+verlassen, werden die angekreuzten Protokolldateien
+ausgewertet und anschließend auf dem Bildschirm
+angezeigt. 
+   Das Protokoll ist jeweils nach folgendem Schema
+aufgebaut: Zunächst werden Datum und Uhrzeit des
+Simulationslaufs ausgegeben; anschließend alle
+Kenndaten der Simulation, so daß daraus die gesamte
+Konfiguration des Simulationssystems rekonstruier­
+bar ist. Es folgt die "Gesamtauswertung" des Simu­
+lationslaufes, die identisch ist mit der auf dem
+Bildschirm angezeigten 'Kurzauswertung'. Die Ge­
+samtauswertung erfolgt nach den gleichen Grundsät­
+zen wie die sich anschließenden Auswertungen der
+einzelnen Werkstücke (es werden hier nur die ggf.
+angefallenen Pausenüberschreitung(en) mit in die
+Beurteilung einbezogen). 
+   Das Protokoll ist durch die angehängten Bemer­
+kungen nahezu selbsterklärend. Damit Sie sich einen
+Eindruck verschaffen können, haben wir auf den
+nächsten Seiten ein ausgewertetes Protokoll abge­
+druckt. Bitte studieren Sie es eingehend - insbe­
+sondere die Anmerkungen am Ende des Protokolls: 
+ 
+ 
+ 
+ 
+ 
+ 
+#on("b")# 
+                        gs-Protokoll: TEST - Auswertung 
+                        =============================== 
+Datum :  03.09.87                            Uhrzeit (zu Beginn):  10:21 
+ 
+                      Kenndaten der Werkstückbearbeitung: 
+                      =================================== 
+Nach rechts  : <rechts>               Anzahl der Arbeitsphasen:    3 
+Nach links   : <links>                Dauer einer Arbeitsphase:   10 min 
+Nach oben    : <hoch>                 Dauer einer Pause       :    2 min 
+Nach unten   : <runter>               Simulationsgesamtdauer  :   34 min 
+Ausbesserung : <HOP> 
+Nächstes     : <ESC>                  Fehlerzeichen           :    F 
+ 
+Werkstückbreite              :   15 Zeichen 
+Werkstückhöhe                :   12 Zeichen 
+Anzahl Zeichen pro Werkstück :  180 Zeichen 
+Umfang des Zeichensatzes     :  A ... Z ( 26 Zeichen) 
+ 
+                              Beispielwerkstück: 
+                              ------------------ 
+                                QQSEUZSTABQBZWI 
+                                UKZVNYPHCPLQMGH 
+                                NDJZPCMOOPQQICL 
+                                ARELRDKUOOZWOIE 
+                                NASIPRLRQUKJHGN 
+                                YJJVKIGWCJOLRTL 
+                                FXSZBOBIBKQPYXN 
+                                JJFKFMEVALZNDPU 
+                                VTWWIHKWRMPMHZP 
+                                CSSFZBOSACLARKQ 
+                                WAAIMHJELLFKIWA 
+                                XLNHUCZRVXOXHRL 
+ 
+ 
+ 
+                       G e s a m t a u s w e r t u n g: 
+                       ================================ 
+Anzahl der vollständig bearbeiteten Werkstücke :        51 
+Anzahl der Zeichen pro Werkstück               :       180 
+Anzahl der insgesamt untersuchten Zeichen      :      9180 
+ 
+Anzahl der Bedienfehler                        :         3 
+ 
+Anzahl der vorgegebenen Fehler                 :       363 
+Anzahl der Fehlerkorrekturen                   :       304 
+Arbeitszeit     (incl. Pausenüberschreitungen) :    1792.5  sec 
+Anzahl bearbeiteter Zeichen pro Sekunde        :       5.1 
+ 
+Ausbesserungsrate                              :       0.8 
+Bewertungsfaktor                               :       0.8 
+ 
+Gesamtbewertung (incl. Pausenüberschreitungen) :       4.3 
+================================================  ======== 
+Arbeitszeit     (ohne  Pausenüberschreitungen) :    1788.5  sec 
+Anzahl bearbeiteter Zeichen pro Sekunde        :       5.1 
+Gesamtbewertung (ohne  Pausenüberschreitungen) :       4.3 
+================================================  ======== 
+ 
+ 
+                       Einzelauswertung der Werkstücke: 
+                       ================================ 
+ 
+Werk-  | Anzahl | Vorge- | Anzahl | Benö- | Zei-  | Aus-  |Bewer- | Bewer- 
+stück- |   Be-  | gebene |  Kor-  | tigte | chen  | bes-  |tungs- | tungs- 
+nummer | dien-  |  Feh-  |  rek-  | Zeit  |  pro  |  se-  |faktor |  zahl 
+       |  feh-  |  ler-  | turen  | [sec] |  Se-  | rungs-|       | 
+       |  ler   |  zahl  |        |       | kunde |  rate |       | 
+-------------------------------------------------------------------------- 
+       |        |        |        |       |       |       |       | 
+    1  |    0   |     5  |     3  |  45.6 |   3.9 |   0.6 |   0.6 |   2.4 
+    2  |    0   |    10  |     6  |  33.5 |   5.4 |   0.6 |   0.6 |   3.2 
+    3  |    0   |     5  |     4  |  35.7 |   5.0 |   0.8 |   0.8 |   4.0 
+    4  |    0   |     3  |     3  |  33.9 |   5.3 |   1.0 |   1.0 |   5.3 
+    5  |    0   |    10  |     7  |  38.0 |   4.7 |   0.7 |   0.7 |   3.3 
+    6  |    0   |     5  |     4  |  37.2 |   4.8 |   0.8 |   0.8 |   3.9 
+    7  |    0   |     9  |     8  |  36.9 |   4.9 |   0.9 |   0.9 |   4.3 
+    8  |    0   |     5  |     4  |  31.7 |   5.7 |   0.8 |   0.8 |   4.5 
+    9  |    0   |     4  |     3  |  27.3 |   6.6 |   0.8 |   0.8 |   4.9 
+   10  |    0   |     6  |     6  |  33.3 |   5.4 |   1.0 |   1.0 |   5.4 
+   11  |    0   |     3  |     3  |  25.0 |   7.2 |   1.0 |   1.0 |   7.2 
+   12  |    0   |     6  |     3  |  28.6 |   6.3 |   0.5 |   0.5 |   3.1 
+   13  |    0   |    11  |    10  |  37.9 |   4.7 |   0.9 |   0.9 |   4.3 
+   14  |    0   |     4  |     4  |  38.3 |   4.7 |   1.0 |   1.0 |   4.7 
+   15  |    0   |    11  |     8  |  39.3 |   4.6 |   0.7 |   0.7 |   3.3 
+   16  |    0   |     5  |     4  |  28.4 |   6.3 |   0.8 |   0.8 |   5.1 
+   17  |    0   |     4  |     4  |  36.4 |   4.9 |   1.0 |   1.0 |   4.9 
+   18  |    0   |    15  |    14  |  44.9 |   4.0 |   0.9 |   0.9 |   3.7 
+ 
+ PAUSE     --->    Überzogen um     2.2  sec 
+ 
+   19  |    0   |     3  |     3  |  38.9 |   4.6 |   1.0 |   1.0 |   4.6 
+   20  |    0   |    11  |    10  |  40.2 |   4.5 |   0.9 |   0.9 |   4.1 
+   21  |    0   |     8  |     7  |  34.7 |   5.2 |   0.9 |   0.9 |   4.5 
+   22  |    0   |     7  |     5  |  30.3 |   5.9 |   0.7 |   0.7 |   4.2 
+   23  |    0   |     4  |     4  |  33.9 |   5.3 |   1.0 |   1.0 |   5.3 
+   24  |    0   |     7  |     7  |  39.5 |   4.6 |   1.0 |   1.0 |   4.6 
+   25  |    0   |     6  |     4  |  28.1 |   6.4 |   0.7 |   0.7 |   4.3 
+   26  |    0   |    11  |    10  |  34.8 |   5.2 |   0.9 |   0.9 |   4.7 
+   27  |    0   |    11  |     9  |  34.2 |   5.3 |   0.8 |   0.8 |   4.3 
+   28  |    0   |    10  |     8  |  35.0 |   5.1 |   0.8 |   0.8 |   4.1 
+   29  |    0   |     9  |     8  |  36.4 |   4.9 |   0.9 |   0.9 |   4.4 
+   30  |    0   |     8  |     7  |  34.8 |   5.2 |   0.9 |   0.9 |   4.5 
+   31  |    0   |    10  |     8  |  36.2 |   5.0 |   0.8 |   0.8 |   4.0 
+   32  |    0   |    10  |    10  |  44.0 |   4.1 |   1.0 |   1.0 |   4.1 
+   33  |    0   |     8  |     8  |  44.4 |   4.1 |   1.0 |   1.0 |   4.1 
+   34  |    0   |     4  |     3  |  35.6 |   5.1 |   0.8 |   0.8 |   3.8 
+ 
+ PAUSE     --->    Überzogen um     1.8  sec 
+ 
+   35  |    0   |     8  |     8  |  42.7 |   4.2 |   1.0 |   1.0 |   4.2 
+   36  |    1   |     8  |     8  |  45.3 |   4.0 |   1.0 |   1.0 |   4.0 
+   37  |    0   |     5  |     5  |  34.3 |   5.2 |   1.0 |   1.0 |   5.2 
+   38  |    0   |     5  |     4  |  27.9 |   6.5 |   0.8 |   0.8 |   5.2 
+   39  |    0   |    10  |     8  |  39.5 |   4.6 |   0.8 |   0.8 |   3.6 
+   40  |    1   |     7  |     6  |  35.5 |   5.1 |   0.9 |   0.9 |   4.3 
+   41  |    0   |     3  |     3  |  29.5 |   6.1 |   1.0 |   1.0 |   6.1 
+   42  |    0   |     5  |     5  |  30.2 |   6.0 |   1.0 |   1.0 |   6.0 
+   43  |    0   |     6  |     3  |  28.0 |   6.4 |   0.5 |   0.5 |   3.2 
+   44  |    0   |     5  |     4  |  30.2 |   6.0 |   0.8 |   0.8 |   4.8 
+   45  |    0   |     5  |     4  |  33.1 |   5.4 |   0.8 |   0.8 |   4.4 
+   46  |    0   |     8  |     7  |  33.7 |   5.3 |   0.9 |   0.9 |   4.7 
+   47  |    0   |     9  |     7  |  32.2 |   5.6 |   0.8 |   0.8 |   4.3 
+   48  |    0   |     9  |     8  |  37.5 |   4.8 |   0.9 |   0.9 |   4.3 
+   49  |    0   |     4  |     4  |  32.0 |   5.6 |   1.0 |   1.0 |   5.6 
+   50  |    0   |     9  |     7  |  34.8 |   5.2 |   0.8 |   0.8 |   4.0 
+   51  |    1   |     9  |     4  |  29.2 |   6.2 |   0.4 |   0.4 |   2.7 
+       |        |        |        |       |       |       |       | 
+========================================================================== 
+ 
+(  52  |    0   |     7  |     7  |  35.9 |   5.0 |   1.0 |   1.0 |   5.0) 
+ 
+                                 Anmerkungen: 
+                                 ============= 
+ 
+  -  Das zuletzt bearbeitete Werkstück  (in der obigen Tabelle unterhalb 
+     der letzten Trennlinie in Klammern angegeben) wurde nicht vollstän- 
+     dig innerhalb der zur Verfügung stehenden Zeit bearbeitet. 
+     Aus diesem Grunde wird es bei der Auswertung (Gesamtwertung)  nicht 
+     berücksichtigt! 
+ 
+  -  Bei der Auflistung der Daten der einzelnen Werkstücke sind auch die 
+     Pausen eingetragen,  so daß sich die einzelnen Arbeitsphasen erken- 
+     nen und miteinander vergleichen lassen.  Die dabei notierten Zeiten 
+     geben  die Pausenüberschreitungen an.  Diese Zeiten bleiben bei der 
+     Betrachtung der einzelnen Werkstücke unberücksichtigt, fließen aber 
+     in die Gesamtauswertung ein! 
+ 
+  -  Die Anzahl der  Bedienfehler  ist ein Maß für die Sicherheit im Um- 
+     gang mit dem System.  Bei den weiteren  Auswertungen bleibt die Be- 
+     dienfehlerzahl allerdings unberücksichtigt! 
+ 
+  -  Die 'Vorgegebene Fehlerzahl', die 'Anzahl Korrekturen' und die 'Be- 
+     nötigte Zeit [sec]'  wurden bei der Bearbeitung des  Werkstücks er- 
+     faßt. Auf diesen Daten beruhen die folgenden Auswertungen! 
+ 
+  -  Da die Werkstücke ganz unterschiedliche Größen haben können, eignet 
+     sich die 'Benötigte Zeit [sec]',  die für die Bearbeitung eines je- 
+     den Werkstücks ermittelt wird, als Maß für die "Arbeitsgeschwindig- 
+     keit" nicht!  Stattdessen wird ermittelt, wie viele Zeichen pro Se- 
+     kunde "bearbeitet" wurden: 
+ 
+                             Anzahl Zeichen pro Werkstück 
+     Zeichen pro Sekunde  =  ---------------------------- 
+                                 Benötigte Zeit [sec] 
+ 
+     Die 'Anzahl Zeichen pro Werkstück' kann aus der Werkstückbreite und 
+     Werkstückhöhe ermittelt werden: 
+ 
+     Anzahl Zeichen pro Werkstück = Werkstückbreite * Werkstückhöhe 
+ 
+  -  Aus der (zufällig)  'Vorgegebenen Fehlerzahl'  und der 'Anzahl Kor- 
+     rekturen' wird die 'Ausbesserungsrate' ermittelt: 
+ 
+                             Anzahl Korrekturen 
+     Ausbesserungsrate  =  ---------------------- 
+                           Vorgegebene Fehlerzahl 
+ 
+     Die Ausbesserungsrate gibt an,  welcher Anteil der vorhandenen Feh- 
+     ler ausgebessert wurde. Sie ist ein Maß für die Güte der verrichte- 
+     ten Arbeit. 
+ 
+  -  Der 'Bewertungsfaktor' ist abhängig von der 'Ausbesserungsrate'. Er 
+     läßt sich aus dem folgenden Diagramm entnehmen: 
+ 
+              Bewertungs- 
+                faktor 
+ 
+             1.0|                             + 
+                |                          + 
+                |                       + 
+                |                    + 
+                |                 + 
+             0.5|              + 
+                |           + 
+                |        + 
+                |     + 
+                |  + 
+             0.0+--|--|--|--|--|--|--|--|--|--| 
+               0.0            0.5            1.0 
+                               Ausbesserungsrate 
+ 
+ 
+     In diesem  Diagramm ist festgelegt,  wie die  einzelnen  'Ausbesse- 
+     rungsraten' bewertet werden. 
+ 
+  -  Am Ende wird die 'Bewertungszahl' folgendermaßen ermittelt: 
+ 
+     Bewertungszahl = Zeichen pro Sekunde * Bewertungsfaktor 
+ 
+     Da der 'Bewertungsfaktor' nur Werte zwischen 0 und 1 annehmen kann, 
+     ist die  'Bewertungszahl'  ein Wert zwischen 0 und der 'Zeichen pro 
+     Sekunde'. Die "Arbeitsleistung" war um so größer, je höher die 'Be- 
+     wertungszahl ist. 
+ 
+Eine weitere Kommentierung des Protokolls dürfte
+sich wohl erübrigen, wenn Sie die Anmerkungen in­
+tensiv studiert haben. 
+ 
+ 
+4.5  Hinweise zur Protokollauswertung 
+ 
+4.5.1  Der Bewertungsfaktor 
+ 
+   Sie haben sich sicher über den sogenannten 'Be­
+wertungsfaktor' gewundert, der an verschiedenen
+Stellen genannt wird - aber bisher unberücksichtigt
+blieb. In den bisher aufgezeigten Situationen war
+der Bewertungsfaktor identisch mit der 'Ausbesse­
+rungsrate'. Warum dieser Faktor gesondert einge­
+führt wurde, möchten wir an einem kleinen Beispiel
+erläutern: 
+   Wenn Ihnen der Auswertalgorithmus vor dem Simu­
+lationslauf bekannt gewesen wäre und Sie die Ab­
+sicht gehabt hätten, eine möglichst hohe Bewer­
+tungszahl zu erzielen, wäre folgende "Arbeitsstra­
+tegie" erfolgversprechend gewesen: 
+   Sobald ein Werkstück auf dem Bildschirm er­
+scheint, bewegen Sie den Cursor schnellstens zum
+ersten Fehlerzeichen, das Sie entdecken können und
+löschen es mit der Ausbesserungstaste. Sollten zu­
+fällig noch weiterer Fehlerzeichen in unmittelbarer
+Nähe zu sehen sein, so können Sie sie ja auch "aus­
+merzen" - aber dann schnell das nächste Werkstück
+anfordern usw. 
+   Machen wir uns klar, was das bedeutet: Da sie
+das Werkstück in sehr kurzer Zeit bearbeitet haben,
+wird der eigentlich entscheidende Faktor hinsicht­
+lich der Auswertung "enorm in die Höhe getrieben"
+(die Anzahl der Zeichen pro Sekunde). Da Sie bei
+dieser Strategie zumeist nur 2 - 4 Sekunden zur
+Bearbeitung eines Werkstücks brauchen, erhalten Sie
+- auf das obige Beispielprotokoll bezogen - Werte
+zwischen 90.0 und 45.0 (bearbeitete Zeichen pro
+Sekunde). 
+   Im Schnitt treten pro Werkstück etwa 7 Fehler­
+zeichen auf (sehen Sie dazu auch unter 'Aufbau der
+Werkstücke'), von denen Sie dann eines korrigiert
+haben. Sie kommen also auf eine durchschnittliche
+Ausbesserungsrate von 0.14. Wäre - wie im obigen
+Beispielprotokoll - der Bewertungsfaktor mit der
+Ausbesserungsrate identisch, so erhielten Sie Be­
+wertungszahlen zwischen 12.9 und 6.4. Ein deut­
+licher Unterschied zur "Leistung" die im Protokoll
+dokumentiert ist - oder? 
+   Das aber ist nicht Sinn der dem Benutzer ge­
+stellten Aufgabe! Es würde auch nicht einer sinn­
+vollen 'Kontrolltätigkeit' entsprechen, wenn derart
+viele Fehler unentdeckt blieben. Um hier "regulie­
+rend" einschreiten zu können, ist der 'Bewertungs­
+faktor' eingeführt worden. So können Sie festlegen,
+daß Werkstücke, in denen weniger als 80% der Fehler
+entdeckt wurden, bei der Auswertung unberücksich­
+tigt bleiben. Sie brauchen dazu nur den Bewertungs­
+schlüssel entsprechend einzustellen. ("Ziehen Sie
+dazu bei der Einstellung des Bewertungsschlüssels
+die ersten 8 Kreuzchen auf die Grundlinie"). 
+   Anders ausgedrückt: Durch die Manipulation des
+Bewertungsschlüssels können Sie die Anforderungen,
+die an die Werkstückbearbeitung gestellt werden,
+festlegen. Hierdurch entscheiden Sie über die Wer­
+tigkeit von Schnelligkeit und Genauigkeit. 
+   Übrigens wird der zur Simulationszeit einge­
+stellte Wertungsschlüssel mit im Protokoll notiert.
+Eine Auswertung des Protokolls mit verschiedenen
+Wertungsschlüsseln ist so nicht möglich - und auch
+nicht sinnvoll. Denn sonst könnte es ja vorkommen,
+daß der Anwender ein ganz anderes Ergebnis in der
+Kurzauswertung auf dem Bildschirm gezeigt bekommt
+als er nachher im Protokoll nachlesen kann. Wenn
+Sie also mit einem veränderten Wertungsschlüssel
+arbeiten wollen, müssen Sie ihn #on("u")#vor dem Simula­
+tionslauf#off("u")# eingestellt haben! 
+ 
+ 
+4.5.2  Fehlerzeichenhäufigkeit in den Werkstücken 
+ 
+   Die Häufigkeit des Auftretens der Fehlerzeichen
+in den einzelnen Werkstücken kann deutlich schwan­
+ken. Die Werkstücke werden nämlich mit Hilfe des
+Zufallszahlengenerators aufgebaut. Je nach Anzahl
+der verschiedenen Zeichen, die in einem Werkstück
+auftreten können, ändert sich auch der Anteil der
+auftretenden Fehlerzeichen. 
+   In unserem bisher betrachteten Beispiel können
+26 verschiedene Buchstaben im Werkstück auftreten.
+Ein Werkstück besteht aus 180 Zeichen. In 1/26 al­
+ler Fälle müßte also das Fehlerzeichen auftreten,
+d.h. also etwa 7 Fehlerzeichen pro Werkstück - al­
+lerdings auf eine große Anzahl von produzierten
+Werkstücken bezogen. Da die Werkstücke zufällig
+zusammengesetzt werden, gilt dieser Wert natürlich
+nicht für das einzelne Werkstück! 
+ 
+ 
+4.5.3  Fehlerhafte Auswertungen 
+ 
+   In zwei Situationen kann es zu Fehlern bei der
+Auswertung von Protokollen kommen: 
+ 
+   Wurde der Simulationslauf mit der <SV>-Taste
+rigoros abgebrochen, so ist ggf. eine sinnvolle
+Auswertung des Protokolls nicht möglich, da nur
+unvollständige Daten vorhanden sind. 
+ 
+   In der letzten Arbeitsphase eines Simulations­
+laufes muß zumindest ein Werkstück angefordert wor­
+den sein. Dehnt ein Anwender die letzte Pause so
+lange aus, daß das Pausenende über das Ende der
+letzten Arbeitsphase hinausreicht, so erscheinen im
+Protokoll keine Werte für die einzelnen Werkstücke
+- in der Gesamtauswertung sind (fast) alle Werte
+auf '0' gesetzt. 
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5
new file mode 100644
index 0000000..d08e4a7
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 5	
@@ -0,0 +1,699 @@
+#limit (11.0)##pagelength (16.5)##block##pageblock# 
+#start (2.0,0.0)# 
+#page (40)# 
+#headodd# 
+#center#gs-MP BAP#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-MP BAP 
+ 
+#end# 
+#center#5 
+ 
+#center#Beschreibung 
+#center#der 
+#center#Menufunktionen 
+ 
+#center#(Programmteil 'Bildschirmarbeitsplatz' (BAP)) 
+ 
+ 
+5.1  Kurzhinweise zur Bedienung des Menus 
+ 
+   Die Bedienung des Menus ist sehr einfach. Eine
+ausführliche Beschreibung dazu finden Sie in den
+Unterlagen zum Programmsystem #on("b")#gs-DIALOG#off("b")#. An dieser
+Stelle sollen nur die wesentlichen Bedienungsvor­
+gänge beschrieben werden. 
+ 
+-  Mit der Tastenfolge <ESC><?> können Sie sich
+   Informationen zur Bedienung des Menusystems in
+   das Menu einblenden lassen. 
+ 
+-  Mit den Pfeiltasten <rechts> und <links> können
+   Sie zwischen den "Oberbegriffen" in der Kopfzei­
+   le wählen. Der aktuelle Oberbegriff ist jeweils
+   invers dargestellt. Das ausgeklappte 'Pull-
+   Down-Menu' bezieht sich auf diesen invers darge­
+   stellten Oberbegriff. 
+ 
+-  Mit den Pfeiltasten <hoch> und <runter> können
+   Sie zwischen den Menufunktionen wählen, die
+   Ihnen im aktuellen Pull-Down-Menu zur Auswahl
+   angeboten werden. Die aktuell angewählte Menu­
+   funktion wird jeweils invers dargestellt. Die
+   Trennlinien, die in einigen Pull-Down-Menus
+   sichtbar sind, dienen nur der optischen Unter­
+   gliederung; sie können nicht angewählt werden
+   und werden deshalb automatisch übersprungen. Die
+   einzelnen Menupunkte sind "zyklisch miteinander
+   verknüpft", das heißt, man gelangt vom untersten
+   Menupunkt wieder zum obersten und umgekehrt.
+   Menupunkte, vor denen ein Minuszeichen steht
+   ('-'), sind (zur Zeit) nicht aktivierbar; auch
+   sie können nicht angewählt werden und werden
+   einfach übersprungen. 
+ 
+-  Durch Tippen der Fragezeichentaste (<?>) können
+   Sie sich jeweils zur aktuellen Menufunktion (in­
+   vers im Pull-Down-Menu) Informationen in das
+   Menu einblenden lassen. 
+ 
+-  Um eine Menufunktion ausführen zu lassen, bewe­
+   gen Sie sich mit den Pfeiltasten auf die ge­
+   wünschte Menufunktion im aktuellen Pull-Down-
+   Menu und tippen dann die <RETURN>-Taste. Steht
+   vor dem gewünschten Menupunkt ein einzelner
+   Buchstabe oder eine Ziffer, so kann durch Tippen
+   der entsprechenden Taste diese Menufunktion da­
+   durch direkt aufgerufen werden. Sobald eine Me­
+   nufunktion aufgerufen worden ist, erscheint da­
+   vor ein Stern ('*'). Daraus können Sie entneh­
+   men, daß das System bereits den Auftrag aus­
+   führt. 
+ 
+-  An verschiedenen Stellen werden Fragen an Sie
+   gerichtet, die Sie mit 'ja' oder 'nein' beant­
+   worten müssen. Tippen Sie dazu entsprechend der
+   Entscheidung die Taste <j> (für 'ja') bzw. <n>
+   (für 'nein'). 
+ 
+-  Werden Ihnen vom Menu aus Dateinamen zur Auswahl
+   angeboten, so können Sie den auf dem Bildschirm
+   sichtbaren Pfeil vor den gewünschten Namen posi­
+   tionieren. Mit den Tasten <x> oder <RETURN> kön­
+   nen Sie den Namen ankreuzen. Ist die Auswahl
+   mehrerer Dateinamen möglich, so können Sie den
+   Vorgang wiederholen. Mit den Tasten <o> oder
+   <RUBOUT> können Sie auch ein Kreuz vor einem
+   Namen wieder löschen. Daneben gibt es noch eini­
+   ge Tastenfunktionen, die für die Bedienung recht
+   hilfreich sein können. Tippen Sie während der
+   Auswahl die Fragezeichentaste (<?>), so werden
+   Ihnen alle Bedienungsmöglichkeiten auf dem Bild­
+   schirm angezeigt. Eine Auswahl, in der mehrere
+   Dateien angekreuzt werden dürfen, wird durch die
+   Tastenfolge <ESC><q> verlassen. Anschließend
+   wird die eingestellte Operation mit den ange­
+   kreuzten Dateien ausgeführt. Sind Sie versehent­
+   lich in eine solche Auswahl gelangt, so können
+   Sie den Vorgang durch die Tastenkombination
+   <ESC><h> abbrechen. 
+ 
+-  An einigen Stellen werden Sie aufgefordert, eine
+   Eingabe zu machen (z.B. einen Dateinamen einzu­
+   geben). Wird Ihnen hier ein Vorschlag gemacht,
+   den Sie akzeptieren, so brauchen Sie zur Bestä­
+   tigung nur die <RETURN>-Taste zu tippen. Ge­
+   fällt Ihnen der Vorschlag nicht oder wird Ihnen
+   kein Vorschlag gemacht, so machen Sie bitte die
+   gewünschte Eingabe. Zum Schreiben stehen Ihnen
+   alle aus dem Editor bekannten Funktionen zur
+   Verfügung. Mit der Taste <RUBOUT> können Sie
+   Buchstaben löschen, mit <RUBIN> einfügen. Die
+   Eingabe wird durch Tippen der <RETURN>-Taste
+   abgeschlossen. Ist der von Ihnen gewünschte Name
+   schon in Ihrer Task vorhanden und steht in der
+   Fußzeile der Hinweis 'Zeigen: <ESC><z>', dann
+   können Sie sich auch alle vorhandenen Namen zur
+   Auswahl anbieten lassen und durch Ankreuzen den
+   beabsichtigten Namen auswählen. 
+ 
+-  Ihnen können auch mehrere Alternativen angeboten
+   werden, zwischen denen Sie wählen müssen. In der
+   untersten Zeile eines solchen Kastens, in denen
+   Ihnen die Alternativen auf dem Bildschirm einge­
+   blendet werden, sind die Möglichkeiten aufge­
+   führt, die darüber beschrieben sind. Mit den
+   Pfeiltasten können sie die Markierung auf die
+   gewünschte Alternative positionieren und dann
+   durch die <RETURN>-Taste zur Ausführung bringen.
+   (Manchmal ist das auch durch Tippen der den Al­
+   ternativen vorangestellten Buchstaben oder Zif­
+   fern möglich). 
+ 
+-  Durch die Tastenfolge <ESC><q> kann das Menu
+   insgesamt verlassen werden. Damit das nicht ver­
+   sehentlich geschieht, wird jeweils die Frage
+   gestellt, ob Sie das Menu tatsächlich verlassen
+   wollen. Diese Frage beantworten Sie bitte je
+   nach Wunsch mit 'ja' oder 'nein' durch Tippen
+   der Tasten <j> bzw. <n>. 
+ 
+#page#    
+5.2  Menufunktionen zum Oberbegriff  'Simulation' 
+ 
+#on("b")# 
+BAP:  Simulation  Parameter  Konfiguration  Dateien  Archiv 
++-------------------------------+----------------------------------------- 
+|  s Simulation ausführen       | 
+|  ---------------------------  | 
+|  a Auswertung auf Bildschirm  | 
+|  d Drucken von Auswertungen   | 
++-------------------------------+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+#on("u")##on("b")#s Simulation ausführen#off("b")##off("u")# 
+        Mit dieser Menufunktion starten Sie einen
+     Simulationslauf. Bevor Sie aber mit der Arbeit
+     am Bildschirmarbeitsplatz beginnen können,
+     wird eine "Identifikation" (Vor- und Nachname)
+     von Ihnen verlangt. Das Protokoll, das bei der
+     Simulation entsteht, erhält dann die hier ein­
+     gegebene Kennung. Geben Sie für mehrere Proto­
+     kolle den gleichen Namen an, so werden die
+     Protokolle in der Reihenfolge ihrer Anlage
+     durchnumeriert. 
+        Nach Eingabe der Kennung werden oben auf
+     dem Bildschirm die zur Zeit eingestellten Si­
+     mulationsdaten angezeigt - alle Daten, die Sie
+     zur Bedienung während der Simulation benöti­
+     gen. Die eigentliche Simulation beginnt erst
+     mit dem nächsten Tastendruck; dazu erfolgt ein
+     Hinweis auf dem Bildschirm. 
+        Nach Abschluß der Simulation wird Ihnen
+     gegebenenfalls (sehen Sie dazu auch die Menu­
+     funktion 'k Kurzauswertung' unter dem Oberbe­
+     griff 'Konfiguration') eine Kurzauswertung auf
+     dem Bildschirm ausgegeben. Anschließend gelan­
+     gen Sie zurück in das Menu. 
+        Diese Menufunktion hat eine ähnliche Wir­
+     kung wie der Aufruf des Programms 'Material­
+     prüfung' (MP). Im Gegensatz zum Aufruf des
+     Programms 'Materialprüfung' (MP - mit dem Be­
+     fehl: mp <RETURN>) werden hier allerdings kei­
+     ne ausführlichen Informationen vor dem eigent­
+     lichen Simulationslauf ausgegeben, sondern es
+     wird nur nach einer Identifikation (Vorname
+     und Nachname) gefragt. Nach Abschluß der Si­
+     mulation verbleibt das Protokoll in der Task -
+     es wird nicht, wie im Programmteil 'Material­
+     prüfung', in die Vatertask geschickt. 
+ 
+#on("u")##on("b")#a Auswertung auf Bildschirm#off("b")##off("u")# 
+        Alle Simulationsprotokolle, die sich in
+     Ihrer Task befinden, werden Ihnen zur Auswahl
+     angeboten. Wenn Sie den/die gewünschten Proto­
+     kollnamen angekreuzt und die Auswahl mit der
+     Tastenfolge <ESC><q> verlassen haben, werden
+     die Protokolle nacheinander in der Ankreuzrei­
+     henfolge ausgewertet und die Auswertungen auf
+     dem Bildschirm angezeigt. 
+        Die gesamte Auswertung kann zwar nicht auf
+     einmal auf dem Bildschirm angezeigt werden -
+     Sie können aber das Fenster mit <HOP><hoch>
+     und <HOP><runter> rollen und so in die gesamte
+     Datei Einsicht nehmen. Gegebenenfalls (sehen
+     Sie dazu auch die Menufunktion 'u Umfang der
+     Auswertung' unter dem Oberbegriff 'Konfigura­
+     tion') werden an das Ende der eigentlichen
+     Ergebnisse noch Erläuterungen zum Protokoll
+     ausgegeben. (Zur Protokollauswertung selbst
+     sehen Sie bitte Kapitel 4.4). Da die Auswer­
+     tung jeweils in eine Datei geschrieben wird,
+     können Sie sie mit der Tastenkombination
+     <ESC><q> verlassen. 
+ 
+     Fehlerfälle:  - Sehen Sie dazu bitte Kapitel
+                     4.5.3 
+ 
+#on("u")##on("b")#d Drucken von Auswertungen#off("b")##off("u")# 
+        Alle Simulationsprotokolle, die sich in
+     Ihrer Task befinden, werden Ihnen zur Auswahl
+     angeboten. Wenn Sie den/die gewünschten Proto­
+     kollnamen angekreuzt und die Auswahl mit der
+     Tastenfolge <ESC><q> verlassen haben, werden
+     die Protokolle nacheinander in der Ankreuzrei­
+     henfolge ausgewertet und die Auswertdateien
+     zum Drucker geschickt. 
+        #on("b")#ACHTUNG!#off("b")# Zum Ausdruck von Simulationsproto­
+     kollen muß unbedingt diese Menufunktion ge­
+     wählt werden! Zwar können normale Textdateien
+     auch mit dem Menupunkt 'Drucken' unter dem
+     Oberbegriff 'Dateien' ausgedruckt werden - das
+     gilt aber nicht für die bei den Simulationen
+     erzeugten Protokolldateien, die Sie am Präfix
+     'gs-Protokoll:' erkennen können. 
+        Der Ausdruck der Protokollauswertungen er­
+     folgt normalerweise im Standardschrifttyp Ih­
+     res Druckers. Es besteht allerdings die Mög­
+     lichkeit, einen anderen Schrifttyp für den
+     Ausdruck der Protokolldateien einzustellen.
+     Sehen Sie dazu bitte im Kapitel 6 'Hinweise
+     für den Systembetreuer'. 
+ 
+#page#             
+5.3  Menufunktionen zum Oberbegriff  'Parameter' 
+ 
+#on("b")# 
+BAP:  Simulation  Parameter  Konfiguration  Dateien  Archiv 
+-------+---------------------------+-------------------------------------- 
+       |  e Einstellung anzeigen   | 
+       |  s Standardwerte          | 
+       |  -----------------------  | 
+       |  b Breite des Werkstücks  | 
+       |  h Höhe   des Werkstücks  | 
+       |  i Invers-/Normal         | 
+       |  z Zeichensatz            | 
+       |  f Fehlerzeichen          | 
+       |  t Tastenbelegung         | 
+       |  -----------------------  | 
+       |  a Anzahl Arbeitsphasen   | 
+       |  d Dauer Arbeitsphase     | 
+       |  p Pausendauer            | 
+       |  -----------------------  | 
+       |  w Wertungsschlüssel      | 
+       +---------------------------+ 
+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+#on("u")##on("b")#e Einstellung anzeigen#off("b")##off("u")# 
+        Auf dem Bildschirm erscheinen zwei Fenster.
+     Im Fenster links werden alle Werte angezeigt,
+     die die Parameter zur Zeit annehmen. Oben kön­
+     nen Sie ablesen, welches Aussehen ein Werk­
+     stück nach der augenblicklichen Einstellung
+     auf dem Bildschirm hätte. Darunter ist angege­
+     ben, welche Tasten bei der Bearbeitung der
+     Werkstücke während des Simulationslauf benutzt
+     werden können. Unten ist noch aufgeführt, wie
+     viele Arbeitsphasen vorgesehen sind und wie
+     lange die Arbeitsphasen, Pausen und die Ge­
+     samtsimulation dauern. 
+        Im Fenster rechts wird ein Diagramm ausge­
+     geben. Hier ist der Bewertungsfaktors in Ab­
+     hängigkeit von der Ausbesserungsrate darge­
+     stellt. Hinsichtlich der Bedeutung des Bewer­
+     tungsfaktors sehen Sie bitte in Kapitel 4.5.1. 
+        Die Anzeige kann durch Tippen einer belie­
+     bigen Taste verlassen werden. 
+ 
+#on("u")##on("b")#s Standardwerte#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie mit ei­
+     nem Tastendruck die sogenannten "Standardwer­
+     te" einstellen - die Werte, die die Parameter
+     haben, wenn das System "frisch installiert"
+     ist. 
+        Zur Sicherheit zeigt das System die aktuel­
+     len Werte an und erfragt, ob Sie die Standard­
+     werte tatsächlich einstellen wollen. Bejahen
+     Sie diese Frage, so werden alle aktuellen Wer­
+     te durch die Standardwerte überschrieben und
+     auf dem Bildschirm angezeigt. Von dieser Ein­
+     stellung ist auch der Wertungsschlüssel be­
+     troffen - der aber nicht angezeigt wird. Die
+     Einstellung wird derart vorgenommen, daß Be­
+     wertungsfaktor und Ausbesserungsrate identisch
+     sind. 
+ 
+#on("u")##on("b")#b Breite des Werkstücks#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie die An­
+     zahl der Zeichen je Werkstückzeile festlegen.
+     Im Fenster links oben werden der kleinstmög­
+     liche Wert (1), der größtmögliche Wert (70)
+     und der aktuell eingestellte Wert angezeigt.
+     Unten erscheint zur Kontrolle ein Werkstück,
+     das den aktuellen Parameterwerten entspricht. 
+        Im Fenster rechts oben wird an Sie die Fra­
+     ge gerichtet, ob Sie tatsächlich eine Verände­
+     rung vornehmen möchten. Haben Sie versehent­
+     lich diesen Menupunkt gewählt, verneinen Sie
+     einfach diese Frage (Taste <n>) und gelangen
+     so - unter Beibehaltung des z.Z. eingestellten
+     Wertes - zurück in das Menu. 
+        Bejahen Sie die Frage, so erhalten Sie die
+     Möglichkeit, den bisher eingestellten Wert mit
+     der Pfeiltaste <hoch> zu erhöhen, mit der
+     Pfeiltaste <runter> zu erniedrigen - aller­
+     dings nur innerhalb der angezeigten Grenzen.
+     Wenn Sie die gewünschte Einstellung vorgenom­
+     men und die Eingabe durch <RETURN> abgeschlos­
+     sen haben, erscheint ein Werkstück in der neu
+     eingestellten Breite unten auf dem Bildschirm.
+     Bejahen Sie die Frage, ob Sie mit der Werk­
+     stückbreite einverstanden sind, dann gelangen
+     Sie ins Menu zurück; ansonsten können Sie die
+     Werkstückbreite nach gleichem Verfahren erneut
+     einstellen. 
+ 
+#on("u")##on("b")#h Höhe des Werkstücks#off("b")##off("u")# 
+        Die Einstellung der Werkstückhöhe (Anzahl
+     Zeichen pro Werkstückspalte) erfolgt analog
+     zur Einstellung der Werkstückbreite - sehen
+     Sie bitte dort. 
+ 
+#on("u")##on("b")#i Invers-/Normal#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie festle­
+     gen, ob das zu bearbeitende Werkstück 'normal'
+     oder 'invers' dargestellt wird. Diese Darstel­
+     lung ist aber immer in Abhängigkeit von der
+     Grundeinstellung Ihres Bildschirms zu sehen.
+     Wenn Ihr Bildschirm normalerweise helle Zei­
+     chen auf dunklem Grund darstellt, so bedeutet
+     'normal' eben diese Einstellung; 'invers' be­
+     deutet dann, daß die Zeichen des Werkstücks
+     dunkel auf hellem Grund dargestellt werden -
+     bei anderer Bildschirmgrundeinstellung eben
+     umgekehrt. 
+        Unten auf dem Bildschirm wird Ihnen zur
+     Kontrolle ein Werkstück in aktueller Darstel­
+     lung gezeigt. Im Fenster oben rechts erscheint
+     die Frage, ob Sie eine Veränderung der augen­
+     blicklichen Einstellung wünschen. Je nachdem,
+     ob Sie die Frage bejahen oder verneinen, wird
+     eine Veränderung vorgenommen oder nicht. 
+ 
+#on("u")##on("b")#z Zeichensatz#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie das Feh­
+     lerzeichen festlegen und bestimmen, aus wel­
+     chen Zeichen die Werkstücke zusammengesetzt
+     werden sollen. Bejahen Sie die Frage nach der
+     Neufestlegung des Zeichensatzes, so werden
+     Ihnen im Fenster links alle möglichen Zeichen
+     angezeigt. Die Zeichen werden hier in der Rei­
+     henfolge ihres internen Codes ausgegeben. Sie
+     können nun - indem Sie einfach die entspre­
+     chende Taste tippen - eines der angegebenen
+     Zeichen als 'Fehlerzeichen' bestimmen. Es wird
+     daraufhin invers dargestellt. 
+        Anschließend können Sie die Zeichen bestim­
+     men, die sonst noch im Werkstück vorkommen
+     sollen. Allerdings sind Sie bei dieser Wahl
+     nicht so frei wie bei der Wahl des Fehlerzei­
+     chens. Es muß sich um einen zusammenhängenden
+     Bereich von Zeichen handeln, die um das Feh­
+     lerzeichen gruppiert sind - 'zusammenhängend'
+     bezieht sich dabei auf die Reihenfolge der
+     Zeichen im Fenster links. 
+        Die Festlegung selbst erfolgt in zwei Etap­
+     pen. Zuerst können Sie den Bereich der Zeichen
+     bestimmen, die in der Reihenfolge vor dem Feh­
+     lerzeichen stehen. Mit der Pfeiltaste <hoch>
+     markieren Sie den Bereich, der vor dem Fehler­
+     zeichen liegt; mit der Pfeiltaste <runter>
+     können Sie ggf. die Markierung wieder rückgän­
+     gig machen. Wenn Sie so den gewünschten Be­
+     reich markiert haben, tippen Sie die
+     <RETURN>-Taste. 
+        Anschließend bestimmen Sie den Bereich hin­
+     ter dem Fehlerzeichen auf vergleichbare Weise
+     und schließen auch hier die Einstellung mit
+     der <RETURN>-Taste ab. Daraufhin wird Ihnen
+     der eingestellte Zeichensatz mit markiertem
+     Fehlerzeichen noch einmal zur Kontrolle im
+     Fenster links ausgegeben. Sind Sie mit der
+     Einstellung einverstanden, so bejahen Sie die
+     an Sie gerichtete Frage und gelangen ins Menu
+     zurück; ansonsten können Sie nach gleichem
+     Verfahren die Einstellung korrigieren. 
+ 
+#on("u")##on("b")#f Fehlerzeichen#off("b")##off("u")# 
+        Diese Menufunktion ist dann sinnvoll zu
+     wählen, wenn Sie den eingestellten Zeichensatz
+     beibehalten und nur das Fehlerzeichen verän­
+     dern wollen. Wenn Sie die Frage bejaht haben,
+     eine Veränderung vornehmen zu wollen, haben
+     Sie die Möglichkeit, durch Verschiebung der
+     Markierung im Fenster links (durch die Tasten
+     <hoch> und <runter>) das neue Fehlerzeichen
+     einzustellen. Die Einstellung wird durch
+     <RETURN> abgeschlossen. Sind Sie mit dem ein­
+     gestellten Fehlerzeichen einverstanden, gelan­
+     gen Sie zurück ins Menu; ansonsten können Sie
+     Ihre Einstellung korrigieren. 
+ 
+#on("u")##on("b")#t Tastenbelegung#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie die Ta­
+     sten bestimmen, die bei einem Simulationslauf
+     zur Bedienung des Systems benutzt werden kön­
+     nen. Ihnen wird im Fenster links oben die ak­
+     tuelle Einstellung angezeigt. Haben Sie sich
+     entschlossen, eine Neueinstellung vorzunehmen,
+     werden nacheinander die entsprechenden Tasten
+     erfragt. Sie brauchen dabei jeweils nur die
+     Taste zu tippen, die Sie für die entsprechende
+     Funktion vorgesehen haben. 
+        Sie können die Tasten nahezu frei wählen.
+     Es ist allerdings nicht erlaubt, die <SV>-
+     Taste zu wählen. Ebensowenig wird die Einstel­
+     lung akzeptiert, wenn Sie Mehrfachbelegungen
+     vornehmen, d.h, eine Taste für mehrere Funk­
+     tionen vorschlagen. Achten Sie deshalb immer
+     auf den Kommentar zur Einstellung im Fenster
+     unten links. Ist die Neueinstellung fehler­
+     haft, so erfolgt ein Hinweis darauf - in einem
+     solchen Falle bleibt die alte Tastenbelegung
+     erhalten. 
+ 
+#on("u")##on("b")#a Anzahl Arbeitsphasen#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie festle­
+     gen, in wie viele Arbeitsphasen ein Simula­
+     tionslauf jeweils eingeteilt werden soll. Im
+     Fenster links oben werden der kleinstmögliche
+     Wert (2), der größtmögliche Wert (20) und der
+     aktuell eingestellte Wert angezeigt. Im Fen­
+     ster unten wird die aktuelle Simulationsdauer
+     angezeigt. 
+        Im Fenster rechts oben wird an Sie die Fra­
+     ge gerichtet, ob Sie tatsächlich eine Verände­
+     rung vornehmen möchten. Bejahen Sie die Frage,
+     so erhalten Sie die Möglichkeit, den bisher
+     eingestellten Wert mit der Pfeiltaste <hoch>
+     zu erhöhen, mit der Pfeiltaste <runter> zu
+     erniedrigen - allerdings nur innerhalb der
+     angezeigten Grenzen. 
+        Wenn Sie die gewünschte Einstellung vorge­
+     nommen und die Eingabe durch <RETURN> abge­
+     schlossen haben, erscheinen die neuen Simula­
+     tionszeiten im Fenster unten. Bejahen Sie die
+     Frage, ob Sie mit der Arbeitsphasenanzahl ein­
+     verstanden sind, dann gelangen Sie ins Menu
+     zurück; ansonsten können Sie nach gleichem
+     Verfahren die getroffene Einstellung korrigie­
+     ren. 
+ 
+#on("u")##on("b")#d Dauer Arbeitsphase#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie festle­
+     gen, wie lange eine Arbeitsphase dauern soll.
+     Es kann ein Wert zwischen 1 min und 60 min
+     eingestellt werden. Das Einstellverfahren ver­
+     läuft analog zur Festlegung der Anzahl der
+     Arbeitsphasen - sehen Sie bitte dort. 
+ 
+#on("u")##on("b")#p Pausendauer#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie festle­
+     gen, wie lange die Pause zwischen je zwei Ar­
+     beitsphasen dauern soll. Es kann ein Wert zwi­
+     schen 1 min und 30 min eingestellt werden. Das
+     Einstellverfahren verläuft analog zur Festle­
+     gung der Anzahl der Arbeitsphasen - sehen Sie
+     bitte dort. 
+ 
+#on("u")##on("b")#w Wertungsschlüssel#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie den Wer­
+     tungsschlüssel festlegen. Zur genauen Erläu­
+     terung der Bedeutung des Bewertungsfaktors
+     sehen Sie bitte Kapitel 4.5.1. 
+        Im Fenster links wird der aktuell einge­
+     stellte Wertungsschlüssel angezeigt. Stellen
+     Sie sich die ins Koordinatensystem eingetrage­
+     nen Kreuzchen durch einen Streckenzug verbun­
+     den vor. Entscheiden Sie sich für eine Neu­
+     festlegung, dann können Sie mit den Pfeil­
+     tasten <hoch> und <runter> nacheinander die
+     einzelnen Kreuzchen im Koordinatensystem nach
+     oben bzw. nach unten verschieben. 
+        Haben Sie ein Kreuzchen an die gewünschte
+     Stelle positioniert, so tippen Sie als Kenn­
+     zeichen dafür die <RETURN>-Taste. So gelangen
+     Sie zum nächsten Kreuzchen bzw. nach dem letz­
+     ten Kreuzchen zurück in das Fenster oben
+     rechts. Wenn Sie mit dem eingestellten Wer­
+     tungsschlüssel einverstanden sind, gelangen
+     Sie zurück ins Menu; ansonsten können Sie die
+     vorgenommene Einstellung korrigieren. 
+ 
+#page# 
+5.4  Menufunktionen zum Oberbegriff  'Konfigu­
+     ration' 
+ 
+#on("b")# 
+BAP:  Simulation  Parameter  Konfiguration  Dateien  Archiv 
+--------------------+---------------------------+------------------------- 
+                    |  u Umfang der Auswertung  | 
+                    |  k Kurzauswertung         | 
+                    +---------------------------+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+#on("u")##on("b")#u Umfang der Auswertung#off("b")##off("u")# 
+        Mit dieser Menufunktion können Sie festle­
+     gen, ob am Ende einer Protokollauswertung die
+     sogenannten 'Anmerkungen', die die Zusammen­
+     hänge im Protokoll erläutern, jeweils mit aus­
+     gegeben werden sollen oder nicht. Die hier
+     getroffene Festlegung gilt sowohl für die Aus­
+     wertung auf dem Bildschirm als auch für den
+     Ausdruck über einen angeschlossenen Drucker. 
+        Zum Verständnis der Auswertungen sind die
+     Anmerkungen sehr hilfreich. Hat man aber meh­
+     rere Simulationsläufe absolviert, bei denen
+     der Wertungsschlüssel identisch ist, so wäre
+     es überflüssig, jeweils die Anmerkungen mit
+     ausgeben zu lassen. 
+        Die aktuelle Einstellung (mit/ohne Anmer­
+     kungen) wird im Fenster links oben angezeigt.
+     Im Fenster rechts oben wird die Frage ge­
+     stellt, ob Sie eine Veränderung der Einstel­
+     lung wünschen. Nur wenn Sie diese Frage beja­
+     hen, wird die Einstellung verändert; ansonsten
+     gelangen Sie unter Beibehaltung der alten Ein­
+     stellung ins Menu zurück. 
+ 
+#on("u")##on("b")#k Kurzsauswertung#off("b")##off("u")# 
+        Standardmäßig wird am Ende eines Simula­
+     tionslaufes eine Kurzauswertung auf dem Bild­
+     schirm ausgegeben. Wenn Sie diese überflüssig
+     finden oder wenn Sie es aus didaktischen Grün­
+     den vorziehen, auf eine solche Kurzauswertung
+     zu verzichten, können Sie diese Kurzauswertung
+     durch diese Menufunktion ab- bzw. wieder ein­
+     schalten. 
+        Die hier getroffene Einstellung ist auch
+     gültig für anschließend eingerichtete Sohn­
+     tasks - und zwar sowohl für das Teilprogramm
+     'Bildschirmarbeitsplatz' als auch für das
+     Teilprogramm 'Materialprüfung'. 
+        Die aktuelle Einstellung (mit/ohne Kurzaus­
+     wertung) wird im Fenster links oben angezeigt.
+     Im Fenster rechts oben wird die Frage ge­
+     stellt, ob Sie eine Veränderung der Einstel­
+     lung wünschen. Nur wenn Sie diese Frage beja­
+     hen, wird die Einstellung verändert; ansonsten
+     gelangen Sie unter Beibehaltung der alten Ein­
+     stellung ins Menu zurück 
+ 
+#page# 
+5.5  Menufunktionen zum Oberbegriff  'Dateien' 
+ 
+#on("b")# 
+BAP:  Simulation  Parameter  Konfiguration  Dateien  Archiv 
+------------------------------------+-------------------+----------------- 
+                                    |  v Verzeichnis    | 
+                                    |  ---------------  | 
+                                    |  l Löschen        | 
+                                    |  d Drucken        | 
+                                    |  ---------------  | 
+                                    |  k Kopieren       | 
+                                    |  u Umbenennen     | 
+                                    |  ---------------  | 
+                                    |  s Speicherplatz  | 
+                                    |  a Aufräumen      | 
+                                    +-------------------+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+   Die einzelnen Menufunktionen zu diesem Oberbe­
+griff sind detailliert im Handbuch zum Programm
+#on("b")#gs-DIALOG#off("b")# beschrieben und können dort nachgeschla­
+gen werden. An dieser Stelle seien nur einige Be­
+sonderheiten genannt, die hinsichtlich des Pro­
+grammsystems #on("b")#gs-MP BAP#off("b")# zutreffen: 
+   Protokolldateien, die während eines Simulations­
+laufs angelegt werden, können Sie am Präfix 'gs-
+Protokoll:' erkennen. Diese Protokolldateien können
+#on("u")#nicht#off("u")# mit der in diesem Pull-Down-Menu angegebenen
+Menufunktion 'd Drucken' über den Drucker ausge­
+druckt werden. Die Simulationsdaten sind in den
+Protokolldateien nämlich in einem gesonderten For­
+mat aufgezeichnet, das vom Drucker nicht ausgewer­
+tet werden kann. 
+   Für die Auswertung und den anschließenden Aus­
+druck dieser Protokolldateien ist die Menufunktion
+'d Drucken von Auswertungen' unter dem Oberbegriff
+'Simulation' bereitgestellt! 
+   Sie können den Protokolldateien mit der Menu­
+funktion 'u Umbenennen' einen neuen Namen geben.
+Achten Sie aber #on("u")#unbedingt(!)#off("u")# darauf, daß das Präfix
+'gs-Protokoll:' bei der Umbenennung erhalten bleibt
+- sonst wird die Datei nicht mehr als Protokollda­
+tei vom Auswertsystem erkannt! 
+   Die eben angesprochenen Protokolldateien können
+auch nicht mit der Menufunktion 'a Aufräumen' bear­
+beitet werden, da hier nur "normale" Textdateien
+akzeptiert werden - im übrigen sind die Protokoll­
+dateien immer optimal organisiert. 
+ 
+#page# 
+5.6  Menufunktionen zum Oberbegriff  'Archiv' 
+ 
+#on("b")# 
+BAP:  Simulation  Parameter  Konfiguration  Dateien  Archiv 
+------------------------------------------+-------------------------+----- 
+                                          |  r Reservieren          | 
+                                          |  n Neue Diskette        | 
+                                          |  ---------------------  | 
+                                          |  s Schreiben            | 
+                                          |  c Checken              | 
+                                          |  k Kombination          | 
+                                          |  h Holen/Lesen          | 
+                                          |  l Löschen              | 
+                                          |  ---------------------  | 
+                                          |  v Verzeichnis          | 
+                                          |  d Drucken              | 
+                                          |  ---------------------  | 
+                                          |  i Initialisieren       | 
+                                          |  z Zieltask einstellen  | 
+  +---------------------+                 +-------------------------+ 
+  | Dateiaustausch mit: | 
+  |  Archiv             | 
+  | Archivname:         | 
+  |  gs-MP BAP          | 
+  +---------------------+ 
+-------------------------------------------------------------------------- 
+Info:<ESC><?>/<?>  Wahl:<Pfeile>  Ausführen:<RETURN>  Verlassen:<ESC><q> 
+#off("b")# 
+ 
+   Die einzelnen Menufunktionen zu diesem Oberbe­
+griff sind detailliert im Handbuch zum Programm
+#on("b")#gs-DIALOG#off("b")# beschrieben und können dort nachgeschla­
+gen werden. 
+ 
+
diff --git a/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 6 b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 6
new file mode 100644
index 0000000..7d485d7
--- /dev/null
+++ b/doc/mp-bap/A5 - Doku: gs-MP BAP - Kapitel 6	
@@ -0,0 +1,53 @@
+#limit (11.0)##pagelength (16.5)##block##pageblock# 
+#start (2.0,0.0)# 
+#page (61)# 
+#headodd# 
+#center#gs-MP BAP#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-MP BAP 
+ 
+#end# 
+#center#6
+ 
+#center#Hinweise 
+#center#für den 
+#center#Systembetreuer 
+ 
+ 
+   Für den Ausdruck von Protokollauswertungen ist
+der Standardschrifttyp des Druckers voreingestellt.
+Sie haben aber die Möglichkeit, einen anderen
+Schrifttyp für den Protokollausdruck einzustellen.
+Dafür sind die beiden folgenden Prozeduren vorbe­
+reitet: 
+ 
+PROC druckereinstellung fuer protokolldatei 
+     (TEXT CONST schrifttyp, REAL CONST linker 
+      rand, oberer rand, schreibfeldbreite, 
+      schreibfeldlaenge) 
+ 
+     Geben Sie einen in Ihrer Installation vorhan­
+     denen Schrifttyp an. Beachten Sie bei der
+     Festlegung der anderen Maße (wie gewohnt in
+     cm), daß auf dem Schreibfeld 80 Druckpositio­
+     nen nebeneinander Platz haben müssen! 
+ 
+ 
+PROC std druckereinstellung fuer protokolldatei 
+ 
+     Sie können mit diesem Befehl wieder die Ein­
+     stellung vornehmen, die sonst standardmäßig
+     von #on("b")#gs-MP BAP#off("b")# vorgegeben wird: 
+ 
+     schrifttyp         :    ""  (Standard- 
+                                  schrifttyp) 
+     linker rand        :   0.0  (cm) 
+     oberer rand        :   0.0  (cm) 
+     schreibfeldbreite  :  21.0  (cm) 
+     schreibfeldlaenge  :  29.5  (cm) 
+ 
+ 
+ 
+
diff --git a/doc/mp-bap/gs-MP BAP handbuch.impressum b/doc/mp-bap/gs-MP BAP handbuch.impressum
new file mode 100644
index 0000000..91c6ce0
--- /dev/null
+++ b/doc/mp-bap/gs-MP BAP handbuch.impressum	
@@ -0,0 +1,104 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#gs-MP BAP 
+ 
+ 
+ 
+ 
+#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# 
+ 
+#free (4.0)##on("b")# 
+#center#gs-MP BAP
+ 
+ 
+#center#Benutzerhandbuch 
+ 
+ 
+#center#Version 1.0 
+ 
+ 
+#off("b")##center#copyright 
+#center#Eva Latta-Weber 
+#center#Software- und Hardware-Systeme, 1988 
+#center#ERGOS GmbH, 1990 
+#page# 
+#block# 
+#center#____________________________________________________________________________ 
+ 
+ 
+Copyright:  ERGOS GmbH   März 1990 
+ 
+                     Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+                     maschinenlesbare Form sowie das Speichern in Informations­
+                     systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+                     der ERGOS GmbH gestattet. 
+ 
+ 
+#center#____________________________________________________________________________ 
+ 
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender. 
+ 
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden. 
+ 
+Texterstellung   :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+                   erstellt und aufbereitet und auf einem Kyocera Laser­
+                   drucker gedruckt. 
+ 
+ 
+ 
+ 
+#center#___________________________________________________________________________ 
+ 
+ 
+ 
+Ergonomic Office Software GmbH 
+ 
+Bergstr. 7              Telefon: (02241) 63075 
+5200 Siegburg           Teletex: 2627-2241413=ERGOS 
+                        Telefax: (02241) 63078 
+ 
+ 
+#center#____________________________________________________________________________ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/programming/programmierhandbuch.1 b/doc/programming/programmierhandbuch.1
new file mode 100644
index 0000000..24f2b03
--- /dev/null
+++ b/doc/programming/programmierhandbuch.1
@@ -0,0 +1,650 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 1 : Einleitung","1")# 
+#pagenr("%",1)##setcount(1)##block##pageblock# 
+#headeven# 
+#center#EUMEL-Benutzerhandbuch 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#TEIL 1 : Einleitung 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+1 - % #right#GMD 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+GMD #rigth#1 - % 
+#end# 
+ 
+TEIL 1 : Einleitung 
+ 
+ 
+1.1  Allgemeines über EUMEL 
+ 
+Dieses Buch bietet eine Übersicht über die Standardprozeduren des Betriebssystem
+EUMEL. Es bietet damit sowohl Hilfestellung für die Benutzung der standardmäßig
+vorhandenen Kommandos als auch für die Programmierung, also die Erweiterung
+dieses Kommandovorrats. Es ist jedoch kein Lehrbuch der Programmierung! 
+ 
+In den ersten drei Kapiteln dieses Programmierhandbuches werden einige Grund­
+begriffe des Systems, die grundlegende Programmiersprache (ELAN) und der
+EUMEL-Editor erläutert. 
+ 
+Das vierte Kapitel bietet eine Übersicht über diejenigen Prozeduren und Operatoren,
+die eher der 'Job-Control-Language' zugerechnet werden können, also häufig im
+Kommandodialog benutzt werden. 
+ 
+Im fünften Teil sind diejenigen Operationen beschrieben, die meistenteils für die
+Programmierung benutzt werden. (Compiler, Operationen auf den elementaren Daten­
+typen, Dateien, Ein- und Ausgabe usw.). 
+ 
+Diese Trennung ist jedoch recht willkürlich, es ist ja gerade eine der wichtigen Eigen­
+schaften dieses Betriebssystems, daß es keine Trennung zwischen der Kommando­
+sprache des Betriebssystems und Programmmiersprache für das System gibt. Jedes
+Systemkommando ist Aufruf einer ELAN Prozedur, jede neue Prozedur stellt eine
+Erweiterung des Kommandovorrats des Systems dar. 
+ 
+Aus Gründen der Übersichtlichkeit der Zusammenstellung ist dieses Buch nicht frei
+von Vorwärtsverweisen! 
+ 
+#page# 
+ 
+1.2  Struktur des Betriebssystems EUMEL  
+ 
+Grundlegend für das Verständnis des Betriebssystems EUMEL ist der Begriff der
+#on("b")#Task#off("b")#. Eine Task kann als theoretisch unendliche Wiederholung eines Systempro­
+gramms der Form: 
+ 
+         'nimm Kommando entgegen' 
+         'verarbeite Kommando' 
+ 
+aufgefaßt werden. Einige Tasks existieren bereits als Grundstock des Systems,
+weitere werden von Benutzern des Systems erschaffen und dienen als persönliche
+Arbeitsumgebung für den 'Eigentümer'. Eine Task kann als benutzereigener, unab­
+hängiger Computer im Computer betrachtet werden, denn sie kann Kommandos
+entgegennehmen und ausführen und Daten verwalten und aufbewahren. 
+ 
+Eine Task kann neu erzeugt werden, an einen Bildschirm gekoppelt werden und
+beendet werden. 
+ 
+Das Tasksystem ist in einer baumartigen Struktur angeordnet. Außer der Wurzel 'UR'
+hat jede Task einen Vorgänger ('Vater-Task') und möglicherweise Nachfolger
+('Sohn-Tasks'). 
+ 
+#on("u")##ib#Task-Organisation#ie##off("u")# 
+ 
+ 
+       SUPERVISOR 
+             - 
+           SYSUR 
+               ARCHIVE 
+               configurator 
+               OPERATOR 
+               shutup 
+ 
+       UR 
+           PUBLIC 
+               Benutzertask1 
+               Benutzertask2 
+                   Benutzertask3 
+                 ..... 
+ 
+ 
+ 
+Jeder Benutzer arbeitet innerhalb eines EUMEL-Systems, indem er eine Task an
+sein Terminal koppelt und dort Programme aufruft. 
+ 
+Dateien sind grundsätzlich Eigentum einer Task. Es ist grundlegend für das Verständ­
+nis des Betriebssystems EUMEL, die Beziehung zwischen Tasks und Dateien zu
+erkennen. 
+ 
+Eine Task ist ein Prozeß, der gegebenenfalls Dateien besitzt. Dateien können nur in
+einer Task existieren. Um eine Datei einer anderen Task zur Verfügung zu stellen,
+wird eine Kopie der Datei an die andere Task geschickt, die sendende Task ist da­
+nach Eigentümer des 'Originals', die empfangende Task Eigentümer der 'Kopie'. 
+ 
+Soll eine Hierarchie von Dateien aufgebaut werden, so ist sie über eine Hierarchie
+von Tasks zu realisieren, da in einer Task alle Dateien gleichberechtigt sind. 
+ 
+Bis zu dieser Stelle war stets von Dateien die Rede. Dateien sind jedoch ein Spezial­
+fall der grundlegenderen Struktur des Datenraumes. 
+ 
+Ein #ib#Datenraum#ie# ist ein allgemeiner Datenbehälter. Ein Datenraum kann beliebige
+Daten aufnehmen und erlaubt direkten Zugriff auf diese Daten. Die Struktur der Daten
+im Datenraum unterscheidet sich nicht von der Struktur der Programmdaten. Der
+'innere Datentyp' eines Datenraums wird vom Programmierer festgelegt. 
+ 
+Vorgeprägt vom System gibt es Textdateien, jeder andere Datentyp muß vom Pro­
+grammierer geprägt werden, um so Dateien erzeugen zu können, die Objekte eben
+dieses neuen Typs enthalten. 
+#page# 
+ 
+ 
+1.3  Eigenschaften des Betriebssystems 
+ 
+Der erste Entwurf des Mikroprozessor-Betriebssystems EUMEL (#on("b")#E#off("b")#xtendable multi
+#on("b")#U#off("b")#ser #on("b")#M#off("b")#icroprozessor #on("b")#EL#off("b")#AN system) entstand 1979 mit dem Anspruch, auf Mikrocom­
+putern den Anwendern Hilfsmittel und Unterstützungen zu bieten, wie sie sonst nur
+auf Großrechnern zur Verfügung gestellt werden. 
+ 
+Aspekte, die EUMEL von anderen Betriebssystemen für Mikrocomputer unterscheiden,
+sind: 
+ 
+- Hardwareunabhängigkeit 
+- Multitaskingkonzept 
+- Multiuserbetrieb 
+- Erweiterbarkeit 
+- virtuelle Speicherverwaltung 
+- Datensicherheit 
+ 
+ 
+ 
+#on("u")##on("b")#Das EUMEL-Schichtenmodell#off("b")##off("u")# 
+ 
+Die Hardwareunabhängigkeit des Betriebssystems EUMEL begründet sich in seinem
+Aufbau aus Schichten (sogenannten virtuellen Maschinen), die einen klar definierten
+Leistungsumfang haben. 
+ 
+#center#beliebige Anwendungen 
+#center#Textverarbeitung, Datenbanken etc. 
+ 
+#center#Systemdienste: Monitor, Dateiverwaltung, Editor 
+#center#Task-System 
+#center#Standardpakete (BOOL, INT, REAL, TEXT) 
+#center#ELAN-Compiler 
+ 
+#center#EUMEL0 
+#center#(virtueller Prozessor mit eigenem Befehlssatz) 
+ 
+#center#SHard (Gerätetreiber) 
+ 
+#center#Hardware 
+ 
+ 
+Jede Schicht erwartet und erhält von ihren Nachbarn wohldefinierte Eingaben und gibt
+wohldefinierte Ausgaben weiter. Änderungen in einer Schicht müssen also in den
+angrenzenden Schichten beachtet werden, aber nicht in allen Teilen des Systems. 
+ 
+Um EUMEL auf Rechner mit einem neuen Prozessortyp zu portieren, wird zunächst
+eine auf die Eigenheiten des Prozessors abgestimmte EUMEL0-Maschine entworfen
+und eine Hardwareanpassung (#ib#SHard#ie# : Software/Hardware-Interface) für einen
+Rechner mit diesem Prozessor hergestellt. Alle höheren Schichten des Systems
+bleiben unberührt. Weitere mit diesem Prozessortyp ausgestattete Rechner können mit
+EUMEL betrieben werden, indem ein SHard für dieses Rechnermodell geschrieben
+wird. 
+ 
+Aus Benutzersicht ist wichtig, daß dadurch jegliche Software, die auf irgendeinem
+Rechner unter EUMEL verfügbar ist, auf jedem anderen Rechner, für den eine
+EUMEL Portierung existiert, lauffähig ist und gleiches Verhalten zeigt. Eine Vernet­
+zung beliebiger Rechner, auf die EUMEL portiert ist, ist problemlos möglich. 
+ 
+Desweiteren ist für den Benutzer des Systems von Bedeutung, daß er von der hard­
+warenahen Schicht entfernt ist. Weder die Programmiersprache noch irgendwelche
+speziellen Systemfunktionen gewähren direkten Zugriff auf den Speicher oder Regi­
+sterinhalte. Diese Tatsache hat weitreichende Folgen in Hinsicht auf Datenschutz und
+Systemsicherheit. 
+ 
+ 
+ 
+ 
+Multi-Tasking-/Multi-User-Betrieb 
+Wie einleitend dargestellt, besteht ein EUMEL-System aus diversen Tasks. Durch
+eine Aufteilung der Prozessorzeit in Zeitscheiben ist eine (quasi) parallele Bedienung
+mehrerer Tasks möglich. 
+ 
+Die multi-user-Fähigkeit des Betriebssystems wird durch den Anschluß mehrerer
+Bildschirmarbeitsplätze (Terminals) an V.24 Schnittstellen des Rechners erreicht.
+Dabei wird jeder Schnittstelle eine sogenannte Kanalnummer zugeordnet. Jeder
+Benutzer kann seine Task dann an einen Kanal (=Terminal) koppeln und an diesem
+Terminal gleichzeitig mit anderen Benutzern arbeiten. 
+ 
+ 
+ 
+ 
+Prozeßkommunikation und Netzwerkfähigkeit 
+Grundlage der Kommunikation ist die 'Manager-Eigenschaft' von Tasks. Eine Task
+ist 'Manager', wenn sie Aufträge anderer Tasks annehmen und ausführen kann.
+Insbesondere kann ein Manager veranlaßt werden, eine an ihn geschickte Datei anzu­
+nehmen, bzw. eine ihm gehörende Datei an die fordernde Task zu schicken. 
+ 
+Derartige Kommunikationslinien verlaufen normalerweise in der Baumstruktur des
+Systems: z.B. ist die Task 'PUBLIC' (vergl. Seite 2) grundsätzlich Manager-Task.
+Eine unterhalb von PUBLIC liegende Task kann eine Datei an PUBLIC senden, bzw.
+von PUBLIC holen. 
+ 
+Es ist auch möglich, eine Task für den Zugriff beliebiger anderer Tasks zu öffnen und
+somit beliebige Kommunikationspfade aufzubauen. Prinzipiell ist damit auch schon der
+Aufbau eines Netzwerkes beschrieben, denn sendende und empfangende Tasks
+können sich auf verschiedenen Rechnern befinden. 
+ 
+Durch selbst erstellte Programme kann der Eigentümer einer 'Manager-Task' die
+Reaktion dieser Task auf einen Auftrag von außen bestimmen. Beispielsweise kann
+ein Manager derart programmiert werden, daß er nur Dateien empfängt und ausdruckt,
+aber niemals Dateien verschickt (Spool-Task). 
+ 
+ 
+ 
+Erweiterbarkeit 
+Die Programmiersprache ELAN ist im EUMEL-System gleichzeitig Programmier-
+und System-Kommandosprache (JCL), denn jedes Kommando ist Aufruf einer
+ELAN-Prozedur und jede vom Benutzer geschriebene ELAN-Prozedur erweitert
+den Kommandovorrat des Systems. 
+ 
+Da alle EUMEL-Werkzeuge (einschließlich Editor) selbst ELAN-Programme sind,
+kann das System vom Benutzer selbst durch Hinzufügen eigener ELAN-Programme
+oder Programmpakete beliebig erweitert werden. Dabei können die bereits implemen­
+tierten Systemteile (z.B. die Fenstertechnik des Editors) genutzt werden. 
+ 
+Ein Benutzer muß, um alle Möglichkeiten vom EUMEL zu nutzen, nur eine Sprache
+lernen und nicht - wie bei anderen Betriebssystemen - zwei unterschiedliche, eine
+Kommando- und eine Programmiersprache. 
+ 
+ELAN selbst ist eine PASCAL-ähnliche Programmiersprache, die mit Hilfe der
+schrittweisen Verfeinerung (Refinement-Konzept) die Top-Down-Programmierung
+unterstützt. Das Paketkonzept, das der Modularisierung dient, und die freie Wahl von
+Bezeichnernamen sind Voraussetzung für übersichtliche und effiziente Programmie­
+rung. 
+ 
+ 
+ 
+ 
+Virtuelle Speicherverwaltung 
+Im EUMEL-System wird der Hauptspeicherplatz nach dem #on("b")#Demand-Paging-Prinzip#off("b")#
+verwaltet. Daten und Programme werden dazu in Seiten von 512 Byte aufgeteilt. Nur
+diejenigen Seiten, die wirklich benötigt werden, werden vom Hintergrundspeicher
+(Platte) in den Hauptspeicher geholt. Damit ist für den Benutzer bezüglich seiner
+Programm- bzw. Dateigrößen nicht mehr der Hauptspeicher, sondern die Hinter­
+grundkapazität von Bedeutung. Die Durchsatzgeschwindigkeit (Performance) ist
+abhängig von der Größe des RAM-Speichers und der Zugriffsgeschwindigkeit des
+Hintergrundmediums. Das Demand-Paging-Verfahren ist Grundlage für den
+Multi-User-Betrieb, wobei der Hauptspeicherplatz möglichst effizient zu nutzen und
+kein Benutzer zu benachteiligen ist. 
+ 
+Beim Duplizieren eines Datenraumes wird im EUMEL-System lediglich eine logische,
+keine physische Kopie erzeugt. Zwei Seiten (zweier Datenräume) heißen dann gekop­
+pelt (geshared), wenn beide Seiten physisch demselben Block zugeordnet sind. Erst
+bei einem Schreibzugriff werden die Seiten entkoppelt (entshared) und tatsächlich
+physisch kopiert. Daher der Name "#on("b")#copy-on-write#off("b")#". 
+ 
+Dieses Prinzip wird natürlich auch systemintern angewandt. Beispielsweise erbt eine
+Sohn-Task den Kommandovorrat der Vater-Task, indem der Standard-Datenraum,
+der die vorübersetzten ELAN-Prozeduren enthält, in der beschriebenen Weise kopiert
+wird. Prozeduren, die später hinzugefügt werden, werden natürlich nicht vererbt, da
+die Standard-Datenräume dann entkoppelt werden. 
+ 
+ 
+ 
+ 
+Datensicherheit 
+Störungen (inklusive Stromausfall) werden systemseitig durch eine automatische
+#on("b")#Fixpoint-Rerun-Logik#off("b")# aufgefangen, indem zum Zeitpunkt eines Fixpunkts der Inhalt
+des RAM Speichers, der seit dem letzten #ib#Fixpunkt#ie# verändert wurde auf den
+permanenten Speicher (Festplatte) geschrieben wird. Somit kann nach einer Störung
+immer auf den Systemzustand des letzten Fixpunktes aufgesetzt werden und die
+Datenverluste halten sich in erträglichen Grenzen. 
+ 
+Der Zeitraum zwischen zwei Fixpunkten beträgt standardmäßig 15 Minuten, kann aber
+vom Benutzer anders eingestellt werden. 
+ 
+Auch bei dieser Sicherung wird das Copy-on-write-Prinzip angewendet, so daß
+Platz- und Zeitaufwand gering sind und den normalen Ablauf nicht stören. 
+ 
+#page# 
+
+1.4  Wichtige Begriffe 
+ 
+-  #on("b")##ib#archive#ie##off("b")#.  Spezielle Task zur Verwaltung des Diskettenlaufwerks. Da für die
+   längerfristige Datenhaltung und zur zusätzlichen Datensicherung Dateien auf
+   Disketten geschrieben werden, besitzt das EUMEL-System für diese Aufgabe
+   eine besondere Task, die die Bedienung vereinfacht und exklusiven Zugriff auf das
+   Laufwerk garantiert. 
+ 
+-  #on("b")##ib#configurator#ie##off("b")#.  Besondere Task im Systemzweig des EUMEL-Systems. In
+   dieser Task ist die #ib#Konfiguration#ie# von Kanälen möglich, d.h. Kanal und
+   angeschlossenenes Gerät werden aufeinander abgestimmt. 
+ 
+-  #on("b")##ib#editor#ie##off("b")#.  Programm zur Dateibearbeitung am Bildschirm. Das Programm wird
+   durch das ( Monitor- ) Kommando 'edit' und die Eingabe des Namens der ge­
+   wünschten Datei als Parameter gestartet. 
+ 
+   Da ein Bildschirm normalerweise auf 80 Zeichen Zeilenbreite und 24 Zeilen be­
+   schränkt ist, kann der Editor als Fenster betrachtet werden, das über die mögli­
+   cherweise weitaus größere Datei bewegt wird und durch das der betrachtete Aus­
+   schnitt der Datei bearbeitet werden kann. 
+ 
+-  #on("b")##ib#manager task#ie##off("b")#.  Task, die Aufträge von anderen Tasks entgegennehmen und
+   ausführen #on("u")#kann#off("u")#. Beispielsweise ist die Verwaltung von Dateien, die mehreren
+   Benutzern (= anderen Tasks) zugänglich sein sollen, eine typische Aufgabe für
+   einen Manager. 
+ 
+-  #on("b")##ib#Monitor#ie##off("b")#. Der Empfänger von Kommandos innerhalb einer Task ist der Monitor. Der
+   Monitor ist sichtbar durch eine Zeile, in der 'gib kommando' steht. In diese Zeile
+   werden #ib#Kommando#ie#s und erforderliche Parameter eingegeben. 
+ 
+-  #on("b")##ib#Supervisor#ie##off("b")#.  Spezielle Task zur Überwachung eines EUMEL-Systems. Ein
+   Benutzer kann durch die Supervisor-Kommandos Leistungen von dieser Task
+   fordern: neue Task einrichten, Task wiederaufnehmen und diverse Informationen. 
+ 
+-  #on("b")##ib#Task#ie##off("b")#.  Beliebig langlebiger Prozeß im EUMEL-System, der die Arbeits­
+   umgebung für Benutzer bildet. Jede Task besitzt einen #ib#Standard-Datenraum#ie#, der
+   Code und Compilertabellen der Task enthält und kann weitere Datenräume
+   (Dateien) besitzen. 
+ 
+#page# 
+
+1.5  Die Notation in diesem Buch 
+ 
+Beachten Sie bitte folgende Regeln der Aufschreibung: 
+ 
+-  Funktionstasten werden ebenso wie besondere Tastenkombinationen explizit als
+   Tasten dargestellt: 
+ 
+      <SV>     <ESC>     <e>     
+ 
+       
+-  Alles, was Sie am Bildschirm Ihres Rechners schreiben oder lesen sollen, ist in
+   Textbereiche, die einen Bildschirm darstellen, eingefaßt. 
+ 
+  Beispiel: 
+ 
+____________________________________________________________________________ 
+    gib kommando: 
+    edit ("mein programm") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+-  Innerhalb des Handbuchs sind in der Aufschreibung die Konventionen der Pro­
+   grammiersprache ELAN berücksichtigt. Dabei sind folgende Besonderheiten zu
+   beachten: 
+ 
+   1) Kommandos werden grundsätzlich klein geschrieben. 
+ 
+   2) Dateinamen u.ä. sind Textdenoter und werden somit in Klammern und Anfüh­
+      rungsstriche gesetzt. In diesem Buch steht an den Stellen, wo ein Dateiname
+      auftaucht #on("i")# 'dateiname' #off("i")#; den Namen, den Sie tatsächlich verwenden, können
+      Sie frei wählen. 
+ 
+   3) Falls besondere Begriffe oder Beispiele innerhalb eines normalen Textes
+      auftreten, werden sie in einfache Anführungsstriche gesetzt. 
+ 
+ 
+#page# 
+
+1.6  Die Funktionstasten des EUMEL-Systems 
+ 
+Die Lage der EUMEL-Funktionstasten entnehmen Sie bitte der speziellen Installa­
+tionsanleitung zu dem von Ihnen benutzten Gerät. #l pos (0.0)##l pos(4.0)# 
+ 
+ 
+<v> <^> <>> <<>    Positionierungstasten 
+#table# 
+ 
+<SHIFT>           Umschalttaste 
+ 
+<CR>              Eingabe-/ Absatztaste 
+ 
+<ESC>             Kommandotaste 
+ 
+<SV>              Supervisortaste 
+ 
+<HOP>             Verstärkertaste 
+ 
+<RUBOUT>          Löschtaste 
+ 
+<RUBIN>           Einfügetaste 
+ 
+<TAB>             Tabulatortaste 
+ 
+<MARK>            Markiertaste 
+ 
+<STOP>            Stoptaste 
+ 
+<WEITER>          Weitertaste 
+#tableend##clear pos# 
+ 
+Weitere Informationen hierzu finden Sie in der Installationsanleitung zu dem von Ihnen
+benutzten Rechner oder Terminal. 
+#page# 
+ 
+1.7  Eine Beispielsitzung 
+ 
+Im Folgenden wird eine Beispielsitzung skizziert, in der ein ELAN-Programm erstellt
+und getestet wird. 
+ 
+  <SV>       SUPERVISOR aufrufen 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+                                           Terminal 2  
+ 
+ 
+                      EUMEL Version 1.8/M 
+ 
+ 
+        gib supervisor kommando: 
+        begin("meine erste Task") 
+ 
+ 
+ 
+   ESC ? --> help 
+   ESC b --> begin("")            ESC h --> halt 
+   ESC c --> continue("")         ESC s --> storage info 
+   ESC q --> break                ESC t --> task info 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+Durch das Kommando 'begin ("meine erste Task")', welches durch <CR> abgeschlos­
+sen werden muß, wird eine Task mit dem Namen 'meine erste Task' im Benutzer­
+zweig, also unterhalb von 'PUBLIC' angelegt. Würde diese Task bereits existieren, so
+könnten Sie sie mit 'continue ("meine erste Task")' an das Terminal holen. 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    edit ("mein erstes Programm") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+In der Task eröffnen Sie eine Datei mit dem Kommando 'edit ("dateiname")'. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    edit ("mein erstes Programm") 
+  "mein erstes Programm" neu einrichten (j/n) ? j 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Falls diese Datei neu ist, erfolgt eine Kontrollfrage (zur Kontrolle der gewünschten
+Schreibweise des Dateinamens), die Sie durch <j> bejahen. 
+ 
+ 
+____________________________________________________________________________ 
+  ............ mein erstes Programm ............... Zeile 1  #markon#    
+_
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+ 
+ 
+In die noch leere Datei tippen Sie nun den Programmtext ein. 
+ 
+ 
+____________________________________________________________________________ 
+  ............ mein erstes Programm ............... Zeile 1 
+ _INT PROC ggt (INT CONST a, b): 
+   INT VAR b kopie :: abs (b), a kopie :: abs (a); 
+    WHILE b kopie <> 0 REPEAT 
+      INT VAR rest := a kopie MOD b kopie; 
+      a kopie := b kopie; 
+      b kopie := rest 
+    END REPEAT; 
+   a kopie 
+ END PROC gt; 
+ 
+ REP 
+   lies 2 zahlen ein; 
+   gib groessten gemeinsamen teiler aus 
+ UNTIL no ("weitertesten") PER. 
+ 
+ lies 2 zahlen ein: 
+   line; put ("2 Zahlen eingeben:"); 
+   INT VAR a, b; 
+   get (a); get (b). 
+ 
+ gib groessten gemeinsamen teiler aus: 
+   put ("der größte gemeinsame Teiler von"); 
+   put (a); put ("und"); put (b); put ("ist"); put (ggt (a,b)); 
+   line. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+In dem Programmbeispiel wird ein Prozedur 'ggt' definiert, die den größten gemein­
+samen Teiler zweier Zahlen bestimmt. Die Prozedur soll für verschiedene Beispiele
+getestet werden; dies geschieht in dem Hauptprogramm, das solange Zahlen einliest
+und den größten gemeinsamen Teiler ausgibt, bis der Benutzer auf die Frage 'weiter­
+testen (j/n) ?' mit <n> antwortet. 
+ 
+Haben Sie das Programm eingegeben, so können Sie die Bearbeitung dieser Pro­
+grammdatei durch Drücken der Tasten <ESC> <q> (nacheinander!) beenden. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando : 
+   run ("mein erstes Programm") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Um Ihr Programm zu übersetzen und auszuführen, geben Sie das Kommando
+'run ("dateiname")'. 
+ 
+Der Verlauf der Übersetzung, die zwei Läufe über das Programm erfordert, ist am
+Zähler, der an der linken Seite des Bildschirms ausgegeben wird, zu erkennen. 
+ 
+Werden beim Übersetzen des Programms Fehler entdeckt, so werden diese im 'note­
+book' parallel zur Programmdatei gezeigt. In dem Beispielprogramm wurde ein
+Schreibfehler in Zeile 9 gemacht. 
+ 
+ 
+____________________________________________________________________________ 
+  ............ mein erstes Programm ............... Zeile 1 
+ _INT PROC ggt (INT CONST a, b): 
+   INT VAR b kopie :: abs (b), a kopie :: abs (a); 
+   WHILE b kopie <> 0 REPEAT 
+      INT VAR rest := a kopie MOD b kopie; 
+      a kopie := b kopie; 
+      b kopie := rest 
+   END REPEAT; 
+   a kopie 
+ END PROC gt; 
+ 
+ REP 
+  .................. notebook ..................... Zeile 1  #markon#    
+   Zeile 9    FEHLER bei >> gt << 
+              ist nicht der PROC Name 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Diesen Fehler müssen Sie nun verbessern. 
+ 
+____________________________________________________________________________ 
+  ............ mein erstes Programm ............... Zeile 9 
+ INT PROC ggt (INT CONST a, b): 
+   INT VAR b kopie :: abs (b), a kopie :: abs (a); 
+   WHILE b kopie <> 0 REPEAT 
+      INT VAR rest := a kopie MOD b kopie; 
+      a kopie := b kopie; 
+      b kopie := rest 
+   END REPEAT; 
+   a kopie 
+ END PROC ggt;_ 
+ 
+ REP 
+  .................. notebook ..................... Zeile 1 
+   Zeile 9    FEHLER bei >> gt << 
+              ist nicht der PROC Name 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+Haben Sie das Programm korrigiert, so können Sie die Datei durch Drücken der
+Tasten <ESC> <q> (nacheinander!) wieder verlassen. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    run ("mein erstes Programm") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nach Eingabe von <R> wird das Programm erneut übersetzt. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ Keine Fehler gefunden,  136 B Code, 82 B Paketdaten generiert 
+ 
+ 
+       *******  ENDE DER UEBERSETZUNG  ******* 
+ 
+ 
+ 2 Zahlen eingeben: _ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Das Programm war jetzt fehlerfrei. Nach der Übersetzung wurde die Ausführung
+gestartet. Nun können Beispiele getestet werden. 
+ 
+____________________________________________________________________________ 
+ 
+ 2 Zahlen eingeben: 125 250 
+ der größte gemeinsame Teiler von 125 und 225 ist 25 
+ weitertesten (j/n) ? 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Beantwortet man die Frage mit <n>, so wird die Ausführung des Programms beendet. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando : 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Um die Arbeit in der Task zu beenden, geben Sie auch an dieser Stelle <ESC> <q>
+(nacheinander!) ein. 
+ 
+Nach Verlassen der Task ist wiederum die EUMEL-Tapete auf dem Bildschirm. Jede
+weitere Aktion wird wiederum von hier aus durch <SV> begonnen. Insbesondere vor
+dem #ib#Ausschalten des Geräts#ie# muß nach <SV> eine Task des priviliegierten System­
+zweigs (oft: '#ib#shutup#ie#') mit <ESC> <c> an das Terminal gekoppelt werden, in der das
+Kommando 'shutup' gegeben wird. 
+
diff --git a/doc/programming/programmierhandbuch.2a b/doc/programming/programmierhandbuch.2a
new file mode 100644
index 0000000..a204091
--- /dev/null
+++ b/doc/programming/programmierhandbuch.2a
@@ -0,0 +1,1845 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 2 : ELAN","2")# 
+#pagenr("%",1)##setcount(1)##block##pageblock# 
+#headeven# 
+#center#EUMEL-Benutzerhandbuch 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#TEIL 2 : ELAN 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+2 - % #right#GMD 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+GMD #right# 2 - % 
+#end# 
+ 
+TEIL 2:  ELAN 
+ 
+2.1  Besondere Eigenschaften von ELAN 
+ 
+Kerneigenschaften von ELAN sind das #ib#Paketkonzept#ie# und die Methode des
+#ib#Refinements#ie#. 
+ 
+#on("b")#Paketkonzept:#off("b")# 
+ELAN bietet die Möglichkeit, neue Datentypen sowie Prozeduren und Operatoren auf
+diesen Datentypen zu definieren. Eine solche Definition von Algorithmen und Daten­
+typen kann zu einer logischen Einheit, einem Paket, zusammengefaßt werden. Pakete
+können in einer Task vorübersetzt werden und erweitern damit automatisch den
+Sprachumfang. 
+ 
+#on("b")#Methode des Refinements:#off("b")# 
+Die Methode des Refinements erlaubt das schrittweise Herleiten von Problemlösungen
+von der jeweils geeigneten Terminologie herunter zu den von ELAN standardmäßig
+angebotenen Sprachelementen. Durch diese Vorgehensweise wird in äußerst starkem
+Maße ein strukturierter Programmentwurf gemäß dem Top-Down-Prinzip gefördert. 
+ 
+Die Programmiersprache ELAN wird im EUMEL-System zu folgenden Zwecken
+eingesetzt: 
+ 
+-  Systemimplementationssprache 
+-  Kommandosprache 
+-  Anwenderprogrammiersprache 
+#page# 
+ 
+2.2  Lexikalische Elemente 
+ 
+Unter lexikalischen Elementen einer Programmiersprache versteht man die Elemente,
+in denen ein Programm notiert wird. 
+ 
+In ELAN sind dies: 
+ 
+-  Schlüsselwörter 
+-  Bezeichner 
+-  Sonderzeichen 
+-  Kommentare 
+ 
+ 
+ 
+ 
+2.2.1  Schlüsselwörter 
+ 
+Einige Wörter haben in ELAN eine feste Bedeutung und können somit nicht frei
+gewählt werden. Solche Wörter werden im EUMEL-System in Großbuchstaben
+geschrieben, Leerzeichen dürfen nicht enthalten sein. 
+ 
+Beispiele: 
+ 
+ 
+VAR 
+INT 
+WHILE 
+ 
+ 
+Wie später beschrieben wird, gibt es in ELAN auch die Möglichkeit, neue Schlüssel­
+wörter einzuführen. 
+ 
+ 
+#page# 
+ 
+2.2.2  Bezeichner 
+ 
+Bezeichner oder Namen werden benutzt, um Objekte in einem Programmtext zu
+benennen und zu identifizieren (z.B: Variablennamen, Prozedurnamen). 
+ 
+Namen werden in ELAN folgendermaßen formuliert: 
+ 
+Das erste Zeichen eines Namens muß immer ein Kleinbuchstabe sein. Danach dürfen
+bis zu 254 Kleinbuchstaben, aber auch Ziffern folgen. Zur besseren Lesbarkeit können
+Leerzeichen in einem Namen erscheinen, die aber nicht zum Namen zählen. Sonder­
+zeichen sind in Namen nicht erlaubt. 
+ 
+Beispiele für #on("b")#korrekte#off("b")# Bezeichner: 
+ 
+ 
+das ist ein langer name 
+x koordinate 
+nr 1 
+ 
+ 
+ 
+Beispiele für #on("b")#falsche#off("b")# Bezeichner: 
+ 
+ 
+x*1 
+1 exemplar 
+Nr 1 
+#page# 
+ 
+2.2.3  Sonderzeichen 
+ 
+Sonderzeichen sind Zeichen, die weder Klein- oder Großbuchstaben, noch Ziffern
+sind. Sie werden in ELAN als Trennzeichen oder als Operatoren benutzt. 
+ 
+In ELAN gibt es folgende Trennungszeichen: 
+ 
+-  das Semikolon (';') trennt Anweisungen 
+-  der Doppelpunkt (':') trennt Definiertes und Definition 
+-  der Punkt ('.') wird als Endezeichen für bestimmte Programmabschnitte, als Dezi­
+   malpunkt und als Selektor-Zeichen für Datenstrukturen benutzt 
+-  das Komma (',') trennt Parameter 
+-  Klammernpaare ('(', ')') werden zum Einklammern von Parameterlisten oder Teil­
+   ausdrücken benutzt 
+-  mit Anführungszeichen ('"') werden Text-Denoter umrahmt 
+-  eckige Klammernpaare ('[', ']') werden zur Subskription benutzt. 
+ 
+ 
+Als Operatornamen sind folgende Sonderzeichen erlaubt: 
+ 
+-  ein Sonderzeichen, sofern es nicht als Trennzeichen benutzt wird: 
+   !  $  %  &  '  *  +  -  /  <  =  >  ?  §  ^  '  ~ 
+-  eine Kombination von zwei Sonderzeichen. Diese Kombination muß jedoch bereits
+   in ELAN existieren: 
+   :=   <=   >=   <>   ** 
+ 
+#page# 
+ 
+2.2.4  Kommentare 
+ 
+Kommentare dienen ausschließlich der Dokumentation eines Programms. Sie werden
+vom Compiler überlesen und haben somit keinen Einfluß auf die Ausführung eines
+Programms. Sie dürfen an beliebigen Stellen eines Programmtextes geschrieben
+werden, jedoch nicht innerhalb von Schlüsselwörtern und Namen. Ein Kommentar darf
+über mehrere Zeilen gehen. In ELAN sind Kommentare nur in wenigen Fällen notwen­
+dig, da Programme durch andere Mittel gut lesbar geschrieben werden können. 
+ 
+Ein Kommentar in ELAN wird durch Kommentarklammern eingeschlossen. Es gibt
+folgende Formen von Kommentarklammern: 
+ 
+(*     Kommentar    *) 
+{      Kommentar     } 
+\#(     Kommentar    )# 
+ 
+Die letzte Version '\#(  Kommentar  )\#' wird im EUMEL-System nicht
+unterstützt; statt dessen gibt es noch folgende Möglichkeit: 
+ 
+\#     Kommentar    \# 
+ 
+Da bei der Kommentarkennzeichnung mit \# für Kommentaranfang und -ende das
+gleiche Zeichen benutzt wird, ist eine Schachtelung hier nicht möglich. 
+#page# 
+ 
+2.3  Datenobjekte 
+ 
+Eine Klasse von Objekten mit gleichen Eigenschaften wird in Programmiersprachen
+Datentyp genannt. Dabei hat ein Datentyp immer einen Namen, der die Klasse von
+Objekten sinnvoll kennzeichnet. Als ein Datenobjekt wird ein Exemplar eines Daten­
+typs (also ein spezielles Objekt einer Klasse) bezeichnet. 
+ 
+Datentypen sind in ELAN ein zentrales Konzept. Jedes der in einem ELAN-
+Programm verwandten Datenobjekte hat einen Datentyp; somit kann man Datentypen
+auch als Eigenschaften von Datenobjekten ansehen. Für jeden Datentyp sind nur
+spezielle Operationen sinnvoll. Man kann nun Compilern die Aufgabe überlassen zu
+überprüfen, ob stets die richtige Operation auf einen Datentyp angewandt wird. 
+ 
+ 
+ 
+2.3.1   Elementare Datentypen 
+ 
+Einige Datentypen spielen bei der Programmierung eine besondere Rolle, weil sie
+häufig benötigt werden. 
+ 
+In ELAN sind das die Datentypen für 
+ 
+-  ganze Zahlen (INT) 
+-  reelle Zahlen (REAL) 
+-  Zeichen und Zeichenfolgen (TEXT) 
+-  Wahrheitswerte (BOOL). 
+ 
+Diese Datentypen sind von der Sprache ELAN vorgegeben und werden elementare
+Datentypen genannt. Für effiziente Rechnungen mit elementaren Datentypen gibt es
+in den meisten Rechnern spezielle Schaltungen, so daß die Hervorhebung und be­
+sondere Rolle, die sie in Programmiersprachen spielen, gerechtfertigt ist. Zudem hat
+man Werte-Darstellungen (Denoter) innerhalb von Programmen für die elementaren
+Datentypen vorgesehen. 
+ 
+ 
+ 
+2.3.1.1  Denoter für elementare Datentypen 
+ 
+Die Darstellung eines Werts in einem Rechner zur Laufzeit eines Programms wird
+Repräsentation genannt. Wenn es eindeutig ist, daß es sich nur um die Repräsenta­
+tion im Rechner handelt, spricht man kurz von Werten. Um mit Objekten elementarer
+Datentypen arbeiten zu können, muß es in einem Programm die Möglichkeit geben,
+Werte eines Datentyps zu bezeichnen (denotieren). Die Werte-Darstellungen, die in
+ELAN Denoter genannt werden, sind für jeden Datentyp unterschiedlich. Wie bereits
+erwähnt, haben alle Datenobjekte in ELAN (also auch Denoter) nur einen - vom
+Compiler feststellbaren - Datentyp. Aus der Form eines Denoters ist also der Daten­
+typ erkennbar: 
+ 
+ 
+ 
+INT-Denoter: 
+Sie bestehen aus einer Aneinanderreihung von Ziffern. 
+ 
+Beispiele: 
+ 
+ 
+17 
+007 
+32767 
+0 
+ 
+ 
+Führende Nullen spielen bei der Bildung des Wertes keine Rolle (sie werden vom
+ELAN-Compiler überlesen). Negative INT-Denoter gibt es nicht. Negative Werte
+werden durch eine Aufeinanderfolge des monadischen Operators '-' (siehe 2.4.1.1)
+und eines INT- Denoters realisiert. 
+ 
+ 
+REAL-Denoter: 
+Hier gibt es zwei Formen: 
+Die erste besteht aus zwei INT-Denotern, die durch einen Dezimalpunkt getrennt
+werden. 
+ 
+Beispiele: 
+ 
+ 
+0.314159 
+17.28 
+ 
+ 
+Der Dezimalpunkt wird wie ein Komma in der deutschen Schreibweise benutzt. Nega­
+tive REAL-Denoter gibt es wiederum nicht. 
+ 
+Die zweite Form wird als "wissenschaftliche Notation" bezeichnet. Sie findet dann
+Verwendung, wenn sehr große Zahlen oder Zahlen, die nahe bei Null liegen, darge­
+stellt werden müssen. 
+ 
+Beispiele: 
+ 
+ 
+3.0 e5 
+3.0e-5 
+ 
+ 
+Der INT-Denoter hinter dem Buchstaben #on("b")#e#off("b")# gibt an, wie viele Stellen der Dezimal­
+punkt nach rechts (positive Werte) bzw. nach links (negative Werte) zu verschieben
+ist. Dieser Wert wird Exponent und der Teil vor dem Buchstaben #on("b")#e#off("b")# Mantisse genannt. 
+ 
+ 
+TEXT-Denoter: 
+Sie werden in Anführungszeichen eingeschlossen. 
+ 
+Beispiele: 
+ 
+ 
+"Das ist ein TEXT-Denoter" 
+"Jetzt ein TEXT-Denoter ohne ein Zeichen: ein leerer Text" 
+"" 
+ 
+ 
+Zu beachten ist, daß das Leerzeichen ebenfalls ein Zeichen ist. Soll ein Anführungs­
+zeichen in einem TEXT erscheinen (also gerade das Zeichen, welches einen Denoter
+beendet), so muß es doppelt geschrieben werden. 
+ 
+Beispiele: 
+ 
+ 
+"Ein TEXT mit dem ""-Zeichen" 
+"Ein TEXT-Denoter nur mit dem ""-Zeichen:" 
+"""" 
+ 
+ 
+Manchmal sollen Zeichen in einem TEXT-Denoter enthalten sein, die auf dem
+Eingabegerät nicht zur Verfügung stehen. In diesem Fall kann der Code-Wert des
+Zeichens angegeben werden. 
+ 
+Beispiel: 
+ 
+ 
+"da"251"" 
+ 
+ 
+ist gleichbedeutend mit "daß". Der Code-Wert eines Zeichens ergibt sich aus der
+EUMEL-Code-Tabelle (siehe 5.2.4.1), in der jedem Zeichen eine ganze Zahl zuge­
+ordnet ist. 
+ 
+ 
+BOOL-Denoter: 
+Es gibt nur zwei BOOL-Denoter: 
+TRUE für "wahr" und FALSE für "falsch". 
+ 
+ 
+ 
+2.3.1.2  LET-Konstrukt für Denoter 
+ 
+Neben der Funktion der Abkürzung von Datentypen (siehe 2.6.3) kann das LET-
+Konstrukt auch für die Namensgebung für Denoter verwandt werden. 
+ 
+Die LET-Vereinbarung sieht folgendermaßen aus: 
+ 
+ 
+#on("i")##on("b")#LET#off("i")##off("b")# Name #on("i")##on("b")#=#off("i")##off("b")# Denoter 
+ 
+ 
+Mehrere Namensgebungen können durch Komma getrennt werden. 
+ 
+ 
+____________________________________________________________________________ 
+ .......................... Beispiele: ......................... 
+ LET anzahl = 27; 
+ LET pi     = 3.14159, 
+     blank  = " "; 
+____________________________________________________________________________ 
+ 
+ 
+Der Einsatz von LET-Namen für Denoter hat zwei Vorteile: 
+ 
+-  feste Werte im Programm sind leicht zu ändern, da nur an einer Stelle des Pro­
+   gramms der Denoter geändert werden muß 
+   (z.B.: In Vereinbarungen von Reihungen (siehe 2.6.1) können LET-Denoter, im
+          Gegensatz zu Konstanten, als Obergrenze angegeben werden. Dieser
+          Wert kann dann auch an anderen Stellen des Programms, z.B. in Schlei­
+          fen (siehe 2.4.2.5), benutzt werden. Bei Änderung der Reihungsgröße
+          braucht dann nur an einer Stelle des Programms der Wert geändert zu
+          werden.) 
+-  der Name gibt zusätzliche Information über die Bedeutung des Denoters. 
+ 
+ 
+ 
+2.3.2   Zugriffsrecht 
+ 
+Von manchen Datenobjekten weiß man, daß sie nur einmal einen Wert erhalten
+sollen. Sie sollen also nicht verändert werden. Oder man weiß, daß in einem Pro­
+grammbereich ein Datenobjekt nicht verändert werden soll. Um ein unbeabsichtigtes
+Verändern zu verhindern, wird in ELAN dem Datenobjekt ein zusätzlicher Schutz
+mitgegeben: das Zugriffsrecht oder Accessrecht. 
+ 
+In der Deklaration eines Datenobjekts können folgende Accessattribute angegeben
+werden: 
+ 
+-  #on("i")##on("b")#VAR  #off("i")##off("b")#  für lesenden und schreibenden (verändernden) Zugriff 
+ 
+-  #on("i")##on("b")#CONST#off("i")##off("b")#  für nur lesenden Zugriff. 
+ 
+ 
+ 
+2.3.3  Deklaration 
+ 
+Damit man Datenobjekte in einem Programm ansprechen kann, gibt man einem
+Datenobjekt einen Namen (wie z.B. einen Personennamen, unter der sich eine wirk­
+liche Person "verbirgt"). Will man ein Datenobjekt in einem Programm verwenden, so
+muß man dem Compiler mitteilen, welchen Datentyp und welches Accessrecht das
+Objekt haben soll. Das dient u.a. dazu, nicht vereinbarte Namen (z.B. verschriebene)
+vom Compiler entdecken zu lassen. Weiterhin ist aus dem bei der Deklaration ange­
+gebenen Datentyp zu entnehmen, wieviel Speicherplatz für das Objekt zur Laufzeit zu
+reservieren ist. 
+ 
+Eine Deklaration oder Vereinbarung besteht aus der Angabe von 
+ 
+-  Datentyp 
+-  Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")#) 
+-  Name des Datenobjekts. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT VAR mein datenobjekt; 
+ 
+____________________________________________________________________________  
+ 
+ 
+Verschiedene Datenobjekte mit gleichem Datentyp und Accessrecht dürfen in einer
+Deklaration angegeben werden; sie werden durch Kommata getrennt. Mehrere Dekla­
+rationen werden - genauso wie Anweisungen - durch das Trennzeichen Semikolon
+voneinander getrennt. 
+ 
+____________________________________________________________________________ 
+ .......................... Beispiele: ......................... 
+ INT VAR mein wert, dein wert, unser wert; 
+ BOOL VAR listen ende; 
+ TEXT VAR zeile, wort; 
+ 
+____________________________________________________________________________ 
+ 
+ 
+2.3.4  Initialisierung 
+ 
+Um mit den vereinbarten Datenobjekten arbeiten zu können, muß man ihnen einen
+Wert geben. Hat ein Datenobjekt noch keinen Wert erhalten, so sagt man, sein Wert
+sei undefiniert. Das versehentliche Arbeiten mit undefinierten Werten ist eine beliebte
+Fehlerquelle. Deshalb wird von Programmierern streng darauf geachtet, diese Fehler­
+kuelle zu vermeiden. Eine Wertgebung an ein Datenobjekt kann (muß aber nicht)
+bereits bei der Deklaration erfolgen. In ELAN wird dies Initialisierung genannt. Für mit
+CONST vereinbarte Datenobjekte ist die Initialisierung die einzige Möglichkeit, ihnen
+einen Wert zu geben. Die Initialisierung von Konstanten ist zwingend vorgeschrieben
+und wird vom Compiler überprüft. 
+ 
+Die Initialisierung besteht aus der Angabe von 
+ 
+-  Datentyp 
+-  Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")#) 
+-  Name des Datenobjekts 
+-  Operator #on("i")##on("b")#::#off("i")##off("b")# oder #on("i")##on("b")#:=#off("i")##off("b")# 
+-  Wert, den das Datenobjekt erhalten soll (Denoter, Ausdruck). 
+ 
+____________________________________________________________________________ 
+ .......................... Beispiele: ......................... 
+ INT CONST gewuenschtes gehalt :: 12 000; 
+ TEXT VAR zeile :: ""; 
+ REAL CONST pi :: 3.14159, zwei pi := 2.0 * pi; 
+ BOOL VAR bereits sortiert :: TRUE; 
+____________________________________________________________________________ 
+#page# 
+ 
+2.4  Programmeinheiten 
+ 
+Neben Deklarationen (Vereinbarungen) sind Programmeinheiten die Grundbestandteile
+von ELAN. 
+ 
+ 
+Programmeinheiten können sein: 
+ 
+#on("b")#-  elementare Programmeinheiten #off("b")# 
+   -  Ausdruck 
+   -  Zuweisung 
+   -  Refinementanwendung 
+   -  Prozeduraufruf 
+ 
+#on("b")#-  zusammengesetzte Programmeinheiten #off("b")# 
+   -  Folge 
+   -  Abfrage 
+   -  Auswahl 
+   -  Wiederholung 
+ 
+#on("b")#-  abstrahierende Programmeinheiten #off("b")# 
+   -  Refinementbvereinbarung 
+   -  Prozedurvereinbarung 
+   -  Operatorvereinbarung 
+   -  Paketvereinbarung. 
+#page# 
+ 
+2.4.1  Elementare Programmeinheiten 
+ 
+ 
+2.4.1.1  Ausdruck 
+ 
+Ausdrücke sind eine Zusammenstellung von Datenobjekten (Denoter, VAR- oder
+CONST-Objekte) und Operatoren. Jeder korrekte Ausdruck liefert einen Wert. Der
+Typ des Ausdrucks wird bestimmt durch den Typ des Wertes, den der Ausdruck
+liefert. 
+ 
+ 
+Operatoren 
+ 
+Operatoren werden in ELAN durch ein oder zwei Sonderzeichen oder durch Groß­
+buchstaben als Schlüsselwort dargestellt (siehe 2.4.3.3). 
+ 
+Als Operanden (also die Datenobjekte, auf die ein Operator "wirken" soll) dürfen
+VAR- und CONST-Datenobjekte, Denoter oder Ausdrücke verwendet werden. Typ
+der Operanden und des Resultats eines Operators werden in der Operatorvereinba­
+rung festgelegt (siehe 2.4.3.3). 
+ 
+Man unterscheidet zwei Arten von Operatoren: 
+ 
+#on("b")#-  monadische Operatoren #off("b")# 
+   Monadischen Operatoren haben nur einen Operanden, der rechts vom Operator­
+   zeichen geschrieben werden muß. 
+ 
+   Beispiel: 
+ 
+ 
+   - a 
+   NOT x 
+ 
+ 
+   Der '-' - Operator liefert den Wert von a mit umgekehrten Vorzeichen. a muß
+   dabei vom Datentyp INT oder REAL sein. 
+   Der Operator 'NOT' realisiert die logische Negation. y muß vom Datentyp BOOL
+   sein. 
+ 
+ 
+#on("b")#-  dyadische Operatoren #off("b")# 
+   Dyadische Operatoren haben zwei Operanden. Das Operatorzeichen steht zwi­
+   schen den beiden Operanden. 
+ 
+   Beispiele: 
+ 
+ 
+   a + b 
+   a - b 
+   a * b 
+   a DIV b 
+   a ** b 
+   x < y 
+   x <> y 
+   x AND y 
+   x OR y 
+ 
+ 
+   In den ersten fünf Beispielen werden jeweils die Werte von zwei INT-Objekten a
+   und b addiert (Operatorzeichen: '+'), subtrahiert ('-'), multipliziert ('*'), dividiert
+   (ganzzahlige Division ohne Rest: 'DIV') und potenziert ('**'). 
+   Im sechsten und siebten Beispiel werden zwei BOOL-Werte x und y verglichen
+   und im achten und neunten Beispiel die logische Operation 'und' (Operator 'AND')
+   bzw. 'oder' (Operator 'OR') durchgeführt. 
+ 
+ 
+Priorität von Operatoren 
+ 
+Es ist erlaubt, einen Ausdruck wiederum als Operanden zu verwenden. Praktisch
+bedeutet dies, daß mehrere Operatoren und Datenobjekte zusammen in einem Aus­
+druck geschrieben werden dürfen. 
+ 
+Beispiele: 
+ 
+ 
+a + 3 - b * c 
+- a * b 
+ 
+ 
+Die Reihenfolge der Auswertung kann man durch Angabe von Klammern steuern. 
+ 
+Beispiel: 
+ 
+ 
+(a + b) * (a + b) 
+ 
+ 
+Es wird jeweils erst 'a + b' ausgewertet und dann erst die Multiplikation durchge­
+führt. In ELAN ist es erlaubt, beliebig viel Klammernpaare zu verwenden (Regel: die
+innerste Klammer wird zuerst ausgeführt). Es ist sogar zulässig, Klammern zu ver­
+wenden, wo keine notwendig sind, denn überflüssige Klammernpaare werden überle­
+sen. Man muß jedoch beachten, daß Ausdrücke, und damit auch z.B. #on("b")#(a)#off("b")#, immer
+Accessrecht CONST haben. 
+ 
+Beispiel: 
+ 
+ 
+((a - b)) * 3 * ((c + d) * (c - d)) 
+ 
+ 
+Somit können beliebig komplizierte Ausdrücke formuliert werden. 
+ 
+Um solche Ausdrücke einfacher zu behandeln und sie so ähnlich schreiben zu kön­
+nen, wie man es in der Mathematik gewohnt ist, wird in Programmiersprachen die
+Reihenfolge der Auswertung von Operatoren festgelegt. In ELAN wurden neun Ebe­
+nen, Prioritäten genannt, festgelegt: 
+ 
+ 
+#on("bold")#Priorität               Operatoren 
+#off("bold")# 
+ 
+   9                     alle monadischen Operatoren 
+   8                     ** 
+   7                     *, /, DIV, MOD 
+   6                     +, - 
+   5                     =, <>, <, <=, >, >= 
+   4                     AND 
+   3                     OR 
+   2                     alle übrigen, nicht in dieser Tabelle aufgeführten 
+                         dyadischen Operatoren 
+   1                     := 
+ 
+(Die erwähnten Operatoren in der Tabelle werden in der Beschreibung der Standard­
+prozeduren und -Operatoren besprochen). 
+ 
+Operatoren mit der höchsten Priorität werden zuerst ausgeführt, dann die mit der
+nächst niedrigeren Priorität usw.. Operatoren mit gleicher Priorität werden von links
+nach rechts ausgeführt. Dadurch ergibt sich die gewohnte Abarbeitungsfolge wie beim
+Rechnen. 
+ 
+Beispiel: 
+ 
+ 
+-2 + 3 * 2 ** 3 
+ 
+a) -2 
+b) 2 ** 3 
+c) 3 * (2 ** 3) 
+d) ((-2)) + (3 * (2 ** 3)) 
+ 
+ 
+Wie bereits erwähnt, ist es immer erlaubt, Klammern zu setzen. Ist man sich also
+über die genaue Abarbeitungsfolge nicht im Klaren, so kann man Klammern verwen­
+den. 
+ 
+ 
+ 
+2.4.1.2  Zuweisung 
+ 
+Ein spezieller Operator ist die Zuweisung. 
+ 
+Form: 
+ 
+ 
+Variable #on("i")##on("b")#:=#off("i")##off("b")# Wert 
+ 
+ 
+Dieser Operator hat immer die geringste Priorität, wird also immer als letzter einer
+Anweisung ausgeführt. Die Zuweisung wird verwendet, um einer Variablen einen
+neuen Wert zu geben. Der Operator ':=' liefert kein Resultat (man sagt auch, er
+liefert keinen Wert) und verlangt als linken Operanden ein VAR-Datenobjekt, an den
+der Wert des rechten Operanden zugewiesen werden soll). Der Wert des linken Oper­
+anden wird also verändert. Der rechte Operand wird nur gelesen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ a := b; 
+ 
+____________________________________________________________________________  
+ 
+ 
+Hier wird der Wert von 'b' der Variablen 'a' zugewiesen. Der vorher vorhandene Wert
+von 'a' geht dabei verloren. Man sagt auch, der Wert wird überschrieben. 
+ 
+Als rechter Operand des ':='-Operators darf auch ein Ausdruck stehen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ a := b + c; 
+ 
+____________________________________________________________________________  
+ 
+ 
+Hier wird das Resultat von 'b + c' an die Variable 'a' zugewiesen. Man beachte
+dabei die Prioritäten der Operatoren '+' (Priorität 6) und ':=' (Priorität 1): die Addition
+wird vor der Zuweisung ausgeführt. Die Auswertung von Zuweisungen mit Ausdrücken
+muß immer so verlaufen, da die Zuweisung stets die niedrigste Priorität aller Operato­
+ren hat. 
+ 
+Oft kommt es vor, daß ein Objekt auf der linken und rechten Seite des Zuweisungs­
+operators erscheint, z.B. wenn ein Wert erhöht werden soll. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ a := a + 1; 
+ 
+____________________________________________________________________________  
+ 
+ 
+Hier wird der "alte", aktuelle Wert von 'a' genommen, um '1' erhöht und dem Objekt
+'a' zugewiesen. Man beachte, daß hier in einer Anweisung ein Datenobjekt unter­
+schiedliche Werte zu unterschiedlichen Zeitpunkten haben kann. 
+ 
+ 
+ 
+2.4.1.3  Refinementanwendung 
+ 
+In ELAN ist es möglich, Namen für Ausdrücke oder eine bzw. mehrere Anweisungen
+zu vergeben. Das Sprachelement, das diese Namensgebung ermöglicht, heißt Refi­
+nement. Die Ausführung eines solchen Namens heißt Refinementanwendung, die
+Namensgebung heißt Refinementvereinbarung (siehe 2.4.3.1). Die Ausdrücke oder
+Anweisungen bilden den Refinementrumpf. Ein Refinement kann man in einem Pro­
+gramm unter dem Refinementnamen ansprechen. Man kann sich die Ausführung so
+vorstellen, als würden der Refinementrumpf immer dort eingesetzt, wo der Name des
+Refinements als Operation benutzt wird. 
+ 
+ 
+ 
+2.4.1.4  Prozeduraufruf 
+ 
+Eine Prozedur ist eine Sammlung von Anweisungen und Daten, die zur Lösung einer
+bestimmten Aufgabe benötigt werden. Eine Prozedur wird in einer Prozedurvereinba­
+rung definiert (siehe 2.4.3.2). Eine solche Prozedur kann man in einem Programm
+unter einem Namen (eventuell unter Angabe von Parametern) ansprechen. Man
+spricht dann vom Aufruf einer Prozedur oder einer Prozeduranweisung. 
+ 
+Formen des Prozeduraufrufs: 
+ 
+-  #on("b")#Prozeduren ohne Parameter#off("b")# werden durch den Prozedurnamen angesprochen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ pause; 
+ 
+____________________________________________________________________________  
+ 
+ 
+   (Die Prozedur 'pause' wartet bis ein Zeichen eingegeben wird) 
+ 
+ 
+-  #on("b")#Prozeduren mit Parameter#off("b")# werden durch 
+ 
+ 
+   Prozedurnamen #on("i")##on("b")#(#off("i")##off("b")# aktuelle Parameterliste #on("i")##on("b")#)#off("i")##off("b")# 
+ 
+ 
+   aufgerufen. Eine Parameterliste ist entweder ein Datenobjekt oder mehrere durch
+   Kommata getrennte Datenobjekte. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ pause (10); 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   (Mit der Prozedur 'pause (INT CONST zeitgrenze)' kann für eine Zeitdauer von
+   'zeitgrenze' in Zehntel-Sekunden gewartet werden. Die Wartezeit wird durch
+   Erreichen der Zeitgrenze oder durch Eingabe eines Zeichens abgebrochen) 
+ 
+ 
+   Bei den aktuellen Parametern ist folgendes zu beachten: 
+ 
+   a) Wird ein VAR-Parameter in der Definition der Prozedur vorgeschrieben, darf
+      kein Ausdruck als aktueller Parameter "übergeben" werden, weil an einen
+      Ausdruck nichts zugewiesen werden kann. Ausdrücke haben - wie bereits
+      erwähnt - das Accessrecht CONST. 
+ 
+____________________________________________________________________________ 
+ ........................ Gegenbeispiel: ....................... 
+ TEXT VAR text1, text2; 
+ text1 := "Dieses Beispiel "; 
+ text2 := "Fehlermeldung"; 
+ insert char (text1 + text2, "liefert eine", 17); 
+ 
+____________________________________________________________________________ 
+ 
+ 
+      (Die Prozedur 'insert char (TEXT VAR string, TEXT CONST char, INT CONST
+      pos)' fügt das Zeichen 'char' in den Text 'string' an der Position 'pos' ein) 
+ 
+   b) Wird ein CONST-Parameter verlangt, dann darf in diesem Fall ein Ausdruck
+      als aktueller Parameter geschrieben werden. Aber auch ein VAR-Datenobjekt
+      darf angegeben werden. In diesem Fall wird eine Wandlung des Accessrechts
+      (CONSTing) vorgenommen: der aktuelle Parameter erhält sozusagen für die
+      Zeit der Abarbeitung der Prozedur das Accessrecht CONST. 
+ 
+ 
+   In ELAN sind auch Prozeduren als Parameter erlaubt. Die Prozedur als aktueller
+   Parameter wird in der Parameterliste folgendermaßen angegeben: 
+ 
+ 
+   Resultattyp #on("i")##on("b")#PROC#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# virtuelle Parameterliste #on("i")##on("b")#)#off("i")##off("b")# Procname 
+ 
+ 
+   Die Angabe des Resultattyps entfällt, wenn es sich nicht um eine wertliefernde
+   Prozedur handelt. Die virtuelle Parameterliste inklusive der Klammern entfällt, falls
+   die Prozedur keine Parameter hat. Die virtuelle Parameterliste beschreibt die
+   Parameter der Parameterprozedur. Es werden Datentyp und Zugriffsrecht eines
+   jeden Parameters angegeben, jedoch ohne Namen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ wertetabelle (REAL PROC (REAL CONST) sin, 
+               untergrenze, obergrenze, schrittweite); 
+  
+ 
+   (Die Prozedur 'sin' wird an die Prozedur 'wertetabelle' übergeben) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+2.4.2 Zusammengesetzte Programmeinheiten 
+ 
+ 
+2.4.2.1  Folge 
+ 
+Mehrere in einer bestimmten Reihenfolge auszuführende Anweisungen werden als
+Folge bezeichnet. In ELAN kann man eine oder mehrere Anweisungen in eine Pro­
+grammzeile schreiben oder eine Anweisung über mehrere Zeilen. Das setzt jedoch
+voraus, daß die Anweisungen voneinander getrennt werden. Die Trennung von Anwei­
+sungen erfolgt in ELAN durch das Trennsymbol Semikolon. Es bedeutet soviel wie:
+"führe die nächste Anweisung aus". 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ put ("mein"); 
+ put (1); 
+ put (". Programm") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+(Die Prozedur 'put' gibt den als Parameter angegebenen Wert auf dem Ausgabegerät
+aus) 
+ 
+ 
+ 
+2.4.2.2  Abfrage 
+ 
+Mit Abfragen steuert man die bedingte Ausführung von Anweisungen. Abhängig von
+einer Bedingung wird in zwei verschiedene Programmabschnitte verzweigt. 
+ 
+Der formale Aufbau einer Abfrage sieht folgendermaßen aus: 
+ 
+ 
+#on("i")##on("b")#IF#off("i")##off("b")# Bedingung 
+   #on("i")##on("b")#THEN#off("i")##off("b")# Abschnitt 
+   #on("i")##on("b")#ELSE#off("i")##off("b")# Abschnitt 
+#on("i")##on("b")#END IF#off("i")##off("b")# 
+ 
+ 
+Der ELSE-Teil darf dabei auch fehlen. Anstelle von #on("i")##on("b")#END IF#off("i")##off("b")# darf auch die Abkürzung #on("i")##on("b")#FI#off("i")##off("b")# (IF von hinten gelesen) benutzt werden.
+ 
+In folgenden Beispielen wird der Absolutbetrag von 'a' ausgegeben: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT VAR a; 
+ get (a); 
+ IF a < 0 
+    THEN a := -a 
+ END IF; 
+ put (a) 
+  
+____________________________________________________________________________ 
+ 
+ 
+Die Umkehrung des Vorzeichens von a im THEN-Teil wird nur durchgeführt, wenn
+der BOOLesche Ausdruck ('a < 0') den Wert TRUE liefert. Liefert er den Wert
+FALSE, wird die Anweisung, die der bedingten Anweisung folgt (nach END IF), ausge­
+führt. Das obige Programm kann auch anders geschrieben werden: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT VAR a; 
+ get (a); 
+ IF a < 0 
+    THEN put (-a) 
+    ELSE put (a) 
+ END IF 
+  
+____________________________________________________________________________ 
+ 
+ 
+Der THEN-Teil wird wiederum ausgeführt, wenn die BOOLesche Bedingung erfüllt
+ist. Liefert sie dagegen FALSE, wird der ELSE-Teil ausgeführt. 
+ 
+Die bedingte Anweisung ermöglicht es, abhängig von einer Bedingung eine oder
+mehrere Anweisungen ausführen zu lassen. Dabei können im THEN- bzw. ELSE-
+Teil wiederum bedingte Anweisungen enthalten sein. 
+ 
+ 
+Abfragekette 
+Bei Abfrageketten kann das ELIF-Konstrukt eingesetzt werden. (ELIF ist eine Zu­
+sammenziehung der Worte ELSE und IF). 
+ 
+Anstatt 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ IF bedingung1 
+    THEN aktion1 
+    ELSE IF bedingung2 
+            THEN aktion2 
+            ELSE aktion3 
+         END IF 
+    END IF; 
+ 
+____________________________________________________________________________ 
+ 
+ 
+kann man besser 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ IF bedingung1 
+    THEN aktion1 
+ ELIF bedingung2 
+    THEN aktion2 
+    ELSE aktion3 
+ END IF; 
+  
+____________________________________________________________________________ 
+ 
+ 
+schreiben. 
+ 
+ 
+ 
+2.4.2.3  Auswahl 
+ 
+Die Auswahl wird benutzt, wenn alternative Anwendungen in Abhängikeit von Werten
+eines Datenobjekts ausgeführt werden sollen. 
+ 
+Der formale Aufbau der Auswahl sieht folgendermaßen aus: 
+ 
+ 
+#on("i")##on("b")#SELECT#off("i")##off("b")# INT-Ausdruck #on("i")##on("b")#OF#off("i")##off("b")# 
+   #on("i")##on("b")#CASE#off("i")##off("b")# 1. Liste von INT-Denotern #on("i")##on("b")#:#off("i")##off("b")# Abschnitt 
+   #on("i")##on("b")#CASE#off("i")##off("b")# 2. Liste von INT-Denotern #on("i")##on("b")#:#off("i")##off("b")# Abschnitt 
+                   . 
+                   . 
+                   . 
+   #on("i")##on("b")#CASE#off("i")##off("b")# n. Liste von INT-Denotern #on("i")##on("b")#:#off("i")##off("b")# Abschnitt 
+   #on("i")##on("b")#OTHERWISE#off("i")##off("b")# Abschnitt 
+#on("i")##on("b")#END SELECT#off("i")##off("b")# 
+ 
+ 
+Eine Liste von INT-Denotern besteht aus einem oder mehreren durch Kommata ge­
+trennten INT-Denotern. Der OTHERWISE-Teil darf auch fehlen. Man sollte ihn
+jedoch verwenden, um Fehlerfälle abzufangen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ SELECT monat OF 
+    CASE 2: IF schaltjahr 
+               THEN tage := 29 
+               ELSE tage := 28 
+            END IF 
+    CASE 4, 6, 9, 11: tage := 30 
+    CASE 1, 3, 5, 7, 8, 10 ,12: tage := 31 
+    OTHERWISE kein monat 
+ END SELECT; 
+  
+____________________________________________________________________________ 
+ 
+ 
+(In diesem Programmausschnitt werden die Tage eines Monats bestimmt) 
+ 
+ 
+ 
+2.4.2.4  Wertliefernde Abfrage und 
+         wertliefernde Auswahl
+          
+ 
+Soll eine Abfrage oder eine Auswahl einen Wert liefern, dann darf der ELSE- bzw.
+der OTHERWISE-Teil nicht fehlen und alle Zweige müssen einen Wert liefern. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ SELECT monat OF 
+    CASE 2: IF schaltjahr 
+               THEN 29 
+               ELSE 28 
+            END IF 
+    CASE 4, 6, 9, 11: 30 
+    CASE 1, 3, 5, 7, 8, 10 ,12: 31 
+    OTHERWISE kein monat; 0 
+ END SELECT; 
+  
+____________________________________________________________________________ 
+ 
+ 
+2.4.2.5  Wiederholung 
+ 
+Die Wiederholung dient zur mehrfachen Ausführung von Anweisungen, meist in Ab­
+hängigkeit von einer Bedingung. Darum wird die Wiederholungsanweisung oft auch
+Schleife genannt und die in ihr enthaltenen Anweisungen Schleifenrumpf. 
+ 
+Es gibt verschiedene Schleifentypen: 
+ 
+-  Endlosschleife 
+-  abweisende Schleife 
+-  nicht abweisende Schleife 
+-  Zählschleife. 
+ 
+ 
+Endlosschleife 
+Bei der Endlosschleife wird nicht spezifiziert, wann die Schleife beendet werden soll. 
+ 
+Form: 
+ 
+ 
+#on("i")##on("b")#REPEAT#off("i")##off("b")# 
+   Abschnitt 
+#on("i")##on("b")#END REPEAT#off("i")##off("b")# 
+ 
+ 
+Anstelle von #on("i")##on("b")#REPEAT#off("i")##off("b")# darf die Abkürzung #on("i")##on("b")#REP#off("i")##off("b")# und anstelle von #on("i")##on("b")#END REPEAT#off("i")##off("b")# 
+das Schlüsselwort #on("i")##on("b")#PER#off("i")##off("b")# (REP von hinten gelesen)
+benutzt werden. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ break; 
+ REPEAT 
+    fixpoint; 
+    pause (18000) 
+ END REPEAT 
+  
+____________________________________________________________________________ 
+ 
+ 
+Wird dieses Programm in einer Task im SYSUR-Zweig ausgeführt, so führt diese
+Task Fixpunkte im Abstand von 30 Minuten durch. 
+ 
+ 
+ 
+Abweisende Schleife 
+Bei der abweisenden Schleife wird die Abbruchbedingung an den Anfang der Schleife
+geschrieben. 
+ 
+Form: 
+ 
+ 
+#on("i")##on("b")#WHILE#off("i")##off("b")# Bedingung #on("i")##on("b")#REPEAT#off("i")##off("b")# 
+   Abschnitt 
+#on("i")##on("b")#END REPEAT#off("i")##off("b")# 
+ 
+ 
+Bei jedem erneuten Durchlauf der Schleife wird überprüft, ob der BOOLesche Aus­
+druck den Wert TRUE liefert. Ist das nicht der Fall, wird die Bearbeitung mit der
+Anweisung fortgesetzt, die auf das Schleifenende folgt. Die Schleife wird abweisende
+Schleife genannt, weil der Schleifenrumpf nicht ausgeführt wird, wenn die Bedingung
+vor Eintritt in die Schleife bereits FALSE liefert. 
+ 
+ 
+Nicht abweisende Schleife 
+Anders verhält es sich bei der nicht abweisenden Schleife. Bei der nicht abweisenden
+Schleife wird die Abbruchbedingung an das Ende der Schleife geschrieben. 
+ 
+Form: 
+ 
+ 
+#on("i")##on("b")#REPEAT#off("i")##off("b")# 
+   Abschnitt 
+#on("i")##on("b")#UNTIL#off("i")##off("b")# Bedingung #on("i")##on("b")#END REPEAT#off("i")##off("b")# 
+ 
+ 
+Hier wird der Schleifenrumpf auf jeden Fall einmal bearbeitet. Am Ende des Rumpfes
+wird die BOOLesche Bedingung abgefragt. Liefert sie den Wert FALSE, wird die
+Schleife erneut abgearbeitet. Liefert die Bedingung den Wert TRUE, wird die Schleife
+abgebrochen und mit der ersten Anweisung hinter der Schleife in der Bearbeitung
+fortgefahren. 
+ 
+Bei den beiden letztgenannten Arten der Wiederholungsanweisung ist es wichtig, daß
+Elemente der BOOLeschen Bedingung in der Schleife verändert werden, damit das
+Programm terminieren kann, d.h. die Schleife abgebrochen wird. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ TEXT VAR wort, satz :: ""; 
+ REPEAT 
+   get (wort); 
+   satz CAT wort; 
+   satz CAT " " 
+ UNTIL wort = "." PER; 
+  
+____________________________________________________________________________ 
+ 
+ 
+Dises Programm liest solange Wörter ein und verbindet diese zu einem Satz, bis ein
+Punkt eingegeben wurde. 
+ 
+ 
+ 
+Zählschleife 
+Zählschleifen werden eingesetzt, wenn die genaue Anzahl der Schleifendurchläufe
+bekannt ist. 
+ 
+Form: 
+ 
+ 
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Anfangswert #on("i")##on("b")#UPTO#off("i")##off("b")# Endwert #on("i")##on("b")#REPEAT#off("i")##off("b")# 
+   Abschnitt 
+#on("i")##on("b")#END REPEAT#off("i")##off("b")# 
+ 
+ 
+Bei Zählschleifen wird eine Laufvariable verwendet, die die INT-Werte von 'Anfangs­
+wert' bis 'Endwert' in Schritten von 1 durchläuft. 'Anfangswert' und 'Endwert' können
+beliebige INT-Ausdrücke sein. Diese Schleife zählt "aufwärts". Wird anstatt #on("i")##on("b")#UPTO#off("i")##off("b")#
+das Schlüsselwort #on("i")##on("b")#DOWNTO#off("i")##off("b")# verwendet, wird mit Schritten von 1 "abwärts" gezählt. 
+ 
+Form: 
+ 
+ 
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Endwert #on("i")##on("b")#DOWNTO#off("i")##off("b")# Anfangswert #on("i")##on("b")#REPEAT#off("i")##off("b")# 
+   Abschnitt 
+#on("i")##on("b")#END REPEAT#off("i")##off("b")# 
+ 
+ 
+Die Laufvariable darf in der Schleife nicht verändert werden. Nach dem normalen
+Schleifenende ist der Wert der Laufvariablen nicht definiert. 
+ 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT VAR summe :: 0, i; 
+ FOR i FROM 1 UPTO 100 REPEAT 
+    summe INCR i 
+ END REPEAT 
+  
+____________________________________________________________________________ 
+ 
+ 
+Dieses Programm berechnet die Summe der natürlichen Zahlen von 1 bis 100. 
+ 
+ 
+Die verschiedenen Schleifenarten können kombiniert werden: 
+ 
+ 
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Anfangswert #on("i")##on("b")#UPTO#off("i")##off("b")# Endwert 
+#on("i")##on("b")#WHILE#off("i")##off("b")# Bedingung #on("i")##on("b")#REPEAT#off("i")##off("b")# 
+   Abschnitt 
+#on("i")##on("b")#END REPEAT#off("i")##off("b")# 
+ 
+ 
+ 
+#on("i")##on("b")#FOR#off("i")##off("b")# Laufvariable #on("i")##on("b")#FROM#off("i")##off("b")# Anfangswert #on("i")##on("b")#UPTO#off("i")##off("b")# Endwert #on("i")##on("b")#REPEAT#off("i")##off("b")# 
+   Abschnitt 
+#on("i")##on("b")#UNTIL#off("i")##off("b")# Bedingung #on("i")##on("b")#END REPEAT#off("i")##off("b")# 
+ 
+ 
+ 
+ 
+ 
+#on("i")##on("b")#WHILE#off("i")##off("b")# Bedingung #on("i")##on("b")#REPEAT#off("i")##off("b")# 
+   Abschnitt 
+#on("i")##on("b")#UNTIL#off("i")##off("b")# Bedingung #on("i")##on("b")#END REPEAT#off("i")##off("b")# 
+ 
+#page# 
+ 
+2.4.3  Abstrahierende Programmeinheiten 
+ 
+ 
+2.4.3.1  Refinementvereinbarung 
+ 
+In ELAN ist es möglich, Namen für Ausdrücke oder eine bzw. mehrere Anweisungen
+zu vergeben. Das Sprachelement, das diese Namensgebung ermöglicht, heißt Refi­
+nement. Die Ausführung eines solchen Namens heißt Refinementanwendung (siehe
+2.4.1.3), die Namensgebung heißt Refinementvereinbarung. Die Ausdrücke oder
+Anweisungen bilden den Refinementrumpf. 
+ 
+Werden in einem Programm Refinements benutzt, dann wird der Programmteil bis
+zum ersten Refinement durch einen Punkt abgeschlossen. Die Refinementvereinba­
+rung sieht folgendermaßen aus: 
+ 
+ 
+Name #on("i")##on("b")#:#off("i")##off("b")# 
+   Abschnitt #on("i")##on("b")#.#off("i")##off("b")# 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT VAR a, b, x; 
+ einlesen von a und b; 
+ vertauschen von a und b; 
+ vertauschte werte ausgeben. 
+ 
+ einlesen von a und b: 
+    get (a); 
+    get (b). 
+ 
+ vertauschen von a und b: 
+    x := a; 
+    a := b; 
+    b := x. 
+ 
+ vertauschte werte ausgeben: 
+    put (a); 
+    put (b). 
+  
+____________________________________________________________________________ 
+ 
+ 
+Für den Namen 'einlesen von a und b' werden die Anweisungen 'get (a); get (b)' vom
+ELAN-Compiler eingesetzt. Man kann also die ersten vier Zeilen des Programms als
+eigentliches Programm ansehen, wobei die Namen durch die betreffenden Anwei­
+sungen ersetzt werden. Ein Refinement hat also keinen eigenen Datenbereich, d.h.
+Vereinbarungen, die in Refinements gemacht werden, gelten auch außerhalb des
+Refinements. 
+ 
+ 
+ 
+Vorteile der Refinementanwendung 
+Durch die sinnvolle Verwendung von Refinements wird ein Programm im Programm
+und nicht in einer separaten Beschreibung dokumentiert. Weiterhin kann ein Pro­
+gramm "von oben nach unten" ("top down") entwickelt werden: Das obige - zuge­
+geben einfache - Beispielprogramm wurde in drei Teile zerlegt und diese durch
+Namen beschrieben. Bei der Beschreibung von Aktionen durch Namen wird gesagt
+was gemacht werden soll. Es wird noch nicht beschrieben wie, denn auf dieser Stufe
+der Programmentwicklung braucht man sich um die Realisierung der Refinements
+(noch) keine Sorgen zu machen. Das erfolgt erst, wenn das Refinement programmiert
+werden muß. Dabei können wiederum Refinements verwendet werden usw., bis man
+auf eine Ebene "heruntergestiegen" ist, bei der eine (jetzt: Teil-) Problemlösung sehr
+einfach ist und man sie direkt hinschreiben kann. Man beschäftigt sich also an jedem
+Punkt der Problemlösung nur mit einem Teilaspekt des gesamten Problems. Zudem
+sieht man - wenn die Refinements einigermaßen vernünftig verwendet werden -
+dem Programm an, wie die Problemlösung entstanden ist. 
+ 
+Die Verwendung von Refinements hat also eine Anzahl von Vorteilen. 
+Refinements ermöglichen: 
+ 
+-  "top down" - Programmierung 
+-  Strukturierung von Programmen und damit effiziente Fehlersuche und gute Wart­
+   barkeit 
+-  Dokumentation im Programmtext. 
+ 
+ 
+Wertliefernde Refinements 
+Refinements können auch dort verwendet werden, wo ein Wert erwartet wird, z.B. in
+einem Ausdruck oder einer 'put'-Anweisung. In diesem Fall muß die letzte Anwei­
+sung des Refinements einen Wert liefert. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT VAR a :: 1, b :: 2, c :: 3; 
+ put (resultat). 
+ 
+ resultat: 
+    (a * b + c) ** 3. 
+  
+____________________________________________________________________________ 
+ 
+ 
+Man kann auch ein wertlieferndes Refinement mit mehreren Anweisungen schrei­
+ben. 
+ 
+Allgemeine Regel: 
+Die letzte Anweisung eines Refinements bestimmt, ob es einen Wert liefert - und
+wenn ja, von welchen Datentyp. 
+ 
+ 
+ 
+2.4.3.2  Prozedurvereinbarung 
+ 
+Eine Prozedur ist eine Sammlung von Anweisungen und Daten, die zur Lösung einer
+bestimmten Aufgabe benötigt werden. 
+ 
+Der formale Aufbau einer Prozedur sieht folgendermaßen aus: 
+ 
+ 
+#on("i")##on("b")#PROC#off("i")##off("b")# Prozedurname #on("i")##on("b")#:#off("i")##off("b")# 
+   Prozedurrumpf 
+#on("i")##on("b")#END PROC#off("i")##off("b")# Prozedurname 
+ 
+ 
+Der Prozedurrumpf kann Deklarationen, Anweisungen und Refinements enthalten. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+     PROC loesche bildschirm ab aktueller cursorposition: 
+        out (""4"") 
+     END PROC loesche bildschirm ab aktueller cursorposition 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Verwendung von Prozeduren 
+Prozeduren werden verwendet, wenn 
+ 
+-  Anweisungen und Datenobjekte unter einem Namen zusammengefaßt werden
+   sollen ("Abstraktion") 
+-  gleiche Anweisungen von mehreren Stellen eines Programms verwandt werden
+   sollen (Codereduktion), u.U. mit verschieden Datenobjekten (Parameter) 
+-  Datenobjekte nur innerhalb eines Programmteils benötigt werden und diese nicht
+   von dem gesamten Programm angesprochen werden sollen. 
+ 
+In den folgenden Programmfragmenten werden zwei Werte vertauscht. In der ersten
+Lösung wird ein Refinement, in der zweiten eine Prozedur verwandt. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ IF a > b 
+   THEN vertausche a und b 
+ END IF; 
+ put (a); 
+ put (b); 
+ vertausche a und b. 
+ 
+ vertausche a und b: 
+    INT CONST x :: a; 
+    a := b; 
+    b := x. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PROC vertausche a und b: 
+    INT CONST x :: a; 
+    a := b; 
+    b := x 
+ END PROC vertausche a und b; 
+ 
+ IF a > b 
+   THEN vertausche a und b 
+ END IF; 
+ put (a); 
+ put (b); 
+ vertausche a und b; 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Beim ersten Hinsehen leisten beide Programme das Gleiche. Es gibt jedoch drei
+wichtige Unterschiede: 
+ 
+1) Das Refinement 'vertausche a und b' wird zweimal (vom ELAN-Compiler) ein­
+   gesetzt, d.h. der Code ist zweimal vorhanden. Die Prozedur dagegen ist vom Code
+   nur einmal vorhanden, wird aber zweimal - durch das Aufführen des Prozedur­
+   namens - aufgerufen. 
+ 
+2) Die Variable 'x' ist in der ersten Programmversion während des gesamten Ablauf
+   des Programms vorhanden, d.h. ihr Speicherplatz ist während dieser Zeit belegt.
+   Solche Datenobjekte nennt man statische Datenobjekte oder auch (aus Gründen,
+   die erst etwas später offensichtlich werden) Paket-Objekte. Das Datenobjekt 'x'
+   der rechten Version dagegen ist nur während der Bearbeitung der Prozedur vor­
+   handen, sein Speicherplatz wird danach freigegeben. Solche Datenobjekte, die nur
+   kurzfristig Speicher belegen, werden dynamische Datenobjekte genannt. 
+ 
+   Prozeduren sind also ein Mittel, um die Speicherbelegung zu beeinflussen. 
+ 
+3) Da Refinements keinen eigenen Datenbereich haben, kann die Variable 'x' in der
+   ersten Programmversion - obwohl sie in einem Refinement deklariert wurde -
+   von jeder Stelle des Programms angesprochen werden. Solche Datenobjekte
+   werden globale Datenobjekte genannt. Das Datenobjekt 'x' der Prozedur dagegen
+   kann nur innerhalb der Prozedur angesprochen werden, es ist also ein lokales
+   Datenobjekt der Prozedur. Innerhalb der Prozedur dürfen globale Datenobjekte
+   (also Objekte, die außerhalb von Prozeduren deklariert wurden) auch angespro­
+   chen werden. 
+ 
+   Eine Prozedur in ELAN bildet im Gegensatz zu Refinements einen eigenen Gültig­
+   keitsbereich hinsichtlich Datenobjekten und Refinements, die innerhalb der Pro­
+   zedur deklariert werden. Prozeduren sind somit ein Mittel, um die in ihr dekla­
+   rierten Datenobjekte hinsichtlich der Ansprechbarkeit nach Außen "abzuschotten". 
+ 
+ 
+ 
+Prozeduren mit Parametern 
+Prozeduren mit Parametern erlauben es, gleiche Anweisungen mit unterschiedlichen
+Datenobjekten auszuführen. 
+ 
+Form: 
+ 
+ 
+#on("i")##on("b")#PROC#off("i")##off("b")# Prozedurname #on("i")##on("b")#(#off("i")##off("b")# formale Parameterliste #on("i")##on("b")#)#off("i")##off("b")# #on("i")##on("b")#:#off("i")##off("b")# 
+   Prozedurrumpf 
+#on("i")##on("b")#END PROC#off("i")##off("b")# Prozedurnamen 
+ 
+ 
+Die Parameterliste besteht aus einem oder mehreren durch Kommata getrennten Para­
+metern. Ein Parameter wird mit Datentyp, Accessrecht und Namen angegeben. 
+Ähnlich wie bei der Datendeklaration braucht man für aufeinanderfolgende Parameter
+mit gleichem Datentyp und gleichem Accessrecht die Attribute nur einmal anzugeben.
+Parameter mit Accessrecht #on("i")##on("b")#CONST#off("i")##off("b")# sind Eingabeparameter, Parameter mit Access­
+recht #on("i")##on("b")#VAR#off("i")##off("b")# realisieren Ein-/Ausgabeparameter. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PROC vertausche (INT VAR a, b): 
+    INT VAR x :: a; 
+    a := b; 
+    b := x 
+ END PROC vertausche; 
+ 
+ INT VAR eins :: 1, 
+         zwei :: 2, 
+         drei :: 3; 
+ vertausche (eins, zwei); 
+ vertausche (zwei, drei); 
+ vertausche (eins, zwei); 
+ put (eins); put (zwei); put (drei) 
+  
+____________________________________________________________________________ 
+ 
+ 
+Die Datenobjekte 'a' und 'b' der Prozedur 'vertausche' werden formale Parameter
+genannt. Sie stehen als Platzhalter für die bei einem Prozeduraufruf einzusetzenden
+aktuellen Parameter (in obigen Beispiel die Datenobjekte 'eins', 'zwei' und 'drei'). 
+ 
+ 
+ 
+Prozeduren als Parameter 
+Es ist auch möglich, Prozeduren als Parameter zu definieren. 
+ 
+Eine Prozedur als Parameter wird folgendermaßen in der Parameterliste spezifiziert:  
+ 
+Resultattyp #on("i")##on("b")#PROC#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# virtuelle Parameterliste #on("i")##on("b")#)#off("i")##off("b")# Prozedurname 
+ 
+ 
+Die Angabe des Resultattyps entfällt, wenn es sich nicht um eine wertliefernde Proze­
+dur handelt. Die virtuelle Parameterliste inklusive der Klammern entfällt, falls die
+Prozedur keine Parameter hat. Die virtuelle Parameterliste beschreibt die Parame­
+ter der Parameterprozedur. Es werden Datentyp und Zugriffsrecht eines jeden Para­
+meters angegeben, jedoch ohne Namen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PROC wertetabelle (REAL PROC (REAL CONST) funktion, 
+                    REAL CONST untergrenze, obergrenze, 
+                         schrittweite): 
+ 
+ REAL VAR wert; 
+ putline ("W E R T E T A B E L L E"); 
+ putline ("-----------------------"); 
+ wert := untergrenze; 
+ REPEAT 
+    put (text (wert, 10, 5)); 
+    put (text (funktion (wert), 10, 5)); 
+    line; 
+    wert INCR schrittweite 
+ UNTIL wert > obergrenze PER 
+ 
+ END PROC wertetabelle; 
+ 
+ (* Prozeduraufruf: *) 
+ wertetabelle (REAL PROC (REAL CONST) sin, 0.0, pi, 0.2) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Wertliefernde Prozeduren 
+Eine wertliefernde Prozedur sieht folgendermaßen aus: 
+ 
+ 
+Resultattyp #on("i")##on("b")#PROC#off("i")##off("b")# Prozedurname #on("i")##on("b")#(#off("i")##off("b")# formale Parameterliste #on("i")##on("b")#)#off("i")##off("b")# #on("i")##on("b")#:#off("i")##off("b")# 
+   wertliefernder Prozedurrumpf 
+#on("i")##on("b")#END PROC#off("i")##off("b")# Prozedurnamen 
+ 
+ 
+ 
+Die Parameterliste inklusive Klammerung kann fehlen. Der Prozedurrumpf muß einen
+Wert mit dem in Resultattyp angegeben Datentyp liefern. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT PROC max (INT CONST a, b): 
+    IF a > b 
+      THEN a 
+      ELSE b 
+    END IF 
+ END PROC max; 
+ 
+ put (max (3, 4)) 
+  
+____________________________________________________________________________ 
+ 
+ 
+(In diesem Beispiel wird das Maximum von 'a' und 'b' ermittelt und ausgegeben) 
+ 
+#page# 
+ 
+2.4.3.3  Operatorvereinbarung 
+ 
+Operatoren können in ELAN ähnlich wie Prozeduren definiert werden. Operatoren
+müssen einen und können maximal zwei Operatoren besitzen (monadische und dyadi­
+sche Operatoren). 
+ 
+Form: 
+ 
+ 
+Resultattyp #on("i")##on("b")#OP#off("i")##off("b")# Opname #on("i")##on("b")#(#off("i")##off("b")# ein oder zwei Parameter #on("i")##on("b")#)#off("i")##off("b")# #on("i")##on("b")#:#off("i")##off("b")# 
+   Operatorrumpf 
+#on("i")##on("b")#END OP#off("i")##off("b")# Opname 
+ 
+ 
+Der Resultattyp wird nur bei wertliefernden Operatoren angegeben. 
+ 
+Als Operatornamen sind erlaubt: 
+ 
+-  ein Sonderzeichen, sofern es nicht als Trennzeichen benutzt wird: 
+   !  $  %  &  '  *  +  -  /  <  =  >  ?  §  ^  '  ~ 
+-  eine Kombination von zwei Sonderzeichen. Diese Kombination muß jedoch bereits
+   in ELAN existieren: 
+   :=   <=   >=   <>   ** 
+-  ein Schlüsselwort (siehe 2.2.1). 
+ 
+ 
+ 
+Vereinbarung eines monadischen Operators 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT OP SIGN (REAL CONST argument): 
+    IF    argument < 0.0  THEN  -1 
+    ELIF  argument = 0.0  THEN  0 
+                          ELSE  1 
+    FI 
+ END OP SIGN 
+  
+____________________________________________________________________________ 
+ 
+ 
+(Der Operator 'SIGN' liefert abhängig vom Vorzeichen des übergebenen Wertes den
+INT-Wert -1, 0 oder 1) 
+ 
+ 
+ 
+Vereinbarung eines dyadischen Operators 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ TEXT OP * (INT CONST anzahl, TEXT CONST t): 
+    INT  VAR zaehler :: anzahl; 
+    TEXT VAR ergebnis :: ""; 
+    WHILE zaehler > 0 REP 
+       ergebnis := ergebnis + t; 
+       zaehler := zaehler - 1 
+    END REP; 
+    ergebnis 
+ END OP *; 
+  
+____________________________________________________________________________ 
+ 
+ 
+(Der Operator '*' verkettet 'anzahl'- mal den Text 't') 
+ 
+ 
+ 
+2.4.3.4  Paketvereinbarung 
+ 
+Pakete sind in ELAN eine Zusammenfassung von Datenobjekten, Prozeduren, Opera­
+toren und Datentypen. Diese bilden den Paketrumpf. Elemente eines Pakets (Prozedu­
+ren, Operatoren, Datentypen) können außerhalb des Pakets nur angesprochen werden,
+wenn sie in der Schnittstelle des Pakets, die auch "interface" genannt wird, aufge­
+führt werden. Mit anderen Worten: es können alle Elemente eines Pakets von außen
+nicht angesprochen werden, sofern sie nicht über die Schnittstelle "nach außen ge­
+reicht" werden. Pakete können separat übersetzt werden, so daß der "Zusammen­
+bau" eines umfangreichen Programms aus mehreren Paketen möglich ist. 
+ 
+Der formale Aufbau eines Pakets sieht folgendermaßen aus: 
+ 
+ 
+#on("i")##on("b")#PACKET#off("i")##off("b")# Paketname #on("i")##on("b")#DEFINES#off("i")##off("b")# Schnittstelle #on("i")##on("b")#:#off("i")##off("b")# 
+   Paketrumpf 
+#on("i")##on("b")#END PACKET#off("i")##off("b")# Paketname 
+ 
+ 
+In der Schnittstelle werden Prozeduren und Operatoren nur mit ihrem Namen, durch
+Kommata getrennt, angegeben. Weiterhin können Datentypen und mit CONST verein­
+barte Datenobjekte in der Schnittstelle aufgeführt werden, aber keine VAR-Datenob­
+jekte, weil diese sonst über Paket-Grenzen hinweg verändert werden könnten. 
+ 
+Im Gegensatz zu einer Prozedur kann ein PACKET nicht aufgerufen werden (nur die
+Elemente der Schnittstelle können benutzt werden). 
+ 
+Pakete werden zu folgenden Zwecken eingesetzt: 
+ 
+-  Spracherweiterung 
+-  Schutz vor fehlerhaftem Zugriff auf Datenobjekte 
+-  Realisierung von abstrakten Datentypen. 
+ 
+ 
+ 
+Spracherweiterung 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PACKET fuer eine prozedur DEFINES swap: 
+ 
+ PROC swap (INT VAR a, b): 
+    INT CONST x :: a; 
+    b := a; 
+    a := x 
+ END PROC swap 
+ 
+ END PACKET fuer eine prozedur 
+  
+____________________________________________________________________________ 
+ 
+ 
+Dies ist ein Paket, das eine Tausch-Prozedur für INT-Datenobjekte bereitstellt. Das
+PACKET kann übersetzt und dem ELAN-Compiler bekannt gemacht werden
+(EUMEL: "insertieren"). Ist das geschehen, kann man 'swap' wie alle anderen Proze­
+duren (z.B. 'put', 'get') in einem Programm verwenden. Tatsächlich werden die mei­
+sten Prozeduren und Operatoren (aber auch einige Datentypen), die in ELAN zur
+Verfügung stehen, nicht durch den ELAN-Compiler realisiert, sondern durch solche
+PACKETs. Um solche Objekte einigermaßen zu standardisieren, wurde in der
+ELAN-Sprachbeschreibung festgelegt, welche Datentypen, Prozeduren und Operato­
+ren in jedem ELAN-System vorhanden sein müssen. Solche Pakete werden Stan­
+dard-Pakete genannt. Jeder Installation - aber auch jedem Benutzer - steht es
+jedoch frei, zu den Standard-Paketen zusätzliche Pakete dem Compiler bekannzu­
+geben, und damit den ELAN-Sprachumfang zu erweitern. 
+ 
+ 
+ 
+Schutz vor fehlerhaftem Zugriff auf Datenobjekte 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PACKET stack handling DEFINES push, pop, init stack: 
+ 
+ LET max = 1000; 
+ ROW max INT VAR stack; (* siehe Kapitel Reihung, 2.6.1. *) 
+ INT VAR stack pointer; 
+ 
+ PROC init stack: 
+    stack pointer := 0 
+ END PROC init stack; 
+ 
+ PROC push (INT CONST dazu wert): 
+    stack pointer INCR 1; 
+    IF stack pointer > max 
+      THEN errorstop ("stack overflow") 
+      ELSE stack [stack pointer] := dazu wert 
+    END IF 
+ END PROC push; 
+ 
+ PROC pop (INT VAR von wert): 
+    IF stack pointer = 0 
+      THEN errorstop ("stack empty") 
+      ELSE von wert := stack [stack pointer]; 
+           stack pointer DECR 1 
+    END IF 
+ END PROC pop 
+ 
+ END PACKET stack handling; 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Dieses Packet realisiert einen Stack. Den Stack kann man über die Prozeduren 'init
+stack', 'push' und 'pop' benutzen. 
+#page# 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ init stack; 
+ werte einlesen und pushen; 
+ werte poppen und ausgeben. 
+ 
+ werte einlesen und pushen: 
+    INT VAR anzahl :: 0, wert; 
+    REP 
+       get (wert); 
+       push (wert); 
+       anzahl INCR 1 
+    UNTIL ende kriterium END REP. 
+ 
+ werte poppen und ausgeben: 
+    INT VAR i; 
+    FOR i FROM 1 UPTO anzahl REP 
+       pop (wert); 
+       put (wert) 
+    END REP. 
+  
+____________________________________________________________________________ 
+ 
+ 
+Die Datenobjekte 'stack' und 'stack pointer' haben nur Gültigkeit innerhalb des
+PACKETs 'stack handling'. 
+ 
+Anweisungen wie z.B. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ put (stack [3]); 
+ stack [27] := 5 
+  
+____________________________________________________________________________ 
+ 
+ 
+ 
+außerhalb des PACKETs 'stack handling' sind also verboten und werden vom
+ELAN-Compiler entdeckt. 
+ 
+Ein PACKET bietet also auch einen gewissen Schutz vor fehlerhafter Verwendung von
+Programmen und Datenobjekten. Wichtig ist weiterhin, daß die Realisierung des
+Stacks ohne weiteres geändert werden kann, ohne daß Benutzerprogramme im 'main
+packet' geändert werden müssen, sofern die Schnittstelle nicht verändert wird. Bei­
+spielsweise kann man sich entschließen, den Stack nicht durch eine Reihung, son­
+dern durch eine Struktur zu realisieren. Davon bleibt ein Benutzerprogramm unbe­
+rührt. 
+ 
+ 
+ 
+Realisierung von abstrakten Datentypen 
+Der Vollständigkeit halber wird folgendes Beispiel hier gezeigt. Wie neue Datentypen
+definiert werden, wird in Kapitel 2.7.1. erklärt. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PACKET widerstaende DEFINES WIDERSTAND, REIHE, PARALLEL, 
+                             :=, get, put: 
+ 
+ TYPE WIDERSTAND = INT; 
+ 
+ OP := (WIDERSTAND VAR l, WIDERSTAND CONST r): 
+    CONCR (l) := CONCR (r) 
+ END OP :=; 
+ 
+ PROC get (WIDERSTAND VAR w): 
+    INT VAR i; 
+    get (i); 
+    w := WIDERSTAND : (i) 
+ END PROC get; 
+ 
+ PROC put (WIDERSTAND CONST w): 
+    put (CONCR (w)) 
+ END PROC put; 
+ 
+ WIDERSTAND OP REIHE (WIDERSTAND CONST l, r): 
+    WIDERSTAND : ( CONCR (l) + CONCR (r)) 
+ END OP REIHE; 
+ 
+ WIDERSTAND OP PARALLEL (WIDERSTAND CONST l, r): 
+   WIDERSTAND : 
+     ((CONCR (l) * CONCR (r)) DIV (CONCR (l) + CONCR (r))) 
+ END OP PARALLEL 
+ 
+ END PACKET widerstaende 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Dieses Programm realisiert den Datentyp WIDERSTAND und mit den Operationen
+eine Fachsprache. 
+ 
+ 
+ 
+2.4.4  Terminatoren für Refinements, 
+       Prozeduren und Operatoren
+        
+ 
+Das LEAVE-Konstrukt wird verwendet, um eine benannte Anweisung (Refinement,
+Prozedur oder Operator) vorzeitig zu verlassen. Es ist auch möglich, geschachtelte
+Refinements zu verlassen. 
+ 
+Form: 
+ 
+#on("i")##on("b")#LEAVE#off("i")##off("b")# Name 
+ 
+ 
+Durch eine (optionale) WITH-Angabe kann auch eine wertliefernde benannte Anwei­
+sung verlassen werden. 
+ 
+Form: 
+ 
+#on("i")##on("b")#LEAVE#off("i")##off("b")# Name #on("i")##on("b")#WITH#off("i")##off("b")# Ausdruck 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT OP ** (INT CONST basis, exp): 
+     IF exp = 0 
+        THEN LEAVE ** WITH 1 
+     ELIF exp < 0 
+        THEN LEAVE ** WITH 0 
+     FI; 
+ 
+     INT VAR  zaehler, ergebnis; 
+     ergebnis := basis; 
+     FOR zaehler FROM 2 UPTO exp REP 
+        ergebnis := ergebnis * basis 
+     PER; 
+     ergebnis 
+ END OP ** 
+  
+____________________________________________________________________________ 
+ 
+ 
+(Diese Operation realisiert die Exponentiation für INT-Werte) 
+ 
+ 
+ 
+2.4.5  Generizität von Prozeduren 
+       und Operatoren
+        
+ 
+In ELAN ist es möglich, unterschiedlichen Prozeduren bzw. Operatoren gleiche
+Namen zu geben. Solche Prozeduren (Operatoren) werden generische Prozeduren
+(Operatoren) genannt. Die Identifizierung erfolgt durch Anzahl, Reihenfolge und Daten­
+typ der Parameter (Operanden). 
+ 
+Deshalb werden Prozeduren und Operatoren unter Angabe des Prozedur- bzw. des
+Operatorkopfes dokumentiert. 
+ 
+Beispiele: 
+ 
+ 
+INT  OP MOD (INT CONST  l, r) 
+REAL OP MOD (REAL CONST l, r) 
+ 
+ 
+Der MOD-Operator liefert den Rest einer Division. Er ist sowohl für INT- wie auch
+für REAL-Datenobjekte definiert. 
+ 
+ 
+ 
+PROC put (INT CONST wert) 
+PROC put (REAL CONST wert) 
+PROC put (TEXT CONST wert) 
+ 
+ 
+Die put-Prozedur ist für INT-, REAL- und TEXT-Datenobjekte definiert. 
+ 
+ 
+
+Priorität von generischen Operatoren
+Bei der Neudefinition von Operatoren kann man bereits benutzte Sonderzeichen oder
+Schlüsselwörter benutzen. In diesem Fall bekommt der neudefinierte Operator die
+gleiche Priorität wie der bereits vorhandene Operator. 
+ 
+ 
+ 
+2.4.6     Rekursive Prozeduren 
+           und Operatoren
+           
+ 
+Alle Prozeduren und Operatoren dürfen in ELAN rekursiv sein. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT PROC fakultaet (INT CONST n): 
+    IF n > 0 
+      THEN fakultaet (n-1) * n 
+      ELSE 1 
+    END IF 
+ END PROC fakultaet 
+  
+____________________________________________________________________________ 
+ 
+ 
+Die Fakultätsfunktion ist kein gutes Beispiel für eine Rekursion, denn das Programm
+kann leicht in eine iterative Version umgewandelt werden: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT PROC fakultaet (INT CONST n): 
+    INT VAR prod :: 1, i; 
+    FOR i FROM 2 UPTO n REP 
+      prod := prod * i 
+    END REP; 
+    prod 
+ END PROC fakultaet 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Umwandlung von einem rekursiven Programm in ein iteratives ist übrigens immer
+möglich, jedoch oft nicht so einfach, wie in dem Beispiel der Ackermann-Funktion: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT PROC acker (INT CONST m, n): 
+    IF m = 0 
+      THEN n + 1 
+    ELIF n = 0 
+      THEN acker (m-1, 0) 
+      ELSE acker (m - 1, acker (m, n - 1)) 
+    ENDIF 
+ END PROC acker 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Das eigentliche Einsatzgebiet von rekursiven Algorithmen liegt aber bei den 'back­
+track'-Verfahren. Diese werden eingesetzt, wenn eine exakte algorithmische Lösung
+nicht bekannt ist oder nicht gefunden werden kann und man verschiedene Versuche
+machen muß, um zu einem Ziel (oder Lösung) zu gelangen. 
+
diff --git a/doc/programming/programmierhandbuch.2b b/doc/programming/programmierhandbuch.2b
new file mode 100644
index 0000000..c2103ba
--- /dev/null
+++ b/doc/programming/programmierhandbuch.2b
@@ -0,0 +1,1395 @@
+#headandbottom("52","EUMEL-Benutzerhandbuch","TEIL 2 : ELAN","2")# 
+#pagenr ("%", 52)##setcount(1)##block##pageblock# 
+#headeven# 
+#center#EUMEL-Benutzerhandbuch 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#TEIL 2 : ELAN 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+2 - % #right#GMD 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+GMD #right#2 - % 
+#end# 
+ 
+ 
+2.5  Programmstruktur 
+ 
+Ein ELAN-Programm kann aus mehreren Moduln (Bausteinen) aufgebaut sein, die in
+ELAN PACKETs genannt werden. Das letzte PACKET wird "main packet" genannt,
+weil in diesem das eigentliche Benutzerprogramm (Hauptprogramm) enthalten ist. 
+Dies soll eine Empfehlung sein, in welcher Reihenfolge die Elemente eines PACKETs
+geschrieben werden sollen: 
+ 
+Ein "main packet" kann aus folgenden Elementen bestehen: 
+ 
+a) Deklarationen und Anweisungen. Diese müssen nicht in einer bestimmten Reihen­
+   folge im Programm erscheinen, sondern es ist möglich, erst in dem Augenblick zu
+   deklarieren, wenn z.B. eine neue Variable benötigt wird. Es ist jedoch gute Pro­
+   grammierpraxis, die meisten Deklarationen an den Anfang eines Programms oder
+   Programmteils (Refinement, Prozedur) zu plazieren. 
+ 
+   <Deklarationen> ; 
+   <Anweisungen> 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT VAR erste zahl, zweite zahl; 
+ 
+ page; 
+ put ("erste Zahl = "); get (erste zahl); 
+ put ("zweite Zahl ="); get (zweite zahl) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+b) Deklarationen, Refinements und Anweisungen. In diesem Fall ist es notwendig, die 
+   Refinements hintereinander zu plazieren. Refinement-Aufrufe und/oder
+   Anweisungen sollten textuell vorher erscheinen. 
+ 
+   <Deklarationen> ; 
+   <Refinement-Aufrufe und/oder Anweisungen> . 
+   <Refinements> 
+ 
+   Innerhalb der Refinements sind Anweisungen und/oder Deklarationen möglich. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT VAR erste zahl, zweite zahl; 
+ 
+ loesche bildschirm; 
+ lies zwei zahlen ein. 
+ 
+ loesche bildschirm: 
+   page. 
+ 
+ lies zwei zahlen ein: 
+   put ("erste Zahl = "); get (erste zahl); 
+   put ("zweite Zahl ="); get (zweite zahl). 
+ 
+____________________________________________________________________________ 
+ 
+ 
+c) Deklarationen, Prozeduren und Anweisungen. Werden Prozeduren vereinbart,
+   sollte man sie nach den Deklarationen plazieren. Danach sollten die Anweisungen
+   folgen: 
+ 
+   <Deklarationen> ; 
+   <Prozeduren> ; 
+   <Anweisungen> 
+ 
+   Mehrere Prozeduren werden durch ";" voneinander getrennt. In diesem Fall sind
+   die Datenobjekte aus den Deklarationen außerhalb von Prozeduren statisch, d.h.
+   während der gesamten Laufzeit des Programm vorhanden. Solche Datenobjekte
+   werden auch PACKET-Daten genannt. Im Gegensatz dazu sind die Datenobjekte
+   aus Deklarationen in Prozeduren dynamische Datenobjekte, die nur während der
+   Bearbeitungszeit der Prozedur existieren. Innerhalb einer Prozedur dürfen wieder­
+   um Refinements verwendet werden. Ein Prozedur-Rumpf hat also den formalen
+   Aufbau wie unter a) oder b) geschildert. 
+ 
+   Die Refinements und Datenobjekte, die innerhalb einer Prozedur deklariert wurden,
+   sind lokal zu dieser Prozedur, d.h. können von außerhalb nicht angesprochen
+   werden. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT VAR erste zahl, zweite zahl; 
+ 
+ PROC vertausche (INT VAR a, b): 
+   INT VAR x; 
+ 
+   x := a; 
+   a := b; 
+   b := x 
+ END PROC vertausche; 
+ 
+ put ("erste Zahl = "); get (erste zahl); 
+ put ("zweite Zahl ="); get (zweite zahl); 
+ IF erste zahl > zweite zahl 
+    THEN vertausche (erste zahl, zweite zahl) 
+ FI 
+ 
+____________________________________________________________________________ 
+ 
+ 
+d) Deklarationen, Prozeduren, Anweisungen und PACKET-Refinements. Zusätzlich
+   zu der Möglichkeit c) ist es erlaubt, neben den Anweisungen außerhalb einer
+   Prozedur auch Refinements zu verwenden: 
+ 
+   <Deklarationen> ; 
+   <Prozeduren> ; 
+   <Anweisungen> . 
+   <Refinements> 
+ 
+   Diese Refinements können nun in Anweisungen außerhalb der Prozeduren benutzt
+   werden oder auch durch die Prozeduren (im letzteren Fall spricht man analog zu
+   globalen PACKET-Daten auch von PACKET-Refinements oder globalen Refine­
+   ments). In PACKET-Refinements dürfen natürlich keine Datenobjekte verwandt
+   werden, die lokal zu einer Prozedur sind. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ INT VAR erste zahl, zweite zahl; 
+ 
+ PROC vertausche (INT VAR a, b): 
+   INT VAR x; 
+ 
+   x := a; 
+   a := b; 
+   b := x 
+ END PROC vertausche; 
+ 
+ loesche bildschirm; 
+ lies zwei zahlen ein; 
+ ordne die zahlen. 
+ 
+ loesche bildschirm: 
+   page. 
+ 
+ lies zwei zahlen ein: 
+   put ("erste Zahl = "); get (erste zahl); 
+   put ("zweite Zahl ="); get (zweite zahl). 
+ 
+ ordne die zahlen: 
+   IF erste zahl > zweite zahl 
+      THEN vertausche (erste zahl, zweite zahl) 
+   FI 
+ 
+____________________________________________________________________________ 
+#page# 
+ 
+2.6  Zusammengesetzte Datentypen 
+ 
+In ELAN gibt es die Möglichkeit, gleichartige oder ungleichartige Datenobjekte zu
+einem Objekt zusammenzufassen. 
+ 
+ 
+2.6.1  Reihung 
+ 
+Die Zusammenfassung gleichartiger Datenobjekte, wird in ELAN eine Reihung (ROW)
+genannt. Die einzelnen Objekte einer Reihung werden Elemente genannt. 
+ 
+Eine Reihung wird folgendermaßen deklariert: 
+  
+-  Schlüsselwort #on("i")##on("b")#ROW#off("i")##off("b")# 
+-  Anzahl der zusammengefaßten Elemente 
+   (INT-Denoter oder durch LET definierter Name) 
+-  Datentyp der Elemente 
+-  Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")# ) 
+-  Name der Reihung. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ ROW 10 INT VAR feld 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Im obigen Beispiel wird eine Reihung von 10 INT-Elementen deklariert. ROW 10 INT
+ist ein (neuer, von den elementaren unterschiedlicher) Datentyp, für den keine Opera­
+tionen definiert sind, außer der Zuweisung. Das Accessrecht (VAR im obigen Bei­
+spiel) und der Name ('feld') gilt - wie bei den elementaren Datentypen - für diesen
+neuen Datentyp, also für alle 10 Elemente. 
+ 
+Warum gibt es keine Operationen außer der Zuweisung? Das wird sehr schnell
+einsichtig, wenn man bedenkt, daß es ja sehr viele Datentypen (zusätzlich zu den
+elementaren) gibt, weil Reihungen von jedem Datentyp gebildet werden können: 
+ 
+ 
+ROW 1 INT             ROW 1 REAL 
+ROW 2 INT             ROW 2 REAL 
+ :                     : 
+ROW maxint INT        ROW maxint REAL 
+ 
+ROW 1 TEXT            ROW 1 BOOL 
+ROW 2 TEXT            ROW 2 BOOL 
+ :                     : 
+ROW maxint TEXT       ROW maxint BOOL 
+ 
+ 
+Für die elementaren INT-, REAL-, BOOL- und TEXT-Datentypen sind unter­
+schiedliche Operationen definiert. Man müßte nun für jeden dieser zusammengesetz­
+ten Datentypen z.B. auch 'get'- und 'put'-Prozeduren schreiben, was allein vom
+Schreibaufwand sehr aufwendig wäre. Das ist der Grund dafür, daß es keine vorgege­
+bene Operationen auf zusammengesetzte Datentypen gibt. 
+ 
+Zugegebenermaßen könnte man mit solchen Datentypen, die nur über eine Operation
+verfügen (Zuweisung), nicht sehr viel anfangen, wenn es nicht eine weitere vorgege­
+bene Operation gäbe, die Subskription. Sie erlaubt es, auf die Elemente einer Reih­
+ung zuzugreifen und den Datentyp der Elemente "aufzudecken". 
+ 
+Form: 
+ 
+Rowname #on("i")##on("b")#[#off("i")##off("b")# Indexwert #on("i")##on("b")#]#off("i")##off("b")# 
+ 
+Beispiel: 
+ 
+ 
+feld [3] 
+ 
+ 
+bezieht sich auf das dritte Element der Reihung 'feld' und hat den Datentyp INT. Für
+INT-Objekte haben wir aber einige Operationen, mit denen wir arbeiten können. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiele: ........................ 
+ feld [3] := 7; 
+ feld [4] := feld [3] + 4; 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Eine Subskription "schält" also vom Datentyp ein ROW ab und liefert ein Element der
+Reihung. Die Angabe der Nummer des Elements in der Reihung nennt man Subskript
+oder Index (in obigem Beispiel '3'). Der Subskript wird in ELAN in eckigen Klammern
+angegeben, um eine bessere Unterscheidung zu den runden Klammern in Ausdrücken
+zu erreichen. Ein subskribiertes ROW-Datenobjekt kann also überall da verwendet
+werden, wo ein entsprechender Datentyp benötigt wird (Ausnahme: nicht als Schlei­
+fenvariable). 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PROC get (ROW 10 INT VAR feld): 
+    INT VAR i; 
+    FOR i FROM 1 UPTO 10 REP 
+      put (i); put ("tes Element bitte:"); 
+      get (feld [i]); 
+      line 
+    END REP 
+ END PROC get; 
+ 
+ PROC put (ROW 10 INT CONST feld): 
+    INT VAR i; 
+    FOR i FROM 1 UPTO 10 REP 
+      put (i); put ("tes Element ist:"); 
+      put (feld [i]); 
+      line 
+    END REP 
+ END PROC put 
+ 
+____________________________________________________________________________ 
+ 
+ 
+In diesen Beispielen werden Reihungen als Parameter benutzt. 
+ 
+Diese beiden Prozeduren werden im folgenden Beispiel benutzt um 10 Werte einzu­
+lesen und die Summe zu berechnen: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ ROW 10 INT VAR werte; 
+ lies werte ein; 
+ summiere sie; 
+ drucke die summe und einzelwerte. 
+ 
+ lies werte ein: 
+    get (werte). 
+ 
+ summiere sie: 
+    INT VAR summe :: 0, i; 
+    FOR i FROM 1 UPTO 10 REP 
+      summe INCR werte [i] 
+    END REP. 
+ 
+ drucke die summe und einzelwerte: 
+    put (werte); 
+    line; 
+    put ("Summe:"); put (summe). 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Da es möglich ist, von jedem Datentyp eine Reihung zu bilden, kann man natürlich
+auch von einer Reihung eine Reihung bilden: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ ROW 5 ROW 10 INT VAR matrix 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Für eine "doppelte" Reihung gilt das für "einfache" Reihungen gesagte. Wiederum
+existieren keine Operationen für dieses Datenobjekt (außer der Zuweisung), jedoch ist
+es durch Subskription möglich, auf die Elemente zuzugreifen: 
+ 
+ 
+matrix [3] 
+ 
+ 
+liefert ein Datenobjekt mit dem Datentyp ROW 10 INT. 
+ 
+Subskribiert man jedoch 'matrix' nochmals, so erhält man ein INT: 
+ 
+ 
+matrix [2] [8] 
+ 
+ 
+(jede Subskription "schält" von Außen ein ROW vom Datentyp ab). 
+#page# 
+ 
+2.6.2  Struktur 
+ 
+Strukturen sind Datenverbunde wie Reihungen, aber die Komponenten können unglei­
+chartige Datentypen haben. Die Komponenten von Strukturen heißen Felder (Reihun­
+gen: Elemente) und der Zugriff auf ein Feld Selektion (Reihungen: Subskription). Eine
+Struktur ist - genauso wie bei Reihungen - ein eigener Datentyp, der in einer
+Deklaration angegeben werden muß. 
+ 
+Die Deklaration einer Struktur sieht folgendermaßen aus: 
+ 
+-  Schlüsselwort #schl ("STRUCT#off("i")##off("b")# 
+-  unterschiedliche Datenobjekte in Klammern. Die Datenobjekte werden mit Datentyp und Namen angegeben 
+-  Zugriffsrecht ( #on("i")##on("b")#VAR#off("i")##off("b")# oder #on("i")##on("b")#CONST#off("i")##off("b")# ) 
+-  Name der Struktur. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ STRUCT (TEXT name, INT alter) VAR ich 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Wiederum existieren keine Operationen auf Strukturen außer der Zuweisung und der
+Selektion, die es erlaubt, Komponenten aus einer Struktur herauszulösen. 
+ 
+Die Selektion hat folgende Form: 
+ 
+Objektname #on("i")##on("b")#.#off("i")##off("b")# Feldname 
+ 
+Beispiele: 
+ 
+ 
+ich . name 
+ich . alter 
+ 
+ 
+Die erste Selektion liefert einen TEXT-, die zweite ein INT-Datenobjekt. Mit diesen
+(selektierten) Datenobjekten kann - wie gewohnt - gearbeitet werden (Ausnahme:
+nicht als Schleifenvariable). 
+ 
+Zum Datentyp einer Struktur gehören auch die Feldnamen: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ STRUCT (TEXT produkt name, INT artikel nr) VAR erzeugnis 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die obige Struktur ist ein anderer Datentyp als im ersten Beispiel dieses Abschnitts,
+da die Namen der Felder zur Unterscheidung hinzugezogen werden. Für Strukturen -
+genauso wie bei Reihungen - kann man sich neue Operationen definieren. 
+ 
+Im folgenden Programm werden eine Struktur, die Personen beschreibt, die Prozedu­
+ren 'put', 'get' und der dyadische Operator HEIRATET definiert. Anschließend werden
+drei Paare verHEIRATET. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PROC get (STRUCT (TEXT name, vorname, INT alter) VAR p): 
+    put ("bitte Nachname:"); get ( p.name); 
+    put ("bitte Vorname:");  get ( p.vorname); 
+    put ("bitte Alter:");    get ( p.alter); 
+    line 
+ END PROC get; 
+ 
+ PROC put (STRUCT (TEXT name, vorname, INT alter) CONST p): 
+    put (p.vorname); put (p.name); 
+    put ("ist"); 
+    put (p.alter); 
+    put ("Jahre alt"); 
+    line 
+ END PROC put; 
+ 
+ OP HEIRATET 
+    (STRUCT (TEXT name, vorname, INT alter) VAR w, 
+     STRUCT (TEXT name, vorname, INT alter) CONST m): 
+    w.name := m.name 
+ END OP HEIRATET; 
+ 
+____________________________________________________________________________ 
+ 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ ROW 3 STRUCT (TEXT name, vorname, INT alter) VAR frau, 
+                                                  mann; 
+ 
+ personendaten einlesen; 
+ heiraten lassen; 
+ paardaten ausgeben. 
+ 
+ personendaten einlesen: 
+    INT VAR i; 
+    FOR i FROM 1 UPTO 3 REP 
+      get (frau [i]); 
+      get (mann [i]) 
+    END REP. 
+ 
+ heiraten lassen: 
+    FOR i FROM 1 UPTO 3 REP 
+      frau [i] HEIRATET mann [i] 
+    END REP. 
+ 
+ paardaten ausgeben: 
+    FOR i FROM 1 UPTO 3 REP 
+      put (frau [i]); 
+      put ("hat geheiratet:"); line; 
+      put (mann [i]); line 
+    END REP. 
+  
+____________________________________________________________________________ 
+ 
+ 
+Reihungen und Strukturen dürfen miteinander kombiniert werden, d.h. es darf eine
+Reihung in einer Struktur erscheinen oder es darf eine Reihung von einer Struktur
+vorgenommen werden. Selektion und Subskription sind in diesen Fällen in der Reihen­
+folge vorzunehmen, wie die Datentypen aufgebaut wurden (von außen nach innen). 
+#page# 
+ 
+2.6.3  LET-Konstrukt für zusammengesetzte Datentypen 
+       
+ 
+Die Verwendung von Strukturen oder auch Reihungen kann manchmal schreibauf­
+wendig sein. Mit dem LET-Konstrukt darf man Datentypen einen Namen geben.
+Dieser Name steht als Abkürzung und verringert so die Schreibarbeit. Zusätzlich wird
+durch die Namensgebung die Lesbarkeit des Programms erhöht. 
+ 
+Form: 
+ 
+#on("i")##on("b")#LET#off("i")##off("b")# Name #on("i")##on("b")#=#off("i")##off("b")# Datentyp 
+ 
+Der Name darf nur aus Großbuchstaben (ohne Blanks) bestehen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ LET PERSON = STRUCT (TEXT name, vorname, INT alter); 
+ 
+ PROC get (PERSON VAR p): 
+    put ("bitte Nachname:"); get ( p.name); 
+    put ("bitte Vorname:");  get ( p.vorname); 
+    put ("bitte Alter:");    get ( p.alter); 
+    line 
+ END PROC get; 
+ 
+ PROC put (PERSON CONST p): 
+    put (p.vorname); put (p.name); put ("ist"); 
+    put (p.alter);   put ("Jahre alt"); line 
+ END PROC put; 
+ 
+ OP HEIRATET (PERSON VAR f, PERSON CONST m): 
+    f.name := m.name 
+ END OP HEIRATET; 
+ 
+ ROW 3 PERSON VAR mann, frau; 
+  
+____________________________________________________________________________ 
+ 
+ 
+Überall, wo der abzukürzende Datentyp verwandt wird, kann stattdessen der Name
+PERSON benutzt werden. Wohlgemerkt: PERSON ist kein neuer Datentyp, sondern
+nur ein Name, der für STRUCT (....) steht. Der Zugriff auf die Komponenten des
+abgekürzten Datentyps bleibt erhalten (was bei abstrakten Datentypen, die später
+erklärt werden, nicht mehr der Fall ist). 
+ 
+Neben der Funktion der Abkürzung von Datentypen kann das LET-Konstrukt auch
+zur Namensgebung für Denoter verwandt werden (siehe 2.3.1.2). 
+ 
+ 
+ 
+2.6.4  Denoter für zusammengesetzte 
+       Datentypen (Konstruktor)
+       
+ 
+Oft ist es notwendig, Datenverbunden Werte zuzuweisen (z.B.: bei der Initialisierung).
+Dies kann durch normale Zuweisungen erfolgen: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ LET PERSON = STRUCT (TEXT name, vorname, INT alter); 
+ 
+ PERSON VAR mann; 
+ 
+ mann.name := "meier"; 
+ mann.vorname := "egon"; 
+ mann.alter := 27 
+  
+____________________________________________________________________________ 
+ 
+ 
+Eine andere Möglichkeit für die Wertbesetzung von Datenverbunden ist der Konstruk­
+tor: 
+ 
+Form: 
+ 
+Datentyp #on("i")##on("b")#:#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Wertliste #on("i")##on("b")#)#off("i")##off("b")# 
+ 
+In der Wertliste wird für jede Komponente des Datentyps, durch Kommata getrennt,
+ein Wert aufgeführt. Besteht eine der Komponenten wiederum aus einem Datenver­
+bund, muß innerhalb des Konstruktors wiederum ein Konstruktor eingesetzt werden. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ LET PERSON = STRUCT (TEXT name, vorname, INT alter); 
+ 
+ PERSON VAR mann, frau; 
+ 
+ frau := PERSON : ( "niemeyer", "einfalt", 65); 
+ frau HEIRATET PERSON : ( "meier", "egon", 27) 
+  
+____________________________________________________________________________ 
+ 
+ 
+Ein Konstruktor ist also ein Mechanismus, um ein Datenobjekt eines Datenverbundes
+in einem Programm zu notieren. 
+ 
+Konstruktoren sind natürlich für Reihungen auch möglich: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ ROW 7 INT VAR feld; 
+ feld := ROW 7 INT : ( 1, 2, 3, 4, 5, 6, 7); 
+____________________________________________________________________________ 
+#page# 
+ 
+2.7  Abstrakte Datentypen 
+ 
+ 
+2.7.1  Definition neuer Datentypen 
+ 
+Im Gegensatz zur LET-Vereinbarung für Datentypen, bei der lediglich ein neuer
+Name für einen bereits vorhandenen Datentyp eingeführt wird und bei der somit auch
+keine neuen Operationen definiert werden müssen (weil die Operationen für den
+abzukürzenden Datentyp verwandt werden können), wird durch eine TYPE-Verein­
+barung ein gänzlich neuer Datentyp eingeführt. 
+ 
+Form: 
+ 
+#on("i")##on("b")#TYPE#off("i")##off("b")# Name #on("i")##on("b")#=#off("i")##off("b")# Feinstruktur 
+ 
+Der Name darf nur aus Großbuchstaben (ohne Blanks) bestehen. Die Feinstruktur
+(konkreter Typ, Realisierung des Datentyps) kann jeder bereits definierte Datentyp
+sein. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ TYPE PERSON = STRUCT (TEXT name, vorname, INT alter) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Der neudefinierte Datentyp wird abstrakter Datentyp genannt. Im Gegensatz zu
+Strukturen und Reihungen stehen für solche Datentypen noch nicht einmal die Zuwei­
+sung zur Verfügung. Ein solcher Datentyp kann genau wie alle anderen Datentypen
+verwendet werden (Deklarationen, Parameter, wertliefernde Prozeduren, als Kompo­
+nenten in Reihungen und Strukturen usw.). 
+ 
+Wird der Datentyp über die Schnittstelle des PACKETs anderen Programmteilen zur
+Verfügung gestellt, so müssen Operatoren und/oder Prozeduren für den Datentyp
+ebenfalls "herausgereicht" werden. Da dann der neudefinierte Datentyp genauso wie
+alle anderen Datentypen verwandt werden kann, aber die Komponenten (Feinstruktur)
+nicht zugänglich sind, spricht man von abstrakten Datentypen. 
+ 
+Welche Operationen sollten für einen abstrakten Datentyp zur Verfügung stehen?
+Obwohl das vom Einzelfall abhängt, werden meistens folgende Operationen und
+Prozeduren definiert: 
+ 
+-  'get'- und 'put'-Prozeduren. 
+-  Zuweisung (auch für die Initialisierung notwendig). 
+-  Denotierungs-Prozedur (weil kein Konstruktor für den abstrakten Datentyp außer­
+   halb des definierenden PACKETs zur Verfügung steht) 
+ 
+ 
+ 
+2.7.2  Konkretisierung 
+ 
+Um neue Operatoren und/oder Prozeduren für einen abstrakten Datentyp zu schrei­
+ben, ist es möglich, auf die Komponenten des Datentyps (also auf die Feinstruktur)
+mit Hilfe des Konkretisierers zuzugreifen. Der Konkretisierer arbeitet ähnlich wie die
+Subskription oder Selektion: er ermöglicht eine typmäßige Umbetrachtung vom ab­
+strakten Typ zum Datentyp der Feinstruktur. 
+ 
+Form: 
+ 
+#on("i")##on("b")#CONCR#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Ausdruck #on("i")##on("b")#)#off("i")##off("b")# 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ TYPE MONAT = INT; 
+ 
+ PROC put (MONAT CONST m): 
+    put ( CONCR (m)) 
+ END PROC put; 
+  
+____________________________________________________________________________ 
+ 
+ 
+Der Konkretisierer ist bei Feinstrukturen notwendig, die von elementarem Datentyp
+sind. Besteht dagegen die Feinstruktur aus Reihungen oder Strukturen, dann wird
+durch eine Selektion oder Subskription eine implizite Konkretisierung vorgenommen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ TYPE LISTE = ROW 100 INT; 
+ 
+ LISTE VAR personal nummer; 
+ ... 
+ personal nummer [3] := ... 
+ (* das gleiche wie *) 
+ CONCR (personal nummer) [3] := ... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+2.7.3  Denoter für abstrakte 
+       Datentypen (Konstruktor)
+       
+ 
+Denoter für neudefinierte Datentypen werden mit Hilfe des Konstruktors gebildet: 
+ 
+Form: 
+ 
+Datentyp #on("i")##on("b")#:#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Wertliste #on("i")##on("b")#)#off("i")##off("b")# 
+ 
+In der Wertliste wird für jede Komponente des Datentyps, durch Kommata getrennt,
+ein Wert aufgeführt. Besteht eine der Komponenten wiederum aus einem Datenver­
+bund, muß innerhalb des Konstruktors wiederum ein Konstruktor eingesetzt werden. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ TYPE GEHALT = INT; 
+ 
+ GEHALT VAR meins :: GEHALT : (10000); 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Besteht die Feinstruktur aus einem Datenverbund, muß der Konstruktor u.U. mehrfach
+geschachtelt angewandt werden: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ TYPE KOMPLEX = ROW 2 REAL; 
+ 
+ KOMPLEX CONST x :: KOMPLEX : ( ROW 2 REAL : ( 1.0, 2.0)); 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Auf die Feinstruktur über den Konkretisierer eines neudefinierten Datentyps darf nur in
+dem PACKET zugegriffen werden, in dem der Datentyp definiert wurde. Der Konstruk­
+tor kann ebenfalls nur in dem typdefinierenden PACKET verwandt werden. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PACKET widerstaende DEFINES WIDERSTAND, REIHE, PARALLEL, 
+                             :=, get, put: 
+ 
+ TYPE WIDERSTAND = INT; 
+ 
+ OP := (WIDERSTAND VAR l, WIDERSTAND CONST r): 
+    CONCR (l) := CONCR (r) 
+ END OP :=; 
+ 
+ PROC get (WIDERSTAND VAR w): 
+    INT VAR i; 
+    get (i); 
+    w := WIDERSTAND : (i) 
+ END PROC get; 
+ 
+ PROC put (WIDERSTAND CONST w): 
+    put (CONCR (w)) 
+ END PROC put; 
+ 
+ WIDERSTAND OP REIHE (WIDERSTAND CONST l, r): 
+    WIDERSTAND : ( CONCR (l) + CONCR (r)) 
+ END OP REIHE; 
+ 
+ WIDERSTAND OP PARALLEL (WIDERSTAND CONST l, r): 
+   WIDERSTAND : 
+     ((CONCR (l) * CONCR (r)) DIV (CONCR (l) + CONCR (r))) 
+ END OP PARALLEL 
+ 
+ END PACKET widerstaende 
+  
+____________________________________________________________________________ 
+ 
+ 
+Dieses Programm realisiert den Datentyp WIDERSTAND und mit den Operationen
+eine Fachsprache, mit dem man nun leicht WIDERSTANDs-Netzwerke berechnen
+kann, wie z.B. folgendes: 
+ 
+ 
+ 
+                          +---R4---+ 
+                          |        | 
+        +---R1---+        +---R5---+ 
+        |        |        |        | 
+     ---+        +---R3---+        +--- 
+        |        |        |        | 
+        +---R2---+        +---R6---+ 
+                          |        | 
+                          +---R7---+ 
+ 
+ 
+Zur Berechnung des Gesamtwiderstandes kann nun folgendes Programm geschrieben
+werden: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ ROW 7 WIDERSTAND VAR r; 
+ widerstaende einlesen; 
+ gesamtwiderstand berechnen; 
+ ergebnis ausgeben. 
+ 
+ widerstaende einlesen: 
+    INT VAR i; 
+    FOR i FROM 1 UPTO 7 REP 
+       put ("bitte widerstand R"); put (i); put (":"); 
+       get (r [i]); 
+    END REP. 
+ 
+ gesamtwiderstand berechnen: 
+    WIDERSTAND CONST rgesamt :: (r [1] PARALLEL r [2]) REIHE 
+      r [3] REIHE (r [4] PARALLEL r [5] PARALLEL r [6] 
+      PARALLEL r [7]). 
+ 
+ ergebnis ausgeben: 
+    line; 
+    put (rgesamt). 
+____________________________________________________________________________ 
+#page# 
+ 
+2.8  Dateien 
+ 
+Dateien werden benötigt, wenn 
+ 
+-  Daten über die Abarbeitungszeit eines Programms aufbewahrt werden sollen; 
+-  der Zeitpunkt oder Ort der Datenerfassung nicht mit dem Zeitpunkt oder Ort der
+   Datenverarbeitung übereinstimmt; 
+-  die gesamte Datenmenge nicht auf einmal in den Zentralspeicher eines Rechners
+   paßt; 
+-  die Anzahl und/oder Art der Daten nicht von vornherein bekannt sind. 
+ 
+Eine Datei ("file") ist eine Zusammenfassung von Daten, die auf Massenspeichern
+aufbewahrt wird. Dateien sind in bestimmten Informationsmengen, den Sätzen ("re­
+cords") organisiert. 
+ 
+ 
+ 
+2.8.1  Datentypen FILE und DIRFILE 
+ 
+In ELAN gibt es zwei Arten von Dateien. Sie werden durch die Datentypen FILE 
+und DIRFILE realisiert: 
+ 
+ 
+ 
+FILE: 
+sequentielle Dateien. Die Sätze können nur sequentiell gelesen bzw. geschrieben
+werden. Eine Positionierung ist nur zum nächsten Satz möglich. 
+ 
+ 
+DIRFILE: 
+indexsequentielle Dateien. Die Positionierung erfolgt direkt mit Hilfe eines Schlüssels
+("key") oder Index, kann aber auch sequentiell vorgenommen werden. 
+ 
+#on("b")#Wichtig: #off("b")# 
+DIRFILEs sind auf dem EUMEL-System standardmäßig nicht implementiert! Deswe­
+gen wird auf diesen Dateityp hier nicht weiter eingegangen. 
+#page# 
+ 
+2.8.2  Deklaration und Assoziierung 
+ 
+Dateien müssen in einem ELAN-Programm - wie alle anderen Objekte auch -
+deklariert werden. 
+ 
+Form: 
+ 
+#on("i")##on("b")#FILE#off("i")##off("b")# #on("i")##on("b")#VAR#off("i")##off("b")# interner Dateibezeichner 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ FILE VAR f 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Dabei ist zu beachten, daß im EUMEL-System alle FILEs als VAR deklariert werden
+müssen, denn jede Lese/Schreib-Operation verändert einen FILE. 
+ 
+Dateien werden normalerweise vom Betriebsystem eines Rechners aufbewahrt und
+verwaltet. Somit ist eine Verbindung von einem ELAN-Programm, in dem eine Datei
+unter einem Namen - wie jedes andere Datenobjekt auch - angesprochen werden
+soll, und dem Betriebssystem notwendig. Dies erfolgt durch die sogenannte Assozi­
+ierungsprozedur. Die Assoziierungsprozedur 'sequential file' hat die Aufgabe, eine in
+einem Programm deklarierte FILE VAR mit einer bereits vorhandenen oder noch
+einzurichtenden Datei des EUMEL-Systems zu koppeln. 
+ 
+Form: 
+ 
+#on("i")##on("b")#sequential file#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Betriebsrichtung, Dateiname #on("i")##on("b")#)#off("i")##off("b")# 
+ 
+Es gibt folgende Betriebsrichtungen (TRANSPUTDIRECTIONs): 
+ 
+ 
+input:  
+Die Datei kann vom Programm nur gelesen werden. Durch 'input' wird bei der Asso­
+ziierung automatisch auf den ersten Satz der Datei positioniert. Ist die zu lesende
+Datei nicht vorhanden, wird ein Fehler gemeldet. 
+ 
+ 
+output:  
+Die Datei kann vom Programm nur beschrieben werden. Durch 'output' wird bei der
+Assoziierung automatisch hinter den letzten Satz der Datei positioniert (bei einer
+leeren Datei also auf den ersten Satz). Ist die Datei vor der Assoziierung nicht vor­
+handen, wird sie automatisch eingerichtet. 
+ 
+ 
+modify:  
+Im EUMEL-System gibt es noch die Betriebsrichtung 'modify'. 
+Die Datei kann vom Programm in beliebiger Weise gelesen und beschrieben werden.
+Im Gegensatz zu den Betriebsrichtungen 'input' und 'output', bei denen ausschließlich
+ein rein sequentielles Lesen oder Schreiben erlaubt ist, kann bei 'modify' beliebig
+positioniert, gelöscht, eingefügt und neu geschrieben werden. 
+ 
+Nach erfolgter Assoziiierung ist auf den zuletzt bearbeiteten Satz positioniert. Die
+Datei wird automatisch eingerichtet, wenn sie vor der Assoziierung nicht vorhanden
+war. 
+ 
+Der zweite Parameter der Assoziierungsprozedur gibt an, unter welchem Namen die
+Datei in der Task existiert oder eingerichtet werden soll. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ FILE VAR meine datei :: sequential file (output, "xyz"); 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Folgendes Beispiel zeigt ein Programm, welches eine Datei liest und auf dem Ausga­
+bemedium ausgibt: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ FILE VAR f :: sequential file (input, "datei1"); 
+ TEXT VAR satz; 
+ WHILE NOT eof (f) REP 
+    getline (f, satz); 
+    putline (satz); 
+ END REP. 
+  
+____________________________________________________________________________ 
+ 
+ 
+Eine genau Übersicht der für Dateien existierende Operatoren und Prozeduren finden
+Sie im Teil 5.3. 
+#page# 
+
+2.9  Abstrakte Datentypen 
+     im EUMEL-System
+     
+ 
+ 
+2.9.1  Datentyp TASK 
+ 
+Tasks müssen im Rechnersystem eindeutig identifiziert werden; sogar im EUMEL-
+Rechner-Netz sind Tasks eindeutig identifizierbar. Dazu wird der spezielle Datentyp
+'TASK' benutzt, denn die Identifizierung einer Task über den Namen ist nicht eindeu­
+tig. Der Benutzer kann ja einen Tasknamen ändern, eine Task löschen und eine
+neue Task mit gleichem Namen einrichten, die jedoch nicht gleich reagiert. Somit
+werden Tasks eindeutig über Variablen vom  Datentyp TASK identifiziert. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ TASK VAR plotter := task ("PLOTTER 1") 
+  
+____________________________________________________________________________ 
+ 
+ 
+Die Taskvariable 'plotter' bezeichnet jetzt die Task im System, die augenblicklich den
+Namen "PLOTTER 1" hat. Die Prozedur 'task' liefert den systeminternen Taskbe­
+zeichner. 
+ 
+Nun sind Taskvariablen auch unter Berücksichtigung der Zeit und nicht nur im aktuel­
+len Systemzustand eindeutig. Der Programmierer braucht sich also keine Sorgen
+darüber zu machen, daß seine Taskvariable irgendwann einmal eine "falsche" Task
+(nach Löschen von "PLOTTER 1" neu eingerichtete gleichen oder anderen Namens)
+identifiziert. Wenn die Task "PLOTTER 1" gelöscht worden ist, bezeichnet 'plotter'
+keine gültige Task mehr. 
+ 
+Unbenannte Tasks haben alle den Pseudonamen "-". Sie können nur über Taskvari­
+ablen angesprochen werden. 
+ 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PROC generate shutup manager: 
+    TASK VAR son; 
+    begin ("shutup", PROC shutup manager, son) 
+ END PROC generate shutup manager; 
+ 
+ PROC shutup manager: 
+    disable stop; 
+    command dialogue (TRUE); 
+    REP 
+       break; 
+       line; 
+       IF yes ("shutup") 
+          THEN clear error; 
+               shutup 
+       FI 
+    PER 
+ END PROC shutup manager 
+  
+____________________________________________________________________________ 
+ 
+ 
+Ein Taskvariable wird zum Beispiel als Parameter für die Prozedur 'begin' benötigt. 
+ 
+begin 
+   #on("b")#PROC begin (TEXT CONST son name, PROC start, 
+               TASK VAR new task)#off("b")# 
+   Die Prozedur richtet eine Sohntask mit Namen 'son name' (im Beispiel: shutup)
+   ein, die mit der Prozedur 'start' (im Beispiel: shutup manager) gestartet wird. 'new
+   task' (im Beispiel: son) identifiziert den Sohn, falls die Sohntask korrekt eingerich­
+   tet wurde. 
+#page# 
+ 
+2.9.2   Datentyp THESAURUS 
+ 
+Ein Thesaurus ist ein Namensverzeichnis, das bis zu 200 Namen beinhalten kann.
+Dabei muß jeder Name mindestens ein Zeichen und höchstens 100 Zeichen lang sein.
+Steuerzeichen (code < 32) werden im Namen folgendermaßen umgesetzt: 
+ 
+#on("i")##on("b")#steuerzeichen#off("b")##off("i")# wird umgesetzt in #on("i")##on("b")#"""" + code(steuerzeichen) + """"#off("b")##off("i")# 
+ 
+Ein Thesaurus ordnet jedem eingetragenen Namen einen Index zwischen 1 und 200
+(einschließlich) zu. Diese Indizes bieten dem Anwender die Möglichkeit, Thesauri zur
+Verwaltung benannter Objekte zu verwenden. (Der Zugriff erfolgt dann über den Index
+eines Namens in einem Thesaurus). So werden Thesauri u.a. von der Dateiverwaltung
+benutzt. Sie bilden die Grundlage der ALL- und SOME-Operatoren. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ initialisiere; 
+ arbeite thesaurus ab. 
+ 
+ initialisiere: 
+    THESAURUS VAR eine auswahl :: SOME (myself); 
+    TEXT VAR thesaurus element; 
+    INT VAR index :: 0. 
+ 
+ arbeite thesaurus ab: 
+    REPEAT 
+       get (eine auswahl, thesaurus element, index); 
+       IF thesaurus element = "" 
+          THEN LEAVE arbeite thesaurus ab 
+       FI; 
+       fuehre aktionen durch 
+    PER. 
+ 
+    fuehre aktionen durch: 
+       edit (thesaurus element); 
+       lineform (thesaurus element); 
+       pageform (thesaurus element); 
+       print (thesaurus element). 
+  
+____________________________________________________________________________ 
+ 
+ 
+Dieses Beispiel führt für eine Auswahl der in der Task befindlichen Dateien nachein­
+ander die Kommandos 'edit', 'lineform', 'pageform' und 'print' aus. 
+ 
+Die benutzten Operatoren und Prozeduren leisten folgendes: 
+ 
+#ix("SOME")# 
+   #on("b")#THESAURUS OP SOME (TASK CONST task) #off("b")# 
+   Der Operator bietet das Verzeichnis der in der angegeben Task befindlichen
+   Dateien zum Editieren an. Namen, die nicht gewünscht sind, müssen aus dem
+   Verzeichnis gelöscht werden. 
+ 
+ 
+#ix("get")# 
+   #on("b")#PROC get (THESAURUS CONST t, TEXT VAR name, INT VAR index) 
+   #off("b")# Die Prozedur liefert den nächsten Eintrag aus dem angegebenen Thesaurus 't'.
+   'Nächster' heißt hier, der kleinste vorhandene mit einem Index größer als 'index'.
+   Dabei wird in 'name'der Name und in 'index'der Index des Eintrags geliefert. 
+#page# 
+ 
+2.9.3  Datenräume 
+ 
+Datenräume sind die Grundlage von Dateien im EUMEL-System. Einen Datenraum
+kann man sich als eine Sammlung von Daten vorstellen (u.U. leer). Man kann einem
+Datenraum durch ein Programm einen Datentyp "aufprägen". Nach einem solchen
+"Aufpräge"-Vorgang kann der Datenraum wie ein "normaler" Datentyp behandelt
+werden. 
+ 
+Standarddateien (FILEs) sind eine besondere Form von Datenräumen. Sie können nur
+Texte aufnehmen, da sie ja hauptsächlich für die Kommunikation mit dem Menschen
+(vorwiegend mit Hilfe des Editors bzw. Ein-/ Ausgabe) gedacht sind. Will man Zahlen
+in einen FILE ausgeben, so müssen diese zuvor in Texte umgewandelt werden. Hier­
+für stehen Standardprozeduren zur Verfügung (z.B. 'put (f, 17)'). 
+ 
+Will man aber Dateien zur Kommunikation zwischen Programmen verwenden, die
+große Zahlenmengen austauschen, verursachen die Umwandlungen von Zahlen in
+TEXTe und umgekehrt unnötigen Rechenaufwand. Zu diesem Zweck werden im
+EUMEL-System Datenräume eingesetzt, die es gestatten, beliebige Strukturen
+(Typen) in Dateien zu speichern. Solche Datenräume kann man weder mit dem Editor
+noch mit dem Standarddruckprogramm (print) bearbeiten, da diese ja den Typ des in
+dem Datenraum gespeicherten Objektes nicht kennen. 
+ 
+ 
+ 
+2.9.3.1  Datentyp DATASPACE 
+ 
+Datenräume können als eigener Datentyp (DATASPACE) in einem Programm behan­
+delt werden. Somit können Datenräume (als Ganzes) ohne Kenntnis eines eventuell
+(vorher oder später) aufgeprägten Typs benutzt werden. 
+ 
+Als Operationen auf DATASPACE-Objekte sind nur Transporte, Löschen und Zuwei­
+sung zugelassen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ DATASPACE VAR ds 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Für Datenräume ist die Zuweisung definiert. Der Zuweisungsoperator (':=') bewirkt
+eine Kopie des Datenraums vom rechten auf den linken Operanden. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ DATASPACE VAR datenraum :: nilspace; 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Prozedur 'nilspace' liefert einen leeren Datenraum. Der Datenraum 'datenraum' ist
+also eine Kopie des leeren Datenraums. 
+ 
+Die Prozeduren und Operatoren für Datenräume werden im Teil 5.4.7 beschrieben. 
+#page# 
+ 
+2.9.3.2  BOUND-Objekte 
+ 
+Wie bereits erwähnt, kann man einem Datenraum einen Datentyp aufprägen. Dazu
+werden #ib#BOUND#ie#-Objekte benutzt. Mit dem Schlüsselwort #on("i")##on("b")#BOUND#off("i")##off("b")#, welches in der
+Deklaration vor den Datentyp gestellt wird, teilt man dem ELAN-Compiler mit, daß
+die Werte eines Datentyps in einem Datenraum gespeichert sind bzw. gespeichert
+werden sollen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ BOUND ROW 1000 REAL VAR liste 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Ankopplung des BOUND-Objekts an eine Datei erfolgt mit dem Operator #on("i")##on("b")#:=#off("i")##off("b")#. 
+ 
+Form: 
+ 
+BOUND-Objekt #on("i")##on("b")#:=#off("i")##off("b")# Datenraum 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ BOUND ROW 1000 REAL VAR gehaltsliste := new ("Gehälter") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Prozedur 'new' kreiert dabei einen leeren Datenraum (hier mit dem Namen 'Ge­
+hälter'), der mit Hilfe der Zuweisung (hier: Initialisierung) an die Variable 'gehaltsliste'
+gekoppelt wird. 
+ 
+Nun kann man mit der 'gehaltsliste' arbeiten wie mit allen anderen Feldern auch. Die
+Daten, die in 'gehaltsliste' gespeichert, werden eigentlich im Datenraum 'Gehälter'
+abgelegt. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ gehaltsliste [5] := 10 000.0;           (* Traumgehalt *) 
+ gehaltsliste [index] INCR 200.0;        (* usw.        *) 
+  
+____________________________________________________________________________ 
+ 
+ 
+Man kann auch Prozeduren schreiben, die auf der Gehaltsliste arbeiten. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PROC sort (ROW 1000 REAL VAR liste): 
+ ... 
+ END PROC sort; 
+ ... 
+ sort (CONCR (gehaltsliste)); 
+ ... 
+  
+____________________________________________________________________________ 
+ 
+ 
+Man beachte, daß der formale Parameter der Prozedur 'sort' nicht mit BOUND spezi­
+fiziert werden darf (BOUND wird nur bei der Deklaration des Objekts angegeben). Das
+ist übrigens ein weiterer wichtiger Vorteil von BOUND-Objekten: man kann alle
+Prozeduren des EUMEL-Systems auch für BOUND-Objekte verwenden, nur die
+Datentypen müssen natürlich übereinstimmen. 
+ 
+ 
+Häufige Fehler bei der Benutzung von Datenräumen 
+ 
+-  Wenn man an ein DATASPACE-Objekt zuweist (z.B.: DATASPACE VAR ds :=
+   new ("mein datenraum")), so erhält man, wie bereits erwähnt, eine Kopie des
+   Datenraums in 'ds'. Koppelt man jetzt 'ds' an ein BOUND-Objekt an und führt
+   Änderungen durch, so wirken diese nur auf die Kopie und nicht auf die Quelle.
+   Für Änderungen in der Quelle, also in der vom Datei-Manager verwalteten Datei,
+   ist stets direkt anzukoppeln. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ BOUND ROW 10 INT VAR reihe; 
+ INT VAR i; 
+ 
+ PROC zeige dsinhalt (TEXT CONST datenraum): 
+    BOUND ROW 10 INT VAR inhalt := old (datenraum); 
+    INT VAR j; 
+    line; 
+    putline ("Inhalt:" + datenraum); 
+    FOR j FROM 1 UPTO 10 REP 
+       put (inhalt (j)) 
+    PER 
+ END PROC zeige dsinhalt; 
+ 
+ (*  falsch: es wird auf der Kopie gearbeitet:           *) 
+ DATASPACE VAR ds := new ("Gegenbeispiel: Zahlen 1 bis 10"); 
+ reihe := ds; 
+ besetze reihe; 
+ zeige dsinhalt ("Gegenbeispiel: Zahlen 1 bis 10"); 
+ 
+ (*  richtig: es wird auf dem Datenraum gearbeitet:      *) 
+ reihe := new ("Beispiel: Zahlen 1 bis 10"); 
+ besetze reihe; 
+ zeige dsinhalt ("Beispiel: Zahlen 1 bis 10"). 
+ 
+ besetze reihe: 
+    FOR i FROM 1 UPTO 10 REP 
+       reihe (i) := i 
+    PER. 
+  
+____________________________________________________________________________ 
+ 
+ 
+   Der Datenraum 'Gegenbeispiel: Zahlen 1 bis 10' wird nicht mit Werten besetzt,
+   sondern die Kopie dieses Datenraums, der unbenannte Datenraum 'ds'. Auf dem
+   direkt angekoppelten Datenraum 'Beispiel: Zahlen 1 bis 10' werden die Werte
+   gespeichert. 
+ 
+ 
+-  Wenn man ein DATASPACE-Objekt benutzt, ohne den Datei-Manager zu
+   verwenden, so muß man selbst dafür sorgen, daß dieses Objekt nach seiner
+   Benutzung wieder gelöscht wird. Das Löschen geschieht durch die Prozedur
+   'forget'. Ein automatisches Löschen von DATASPACE-Objekten erfolgt nicht bei
+   Programmende (sonst könnten sie ihre Funktion als Datei nicht erfüllen). Nur
+   durch 'forget' oder beim Löschen einer Task werden alle ihr gehörenden
+   DATASPACE-Objekte gelöscht und der belegte Speicherplatz freigegeben. 
+ 
+ 
+-  Ferner ist zu beachten, daß vor der Ankopplung an ein BOUND-Objekt das
+   DATASPACE-Objekt initialisiert wird (im Normalfall mit 'nilspace'). 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ DATASPACE VAR ds :=  nilspace; 
+ BOUND ROW 1000 REAL VAR real feld := ds; 
+ .... 
+ real feld [index] := wert; 
+ .... 
+ forget (ds) (* Datenraum löschen, 
+                damit der Platz wieder verwendet wird *) 
+  
+____________________________________________________________________________ 
+ 
+ 
+-  Will man auf die Feinstruktur eines BOUND-Objekts zugreifen, so muß man
+   strenggenommen den Konkretisierer benutzen: 
+ 
+   Form: 
+ 
+   #on("i")##on("b")#CONCR#off("i")##off("b")# #on("i")##on("b")#(#off("i")##off("b")# Ausdruck #on("i")##on("b")#)#off("i")##off("b")# 
+ 
+   Der Konkretisierer ermöglicht eine typmäßige Umbetrachtung vom BOUND-Objekt
+   zum Datentyp der Feinstruktur. Ist der Zugriff jedoch eindeutig, so wird 'CONCR'
+   automatisch vom Compiler ergänzt. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ BOUND INT VAR i := old ("i-Wert"); 
+ INT VAR x; 
+ x := wert. 
+ 
+ wert: 
+    IF x < 0 
+      THEN 0 
+      ELSE CONCR (i) 
+    FI. 
+  
+____________________________________________________________________________ 
+ 
+ 
+In diesem Beispiel muß der Konkretisierer benutzt werden, da sonst der Resultattyp
+des Refinements nicht eindeutig ist (BOUND oder INT?). 
+ 
+ 
+ 
+2.9.3.3  Definition neuer Dateitypen 
+ 
+Durch die Datenräume und die Datentyp-Definition von ELAN ist es für Programmie­
+rer relativ einfach, neue Datei-Datentypen zu definieren. In der Regel reicht der
+Datentyp FILE für "normale" Anwendungen aus, jedoch kann es manchmal sinnvoll
+und notwendig sein, neue Datei-Typen für spezielle Aufgaben zu definieren. 
+ 
+In diesem Abschnitt soll an dem Beispiel DIRFILE (welcher zwar im ELAN-Standard
+definiert, aber nicht im EUMEL-System realisiert ist) gezeigt werden, wie ein neuer
+Datei-Datentyp definiert wird: 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PACKET dirfiles DEFINES DIRFILE, :=, dirfile, getline, ...: 
+ 
+ LET maxsize = 1000; 
+ 
+ TYPE DIRFILE = BOUND ROW maxsize TEXT; 
+ (* DIRFILE besteht aus TEXTen; Zugriff erfolgt ueber einen
+    Schluessel, der den Index auf die Reihung darstellt *) 
+ 
+ OP := (DIRFILE VAR dest, DATASPACE CONST space): 
+    CONCR (dest) := space 
+ END OP :=; 
+ 
+ DATASPACE PROC dirfile (TEXT CONST name): 
+    IF exists (name) 
+       THEN old (name) 
+       ELSE new (name) 
+    FI 
+ END PROC dirfile; 
+ 
+ PROC getline (DIRFILE CONST df, INT CONST index, 
+               TEXT VAR record): 
+    IF index <= 0 
+       THEN errorstop ("access before first record") 
+    ELIF index > maxsize 
+       THEN errorstop ("access after last record") 
+       ELSE record := df [index] 
+    FI 
+ END PROC getline; 
+ 
+ PROC putline (DIRFILE CONST df, INT CONST index, 
+               TEXT VAR record): 
+    ... 
+ END PROC putline; 
+ 
+ ... 
+ END PACKET dirfiles; 
+  
+____________________________________________________________________________ 
+ 
+ 
+Die Prozedur 'dirfile' ist die Assoziierungsprozedur für DIRFILEs (analog 'sequential
+file' bei FILEs). 'dirfile' liefert entweder einen bereits vorhandenen Datenraum oder
+richtet einen neuen ein. Um eine Initialisierung mit der 'dirfile'-Prozedur vorneh­
+men zu können, braucht man auch einen Zuweisungsoperator, der den Datenraum an
+den DIRFILE-Datentyp koppelt. 
+ 
+Zugriffe auf einen DIRFILE sind nun relativ einfach zu schreiben. Im obigen Beispiel
+wird nur die Prozedur 'getline' gezeigt. 
+ 
+Nun ist es möglich, Programme zu schreiben, die den DIRFILE-Datentyp benut­
+zen. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ DIRFILE VAR laeufer :: dirfile ("Nacht von Borgholzhausen"); 
+ INT VAR nummer; 
+ TEXT VAR name; 
+ 
+ REP 
+    put ("Startnummer bitte:"); 
+    get (nummer); 
+    line; 
+    put ("Name des Laeufers:"); 
+    get (name); 
+    putline (laeufer, nummer, name); 
+    line 
+ UNTIL no ("weiter") END REP; 
+ ... 
+  
+____________________________________________________________________________ 
+#page# 
+ 
+2.9.4  Datentyp INITFLAG 
+ 
+Im Multi-User-System ist es oft notwendig, Pakete beim Einrichten einer neuen
+Task in dieser neu zu initialisieren. Das muß z.B. bei der Dateiverwaltung gemacht
+werden, da die neue Task ja nicht die Dateien des Vaters erbt. Mit Hilfe von
+INITFLAG-Objekten kann man zu diesem Zweck feststellen, ob ein Paket in dieser
+Task schon initialisiert wurde. 
+ 
+ 
+INITFLAG 
+   #on("b")#TYPE INITFLAG #off("b")# 
+   Erlaubt die Deklaration entsprechender Flaggen. 
+ 
+:= 
+   #on("b")#OP := (INITFLAG VAR flag, BOOL CONST flagtrue) #off("b")# 
+   Erlaubt die Initialisierung von INITFLAGs 
+ 
+initialized 
+   #on("b")#BOOL PROC initialized (INITFLAG VAR flag) #off("b")# 
+   Wenn die Flagge in der Task A auf TRUE oder FALSE gesetzt wurde, dann liefert
+   sie beim ersten Aufruf den entsprechenden Wert, danach immer TRUE (in der
+   Task A!). 
+ 
+   Beim Einrichten von Söhnen wird die Flagge in den Sohntasks automatisch auf
+   FALSE gesetzt. So wird erreicht, daß diese Prozedur in den neu eingerichteten
+   Söhnen und Enkeltasks genau beim ersten Aufruf FALSE liefert. 
+ 
+____________________________________________________________________________ 
+ ........................... Beispiel: ......................... 
+ PACKET stack DEFINES push, pop: 
+ 
+ INITFLAG VAR in this task := FALSE ; 
+ INT VAR stack pointer ; 
+ ROW 1000 INT VAR stack ; 
+ 
+ PROC push (INT CONST value) : 
+ 
+    initialize stack if necessary ; 
+    .... 
+ 
+ END PROC push ; 
+ 
+ PROC pop (INT VAR value) : 
+ 
+    initialize stack if necessary ; 
+    .... 
+ 
+ END PROC pop ;. 
+ 
+ initialize stack if necessary : 
+ IF NOT initialized (in this task) 
+    THEN stack pointer := 0 
+ 
+ FI . 
+ 
+ END PACKET stack 
+____________________________________________________________________________ 
+
diff --git a/doc/programming/programmierhandbuch.3 b/doc/programming/programmierhandbuch.3
new file mode 100644
index 0000000..eade335
--- /dev/null
+++ b/doc/programming/programmierhandbuch.3
@@ -0,0 +1,728 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 3 : Editor","3")# 
+#pagenr("%",1)##setcount##block##pageblock# 
+#headeven# 
+#center#EUMEL-Benutzerhandbuch 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#TEIL 3 : Editor 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+3 - % #right#GMD 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+GMD #right#3 - % 
+#end# 
+
+TEIL 3:  Der Editor 
+ 
+Mit dem #ib#EUMEL-Editor#ie# steht für den Teil der Programmierung, der aus der Eingabe
+von Programmtext besteht, dasselbe komfortable Werkzeug zur Verfügung, wie für die
+Textverarbeitung. Merkmale des EUMEL-Editors sind die einfache Fenstertechnik
+und die übersichtliche Bedienung durch wenige Funktionstasten. 
+ 
+Eine mit dem Editor erzeugte Textdatei ist maximal 4075 Zeilen lang, die maximale
+Breite einer Zeile beträgt 16000 Zeichen. 
+ 
+ 
+ 
+3.1  Ein- und Ausschalten des Editors 
+ 
+Der Editor wird eingeschaltet durch Eingabe von: 
+ 
+____________________________________________________________________________ 
+    gib kommando : 
+    #ib#edit#ie# ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Falls eine Datei unter dem eingegebenen Namen existiert, wird ein Fenster auf dieser
+Datei an der Stelle geöffnet, an der zuletzt ein Zugriff auf diese Datei stattfand. 
+ 
+Existiert noch keine Datei unter dem angegebenen Namen in der Task, folgt eine
+Anfrage, ob eine Datei unter dem eingegebenen Namen neu eingerichtet werden soll: 
+ 
+____________________________________________________________________________ 
+    gib kommando : 
+    edit("dateiname") 
+    "dateiname" neu einrichten (j/n) ? 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Abfrage dient der Kontrolle der Schreibweise. Man kann ggf. das Einrichten der
+Datei ablehnen, den Dateinamen verbessern und das Kommando erneut geben. 
+ 
+Bei korrekter Schreibweise bejahen Sie die Kontrollfrage#u# 1)#e#mit 
+ 
+#center#<j> <J> <y> oder <Y> 
+ 
+ 
+Es erscheint ein leerer Editorbildschirm. Die oberste Zeile des Bildschirms ist die
+#ib#Titelzeile#ie#. In ihr kann nicht geschrieben werden. Sie zeigt jedoch verschiedene nütz­
+liche Dinge an: den Namen der Datei, die Nummer der aktuellen Zeile, in der gerade
+geschrieben wird, Tabulatormarken, Einfügemodus, Lernmodus usw. 
+ 
+____________________________________________________________________________ 
+ #mark on# ............... dateiname ....................#mark off# Zeile 1  #mark on#  #mark off# 
+ _ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Wollen Sie die #ib#Schreibarbeit beenden#ie# und den #ib#Editor ausschalten#ie#, so drücken Sie die
+beiden Tasten 
+ 
+<ESC> <q> 
+ 
+nacheinander. Sie haben damit den #ib#Editor verlassen#ie# und befinden sich wieder auf
+Monitor-Ebene. 
+#page# 
+
+3.2  Die Funktionstasten 
+ 
+Die Funktionstasten realisieren diejenigen Fähigkeiten des Editor, die über die reine
+Zeicheneingabe hinausgehen. Wo die Tasten auf Ihrem Gerät liegen, hängt von dem
+jeweiligen Gerätetyp ab. Die Wirkung der Tasten ist im Weiteren erläutert. 
+ 
+#l pos (0.0)##l pos(4.0)# 
+#table# 
+#free(0.5)# 
+#taste1(" SHIFT ")#           Umschalttaste 
+#tableend# 
+#free(0.5)# 
+<v> <^> <>> <<>            Positionierungstasten 
+#table# 
+#free(0.5)# 
+<CR>              Eingabe-/ Absatztaste 
+#free(0.5)# 
+<ESC>             Kommandotaste 
+#free(0.5)# 
+<HOP>             Verstärkertaste 
+#free(0.5)# 
+<TAB>             Tabulatortaste 
+#free(0.5)# 
+<MARK>            Markiertaste 
+#free(0.5)# 
+<RUBOUT>          Löschtaste 
+#free(0.5)# 
+<RUBIN>           Einfügetaste 
+#free(0.5)# 
+<SV>              Supervisortaste 
+#free(0.5)# 
+<STOP>            Stoptaste 
+#free(0.5)# 
+<WEITER>          Weitertaste 
+#tableend##clear pos# 
+#free(0.5)# 
+Es kann sein, daß Tasten nicht richtig beschriftet sind. Die Installations-anleitung
+muß dann die Entsprechungen beschreiben. Natürlich können sich weitere Funktions­
+tasten außer den im folgenden beschriebenen auf Ihrer Tastatur befinden. Diese
+haben standardmäßig jedoch keine besondere Bedeutung für den Editor. 
+ 
+#page# 
+
+3.3  Die Wirkung der Funktionstasten 
+ 
+<SHIFT> 
+ 
+#ib#Umschalttaste#ie# 
+ 
+Wird diese Taste gleichzeitig mit einer anderen betätigt, so wird ein Buchstabe in
+Großschreibung, bei den übrigen Tasten das obere Zeichen, ausgegeben. So wird z.B.
+anstelle der "9" das Zeichen ")" ausgegeben. 
+#free(0.5)# 
+<>> <<> 
+ 
+<v> <^> 
+ 
+Positionierungstasten 
+ 
+#ib#Positionierung des Cursors#ie# um eine Spalten-/Zeilenposition in die jeweilige Richtung. 
+#free(0.5)# 
+<CR> 
+ 
+#ib#Eingabetaste / Absatztaste#ie#, Carriage Return, kurz: 'CR' 
+ 
+Diese Taste schließt die aktuelle Zeile explizit ab und es wird an den Beginn der
+nächsten Zeile positioniert. Einrückungen werden beibehalten. 
+ 
+Der EUMEL-Editor ist auf automatischen Wortumbruch voreingestellt, d.h. ein Wort,
+das über das 77. Zeichen der aktuellen Zeile herausreichen würde, wird automatisch
+in die nächste Zeile gerückt (siehe 'word wrap' 4.2.5). Die Absatztaste wird also
+benötigt, um explizite Zeilenwechsel und Einrückungen bei der Textformatierung zu
+erhalten. Eine Absatzmarke wird durch ein 'blank' hinter dem letzten Zeichen der
+Zeile erzeugt und ist im Editor an der Inversmarkierung am rechten Bildschirmrand zu
+erkennen. 
+ 
+Im EUMEL-System werden Kommandos auf einer Kommandozeile, auf der alle
+Editorfunktionen zur Verfügung stehen, eingegeben. Auf dieser Ebene beendet die
+Taste also ausdrücklich die Kommandoeingabe, das gegebene Kommando wird an­
+schließend analysiert und ausgeführt. 
+ 
+<HOP> 
+ 
+"#ib#Verstärkertaste#ie#"; wird als Vorschalttaste bedient. 
+ 
+In Kombination mit anderen Funktionstasten wird deren Wirkung verstärkt. 
+ 
+ 
+<HOP> <v> 
+ 
+Steht der Cursor nicht am unteren Bildrand, so wird er dorthin positioniert. Steht er
+am unteren Bildrand, so wird um einen Bildschirminhalt "weitergeblättert". 
+ 
+Entsprechend werden auch die Tasten : <^> <>> <<> mit der HOP-Taste verstärkt. 
+ 
+#page# 
+<HOP> <RUBIN> 
+ 
+#ib#Einfügen von Textpassagen#ie#. Die HOP-Taste in Verbindung mit RUBIN und RUBOUT
+wird zum 'verstärkten' Löschen und Einfügen verwendet. 
+ 
+Ab der aktuellen Position des Cursors 'verschwindet' der restliche Text. Es kann wie
+bei der anfänglichen Texteingabe fortgefahren werden. Die Anzeige '#ib#REST#ie#' in der
+Titelzeile erinnert daran, daß noch ein Resttext existiert. Dieser erscheint nach einem
+neuerlichen Betätigen der beiden Tasten HOP RUBIN wieder auf dem Bildschirm (die
+Anzeige 'REST' verschwindet dann wieder). 
+ 
+____________________________________________________________________________ 
+   ................ dateiname ..................... Zeile 4     
+  In diesem Text soll vor dem zweiten Satz  
+  etwas eingefügt werden. Hierzu wird der 
+  Cursor an die Position geführt, an der  
+  ein beliebiger Text eingefügt werden soll.#absatz# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nach Betätigen der Taste #on("i")##on("b")#HOP#off("i")##off("b")# und #on("i")##on("b")#RUBIN#off("i")##off("b")#sieht der Bildschirm wie folgt aus: 
+ 
+____________________________________________________________________________ 
+   .............. dateiname ........REST.......... Zeile 4     
+  In diesem Text soll vor dem zweiten Satz  
+  etwas eingefügt werden. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Nun kann beliebig viel Text eingefügt werden. Nochmaliges Betätigen von HOP und
+RUBIN führt den Text-Rest wieder bündig heran. 
+ 
+#page# 
+<HOP>  <RUBOUT> 
+ 
+Löscht die Zeile ab Cursor-Position bis Zeilenende. 
+ 
+____________________________________________________________________________ 
+   ................ dateiname ..................... Zeile 4     
+  Soll eine ganze Zeile oder ein Textrest  
+  gelöscht werden, so positioniert man an die  
+  Stelle, ab der gelöscht werden soll. Rest löschen.... 
+  Nach HOP RUBOUT ist der Zeilenrest gelöscht.#absatz# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Nach Betätigen der Tasten #on("i")##on("b")#HOP#off("i")##off("b")# und #on("i")##on("b")#RUBOUT#off("i")##off("b")# sieht der Bildschirm wie folgt aus. 
+ 
+____________________________________________________________________________ 
+   ............... dateiname .................... Zeile 4     
+  Soll eine ganze Zeile oder ein Textrest  
+  gelöscht werden, so positioniert man an die  
+  Stelle, ab der gelöscht werden soll. 
+  Nach HOP RUBOUT ist der Zeilenrest gelöscht.#absatz# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Steht der Cursor am Zeilenanfang, wird nach HOP RUBOUT dementsprechend die
+ganze Zeile gelöscht und die Lücke durch Nachrücken der Folgezeilen geschlossen
+(HOP RUBOUT betätigen). 
+#page# 
+<TAB> 
+ 
+#ib#Tabulatortaste#ie# 
+ 
+Mit der Tabulatortaste werden die eingestellten Tabulatorpositionen angesprungen.
+Jeder Tastendruck läßt den Cursor auf die nächste eingestellte Tabulatorposition
+springen. 
+ 
+#on("i")#Voreingestellte#off("i")# Tabulatorpositionen sind die beiden Schreibgrenzen, Textanfang in der
+Zeile und Ende der Zeile. 
+ 
+Weitere Tabulatorpositionen können durch Positionierung auf die gewünschte Spalte
+und #on("i")##on("b")#HOP#off("i")##off("b")# #on("i")##on("b")#TAB#off("i")##off("b")# gesetzt werden. Sie können gelöscht werden, indem sie mit #on("i")##on("b")#TAB#off("i")##off("b")#
+angesprungen und mit #on("i")##on("b")#HOP#off("i")##off("b")# #on("i")##on("b")#TAB#off("i")##off("b")# 
+ausgeschaltet werden. 
+ 
+Die gesamte eingestellte Tabulalation kann durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#TAB#off("i")##off("b")# ein-/ und ausge­
+schaltet werden. 
+ 
+Die eingestellten Tabulatorpositionen erkennen Sie an den Tabulatorzeichen (Dachzei­
+chen) in der obersten Bildschirmzeile. 
+#page# 
+<MARK> 
+ 
+#ib#Ein- bzw. Ausschalten der Markierung#ie#. 
+ 
+Bei Betätigung dieser Taste wird in einen speziellen #ib#Markierzustand#ie# geschaltet. Alles,
+was Sie jetzt schreiben bzw. durch Bewegen des Cursors in Richtung Dateiende
+kennzeichnen, steht als #on("i")#markierter#off("i")# Bereich für die Bearbeitung zur Verfügung. Zur
+besseren Sichtbarkeit wird der markierte Bereich invers zum übrigen Text dargestellt. 
+ 
+Wird der Cursor in eine Richtung bewegt, wird das gesamte Textstück zwischen
+Einschaltpunkt der Markierung und aktueller Cursorposition markiert. Rückwärtsbewe­
+gungen des Cursors verkürzen den markierten Bereich wieder. 
+ 
+Durch erneutes Betätigen der MARK-Taste schalten Sie den Markier-Zustand
+wieder aus. 
+ 
+Mit weiteren Kommandos kann der Bereich nun bearbeitet werden: 
+ 
+<ESC>  <d>         Markierten Abschnitt in 'Scratch'-Datei kopieren. 
+ 
+<ESC>  <p>         Markierten Abschnitt herauskopieren. 
+ 
+<ESC>  <RUBOUT>    Markierten Abschnitt löschen. 
+ 
+ 
+Der mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#p#off("i")##off("b")# oder#on("i")##on("b")#d#off("i")##off("b")# kopierte Bereich kann beliebig oft in derselben oder einer
+anderen Datei ein/angefügt werden. 
+ 
+Der mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#RUBOUT#off("i")##off("b")# gelöschte Abschnitt kann genau einmal durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#RUBOUT#off("i")##off("b")#
+an anderer Stelle derselben Datei eingefügt werden. 
+ 
+(vgl. ESC-Taste, Operationen auf Markierungen, 3-#topage("ESC")#) 
+#page# 
+<RUBIN> 
+ 
+#ib#Ein- bzw. Ausschalten des Einfügemodus.#ie# 
+ 
+Das Betätigen der Taste schaltet in den Einfügemodus. Der Zustand wird durch das
+Wort "RUBIN" im linken Drittel der Titelzeile der Datei angezeigt. Vor dem Zeichen,
+auf dem der Cursor steht, wird eingefügt. Nochmaliges Betätigen der Taste schaltet
+den Einfügemodus aus. 
+#free(1.0)# 
+<RUBOUT> 
+ 
+#ib#Löschtaste#ie# 
+ 
+Das Zeichen, auf dem der Cursor steht, wird gelöscht. Wenn der Cursor, wie bei
+fortlaufender Eingabe üblich, hinter dem letzten Zeichen einer Zeile steht, wird das
+letzte Zeichen gelöscht. 
+ 
+#page# 
+
+3.4  ESC Kommandos 
+ 
+<ESC> 
+ 
+#ib#Kommandotaste#ie# 
+ 
+Mit der ESC-Taste in Kombination mit einer Folgetaste werden vordefinierte Aktionen
+ausgelöst. Es gibt Aktionen, die vorprogrammiert zur Verfügung stehen, und Sie selbst
+können weitere hinzufügen. 
+ 
+Der Kommandodialog wird eingeschaltet durch: 
+ 
+<ESC> <ESC> 
+ 
+ 
+____________________________________________________________________________ 
+  ............... Beispiel ..................... Zeile 4     
+ 
+  gib kommando:                                              
+ 
+____________________________________________________________________________ 
+ 
+ 
+Der Kommandodialog ermöglicht die Eingabe von beliebigen Kommandos ohne den
+Editor verlassen zu müssen. Insbesondere Such- und Kopieroperationen stellen auch
+für den Programmierer nützliches Werkzeug dar (siehe 3.5). 
+ 
+Auf der Kommandozeile kann jedes Kommando gegeben werden. Die Kommandozeile
+kann wie eine normale Textzeile editiert werden. Nach #on("i")##on("b")#CR#off("i")##off("b")# verschwindet die Kom­
+mandozeile und das Kommando wird ausgeführt. 
+ 
+Falls ein Fehler auftritt erfolgt eine entsprechende Fehlermeldung in der Kopfzeile und
+die Kommandozeile erscheint erneut. 
+ 
+Um ein weiteres Editor-Fenster zu 'öffnen', betätigt man im Editor 
+ 
+<ESC>  <e> 
+ 
+Betätigt man ESC e ungefähr in der Mitte des Bildschirms, hat man das Fenster auf
+die neue Datei in der unteren Hälfte des Bildschirms und die 'alte' Datei in der
+oberen Bildschirmhälfte. Zunächst wird der Dateiname erfragt. Nach dessen Eingabe
+und #on("i")##on("b")#CR#off("i")##off("b")# wird ein Fenster auf eröffnet. Die obere linke Ecke des Fensters befindet
+sich an der aktuellen Cursor-Position. Dabei darf sich der Cursor nicht zu sehr am
+rechten oder unteren Rand befinden, weil das Fenster sonst zu klein würde. In diesem
+'Fenster' kann man dann genauso arbeiten wie im 'normalen' Editor. 
+ 
+Mit der Tastenfolge 
+ 
+<ESC>  <w> 
+ 
+wechselt man von einem Fenster (zyklisch) in das benachbarte. Es gibt eine Hier­
+archie zwischen den Fenstern in der Reihenfolge, in der eines im anderen einge­
+richtet worden ist. Gibt man 
+ 
+<ESC>  <q> 
+ 
+in einem Fenster, so verschwindet dieses und alle darin eingeschachtelten Fenster,
+und man befindet sich im übergeordneten Fenster. 
+ 
+Durch 
+ 
+<ESC>  <p>  oder   <ESC>  <d> 
+ 
+schreibt man einen markierten Teil in eine 'Scratch'-Datei (nicht editierbarer
+Zwischenspeicher); durch ESC p wird ein markierter Text aus der Ursprungsdatei
+entfernt und in die 'Scratch'-Datei geschrieben. Im Gegensatz dazu wird er durch
+ESC d kopiert. Durch 
+ 
+<ESC>  <g> 
+ 
+fügt man ihn in eine andere (oder dieselbe) Datei ein. Im Unterschied zu ESC RUBIN
+wird die temporäre Datei dadurch nicht entleert. 
+ 
+Die für ESC p, bzw. ESC d benutzte #ib#'Scratch'-Datei#ie#, die nicht editierbar ist, ist nicht
+mit dem sogenannten Notizbuch zu verwechseln. Das Notizbuch ist eine Datei, in der
+alle Editorfunktionen benutzt werden können, auf die jedoch ohne Angabe eines
+Dateinamens durch 
+ 
+<ESC> <n> 
+ 
+ab der aktuellen Cursorposition ein Fenster eröffnet wird. Das Notizbuch nimmt
+insbesondere Fehlermeldungen und Meldungen bei der Übersetzung von Programmen
+auf. 
+ 
+<ESC> <v> 
+ 
+erlaubt vom äußeren Fenster aus alle eingeschachtelten Fenster zu verlassen. 
+#page# 
+
+Vorbelegte Tasten 
+ 
+#ib#ESC q#ie#          Verlassen des Editors bzw. der eingeschachtelten Fenster. 
+ 
+#ib#ESC e#ie#          Weiteres Editorfenster einschalten. 
+ 
+#ib#ESC n#ie#          Notizbuch 'anzeigen'. 
+ 
+#ib#ESC v#ie#          Dateifenster auf ganzen Bildschirm vergrößern 
+               bzw. Bildschirm rekonstruieren (eingeschachteltes Fenster verlas­
+               sen). 
+ 
+#ib#ESC w#ie#          Dateiwechsel beim Fenstereditor. 
+ 
+#ib#ESC f#ie#          Nochmalige Ausführung des letzten Kommandos. 
+ 
+#ib#ESC b#ie#          Das Fenster wird auf den linken Rand der aktuellen (ggf. verscho­
+               benen) Zeile gesetzt. 
+ 
+ESC  >         Zum nächsten Wortanfang. 
+ 
+ESC  <         Zum vorherigen Wortanfang. 
+ 
+#ib#ESC 1#ie#          Zum Anfang der Datei. 
+ 
+#ib#ESC 9#ie#          Zum Ende der Datei. 
+#page# 
+
+Operationen auf Markierungen 
+ 
+ 
+#goalpage("ESC")# 
+#ib#ESC RUBOUT#ie#     Markiertes "vorsichtig" löschen. 
+ 
+#ib#ESC RUBIN#ie#      Mit ESC RUBOUT vorsichtig Gelöschtes einfügen. 
+ 
+#ib#ESC p#ie#          Markiertes löschen und in die Notiz-Datei schreiben. Kann mit ESC
+               g an anderer Stelle reproduziert werden. 
+ 
+#ib#ESC d#ie#          Duplizieren: 
+               Markiertes in die Notiz-Datei kopieren, anschließend die
+               Markierung abschalten. Kann mit ESC g beliebig oft reproduziert
+               werden. 
+ 
+#ib#ESC g#ie#          Mit ESC p gelöschten oder mit ESC d duplizierten Text an aktuelle
+               Cursor-Stelle schreiben, d.h. Notiz-Datei an aktueller Stelle einfü­
+               gen. 
+#page# 
+
+Zeichen schreiben 
+Diese Tasten sind standardmäßig so vorbelegt wie hier aufgeführt, sie können aber
+von Benutzern und in Anwenderprogrammen geändert werden. 
+ 
+#ib#ESC a#ie#          Schreibt ein ä. 
+#ib#ESC A#ie#          Schreibt ein Ä. 
+#ib#ESC o#ie#          Schreibt ein ö. 
+#ib#ESC O#ie#          Schreibt ein Ö. 
+#ib#ESC u#ie#          Schreibt ein ü. 
+#ib#ESC U#ie#          Schreibt ein Ü. 
+#ib#ESC s#ie#          Schreibt ein ß. 
+#ib#ESC (#ie#          Schreibt eine [. 
+#ib#ESC )#ie#          Schreibt eine ]. 
+#ib#ESC <#ie#          Schreibt eine {. 
+#ib#ESC >#ie#          Schreibt eine }. 
+#ib#ESC \##ie#          Schreibt ein \#, das auch gedruckt werden kann. 
+#ib#ESC ­#ie#          Schreibt einen (geschützten) Trennstrich, siehe Textverarbeitung. 
+#ib#ESC k#ie#          Schreibt ein (geschütztes) "k", siehe Textverarbeitung. 
+#ib#ESC blank#ie#      Schreibt ein (geschütztes) Leerzeichen, siehe Textverarbeitung. 
+#free(0.7)# 
+
+Kommando auf Taste legen
+
+#ib#ESC ESC#ie#        Kommandodialog einschalten 
+ 
+#ib#ESC ! taste#ie#    Im Kommandodialog: 
+               Geschriebenes Kommando auf Taste legen. 
+ 
+#ib#ESC ? taste#ie#    Im Kommandodialog: 
+               Auf 'taste' gelegtes Kommando zum Editieren anzeigen. 
+ 
+#ib#ESC k#ie#          Im Kommandodialog: 
+               Das zuletzt editierte Kommando (einzeilige ELAN-Programm)
+               anzeigen. 
+ 
+ 
+Der Lernmodus 
+Der Lernmodus ermöglicht beliebige Tastensequenzen zu speichern und auf eine 
+Taste 't' zu legen. Durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#t#off("i")##off("b")# wird die gesamte Sequenz ausgeführt. 
+ 
+Nicht belegt werden können die vom System vorbelegten Tasten (3-14). 
+ 
+Beispielsweise könnte es für einen Programmierer sinnvoll sein die Tastenfolge 
+'THEN' 'CR' '>' '>' '>' '>' auf die Taste #on("i")##on("b")#T#off("i")##off("b")# zu legen. Durch #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#T#off("i")##off("b")# wird 'THEN' in
+die aktuelle Zeile geschrieben und der Cursor mit passender Einrückung in die 
+Einrückung in die Folgezeile gesetzt. 
+
+ 
+#ib#ESC HOP#ie#        #ib#Lernen einschalten#ie#. 
+ 
+#ib#ESC HOP taste#ie#  #ib#Lernen ausschalten#ie# und Lernsequenz auf 'taste'legen. 
+ 
+#ib#ESC HOP HOP#ie#    #ib#Gelerntes vergessen#ie#. Bedingung ist, daß man die Lernsequenz in
+                       der Task löscht, in der man sie hat lernen lassen. 
+ 
+ 
+#on("b")# 
+#center#A C H T U N G : 
+Der Lernmodus bleibt eingeschaltet, auch wenn der Editor beendet wird. Dann werden
+die folgenden Monitor-Kommandos usw. usf. 'gelernt'. Durch unsinniges 'Lernen'
+lassen sich schlimmstenfalls beliebige Verwüstungen anrichten. 
+ 
+Der Lernmodus wird in der Editor-Kopfzeile angezeigt. Falls der Editor beendet wird,
+ohne den Lernmodus auszuschalten, erfolgt eine Warnung auf Monitor-Ebene. 
+ 
+Um den Lernmodus zu beenden drücken Sie: 
+ 
+<ESC> <HOP> <HOP>  
+ 
+Dadurch wird der Lernmodus ausgeschaltet und nichts gelernt, die Gefahr ist gebannt.#off("b")# 
+ 
+#page# 
+<SV> 
+ 
+#ib#SUPERVISOR-Taste#ie# 
+ 
+Betätigen Sie diese Taste im Editor, dann unterbrechen Sie Ihre Editierarbeit und
+erhalten die Meldung 
+ 
+____________________________________________________________________________ 
+ 
+                                           Terminal 2  
+ 
+ 
+                      EUMEL Version 1.8/M 
+ 
+ 
+            gib supervisor kommando: 
+ 
+ 
+ 
+ 
+       ESC ? --> help 
+       ESC b --> begin("")            ESC h --> halt 
+       ESC c --> continue("")         ESC s --> storage info 
+       ESC q --> break                ESC t --> task info 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Wollen Sie nun im Editor fortfahren bzw. haben Sie irrtümlich die SV-Taste betätigt,
+dann geben Sie das Kommando 
+ 
+____________________________________________________________________________ 
+ 
+              gib supervisor kommmando : 
+              continue ("meine task") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+(falls Ihre Task, in der Sie arbeiteten, wirklich "meine task" hieß!) 
+ 
+Um Ihren in Bearbeitung befindlichen Text wieder vollständig auf dem Bildschirm zu
+sehen, betätigen die die Tasten 
+ 
+<ESC> <b> 
+ 
+Sie sind wieder an der Stelle, an der Sie den Text mit der SV-Taste verlassen ha­
+ben, und können normal weiterarbeiten. 
+ 
+#on("u")#Achtung:#off("u")# Die SV-Taste kann, je nach Terminal, durch das Betätigen von zwei
+Tasten gleichzeitig realisiert sein (oft 'CTRL b'). Beachten Sie die Beschreibung Ihrer
+Tastatur! 
+ 
+ 
+ 
+#on("b")# 
+Für die Programmierung ist die Tastenfolge <SV> <ESC> <h> von Bedeutung, da hier­
+durch der Fehler 'halt vom Terminal' erzeugt wird. Dadurch können unerwünscht
+laufende Programme abgebrochen werden. 
+#off("b")# 
+#page# 
+<STOP> 
+ 
+#ib#Unterbrechen einer Ausgabe#ie# (oft auch als CTRL a realisiert). 
+ 
+Haben Sie diese Taste aus Versehen betätigt, erkennen Sie dies daran, daß der
+Editor nicht "reagiert". Betätigen Sie die WEITER-Taste (oft auch CTRL c). 
+#free(1.0)# 
+<WEITER> 
+ 
+Unterbrochene Ausgabe fortsetzen. 
+ 
+Ein mit der STOP-Taste angehaltene Ausgabe können Sie durch Betätigen der
+#ib#WEITER-Taste#ie# fortsetzen. 
+ 
+ 
+#on("u")#VORSICHT:#off("u")#  Die STOP-Taste unterbricht nur die Ausgabe auf den Bildschirm. Zei­
+           chen, die während des STOP eingegeben werden, werden gespeichert
+           und nach 'WEITER' ausgegeben! 
+ 
+ 
+#page# 
+
+3.5  Positionieren, Suchen, Ersetzen 
+     im Kommandodialog
+      
+ 
+Um das Editorfenster auf eine bestimmte Zeile zu positionieren wird einfach diese
+Zeilennummer angegeben. 
+ 
+____________________________________________________________________________ 
+  ............... Beispiel ..................... Zeile 4     
+ 
+  gib kommando: 123                                           
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Falls die Zeilenzahl der Datei geringer als die angegebene Zeilennummer ist, wird auf
+die letzte Zeile positioniert. 
+ 
+ 
+Um das Editorfenster auf ein bestimmtes Textstück zu positionieren, wird der gesuch­
+te Text, ggf. mit Suchrichtung angegeben. 
+ 
+____________________________________________________________________________ 
+  ............... Beispiel ..................... Zeile 4     
+ 
+   gib kommando: "END PROC"                                   
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Suchrichtung kann durch 'D' (down) oder 'U' (up) zusätzlich spezifiziert werden. 
+ 
+____________________________________________________________________________ 
+  ............... Beispiel ..................... Zeile 4     
+ 
+  gib kommando: U "INT VAR schleifenzaehler"                  
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Um beliebige Texte durch andere zu ersetzen, dienen die Operatoren 'C' (change)
+bzw. 'CA' (change all). 
+ 
+Bei Ausführung dieses Kommandos wird zunächst nach #on("u")#unten#off("u")# in der editierten Datei
+nach dem zu ersetzenden Text gesucht. Wenn der Text gefunden wird, wird er durch
+den hinter dem Operator stehenden Text ersetzt. 
+ 
+____________________________________________________________________________ 
+  ............... Beispiel ..................... Zeile 4     
+ 
+  gib kommando: "lb" C "lange bezeichnung"                    
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Bei Anwendung von 'CA' wird jedes Auftreten des gesuchten Textes ab der
+Cursorposition durch den Ersatztext ersetzt, bis das Dateiende errreicht ist. 
+ 
+Weitere Erklärungen zum Suchen und Ersetzen in 5.5. 
+#page# 
+
+Weitere Hilfen 
+ 
+ 
+Textabschnitt an anderer Stelle der Datei einsetzen: 
+ 
+- Abschnitt markieren und mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#d#off("i")##off("b")# zwischenspeichern. 
+ 
+- Zweites Editorfenster auf die Datei mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#e#off("i")##off("b")# öffnen. 
+ 
+- Nach #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# Zeilennummer oder Suchbegriff angeben und mit #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#g#off("i")##off("b")# Abschnitt an der gewünschte Stelle einsetzen. 
+ 
+ 
+ 
+Textabschnitt schnell herauskopieren und sichern: 
+ 
+- Gewünschten Abschnitt markieren 
+ 
+- #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# PUT("dateiname") #on("i")##on("b")#CR#off("i")##off("b")# 
+  Der Abschnitt wird in die Datei 'dateiname' geschrieben. Falls die Frage 'dateina­
+  me' löschen (j/n) verneint wird, wird der Abschnitt, an das Ende der Datei angefügt.
+  Dadurch können Textabschnitte schnell gesammelt werden. 
+ 
+ 
+Komplette Datei in die editierte Datei einfügen: 
+ 
+- #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# GET("dateiname") #on("i")##on("b")#CR#off("i")##off("b")# 
+  Der komplette Inhalt von 'dateiname' wird an die aktuelle Position geschrieben. 
+ 
+ 
+Breitere Zeile erzeugen: 
+ 
+- #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# limit(123) #on("i")##on("b")#CR#off("i")##off("b")# 
+  Die Zeilenbreite wird auf 123 Zeichen geändert. Der maximal zulässige Wert ist
+  16000. Dieser Wert bezieht sich auf den Zeilenumbruch. Bei Zeilenbreite > 77 wird
+  nur die aktuelle Zeile verschoben. Um für den ganzen Bildschirm die rechte Seite
+  der Datei zu sehen, kann die linken Spalte des Bildschirmfenster neu gesetzt wer­
+  den: 
+ 
+  #on("i")##on("b")#ESC#off("i")##off("b")# #on("i")##on("b")#ESC#off("i")##off("b")# margin(60) #on("i")##on("b")#CR#off("i")##off("b")# 
+ 
+  Die Normaleinstellung wird durch 'limit(77)' und 'margin(1)' wiederhergestellt. 
+
diff --git a/doc/programming/programmierhandbuch.4 b/doc/programming/programmierhandbuch.4
new file mode 100644
index 0000000..650d945
--- /dev/null
+++ b/doc/programming/programmierhandbuch.4
@@ -0,0 +1,1692 @@
+#headandbottom("1","EUMEL-Benutzerhandbuch","TEIL 4 : Kommandosprache","4")# 
+#pagenr("%",1)##setcount(1)##block##pageblock# 
+#headeven# 
+#center#EUMEL-Benutzerhandbuch 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#TEIL 4 : Kommandosprache 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+4 - % #right#GMD 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+GMD #right#4 - % 
+#end# 
+TEIL 4:  Kommandosprache 
+ 
+In Teil 4 sind diejenigen Kommandos beschrieben, die erfahrungsgemäß eher der
+Handhabung der Arbeitsumgebung zuzurechnen sind. Es ist den Verfassern bewußt,
+daß Auswahl und Zusammenstellung recht willkürlich sind, weil eine klare Abgrenzung
+zum Teil 5, welcher die Kommandos, die dem Thema: 'Programmierung' zugeordnet
+werden, nicht möglich ist. 
+ 
+Der Teil 4 ist in die Themen: 
+ 
+- 4.1.                     Supervisor-Kommandos 
+ 
+- 4.2.1                    Hilfs- und Informationsprozeduren 
+ 
+- 4.2.2                    Thesaurus 
+ 
+- 4.2.3                    Tasks 
+ 
+- 4.2.4                    Handhabung von Dateien 
+ 
+- 4.2.5                    Editor 
+ 
+- 4.2.6                    Dateitransfer 
+ 
+- 4.2.7                    Passwortschutz 
+ 
+- 4.2.8                    Archiv 
+ 
+gegliedert. Insbesondere zu 4.2.4 ist anzumerken, daß nur Kommandos, die ganze
+Dateien betreffen hier erläutert sind. Kommandos, die Dateiinhalte betreffen (Suchen,
+Ersetzen etc.) sind in 3.5, bzw. 5.3 beschrieben. 
+#page# 
+
+4.1  Supervisor 
+ 
+Es gibt genau sieben vom Supervisor akzeptierte Kommandos. Diese Kommandos
+können gegeben werden wenn nach dem Einschalten des Geräts oder dem Abkoppeln
+einer Task die SV-Taste gedrückt wurde und die sogenannte EUMEL-Tapete
+erscheint. 
+ 
+____________________________________________________________________________ 
+ 
+                                           Terminal 2  
+ 
+ 
+                    EUMEL Version 1.8.1/M 
+ 
+ 
+        gib supervisor kommando: 
+          
+ 
+ 
+ 
+   ESC ? --> help 
+   ESC b --> begin("")            ESC h --> halt 
+   ESC c --> continue("")         ESC s --> storage info 
+   ESC q --> break                ESC t --> task info 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+Desweiteren kann <SV> in einer Task gedrückt werden, um durch <ESC> <h> einen
+Programmabbruch einzuleiten. 
+ 
+Im Gegensatz zu den im weiteren beschriebenen, durch ELAN Prozeduren realisierten
+Kommandos, sind diese Supervisor-Kommandos nicht als Prozeduren im System und
+mithin nicht durch 'help (...)' anzeigbar. 
+#page# 
+'begin' 
+   #on("b")#PROC begin (TEXT CONST taskname) #off("b")# 
+   Richtet eine neue Task als Sohn von PUBLIC ein. 
+ 
+ 
+   #on("b")#PROC begin (TEXT CONST taskname, vatertask) #off("b")# 
+   Richtet eine neue Task als Sohn der Task 'vatertask' ein, falls die Vater-Task
+   eine Manager-Task ist. Falls diese Task keinen Managerstatus besitzt, passiert
+   nichts! In diesem Falle muß das Kommando durch <SV> abgebrochen werden. 
+ 
+ 
+   FEHLER :  "taskname" existiert bereits 
+             "vatertask" gibt es nicht 
+ 
+ 
+ 
+ 
+'continue' 
+   #on("b")#PROC continue (TEXT CONST taskname) #off("b")# 
+   Eine existierende Task wird an das Terminal des Benutzers angekoppelt. 
+ 
+   FEHLER :  "taskname" gibt es nicht 
+ 
+ 
+   Falls 'begin' oder 'continue' trotz korrekter Voraussetzungen kein Resultat zeigen,
+   'hängt' die betroffene Task. Beim 'begin' Kommando kann das der Fall sein, falls
+   die Vater-Task nicht durch 'break' abgekoppelt wurde, sondern mit < SV > verlas­
+   sen wurde. In diesem Fall muß das Kommando durch <SV> abgebrochen werden,
+   die Vater-Task angekoppelt und mit <ESC> <q> korrekt abgekoppelt werden. 
+#page# 
+'break' 
+   #on("b")#PROC break #off("b")# 
+   Das Terminal wird vom Rechner abgekoppelt. 
+ 
+ 
+ 
+'halt' 
+   #on("b")#PROC halt #off("b")# 
+   Das laufende Programm der dem Terminal aktuell zugeordneten Task wird abge­
+   brochen. 
+ 
+   Falls in der an das Terminal gekoppelten Task ein laufendes Programm abgebro­
+   chen werden soll, muß zunächst durch <SV> der Supervisor aufgerufen werden.
+   Durch das Supervisor-Kommando 'halt' wird der Fehler 'halt from terminal'
+   induziert. Das Programm wird wie durch jeden anderen Fehler abgebrochen, falls
+   nicht 'disable stop' gesetzt wurde! 
+ 
+ 
+ 
+#page# 
+'storage info' 
+   #on("b")#PROC storage info #off("b")# 
+   Informationsprozedur über den belegten und den verfügbaren Hintergrund-Spei­
+   cher des gesamten Systems in KByte#u#1)#e#. 
+ 
+#foot# 
+ 
+   1) Bei der derzeit aktuellen '+' Version EUMEL 1.8.1/M+ sind die beiden Anga­
+      ben mit 4 zu multiplizieren ! 
+#end# 
+   Das Terminal wird unmittelbar abgekoppelt! 
+ 
+ 
+ 
+'task info' 
+   #on("b")#PROC task info #off("b")# 
+   Informiert über alle Tasknamen im System unter gleichzeitiger Angabe der Vater/
+   Sohn-Beziehungen durch Einrückungen. 
+ 
+ 
+ 
+ 
+'help' 
+   #on("b")#PROC help #off("b")# 
+   Kurzbeschreibung der SV-Kommandos. 
+#page# 
+
+4.2  Monitor
+ 
+Unter dem Stichwort Monitor-Kommandos sind an dieser Stelle Kommandos be­
+schrieben, die ständig zur Handhabung der Arbeitsumgebung benutzt werden.
+Gleichwohl sei sofort darauf hingewiesen, daß jedes ELAN Programm dem Monitor zur
+Ausführung übergeben werden kann. Es gibt also keine speziellen Monitor-
+Kommandos, sondern nur eine Reihe von Prozeduren (=Kommandos), die in dieser
+Umgebung erfahrungsgemäß besonders häufig benutzt werden. 
+ 
+ 
+#on("u")#4.2.1  Hilfs- und Informationsprozeduren#off("u")# 
+ 
+- Pakete, Prozeduren       :  packets, bulletin , help 
+  Parameter 
+ 
+- Tasksystem zeigen        :  task info , task status 
+ 
+- Speicherplatz zeigen     :  storage , storage info 
+ 
+ 
+#on("u")#4.2.2  Thesaurus #off("u")# 
+ 
+-  besondere Thesauri      :  ALL , all , SOME , remainder 
+ 
+-  Verknüpfung             :  + , - ,  / 
+ 
+ 
+#on("u")#4.2.3  Taskoperationen#off("u")# 
+ 
+- besondere Tasknamen      :  archive , brother , father , myself 
+                              printer , public , son , supervisor 
+- Terminal abkoppeln       :  break 
+- Task löschen             :  end 
+- Manager-Task             :  global manager , free global manager 
+- Umbenennen der Task      :  rename myself 
+ 
+#page# 
+#on("u")#4.2.4  Handhabung von Dateien #off("u")# 
+ 
+                           :  copy , edit , forget , list , rename , show 
+ 
+ 
+#on("u")#4.2.5  Editor #off("u")# 
+ 
+- Editieren                :  edit , editget , show 
+- Tastenbelegung           :  kommando auf taste (legen) , 
+                              lernsequenz auf taste (legen) , 
+                              std tastenbelegung , 
+                              taste enthält kommando , 
+                              word wrap 
+ 
+ 
+#on("u")#4.2.6  Transfer #off("u")# 
+ 
+- Datei holen              :  fetch , fetchall 
+- Datei senden             :  save , saveall 
+- Drucken                  :  print 
+- Datei löschen            :  erase 
+ 
+ 
+#on("u")#4.2.7  Passwortschutz #off("u")# 
+ 
+- 'begin' absichern        :  begin password 
+- 'continue' absichern     :  task password 
+- Dateien absichern        :  enter password 
+- Systemzweig sichern      :  family password 
+ 
+ 
+#on("u")#4.2.8  Das Archiv #off("u")# 
+ 
+- Reservieren/freigeben    :  archive , release 
+- Formatieren              :  format 
+- Löschen                  :  clear 
+- Kontrollesen             :  check 
+ 
+ 
+#page# 
+
+4.2.1  Hilfsprozeduren 
+ 
+Die drei Prozeduren listen ihre Ausgabe jeweils in eine temporäre Datei, die mit
+'show' (s. 4.2.5) gezeigt wird. 
+ 
+ 
+'packets' 
+   #on("b")#PROC packets #off("b")# 
+   Auflisten der Namen aller insertierten Pakete in der Task. 
+ 
+ 
+ 
+ 
+ 
+ 
+'bulletin' 
+   #on("b")#PROC bulletin (TEXT CONST paket name) #off("b")# 
+   Listen aller in der DEFINES-Liste des Pakets mit dem Namen "paket name"
+   enthaltenen Prozeduren. 
+ 
+   FEHLER :  ... ist kein Paketname 
+ 
+ 
+   #on("b")#PROC bulletin #off("b")# 
+   Es wird eine Liste aller bisher insertierten Objekte erstellt. Diese Liste ist paket­
+   weise sortiert. 'bulletin' zeigt also eine Liste #on("u")#aller#off("u")# Prozeduren an, die in der Task
+   benutzt werden können. 
+#page# 
+'help' 
+   #on("b")#PROC help (TEXT CONST name) #off("b")# 
+   Listen aller Prozeduren / Operatoren mit dem Namen "name". Der Name des
+   Packets in dessen Schnittstelle die Prozedur steht wird mit ausgegeben. 
+ 
+   Falls es kein Objekt des erfragten Namens gibt, erfolgt die Ausgabe: 
+ 
+   unbekannt "name". 
+ 
+   Beispiel: 
+____________________________________________________________________________ 
+ 
+     gib kommando : 
+     help("save") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   liefert: 
+ 
+____________________________________________________________________________ 
+ 
+PACKET nameset: 
+ 
+      save........... (THESAURUS CONST, TASK CONST) 
+      save........... (THESAURUS CONST) 
+ 
+PACKET globalmanager: 
+ 
+      save........... (DATASPACE CONST, TEXT CONST, TASK CONST) 
+      save........... (TEXT CONST, TASK CONST) 
+      save........... (TEXT CONST) 
+      save........... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+   Desweiteren kann auch nach Prozedurnamen gesucht werden, die nur annähernd
+   bekannt sind, indem ein Suchmuster spezifiziert wird. Das Suchmuster besteht aus
+   dem bekannten Teil des Namens und dem Operator '*', der vor und/oder nach
+   dem Suchbegriff gesetzt werden kann. '*' bezeichnet eine beliebige (auch leere)
+   Zeichenkette. 
+ 
+   Beispiel: Gesucht werden die verschiedenen 'info' Prozeduren: 
+ 
+____________________________________________________________________________ 
+     gib kommando : 
+     help("*info*") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+      taskinfo....... (INT CONST, INT CONST) 
+      taskinfo....... (INT CONST, FILE VAR) 
+      taskinfo....... (INT CONST) 
+      taskinfo....... 
+      editinfo....... (FILE VAR, INT CONST) 
+      editinfo....... (FILE CONST)  --> INT 
+      storageinfo.... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+   Dieser Stern darf nicht mit dem 'joker' des 'Pattern Matching' verwechselt werden.
+   In der 'help' Prozedur darf '*' #on("u")#nicht#off("u")# in den Suchbegriff eingesetzt werden, sondern
+   nur an Wortanfang und -Ende gesetzt werden. 
+ 
+ 
+#page# 
+
+Informationsprozeduren 
+ 
+'storage' 
+   #on("b")#INT PROC storage (TASK CONST task) #off("b")# 
+   Informationsprozedur über den logisch belegten Hintergrund-Speicher der Task.
+   (Angabe in KByte, bzw. 4KB Einheiten bei der '+'-Version) 
+ 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    put(storage(myself)) 
+    1234 
+ 
+    gib kommando : 
+ 
+____________________________________________________________________________ 
+ 
+ 
+'storage info' 
+   #on("b")#PROC storage info #off("b")# 
+   Informationsprozedur über den belegten und den verfügbaren Hintergrund-Spei­
+   cher des gesamten Systems. Die Ausgabe erfolgt in KByte, bei der aktuellen
+   '+'-Version in 4 KByte Einheiten. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    storage info 
+    1234K von 12000K 
+ 
+    gib kommando : 
+____________________________________________________________________________ 
+#page# 
+ 
+'task info' 
+   #on("b")#PROC task info #off("b")# 
+   Informiert über alle Tasknamen im System unter gleichzeitiger Angabe der Vater/
+   Sohn-Beziehungen (Angabe durch Einrückungen). 
+ 
+ 
+   #on("b")#PROC task info (INT CONST art) #off("b")# 
+   Informiert über alle Tasks im System. Mit 'art' kann man die Art der Zusatz-
+   Information auswählen. 
+ 
+   art=1: entspricht 'task info' ohne Parameter, d.h. es gibt nur die Tasknamen
+          unter Angabe der Vater/Sohn-Beziehungen aus. 
+ 
+   art=2: gibt die Tasknamen aus. Zusätzlich erhalten Sie Informationen über die
+          verbrauchte CPU-Zeit der Task, die Priorität, den Kanal, an dem die
+          Task angekoppelt ist, und den eigentlichen Taskstatus. Hierbei bedeuten: 
+ 
+          0    -busy-        Task ist aktiv. 
+          1    i/o           Task wartet auf Beendigung des Outputs oder auf
+                             Eingabe. 
+          2    wait          Task wartet auf Sendung von einer anderen Task. 
+          4    busy-blocked  Task ist rechenwillig, aber blockiert#u#1)#e#. 
+          5    i/o -blocked  Task wartet auf I/O, ist aber blockiert. 
+          6    wait-blocked  Task wartet auf Sendung, ist aber blockiert. Ach­
+                             tung: Die Task wird beim Eintreffen einer Sendung
+                             automatisch entblockiert. 
+        > 6    dead 
+ 
+    art=3: wie 2, aber zusätzlich wird der belegte Speicher angezeigt. (Achtung:
+           Prozedur ist zeitaufwendig!). 
+ 
+#foot# 
+ 
+1) Eine Blockierung kann von 'Scheduler' veranlaßt werden 
+   (siehe Systemhandbuch) 
+#end# 
+ 
+#page# 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    task info(2) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+    liefert: 
+ 
+____________________________________________________________________________ 
+ 
+ ............................ ............................... 
+ 15.05.87   10:39                         CPU    PRIO CHAN STATUS 
+ SUPERVISOR.......................... 0000:19:47   0   -   wait 
+    -................................ 0000:07:54   0   -   wait 
+    SYSUR............................ 0000:34:02   0   -   wait 
+        shutup dialog................ 0000:05:26   0   -   i/o 
+        configurator................. 0000:04:17   0   -   wait 
+        OPERATOR..................... 0000:00:14   0   -   i/o 
+        ARCHIVE...................... 0000:10:33   0  31   wait 
+        net.......................... 0006:41:56   0   -   wait 
+            net timer................ 0000:02:48   2   -   i/o 
+            net port................. 0000:40:23   0   7   wait 
+        PRINTER...................... 0000:05:59   0   -   wait 
+            -........................ 0000:00:11   0   -   wait 
+ UR.................................. 0000:02:11   0   -   wait 
+    PUBLIC........................... 0002:02:03   0   -   wait 
+        task1........................ 0000:41:50   0   -   -busy- 
+        task2........................ 0000:03:10   0   -   i/o 
+        task3........................ 0000:57:28   0   1   -busy- 
+ 
+____________________________________________________________________________ 
+ 
+ 
+#page# 
+ 
+ 
+   #on("b")#PROC task info (INT CONST art, FILE VAR infodatei) #off("b")# 
+   Wie oben, die Ausgabe wird jedoch in die Datei 'infodatei' geschrieben. 
+ 
+____________________________________________________________________________ 
+ 
+    FILE VAR info := sequential file(output,"infodatei") ; 
+    taskinfo(3, info); 
+     
+____________________________________________________________________________ 
+ 
+ 
+   #on("b")#PROC task info ( INT CONST art, stationsnr) #off("b")# 
+   Ermöglicht im Netzbetrieb 'task info' über die Station mit der Nummer 'stationsnr'. 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    taskinfo(1,12) ; 
+ 
+____________________________________________________________________________ 
+#page# 
+'task status' 
+ 
+   #on("b")#PROC task status #off("b")# 
+   Informationsprozedur über den Zustand der eigenen Task. Informiert über 
+   -  Name der Task, Datum und Uhrzeit; 
+   -  verbrauchte CPU-Zeit; 
+   -  belegten Speicherplatz; 
+   -  Kanal, an den die Task angekoppelt ist; 
+   -  Zustand der Task (rechnend u.a.m.); 
+   -  Priorität. 
+ 
+   #on("b")#PROC task status (TASK CONST t) #off("b")# 
+   Wie obige Prozedur, aber über die Task mit dem internen Tasknamen 't'. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando : 
+   task status (public) 
+ 
+ 15.05.87 10:30   TASK: PUBLIC 
+ 
+ Speicher: 1234K 
+ CPU Zeit: 0011.12:23 
+ Zustand : wait, (Prio 0), Kanal - 
+ 
+____________________________________________________________________________ 
+#page# 
+ 
+4.2.2  Thesaurus 
+ 
+Ein #ib#Thesaurus#ie# ist ein #ib#Namensverzeichnis#ie#, das bis zu 200 Namen beinhalten kann.
+Dabei muß jeder Namen mindestens ein Zeichen und darf höchstens 100 Zeichen
+lang sein. Steuerzeichen (code < 32) in Namen werden umgesetzt (siehe 2.9.2). 
+ 
+Thesauri werden unter anderem von der Dateiverwaltung benutzt, um das Dateiver­
+zeichnis einer Task zu führen. 
+ 
+Man kann einen Thesaurus selbst erstellen, indem eine Datei z.B. mit Namen von
+Dateien gefüllt wird. Diese Datei kann dann als Thesaurus für weitere Aktionen die­
+nen. 
+ 
+ 
+ 
+- Thesaurus liefern        :  ALL , all , SOME , remainder 
+- Auswählen                :  LIKE 
+- Verknüpfen               :  + , - , / 
+ 
+ 
+ 
+#on("b")#ACHTUNG#off("b")# :  Bei der Verwendung von Thesaurus Operationen in Verbindung mit
+'fetch', 'save' etc. ist zu beachten, daß mit 'SOME', 'ALL' und 'all' zunächst nur eine
+Auswahl aus einer Liste getroffen wird. Zusätzlich muß das Ziel oder die Quelle des
+Dateitransfers vereinbart werden. 
+ 
+Ein beliebter Fehler ist z.B.:   'fetch (ALL archive)'. 
+ 
+Hier ist nicht weiter spezifiziert, von wo Dateien geholt werden sollen - also werden
+sie von 'father' geholt!  (s. 4.2.5) 
+ 
+Falls die Dateien vom Archiv geholt werden sollen, ist das Archiv als Quelle zu be­
+nennen: 
+ 
+Also : 'fetch (ALL archive, archive)' = Hole alle Dateien, die in dem Thesaurus von 
+                                  'archive' sind von der Task 'archive'. 
+#page# 
+'ALL' 
+   THESAURUS OP ALL (TASK CONST task) 
+   Liefert einen Thesaurus, der alle Dateinamen der angegebenen Task enthält. 
+ 
+ 
+ 
+   #on("b")#THESAURUS OP ALL (TEXT CONST dateiname) #off("b")# 
+   Liefert einen Thesaurus, der die in der angegebenen Datei vorhandenen Namen
+   (jede Zeile ein Name) enthält. 
+ 
+ 
+ 
+ 
+'all' 
+   #on("b")#THESAURUS PROC all #off("b")# 
+   Liefert einen Thesaurus, der alle Dateinamen der eigenen Task enthält. Entspricht
+   'ALL myself'. 
+ 
+ 
+ 
+ 
+'SOME' 
+   #on("b")#THESAURUS OP SOME (THESAURUS CONST thesaurus) #off("b")# 
+   Bietet den angegebenen Thesaurus zum editieren an. Dort können nicht erwünsch­
+   te Namen gestrichen werden. 
+ 
+ 
+ 
+   #on("b")#THESAURUS OP SOME (TASK CONST task) #off("b")# 
+   Aufruf von: SOME ALL task. 
+ 
+ 
+   #on("b")#THESAURUS OP SOME (TEXT CONST dateiname) #off("b")# 
+   Aufruf von: SOME ALL dateiname. 
+ 
+#page# 
+'remainder' 
+   #on("b")#PROC remainder #off("b")# 
+   Liefert nach einem 'errorstop' die noch nicht bearbeiteten Dateien. 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    save all (archive) 
+ 
+   '"....." kann nicht geschrieben werden (Archiv voll)' 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+   Nachdem man eine neue Floppy ins Archivlaufwerk gelegt hat, kann man mit 
+ 
+ 
+____________________________________________________________________________ 
+    gib kommando : 
+    save (remainder, archive) 
+ 
+____________________________________________________________________________ 
+ 
+   den Rest der Dateien auf die nächste Floppy sichern. 
+#page# 
+'LIKE' 
+   #on("b")#THESAURUS OP LIKE (THESAURUS CONST thesaurus, TEXT CONST muster) #off("b")# 
+   Alle im Thesaurus enthaltenen Dateien, die dem 'muster' entsprechen sind im
+   Ergebnisthesaurus enthalten. 
+ 
+   (Die Syntax von 'muster' ist bei der Beschreibung des Pattern-Matching (5.4)
+   beschrieben) 
+ 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    print (all LIKE "*.p") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+  Alle Dateien, deren Name mit '.p' endet, werden gedruckt. 
+ 
+#page# 
+'+' 
+   #on("b")#THESAURUS OP + (THESAURUS CONST links, rechts) #off("b")# 
+   Liefert die Vereinigungsmenge von 'links' und 'rechts'. 
+   Achtung: Die Vereinigungsmenge enthält keine Namen mehrfach. 
+ 
+   #on("b")#THESAURUS OP + (THESAURUS CONST links, TEXT CONST rechts)#off("b")# 
+   Fügt dem Thesaurus 'rechts' zu, wenn 'rechts' noch nicht im Thesaurus enthal­
+   ten ist. 
+ 
+ 
+ 
+ 
+'-' 
+   #on("b")#THESAURUS OP - (THESAURUS CONST links, rechts) #off("b")# 
+   Liefert die Differenzmenge. Achtung: Die Differenzmenge enthält keine Namen
+   mehrfach. 
+ 
+   #on("b")#THESAURUS OP - (THESAURUS CONST links, TEXT CONST rechts)#off("b")# 
+   Nimmt den Namen 'rechts' aus dem Thesaurus. 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    fetch(ALL father - ALL myself) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+'/' 
+   #on("b")#THESAURUS OP / (THESAURUS CONST links, rechts) #off("b")# 
+   Liefert die Schnittmenge 
+   Achtung: Die Schnittmenge enthält keine Namen mehrfach. 
+ 
+ 
+#page# 
+
+4.2.3  Tasks
+ 
+Zur Identifizierung von Tasks dienen sogenannte 'interne Taskbezeichner'. Ein solcher
+Taskbezeichner wird beim Einrichten einer neuen Task vergeben. Interne Taskbe­
+zeichner sind auch unter Berücksichtigung der Zeit eindeutig. 
+ 
+Der Zugriff auf interne Taskbezeichner erfolgt über Prozeduren und Operatoren, die
+auf Objekte des Datentyps TASK (siehe 2.9.1) angewandt werden. 
+ 
+Zusätzlich zum internen Tasknamen, der nicht auszugeben ist, haben Tasks meistens
+einen Namen#u#1) #e#. 
+#foot# 
+ 
+1) Unbenannte Tasks haben den Pseudonamen "-". 
+#end# 
+ 
+Aus Benutzersicht können benannte Tasks innerhalb eines Rechners vollständig und
+eindeutig über ihren Namen identifiziert werden. 
+ 
+ 
+- Task liefern             :  / , task , niltask 
+ 
+- Verwandtschaften         :  brother , father , myself , son 
+ 
+- Ausgezeichnete Tasks     :  archive , printer , public , supervisor 
+ 
+- Namen liefern            :  name 
+ 
+- Tasknamen ändern         :  rename myself 
+ 
+- Reservieren bes. Tasks   :  reserve 
+ 
+#page# 
+'/' 
+   #on("b")#TASK OP / (TEXT CONST taskname) #off("b")# 
+   Liefert die Task des angegebenen Namens, falls sie existiert. Der eigene Katal­
+   og wird automatisch aktualisiert 
+ 
+   (identisch mit der PROC task (TEXT CONST taskname). 
+ 
+   FEHLER :   "taskname" gibt es nicht 
+ 
+ 
+   #on("b")#TASK OP / (INT CONST station number, TEXT CONST name) #off("b")# 
+   Liefert im Netzbetrieb die Task des angegebenen Namen von der Station mit der
+   angegebenen Nummer. 
+ 
+ 
+ 
+'niltask' 
+   #on("b")#TASK CONST niltask #off("b")# 
+   Bezeichner für "keine Task". So liefern die Prozeduren 'son', 'brother' und 'father'
+   als Resultat 'niltask', wenn keine Sohn-, Bruder- oder Vatertask existiert. 
+ 
+ 
+ 
+'task' 
+   #on("b")#TASK PROC task (TEXT CONST taskname) #off("b")# 
+   Liefert die Task des angegebenen Namens, falls sie existiert. Der eigene Katal­
+   og wird automatisch aktualisiert. 
+ 
+   FEHLER :     "taskname" gibt es nicht 
+ 
+ 
+   #on("b")#TASK PROC task (INT CONST channel number) #off("b")# 
+   Liefert den Namen der Task, die an dem angegebenen Kanal hängt. 
+#page# 
+'brother' 
+   #on("b")#TASK PROC brother (TASK CONST task) #off("b")# 
+   Liefert den nächsten Bruder von 'task'. Falls kein Bruder existiert, wird 'niltask'
+   geliefert. Aktualisiert den eigenen Katalog nicht automatisch! 
+ 
+ 
+ 
+'father' 
+   #on("b")#TASK PROC father #off("b")# 
+   Liefert die eigene Vatertask. 
+ 
+ 
+   #on("b")#TASK PROC father (TASK CONST task) #off("b")# 
+   Liefert den Vater von 'task'. Existiert kein Vater (z.B. bei UR), wird niltask gelie­
+   fert. Aktualisiert den eigenen Katalog nicht automatisch! 
+ 
+ 
+ 
+'myself' 
+   #on("b")#TASK PROC myself #off("b")# 
+   Liefert eigenen Task-Bezeichner. 
+ 
+ 
+ 
+'son' 
+   #on("b")#TASK PROC son (TASK CONST task) #off("b")# 
+   Liefert den ersten Sohn von 'task'. Falls keiner im Katalog vermerkt ist, wird
+   'niltask' geliefert. Aktualisiert den eigenen Katalog nicht automatisch! 
+ 
+ 
+#page# 
+'archive' 
+   #on("b")#TASK PROC archive #off("b")# 
+   Liefert den internen Taskbezeichner der aktuellen Task mit Namen ARCHIVE.
+   Diese Prozedur dient zum schnellen und bequemen Ansprechen der Archivtask. 
+ 
+ 
+ 
+'printer' 
+   #on("b")#TASK PROC printer #off("b")# 
+   Liefert den internen Taskbezeichner der aktuellen Task mit Namen #ib#PRINTER#ie#.
+   Diese Prozedur dient zum schnellen und bequemen Ansprechen des Druckspoo­
+   lers. 
+ 
+ 
+'public' 
+   #on("b")#TASK PROC public #off("b")# 
+   Liefert den internen Taskbezeichner der Task #ib#PUBLIC#ie#. 
+ 
+ 
+ 
+ 
+'supervisor' 
+   #on("b")#TASK PROC supervisor #off("b")# 
+   Liefert den internen Taskbezeichner des Supervisors. 
+ 
+ 
+#page# 
+'name' 
+   #on("b")#TEXT PROC name (TASK CONST task) #off("b")# 
+   Liefert den Namen von 'task'. Die Task muß noch im System existieren, sonst ist
+   der Name nicht mehr bekannt. Falls die 'task' noch nicht im eigenen Katalog
+   enthalten ist, wird er aktualisiert. 
+ 
+ 
+ 
+'rename myself' 
+   #on("b")#PROC rename myself (TEXT CONST neuer name) #off("b")# 
+   Name der eigenen Task wird in 'neuer name' geändert. Wirkt wie Löschung und
+   Wiedereinrichten der Task in Bezug auf alle TASK VAR's die sich auf diese Task
+   beziehen. 
+ 
+   FEHLER :   Task existiert bereits 
+              Name unzulässig 
+              => anderen Namen wählen 
+ 
+ 
+ 
+'reserve' 
+   #on("b")#PROC reserve (TASK CONST task) #off("b")# 
+   Reservieren einer Task für den ausschließlichen Dialog mit der Task, in der das
+   Kommando gegeben wurde. 
+ 
+   #on("b")#PROC reserve (TEXT CONST message, TASK CONST task) #off("b")# 
+   Wie 'reserve (TASK CONST task)' mit Übergabe einer 'message'. 
+ 
+ 
+   Die reservierte Task muß ein spezieller Manager, (z.B. /"DOS" aus dem Werkzeug
+   MS-DOS-DAT) sein ! 
+#page# 
+
+4.2.4  Handhabung von Dateien 
+ 
+'copy' 
+   #on("b")#PROC copy (TEXT CONST quelle, ziel) #off("b")# 
+   Kopiert die Datei 'quelle' in eine neue Datei mit dem Namen 'ziel' in der Benut­
+   zer-Task. 
+ 
+   FEHLER :  "ziel" existiert bereits 
+             "quelle" gibt es nicht 
+             zu viele Dateien 
+ 
+ 
+ 
+'forget' 
+   #on("b")#PROC forget (TEXT CONST dateiname) #off("b")# 
+   Löschen einer Datei mit dem Namen 'dateiname' in der Benutzer-Task. 
+ 
+   FEHLER :  "datei" gibt es nicht 
+ 
+ 
+   #on("b")#PROC forget (THESAURUS CONST thesaurus) #off("b")# 
+   Löscht die im 'thesaurus' enthaltenen Dateien in der Benutzer-Task. 
+ 
+   Im Dialog erfolgt vor dem Löschen einer Datei standardmäßig die Abfrage: 
+ 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    forget("einedatei") 
+ "einedatei" löschen(j/n) ? 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+'list' 
+   #on("b")#PROC list #off("b")# 
+   Listet alle Dateien der Benutzer-Task mit Namen und Datum des letzten Zugriffs
+   auf dem Terminal auf. 
+ 
+ 
+   #on("b")#PROC list (TASK CONST task) #off("b")# 
+   Listet alle Dateien der angegebenen 'task' mit Namen und Datum der letzten
+   Änderung auf dem Terminal auf. Die Task muß Manager sein. 
+ 
+ 
+   #on("b")#PROC list (FILE VAR liste) #off("b")# 
+   Listet alle Dateinamen in die Datei 'liste', die mit 'output'(s. 5.3.5) assoziiert sein
+   muß. 
+ 
+ 
+   #on("b")#PROC list (FILE VAR liste, TASK CONST manager) #off("b")# 
+   Listet alle Dateien der Task 'manager' mit Namen und Datum der letzten Ände­
+   rung in die Datei 'liste'. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ gib kommando : 
+ FILE VAR f:= sequential file (output,"list");list(f,archive) 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+'rename' 
+   #on("b")#PROC rename (TEXT CONST altername, neuername) #off("b")# 
+   Umbenennen einer Datei von 'altername' in 'neuername'. 
+ 
+ 
+ 
+   FEHLER :   "neuername" gibt es bereits 
+              "altername" gibt es nicht 
+#page# 
+ 
+4.2.5  Editor-Prozeduren  
+ 
+'edit' 
+   #on("b")#PROC edit (TEXT CONST dateiname) #off("b")# 
+   Ruft den Editor mit 'dateiname' auf. 
+ 
+ 
+   #on("b")#PROC edit #off("b")# 
+   a) Im Monitor: 
+      Ruft den Editor mit den zuletzt verwandten Dateinamen auf. 
+ 
+   b) Im Editor: 
+      Der Dateiname wird erfragt. 
+ 
+   Für jedes 'edit' gilt: 
+   Wurde 'edit' zum ersten Mal aufgerufen, nimmt das Fenster den gesamten Bild­
+   schirm ein. Bei erneutem 'edit'-Aufruf wird ein Fenster nach rechts unten ab der
+   aktuellen Cursor-Position eröffnet. 
+ 
+ 
+   #on("b")#PROC edit (THESAURUS CONST t) #off("b")# 
+   Editieren aller in dem Thesaurus 't' enthaltenen Dateien nacheinander. 
+ 
+ 
+   Weitere 'edit-Prozeduren', die z.B. Variation der Fenstergröße etc. zulassen, sind
+   in 5.4.6 beschrieben. 
+   
+#page# 
+'editget' 
+   #on("b")#PROC editget  (TEXT VAR editsatz) #off("b")# 
+   Ausgabe einer (Kommando)zeile, in der Editorfunktionen zur Verfügung
+   stehen siehe Teil 5.5.1.4. 
+ 
+ 
+ 
+'show' 
+   #on("b")#PROC show (TEXT CONST dateiname) #off("b")# 
+   Die Datei wird am Bildschirm gezeigt. Positionierung und Suchen funktionieren wie
+   in 'edit', Aktionen die Änderungen in der Datei bewirken würden, werden nicht
+   angenommen. 
+ 
+ 
+ 
+   #on("b")#PROC show #off("b")# 
+   'show' auf der zuletzt bearbeiteten Datei. 
+ 
+#page# 
+'kommando auf taste legen' 
+   #on("b")#PROC kommando auf taste legen (TEXT CONST taste, elan programm)#off("b")# 
+   Die Taste 'taste' wird mit dem angegebenen ELAN-Programm belegt. Durch <ESC>
+   <taste> wird das Programm direkt ausgeführt. 
+ 
+____________________________________________________________________________ 
+ 
+  gib kommando : 
+  kommando auf taste legen ("a","fetch (SOME archive,archive)") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+'kommando auf taste' 
+   #on("b")#TEXT PROC kommando auf taste (TEXT CONST taste)#off("b")# 
+   Falls 'taste' mit einem ELAN-Programm belegt ist, liefert die Prozedur den
+   Programmtext, andernfalls den leeren Text niltext. 
+ 
+____________________________________________________________________________ 
+ 
+  gib kommando : 
+  put (kommando auf taste("f")) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+'taste enthaelt kommando' 
+   #on("b")#BOOL PROC taste enthaelt kommando (TEXT CONST taste)#off("b")# 
+   Liefert TRUE falls 'taste' mit einem ELAN-Programm belegt ist. 
+ 
+ 
+'lernsequenz auf taste legen' 
+   #on("b")#PROC lernsequenz auf taste legen (TEXT CONST taste, sequenz)#off("b")# 
+   'taste' wird mit der Zeichenfolge 'sequenz' belegt. Durch <ESC> <taste> wird die
+   Zeichenfolge an der aktuellen Position ausgegeben. 
+ 
+   Als Zeichenfolge sind natürlich auch einzelne Zeichen und EUMEL-Codes zuläs­
+   sig. 
+ 
+   Die vom System vorbelegten Tasten sind in 3.4 'Zeichen schreiben' aufgelistet. 
+ 
+____________________________________________________________________________ 
+ 
+  gib kommando : 
+  lernsequenz auf taste legen ("x","gib kommando :"13""2""2"") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+'lernsequenz auf taste' 
+   #on("b")#TEXT PROC lernsequenz auf taste (TEXT CONST taste) #off("b")# 
+   Liefert die auf 'taste' gelegte Zeichenfolge. 
+ 
+ 
+'std tastenbelegung' 
+   #on("b")#PROC std tastenbelegung #off("b")# 
+   Die Standard-Tastenbelegung (s.3.4) wird (wieder) hergestellt. 
+ 
+ 
+'word wrap' 
+   #on("b")#PROC word wrap (BOOL CONST b) #off("b")# 
+   Der automatische Zeilenumbruch wird durch 'word wrap (FALSE)' aus- und durch
+   'word wrap (TRUE)' eingeschaltet. Wird diese Prozedur während des Editierens
+   aufgerufen, gilt die Einstellung für die aktuelle Textdatei. Wird die Prozedur als
+   Monitor-Kommando gegeben, so gilt die Eingabe als Voreinstellung für neue
+   Dateien. 
+#page# 
+ 
+4.2.6  Dateitransfer
+ 
+Unter diesem Abschnitt sind diejenigen Prozeduren beschrieben, die der simplen
+Kommunikation mit Manager-Tasks dienen: Holen oder Senden einer Dateikopie,
+Löschen in der Manager-Task. 
+ 
+#on("b")#ACHTUNG :  Für alle Prozeduren gilt: falls die Manager-Task nicht existiert, wird eine
+Fehlermeldung erzeugt, existiert eine Task des angegebenen Namens, die aber nicht
+Managertask ist, so terminieren die Prozeduren nicht! 
+#off("b")# 
+ 
+ 
+'fetch' 
+   #on("b")#PROC fetch (TEXT CONST dateiname, TASK CONST manager) #off("b")# 
+   Kopiert die Datei 'dateiname' aus der Task 'manager' 
+ 
+ 
+   #on("b")#PROC fetch (THESAURUS CONST th, TASK CONST manager) #off("b")# 
+   Kopiert alle Dateien, deren Namen im Thesaurus th enthalten sind, aus der Task
+   'manager'. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando : 
+   fetch(ALL(12/"PUBLIC"), 12/"PUBLIC") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+   Mit diesem Kommando werden (in einem EUMEL Netz) alle Dateien der Task
+   'PUBLIC' des Rechners mit der Stationsnummer 12 in diesem Netz kopiert. 
+ 
+#page# 
+____________________________________________________________________________ 
+ 
+   gib kommando : 
+   fetch(SOME archive , archive) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+   Bietet den Thesaurus von 'ARCHIVE' an, nach Auswahl werden alle Dateien deren
+   Namen nicht gelöscht wurden, von der Diskette kopiert. 
+ 
+ 
+   #on("b")#PROC fetch (TEXT CONST dateiname) #off("b")# 
+   Kopiert die Datei 'dateiname' aus der Task 'father' 
+ 
+ 
+   #on("b")#PROC fetch (THESAURUS CONST th) #off("b")# 
+   Kopiert alle Dateien, deren Namen in 'th' sind aus der Task 'father'. 
+ 
+ 
+ 
+'fetchall' 
+ 
+   #on("b")#PROC fetchall #off("b")# 
+   entspricht: fetch (ALL father, father) 
+ 
+ 
+   #on("b")#PROC fetchall (TASK CONST manager)#off("b")# 
+   entspricht: fetch(ALL manager, manager) 
+ 
+#page# 
+'save' 
+   #on("b")#PROC save (TEXT CONST dateiname, TASK CONST manager) #off("b")# 
+   Kopiert die Datei 'dateiname' in die Task 'manager' 
+ 
+ 
+   #on("b")#PROC save (THESAURUS CONST th, TASK CONST manager) #off("b")# 
+   Kopiert alle Dateien, deren Namen im Thesaurus th enthalten sind, in die Task
+   'manager'. 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    save(all, (12/"PUBLIC")) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   Mit diesem Kommando werden (in einem EUMEL Netz) alle Dateien der eigenen
+   Task in die Task 'PUBLIC' des Rechners mit der Stationsnummer 12 in diesem
+   Netz kopiert. 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    save(SOME myself, manager) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   Bietet den eigenen Thesaurus an, nach Auswahl werden alle Dateien deren
+   Namen nicht gelöscht wurden, zur Task 'manager' kopiert. 
+ 
+ 
+   #on("b")#PROC save (TEXT CONST dateiname) #off("b")# 
+   Kopiert die Datei 'dateiname' in die Task 'father' 
+ 
+ 
+   #on("b")#PROC save (THESAURUS CONST th) #off("b")# 
+   Kopiert alle Dateien, deren Namen in 'th' enthalten sind, in die Task 'father'. 
+ 
+ 
+   #on("b")#PROC save #off("b")# 
+   Kopiert die zuletzt bearbeitete Datei in die Task 'father' 
+ 
+ 
+ 
+ 
+'saveall' 
+   #on("b")#PROC saveall #off("b")# 
+   entspricht: save (all, father) 
+ 
+ 
+   #on("b")#PROC saveall (TASK CONST manager) #off("b")# 
+   entspricht: save (ALL myself, manager) 
+ 
+#page# 
+'erase' 
+   #on("b")#PROC erase (TEXT CONST dateiname, TASK CONST manager) #off("b")# 
+   Löscht die Datei 'dateiname' aus der Task 'manager' 
+ 
+ 
+   #on("b")#PROC erase (THESAURUS CONST th, TASK CONST manager) #off("b")# 
+   Löscht alle Dateien, deren Namen im Thesaurus th enthalten sind, aus der Task
+   'manager'. 
+ 
+ 
+   #on("b")#PROC erase (TEXT CONST dateiname) #off("b")# 
+   Löscht die Datei 'dateiname' aus der Task 'father' 
+ 
+ 
+   #on("b")#PROC erase (THESAURUS CONST th) #off("b")# 
+   Löscht alle Dateien, deren Namen in 'th' sind, aus der Task 'father' 
+ 
+ 
+   #on("b")#PROC erase #off("b")# 
+   Löscht die zuletzt bearbeitete Datei aus der Task 'father' 
+ 
+ 
+#page# 
+'print' 
+   Das Kommando 'print' beinhaltet den Auftrag an die Task 'PRINTER' die enthal­
+   tene(n) Datei(en) auszudrucken. 
+ 
+   Voraussetzung ist natürlich, daß die Druckersoftware ordnungsgemäß benutzt
+   wurde, um 'PRINTER' einzurichten. Siehe dazu Systemhandbuch Teil 6. 
+ 
+ 
+   #on("b")#PROC print (TEXT CONST dateiname) #off("b")# 
+   Kopiert die Datei 'dateiname' in die Task 'PRINTER'. 
+ 
+ 
+   #on("b")#PROC print (THESAURUS CONST th) #off("b")# 
+   Kopiert alle Dateien, deren Namen im Thesaurus 'th' enthalten sind, in die Task
+   'PRINTER'. 
+ 
+ 
+   #on("b")#PROC print #off("b")# 
+   Kopiert die zuletzt bearbeitete Datei in die Task 'PRINTER'. 
+ 
+ 
+#page# 
+ 
+4.2.7  Passwortschutz 
+ 
+Der Passwortschutz im EUMEL-System ist in verschiedener Ausprägung möglich.
+Einfachste Möglichkeit ist der Schutz einer Task durch ein Passwort. Falls diese Task
+nicht Manager ist, können alle Daten und Programme, die nur in dieser Task zur
+Verfügung stehen, auch nur vom Besitzer der Task benutzt werden. 
+ 
+Ähnlich kann auch von einer Manager-Task aus der gesamte Zweig unterhalb dieser
+Task mit einem Passwort geschützt werden: beispielsweise kann es empfehlenswert
+sein, den Systemzweig komplett zu schützen, indem in SYSUR ein entsprechendes
+Passwort vereinbart wird. 
+ 
+Ein Umgehen des Passwortschutzes bei Manager-Tasks (durch Einrichten einer
+Sohn-Task und 'fetchall') wird durch ein 'begin password' verhindert. 
+ 
+Auch einzelne Dateien lassen sich schützen, indem Lese/Schreibpasswörter für den
+Dateitransfer vereinbart werden. 
+ 
+Generell gilt für die Verwendung von Passworten: 
+ 
+-  Passworte, die zu naheliegend gewählt sind (Vorname des Lebenspartners o.ä.)
+   sind meistens sinnlos, falls wirklich Datenschutz bezweckt ist. 
+ 
+-  Passworte, die so raffiniert sind, daß sogar ihr Schöpfer sie vergißt, führen zu
+   100%igem Datenverlust, da die betroffene Task oder Datei nur noch gelöscht
+   werden kann. 
+ 
+-  Die Vereinbarung von "-" als Passwort bewirkt, daß die entsprechende Aktion
+   nicht mehr durchgeführt werden kann. Wird z.B. '-' als 'task password'
+   eingegeben, so kann die Task nie wieder an ein Terminal gekoppelt werden. 
+ 
+-  Passwörter können geändert werden, indem das entsprechende Kommando noch
+   einmal mit dem neuen Passwort gegeben wird. 
+ 
+#page# 
+'begin password' 
+ 
+   #on("b")#PROC begin password (TEXT CONST passwort) #off("b")# 
+ 
+   Auf Supervisor-Ebene wird vor Einrichten einer neuen Task als Sohn der Task in
+   der das 'begin password' gegeben wurde, dieses erfragt. 
+ 
+   Das Password vererbt sich auf die hinzukommenden Sohn-Tasks. 
+ 
+____________________________________________________________________________ 
+ 
+    #on("b")#SYSUR#off("b")# 
+    maintenance : 
+    begin password ("alles dicht") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+bewirkt: 
+ 
+____________________________________________________________________________ 
+ 
+                                           Terminal 2  
+ 
+ 
+                    EUMEL Version 1.8.1/M 
+ 
+ 
+        gib supervisor kommando: 
+        begin ("sabotage","SYSUR") 
+              Passwort:  
+ 
+ 
+   ESC ? --> help 
+   ESC b --> begin("")            ESC h --> halt 
+   ESC c --> continue("")         ESC s --> storage info 
+   ESC q --> break                ESC t --> task info 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+#page# 
+'enter password' 
+   #on("b")#PROC enter password (TEXT CONST datei, schreibpass, lesepass) 
+   #off("b")# 
+   Hiermit können ausgewählte Dateien einer Manager-Task geschützt werden. Die
+   angegebene Datei wird mit Schreib- und Lesepassword versehen. Die Pass­
+   wörter werden in der eigenen Task nicht berücksichtigt. 
+ 
+   Bei einem lesenden Zugriff (fetch) von irgendeiner Task aus auf die entsprechende
+   Datei in der Manager-Task muß das Lesepasswort, bei schreibendem Zugriff
+   (save/erase) das Schreibpasswort vereinbart sein. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+    maintenance : 
+    enter password ("wichtige datei","sicher","heit") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+   #on("b")#PROC enter password (TEXT CONST password) #off("b")# 
+   Passwort für den Dateitransfer einstellen. Falls zwei verschiedene Passwörter für
+   Lesen und Schreiben vereinbart werden sollen, so sind sie als ein Text durch "/"
+   getrennt einzugeben. 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    enter password ("sicher/heit") 
+ 
+    gib kommando : 
+    save(SOME all) 
+ 
+____________________________________________________________________________ 
+#page# 
+'family password' 
+   #on("b")#PROC family password (TEXT CONST geheim) #off("b")# 
+   Einstellen eines Passworts für den Zweig des Systems , der unterhalb der (Mana­
+   ger) Task liegt, in der das 'family password' eingegeben wurde. Dabei erhalten
+   alle Tasks, die kein Password oder dasselbe wie diese Manager-Task haben, das
+   'family password'. Tasks in dem Zweig, die ein eigenes anderes besitzen, behal­
+   ten dieses. 
+ 
+____________________________________________________________________________ 
+ 
+   PUBLIC 
+ 
+     Task1 "" 
+ 
+     Task2 family password("fingerweg") 
+        Task21 geheim 
+        Task22 "" 
+ 
+     Task3 "" 
+        Task31 "" 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+bewirkt: 
+ 
+____________________________________________________________________________ 
+   PUBLIC 
+ 
+     Task1 "" 
+ 
+     Task2 fingerweg 
+        Task21 geheim 
+        Task22 fingerweg 
+ 
+     Task3 "" 
+        Task31 "" 
+ 
+____________________________________________________________________________ 
+ 
+ 
+#page# 
+ 
+'task password' 
+ 
+   #on("b")#PROC task password (TEXT CONST geheim) #off("b")# 
+   Einstellen eines Passworts für die Task in der es gegeben wird. Ist eine Task mit
+   einem Passwort geschützt, so wird durch den Supervisor nach dem 'continue'-
+   Kommando das Passwort angefragt (Entsprechend dem 'begin password'). Nur
+   nach Eingabe des richtigen Passworts gelangt man in die gewünschte Task. Das
+   Passwort kann durch nochmaligen Aufruf von 'task password' geändert werden,
+   z.B. wenn es in regelmäßigen Abständen geändert werden muß, um personenbe­
+   zogene Daten zu schützen. 
+ 
+#page# 
+ 
+4.2.8  Das Archiv 
+ 
+Mit dem Terminus 'Archiv' wird beim EUMEL-System ein Diskettenlaufwerk bezeich­
+net, das nur Datensicherungsaufgaben dient. Falls ein Rechner eins von zwei vorhan­
+denen Diskettenlaufwerk als Arbeitsspeicher benutzt, so wird dieses als Hintergrund
+bezeichnet. Falls Sie einen derartigen Rechner benutzen, können Sie der Installa­
+tionsanleitung entnehmen, welches Laufwerk welcher Aufgabe zugeordnet ist. 
+ 
+Das #ib#Archiv#ie# übernimmt im EUMEL-System die Verwaltung der langfristigen Daten­
+haltung. Das Archiv sollen Sie benutzen, um: 
+ 
+-  Sicherungskopien wichtiger Dateien außerhalb des Rechners zu besitzen; 
+ 
+-  nicht benötigte Dateien außerhalb einer Task zu halten (Speicherplatzersparnis!); 
+ 
+-  Dateien auf andere Rechner zu übertragen. 
+ 
+Das Archiv wird im EUMEL-System durch die Task 'ARCHIVE', die das Disketten­
+laufwerk des Rechners verwaltet, realisiert. 
+ 
+- reservieren              :  archive 
+ 
+- freigeben                :  release 
+ 
+- löschen                  :  clear , format 
+ 
+- prüfen                   :  check 
+ 
+#page# 
+'archive' 
+   #on("b")#PROC archive (TEXT CONST archivname) #off("b")# 
+   Reservierung der Task ARCHIVE für den exklusiven Dialog mit der aufrufenden
+   Task. 'archivname' wird bei allen folgenden Archivoperationen mit dem der Disket­
+   te zugewiesenen (und hoffentlich auf dem Aufkleber vermerkten) Namen abgegli­
+   chen. 
+ 
+ 
+ 
+'release' 
+   #on("b")#PROC release (TASK CONST archive) #off("b")# 
+   Nach diesem Kommando kann die Task 'ARCHIVE' mit ihren Leistungen von einer
+   anderen Task in Anspruch genommen werden. Falls dieses Kommando nicht
+   gegeben wird, aber seit 5 Minuten kein Dialog mit 'archive' stattfand, kann eine
+   andere Task durch die Anforderung 'archive("diskettenname")' das Archiv reser­
+   vieren. Durch diese Maßnahme wird verhindert, daß ein vergeßlicher Benutzer bei
+   einem System mit mehreren Benutzern das Archiv blockiert. 
+ 
+#page# 
+ 
+'clear' 
+   #on("b")#PROC clear (TASK CONST archive) #off("b")# 
+   Löschen des Disketten-Inhaltsverzeichnisses und Zuweisung des in der Reservie­
+   rung eingegebenen Namens. 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    archive("name"); #ib#clear#ie# (archive) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   Durch die Ausführung des Kommandos erhält die eingelegte Diskette den in der
+   Reservierung angegebenen Namen. #on("b")#Das Inhaltsverzeichnis, das sich auf der
+   Diskette befindet, wird gelöscht. Damit sind die Daten, die sich eventuell auf
+   dieser Diskette befanden, nicht mehr auffindbar#off("b")#. Die Diskette entspricht einer neu
+   formatierten Diskette#u#1)#e#. 
+ 
+   Man kann also eine beschriebene Diskette nicht umbenennen, ohne die darauf
+   befindlichen Daten zu löschen. 
+ 
+   #foot# 
+ 
+   #u#1)#e# Das Kommando 'format' enthält implizit 'clear'. 
+#end# 
+ 
+   Eine Neuformatierung ist demnach bei Wiederverwendung der Diskette nicht
+   notwendig. 
+ 
+#page# 
+'format' 
+   #on("b")#PROC format (TASK CONST archive) #off("b")# 
+   Formatieren einer Diskette. Vor der erstmaligen Benutzung einer Archivdiskette
+   muß diese formatiert, d.h. in Spuren und Sektoren für die Positionierung des
+   Schreib-/Lesekopfes des Diskettenlaufwerks eingeteilt werden, um überhaupt ein
+   Beschreiben der Diskette zu ermöglichen. Die Einteilung ist geräteabhängig, häufi­
+   ge Formate sind: 
+ 
+              40 Spuren zu je 9 Sektoren (360 K) 
+              80 Spuren zu je 9 Sektoren (720 K). 
+ 
+   Die #on("b")#Erst#off("b")#benutzung einer #ib#Archivdiskette#ie# erfordert nach der Reservierung des Ar­
+   chivs das Kommando: 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    archive("diskname"); 
+ 
+    gib kommando : 
+    format (archive); 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Erst nach einer Kontrollabfrage: 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando: 
+    format (archive) 
+ 
+  Archiv "diskname" formatieren ? (j/n) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+   wird tatsächlich formatiert und die Diskette steht mit dem Namen "diskname" für
+   Archivoperationen zur Verfügung. 
+ 
+#page# 
+ 
+   #on("b")#PROC format (INT CONST code, TASK CONST archive) #off("b")# 
+   Bei einigen Rechnern ist es möglich, die Formatierung zu variieren. Falls beim
+   Formatieren auf einem solchen Rechner ein anderes als das Standardformat
+   erzeugt werden soll, so ist die Codierung des gewünschten Formats mitanzuge­
+   ben. 
+ 
+ 
+   Beispiel:    Für ein Gerät mit 5,25 Zoll Disketten wäre z.B. einstellbar: 
+                code 0 : Standardformat 
+                code 1 : 2D , 40 Spuren , 9 Sektoren 
+                code 2 : 2D , 80 Spuren , 9 Sektoren 
+                code 3 : HD , 80 Spuren ,15 Sektoren 
+ 
+                'format (archive)' erzeugt ebenso wie 'format (0,archive)' eine
+                standardformatierte Diskette, 'format (3,archive)' erzeugt eine High
+                Density Formatierung (HD Floppy benutzen!). 
+ 
+#on("b")# 
+   ACHTUNG:   Wird eine bereits beschriebene Diskette noch einmal formatiert, so
+              sind alle Daten, die auf der Diskette waren, verloren. 
+ 
+              Die Umformatierung einer Diskette (z.B. von 720K auf 360K) auf
+              unterschiedlichen Laufwerken kann zu Problemen führen. 
+#off("b")# 
+#page# 
+'check' 
+   #on("b")#PROC check (TEXT CONST dateiname, TASK CONST task) #off("b")# 
+   Überprüft, ob die Datei 'dateiname' auf dem Archiv lesbar ist. 
+ 
+ 
+   #on("b")#PROC check (THESAURUS CONST t, TASK CONST task) #off("b")# 
+   Überprüft, ob die in dem Thesaurus 't' enthaltenen Dateien auf dem Archiv lesbar
+   sind. 
+ 
+ 
+   Mit diesem Kommando kann nach dem Beschreiben einer Diskette überprüft wer­
+   den, ob die Datei(en) lesbar sind. Hierdurch können also verschmutzte oder
+   beschädigte Disketten erkannt werden. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    save (all , archive) 
+ 
+    gib kommando : 
+    check (ALL archive, archive) 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+ 
+Beispiel: 
+ 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    archive ("neu") 
+ 
+    gib kommando : 
+    format (archive) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+liefert zunächst die Kontollfrage: 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    format (archive) 
+ 
+    Archiv "neu" formatieren ? (j/n) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nach Eingabe 'j' 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    saveall (archive) 
+ 
+    gib kommando : 
+    archive("alt") (* nächste Diskette *) 
+ 
+    gib kommando : 
+    fetch(SOME archive ,archive) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Der Thesaurus des Archivs wird angezeigt: 
+#page# 
+____________________________________________________________________________ 
+ 
+  .................alt (100 K belegt von 720 K)...............  
+ 
+ 01.02.87   25 K  "handbuch teil 1" 
+ 01.03.87   23 K  "handbuch teil 2" 
+ 01.04.87   20 K  "handbuch teil 3" 
+ 01.05.87   32 K  "handbuch teil 4" 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+ 
+Zum Abschluß Archiv freigeben! 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    release(archive) 
+ 
+____________________________________________________________________________ 
+#page# 
+
+Fehlermeldungen des Archivs
+Versucht man, eine Datei vom Archiv zu holen, kann es vorkommen, daß das Ar­
+chiv-System 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando : 
+    fetch ("datei", archive) 
+    #ib#Lese-Fehler (Archiv)#ie# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+meldet und den Lese-Vorgang abbricht. Dies kann auftreten, wenn die Floppy
+beschädigt oder aus anderen Gründen nicht lesbar ist (z.B. nicht justierte Disket­
+ten-Geräte). In einem solchen Fall vermerkt das Archiv-System intern, daß die Datei
+nicht korrekt gelesen werden kann. Das sieht man z.B. bei 'list (archive)'. Dort ist der
+betreffende Datei-Name mit dem Zusatz 'mit Lese-Fehler' gekennzeichnet. Um
+diese Datei trotzdem zu lesen, muß man sie unter ihrem Dateinamen mit dem Zusatz
+'mit Lese-Fehler' lesen. 
+ 
+____________________________________________________________________________ 
+ 
+    gib kommando: 
+    fetch ("datei mit Lese-Fehler", archive) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Die Datei wird in diesem Fall trotz Lese-Fehler (Informationsverlust!) vom Archiv
+gelesen. 
+#page# 
+
+Weitere Fehlermeldungen des Archivs: 
+ 
+ 
+FEHLER : Lesen unmöglich (Archiv) 
+         Die Archiv-Diskette ist nicht eingelegt oder die Tür des Laufwerks ist nicht
+         geschlossen. 
+         => Diskette einlegen bzw. Tür schließen. 
+ 
+FEHLER : Schreiben unmöglich (Archiv) 
+         Die Diskette ist schreibgeschützt. 
+         => falls wirklich gewünscht, Schreibschutz entfernen. 
+ 
+FEHLER : Archiv nicht angemeldet 
+         Das Archiv wurde nicht angemeldet 
+         => 'archive ("name")' geben. 
+ 
+FEHLER : Lese-Fehler (Archiv) 
+         Siehe Lesen unmöglich 
+ 
+FEHLER : Schreibfehler (Archiv) 
+         Die Diskette kann nicht (mehr) beschrieben werden. 
+         => Andere Diskette verwenden. 
+ 
+FEHLER : Speicherengpass 
+         Im System ist nicht mehr genügend Platz, um eine Datei vom Archiv zu
+         laden. 
+         => ggf. Dateien löschen. 
+ 
+FEHLER : RERUN bei Archiv-Zugriff Das System wurde bei einer Archiv-Operation
+         durch Ausschalten bzw. Reset unterbrochen. 
+ 
+FEHLER : "dateiname" gibt es nicht 
+         Die Datei "dateiname" gibt es nicht auf dem Archiv. 
+         => mit 'list(archive)' Archiv prüfen. 
+ 
+FEHLER : Archiv heißt ... 
+         Die eingelegte Diskette hat einen anderen als den eingegebenen Archivna­
+         men. 
+         => Kommando 'archive' mit korrektem Namen geben. 
+ 
+FEHLER : Archiv wird von Task ... benutzt 
+         Das Archiv wurde von einem anderen Benutzer reserviert. 
+         => Abwarten. 
+ 
+FEHLER : "dateiname" kann nicht geschrieben werden (Archiv voll) 
+         Die Datei ist zu groß für die eingelegte Diskette. 
+         => Andere Diskette für diese Datei nehmen. 
+ 
+FEHLER : Archiv inkonsistent 
+         Die eingelegte Diskette hat nicht die Struktur einer Archiv-Diskette. 
+         => 'format (archive)' vergessen. 
+ 
+FEHLER : save/erase wegen Lese-Fehler verboten 
+         Bei Archiven mit Lese-Fehler sind Schreiboperationen verboten, weil ein
+         Erfolg nicht garantiert werden kann. 
+
diff --git a/doc/programming/programmierhandbuch.5 b/doc/programming/programmierhandbuch.5
new file mode 100644
index 0000000..a921572
--- /dev/null
+++ b/doc/programming/programmierhandbuch.5
@@ -0,0 +1,1329 @@
+#pagenr("%",1)##setcount(1)##block##pageblock# 
+#headeven# 
+#center#EUMEL-Benutzerhandbuch 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#TEIL 5 : Programmierung 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+5 - % #right#GMD 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+GMD #right#5 - % 
+#end# 
+ 
+TEIL 5:  Programmierung 
+ 
+ 
+5.1  Der ELAN-Compiler  
+ 
+Der ELAN-Compiler des EUMEL-Systems dient zweierlei Aufgaben: zum einen der
+Übersetzung von ELAN-Programmen, zum anderen der Verwaltung der taskeigenen
+Modulbibliothek. 
+ 
+Diese Moduln, in ELAN Pakete (siehe 2.4.3.4ff.) genannt, stellen als vorübersetzte,
+und damit abrufbereite#u#1)#e# Prozeduren den Kommandovorrat einer Task dar. 
+ 
+Der Codebereich einer Task liegt in ihrem Standarddatenraum (ds4). Die Größe dieses
+Codebereiches beträgt 256K. Der Inhalt besteht zunächst aus den von der Vatertask
+ererbten (durch Kopie des ds4 dieser Task) Moduln, im weiteren allen in dieser Task
+neu hinzu insertierten Packeten. 
+#on("b")# 
+ 
+ 
+ACHTUNG:   Durch ständiges Neuinsertieren eines Packets kann der
+           Codebereich der betroffenen Task zum Überlaufen
+           gebracht werden! 
+ 
+ 
+#foot# 
+ 
+1) Die von anderen Systemen her gewohnten Phasen 'Binden' und 'Laden' sind
+   durch das EUMEL-ELAN-Compiler-Konzept unnötig. 
+#end# 
+Jedes Kommando im EUMEL-System ist der Aufruf einer, in der Schnittstelle eines
+bereits insertierten Packetes stehenden, Prozedur. 
+ 
+Kommandos für den ELAN-Compiler: 
+ 
+- Übersetzen               :  do , insert , run , runagain 
+ 
+- Protokollieren           :  check , checkon/off , 
+                              prot , protoff , warnings on/off 
+ 
+ 
+#page# 
+'do' 
+   #on("b")#PROC do (TEXT CONST program)#off("b")# 
+   Übersetzen und Ausführen von 'program' von einem Programm aus. 'program'
+   muß ein ausführbares ELAN Programm sein. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ ........................... Beispiel .......................... 
+ PACKET reo DEFINES reorganize all: 
+ 
+ PROC reorganize all(THESAURUS CONST thes): 
+ do (PROC (TEXT CONST) reorganize ,thes) 
+    (* Die Prozedur 'reorganize' (siehe 5-52), die einen*) 
+    (* Dateinamen als Parameter verlangt, wird auf alle *) 
+    (* Dateien des Thesaurus 'thes' angewandt.          *) 
+ END PROC reorganize all; 
+ END PACKET reo; 
+ 
+____________________________________________________________________________ 
+ 
+ 
+'insert' 
+   #on("b")#PROC insert (TEXT CONST dateiname) #off("b")# 
+   Insertieren eines oder mehrerer PACKETs aus der Datei 'dateiname'. Der Pro­
+   grammtext muß sich in #on("u")#einer#off("u")# Datei befinden. 
+ 
+ 
+   #on("b")#PROC insert #off("b")# 
+   Insertieren eines oder mehrerer PACKETs. Der Dateiname ist der zuletzt benutzte
+   Dateiname. 
+ 
+ 
+   #on("b")#PROC insert (THESAURUS CONST t) #off("b")# 
+   Insertieren aller PACKETs, die in den Dateien des Thesaurus 't' enthalten sind. 
+ 
+ 
+#page# 
+'run' 
+   #on("b")#PROC run #off("b")# 
+   Übersetzen und Ausführen eines ELAN-Programms. Der Programmtext muß sich
+   in einer Datei befinden. Der Dateiname ist der zuletzt benutzte Dateiname. 
+ 
+ 
+   #on("b")#PROC run (TEXT CONST dateiname) #off("b")# 
+   Wie oben. Der Programmtext wird aus der Datei mit dem Namen 'dateiname'
+   geholt. 
+ 
+ 
+ 
+'runagain' 
+   #on("b")#PROC runagain #off("b")# 
+   Nochmaliges Ausführen des zuletzt mit 'run' übersetzten ELAN-Programms.
+   Wurde in der letzten Übersetzung ein Fehler gefunden, erfolgt die Meldung: 
+ 
+   FEHLER :  "run again nicht möglich" 
+ 
+#page# 
+'check' 
+   #on("b")#BOOL PROC check #off("b")# 
+   Informationsprozedur, die TRUE liefert, wenn 'check' eingeschaltet ist. 
+ 
+   #on("b")#PROC check on #off("b")# 
+   Einschalten der Generierung von Zeilennummern durch den ELAN-Compiler. Der
+   bei der Übersetzung erzeugte Code wird ca. 25% umfangreicher! 
+   Voreinstellung im 'PUBLIC'- Zweig: 'check on'. 
+ 
+   #on("b")#PROC check off #off("b")# 
+   Ausschalten der Generierung von Zeilennummern durch den ELAN-Compiler. 
+   Voreinstellung im 'SYSUR' - Zweig: 'check off. 
+ 
+ 
+'prot' 
+   #on("b")#BOOL PROC prot #off("b")# 
+   Informationsprozedur, die TRUE liefert, gdw. 'prot' eingeschaltet ist. 
+ 
+   #on("b")#PROC prot (TEXT CONST dateiname) #off("b")# 
+   Einschalten des Compilerlistings auf dem Bildschirm. Das Listing wird gleichzeitig
+   in die Datei 'dateiname' geschrieben. 
+ 
+   #on("b")#PROC prot off #off("b")# 
+   Ausschalten des Listings. 
+ 
+ 
+'warnings' 
+   #on("b")#BOOL PROC warnings #off("b")# 
+   Informationsprozedur, die TRUE liefert gdw. 'warnings' eingeschaltet ist. 
+ 
+   #on("b")#PROC warnings on #off("b")# 
+   Warnungen werden wie Fehlermeldungen ins Notizbuch ausgegeben. 
+ 
+   #on("b")#PROC warnings off#off("b")# 
+   Warnungen werden nicht mit in das Notizbuch ausgegeben. 
+#page# 
+
+5.1.1  Fehlermeldungen des ELAN-Compilers 
+erfolgen stets in der Form: 
+ 
+#ib#COMPILER ERROR#ie#: <zahl> 
+ 
+wobei <zahl> folgende Werte annehmen kann: 
+ 
+#on("bold")#<zahl>   Bedeutung und eventuelle Abhilfe#off ("bold")#: 
+ 
+ 101      Überlauf der Namenstabelle 
+          Die Anzahl der Namen aller sichtbaren Pakete ist zu groß oder es wurden
+          die Anführungstriche eines TEXT-Denoters vergessen. 
+          => Keine Abhilfe. 
+ 
+ 102      Überlauf der Symboltabelle 
+          Die Anzahl der deklarierten Objekte ist zu groß. 
+          => Programm in Pakete unterteilen. 
+ 
+ 103      Überlauf des Zwischencodebereiches 
+          => Programm in Pakete unterteilen. 
+ 
+ 104      Überlauf der Permanenttabelle 
+          Zu viele Pakete insertiert. 
+          => Keine (neue Task beginnen). 
+ 
+ 106      Paketdatenadresse zu groß 
+          Im Paket wird zuviel Platz ( > 64K ) von globalen Datenobjekten und
+          Denotern eingenommen. 
+          => Keine Abhilfe. 
+ 
+ 107      Lokale Datenadresse zu groß 
+          Im Paket wird zuviel Platz ( > 32K ) von lokalen Datenobjekten belegt. 
+          => Keine Abhilfe. 
+ #page# 
+ 204      Überlauf des Compilerstack 
+          => Keine Abhilfe. 
+ 
+ 301      Modulnummern-Überlauf 
+          Zu viele sichtbare Pakete, Prozeduren und Operatoren ( > 2048 ). 
+         =>  Keine Abhilfe. 
+ 
+ 303 
+          siehe 304 
+ 
+ 304      Zu viele Ansprungadressen 
+          In dem gerade übersetzten Modul (Prozedur, Operator oder Paketrumpf)
+          werden vom Compiler zu viele Marken benötigt (mehr als 2000). Marken
+          werden z.B. für die Codegenerierung von Auswahl (IF ...) und Wieder­
+          holung (REP ...) gebraucht. Insbesondere bei SELECT-Anweisungen
+          werden 'casemax - casemin + 2' Marken benötigt, wobei 'casemax' der
+          INT-Wert des maximalen, 'casemin' der des minimalen CASE-Wertes
+          ist. Dieser Fehler ist somit fast immer auf zu viele und/oder zu weit ge­
+          spannte SELECT-Anweisungen zurückzuführen. 
+          => SELECT-Anweisungen über mehrere Prozeduren verteilen oder
+             Spannweiten verringern. 
+ 
+ 305      Codeüberlauf 
+          Der insgesamt erzeugte sichtbare Code ist zu umfangreich ( > 256K ). 
+          => Keine Abhilfe. 
+ 
+ 306      Paketdatenadresse zu groß 
+          Insgesamt zu viele Datenobjekte in den Paketen ( > 128K ). 
+          => Keine Abhilfe. 
+ 
+ 307      Temporäre Datenadresse zu groß 
+          Zu viele (lokale) Datenobjekte in einer Prozedur ( > 32K ). 
+          => Prozedur in mehrere unterteilen, so daß die Datenobjekte sich über
+             mehrere Prozeduren verteilen. 
+ 
+ 308      Modulcode-Überlauf 
+          Ein Modul (Prozedur, Operator oder Paket-Initialisierungsteil) ist zu groß
+          ( > 7.5 KB Code). 
+          => In mehrere Prozeduren oder Pakete zerlegen. 
+ 
+ 309      Zuviele Paketdaten 
+          (Insgesamt mehr als 128K Paketdaten) 
+          => Keine Abhilfe 
+ 
+ 
+#page# 
+ 
+5.2  Standardtypen 
+ 
+ 
+5.2.1  Bool 
+ 
+Der Wertebereich für Datenobjekte vom Typ BOOL besteht aus den Werten TRUE
+und FALSE. 
+ 
+'AND' 
+   #on("b")#BOOL OP AND (BOOL CONST a, b) #off("b")# 
+   Logisches UND, liefert TRUE gdw. a und b TRUE sind. 
+ 
+ 
+'CAND' 
+   #on("b")#BOOL OP CAND #off("b")# 
+   Bedingtes logisches UND, entspricht: 'IF a THEN b ELSE false FI'. Der zweite
+   Operand wird nicht ausgewertet, falls er für das Ergebnis nicht relevant ist. 
+ 
+ 
+'COR' 
+   #on("b")#BOOL OP COR #off("b")# 
+   Bedingtes logisches ODER, entspricht: 'IF a THEN true ELSE b FI'. Der zweite
+   Operand wird nicht ausgewertet, falls er für das Ergebnis nicht relevant ist. 
+ 
+
+'false' 
+   #on("b")#BOOL CONST false #off("b")# 
+ 
+ 
+'NOT' 
+   #on("b")#BOOL OP NOT (BOOL CONST a) #off("b")# 
+   Logische Negation. 
+ 
+ 
+'OR' 
+   #on("b")#BOOL OP OR (BOOL CONST a, b) #off("b")# 
+   Logisches ODER, liefert TRUE gdw. a und/oder b TRUE ist. 
+ 
+ 
+'true' 
+   #on("b")#BOOL CONST true #off("b")# 
+ 
+ 
+'XOR' 
+   #on("b")#BOOL OP XOR (BOOL CONST a, b) #off("b")# 
+   Exklusives ODER, liefert TRUE gdw. entweder a oder b TRUE ist. 
+ 
+#page# 
+
+5.2.2  Integer-Arithmetik 
+ 
+Ein Datenobjekt vom Typ INT belegt im Speicher 2 Bytes. Zulässige INT - Werte
+sind die ganzen Zahlen von -32768 bis +32767 einschließlich. 
+ 
+Falls größere ganze Zahlen benötigt werden, muß das Packet 'LONGINT', welches
+sich auf dem Archive 'std.zusatz' befindet, nachinsertiert werden (siehe 6.1.2). 
+ 
+Operationen für Integers: 
+ 
+- Vergleich                :  = , <> , < , <= , > , >= 
+ 
+- Verknüpfung              :  + , - , * , ** , DECR , DIV , INCR 
+ 
+- Sonstiges                :  abs , ABS , initialize random , max , maxint , min , 
+                              minint , MOD , random , sign , SIGN , text 
+#page# 
+':=' 
+   #on("b")#INT OP := (INT VAR a, INT CONST b) #off("b")# 
+   Zuweisung. 
+ 
+ 
+'=' 
+   #on("b")#BOOL OP = (INT CONST a, b) #off("b")# 
+   Vergleich. 
+ 
+ 
+'<>' 
+   #on("b")#BOOL OP <> (INT CONST a, b) #off("b")# 
+   Vergleich auf Ungleichheit. 
+ 
+ 
+'<' 
+   #on("b")#BOOL OP < (INT CONST a, b) #off("b")# 
+   Vergleich auf kleiner. 
+ 
+ 
+'<=' 
+   #on("b")#BOOL OP <= (INT CONST a, b) #off("b")# 
+   Vergleich auf kleiner gleich. 
+ 
+ 
+'>' 
+   #on("b")#BOOL OP > (INT CONST a, b) #off("b")# 
+   Vergleich auf größer. 
+ 
+ 
+'>=' 
+   #on("b")#BOOL OP >= (INT CONST a, b) #off("b")# 
+   Vergleich auf größer gleich. 
+ 
+#page# 
+'+' 
+   #on("b")#INT OP + (INT CONST a) #off("b")# 
+   Monadischer Operator (Vorzeichen, ohne Wirkung). 
+ 
+   #on("b")#INT OP + (INT CONST a, b) #off("b")# 
+   Addition. 
+ 
+ 
+'-' 
+   #on("b")#INT OP - (INT CONST a) #off("b")# 
+   Vorzeichen-Umkehrung. 
+ 
+ 
+   #on("b")#INT OP - (INT CONST a, b) #off("b")# 
+   Subtraktion. 
+ 
+ 
+'*' 
+   #on("b")#INT OP * (INT CONST a, b) #off("b")# 
+   Multiplikation. 
+ 
+ 
+'**' 
+   #on("b")#INT OP ** (INT CONST arg, exp) #off("b")# 
+   Exponentiation mit 'exp' >= 0 
+ 
+ 
+'DECR' 
+   #on("b")#OP DECR (INT VAR links, INT CONST rechts) #off("b")# 
+   Wirkt wie links := links - rechts 
+ 
+ 
+'DIV' 
+   #on("b")#INT OP DIV (INT CONST a, b) #off("b")# 
+   INT-Division. 
+ 
+   FEHLER : 
+   - DIV durch 0 
+ 
+ 
+'INCR' 
+   #on("b")#OP INCR (INT VAR links, INT CONST rechts) #off("b")# 
+   Wirkt wie links := links + rechts 
+ 
+#page# 
+'abs' 
+   #on("b")#INT PROC abs (INT CONST argument) #off("b")# 
+   Absolutbetrag eines INT-Wertes. 
+ 
+ 
+   #on("b")#INT OP ABS (INT CONST argument) #off("b")# 
+   Absolutbetrag eines INT-Wertes. 
+ 
+ 
+'initialize random' 
+   #on("b")#PROC initialize random (INT CONST wert) #off("b")# 
+   Initialisieren der 'random'-Prozedur, um nicht reproduzierbare Zufallszahlen zu
+   bekommen. Diese 'initialize random'-Prozedur gilt für den "INT-Random Gene­
+   rator". 
+ 
+ 
+'max' 
+   #on("b")#INT PROC max (INT CONST links, rechts) #off("b")# 
+   Liefert den Größten der beiden INT-Werte. 
+ 
+ 
+'maxint' 
+   #on("b")#INT CONST maxint #off("b")# 
+   Größter INT-Wert im EUMEL-System (32 767). 
+ 
+ 
+'min' 
+   #on("b")#INT PROC min (INT CONST links, rechts) #off("b")# 
+   Liefert den Kleinsten der beiden INT-Werte. 
+ 
+ 
+        min ( 3.0, 2.0) ==>  2.0 
+        min (-2.0, 3.0) ==> -2.0 
+ 
+ 
+ 
+'minint' 
+   #on("b")#INT CONST minint #off("b")# 
+   Kleinster INT-Wert im EUMEL-System (-32768). 
+ 
+ 
+'MOD' 
+   #on("b")#INT OP MOD (INT CONST links, rechts) #off("b")# 
+   Liefert den Rest einer INT-Division. 
+ 
+ 
+        3 MOD 2 ==> 1 
+       -3 MOD 2 ==> 1 
+ 
+ 
+  FEHLER : 
+  - DIV durch 0 
+ 
+ 
+'random' 
+   #on("b")#INT PROC random (INT CONST lower bound, upper bound) #off("b")# 
+   Pseudo-Zufallszahlen-Generator im Intervall 'upper bound' und 'lower bound'
+   einschließlich. Es handelt sich hier um den "INT Random Generator". 
+ 
+ 
+'real' 
+   #on("b")#REAL PROC real (INT CONST a) #off("b")# 
+   Konvertierungsprozedur. 
+ 
+#page# 
+'sign' 
+   #on("b")#INT PROC sign (INT CONST argument) #off("b")# 
+   Feststellen des Vorzeichens eines INT-Wertes. Folgende Werte werden geliefert: 
+ 
+ 
+        argument > 0     ==>  1 
+        argument = 0     ==>  0 
+        argument < 0     ==> -1 
+ 
+ 
+ 
+   #on("b")#INT OP SIGN (INT CONST argument) #off("b")# 
+   Feststellen des Vorzeichens eines INT-Wertes. 
+ 
+ 
+'text' 
+   #on("b")#TEXT PROC text (INT CONST zahl) #off("b")# 
+   Konvertierung des INT Wertes 'zahl' in den kürzest möglichen Text. Das Vorzei­
+   chen bleibt erhalten. 
+ 
+   #on("b")#TEXT PROC text (INT CONST zahl, länge) #off("b")# 
+   Konvertierung des INT Wertes 'zahl' in einen Text der Länge 'länge'. Das
+   Vorzeichen bleibt erhalten. Falls der Text kürzer als 'länge' ist, wird er links
+   (vorne) mit Leerzeichen aufgefüllt, falls er länder ist wird 'länge' mal "*"
+   ausgegeben. 
+ 
+____________________________________________________________________________ 
+ 
+    out ("X:"); out(text(12345,7)) ; line; 
+    out ("Y:"); out(text(12345,3)) ; 
+        (* ergibt *) 
+    X:  12345 
+    Y:*** 
+ 
+____________________________________________________________________________ 
+#page# 
+ 
+5.2.3  Real-Arithmetik 
+ 
+Für den Datentyp REAL gibt es außer den üblichen Verknüpfungs- und Vergleichs­
+operationen noch eine Anzahl mathematischer Prozeduren und Operationen. Teilweise
+stehen diese in mehr als einer Version zur Verfügung. 
+ 
+Jedes Datenobjekt vom Typ REAL belegt im Speicher 8 Byte. 
+ 
+REALs haben eine 13-stellige #ib#Mantisse#ie#, die im Rechner dezimal geführt wird. (Das
+heißt, bei Konversionen zwischen interner und TEXT-Darstellung treten keine Run­
+dungsfehler auf.) Der Wertebereich wird durch folgende Eckwerte abgegrenzt: 
+#dpos(0.5,".")##lpos(4.5)# 
+ 
+#table# 
+   9.999999999999e+126    größter REAL-Wert 
+   0.000000000001         kleinster positiver REAL-Wert mit x + 1.0 > 1.0 
+   9.999999999999e-126    kleinster positiver REAL-Wert > 0.0 
+  -9.999999999999e-126    größter negativer REAL-Wert 
+  -9.999999999999e+126    kleinster REAL-Wert 
+ 
+#clearpos# 
+#tableend# 
+ 
+- Vergleiche               :  = , <> , < , <= , > , >= 
+ 
+- Verknüpfungen            :  + , - , * , / , ** , DECR , INCR 
+ 
+- Diverse                  :  abs , arctan , arctand , cos , cosd , decimal 
+                              exponent , e , exp , floor , frac , initialize 
+                              random , int , ln , log2 , log10 , max , 
+                              maxreal , min , MOD , pi , random , round , 
+                              sign , SIGN , sin , sind , smallreal , sqrt , 
+                              tan , tand , text 
+ 
+#page# 
+':=' 
+   #on("b")#REAL OP := (REAL VAR a, REAL CONST b) #off("b")# 
+   Zuweisung. 
+ 
+ 
+'=' 
+   #on("b")#BOOL OP = (REAL CONST a, b) #off("b")# 
+   Vergleich. 
+ 
+ 
+'<>' 
+   #on("b")#BOOL OP <> (REAL CONST a, b) #off("b")# 
+   Vergleich auf Ungleichheit. 
+ 
+ 
+'<' 
+   #on("b")#BOOL OP < (REAL CONST a, b) #off("b")# 
+   Vergleich auf kleiner. 
+ 
+ 
+'<=' 
+   #on("b")#BOOL OP <= (REAL CONST a, b) #off("b")# 
+   Vergleich auf kleiner gleich. 
+ 
+ 
+'>' 
+   #on("b")#BOOL OP > (REAL CONST a, b) #off("b")# 
+   Vergleich auf größer. 
+ 
+ 
+'>=' 
+   #on("b")#BOOL OP >= (REAL CONST a, b) #off("b")# 
+   Vergleich auf größer gleich. 
+ 
+#page# 
+'+' 
+   #on("b")#REAL OP + (REAL CONST a) #off("b")# 
+   Monadischer Operator (Vorzeichen, ohne Wirkung). 
+ 
+ 
+   #on("b")#REAL OP + (REAL CONST a, b) #off("b")# 
+   Addition. 
+ 
+ 
+'-' 
+   #on("b")#REAL OP - (REAL CONST a) #off("b")# 
+   Vorzeichen-Umkehrung. 
+ 
+ 
+   #on("b")#REAL OP - (REAL CONST a, b) #off("b")# 
+   Subtraktion. 
+ 
+ 
+'*' 
+   #on("b")#REAL OP * (REAL CONST a, b) #off("b")# 
+   Multiplikation. 
+ 
+ 
+'/' 
+   #on("b")#REAL OP / (REAL CONST a, b) #off("b")# 
+   Division. 
+ 
+   FEHLER : 
+   - Division durch 0 
+ 
+ 
+'**' 
+   #on("b")#REAL OP ** (REAL CONST arg, exp) #off("b")# 
+   Exponentiation. 
+ 
+   #on("b")#REAL OP ** (REAL CONST arg, INT CONST exp) #off("b")# 
+   Exponentiation. 
+ 
+ 
+'DECR' 
+   #on("b")#OP DECR (REAL VAR links, REAL CONST rechts) #off("b")# 
+   Wirkt wie links := links - rechts 
+ 
+ 
+'INCR' 
+   #on("b")#OP INCR (REAL VAR links, REAL CONST rechts) #off("b")# 
+   Wirkt wie links := links + rechts 
+ 
+#page# 
+'abs' 
+   #on("b")#REAL PROC abs (REAL CONST wert) #off("b")# 
+   Absolutbetrag eines REAL-Wertes. 
+ 
+   #on("b")#REAL OP ABS (REAL CONST wert) #off("b")# 
+   Absolutbetrag eines REAL-Wertes. 
+ 
+ 
+'arctan' 
+   #on("b")#REAL PROC arctan (REAL CONST x) #off("b")# 
+   Arcus Tangens-Funktion. Liefert einen Wert in Radiant. 
+ 
+ 
+'arctand' 
+   #on("b")#REAL PROC arctand (REAL CONST x) #off("b")# 
+   Arcus Tangens-Funktion. Liefert einen Wert in Grad. 
+ 
+ 
+'cos' 
+   #on("b")#REAL PROC cos (REAL CONST x) #off("b")# 
+   Cosinus-Funktion. 'x' muß in Radiant angegeben werden. 
+ 
+ 
+'cosd' 
+   #on("b")#REAL PROC cosd (REAL CONST x) #off("b")# 
+   Cosinus-Funktion. 'x' muß in Winkelgrad angegeben werden. 
+ 
+ 
+'decimal exponent' 
+   #on("b")#INT PROC decimal exponent (REAL CONST mantisse) #off("b")# 
+   Liefert aus einem REAL-Wert den dezimalen Exponenten als INT-Wert. 
+ 
+ 
+'e' 
+   #on("b")#REAL PROC e #off("b")# 
+   Eulersche Zahl (2.718282). 
+ 
+ 
+'exp' 
+   #on("b")#REAL PROC exp (REAL CONST z) #off("b")# 
+   Exponentialfunktion. 
+ 
+ 
+'floor' 
+   #on("b")#REAL PROC floor (REAL CONST real) #off("b")# 
+   Schneidet die Nachkommastellen des REAL-Wertes 'real' ab. 
+ 
+ 
+'frac' 
+   #on("b")#REAL PROC frac (REAL CONST z) #off("b")# 
+   Liefert die Stellen eines REAL-Wertes hinter dem Dezimalpunkt. 
+ 
+ 
+'initialize random' 
+   #on("b")#PROC initialize random (REAL CONST z) #off("b")# 
+   Initialisieren der 'random'-Prozedur mit verschiedenen Werten für 'z', um nicht
+   reproduzierbare Zufallszahlen zu bekommen. Diese Prozedur gilt für den
+   'REAL-Random Generator'. 
+ 
+ 
+'int' 
+   #on("b")#INT PROC int (REAL CONST a) #off("b")# 
+   Konvertierungsprozedur. Die Nachkommastellen werden abgeschnitten. 
+   Bsp:   int (3.9)  => 3 
+ 
+ 
+'ln' 
+   #on("b")#REAL PROC ln (REAL CONST x) #off("b")# 
+   Natürlicher Logarithmus. 
+ 
+   FEHLER : 
+   - ln mit negativer Zahl 
+     Nur echt positive Argumente sind zulässig. 
+ 
+ 
+'log2' 
+   #on("b")#REAL PROC log2 (REAL CONST z) #off("b")# 
+   Logarithmus zur Basis 2. 
+ 
+   FEHLER : 
+   - log2 mit negativer zahl 
+     Nur echt positive Argumente sind zulässig. 
+ 
+ 
+'log10' 
+   #on("b")#REAL PROC log10 (REAL CONST x) #off("b")# 
+   Logarithmus zur Basis 10. 
+ 
+   FEHLER : 
+   - log10 mit negativer zahl 
+     Nur echt positive Argumente sind zulässig. 
+ 
+ 
+'max' 
+   #on("b")#REAL PROC max (REAL CONST links, rechts) #off("b")# 
+   Liefert den Größten der beiden REAL-Werte. 
+ 
+ 
+'maxreal' 
+   #on("b")#REAL CONST maxreal #off("b")# 
+   Größter REAL-Wert im EUMEL-System (9.999999999999e126). 
+ 
+ 
+'min' 
+   #on("b")#REAL PROC min (REAL CONST links, rechts) #off("b")# 
+   Liefert den Kleinsten der beiden REAL-Werte. 
+ 
+ 
+'MOD' 
+   #on("b")#REAL OP MOD (REAL CONST links, rechts) #off("b")# 
+   Modulo-Funktion für REALs (liefert den Rest). Beispiele: 
+ 
+ 
+             5.0 MOD 2.0 ==> 1.0 
+             4.5 MOD 4.0 ==> 0.5 
+ 
+ 
+ 
+'pi' 
+   #on("b")#REAL CONST pi #off("b")# 
+   Die Zahl pi (3.141593). 
+ 
+ 
+'random' 
+   #on("b")#REAL PROC random #off("b")# 
+   Pseudo-Zufallszahlen-Generator im Intervall 0 und 1. Es handelt sich hier um
+   den "REAL Random Generator". 
+ 
+ 
+'round' 
+   #on("b")#REAL PROC round (REAL CONST real, INT CONST digits) #off("b")# 
+   Runden eines REAL-Wertes auf 'digits' Stellen. Für positive Werte wird auf
+   Nachkommastellen gerundet. Beispiel: 
+ 
+ 
+              round (3.14159, 3) 
+ 
+ 
+   liefert '3.142'. Für negative 'digits'-Werte wird auf Vorkommastellen gerundet. 
+ 
+ 
+              round (123.456, -2) 
+ 
+ 
+   liefert '100.0'. Abweichung vom Standard: Es wird mit 'digits'-Ziffern gerundet. 
+ 
+ 
+'sign' 
+   #on("b")#INT PROC sign (REAL CONST argument) #off("b")# 
+   Feststellen des Vorzeichens eines REAL-Wertes. 
+ 
+   #on("b")#INT OP SIGN (REAL CONST argument) #off("b")# 
+   Feststellen des Vorzeichens eines REAL-Wertes. 
+ 
+ 
+'sin' 
+   #on("b")#REAL PROC sin (REAL CONST x) #off("b")# 
+   Sinus-Funktion. 'x' muß in Radiant (Bogenmaß) angegeben werden. 
+ 
+ 
+'sind' 
+   #on("b")#REAL PROC sind (REAL CONST x) #off("b")# 
+   Sinus-Funktion. 'x' muß im Winkelgrad angegeben werden. 
+ 
+ 
+'smallreal' 
+   #on("b")#REAL PROC smallreal #off("b")# 
+   Kleinster darstellbarer REAL-Wert im EUMEL-System für den 
+ 
+ 
+        1.0 - smallreal <> 1.0 
+        1.0 + smallreal <> 1.0 
+ 
+ 
+   gilt (1.0E-12). 
+ 
+ 
+'sqrt' 
+   #on("b")#REAL PROC sqrt (REAL CONST z) #off("b")# 
+   Wurzel-Funktion. 
+ 
+   FEHLER : 
+   - sqrt von negativer Zahl 
+     Das Argument muß größer gleich 0.0 sein. 
+ 
+ 
+'tan' 
+   #on("b")#REAL PROC tan (REAL CONST x) #off("b")# 
+   Tangens-Funktion. 'x' muß in Radiant angegeben werden. 
+ 
+ 
+'tand' 
+   #on("b")#REAL PROC tand (REAL CONST x) #off("b")# 
+   Tangens-Funktion. 'x' muß in Winkelgrad angegeben werden. 
+ 
+ 
+'text' 
+   #on("b")#TEXT PROC text (REAL CONST real) #off("b")# 
+   Konvertierung eines REAL-Wertes in einen TEXT. Ggf. wird der TEXT in Expo­
+   nenten-Darstellung geliefert. 
+ 
+   #on("b")#TEXT PROC text (REAL CONST real, laenge) #off("b")# 
+   Konvertierung eines REAL-Wertes in einen TEXT. Der TEXT wird in Exponen­
+   ten-Darstellung geliefert. Um diese Darstellung zu ermöglichen ist der Wert
+   'laenge' größer oder gleich 8 anzugeben. 
+ 
+   #on("b")#TEXT PROC text (REAL CONST real, INT CONST laenge, fracs)#off("b")# 
+   Konvertierung eines REAL-Wertes in einen TEXT. Dabei gibt 'laenge' die Länge
+   des Resultats einschließlich des Dezimalpunktes und 'fracs' die Anzahl der Dezi­
+   malstellen an. Kann der REAL-Wert nicht wie gewünscht dargestellt werden, wird 
+ 
+ 
+              laenge * "*" 
+ 
+ 
+   geliefert. 
+ 
+#page# 
+ 
+5.2.4  Text 
+ 
+Jedes Datenobjekt vom Typ TEXT besteht aus einem festen Teil von 16 Bytes und
+möglicherweise aus einem flexiblen Teil auf dem #on("i")##on("b")#Heap#off("i")##off("b")#. Im festen Teil werden Texte
+bis zur Länge von 13 Zeichen untergebracht. Wenn eine TEXT-Variable einen Wert
+mit mehr als 13 Zeichen Länge annimmt, werden alle Zeichen auf dem Heap unterge­
+bracht. Genauer ergibt sich folgendes Bild: 
+ 
+     kurzer Text (Länge <= 13): 
+ 
+          Heap-Link    2 Bytes 
+          Textlänge    1 Byte 
+          Text        13 Bytes 
+ 
+     langer Text (Länge > 13): 
+ 
+          Heap-Link    2 Bytes 
+          255          1 Byte 
+          Länge        2 Bytes 
+          ungenutzt   11 Bytes 
+ 
+Wenn eine Variable einmal Platz auf dem Heap bekommen hat, behält sie diesen
+vorbeugend auch dann, wenn sie wieder einen kurzen Text als Wert erhält. So muß
+wahrscheinlich kein neuer Platz auf dem Heap zugewiesen werden, wenn sie wieder
+länger wird. Das gilt allerdings nur bis zur nächsten #ib#Garbage Collection#ie# auf den
+TEXT-Heap, denn dabei werden alle Heap-Container minimal gemacht bzw. ge­
+löscht, wenn sie nicht mehr benötigt werden. Der Platz auf dem Heap wird in Vielfa­
+chen von 16 Bytes vergeben. In Fremddatenräumen wird in jedem #ib#Container#ie# neben
+dem eigentlichen Text auch die Containerlänge untergebracht. 
+#page# 
+Beispiele:     TEXT-Länge    Speicherbedarf (Byte) 
+ 
+                   0                 16 
+                  13                 16 
+                  14                 32 
+                  15                 48 
+                  30                 48 
+                  31                 64 
+                  46                 64 
+                  47                 80 
+                  62                 80 
+ 
+ 
+Die Heapgröße eines Fremddatenraums berechnet sich als: 
+ 
+      1024 * 1024 = 1048056 - stat Bytes 
+ 
+'stat' ist dabei die statische Größe der Datenstruktur, die dem Datenraum aufgeprägt
+wurde. Bei einem BOUND ROW 1000 TEXT ergibt sich also eine Heapgröße von 
+ 
+      1048056 - (1000 * 16) = 1032056 Bytes. 
+ 
+ 
+ 
+'heap size' 
+   #on("b")#INT PROC heap size #off("b")# 
+   Informationsprozedur für die Größe (in KB) des TEXT-Heaps. 
+ 
+#page# 
+ 
+TEXT- Operationen: 
+ 
+- Vergleich                :  = , <> , < , <= , > , >= 
+                              LEXEQUAL , LEXGREATER , 
+                              LEXGREATEREQUAL 
+ 
+- Verkettung               :  + , * , CAT 
+ 
+- Veränderung              :  change , change all , code , compress , delete 
+                              char , insert char , length , LENGTH , max 
+                              text length , pos , real , replace , SUB , 
+                              subtext , text 
+#page# 
+
+Der EUMEL-Zeichensatz
+#goalpage("codetab")# 
+Das EUMEL System definiert einen Zeichensatz, der gewährleistet, daß gleiche Text­
+zeichen auf allen Maschinen gleich codiert werden. 
+     Die interne Darstellung wird durch die folgende EUMEL-Codetabelle
+beschrieben. Der Zeichensatz beruht auf dem ASCII-Zeichensatz mit Erweiterungen.
+Der in der Tabelle freie Bereich (z.B code(127) bis code(213)) ist nicht einheitlich
+verfügbar und wird deshalb nicht beschrieben. Die Codierung bildet mithin auch
+Grundlage für Vergleiche und Sortierungen. 
+ 
+Die Korrekte Darstellung dieser Zeichen auf Bildschirm, Drucker etc. setzt natürlich
+eine korrekte Konfiguration der Geräte voraus. Die Anpassung eines Geräts an diesen
+Zeichensatz ist im EUMEL-Systemhandbuch in Teil 2 beschrieben. 
+ 
+ 
+   I 0   1   2   3   4   5   6   7   8   9 
+---+-------------------------------------- 
+3  I        SP   !   "   \#   $   %   &   ' 
+   I 
+4  I (   )   *   +   ,   -   .   /   0   1 
+   I 
+5  I 2   3   4   5   6   7   8   9   :   ; 
+   I 
+6  I <   =   >   ?   §   A   B   C   D   E 
+   I 
+7  I F   G   H   I   J   K   L   M   N   O 
+   I 
+8  I P   Q   R   S   T   U   V   W   X   Y 
+   I 
+9  I Z   [   \   ]   ^   _   `   a   b   c 
+   I 
+10 I d   e   f   g   h   i   j   k   l   m 
+   I 
+11 I n   o   p   q   r   s   t   u   v   w 
+   I 
+12 I x   y   z   {   |   }   ~ 
+   I 
+13 I 
+.  I 
+.  I 
+.  I 
+20 I 
+   I 
+21 I                 Ä   Ö   Ü   ä   ö   ü 
+   I 
+22 I k   ­   \#   SP 
+   I 
+23 I 
+   I 
+24 I 
+   I 
+25 I     ß 
+#page# 
+':=' 
+   #on("b")#TEXT OP := (TEXT VAR a, TEXT CONST b) #off("b")# 
+   Zuweisung. 
+ 
+ 
+'=' 
+   #on("b")#BOOL OP = (TEXT CONST links, rechts) #off("b")# 
+   Vergleich von zwei Texten auf Gleichheit (Texte mit ungleichen Längen sind
+   immer ungleich). 
+ 
+ 
+'<>' 
+   #on("b")#BOOL OP <> (TEXT CONST links, rechts) #off("b")# 
+   Vergleich von zwei Texten auf Ungleichheit (Texte mit ungleichen Längen sind
+   stets ungleich). 
+ 
+ 
+'<' 
+   #on("b")#BOOL OP < (TEXT CONST links, rechts) #off("b")# 
+   Vergleich zweier Texte auf kleiner ('links' kommt lexikographisch vor 'rechts'). 
+ 
+ 
+'<=' 
+   #on("b")#BOOL OP <= (TEXT CONST links, rechts) #off("b")# 
+   Vergleich von zwei Texten auf kleiner gleich ('links' kommt lexikographisch vor
+   oder ist gleich 'rechts'). 
+ 
+ 
+'>' 
+   #on("b")#BOOL OP > (TEXT CONST links, rechts) #off("b")# 
+   Vergleich zweier Texte auf größer ('links' kommt lexikographisch nach 'rechts'). 
+ 
+ 
+'>=' 
+   #on("b")#BOOL OP >= (TEXT CONST links, rechts) #off("b")# 
+   Vergleich zweier Texte auf größer gleich ('links' kommt lexikographisch nach oder
+   ist gleich 'rechts'). 
+ 
+#page# 
+'LEXEQUAL' 
+   #on("b")#BOOL OP LEXEQUAL (TEXT CONST links, rechts) #off("b")# 
+   Prüfung auf lexikalische Gleichheit. 
+ 
+ 
+'LEXGREATER' 
+   #on("b")#BOOL OP LEXGREATER (TEXT CONST links, rechts) #off("b")# 
+   Prüfung ob der Text 'links' lexikalisch größer als 'rechts' ist. 
+ 
+ 
+'LEXGREATEREQUAL' 
+   #on("b")#BOOL OP LEXGREATEREQUAL (TEXT CONST links, rechts) #off("b")# 
+   Prüfung ob der Text 'links' lexikalisch größer oder gleich dem Text 'rechts' ist. 
+ 
+ 
+ 
+   Die drei Operatoren prüfen nach folgenden Regeln: 
+ 
+   - Buchstaben haben die aufsteigende Reihenfolge 'A' bis 'Z'. Dabei werden kleine
+     und große Buchstaben gleich behandelt. 
+ 
+   - Umlaute werden wie üblich ausgeschrieben. (Ä = Ae usw.) 
+                                           (ß = ss) 
+ 
+   - Alle Sonderzeichen (auch Ziffern) außer ' '(Leerzeichen) und '-' werden igno­
+     riert, diese beiden Zeichen werden gleich behandelt. 
+ 
+#page# 
+'+' 
+   #on("b")#TEXT OP + (TEXT CONST links, rechts) #off("b")# 
+   Verkettung der Texte 'links' und 'rechts' in dieser Reihenfolge. Die Länge des
+   Resultats ergibt sich aus der Addition der Längen der Operanden. 
+ 
+ 
+'*' 
+   #on("b")#TEXT OP * (INT CONST faktor, TEXT CONST quelle) #off("b")# 
+   'faktor' fache Erstellung von 'quelle' und Verkettung. Dabei muß 
+ 
+ 
+              times >= 0 
+ 
+ 
+   sein, sonst wird 'niltext' geliefert. 
+ 
+ 
+'CAT' 
+   #on("b")#OP CAT (TEXT VAR links, TEXT CONST rechts) #off("b")# 
+   hat die gleiche Wirkung wie 
+ 
+ 
+              links := links + rechts 
+ 
+ 
+   Hinweis: Der Operator 'CAT' hat eine geringere Heap-Belastung als die Opera­
+            tion mit expliziter Zuweisung. 
+ 
+#page# 
+'change' 
+   #on("b")#PROC change (TEXT VAR senke, TEXT CONST alt, neu) #off("b")# 
+   Ersetzung des (Teil-) TEXTes 'alt' in 'senke' durch 'neu' bei dem erstmaligen
+   Auftreten. Ist 'alt' nicht in 'senke' vorhanden, so wird keine Meldung abgesetzt
+   (Abweichung vom Standard). Die Länge von 'senke' kann sich dabei verändern. 
+   Beispiel: 
+ 
+ 
+        TEXT VAR mein text :: "EUMEL-Benutzerhandbuch"; 
+        change (mein text, "Ben", "N"); 
+                            (* EUMEL-Nutzerhandbuch *) 
+ 
+ 
+   #on("b")#PROC change (TEXT VAR senke, INT CONST von, bis, TEXT CONST neu) #off("b")# 
+   Der TEXT 'neu' wird in den TEXT 'senke' anstatt des TEXTes, der zwischen 'von'
+   und 'bis' steht, eingesetzt. Die Länge von 'senke' kann sich dabei verändern. 
+   Beispiel: 
+ 
+ 
+        TEXT VAR mein text :: "EUMEL-Benutzerhandbuch"; 
+        change (mein text, 7, 9, "N");   (* wie oben *) 
+ 
+ 
+ 
+'change all' 
+   #on("b")#PROC change all (TEXT VAR senke, TEXT CONST alt, neu) #off("b")# 
+   Der Teiltext 'alt' wird durch 'neu' in 'senke' ersetzt. Im Unterschied zur 'chan­
+   ge'-Prozedur findet die Ersetzung nicht nur bei dem erstmaligen Auftreten von
+   'alt' statt, sondern so oft, wie 'alt' in 'senke' vorhanden ist. Beispiel: 
+ 
+  
+        TEXT VAR x :: "Das ist ein Satz"; 
+        change all (x, " ", "");     (* DasisteinSatz *)  
+ 
+#page# 
+'code' 
+   #on("b")#TEXT PROC code (INT CONST code) #off("b")# 
+   Wandelt einen INT-Wert 'code' in ein Zeichen um. 'code' muß 
+ 
+ 
+        0 <= code <= 255 
+ 
+ 
+   sein. 
+ 
+   #on("b")#INT PROC code (TEXT CONST text) #off("b")# 
+   Wandelt ein Zeichen 'text' in einen INT-Wert um. Ist 
+ 
+ 
+        LENGTH text <> 1 
+ 
+ 
+   dann wird der Wert -1 geliefert (also bei mehr als ein Zeichen oder niltext). 
+   (Codetabelle auf Seite 5- #topage("codetab")#) 
+ 
+ 
+'compress' 
+   #on("b")#TEXT PROC compress (TEXT CONST text) #off("b")# 
+   Liefert den TEXT 'text' ohne führende und nachfolgende Leerzeichen. 
+ 
+ 
+'delete char' 
+   #on("b")#PROC delete char (TEXT VAR string, INT CONST delete pos)#off("b")# 
+   Löscht ein Zeichen aus dem Text 'string' an der Position 'delete pos'. Für 
+ 
+ 
+        delete pos <= 0 
+ 
+ 
+          oder 
+ 
+ 
+        delete pos > LENGTH string 
+ 
+ 
+   wird keine Aktion vorgenommen. 
+ 
+#page# 
+'insert char' 
+   #on("b")#PROC insert char (TEXT VAR string, TEXT CONST char,INT CONST insert pos)#off("b")# 
+   Fügt ein Zeichen 'char' in den Text 'string' an der Position 'insert pos' ein. Für 
+ 
+ 
+        insert pos > LENGTH string + 1 
+ 
+ 
+   wird keine Aktion vorgenommen. Daher ist es möglich, mit dieser Prozedur auch
+   am Ende eines Textes (Position: LENGTH string + 1) ein Zeichen anzufügen. 
+ 
+ 
+'length' 
+   #on("b")#INT PROC length (TEXT CONST text) #off("b")# 
+   Anzahl von Zeichen ("Länge") von 'text' einschließlich Leerzeichen. 
+ 
+ 
+'LENGTH' 
+   #on("b")#INT OP LENGTH (TEXT CONST text) #off("b")# 
+   Anzahl von Zeichen ("Länge") von 'text' einschließlich Leerzeichen. 
+ 
+ 
+'max text length' 
+   #on("b")#INT CONST max text length #off("b")# 
+   Maximale Anzahl von Zeichen in einem TEXT (32 000). 
+ 
+#page# 
+'pos' 
+   #on("b")#INT PROC pos (TEXT CONST quelle, pattern) #off("b")# 
+   Liefert die erste Position des ersten Zeichens von 'pattern' in 'quelle', falls 'pat­
+   tern' gefunden wird. Wird 'pattern' nicht gefunden oder ist 'pattern' niltext, so wird
+   der Wert '0' geliefert. Beispiel: 
+ 
+ 
+        TEXT VAR t1 :: "abcdefghijk...xyz", 
+                 t2 :: "cd"; 
+        ... pos (t1, t2) ... (* liefert 3 *) 
+        ... pos (t2, t1) ... (* liefert 0 *) 
+ 
+ 
+ 
+   #on("b")#INT PROC pos (TEXT CONST quelle, pattern, INT CONST von)#off("b")# 
+   Wie obige Prozedur, jedoch wird erst ab der Position 'von' ab gesucht. Dabei gilt
+   folgende Einschränkung: 
+ 
+ 
+        length (pattern) < 255 
+ 
+ 
+ 
+   #on("b")#INT PROC pos (TEXT CONST quelle, low char, high char, INT CONST von#off("b")# 
+   Liefert die Position des ersten Zeichens 'x' in 'quelle' ab der Position 'von', so daß 
+ 
+ 
+        low char <= x <= high char 
+ 
+ 
+   'low char' und 'high char' müssen TEXTe der Länge 1 sein. Wird kein Zeichen in
+   'quelle' in dem Bereich zwischen 'low char' und 'high char' gefunden, wird der
+   Wert '0' geliefert. Beispiel: 
+ 
+____________________________________________________________________________ 
+ 
+ (*Suche nach dem ersten Zeichen <> blank nach einer Leerspalte*) 
+   TEXT VAR zeile :: "BlaBla       Hier gehts weiter"; 
+   INT VAR pos erstes blank :: pos (zeile, " "), 
+   ende leerspalte  :: 
+         pos (zeile, ""33"",""254"", pos erstes blank); 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+'real' 
+   #on("b")#REAL PROC real (TEXT CONST text) #off("b")# 
+   Konvertierung eines TEXTes 'text' in einen REAL-Wert. Achtung: Zur Zeit werden
+   keine Überprüfungen vorgenommen, d.h. in dem TEXT muß ein REAL-Wert
+   stehen. 
+ 
+ 
+'replace' 
+   #on("b")#PROC replace (TEXT VAR senke, INT CONST position, TEXT CONST quelle)#off("b")# 
+   Ersetzung eines Teiltextes in 'senke' durch 'quelle' an der Position 'position' in
+   'senke'. Es muß gelten 
+ 
+ 
+        1 <= position <= LENGTH senke 
+ 
+ 
+   d.h. 'position' muß innerhalb von 'senke' liegen und 'quelle' muß von der Posi­
+   tion 'position' ab in 'senke' einsetzbar sein. Dabei bleibt die Länge von 'senke'
+   unverändert. 
+ 
+ 
+'SUB' 
+   #on("b")#TEXT OP SUB (TEXT CONST text, INT CONST pos) #off("b")# 
+   Liefert ein Zeichen aus 'text' an der Position 'pos'. Entspricht 
+ 
+ 
+        subtext (text, pos, pos) 
+ 
+ 
+   Anmerkung: Effizienter als obiger Prozedur-Aufruf. Für 
+ 
+ 
+        pos <= 0 
+        pos > LENGTH text 
+ 
+ 
+   wird niltext geliefert. 
+ 
+#page# 
+'subtext' 
+   #on("b")#TEXT PROC subtext (TEXT CONST quelle, INT CONST von) #off("b")# 
+   Teiltext von 'quelle', der bei der Position 'von' anfängt. Die Länge des Resultats
+   ergibt sich also zu 
+ 
+ 
+        LENGTH quelle - von + 1 
+ 
+ 
+   d.h. von der Position 'von' bis zum Ende von 'quelle'. 'von' muß innerhalb von
+   'quelle' liegen. Ist von < 1, dann wird 'quelle' geliefert. Falls von > LENGTH
+   quelle ist, wird niltext geliefert. 
+ 
+ 
+   #on("b")#TEXT PROC subtext (TEXT CONST quelle, INT CONST von, bis)#off("b")# 
+   Teiltext von 'quelle' von der Position 'von' bis einschließlich der Position 'bis'. Die
+   Länge des Resultats ist also 
+ 
+ 
+        bis -  von + 1 
+ 
+ 
+   Dabei muß gelten 
+ 
+ 
+        1 <= von <= bis <= LENGTH quelle 
+ 
+ 
+   d.h. die Positionen 'von' und 'bis' müssen in dieser Reihenfolge innerhalb von
+   'quelle' liegen. Ist 
+ 
+ 
+        bis >= LENGTH quelle 
+ 
+ 
+   wird 'subtext (quelle, von)' ausgeführt. Für die Bedingungen für 'von' siehe vor­
+   stehende Beschreibung von 'subtext'. 
+ 
+ 
+'text' 
+   #on("b")#TEXT PROC text (TEXT CONST quelle, INT CONST laenge) #off("b")# 
+   Teiltext aus 'quelle' mit der Länge 'laenge', beginnend bei der Position 1 von
+   'quelle'. Es muß gelten 
+ 
+ 
+              1 <= laenge <= LENGTH quelle 
+ 
+ 
+   d.h. der gewünschte Teiltext muß aus 'quelle' ausblendbar sein. 
+   Wenn gilt: 
+ 
+        laenge > LENGTH quelle 
+ 
+ 
+   wird der zu liefernde TEXT mit der an 'laenge' fehlenden Zeichen mit Leerzeichen
+   aufgefüllt. 
+ 
+   #on("b")#TEXT PROC text (TEXT CONST quelle, INT CONST laenge, von)#off("b")# 
+   Teiltext aus 'quelle' mit der Länge 'laenge', beginnend an der Position 'von' in
+   dem TEXT 'quelle'. Entspricht 
+ 
+ 
+        text (subtext (quelle, von, LENGTH quelle),laenge) 
+ 
+ 
+   Es muß 
+ 
+ 
+        laenge >= 0 
+        1 <= von <= LENGTH quelle 
+ 
+ 
+   gelten, d.h. 'von' muß eine Position angeben, die innerhalb von 'quelle' liegt. Für 
+ 
+ 
+        laenge > LENGTH quelle - von + 1 
+ 
+ 
+   also wenn die angegebene Länge 'laenge' größer ist als der auszublendende Text,
+   wird das Resultat rechts mit Leerzeichen aufgefüllt. Wenn 
+ 
+ 
+        laenge < LENGTH quelle - von + 1 
+ 
+ 
+    d.h. wenn die angegebene Länge kleiner ist als der Teiltext von 'von' bis zum
+    letzten Zeichen von 'quelle', wird das Resultat mit der Länge 
+ 
+ 
+        LENGTH quelle - von + 1 
+ 
+ 
+    geliefert. 
+
diff --git a/doc/programming/programmierhandbuch.5b b/doc/programming/programmierhandbuch.5b
new file mode 100644
index 0000000..d91bcc9
--- /dev/null
+++ b/doc/programming/programmierhandbuch.5b
@@ -0,0 +1,1481 @@
+#pagenr("%",40)##setcount(1)##block##pageblock# 
+#headeven# 
+#center#EUMEL-Benutzerhandbuch 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#TEIL 5 : Programmierung 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+5 - % #right#GMD 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+GMD #right#5 - % 
+#end# 
+ 
+5.3  Der Datentyp FILE (Textdateien) 
+ 
+Der Datentyp FILE definiert Dateien von sequentieller Struktur, die Texte enthalten.
+Ein Objekt vom Datentyp FILE ist charakterisiert durch: 
+ 
+1) seine Betriebsrichtung  :  input = nur lesender Zugriff 
+  (TRANSPUTDIRECTION)         output= nur schreibender Zugriff 
+                              modify= lesender und schreibender Zugriff. 
+2) seinen Namen. 
+ 
+Betriebsrichtung und Name werden in der Assoziierungsprozedur 'sequential file'
+(siehe Kap 2.8.2) festgelegt. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ ........................... Beispiel .......................... 
+  TEXT VAR name := ausgabe ; 
+ 
+  FILE VAR f := sequential file(output,name) ; 
+    
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Das Festlegen einer Betriebsrichtung impliziert eine Kontrolle der Benutzung der
+betreffenden Datei, hilft somit Programmierfehler zu vermeiden. 
+ 
+ACHTUNG :  #on("b")##on("u")#Alle#off("b")##off("u")# Prozeduren, die auf FILEs zugreifen, verlangen Objekte vom Typ
+           FILE VAR, da die Lese/Schreiboperationen als ändernd betrachtet wer­
+           den (müssen). 
+ 
+#page# 
+
+5.3.1  Assoziierung 
+ 
+'sequential file' 
+   #on("b")#FILE PROC sequential file (TRANSPUTDIRECTION CONST mode, DATASPACE VAR ds)  #off("b")# 
+   Assoziierung einer sequentiellen Datei mit dem Dataspace 'ds' und der Betriebs­
+   richtung 'mode' (vergl. 'modify', 'input' bzw. 'output'). Diese Prozedur dient zur
+   Assoziierung eines temporären Datenraums in der Benutzer-Task, der nach der
+   Beendigung des Programmlaufs nicht mehr zugriffsfähig ist (weil der Name des
+   Datenraums nicht mehr ansprechbar ist). Somit muß der Datenraum explizit vom
+   Programm gelöscht werden. 
+ 
+ 
+   #on("b")#FILE PROC sequential file (TRANSPUTDIRECTION CONST mode,TEXT CONST name)#off("b")# 
+   Assoziierung einer sequentiellen Datei mit dem Namen 'name' und der Betriebs­
+   richtung 'mode' (vergl. 'input' bzw. 'output'). Existiert der FILE bereits, dann wird
+   mit 'input' auf den Anfang des FILEs, bei 'output' hinter den letzten Satz der datei
+   positioniert. Existiert dagagen der FILE noch nicht und ist die
+   TRANSPUTDIRECTION 'output' oder 'modify', wird ein neuer FILE eingerich­
+   tet. 
+ 
+   FEHLER : "name" gibt es nicht" 
+             Es wurde versucht, einen nicht vorhandenen FILE mit 'input' zu asso­
+             ziieren. 
+ 
+#page# 
+ 
+'input' 
+   #on("b")#PROC input (FILE VAR f) #off("b")# 
+   Ändern der Verarbeitungsart von 'modify' oder 'output' in 'input'. Dabei wird auf
+   den ersten Satz der Datei positioniert. 
+ 
+   #on("b")#TRANSPUTDIRECTION CONST input #off("b")# 
+   Assoziierung in Zusammenhang mit der Prozedur 'sequential file' einer sequentiel­
+   len Datei mit der 'TRANSPUTDIRECTION' 'input' (nur lesen). 
+ 
+ 
+'output' 
+   #on("b")#PROC output (FILE VAR file) #off("b")# 
+   Ändern der Verarbeitungsart von 'input' oder 'modify' in 'output'. Dabei wird hinter
+   den letzten Satz der Datei positioniert. 
+ 
+   #on("b")#TRANSPUTDIRECTION CONST output #off("b")# 
+   In Verbindung mit der Prozedur 'sequential file' kann eine Datei assoziiert werden
+   mit der Betriebsrichtung 'output' (nur schreiben). 
+ 
+ 
+'modify' 
+   #on("b")#PROC modify (FILE VAR f) #off("b")# 
+   Ändern der Betriebsrichtung von 'input' oder 'output' in die Betriebsrichtung 'mo­
+   dify'. 
+ 
+   #on("b")#TRANSPUTDIRECTION CONST modify #off("b")# 
+   Diese Betriebsrichtung erlaubt das Vorwärts- und Rückwärts-Positionieren und
+   das beliebige Einfügen und Löschen von Sätzen. 'modify' wird für die Assoziie­
+   rungsprozedur 'sequential file' benötigt. 
+ 
+ 
+ 
+#page# 
+
+5.3.2  Informationsprozeduren 
+ 
+'eof' 
+   #on("b")#BOOL PROC eof (FILE CONST file) #off("b")# 
+   Informationsprozedur auf das Ende eines FILEs. Liefert den Wert TRUE, sofern
+   hinter den letzten Satz eines FILEs positioniert wurde. 
+ 
+ 
+'line no' 
+   #on("b")#INT PROC line no (FILE CONST file) #off("b")# 
+   Liefert die aktuelle Zeilennummer. 
+ 
+ 
+'lines' 
+   #on("b")#PROC lines (FILE VAR f) #off("b")# 
+   Liefert die Anzahl der Zeilen der Datei 'f'. 
+ 
+ 
+'headline' 
+   #on("b")#TEXT PROC headline (FILE CONST f) #off("b")# 
+   Liefert den Inhalt der Kopfzeile der Datei 'f'. 
+ 
+   #on("b")#PROC headline (FILE VAR f, TEXT CONST ueberschrift) #off("b")# 
+   Setzt #ib#'ueberschrift' in die Kopfzeile#ie# der Datei 'f'. 
+#page# 
+ 
+5.3.3  Betriebsrichtung INPUT  
+ 
+In der Betriebsrichtung 'input' sind nur Leseoperationen auf der Datei zugelassen. Die
+Assoziierungsprozedur 'sequential file' bewirkt: 
+ 
+1) Falls die Eingabedatei noch nicht existiert, wird eine Fehlermeldung ausgegeben. 
+ 
+2) Falls es eine Datei des Namens gibt, wird auf das erste Zeichen des ersten
+   Satzes positioniert. 
+ 
+ 
+ 
+'get' 
+   #on("b")#PROC get (FILE VAR f, INT VAR number) #off("b")# 
+   Lesen des nächsten Wortes aus der Datei 'f' und Konvertierung des Wortes zu
+   einem Integer-Objekt. 
+ 
+   #on("b")#PROC get (FILE VAR f, REAL VAR number) #off("b")# 
+   Lesen des nächsten Wortes aus der Datei 'f' und Konvertierung des Wortes zu
+   einem Real-Objekt. 
+ 
+ 
+   #on("b")#PROC get (FILE VAR f, TEXT VAR text) #off("b")# 
+   Lesen des nächsten Wortes aus der Datei 'f'. 
+ 
+   #on("b")#PROC get (FILE VAR f, TEXT VAR text, TEXT CONST delimiter)#off("b")# 
+   Lesen eines TEXT-Wertes 'text' von der Datei 'f', bis das Zeichen 'delimiter'
+   angetroffen wird. Ein eventueller Zeilenwechsel in der Datei wird dabei übergan­
+   gen. 
+ 
+   #on("b")#PROC get (FILE VAR f, TEXT VAR text, INT CONST maxlength)#off("b")# 
+   Lesen eines TEXT-Wertes 'text' von der Datei 'f' mit 'maxlength' Zeichen. Ein
+   eventueller Zeilenwechsel in der Datei wird dabei nicht übergangen. 
+ 
+ 
+ 
+'getline' 
+   #on("b")#PROC get line (FILE VAR file, TEXT VAR record) #off("b")# 
+   Lesen der nächsten Zeile aus der sequentiellen Datei 'file'. 
+   Mögliche Fehler bei Betriebsrichtung 'input': 
+ 
+            "Datei zu" 
+             Die Datei 'file' ist gegenwärtig nicht assoziiert. 
+ 
+            "Leseversuch nach Dateiende" 
+             Es wurde versucht, über die letzte Zeile einer Datei zu lesen. 
+ 
+            "Leseversuch auf output file" 
+             Es wurde versucht, von einem mit 'output' assoziierten FILE zu lesen. 
+ 
+            "Unzulässiger Zugriff auf modify-FILE" 
+ 
+#page# 
+
+5.3.4  Betriebsrichtung OUTPUT  
+ 
+In der Betriebsrichtung 'output' sind nur Schreiboperationen auf der Datei zugelassen.
+Die Assoziierungsprozedur 'sequential file' bewirkt: 
+ 
+1) Falls die Ausgabedatei noch nicht existiert, wird sie angelegt und auf den ersten
+   Satz positioniert. 
+ 
+2) Falls es bereits eine Datei des Namens gibt, wird hinter den letzten Satz positio­
+   niert, die Datei wird also fortgeschrieben. 
+ 
+ 
+'put' 
+   #on("b")#PROC put (FILE VAR f, INT CONST number) #off("b")# 
+   Ausgabe eines INT-Wertes 'number' in die Datei 'f'. Dabei wird ein Leerzeichen
+   an die Ausgabe angefügt. 
+ 
+   #on("b")#PROC put (FILE VAR f, REAL CONST number) #off("b")# 
+   Ausgabe eines REAL-Wertes 'number' in die Datei 'f'. Dabei wird ein Leerzei­
+   chen an die Ausgabe angefügt. 
+ 
+   #on("b")#PROC put (FILE VAR f, TEXT CONST text) #off("b")# 
+   Ausgabe eines TEXT-Wertes 'text' in die Datei 'f'. Dabei wird ein Leerzeichen an
+   die Ausgabe angefügt. 
+ 
+ 
+ 
+'putline' 
+   #on("b")#PROC putline (FILE VAR file, TEXT CONST record) #off("b")# 
+   Ausgabe eines TEXTes 'record' in die Datei 'file'. Danach wird auf die nächste
+   Zeile positioniert. 'file' muß mit 'output' assoziiert sein. 
+ 
+ 
+'write' 
+   #on("b")#PROC write (FILE VAR f, TEXT CONST text) #off("b")# 
+   Schreibt 'text' in die Datei 'f' (analog 'put (f, text)'), aber ohne Trennblank. 
+ 
+ 
+'line' 
+   #on("b")#PROC line (FILE VAR file) #off("b")# 
+   Positionierung auf die nächste Zeile der Datei 'file'. Wird versucht, über das Ende
+   eines mit 'input' assoziierten FILEs zu positionieren, wird keine Aktion vorgenom­
+   men. 
+ 
+   #on("b")#PROC line (FILE VAR file, INT CONST lines) #off("b")# 
+   Positionierung mit 'lines' Zeilen Vorschub in der Datei 'file'. 
+ 
+ 
+   FEHLER:  "Datei zu!" 
+             Die Datei 'file' ist gegenwärtig nicht assoziiert. 
+ 
+            "Schreibversuch auf input-File" 
+             Es wurde versucht, auf einen mit 'input' assoziierten FILE zu
+             schreiben. 
+ 
+ 
+   Bei Textdateien, die mit dem Editor weiterbearbeitet werden sollen, ist also zu
+   beachten: ine Ausgabe mit 'put' setzt ein 'blank' hinter die Ausgabe. Falls dieses
+   Leerzeichen das letzte Zeichen in der Zeile ist, wird eine Absatzmarke in der Zeile
+   gesetzt. Wird mit 'write' oder 'putline' ausgegeben, steht kein Leerzeichen und
+   somit keine Absatzmarke am Zeilenende. 
+#page# 
+
+5.3.5  Betriebsrichtung MODIFY  
+ 
+In der Betriebsrichtung 'modify' sind Lese- und Schreiboperationen auf der Datei
+zugelassen. Desweiteren ist beliebiges Positionieren in der Datei erlaubt. Neue Sätze
+können an beliebiger Stelle in die Datei eingefügt werden, die sequentielle Struktur
+der Datei bleibt erhalten. Die Assoziierungsprozedur 'sequential file' bewirkt: 
+ 
+1) Falls die Ausgabedatei noch nicht existiert, wird sie angelegt. 
+ 
+2) Falls es bereits eine Datei des Namens gibt, ist undefiniert wo positioniert ist. Die
+   erste Positionierung muß explizit vorgenommen werden! 
+ 
+ 
+ 
+'col' 
+   #on("b")#PROC col (FILE VAR f, INT CONST position) #off("b")# 
+   Positionierung auf die Spalte 'position' innerhalb der aktuellen Zeile. 
+ 
+   #on("b")#INT PROC col (FILE CONST f) #off("b")# 
+   Liefert die aktuelle Position innerhalb der aktuellen Zeile. 
+ 
+ 
+'down' 
+   #on("b")#PROC down (FILE VAR f) #off("b")# 
+   Positionieren um eine Zeile vorwärts. 
+ 
+   #on("b")#PROC down (FILE VAR f, INT CONST number) #off("b")# 
+   Positionieren um 'number' Zeilen vorwärts. 
+ 
+ 
+'to line' 
+   #on("b")#PROC to line (FILE VAR f, INT CONST number) #off("b")# 
+   Positionierung auf die Zeile 'number'. 
+ 
+ 
+'up' 
+   #on("b")#PROC up (FILE VAR f) #off("b")# 
+   Positionieren um eine Zeile rückwärts. 
+ 
+   #on("b")#PROC up (FILE VAR f, INT CONST number) #off("b")# 
+   Positionieren um 'number' Zeilen rückwärts. 
+ 
+#page# 
+'delete record' 
+   #on("b")#PROC delete record (FILE VAR file) #off("b")# 
+   Der aktuelle Satz der Datei 'file' wird gelöscht. Der folgende Satz wird der aktuelle
+   Satz. 
+ 
+ 
+'insert record' 
+   #on("b'PROC insert record (FILE VAR file) #off("b")# 
+   Es wird ein leerer Satz in die Datei 'file' vor die aktuelle Position eingefügt. Dieser
+   Satz kann anschließend mit 'write record' beschrieben werden (d.h. der neue Satz
+   ist jetzt der aktuelle Satz). 
+ 
+ 
+ 
+'read record' 
+   #on("b")#PROC read record (FILE CONST file, TEXT VAR record) #off("b")# 
+   Liest den aktuellen Satz der Datei 'file' in den TEXT 'record'. Die Position wird
+   dabei nicht verändert. 
+ 
+ 
+ 
+'write record' 
+   #on("b")#PROC write record (FILE VAR file, TEXT CONST record) #off("b")# 
+   Schreibt einen Satz in die Datei 'file' an die aktuelle Position. Dieser Satz muß
+   bereits vorhanden sein, d.h. mit 'write record' kann keine leere Datei beschrieben
+   werden, sondern es wird der Satz an der aktuellen Position überschrieben. Die
+   Position in der Datei wird nicht verändert. 
+ 
+ 
+#page# 
+
+5.3.6  FILE -Ausschnitte 
+ 
+Ähnlich den Editorfunktionen 'ESC RUBOUT' und 'ESC RUBIN', die erlauben ganze
+Abschnitte einer Datei zu löschen und das Gelöschte an anderer Stelle wiedereinzu­
+fügen, gibt es die Möglichkeit per Programm solche Segmente 
+eines 'modify-FILEs' zu verschieben. 
+ 
+ 
+'clear removed' 
+   #on("b")#PROC clear removed (FILE VAR f) #off("b")# 
+   Das mit 'remove' entfernte Segment wird gelöscht und nicht an anderer Stelle
+   eingefügt. 
+ 
+ 
+'reinsert' 
+   #on("b")#PROC reinsert (FILE VAR f) #off("b")# 
+   Das mit 'remove' entfernte Segment wird vor die aktuelle Zeile wiedereingefügt. 
+ 
+ 
+'remove' 
+   #on("b")#PROC remove (FILE VAR f, INT CONST size) #off("b")# 
+   Löscht 'size' Zeilen vor der aktuellen Position aus 'f'. Das Segment wird in einen
+   internen Puffer geschrieben. 
+ 
+ 
+'reorganize' 
+   #on("b")#PROC reorganize (TEXT CONST datei)#off("b")# 
+   Reorganisation von 'datei'. Die durch Löschen und Einfügen aus vielen
+   Segmenten bestehende Datei wird zu einem Segment zusammengefügt, die
+   aktuelle Position ist danach das erste Zeichen der ersten Zeile. 
+ 
+   Durch diese Prozedur kann ggf. Speicherplatz gespart werden. 
+ 
+   #on("b")#PROC reorganize#off("b")# 
+   Reorganisation der zuletzt bearbeiteten Datei. 
+ 
+ 
+'segments' 
+   #on("b")#PROC segments (FILE VAR f) #off("b")# 
+   Liefert die Anzahl der Segmente von 'f'. Eine große Anzahl von Segmenten kann
+   langsamere Zugriffe zur Folge haben. 
+ 
+#page# 
+ 
+5.4  Suchen und Ersetzen in Textdateien 
+ 
+Such- und Ersetzungsprozeduren können sowohl interaktiv beim Editieren (siehe
+dazu 3.3), als auch in Prozeduren, die auf FILEs (siehe 5.3) arbeiten, angewandt
+werden. 
+ 
+Die dazu dienenden Prozeduren sind im Paket 'pattern match' enthalten. Mit 'Pattern
+Matching' (Muster treffen) wird ein Verfahren bezeichnet Gleichheit von Objekten
+anhand von Regeln, denen diese Objekte genügen, zu überprüfen. 
+ 
+Da oft nach Texten gesucht werden muß, deren genaue Ausprägung nicht bekannt ist,
+oder deren Auftreten nur in einem bestimmten Zusammenhang interessiert, gibt es die
+Möglichkeit feststehende Textelemente mit Elementen ungewisser Ausprägung zu
+kombinieren, also Textmuster zu erzeugen. 
+ 
+Um einen Text zu suchen, muß die Suchrichtung und der gesuchte Text oder ein
+Muster, welches diesen Text beschreibt, angegeben werden. 
+ 
+- Aufbauen von Textmustern :  + , - , OR , any , bound , notion 
+ 
+- Suchen nach Textmustern  :  down , downety , up , uppety 
+ 
+- Treffer registrieren     :  LIKE , UNLIKE , at , pattern found 
+ 
+- Treffer herausnehmen     :  ** , match , matchend , matchpos , 
+                              somefix , word 
+ 
+- Ändern in Dateien        :  change 
+ 
+ 
+Nach einem erfolgreichen Suchvorgang ist stets auf das erste Zeichen der zu such­
+enden Zeichenkette positioniert. 
+ 
+ 
+Eine besondere Funktion kommt dem 'joker' zu: Dieses Symbol (Defaultwert: '*') steht
+für eine beliebige Zeichenkette beliebiger Länge. Insbesondere bei Ersetzungsaktionen
+in denen dieses Zeichen zur Musterbeschreibung verwendet wird, ist daher Vorsicht
+geboten und sorgfältig zu testen. 
+ 
+#page# 
+
+5.4.1  Aufbau von Textmustern 
+ 
+'+' 
+   #on("b")#TEXT OP + (TEXT CONST links, rechts) #off("b")# 
+   Verkettung der Texte 'links' und 'rechts' zu 'linksrechts'. Falls das Ergebnis länger
+   als die maximal zulässige Textlänge ist, ist es undefiniert. 
+ 
+   Wenn 'muster1' einen beliebigen Text finden sollte, ( Siehe: PROC any) wird das
+   Ende des von 'muster1' erkannten Textes durch den Anfang des von 'muster2'
+   erkannten Textes im Nachhinein definiert. 
+ 
+ 
+ 
+'-' 
+   #on("b")#TEXT OP - (TEXT CONST alphabet) #off("b")# 
+   Der Operator liefert das zu 'alphabet' komplementäre Alphabet, also alle Zeichen
+   gemäß der EUMEL Codetabelle (5.2.4), die nicht in 'alphabet' enthalten sind.
+   Sinnvoll im Zusammenhang mit der Textprozedur 'any'. 
+ 
+ 
+'OR' 
+   #on("b")#TEXT OP OR (TEXT CONST links, rechts) #off("b")# 
+   Liefert die Alternative von 'links' und 'rechts'. Die Reihenfolge spielt beim Suchen
+   keine Rolle. 
+ 
+ 
+ 
+'any' 
+   Die Textprozedur 'any' liefert einen unbekannten Text unbestimmter Länge.
+   Dieser Text sollte entweder durch festen Text sinnvoll eingegrenzt werden, oder
+   direkt eingeschränkt werden. 
+ 
+ 
+   #on("b")#TEXT PROC any #off("b")# 
+   Beschreibt einen beliebigen Text. 
+ 
+   #on("b")#TEXT PROC any (INT CONST laenge) #off("b")# 
+   Beschreibt einen beliebigen Text der angebenen Länge. 
+ 
+ 
+   #on("b")#TEXT PROC any (TEXT CONST alphabet) #off("b")# 
+   Beschreibt einen beliebigen Text, der nur aus Zeichen besteht, die in 'alphabet'
+   enthalten sind. 
+ 
+ 
+   #on("b")#TEXT PROC any (INT CONST laenge, TEXT CONST alphabet) #off("b")# 
+   Beschreibt einen Text der vorgegebenen Länge, der nur aus den in 'alphabet'
+   vorgegebenen Zeichen besteht. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ ........................... Beispiel .......................... 
+  Die Textprozedur 'any' liefert einen unbekannten Text unbe­ 
+  stimmter Länge. Dieser Text sollte entweder durch festen Text 
+  sinnvoll eingegrenzt werden, oder direkt eingeschränkt werden. 
+gib kommando: D("D" OR "d" + any (2,"aeirs")                    
+  Sucht nach bestimmten Artikeln: 'der', 'die', 'das'  etc. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+'bound' 
+   #on("b")#TEXT PROC bound #off("b")# 
+   Bezeichnet ein Muster der Länge null, das nur am Zeilenanfang oder am Zeilenen­
+   de gefunden wird. Ein Präfix 'bound' fordert, daß das gesuchte Muster in der
+   ersten Spalte beginnen muß, ein Postfix 'bound' fordert, daß das Muster mit dem
+   Zeilenende abschließt. 
+ 
+____________________________________________________________________________ 
+ 
+ ........................... Beispiel .......................... 
+      Die Textprozedur 'any' liefert einen unbekannten Text unbe­ 
+      stimmter Länge. Dieser Text sollte entweder durch festen 
+      Textsinnvoll eingegrenzt werden, oder direkt eingeschränkt 
+      werden. 
+gib kommando: U(bound + any (" "))                              
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+  liefert Treffer bei eingerückten Zeilen. 
+ 
+ 
+ 
+'notion' 
+   #on("b")#PROC notion (TEXT CONST suchwort) #off("b")# 
+   Mit dieser Prozedur kann ein #on("u")#Wort#off("u")# spezifiziert werden, nach dem gesucht werden
+   soll. Bei der Suche nach 'suchwort' wird nur dann ein Treffer geliefert, wenn
+   'suchwort' als Wort, also begrenzt von ' ' (blank), '.' , ','  oder anderen Sonderzei­
+   chen ist. 
+ 
+   #on("b")#PROC notion (TEXT CONST suchwort, INT CONST reg) #off("b")# 
+   Wie oben, der Treffer wird im Register 'reg' gespeichert. 
+ 
+#page# 
+
+5.4.2  Suche nach Textmustern 
+ 
+'down' 
+   #on("b")#PROC down (FILE VAR f, TEXT CONST muster) #off("b")# 
+   Suche nach 'muster' in der Datei 'f' in Richtung Dateiende. Wird 'muster' gefun­
+   den, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man hinter
+   dem letzten Zeichen der Datei. 
+ 
+   Achtung: 'down' sucht vom nächsten Zeichen rechts ab, so daß wiederholtes
+            Suchen keine Endlosschleife ergibt. 
+ 
+ 
+   #on("b")#PROC down (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")# 
+   Wie obiges 'down', es wird aber maximal nur 'number'-Zeilen weit nach 'muster'
+   gesucht. 
+ 
+ 
+ 
+'downety' 
+   #on("b")#PROC downety (FILE VAR f, TEXT CONST muster) #off("b")# 
+   Suche nach 'muster' in der Datei 'f' in Richtung Dateiende. Wird 'muster' gefun­
+   den, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man auf
+   dem letzten Zeichen der Datei. 
+ 
+   Achtung: 'downety' sucht (im Gegensatz zu 'down') vom aktuellen Zeichen an.
+            Daher muß explizit vorwärts positioniert werden. 
+ 
+ 
+   #on("b")#PROC downety (FILE VAR f, TEXT CONST muster, INT CONST number) #off("b")# 
+   Wie obiges 'downety', aber maximal nur 'number'-Zeilen weit. 
+#page# 
+'up' 
+   #on("b")#PROC up (FILE VAR f, TEXT CONST muster) #off("b")# 
+   Suche nach 'muster' in der Datei 'f' in Richtung Dateianfang. Wird 'muster'
+   gefunden, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man
+   auf dem ersten Zeichen der Datei. 
+ 
+   Achtung: 'up' sucht vom nächsten Zeichen links ab, so daß wiederholtes Suchen
+            keine Endlosschleife ergibt. 
+ 
+ 
+   #on("b")#PROC up (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")# 
+   Wie obiges 'up', aber maximal nur 'number'-Zeilen weit. 
+ 
+ 
+ 
+'uppety' 
+   #on("b")#PROC uppety (FILE VAR f, TEXT CONST muster) #off("b")# 
+   Suche nach 'muster' in der Datei 'f' in Richtung Dateianfang. Wird 'muster'
+   gefunden, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man
+   auf dem ersten Zeichen der Datei. 
+ 
+   Achtung: 'uppety' sucht (im Gegensatz zu 'up') vom aktuellen Zeichen. 
+ 
+ 
+   #on("b")#PROC uppety (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")# 
+   Wie obiges 'uppety', aber maximal nur 'number'-Zeilen weit. 
+ 
+#page# 
+
+5.4.3  Treffer registrieren 
+ 
+'LIKE' 
+   #on("b")#BOOL OP LIKE (TEXT CONST text , muster) #off("b")# 
+   Liefert TRUE, falls der Text 'text' 'muster' entspricht. In 'muster' kann das
+   Spezialzeichen '*' verwandt werden, das abkürzend für die Konkatenation mit
+   'any' steht. 
+ 
+   Daraus folgt, daß das Suchen oder Ersetzen des Zeichens '*' nur durch
+   any (1,"*") zu bewerkstelligen ist. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ ........................... Beispiel .......................... 
+ \#Druckdateien aus Thesaurus löschen\# 
+ gib kommando:"*.p" C ""                                        
+ 16.04.87       "Handbuch teil1" 
+ 04.05.87       "Handbuch teil1.p" 
+ 16.04.87       "Handbuch teil2" 
+ 06.05.87       "Handbuch teil2.p" 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+  aber: 
+ 
+____________________________________________________________________________ 
+ 
+ ........................... Beispiel .......................... 
+ \#Vordere Kommentarklammern löschen \# 
+ gib kommando:"(" + any(1,"*") C ""                              
+ lernsequenz auf taste legen("a" , "archive") ; 
+ (* lernsequenz auf taste legen("(" , ""91"") ; *) 
+ (* lernsequenz auf taste legen(")" , ""93"") ; *) 
+    kommando auf taste legen("P" , "print("""")"8""8""11"") . 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+'UNLIKE' 
+   #on("b")#BOOL OP UNLIKE (TEXT CONST text , muster) #off("b")# 
+   Wirkt wie: '(NOT text LIKE muster)' 
+#page# 
+ 
+5.4.4  Treffer herausnehmen 
+ 
+Mit Hilfe der 'Register' ist es möglich identifizierte Texte zwischenzuspeichern und in
+weiteren Aktionen weiterzuverwenden. 
+ 
+ 
+'**' 
+   #on("b")#TEXT OP ** (TEXT CONST muster, INT CONST register)#off("b")# 
+   Der als 'muster' erkannte Text wird einem 'Register' mit der Nummer 'register'
+   zugeordnet. Es können 256 Register (1 bis 256) benutzt werden. 
+ 
+ 
+'match' 
+   #on("b")#TEXT PROC match (INT CONST nr) #off("b")# 
+   Liefert den Text der dem Register 'nr' zuletzt zugeordnet wurde. 
+ 
+ 
+'matchpos' 
+   #on("b")#INT PROC matchpos (INT CONST nummer) #off("b")# 
+   Liefert die Spaltennummer, auf der das dem Register 'nummer' zugeordnete Mu­
+   ster in der Zeile beginnt. 
+ 
+____________________________________________________________________________ 
+ 
+ ........................... Beispiel .......................... 
+ 
+ gib kommando:D("file"+any+"("+(any ** (1)...                    
+ 
+____________________________________________________________________________ 
+#page# 
+
+5.4.5  Ändern in Dateien  
+ 
+'change' 
+   #on("b")#PROC change (FILE VAR datei, INT CONST von, bis , TEXT CONST neuertext)#off("b")# 
+   In der Datei wird in der aktuellen Zeile in den Ausschnitt zwischen 'von' und 'bis'
+   der Text 'neuertext' eingesetzt. 
+ 
+   entspricht: 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ ........................... Beispiel .......................... 
+ FILE VAR file := sequential file (modify, name) 
+ TEXT VAR zeile; 
+      . 
+      . 
+    read record (file ,zeile); 
+    change (zeile, von, bis ,"neuertext"); 
+    write record (file, zeile); 
+      . 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+
+5.4.6  Editor-Prozeduren 
+ 
+'edit' 
+   #on("b")#edit (TEXT CONST datei)#off("b")# 
+   Editieren der Datei 'datei'. Das Editorfenster ist maximal groß (von 1,1 bis
+   max,max). Der Standard-Kommandointerpreter ist gültig, so daß Eingaben, die
+   mit #schl("ESC")# beginnen, interpretiert werden, wie in 3.4 'Vorbelegte Tasten' beschrie­
+   ben. 
+ 
+   #on("b")#edit#off("b")# 
+   Wie oben, editiert wird die Datei mit dem zuletzt benutzten Namen. 
+ 
+   #on("b")#edit (THESAURUS CONST thes)#off("b")# 
+   Wie oben, editiert werden alle Dateien, deren Namen im Thesaurus 'thes' enthal­
+   ten sind. 
+ 
+   #on("b")#edit (TEXT CONST datei, INT CONST von x, von y, bis x, bis y)#off("b")# 
+   Editieren der Datei 'datei'. Das Editorfenster hat die linke obere Ecke bei 'von x,
+   von y' und die rechte untere Ecke bei 'bis x, bis y'. 
+ 
+   #on("b")#edit (FILE VAR f)#off("b")# 
+   Editieren der als 'sequential file' assoziierten Textdatei 'f'. 
+ 
+   #on("b")#edit (FILE VAR, INT CONST von x, von y, bis x, bis y)#off("b")# 
+   Editieren der als 'sequential file' assoziierten Textdatei in einem Fenster mit der
+   linken, oberen Ecke 'von x, von y' und der rechten, unteren Ecke 'bis x, bis y'. 
+ 
+   #on("b")#edit (FILE VAR f, TEXT CONST res, 
+                  PROC (TEXT CONST) kdo interpreter)#off("b")# 
+   Editieren der als 'sequential file' assoziierten Textdatei 'f'. In 'res' werden reser­
+   vierte Zeichen übergeben, die von der Prozedur 'kdo interpreter' als Kommandos
+   interpretiert werden, wenn sie als ESC-Sequenz eingegeben werden. 
+   Beispiel : #schl("ESC ")# #schl("e")# 
+ 
+#page# 
+'editget' 
+   #on("b")#editget (TEXT VAR ausgabe) #off("b")# 
+   Aufruf des Zeileneditor. An der aktuellen Cursorposition wird eine Zeile ausgegeben in
+   der 'ausgabe' steht. Für diese Zeile stehen alle Editiermöglichkeiten zur
+   Verfügung, 'ausgabe' kann also beliebig überschrieben, ergänzt etc. werden. Die
+   Eingabe wird durch #schl("CR")# abgeschlossen. Im Gegensatz zur Prozedur 'get' ist auch
+   eine leere Eingabe möglich. 
+ 
+   #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, INT CONST scroll, 
+             TEXT CONST sep, TEXT CONST res, TEXT VAR exit)  #off("b")# 
+   Wie oben, die Zeilenlänge ist jedoch auf 'zeile' Zeichen begrenzt. Die Eingabe
+   wird durch #schl("CR")# oder durch eine Cursorbewegung über die Position 'zeile' hinaus
+   abgeschlossen. 
+ 
+   Die Angabe 'scroll' setzt die Breite des Zeilenfensters fest, wird diese Breite
+   überschritten, so wird 'ausgabe' gerollt. 
+ 
+   In 'sep' (Separator) können Zeichen festgesetzt werden, mit denen die Eingabe
+   beendet wird (zusätzlich zu CR !). 
+ 
+   In 'res' (reservierte Tasten) können Tasten festgelegt werden, die in Verbindung
+   mit <ESC> die Eingabe beenden. 
+ 
+   Wurde der Zeileneditor durch einen Separator verlassen, so steht in 'exit' dieses
+   Zeichen. Falls der Zeileneditor durch eine reservierte Taste verlassen, so enthält 
+   'exit' 'ESC' und die Taste. 
+ 
+   #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, INT CONST scroll)#off("b")# 
+   Bedeutung der Parameter siehe oben. 
+ 
+   #on("b")#editget (TEXT VAR ausgabe, TEXT CONST sep, TEXT CONST res, 
+                     TEXT VAR exit) #off("b")# 
+   Bedeutung der Parameter siehe oben. 
+ 
+   #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, TEXT VAR exit) #off("b")# 
+   Bedeutung der Parameter siehe oben. 
+#page# 
+
+5.4.7  Sortierung von Textdateien 
+ 
+Für die Sortierung von Textdateien gibt es zwei Sortierprogramme: 
+ 
+- Sortierung nach ASCII    :  sort 
+ 
+- Sortierung nach 
+  deutschem Alphabet       :  lexsort 
+ 
+ 
+'sort' 
+   #on("b")#PROC sort (TEXT CONST datei) #off("b")# 
+   Diese Prozedur sortiert die Datei 'datei' zeilenweise gemäß der von der EUMEL
+   Codetabelle (siehe 5.2.4) vorgegebenen Reihenfolge. Zur Sortierung werden die
+   Zeilen vom ersten Zeichen der Zeile beginnend, zeichenweise verglichen und
+   dementsprechend sortiert. 
+ 
+   #on("b")#PROC sort (TEXT CONST datei, INT CONST position) #off("b")# 
+   Sortierkriterien wie oben, jedoch wird bei Vergleich und Sortierung der Satz erst
+   ab der Position 'position' beachtet. Sortiert wird der ganze Satz! 
+ 
+ 
+'lex sort' 
+   #on("b")#PROC lex sort (TEXT CONST datei) #off("b")# 
+   Zeilenweise Sortierung nach lexikographischer Reihenfolge gemäß DIN 5007. Zu
+   den Vergleichen werden die Operatoren LEXEQUAL, LEXGRATER,
+   LEXGRATEREQUAL benutzt (siehe 5.2.4). 
+ 
+   #on("b")#PROC lex sort (TEXT CONST datei, INT CONST position) #off("b")# 
+   Lexikalische Sortierung durch Vergleich ab Position 'position'. 
+ 
+#page# 
+
+5.4.8  Prozeduren auf Datenräumen 
+ 
+Neben den Textdateien gibt es im EUMEL-System den Typ Datenraum, der Objekte
+jeglichen Typs aufnehmen kann und direkten Zugriff auf die Objekte gewährt (siehe
+2.9.2). 
+ 
+Für Objekte von Type Datenraum (nicht für die in Datenräumen enthaltenen Objekte!)
+existieren folgende Standardprozeduren: 
+ 
+ 
+':=' 
+   #on("b")#OP := ( DATASPACE VAR ds1, DATASPACE CONST ds2)#off("b")# 
+   Der Datenraum 'ds1' wird als Kopie von 'ds2' angelegt. Es handelt sich zunächst
+   um eine logische Kopie, eine physische Kopie wird erst nach einem Schreibzugriff
+   auf 'ds1' oder 'ds2' nötig. 
+ 
+ 
+'new' 
+   #on("b")#DATASPACE PROC new (TEXT CONST dsname) #off("b")# 
+   Liefert einen neuen Datenraum namens 'dsname'. 
+ 
+____________________________________________________________________________ 
+ 
+ DATASPACE VAR ds := new ("datenraum") 
+ (* ergibt zwei Datenräume 'ds' und 'datenraum'! *) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+'nilspace' 
+   #on("b")#DATASPACE PROC nilspace#off("b")# 
+   Der 'nilspace' ist ein leerer Datenraum, der ausschließlich als Quelle zum Kopie­
+   ren bei der Initialisierung Verwendung finden darf. 
+ 
+ 
+'old' 
+   #on("b")#DATASPACE PROC old (TEXT CONST dsname) #off("b")# 
+   Liefert einen bereits existierenden Datenraum (oder auch eine Datei) mit dem
+   Namen 'dsname'. 
+ 
+   FEHLER :  "dsname" gibt es nicht 
+ 
+ 
+'type' 
+   #on("b")#PROC type (DATASPACE CONST ds, INT CONST typ)#off("b")# 
+   Der Datenraum 'ds' erhält den frei wählbaren Schlüssel 'typ'. Es muß eine positive
+   Zahl gewählt werden. Der Datenraum muß zum Zeitpunkt der Typzuweisung an
+   ein BOUND Objekt gekoppelt (gewesen) sein. 
+ 
+   #on("b")#INT PROC type (DATASPACE CONST ds)#off("b")# 
+   Liefert den Schlüssel des Datenraums 'ds'. Falls 'ds' nie an ein BOUND Objekt
+   gekoppelt war, liefert die Prozedur einen Wert < 0, sonst 0 (keine Zuweisung
+   erfolgt) oder die zugewiesene Typnummer. 
+ 
+ 
+'dataspaces' 
+   #on("b")#INT PROC dataspaces (TASK CONST task) #off("b")# 
+   Liefert die Anzahl der Datenräume der Task 'task'. 
+ 
+   #on("b")#INT PROC dataspaces #off("b")# 
+   Anzahl der Datenräume von 'myself'. 
+ 
+ 
+'ds pages' 
+   #on("b")#INT PROC ds pages (DATASPACE CONST ds)#off("b")# 
+   Liefert die Anzahl der durch 'ds' belegten Seiten (je 512 Byte). 
+ 
+ 
+'storage' 
+   #on("b")#INT PROC storage (DATASPACE CONST ds)#off("b")# 
+   Liefert den von 'ds' belegten Speicherplatz in KB. 
+ 
+#page# 
+'copy' 
+   #on("b")#PROC copy (DATASPACE CONST ds, TEXT CONST datei) #off("b")# 
+   Eine neue Datei mit dem Namen 'datei' wird angelegt. Der Inhalt der Datei ist eine
+   Kopie des Inhalts des Datenraumes 'ds'. 
+ 
+ 
+'forget' 
+   #on("b")#PROC forget (DATASPACE CONST ds)#off("b")# 
+   Der Datenraum 'ds' wird gelöscht#u#1)#e#. 
+ 
+#foot# 
+ 
+   1) Durch diese Prozedur steht nicht unmittelbar mehr freier Speicherplatz zur
+      Verfügung. Die physische Räumung von Speicherplatz erfolgt durch die
+      'Müllabfuhr' bei einem Fixpunkt. 
+#end# 
+ 
+'fetch' 
+   #on("b")#PROC fetch (DATASPACE CONST ziel, TEXT CONST datei, 
+               TASK CONST manager) #off("b")# 
+   Aus der Task 'manager' wird der Datenraum der Datei 'datei' in den eigenen
+   Datenraum 'ziel' kopiert. 
+ 
+ 
+'save' 
+   #on("b")#PROC save (DATASPACE CONST quelle, TEXT CONST datei, 
+               TASK CONST manager) #off("b")# 
+   Der eigene Datenraum 'quelle' wird in die Datei 'datei' in der Task 'manager'
+   kopiert. 
+#page# 
+ 
+5.5  Eingabe/Ausgabe 
+ 
+- Eingabesteuerzeichen     :  HOP , � � � � , TAB , RUBIN , RUBOUT 
+                              CR , MARK , ESC 
+ 
+- Ausgabesteuerzeichen     :  HOME , � � � � , CL EOP , CL EOL 
+                              CPOS , BELL , CR , ENDMARK , BEGINMARK 
+ 
+- Positionierung           :  cursor , get cursor , line , page 
+ 
+- Eingabe                  :  get , getline , inchar , incharety 
+ 
+- Ausgabe                  :  cout , out , out subtext , put , putline , 
+                              TIMESOUT , write 
+ 
+- Kontrolle                :  online , pause , sysin , sysout 
+ 
+- Zeitmessung              :  clock , date , day , hour , pause , time 
+                              time of day 
+ 
+#page# 
+ 
+5.5.1  E/A auf Bildschirm  
+ 
+Steuerzeichen und Standardprozeduren zur Ein- Ausgabe am Bildschirm werden
+zur Steuerung des Dialogverhaltens von Prozeduren benutzt.
+
+ 
+5.5.1.1  Eingabesteuerzeichen 
+Eingabesteuerzeichen werden durch die Funktionstasten (s. 3.2) erzeugt. Die Wirkung
+der Tasten ist ebenfalls an dieser Stelle beschrieben. 
+ 
+Durch die Tasten werden folgende Codes an Programme gegeben: 
+ 
+Codierung  I   Bezeichnung 
+-----------+-------------- 
+HOP        I     1 
+RECHTS     I     2 
+OBEN       I     3 
+LINKS      I     8 
+TAB        I     9 
+UNTEN      I    10 
+RUBIN      I    11 
+RUBOUT     I    12 
+CR         I    13 
+MARK       I    16 
+ESC        I    27 
+ 
+ 
+#page# 
+
+5.5.1.2  Ausgabesteuerzeichen 
+ 
+Die Ausgabe dieser Zeichen bewirkt folgendes Verhalten der Bildschirmausgabe. 
+ 
+Code I   Name      I  Wirkung 
+-----+-------------+------------------------------------------------------- 
+ 0   I   NUL       I  keine Wirkung 
+ 1   I   HOME      I  Cursor in die linke obere Ecke setzen (Position 0,0!) 
+ 2   I   RECHTS    I  Cursor eine Stelle nach rechts setzen 
+ 3   I   OBEN      I  Cursor eine Zeile höher setzen 
+ 4   I   CL EOP    I  Rest der Seite löschen 
+ 5   I   CL EOL    I  Rest der Zeile löschen 
+ 6   I   CPOS      I  Cursor setzen, nächstes Ausgabezeichen bestimmt die
+     I             I  y-Position, das darauf folgende die x-Position. 
+ 7   I   BELL      I  akustisches Signal 
+ 8   I   LINKS     I  Cursor eine Stelle nach links setzen 
+10   I   UNTEN     I  Cursor eine Stelle nach unten setzen 
+13   I   CR        I  Cursor an den Anfang der nächsten Zeile setzen 
+14   I   ENDMARK   I  Ende des markierten Bereichs 
+15   I   BEGINMARK I  Anfang des markierten Bereichs 
+ 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ ........................... Beispiel .......................... 
+  TEXT VAR ausgabe := (""7""15"V O R S I C H T"14"7"");  
+       out(ausgabe); 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+
+5.5.1.3  Positionierung 
+ 
+'cursor' 
+   #on("b")#PROC cursor (INT CONST column, row) #off("b")# 
+   Positioniert den Cursor auf dem Bildschirm, wobei 'column' die Spalte und 'row'
+   die Zeile angibt. Die zulässigen Bereiche von 'column' und 'row' sind geräteab­
+   hängig. 
+ 
+ 
+ 
+'get cursor' 
+   #on("b")#PROC get cursor (INT VAR x, y) #off("b")# 
+   Erfragung der aktuellen Cursor-Position. Die Koordinaten des Cursors werden in
+   'x' und 'y' geliefert. Die aktuelle Cursor-Position ist nach Ausgabe von 'HOME'
+   (Code = 1) oder einer Positionierung des Cursors mit der Prozedur 'cursor' stets
+   definiert. Die Prozedur 'get cursor' liefert jedoch undefinierte Werte, wenn über
+   den rechten Rand einer Zeile hinausgeschrieben wurde (die Wirkung einer solchen
+   Operation hängt von der Hardware eines Terminals ab). 
+ 
+ 
+'line' 
+   #on("b")#PROC line #off("b")# 
+   Es wird zum Anfang einer neuen Zeile positioniert. 
+ 
+   #on("b")#PROC line (INT CONST number) #off("b")# 
+   Es werden 'number' Zeilenwechsel vorgenommen. 
+ 
+ 
+'page' 
+   #on("b")#PROC page #off("b")# 
+   Es wird zum Anfang einer neuen Seite positioniert (hier: linke obere Ecke (Position
+   1,1 !) des Bildschirms, wobei der Bildschirm gelöscht wird). 
+ 
+#page# 
+
+5.5.1.4  Eingabe 
+ 
+
+Grundlegende Prozeduren
+Die folgenden Prozeduren dienen ausschließlich der Eingabe vom Terminal. 
+ 
+'editget' 
+   Siehe 5.4.6 
+ 
+ 
+'getchar' 
+   #on("b")#PROC getchar (TEXT VAR zeichen)#off("b")# 
+   Liest genau ein Zeichen von der Tastatur und schreibt es in die Variable 'zeichen'. 
+ 
+ 
+'inchar' 
+   #on("b")#PROC inchar (TEXT VAR character) #off("b")# 
+   Wartet solange, bis ein Zeichen von der Tastatur eingegeben wird, und schreibt
+   dieses Zeichen in die Variable 'character'. 
+ 
+ 
+'incharety' 
+   #on("b")#TEXT PROC incharety #off("b")# 
+   Versucht, ein Zeichen von der Tastatur zu lesen. Wurde kein Zeichen eingegeben,
+   wird niltext geliefert. 
+ 
+   #on("b")#TEXT PROC incharety (INT CONST time limit) #off("b")# 
+   Versucht, ein Zeichen vom Bildschirm zu lesen. Dabei wird maximal eine 'time
+   limit' lange Zeit auf das Zeichen gewartet (gemessen in Zehntel-Sekunden). 
+ 
+#page# 
+
+Umleitbare Eingabeprozeduren
+Die folgenden Eingabeprozeduren lesen ebenfalls vom Terminal, die Eingabequelle
+kann jedoch durch die Prozedur 'sysin' umgestellt werden. Falls in 'sysin' eine Datei
+angegeben wird wird die Eingabe statt vom Terminal aus dieser Datei gelesen. 
+ 
+ 
+'sysin' 
+   #on("b")#PROC sysin (TEXT CONST file name) #off("b")# 
+   Eingabe-Routinen lesen nicht mehr vom Benutzer-Terminal, sondern aus der
+   Datei 'file name'. 
+ 
+   #on("b")#TEXT PROC sysin #off("b")# 
+   Liefert den Namen der eingestellten 'sysin'-Datei. "" bezeichnet das Benutzer-
+   Terminal. 
+ 
+ 
+'get' 
+   #on("b")#PROC get (INT VAR number) #off("b")# 
+   Einlesen eines INT-Wertes vom Bildschirm. Der einzulesende INT-Wert kann
+   bei der Eingabe vom Terminal editiert werden. 
+ 
+   #on("b")#PROC get (REAL VAR value) #off("b")# 
+   Einlesen eines REAL-Wertes vom Bildschirm. Der einzulesende REAL-Wert
+   kann bei der Eingabe vom Terminal editiert werden. 
+ 
+   #on("b")#PROC get (TEXT VAR word) #off("b")# 
+   Liest einen Text in die Variable 'word' mit maximal 255 Zeichen. Es werden
+   solange Zeichen vom Terminal gelesen, bis ein Leerzeichen oder #schl("CR")# eingegeben
+   wird. Dabei werden führende Leerzeichen übergeben. Der einzulesende Text
+   kann bei der Eingabe editiert werden. Eine leere Eingabe ist nicht erlaubt. 
+ 
+   #on("b")#PROC get (TEXT VAR word, INT CONST laenge) #off("b")# 
+   Liest einen Text vom Bildschirm mit der Länge 'laenge' oder bis #schl("CR")# eingegeben
+   wird. Der einzulesende Wert kann bei der Eingabe editiert werden. 
+ 
+   #on("b")#PROC get (TEXT VAR word, TEXT CONST separator) #off("b")# 
+   Liest einen Text vom Bildschirm, bis ein Zeichen 'separator' angetroffen oder #schl("CR")#
+   eingegeben wird. Der einzulesende Text kann bei der Eingabe editiert werden. 
+ 
+ 
+'getline' 
+   #on("b")#PROC get line (TEXT VAR line) #off("b")# 
+   Das System wartet auf eine Zeile vom Bildschirm (max. 255 Zeichen). #schl("CR")# been­
+   det die Eingabe. 
+ 
+#page# 
+
+5.5.1.5  Ausgabe 
+ 
+
+Grundlegende Prozeduren
+Die folgenden Prozeduren dienen ausschließlich der Ausgabe auf das Terminal. 
+ 
+ 
+'cout' 
+   #on("b")#PROC cout (INT CONST number) #off("b")# 
+   Schreibt 'number' an die aktuelle Cursor-Position auf den Bildschirm. Anschlie­
+   ßend wird an diese Position wieder zurück positioniert. 'number' muß > 0 sein.
+   Paßt 'number' nicht mehr auf die Zeile, so ist die Wirkung von 'cout' nicht de­
+   finiert. 'cout' gibt den Wert von 'number' nur aus, wenn genügend freie Kanal-
+   Kapazität für diese Ausgabe vorhanden ist. Das hat zur Folge, daß Programme
+   nicht auf die Beendigung einer Ausgabe von 'number' warten müssen und ggf.
+   Ausgaben überschlagen werden. 
+ 
+ 
+'out' 
+   #on("b")#PROC out (TEXT CONST text) #off("b")# 
+   Ausgabe eines Textes auf dem Bildschirm. Im Unterschied zu 'put' wird kein
+   Blank an den ausgegebenen Text angefügt. 
+ 
+ 
+ 
+'out subtext' 
+   #on("b")#PROC out subtext (TEXT CONST source, INT CONST from) #off("b")# 
+   Ausgabe eines Teiltextes von 'source' von der Position 'from' bis Textende. Es
+   wird keine Aktion vorgenommen für 
+ 
+ 
+              from > LENGTH source 
+ 
+ 
+   #on("b")#PROC out subtext (TEXT CONST source, INT CONST from, to)#off("b")# 
+   Ausgabe eines Teiltextes von 'source' von der Position 'from' bis zur Position 'to'.
+   Für 
+ 
+ 
+              to > LENGTH source 
+ 
+ 
+   wird out subtext (source, from) ausgeführt. 
+ 
+   #on("b")#PROC out text (TEXT CONST source, INT CONST from, to) #off("b")# 
+   Ausgabe eines Teiltextes von 'source' von der Position 'from' bis zur Position 'to'.
+   Für 
+ 
+ 
+              to > LENGTH source 
+ 
+ 
+   wird für die fehlenden Zeichen Blanks ausgegeben. 
+ 
+ 
+ 
+'TIMESOUT' 
+   #on("b")#OP TIMESOUT (INT CONST times, TEXT CONST text) #off("b")# 
+   Ausgabe eines TEXTes 'text' 'times'mal. An die Ausgabe wird im Gegensatz zu
+   'put' kein Leerzeichen angefügt. Es wird kein Text ausgegeben für 
+ 
+ 
+              times < 1 
+ 
+ 
+#page# 
+
+Umleitbare Ausgabeprozeduren
+Die folgenden Ausgabeprozeduren schreiben ebenfalls auf das Terminal, die Ausgabe
+kann jedoch durch die Prozedur 'sysout' umgeleitet werden. Falls in 'sysout' eine
+Datei angegeben wird wird die Ausgabe statt zum 
+Terminal in die angegebene Datei geleitet. 
+ 
+ 
+'sysout' 
+   #on("b")#PROC sysout (TEXT CONST file name) #off("b")# 
+   Ausgabe-Routinen gehen nicht mehr zum Benutzer-Terminal, sondern in die
+   Datei 'file name'. 
+ 
+   #on("b")#TEXT PROC sysout #off("b")# 
+   Liefert den Namen der eingestellten 'sysout'-Datei. "" bezeichnet das Benut­
+   zer-Terminal. 
+ 
+ 
+'line' 
+   #on("b")#line#off("b")# 
+   Positionierung auf den Anfang einer neuen Ausgabezeile. 
+ 
+   #on("b")#line (INT CONST faktor)#off("b")# 
+   Nächste Ausgabezeile um 'faktor' Zeilen weiter positionieren. 
+ 
+ 
+'put' 
+   #on("b")#PROC put (INT CONST number) #off("b")# 
+   Ausgabe eines INT-Wertes auf dem Bildschirm. Anschließend wird ein Leer­
+   zeichen ausgegeben. 
+ 
+   #on("b")#PROC put (REAL CONST real) #off("b")# 
+   Ausgabe eines REAL-Wertes auf dem Bildschirm. Anschließend wird ein Leer­
+   zeichen ausgegeben. 
+ 
+   #on("b")#PROC put (TEXT CONST text) #off("b")# 
+   Ausgabe eines Textes auf dem Bildschirm. Nach der Ausgabe von 'text' wird ein
+   Blank ausgegeben, um nachfolgenden Ausgaben auf der gleichen Zeile voneinan­
+   der zu trennen. Hardwareabhängig sind die Aktionen, wenn eine Ausgabe über
+   eine Zeilengrenze (hier: Bildschirmzeile) vorgenommen wird. Meist wird die Ausga­
+   be auf der nächsten Zeile fortgesetzt. 
+ 
+ 
+'putline' 
+   #on("b")#PROC putline (TEXT CONST text) #off("b")# 
+   Ausgabe von 'text' auf dem Bildschirm. Nach der Ausgabe wird auf den Anfang
+   der nächsten Zeile positioniert. Gibt man TEXTe nur mit 'putline' aus, so ist
+   gesichert, daß jede Ausgabe auf einer neuen Zeile beginnt. Hardwareabhängig
+   sind die Aktionen, wenn eine Ausgabe über eine Zeilengrenze (hier: Bildschirm­
+   zeile) vorgenommen wird. Meist wird die Ausgabe auf der nächsten Zeile fort­
+   gesetzt. 
+ 
+ 
+'write' 
+   #on("b")#PROC write (TEXT CONST text) #off("b")# 
+   Gibt 'text' ohne Trennblank aus ('put' mit Trennblank). 
+ 
+#page# 
+ 
+5.5.1.6  Kontrolle 
+ 
+'online' 
+   #on("b")#BOOL PROC online #off("b")# 
+   Liefert TRUE, wenn die Task mit einem Terminal gekoppelt ist. 
+ 
+ 
+'pause' 
+   #on("b")#PROC pause (INT CONST time limit) #off("b")# 
+   Wartet 'time limit' in Zehntel-Sekunden. Bei negativen Werten ist die Wirkung
+   nicht definiert. Die Wartezeit wird nicht nur durch das Erreichen der Grenze ab­
+   gebrochen, sondern auch durch die Eingabe eines beliebigen Zeichens. 
+ 
+   #on("b")#PROC pause#off("b")# 
+   Wartet bis zur Eingabe eines beliebigen Zeichens. 
+ 
+ 
+#page# 
+ 
+5.5.2  Zeitmessung 
+ 
+'clock' 
+   #on("b")#REAL PROC clock (INT CONST index) #off("b")# 
+   Datum und Uhrzeit werden vom EUMEL-System für alle Tasks geführt. Neben
+   einer Uhr ('Realzeituhr'), die das Datum und die aktuelle Uhrzeit enthält, wird eine
+   Uhr für die von der Task verbrauchte CPU-Zeit geführt ('CPU-Zeituhr'). Beide
+   Zeiten werden vom System als REALs realisiert. Die Prozedur 'clock' liefert die
+   aktuellen Werte dieser Uhren. Bei 'index = 0' wird die akkumulierte CPU-Zeit
+   der Task, bei 'index = 1' der Wert der Realzeituhr geliefert. 
+ 
+   Mit den REAL-Werten der Uhren kann ohne weiteres gerechnet werden, jedoch
+   sind nur Werte > 0 definiert. Die REAL-Werte der Realzeituhr beginnen beim
+   1.1.1900 um 0 Uhr. Es sind nur Werte für dieses Jahrhundert zugelassen. Werte
+   der Realzeituhr in lesbarer Form kann man durch die Konvertierungsprozeduren
+   'date' (vergl. 5- #topage("date")# ) (für den aktuellen Tag) und 'time of day' (Uhrzeit, vergl.
+   5-#topage("time")#) erhalten. 
+ 
+   Um die benötigte CPU-Zeit eines Programms zu berechnen, muß man die
+   CPU-Zeituhr zweimal abfragen. Um solche Zeiten in lesbarer Form zu erhalten,
+   kann man die Konvertierungsprozedur 'time' (vergl. 5- #topage("time")#) verwenden. Beispiel: 
+ 
+____________________________________________________________________________ 
+ 
+ ........................... Beispiel .......................... 
+        REAL CONST anfang :: clock (0); 
+              berechnungen; 
+        REAL CONST ende   :: clock (0); 
+           put ("benoetigte CPU-Zeit in Sek:"); 
+           put (time (ende - anfang)) 
+ 
+____________________________________________________________________________ 
+#page# 
+'date' 
+#goalpage("date")# 
+   #on("b")#TEXT PROC date (REAL CONST time) #off("b")# 
+   Konvertierungsprozedur für das Datum, welches sich aus dem Aufruf der Prozedur
+   'clock (1)' ergibt. Das Datum wird in der Form 'tt.mm.jj' geliefert. Beispiel: 
+ 
+____________________________________________________________________________ 
+ 
+           put (date (clock (1)))  (* z.B.: 24.12.87 *) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   #on("b")#REAL PROC date (TEXT CONST datum) #off("b")# 
+   Konvertierungsprozedur für ein Datum in der Form 'tt.mm.jj'. Liefert einen
+   REAL-Wert, wie ihn die Prozedur 'clock (1)' liefern würde. Beispiel: 
+ 
+____________________________________________________________________________ 
+ 
+              put (date ("24.12.87")) (* 6.273539e10 *) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   #on("b")#TEXT PROC date#off("b")# 
+   Liefert das Tagesdatum. Wirkt wie 'date (clock (1))', ist jedoch erheblich schneller. 
+ 
+ 
+ 
+'day' 
+   #on("b")#REAL CONST day #off("b")# 
+   Liefert die Anzahl der Sekunden eines Tages (86 400.0). 
+ 
+ 
+ 
+'hour' 
+   #on("b")#REAL CONST hour #off("b")# 
+   Liefert die Anzahl der Sekunden einer Stunde (3600.0). 
+ 
+ 
+ 
+'pause' 
+   #on("b")#PROC pause (INT CONST time limit) #off("b")# 
+   Wartet 'time limit' in Zehntel-Sekunden. Bei negativen Werten ist die Wirkung
+   nicht definiert. Die Wartezeit wird nicht nur durch das Erreichen der Grenze ab­
+   gebrochen, sondern auch durch die Eingabe eines beliebigen Zeichens. 
+ 
+ 
+ 
+'time' 
+#goalpage("time")# 
+   #on("b")#TEXT PROC time (REAL CONST time) #off("b")# 
+   Konvertierungsprozedur für die Zeiten der CPU-Zeituhr. Liefert die Zeiten in der
+   Form 'hh:mm:ss.s'. Vergl. dazu 'clock'. 
+ 
+   #on("b")#TEXT PROC time (REAL CONST value, INT CONST laenge) #off("b")# 
+   Konvertiert die Zeit in externe Darstellung. Für die 'laenge'-Werte ergibt sich: 
+ 
+ 
+        laenge = 10              (*   hh:mm:ss.s *) 
+        laenge = 12              (* hhhh:mm:ss.s *) 
+ 
+ 
+ 
+   #on("b")#REAL PROC time (TEXT CONST time) #off("b")# 
+   Konvertierungsprozedur für Texte der CPU-Zeituhr in REAL-Werte. 
+ 
+ 
+ 
+'time of day' 
+   #on("b")#TEXT PROC time of day (REAL CONST time) #off("b")# 
+   Konvertierungsprozedur für REALs, wie sie die Realzeituhr 
+   liefert. Es wird die Tageszeit in der Form 'hh:mm' geliefert. Beispiel: 
+ 
+____________________________________________________________________________ 
+ 
+              put (time of day (clock (1)))  (* z.B.: 17:25 *) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   #on("b")#TEXT PROC time of day #off("b")# 
+   Liefert die aktuelle Tageszeit. Entspricht 
+ 
+____________________________________________________________________________ 
+ 
+              time of day (clock (1)) 
+ 
+____________________________________________________________________________ 
+#page# 
+
+5.6  Scanner
+ 
+Der Scanner kann benutzt werden, um festzustellen, welche Art von Symbolen in
+einem TEXT enthalten sind. Die Repräsentation der Symbole müssen dabei der
+ELAN-Syntax entsprechen. Folgende #ib#Symbole#ie# kann der Scanner erkennen: 
+ 
+   - "tags", d.h. Namen, 
+   - "bolds", d.h. Schlüsselworte, 
+   - "number", d.h. INT oder REAL Zahlen, 
+   - Operatoren, 
+   - "delimiter", d.h. Begrenzer wie z.B. ";", 
+   - und das Ende des Scan-Textes. 
+ 
+ 
+Der Scanner überliest Kommentare und Leerzeichen zwischen den Symbolen. Der
+(erste) zu verarbeitende Text muß mit der Prozedur 
+ 
+ 
+     #ib#scan#ie# 
+ 
+ 
+in den Scanner "hineingesteckt" werden. Mit der Prozedur 
+ 
+ 
+     #ib#next symbol#ie# 
+ 
+ 
+wird das jeweils nächste Symbol des TEXTes geholt. Am Ende wird "end of scan"
+und als Symbol 'niltext' geliefert. Falls innerhalb eines TEXT-Denoters oder eines
+Kommentars "end of scan" auftritt, wird "within text" bzw. "within comment" gemel­
+det. Der Scan-Prozeß kann dann mit dem nächsten zu scannenden TEXT (der
+nächsten Zeile) fortgesetzt werden. Dafür wird nicht die Prozedur 'scan', sondern 
+ 
+ 
+     #ib#continue scan#ie# 
+ 
+ 
+verwandt. Sie setzt im letzten Scan-Zustand (z.B. Kommentar oder TEXT-Deno­
+ter) wieder auf, so daß auch Folgen von TEXTen (Zeilen) wie z.B. Dateien leicht
+gescannt werden können. 
+ 
+Mit den Prozeduren 
+ 
+ 
+     scan              (* meldet eine Datei zum scannen an *) 
+     next symbol       (* holt die Symbole                 *) 
+ 
+ 
+kann man auch eine Datei nach ELAN-Symbolen untersuchen. 
+ 
+____________________________________________________________________________ 
+ 
+     FILE VAR f :: ... 
+     ... 
+     scan (f);          (* beginnt das Scanning in 
+                           der nächsten Zeile      *) 
+     TEXT VAR symbol; 
+     INT VAR type; 
+     REP 
+       next symbol (f, symbol, type); 
+       verarbeite symbol 
+     UNTIL type >= 7 END REP. 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+ 
+Scanner-Kommandos 
+ 
+ 
+'continue scan' 
+   #on("b")#PROC continue scan (TEXT CONST scan text) #off("b")# 
+   Das Scanning soll mit 'scan text' fortgesetzt werden. Falls der Scan-Vorgang
+   beim vorigen 'scan text' innerhalb eines TEXT-Denoters oder eines Kommentars
+   abgebrochen wurde, wird er jetzt entsprechend mit dem nächsten 'next symbol'
+   fortgesetzt. Der erste Teil-Scan einer Folge muß aber stets mit 'scan' eingeleitet
+   werden! 
+ 
+'next symbol' 
+   #on("b")#PROC next symbol (TEXT VAR symbol, INT VAR type) #off("b")# 
+   Holt das nächste Symbol. In "symbol" steht der TEXT des Symbols, so z.B. die
+   Ziffern eines INT-Denoters. Bei TEXT-Denotern werden die führenden und
+   abschließenden Anführungsstriche abgeschnitten. Leerzeichen oder Kommentare
+   spielen in "tags" oder "numbers" keine Rolle. Zwischen Symbolen spielen Leer­
+   zeichen oder Kommentare keine Rolle. In "type" steht eine Kennzeichung für den
+   Typ des Symbols: 
+ 
+               tag             = 1 , 
+               bold            = 2 , 
+               number          = 3 , 
+               text            = 4 , 
+               operator        = 5 , 
+               delimiter       = 6 , 
+               end of file     = 7 , 
+               within comment  = 8 , 
+               within text     = 9 . 
+ 
+   Wird Scan-Ende innerhalb eines Kommentars gefunden, so wird 'niltext' und
+   'within comment' geliefert. Wird Scan-Ende innerhalb eines TEXT-Denoters
+   gefunden, so wird der schon analysierte Teil des Denoters und 'within text' gelie­
+   fert. 
+ 
+   #on("b")#PROC next symbol (TEXT VAR symbol) #off("b")# 
+   s.o. Es wird aber nur der Text des Symbols (ohne Typ) geliefert. 
+ 
+   #on("b")#PROC next symbol (FILE VAR f, TEXT CONST symbol) #off("b")# 
+   Arbeitet wie obige Prozeduren, jedoch auf einen FILE. 
+ 
+   #on("b")#PROC next symbol (FILE VAR f, TEXT CONST symbol, INT VAR type)#off("b")# 
+   Arbeitet wie obige Prozeduren, jedoch auf einen FILE. 
+ 
+ 
+'scan' 
+   #on("b")#PROC scan (TEXT CONST scan text) #off("b")# 
+   Meldet einen 'scan text' für den Scanner zur Verarbeitung an. Die Prozedur 'scan'
+   muß vor dem ersten Aufruf von 'next symbol' gegeben werden. Im Gegensatz zu
+   'continue scan' normiert 'scan' den inneren Zustand des Scanners, d.h. vorherige
+   Scan-Vorgänge haben keinen Einfluß mehr auf das Scanning. 
+ 
+   #on("b")#PROC scan (FILE VAR f) #off("b")# 
+   Wie obige Prozedur, jedoch auf einen FILE. Die zu scannende Zeile ist die näch­
+   ste Zeile im FILE 'f' ('scan' macht zuerst ein 'getline'). 
+
diff --git a/doc/programming/programmierhandbuch.6 b/doc/programming/programmierhandbuch.6
new file mode 100644
index 0000000..ce11f6f
--- /dev/null
+++ b/doc/programming/programmierhandbuch.6
@@ -0,0 +1,1441 @@
+#pagenr("%",1)##setcount(1)##block##pageblock# 
+#headeven# 
+#center#EUMEL-Benutzerhandbuch 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#TEIL 6 : Das Archiv 'std.zusatz' 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+6 - % #right#GMD 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+GMD #right#6 - % 
+#end# 
+ 
+TEIL 6:  Das Archiv 'std.zusatz' 
+ 
+Das Archiv 'std.zusatz' enthält Pakete, die nur bei Bedarf insertiert werden sollen.
+Eine Einbindung in das EUMEL Grundsystem würde dieses ungebührlich unfangreich
+machen. 
+ 
+Das Archiv enthält zusätzliche Software für: 
+ 
+- mathematische Operationen :  complex , longint , vector , matrix 
+ 
+- Analyse                   :  reporter , referencer 
+ 
+- Taschenrechnerfunktion 
+  zur Editor-Erweiterung    :  TeCal , TeCal Auskunft 
+ 
+ 
+#page# 
+
+6.1.  Erweiterungen um 
+      Mathematische Operationen
+ 
+ 
+6.1.1  COMPLEX 
+ 
+Das Packet COMPLEX erweitert das System um den Datentyp COMPLEX (komplexe
+Zahlen) und Operationen auf komplexen Zahlen. Folgende Operationen stehen für
+COMPLEX zur Verfügung: 
+ 
+- Einfache Operatoren       :  := , = , <> , + ,- , * 
+ 
+- Eingabe/Ausgabe           :  get , put 
+ 
+- Denotierungsprozedur      :  complex , complex i , complex one , com­ 
+                               plex zero 
+ 
+- Komponenten               :  real part , imag part 
+ 
+- bes. Funktionen           :  ABS , CONJ , phi , dphi , sqrt 
+ 
+#page# 
+
+COMPLEX Operationen 
+ 
+ 
+'TYPE COMPLEX' 
+   Komplexe Zahl, bestehend aud Realteil 're' und Imaginärteil 'im'. 
+ 
+ 
+':=' 
+   #on("b")#OP := (COMPLEX VAR a, COMPLEX CONST b) #off("b")# 
+   Zuweisung. 
+ 
+ 
+'=' 
+   #on("b")#BOOL OP = (COMPLEX CONST a, b) #off("b")# 
+   Vergleich von 'a' und 'b' auf Gleichheit. 
+ 
+ 
+'<>' 
+   #on("b")#BOOL OP <> (COMPLEX CONST a, b) #off("b")# 
+   Vergleich von 'a' und 'b' auf Ungleichheit. 
+ 
+ 
+'+' 
+   #on("b")#COMPLEX OP + (COMPLEX CONST a, b) #off("b")# 
+   Summe von 'a' und 'b'. 
+ 
+ 
+'-' 
+   #on("b")#COMPLEX OP - (COMPLEX CONST a, b) #off("b")# 
+   Differenz von 'a' und 'b'. 
+ 
+ 
+'*' 
+   #on("b")#COMPLEX OP * (COMPLEX CONST a, b) #off("b")# 
+   Multiplikation von 'a' mit 'b'. 
+ 
+ 
+'/' 
+   #on("b")#COMPLEX OP / (COMPLEX CONST a, b) #off("b")# 
+   Division von 'a' mit 'b'. 
+ 
+#page# 
+'get' 
+   #on("b")#PROC get (COMPLEX VAR a) #off("b")# 
+   Einlesen eines komplexen Wertes vom Bildschirm in der Form zweier REAL-De­
+   noter. Die Eingabe kann editiert werden. 
+ 
+ 
+'put' 
+   #on("b")#PROC put (COMPLEX CONST a) #off("b")# 
+   Ausgabe eines komplexen Wertes auf dem Bildschirm in Form zweier REAL-
+   Werte. Hinter jedem REAL-Wert wird ein Leerzeichen angefügt. 
+ 
+ 
+'complex' 
+   #on("b")#COMPLEX PROC complex (REAL CONST re, im) #off("b")# 
+   Denotierungsprozedur. Angabe in kartesischen Koordinaten. 
+ 
+ 
+'complex i' 
+   #on("b")#COMPLEX PROC complex i #off("b")# 
+   Denotierungsprozedur für den komplexen Wert '0.0 + i 1.0'. 
+ 
+ 
+'complex one' 
+   #on("b")#COMPLEX PROC complex one #off("b")# 
+   Denotierungsprozedur für den komplexen Wert '1.0 + i 0.0'. 
+ 
+ 
+'complex zero' 
+   #on("b")#COMPLEX PROC complex zero #off("b")# 
+   Denotierungsprozedur für den komplexen Wert '0.0 + i 0.0'. 
+ 
+ 
+'imag part' 
+   #on("b")#REAL PROC imag part (COMPLEX CONST number) #off("b")# 
+   Liefert den Imaginärteil des komplexen Wertes 'number'. 
+ 
+ 
+'real part' 
+   #on("b")#REAL PROC real part (COMPLEX CONST number) #off("b")# 
+   Liefert den Real-Teil des komplexen Wertes 'number'. 
+ 
+ 
+'ABS' 
+   #on("b")#REAL OP ABS (COMPLEX CONST x) #off("b")# 
+   REAL-Betrag von 'x'. 
+ 
+ 
+'CONJ' 
+   #on("b")#COMPLEX OP CONJ (COMPLEX CONST number) #off("b")# 
+   Liefert den konjugiert komplexen Wert von 'number'. 
+ 
+ 
+'dphi' 
+   #on("b")#REAL PROC dphi (COMPLEX CONST x) #off("b")# 
+   Winkel von 'x' (Polardarstellung). 
+ 
+ 
+'phi' 
+   #on("b")#REAL PROC phi (COMPLEX CONST x) #off("b")# 
+   Winkel von 'x' (Polardarstellung) in Radiant. 
+ 
+ 
+'sqrt' 
+   #on("b")#COMPLEX PROC sqrt (COMPLEX CONST x) #off("b")# 
+   Wurzelfunktion für komplexe Werte. 
+ 
+#page# 
+
+6.1.2  LONGINT 
+ 
+LONGINT ist ein Datentyp, für den (fast) alle Prozeduren und Operatoren des Daten­
+typs INT implementiert wurden. LONGINT unterscheidet sich von INT dadurch, daß
+erheblich größere Werte darstellbar sind. 
+ 
+Für den Datentyp LONGINT stehen folgende Operationen zur Verfügung: 
+ 
+- Operatoren                :  := , = , <> , < , <= ,> , >= , + , - , * , 
+                               ** , 
+                               ABS , DECR , DIV , INCR , MOD , SIGN 
+ 
+- Eingabe/Ausgabe           :  get , put 
+ 
+ 
+- Math. Prozeduren          :  abs , int , longint , max , max logint , min , 
+                               random , sign , text , zero 
+ 
+ 
+ 
+LONGINT-Operationen 
+ 
+ 
+'TYPE LONGINT' 
+   Datentyp 
+ 
+ 
+':=' 
+   #on("b")#OP := (LONGINT VAR links, LONGINT CONST rechts) : #off("b")# 
+   Zuweisungsoperator 
+ 
+ 
+'= ' 
+   #on("b")#BOOL OP = (LONGINT CONST links, rechts) #off("b")# 
+   Vergleichen zweier LONGINTs auf Gleichheit. 
+ 
+ 
+'<>' 
+   #on("b")#BOOL OP <> (LONGINT CONST links, rechts) #off("b")# 
+   Vergleichen zweier LONGINTs auf Ungleichheit. 
+ 
+ 
+'< ' 
+   #on("b")#BOOL OP < (LONGINT CONST links, rechts) #off("b")# 
+   Vergleichen zweier LONGINTs auf kleiner. 
+ 
+ 
+'<=' 
+   #on("b")#BOOL OP <= (LONGINT CONST links, rechts) #off("b")# 
+   Vergleichen zweier LONGINTs auf kleiner gleich. 
+ 
+ 
+'> ' 
+   #on("b")#BOOL OP > (LONGINT CONST links, rechts) #off("b")# 
+   Vergleichen zweier LONGINTs auf größer. 
+ 
+ 
+'>=' 
+   #on("b")#BOOL OP >= (LONGINT CONST links, rechts) #off("b")# 
+   Vergleichen zweier LONGINTs auf größer gleich. 
+ 
+ 
+'+ ' 
+   #on("b")#LONGINT OP + (LONGINT CONST argument) #off("b")# 
+   Monadischer Operator. Ohne Wirkung. 
+ 
+   #on("b")#LONGINT OP + (LONGINT CONST links, rechts) #off("b")# 
+   Addition zweier LONGINTs. 
+ 
+ 
+'- ' 
+   #on("b")#LONGINT OP - (LONGINT CONST argument) #off("b")# 
+   Vorzeichenumkehrung. 
+ 
+   #on("b")#LONGINT OP - (LONGINT CONST links, rechts) #off("b")# 
+   Subtraktion zweier LONGINTs. 
+ 
+ 
+'* ' 
+   #on("b")#LONGINT OP * (LONGINT CONST links, rechts) #off("b")# 
+   Multiplikation von zwei LONGINTs. 
+ 
+ 
+'**' 
+   #on("b")#LONGINT OP ** (LONGINT CONST argument, exponent) #off("b")# 
+   Exponentiation zweier LONGINTs mit positivem Exponenten. 
+ 
+   FEHLER : 
+            LONGINT OP ** : negative exponent 
+            Der 'exponent' muß >= 0 sein. 
+            0 ** 0 is not defined 
+            'argument' und 'exponent' dürfen nicht gleich 0 sein. 
+ 
+ 
+   #on("b")#LONGINT OP ** (LONGINT CONST argument, INT CONST exponent)#off("b")# 
+   Exponentiation eines LONGINT mit positiven INT Exponenten. 
+ 
+   FEHLER : 
+            LONGINT OP ** : negative exponent 
+            Der 'exponent' muß >= 0 sein. 
+            0 ** 0 is not defined 
+            'argument' und 'exponent' dürfen nicht gleich 0 sein. 
+ 
+'ABS' 
+   #on("b")#LONGINT OP ABS (LONGINT CONST argument) #off("b")# 
+   Absolutbetrag eines LONGINT. 
+ 
+ 
+'DECR' 
+   #on("b")#OP DECR (LONGINT VAR resultat, LONGINT CONST ab) #off("b")# 
+   resultat := resultat - ab 
+ 
+ 
+'DIV' 
+   #on("b")#LONGINT OP DIV (LONGINT CONST links, rechts) #off("b")# 
+   Division zweier LONGINTs. 
+ 
+   FEHLER : 
+             Division durch 0 
+            'rechts' muß <> 0 sein. 
+ 
+ 
+'INCR' 
+   #on("b")#LONGINT OP INCR (LONGINT VAR resultat, LONGINT CONST dazu)#off("b")# 
+   resultat := resultat + dazu 
+ 
+ 
+ 
+'MOD' 
+   #on("b")#LONGINT OP MOD (LONGINT CONST links, rechts) #off("b")# 
+   Modulo-Funktion für LONGINTs. Der Rest einer LONGINT-Division wird ermit­
+   telt. 
+ 
+   FEHLER : 
+           text (links) + 'MOD 0' 
+           'rechts' muß ungleich null sein. 
+ 
+ 
+'SIGN' 
+   #on("b")#INT OP SIGN (LONGINT CONST longint) #off("b")# 
+   Feststellen des Vorzeichens von 'longint'. Liefert: 
+ 
+ 
+           0 wenn 'longint' = 0, 
+           1 wenn 'longint' > 0, 
+          -1 wenn 'longint' < 0. 
+ 
+ 
+#page# 
+'get' 
+   #on("b")#PROC get (LONGINT VAR zahl) #off("b")# 
+   Eingabe eines LONGINTs vom Terminal. 
+ 
+   #on("b")#PROC get (FILE VAR file, LONGINT VAR zahl) #off("b")# 
+   Einlesen von 'zahl' aus der sequentiellen Datei 'file'. Die Datei muß mit 'input'
+   assoziiert sein (vergl. 'sequential file'). 
+ 
+   FEHLER : 
+           Datei zu 
+           Leseversuch nach Daateiende 
+           Leseversuch auf output-FILE 
+ 
+ 
+'put' 
+   #on("b")#PROC put (LONGINT CONST longint) #off("b")# 
+   Ausgabe eines LONGINTs auf dem Bildschirm. Anschließend wird ein Leerzeichen
+   ausgegeben. Hardwareabhängig sind die Aktionen, wenn eine Ausgabe über die
+   Bildschirmzeilengrenze vorgenommen wird. Meist wird jedoch die Ausgabe auf der
+   nächsten Zeile fortgesetzt. 
+ 
+   #on("b")#PROC put (FILE VAR file, LONGINT CONST zahl) #off("b")# 
+   Ausgabe von 'zahl' in die sequentielle Datei 'file'. 'file' muß mit 'output' assoziiert
+   sein. 
+ 
+   FEHLER : 
+           Datei zu 
+           Schreibversuch auf input-FILE 
+#page# 
+'abs' 
+   #on("b")#LONGINT PROC abs (LONGINT CONST argument) #off("b")# 
+   Absolutbetrag eines LONGINT. 
+ 
+ 
+'int' 
+   #on("b")#INT PROC int (LONGINT CONST longint) #off("b")# 
+   Konvertierung von LONGINT nach INT. 
+ 
+   FEHLER : 
+           integer overflow 
+           'longint' ist größer als 'maxint'. 
+ 
+ 
+'longint' 
+   #on("b")#LONGINT PROC longint (INT CONST int) #off("b")# 
+   Konvertierung von 'int' nach LONGINT. 
+ 
+   #on("b")#LONGINT PROC longint (TEXT CONST text) #off("b")# 
+   Konvertierung von 'text' nach LONGINT. 
+ 
+ 
+'max' 
+   #on("b")#LONGINT PROC max (LONGINT CONST links, rechts) #off("b")# 
+   Liefert das Maximum zweier LONGINTs. 
+ 
+ 
+'maxlongint' 
+   #on("b")#LONGINT PROC max longint #off("b")# 
+   Liefert größten LONGINT Wert. 
+ 
+ 
+'min' 
+   #on("b")#LONGINT PROC min (LONGINT CONST links, rechts) #off("b")# 
+   Liefert das Minimum zweier LONGINTs. 
+ 
+ 
+'random' 
+   #on("b")#LONGINT PROC random (LONGINT CONST lower bound, upper bound)#off("b")# 
+   Pseudo-Zufallszahlen-Generator im Intervall 'lower bound' und 'upper bound'
+   einschließlich. Es handelt sich hier um den 'LONGINT Random Generator'. 
+ 
+ 
+'sign' 
+   #on("b")#INT PROC sign (LONGINT CONST longint) #off("b")# 
+   Feststellen des Vorzeichens von 'longint'. Liefert: 
+ 
+ 
+           0 wenn 'longint' = 0, 
+           1 wenn 'longint' > 0, 
+          -1 wenn 'longint' < 0. 
+ 
+ 
+ 
+'text' 
+   #on("b")#TEXT PROC text (LONGINT CONST longint) #off("b")# 
+   Konvertierung von 'longint' nach TEXT. 
+ 
+   #on("b")#TEXT PROC text (LONGINT CONST longint, INT CONST laenge) #off("b")# 
+   Konvertierung von 'longint' nach TEXT. Die Anzahl der Zeichen soll 'laenge'
+   betragen. Für 
+ 
+ 
+           LENGTH (text (longint)) < laenge 
+ 
+ 
+   werden die Zeichen rechtsbündig in einen Text mit der Länge 'laenge' eingetra­
+   gen. Ist der daraus entstehende TEXT kleiner als 'laenge', werden die an 'laenge'
+   fehlenden Zeichen im TEXT mit Leerzeichen aufgefüllt. Für 
+ 
+ 
+          LENGTH (text (longint)) > laenge 
+ 
+ 
+   wird ein Text mit der Länge 'laenge' geliefert, der mit '*'-Zeichen gefüllt ist. 
+ 
+ 
+'zero' 
+   #on("b")#LONGINT PROC zero #off("b")# 
+   Liefert LONGINT Wert Null. 
+ 
+ 
+#page# 
+
+6.1.3  VECTOR 
+ 
+Der Datentyp VECTOR erlaubt Operationen auf Vektoren aus Elementen vom Typ
+REAL. Im Gegensatz zur Struktur 'ROW m REAL' muß die Anzahl der Elemente nicht
+zur Übersetzungszeit deklariert werden, sondern kann zur Laufzeit festgelegt werden.
+Somit kann eine zur Übersetzungszeit unbekannte Anzahl von REALs bearbeitet
+werden, wobei nur soviel Speicherplatz wie nötig verwendet wird. Die maximale Größe
+eines VECTOR beträgt 4000 Elemente. 
+ 
+Der in den Operationen ':=', 'idn' und 'vector' benutzte Datentyp INITVECTOR wird
+nur intern gehalten. Er dient der Speicherplatzersparnis bei der Initialisierung. 
+ 
+ 
+- Operatoren                :  := , = , <> , + , - , * , / 
+                               LENGTH , SUB 
+ 
+- Eingabe/Ausgabe           :  get , put 
+ 
+- Besondere Vector-         :  length , nilvector , norm , vector , replace 
+  Operationen 
+ 
+#page# 
+':=' 
+   #on("b")#OP := (VECTOR VAR ziel, VECTOR CONST quelle) #off("b")# 
+   Zuweisung. Nach der Zuweisung gilt auch 
+ 
+ 
+           length (quelle) = length (ziel) 
+ 
+ 
+   d.h. der linke Operand besitzt nach der Zuweisung genauso viele Elemente wie
+   'quelle', unabhängig davon, ob 'ziel' vor der Zuweisung mehr oder weniger Ele­
+   mente als 'quelle' besaß. Beispiel: 
+ 
+ 
+           VECTOR VAR y :: vector (10, 1.0), 
+                      z :: vector (15, 2.0); 
+                ... 
+           y := z; (* length (y) liefert nun 15 ! *) 
+ 
+ 
+   #on("b")#OP := (VECTOR VAR ziel, INITVECTOR CONST quelle) #off("b")# 
+   Dient zur Initialisierung eines VECTORs. Beispiel: 
+ 
+ 
+           VECTOR VAR x :: vector (17); 
+ 
+ 
+   'vector' erzeugt ein Objekt vom Datentyp INITVECTOR. Dieses Objekt braucht
+   nicht soviel Speicherplatz wie ein VECTOR-Objekt. Dadurch wird vermieden, daß
+   nach erfolgter Zuweisung nicht ein durch 'vector' erzeugtes Objekt auf dem Heap
+   unnötig Speicherplatz verbraucht. 
+ 
+ 
+'=' 
+   #on("b")#BOOL OP = (VECTOR CONST a, b) #off("b")# 
+   Vergleich zweier Vektoren. Der Operator liefert FALSE, wenn die Anzahl der
+   Elemente von 'a' und 'b' ungleich ist oder wenn zwei Elemente mit gleichem
+   Index ungleich sind. Beispiel: 
+ 
+ 
+           VECTOR VAR x :: vector (10, 1.0), 
+                      y :: vector (15, 2.0), 
+                      z :: vector (10, 1.0); 
+                   ... x = y ... (* FALSE *) 
+                   ... x = z ... (* TRUE  *) 
+ 
+ 
+'<>' 
+   #on("b")#BOOL OP <> (VECTOR CONST a, b) #off("b")# 
+   Vergleich zweier Vektoren auf Ungleichheit (NOT (a = b)). 
+ 
+ 
+'+' 
+   #on("b")#VECTOR OP + (VECTOR CONST a) #off("b")# 
+   Monadisches '+' für VECTOR. Keine Auswirkung. 
+ 
+   #on("b")#VECTOR OP + (VECTOR CONST a, b) #off("b")# 
+   Elementweise Addition der Vektoren 'a' und 'b'. Beispiel: 
+ 
+ 
+           VECTOR VAR x, (* 'x' hat undefinierte Länge *) 
+                      a :: vector (10, 1.0), 
+                      b :: vector (10, 2.0); 
+                 ... 
+           x := a + b; (* 'x' hat nun 10 Elemente mit Werten'3.0'
+           *) 
+ 
+   FEHLER : 
+           VECTOR OP + : LENGTH a <> LENGTH b 
+           'a' und 'b' haben nicht die gleiche Anzahl von Elementen. 
+ 
+ 
+'-' 
+   #on("b")#VECTOR OP - (VECTOR CONST a) #off("b")# 
+   Monadisches '-'. 
+ 
+   #on("b")#VECTOR OP - (VECTOR CONST a, b) #off("b")# 
+   Elementweise Subtraktion der Vektoren 'a' und 'b'. 
+ 
+   FEHLER : 
+           VECTOR OP - : LENGTH a <> LENGTH b 
+           'a' und 'b' haben nicht die gleiche Anzahl von Elementen. 
+ 
+'*' 
+   #on("b")#REAL OP * (VECTOR CONST a, b) #off("b")# 
+   Skalarprodukt zweier Vektoren. Liefert die Summe der elementweisen Multiplika­
+   tion der Vektoren 'a' und 'b'. Beachte eventuelle Rundungsfehler! Beispiel: 
+ 
+ 
+           REAL VAR a; 
+           VECTOR VAR b :: vector (10, 2.0), 
+                      c :: vector (10, 2.0); 
+                 ... 
+           a := b * c; (* 40.0 *) 
+ 
+   FEHLER : 
+           REAL OP * : LENGTH a <> LENGTH b 
+           'a' und 'b' haben nicht die gleiche Anzahl von Elementen. 
+ 
+   #on("b")#VECTOR OP * (VECTOR CONST a, REAL CONST s) #off("b")# 
+   Multiplikation des Vektors 'a' mit dem Skalar 's'. 
+ 
+   #on("b")#VECTOR OP * (REAL CONST s, VECTOR CONST a) #off("b")# 
+   Multiplikation des Skalars 's' mit dem Vektor 'a'. 
+ 
+ 
+'/' 
+   #on("b")#VECTOR OP / (VECTOR CONST a, REAL CONST s) #off("b")# 
+   Division des Vektors 'a' durch den Skalar 's'. Beispiel: 
+ 
+ 
+           VECTOR VAR a, (* 'a' hat undefinierte Laenge *) 
+                      b :: vector (10, 4.0); 
+                ... 
+           a := b / 2.0; 
+           (* 'a' hat nun 10 Elemente mit Werten '2.0' *) 
+ 
+ 
+ 
+'LENGTH' 
+   #on("b")#INT OP LENGTH (VECTOR CONST a) #off("b")# 
+   Liefert die Anzahl der Elemente von 'a'. 
+ 
+ 
+'SUB' 
+   #on("b")#REAL OP SUB (VECTOR CONST v, INT CONST i) #off("b")# 
+   Liefert das 'i'-te Element von 'v'. 
+ 
+   FEHLER : 
+           OP SUB : subscript overflow 
+           Der Index 'i' liegt außerhalb des Vektors (i > LENGTH v). 
+           OP SUB : subscript underflow 
+           Der Index 'i' liegt außerhalb des Vektors (i < 1). 
+ 
+#page# 
+'get' 
+   #on("b")#PROC get (VECTOR VAR a, INT CONST l) #off("b")# 
+   Einlesen der Elemente von 'a' vom Terminal, wobei 'l' die Anzahl der Elemente
+   angibt. 
+ 
+   FEHLER : 
+           PROC get : size <= 0 
+           Die angeforderte Elementanzahl 'l' muß > 0 sein. 
+ 
+ 
+'put' 
+   #on("b")#PROC put (VECTOR CONST v) #off("b")# 
+   Ausgabe der Werte der Elemente von 'v' auf dem Terminal. 
+ 
+ 
+#page# 
+'length' 
+   #on("b")#INT PROC length (VECTOR CONST a) #off("b")# 
+   Liefert die Anzahl der Elemente von 'a'. Beispiel: 
+ 
+ 
+           VECTOR VAR a :: vector (10, 1.0), 
+                      b :: vector (15, 2.0); 
+                ... 
+            ... length (a) ... (* 10 *) 
+            ... length (b) ... (* 15 *) 
+ 
+ 
+ 
+'nilvector' 
+   #on("b")#INITVECTOR PROC nilvector #off("b")# 
+   Erzeugen eines Vektors mit einem Element mit dem Wert '0.0'. 
+ 
+ 
+'norm' 
+   #on("b")#REAL PROC norm (VECTOR CONST v) #off("b")# 
+   Euklidische Norm (Wurzel aus der Summe der Quadrate der Elemente). 
+ 
+ 
+ 
+'replace' 
+   #on("b")#PROC replace (VECTOR VAR v, INT CONST i, REAL CONST r)#off("b")# 
+   Zuweisung des i-ten Elementes von 'v' mit dem Wert von 'r'. Beispiel: 
+ 
+ 
+           VECTOR VAR v :: ...; 
+               ... 
+           replace (v, 13, 3.14); 
+           (* Das 13. Element von 'v' bekommt den Wert '3.14' *) 
+ 
+   FEHLER : 
+           PROC replace : subscript overflow 
+           Der Index 'i' liegt außerhalb des Vektors (i > LENGTH v). 
+           PROC replace : subscript underflow 
+           Der Index 'i' liegt außerhalb des Vektors (i < 1). 
+ 
+ 
+'vector' 
+   #on("b")#INITVECTOR PROC vector (INT CONST l) #off("b")# 
+   Erzeugen eines Vektors mit 'l' Elementen. Ein INITVECTOR-Objekt benötigt nicht
+   soviel Speicherplatz wie ein VECTOR-Objekt. Die Elemente werden mit dem
+   Wert '0.0' initialisiert. 
+ 
+   FEHLER : 
+           PROC vector : size <= 0 
+           Die angeforderte Elementanzahl 'l' muß > 0 sein. 
+ 
+   #on("b")#INITVECTOR PROC vector (INT CONST l, REAL CONST value)#off("b")# 
+   Erzeugen eines Vektors mit 'l' Elementen. Ein INITVECTOR-Objekt benötigt nicht
+   soviel Speicherplatz wie ein VECTOR-Objekt. Die Elemente werden mit dem
+   Wert 'value' initialisiert. Beispiel: 
+ 
+ 
+           VECTOR VAR v := vector (17, 3.14159); 
+           (* 'v' hat 17 Elemente mit den Wert '3.14159' *) 
+ 
+    FEHLER : 
+           PROC vector : size <= 0 
+           Die angeforderte Elementanzahl 'l' muß > 0 sein. 
+ 
+#page# 
+
+6.1.4  MATRIX
+
+Der Datentyp MATRIX erlaubt Operationen auf m x n Matrizen. Im Gegensatz zur
+Struktur 'ROW m ROW n REAL' muß die Anzahl der Elemente nicht zur Überset­
+zungszeit deklariert werden, sondern kann zur Laufzeit festgelegt werden. Somit kann
+eine zur Übersetzungszeit unbekannte Anzahl von REALs bearbeitet werden, wobei
+nur soviel Speicherplatz wie nötig verwendet wird. Die maximale Größe einer MATRIX
+beträgt 4000 Elemente. 
+ 
+Der in den Operationen ':=', 'idn' und 'matrix' benutzte Datentyp INITMATRIX wird
+nur intern gehalten. Er dient der Speicherplatzersparnis bei der Initialisierung. 
+ 
+ 
+- Operatoren                :  := , = , <> , + , - , * 
+                               COLUMNS , DET , INV , ROWS , TRANSP , 
+ 
+- Eingabe/Ausgabe           :  get , put 
+ 
+- Besondere Matrix-         :  column , idn , matrix , row , sub 
+  Operationen                  transp , 
+                               replace column , replace element , 
+                               replace row 
+ 
+ 
+ 
+#page# 
+':=' 
+   #on("b")#OP := (MATRIX VAR l, MATRIX CONST r) #off("b")# 
+   Zuweisung von 'r' auf 'l'. Die MATRIX 'l' bekommt u.U. eine neue Anzahl von
+   Elementen. Beispiel: 
+    
+ 
+           MATRIX VAR a :: matrix (3, 4, 0.0), 
+                      b :: matrix (5, 5, 3.0); 
+                          ... 
+           a := b; (* 'a' hat jetzt 5 x 5 Elemente *) 
+ 
+ 
+   #on("b")#OP := (MATRIX VAR l, INITMATRIX CONST r) #off("b")# 
+   Dient zur Initialisierung einer Matrix. Beispiel: 
+ 
+ 
+           MATRIX VAR x :: matrix (17, 4); 
+ 
+ 
+   'matrix' erzeugt ein Objekt vom Datentyp INITMATRIX. Dieses Objekt braucht
+   nicht soviel Speicherplatz wie ein MATRIX-Objekt. Dadurch wird vermieden, daß
+   nach erfolgter Zuweisung nicht ein durch 'matrix' erzeugtes Objekt auf dem Heap
+   unnötig Speicherplatz verbraucht. 
+ 
+'=' 
+   #on("b")#BOOL OP = (MATRIX CONST l, r) #off("b")# 
+   Vergleich zweier Matrizen. Der Operator '=' liefert FALSE, wenn die Anzahl
+   Spalten oder Reihen der Matrizen 'l' und 'r' ungleich ist und wenn mindestens ein
+   Element mit gleichen Indizes der zwei Matrizen ungleiche Werte haben. Beispiel: 
+ 
+ 
+           MATRIX VAR a :: matrix (3, 3), 
+                      b :: matrix (3, 3, 1.0), 
+                      c :: matrix (4, 4); 
+                 ... a = b ... 
+           (* FALSE wegen ungleicher Werte   *) 
+                 ... a = c ... 
+           (* FALSE wegen ungleicher Groesse *) 
+                 ... b = c ... 
+           (* FALSE wegen ungleicher Groesse *) 
+ 
+ 
+ 
+'<>' 
+   #on("b")#BOOL OP <> (MATRIX CONST l, r) #off("b")# 
+   Vergleich der Matrizen 'l' und 'r' auf Ungleichheit. 
+ 
+ 
+'+' 
+   #on("b")#MATRIX OP + (MATRIX CONST m) #off("b")# 
+   Monadisches '+'. Keine Auswirkungen. 
+ 
+   #on("b")#MATRIX OP + (MATRIX CONST l, r) #off("b")# 
+   Addition zweier Matrizen. Die Anzahl der Reihen und der Spalten muß gleich sein.
+   Beispiel: 
+ 
+           MATRIX VAR a :: matrix (3, 43, 1.0), 
+                      b :: matrix (3, 43, 2.0), 
+                           summe; 
+                      summe := a + b; 
+           (* Alle Elemente haben den Wert '3.0' *) 
+ 
+ 
+     FEHLER: 
+           MATRIX OP + : COLUMNS l <> COLUMNS r 
+           Die Anzahl der Spalten von 'l' und 'r' sind nicht gleich. 
+           MATRIX OP + : ROWS l <> ROWS r 
+           Die Anzahl der Zeilen von 'l' und 'r' sind nicht gleich. 
+ 
+ 
+'-' 
+   #on("b")#MATRIX OP - (MATRIX CONST m) #off("b")# 
+   Monadisches Minus. Beispiel: 
+ 
+ 
+           MATRIX VAR a :: matrix (3, 4, 10.0) 
+           a := - a; (* Alle Elemente haben den Wert '- 10.0' *) 
+ 
+ 
+   #on("b")#MATRIX OP - (MATRIX CONST l, r) #off("b")# 
+   Subtraktion zweier Matrizen. Die Anzahl der Reihen und Spalten muß gleich sein. 
+ 
+   FEHLER: 
+           MATRIX OP - : COLUMNS l <> COLUMNS r 
+           Die Anzahl der Spalten von 'l' und 'r' sind nicht gleich. 
+           MATRIX OP - : ROWS l <> ROWS r 
+           Die Anzahl der Zeilen von 'l' und 'r' sind nicht gleich. 
+ 
+'*' 
+   #on("b")#MATRIX OP * (REAL CONST r, MATRIX CONST m) #off("b")# 
+   Multiplikation einer Matrix 'm' mit einem Skalar 'r'. Beispiel: 
+ 
+ 
+           MATRIX VAR a :: matrix (3, 4, 2.0); 
+                ... 
+           a := 3 * a; (* Alle Elemente haben den Wert '6.0' *) 
+ 
+ 
+   #on("b")#MATRIX OP * (MATRIX CONST m, REAL CONST r) #off("b")# 
+   Multiplikation einer Matrix 'm' mit einem Skalar 'r'. 
+ 
+   #on("b")#MATRIX OP * (MATRIX CONST l, r) #off("b")# 
+   Multiplikation zweier Matrizen. Die Anzahl der Spalten von 'l' und die Anzahl der
+   Zeilen von 'r' müssen gleich sein. Beispiel: 
+ 
+ 
+           MATRIX VAR a :: matrix (3, 4, 2.0), 
+                      b :: matrix (4, 2, 3.0), 
+                      produkt; 
+           produkt := a * b; 
+           (* Alle Elemente haben den Wert '24.0' *) 
+ 
+ 
+   FEHLER : 
+           MATRIX OP * : COLUMNS l <> ROWS r 
+           Die Anzahl der Spalten von 'l' muß mit der Anzahl der Zeilen von 'r'
+           übereinstimmen. 
+ 
+   #on("b")#VECTOR OP * (VECTOR CONST v, MATRIX CONST m) #off("b")# 
+   Multiplikation des Vektors 'v' mit der Matrix 'm'. 
+ 
+   FEHLER : 
+            VECTOR OP * : LENGTH v <> ROWS m 
+            Die Anzahl der Elemente von 'v' stimmt nicht mit den Anzahl der Zeilen
+            von 'm' überein. 
+ 
+   #on("b")#VECTOR OP * (MATRIX CONST m, VECTOR CONST v) #off("b")# 
+   Multiplikation der Matrix 'm' mit dem Vektor 'v'. 
+ 
+   FEHLER : 
+            VECTOR OP * : COLUMNS m <> LENGTH v 
+            Die Anzahl der Spalten von 'm' stimmt nicht mit der Anzahl der Ele­
+            menten von 'v' überein. 
+ 
+ 
+'COLUMNS' 
+   #on("b")#INT OP COLUMNS (MATRIX CONST m) #off("b")# 
+   Liefert die Anzahl der Spalten von 'm'. Beispiel: 
+ 
+ 
+           MATRIX VAR a :: matrix (3, 4), 
+                      b :: matrix (7, 10); 
+           put (COLUMNS a); (* 4 *) 
+           put (COLUMNS b); (* 10 *) 
+ 
+ 
+ 
+'DET' 
+   #on("b")#REAL OP DET (MATRIX CONST m) #off("b")# 
+   Es wird der Wert der Determinanten von 'm' geliefert. 
+ 
+   FEHLER : 
+           OP DET : no square matrix 
+           Die Matrix ist nicht quadratisch, d.h. ROWS m <> COLUMNS m 
+ 
+ 
+'INV' 
+   #on("b")#MATRIX OP INV (MATRIX CONST m) #off("b")# 
+   Liefert als Ergebnis die Inverse von 'm' (Achtung: starke Rundungsfehler möglich). 
+ 
+   FEHLER: 
+           OP INV : no square matrix 
+           Die Matrix 'm' ist nicht quadratisch, 
+           d.h. ROWS m <> COLUMNS m 
+           OP INV : singular matrix 
+           Die Matrix ist singulär. 
+ 
+ 
+'ROWS' 
+   #on("b")#INT OP ROWS (MATRIX CONST m) #off("b")# 
+   Liefert die Anzahl der Zeilen von 'm'. Beispiel: 
+ 
+ 
+           MATRIX VAR a :: matrix (3, 4), 
+                      b :: matrix (7, 10); 
+                ... 
+           put (ROWS a); (* 3 *) 
+           put (ROWS b); (* 7 *) 
+ 
+ 
+ 
+'TRANSP' 
+   #on("b")#MATRIX OP TRANSP (MATRIX CONST m) #off("b")# 
+   Liefert als Ergebnis die transponierte Matrix 'm'. 
+ 
+#page# 
+'get' 
+   #on("b")#PROC get (MATRIX VAR m, INT CONST rows, columns) #off("b")# 
+   Einlesen von Werten für die Matrix 'm' vom Terminal mit 'rows'-Zeilen und
+   'columns'-Spalten. 
+ 
+ 
+'put' 
+   #on("b")#PROC put (MATRIX CONST m) #off("b")# 
+   Ausgabe der Werte einer Matrix auf dem Terminal. 
+#page# 
+'column' 
+   #on("b")#VECTOR PROC column (MATRIX CONST m, INT CONST i) #off("b")# 
+   Die 'i'-te Spalte von 'm' wird als VECTOR mit 'ROWS m' Elementen geliefert.
+   Beispiel: 
+ 
+ 
+           MATRIX CONST a :: matrix (3, 4); 
+           VECTOR VAR b   :: column (a, 1); 
+           (* 'b' hat drei Elemente mit den Werten '0.0' *) 
+ 
+   FEHLER: 
+           PROC column : subscript overflow 
+           Der Index 'i' liegt außerhalb der Matrix 'm' (i > COLUMNS m). 
+           PROC column : subscript underflow 
+           Der Index 'i' liegt außerhalb der Matrix 'm' (i < 1). 
+ 
+'idn' 
+   #on("b")#INITMATRIX PROC idn (INT CONST size) #off("b")# 
+   Erzeugen einer Einheitsmatrix vom Datentyp INITMATRIX. Beispiel: 
+ 
+ 
+           MATRIX VAR a :: idn (10); 
+           (* Erzeugt eine Matrix mit 10 x 10 Elementen, deren
+            Werte '0.0' sind, mit der Ausnahme der Diagonalele­
+            mente, die den Wert '1.0' haben.*) 
+ 
+   FEHLER : 
+           PROC idn : size <= 0 
+           Die angeforderte 'size' Anzahl Spalten oder Zeilen muß > 0 sein. 
+ 
+ 
+'matrix' 
+   #on("b")#INITMATRIX PROC matrix (INT CONST rows, columns) #off("b")# 
+   Erzeugen eines Datenobjekts vom Datentyp INITMATRIX mit 'rows' Zeilen und
+   'columns' Spalten. Alle Elemente werden mit dem Wert '0.0' initialisiert. Beispiel: 
+ 
+ 
+           MATRIX CONST :: matrix (3, 3); 
+ 
+   FEHLER: 
+           PROC matrix : rows <= 0 
+           Die angeforderte Zeilenanzahl 'rows' muß > 0 sein. 
+           PROC matrix : columns <= 0 
+           Die angeforderte Spaltenanzahl 'columns' muß > 0 sein. 
+ 
+   #on("b")#INITMATRIX PROC matrix (INT CONST rows, columns, REAL CONST value)#off("b")# 
+   Erzeugen eines Datenobjekts vom Datentyp MATRIX mit 'rows' Zeilen und 'co­
+   lumns' Spalten. Alle Elemente der erzeugten MATRIX werden mit dem Wert
+   'value' initialisiert. Beispiel: 
+ 
+ 
+           MATRIX CONST :: matrix (3, 3, 3.14); 
+ 
+   FEHLER: 
+           PROC matrix : rows <= 0 
+           Die angeforderte Zeilenanzahl 'rows' muß > 0 sein. 
+           PROC matrix : columns <= 0 
+           Die angeforderte Spaltenanzahl 'columns' muß > 0 sein. 
+ 
+ 
+'row' 
+   #on("b")#VECTOR PROC row (MATRIX CONST m, INT CONST i) #off("b")# 
+   Die 'i'-te Reihe von 'm' wird als VECTOR mit 'COLUMNS m' Elementen gelie­
+   fert. Beispiel: 
+ 
+ 
+           MATRIX CONST a :: matrix (3, 4); 
+           VECTOR VAR b   :: row (a, 1); 
+           (* 'b' hat vier Elemente mit den Werten '0.0'*) 
+ 
+   FEHLER: 
+           PROC row : subscript overflow 
+           Der Index 'i' liegt außerhalb der Matrix 'm' (i > ROWS m). 
+           PROC row : subscript underflow 
+           Der Index 'i' liegt außerhalb der Matrix 'm' (i < 1). 
+ 
+ 
+'sub' 
+   #on("b")#REAL PROC sub (MATRIX CONST m, INT CONST row, column) #off("b")# 
+   Liefert den Wert eines Elementes von 'm', welches durch die Indizes 'row' und
+   'column' bestimmt wird. Beispiel: 
+ 
+ 
+           MATRIX VAR m :: matrix (5, 10, 1.0); 
+           put (sub (m, 3, 7)); 
+ 
+   FEHLER: 
+           PROC sub : row subscript overflow 
+           Der Index 'row' liegt außerhalb von 'm' (row > ROWS m). 
+           PROC sub : row subscript underflow 
+           Der Index 'row' liegt außerhalb von 'm' (row < 1). 
+           PROC sub : column subscript overflow 
+           Der Index 'column' liegt außerhalb von 'm' (column > ROWS m). 
+           PROC sub : row subscript underflow 
+           Der Index 'column' liegt außerhalb von 'm' (column < 1). 
+ 
+ 
+'transp' 
+   #on("b")#PROC transp (MATRIX VAR m) #off("b")# 
+   Transponieren der Matrix 'm', wobei kaum zusätzlicher Speicherplatz benötigt
+   wird. 
+ 
+#page# 
+'replace column' 
+   #on("b")#PROC replace column (MATRIX VAR m, INT CONST column index, VECTOR
+                        CONST column value)  #off("b")# 
+   Ersetzung der durch 'column index' definierten Spalte in der MATRIX 'm' durch
+   den VECTOR 'column value'. Beispiel: 
+ 
+ 
+           MATRIX VAR a :: matrix (3, 5, 1.0); 
+           VECTOR VAR b :: vector (3, 2.0); 
+                 ... 
+           replace column (a, 2, b); 
+           (* Die zweite Spalte von 'a' wird durch die Werte von
+              'b' ersetzt *) 
+ 
+   FEHLER: 
+           PROC replace column : LENGTH columnvalue <> ROWS m 
+           Die Anzahl der Zeilen der MATRIX 'm' stimmt nicht mit der Anzahl der
+           Elemente von 'columnvalue' überein. 
+           PROC replace column : column subscript overflow 
+           Der Index 'columnindex' liegt außerhalb von 'm' 
+           (columnindex > COLUMNS m). 
+           PROC sub : column subscript underflow 
+           Der Index 'columnindex' liegt außerhalb von 'm' (columnindex < 1). 
+ 
+ 
+'replace element' 
+   #on("b")#PROC replace element (MATRIX VAR m , INT CONST row, column, 
+                        REAL CONST value) #off("b")# 
+   Ersetzung eines Elementes von 'm' in der 'row'-ten Zeile und 'column'-ten
+   Spalte durch den Wert 'value'. Beispiel: 
+ 
+ 
+           MATRIX VAR a :: matrix (5, 5); 
+                 ... 
+           replace element (1, 1, 3.14159); 
+ 
+   FEHLER: 
+           PROC replace element : row subscript overflow 
+           Der Index 'row' liegt außerhalb von 'm' (row > ROWS m). 
+           PROC replace element : row subscript underflow 
+           Der Index 'row' liegt außerhalb von 'm' (row < 1). 
+           PROC replace element : column subscript overflow 
+           Der Index 'column' liegt außerhalb von 'm' (column > COLUMNS m). 
+           PROC replace element : row subscript underflow 
+           Der Index 'column' liegt außerhalb von 'm' (column < 1). 
+ 
+ 
+'replace row' 
+   #on("b")#PROC replace row (MATRIX VAR m, INT CONST rowindex, 
+                    VECTOR CONST rowvalue) #off("b")# 
+   Ersetzung der Reihe 'rowindex' in der MATRIX 'm' durch den VECTOR 'rowvalue'.
+   Beispiel: 
+ 
+ 
+           MATRIX VAR a :: matrix (3, 5, 1.0); 
+           VECTOR VAR b :: vector (5, 2.0); 
+                 ... 
+           replace row (a, 2, b); 
+           (* Die 2. Reihe von 'a' wird durch Werte von 'b'ersetzt *) 
+ 
+   FEHLER: 
+           PROC replace row : LENGTH rowvalue <> COLUMNS m 
+           Die Anzahl der Spalten der MATRIX 'm' stimmt nicht mit der Anzahl der
+           Elemente von 'rowvalue' überein. 
+           PROC replace row : row subscript overflow 
+           Der Index 'rowindex' liegt außerhalb von 'm' 
+           (rowindex > ROWS m). 
+           PROC sub : row subscript underflow 
+           Der Index 'rowindex' liegt außerhalb von 'm' (rowindex < 1). 
+
+6.2  Programmanalyse 
+ 
+Das Packet 'reporter' ermöglicht: 
+ 
+a) Ablaufinformationen ("trace"); 
+b) #ib#Häufigkeitszählung#ie# ("frequency count"); 
+c) Programmunterbrechung bei Nichterfüllung einer Bedingung ("#ib#assertion#ie#"). 
+ 
+ 
+'Installation' 
+Das Programm befindet sich in der Datei 'reporter' und kann wie üblich insertiert
+werden. Jedoch muß es mit 'check off' übersetzt werden, damit keine Zeilennummern
+für 'reporter' generiert werden. Dies ist notwendig, damit die Zeilennummern des zu
+testenden Programms nicht mit den Zeilennummern des Programms 'reporter' ver­
+wechselt werden können. Beispiel: 
+ 
+ 
+     check off; insert ("reporter"); check on 
+ 
+ 
+Mit dem Kommando 
+ 
+ 
+     #ib#generate reports#ie# ("testdatei") 
+ 
+ 
+werden die oben erwähnten Prozeduraufrufe ('#ib#report#ie#') in das zu testende Programm,
+welches in der Datei 'testdatei' steht, geschrieben. Die Prozeduraufrufe werden nach
+jedem Prozedur-, Operator- oder Refinement-Kopf eingefügt und erhalten den
+entsprechenden Namen als Parameter. Diese Prozeduraufrufe werden gekennzeichnet,
+damit sie von der Prozedur 
+ 
+ 
+     eliminate reports ("testdatei") 
+ 
+ 
+automatisch wieder entfernt werden können. Beispiel (für die eingefügten Prozedurauf­
+rufe): 
+ 
+ 
+    ... 
+    PROC beispiel (INT CONST mist): 
+    \#\#report ("PROC beispiel");\#\# 
+    ... 
+ 
+ 
+ 
+'Automatische Ablaufinformation' 
+Ist ein Programm mit 'generate reports' mit 'report'-Aufrufen versehen worden, kann
+es wie gewohnt übersetzt werden. Wird das Programm vom ELAN-Compiler kor­
+rekt übersetzt und dann gestartet, wird bei jedem Antreffen eines 'report'-Aufrufs der
+Parameter (Name der Prozedur, Operator oder Refinement) in eine Datei, die
+TRACE-Datei geschrieben. Die TRACE-Datei wird beim Programmlauf automatisch
+von 'reporter' unter dem Namen 'TRACE' eingerichtet. 
+ 
+Mit Hilfe dieser Datei kann der Programmablauf verfolgt werden. Es ist damit auch
+möglich festzustellen, wo eine "Endlos-Rekursion" auftritt. Die Ablaufinformationen
+bestehen nur aus den Namen der angetroffenen Prozeduren und Refinements. Trotz­
+dem können die Anzahl der Informationen sehr umfangreich werden. Deshalb gibt es
+die Möglichkeit, die Erzeugung der Ablaufinformationen ab- bzw. wieder anzuschal­
+ten. Dazu gibt es die Möglichkeit, in das zu testende Programm die Prozeduren 
+ 
+ 
+     #ib#report on#ie# 
+     #ib#report off#ie# 
+ 
+ 
+einzufügen und das zu testende Programm mit diesen Prozeduraufrufen (erneut) zu
+übersetzen. 
+ 
+ 
+'Benutzereigene Ablaufinformation' 
+Zusätzlich zu den von 'generate reports' eingefügten 'report'-Aufrufen kann ein
+Benutzer eigene Aufrufe an geeigneten Stellen in ein Programm schreiben. Dafür
+werden weitere 'report'-Prozeduren zur Verfügung gestellt, die als ersten Parameter
+ein TEXT-Objekt (meist Name des Objekts oder der Ausdruck selbst) und als zwei­
+ten ein INT/REAL/TEXT/ BOOL-Objekt (der zu überprüfende Wert oder Ausdruck)
+enthalten. Beispiel: 
+ 
+ 
+    ... 
+    PROC beispiel (INT CONST mist): 
+    \#\#report ("beispiel");\#\#     (* automatisch eingefuegte *) 
+    INT VAR mist :: ...; ... 
+    \#\#report ("mist:", mist);\#\#  (* vom Benutzer per Hand einge­
+                                    fuegt *) 
+    ... 
+ 
+ 
+Folgende 'report'-Routinen stehen zur Verfügung, damit man sie "von Hand" in ein
+zu testendes Programm einfügen kann: 
+ 
+ 
+     PROC report on 
+     PROC report off 
+     PROC report (TEXT CONST message) 
+     PROC report (TEXT CONST message,  INT CONST value) 
+     PROC report (TEXT CONST message, REAL CONST value) 
+     PROC report (TEXT CONST message, TEXT CONST value) 
+     PROC report (TEXT CONST message, BOOL CONST value) 
+ 
+ 
+Wichtig: Hier - wie bei allen anderen "von Hand eingefügten" Aufrufen - sollte
+ein Nutzer sich an die Konvention halten, diese in "\#\#" einzuklammern. Mit 'eliminate
+reports' werden diese Einfügungen automatisch entfernt. Sollen diese Aufrufe aber
+immer im Programm erhalten bleiben (jedoch nicht wirksam sein), sollten sie 
+ 
+a) vor 'generate reports'-Aufruf mit jeweils '\#\#\#' eingefaßt werden. Beispiel: 
+   \#\#\# report ("...") \#\#\# 
+   So steht das 'report'-Statement in einem Kommentar. 'generate reports' wandelt
+   '\#\#\#' --> '\#\#\#\#' um, so daß ein solches Statement wirksam wird. 'eliminate
+   reports' wandelt ein '\#\#\#\#' --> '\#\#\#' zurück. 
+ 
+b) nach 'generate reports' in '\#\#\#\#' eingefaßt werden. 
+ 
+ 
+'Häufigkeitszählung' 
+Eine Häufigkeitszählung erhält man, in dem man in das zu testende Programm die
+Aufrufe 
+ 
+ 
+     count on 
+     count off 
+ 
+ 
+einfügt. Ist die Häufigkeitszählung eingeschaltet, merkt sich 'reporter' die Anzahl der
+Durchläufe für jede Prozedur bzw. Refinement. Mit der Prozedur 
+ 
+ 
+     #ib#generate counts#ie# ("zu testende datei") 
+ 
+ 
+werden die vermerkten Häufigkeiten in das zu testende Programm direkt eingefügt.
+Die Häufigkeiten werden wie oben beschrieben gekennzeichnet, so daß sie mit 'elimi­
+nate reports' entfernt werden können. 
+ 
+ 
+'Assertions' 
+Zusätzlich zu den oben erwähnten Möglichkeiten bietet 'reporter' noch die Prozedur 
+ 
+ 
+     #ib#assert#ie# 
+ 
+ 
+an. Diese Prozedur kann von einem Programmierer an einer Stelle in das zu testende
+Programm eingefügt werden, an der bestimmte Bedingungen erfüllt sein müssen. Die
+Prozedur 'assert' steht in zwei Formen zur Verfügung: 
+ 
+ 
+     PROC #ib#assert#ie# (BOOL CONST zusicherung) 
+     PROC assert (TEXT CONST message, BOOL CONST zusicherung) 
+ 
+ 
+Ist der Wert von 'zusicherung' nicht TRUE, wird der Programmlauf abgebrochen. 
+ 
+ 
+ 
+reporter - Kommandos 
+ 
+ 
+'count on' 
+   #on("b")#PROC count on #off("b")# 
+   Schaltet die Häufigkeitszählung ein. 
+ 
+'count off' 
+   #on("b")#PROC count off #off("b")# 
+   Schaltet die Häufigkeitszählung aus. 
+ 
+'eliminate reports' 
+   #on("b")#PROC eliminate reports (TEXT CONST datei) #off("b")# 
+   Entfernt gekennzeichnete 'report'-Aufrufe aus der Datei 'datei'. 
+ 
+'generate reports' 
+   #on("b")#PROC generate reports (TEXT CONST datei) #off("b")# 
+   Fügt 'report'-Aufrufe in die Datei 'datei' ein und kennzeichnet diese mit '\#\#'. 
+ 
+'report on' 
+   #on("b")#PROC report on #off("b")# 
+   Schaltet die Ablaufinformationen in die Datei 'TRACE' ein. 
+ 
+'report off' 
+   #on("b")#PROC report off #off("b")# 
+   Schaltet die Ablaufinformationen wieder aus. 
+ 
+'generate counts' 
+   #on("b")#PROC generate counts (TEXT CONST datei) #off("b")# 
+   Bringt die Häufigkeitszählung (wie oft eine Prozedur oder Refinement durchlaufen
+   wurde) in die Programmdatei 'datei'. Mit 'eliminate reports' werden diese wieder
+   automatisch entfernt. 
+ 
+'assert' 
+   #on("b")#PROC assert (TEXT CONST message, BOOL CONST value) #off("b")# 
+   Schreibt 'message' und den Wert von 'value' in die TRACE-Datei. Ist 'value'
+   FALSE, wird angefragt, ob das Programm fortgesetzt werden soll. 
+#page# 
+
+Referencer 
+ 
+ 
+'referencer' wird durch 
+ 
+ 
+     referencer ("ref datei", "referenz liste") 
+ 
+ 
+aufgerufen, wobei die Datei 'referenz liste' nicht existieren darf. 'referenz liste' enthält
+nach Ablauf des Programms die gewünschte Liste, die sogenannte #ib# Referenzliste#ie#. 
+ 
+#ub#Achtung#ue#: 'referencer' arbeitet ausschließlich mit Namen und verarbeitet nur wenige
+syntaktische Konstrukte. Darum ist es nur erlaubt, ein PACKET auf einmal von 'refe­
+rencer' verarbeiten zu lassen. Verarbeitet man mehrere PACKETs auf einmal, kann es
+geschehen, daß gleichnamige Objekte in unterschiedlichen Paketen zu Warnungen
+(vergl. die unten beschriebenen Überprüfungen) führen. 
+ 
+In der Referenzliste sind 
+ 
+- alle Objekte mit ihrem Namen (in der Reihenfolge ihres Auftretens im Programm) 
+ 
+- alle Zeilennummern, in der das Objekt angesprochen wird 
+ 
+- die Zeilennummern, in der das Objekt deklariert wurde ('L' für ein lokales und 'G'
+  für ein globales Objekt, 'R' für ein Refinement) 
+ 
+verzeichnet. 
+ 
+Die Referenzliste kann u.a. dazu dienen, zu kontrollieren, ob und wie (bzw. wo) ein
+Objekt angesprochen wird. Dies lohnt sich selbstverständlich nur bei etwas umfan­
+greicheren Programmen (bei "Mini"-Programmen kann man dies sofort sehen). 
+ 
+Bei der Erstellung der Referenzliste nimmt das Programm 'referencer' gleichzeitig
+einige Überprüfungen vor, die helfen können, ein Programm zu verbessern: 
+ 
+1. Warnung bei mehrzeiligen Kommentaren. 
+ 
+2. Überdeckungsfehler. Wird ein Objekt global (auf PACKET-Ebene) und nochmals
+   lokal in einer Prozedur deklariert, ist das globale Objekt nicht mehr ansprechbar.
+   Überdeckungen sind nach der gültigen Sprachdefinition z.Zt. noch erlaubt, werden
+   aber bei einer Revision des Sprachstandards verboten sein. 
+ 
+3. Mehrmaliges Einsetzen von Refinements. Wird ein Refinement mehrmals einge­
+   setzt (das ist völlig legal), sollte man überlegen, ob sich dieses Refinement nicht
+   zu einer Prozedur umgestalten läßt. 
+ 
+4. Nicht angewandte Refinements. Wird ein Refinement zwar deklariert, aber nicht
+   "aufgerufen", erfolgt eine Warnung. 
+ 
+5. Nicht angesprochene Daten-Objekte. Werden Daten-Objekte zwar deklariert,
+   aber im folgenden nicht angesprochen, wird eine Warnung ausgegeben. Hinweis:
+   Alle Objekte, die nur wenig angesprochen werden, also nur wenige Zeilennum­
+   mern in der Referenzliste besitzen, sind verdächtig (Ausnahmen: importierte
+   Prozeduren, LET-Objekte u.a.m.). 
+ 
+ 
+
+referencer - Kommandos
+ 
+ 
+'referencer' 
+   #on("b")#PROC referencer (TEXT CONST check file, dump file) #off("b")# 
+   Überprüft 'check file'. In 'dump file' steht nach Abschluß die Referenzliste. 
+ 
+#page# 
+
+6.3  Rechnen im Editor 
+ 
+Das Programm TeCal ermöglicht einfache Rechnungen (ähnlich wie mit einem Ta­
+schenrechner) unter der Benutzung des Editors. Gleichzeitig stehen dem Benutzer
+aber alle Fähigkeiten des Editors zur Verfügung. TeCal ermöglicht Rechnungen auf
+einfache Weise zu erstellen oder Tabellenspalten zu berechnen. Zur Benutzung 
+müssen 'TeCal' und 'TeCal Auskunft' insertiert werden. 
+ 
+TeCal wird aus dem Editor heraus durch 'ESC t' oder durch das Editor-Kommando 
+ 
+ 
+           tecal 
+ 
+ 
+aktiviert. Dadurch wird in der untersten Zeile des Bildschirms eine Informationszeile
+aufgebaut, in der die (Zwischen-) Ergebnisse einer Rechnung zur Kontrolle fest­
+gehalten werden. 
+ 
+ 
+ 
+Arbeitsweise 
+ 
+ 
+Wenn TeCal insertiert ist, kann die Taschenrechnerfunktion jederzeit durch <ESC> <t>
+aufgerufen werden. Aus der editierten Datei werden Werte mit <ESC> <L> gelesen,
+durch <ESC> <+> (bzw. -,*,/) verknüpft und mit <ESC> <S> an die aktuelle Cursor­
+position geschrieben werden. 
+ 
+Der von TeCal errechnete Wert wird durch <ESC> <S> derart ausgegeben, daß an der
+Stelle an der der Cursor steht die letzte Stelle vor dem Dezimalpunkt geschrieben
+wird. 
+ 
+Die Eingabe von Klammern geschieht durch <ESC> <(> <ESC> <)>. 
+ 
+Durch die Hilfsfunktion <ESC> <?> lassen sich die TeCal Funktionen auflisten. 
+ 
+Der Prozentoperator <ESC> <%> erlaubt einfache Rechnungen der Form: 'zahl' <ESC> <+>
+<ESC> <%> <ESC> <=> . 
+ 
+Derartige Folgen können natürlich mit der bekannten Editor-Lernfunktion auch ge­
+lernt werden, so daß sich z.B. die Mehrwertsteuerberechnung auf wenige Tasten 
+reduziert. 
+ 
+Spalten können summiert werden, indem auf der #on("u")#untersten#off("u")# Zahl einer Spalte <ESC> <V>
+eingegeben wird. Daraufhin werden alle darüberliegende Zahlen addiert, bis ein
+Zeichen auftritt, das nicht in einer Zahl auftritt (Leerzeichen stören nicht!). 
+ 
+____________________________________________________________________________ 
+         ............ 
+               55.00 
+               66.99 
+              123.45 
+ 
+               99.99 
+ 
+             9876.54 
+         ........... 
+ 
+ Anzeige:            0.00  14.00%  Memory:       0.00 
+ 
+____________________________________________________________________________ 
+ 
+ 
+TeCal Prozeduren 
+ 
+ 
+'evaluate' 
+   #on("b")#evaluate (TEXT CONST zeile, INT CONST von) #off("b")# 
+   Ausdruck 'zeile' ab der Stelle 'von' berechnen. 
+ 
+   #on("b")#evaluate (TEXT CONST zeile) #off("b")# 
+   Ausdruck 'zeile' ab Stelle 1 berechnen. 
+ 
+ 
+'kommastellen' 
+   #on("b")#kommastellen (INT CONST stellen) #off("b")# 
+   Berechnungen auf 'stellen' Zahlen hinter dem Komma einstellen. 
+ 
+ 
+'merke' 
+   #on("b")#PROC merke (INT CONST zahl)#off("b")# 
+   Integer 'zahl' im Merkregister abspeichern. 
+ 
+   #on("b")#PROC merke (REAL CONST zahl)#off("b")# 
+   Real 'zahl' im Merkregister abspeichern. 
+ 
+'prozentsatz' 
+   #on("b")#PROC prozentsatz (INT CONST zahl) #off("b")# 
+   Prozentsatz von 'zahl' Prozent einstellen. Der Wert wird automatisch konvertiert. 
+ 
+   #on("b")#PROC prozentsatz (REAL CONST zahl) #off("b")# 
+   Prozentsatz von 'zahl' Prozent einstellen. 
+ 
+ 
+'tecal' 
+   #on("b")#PROC tecal (FILE VAR f) #off("b")# 
+   Datei 'f', die mit 'sequential file' assoziiert ist, mit TeCal editieren. 
+ 
+   #on("b")#PROC tecal (TEXT VAR datei) #off("b")# 
+   'datei' mit TeCal editieren. 
+ 
+   #on("b")#PROC tecal #off("b")# 
+   Zuletzt editierte Datei mit TeCal editieren. 
+ 
+ 
+'tecalauskunft' 
+   #on("b")#PROC tecalauskunft #off("b")# 
+   Auskunft zeigen. 
+ 
+   #on("b")#PROC tecalauskunft (TEXT CONST zeichen) #off("b")# 
+   Auskunft zu 'zeichen' zeigen. 
+
diff --git a/doc/programming/programmierhandbuch.index b/doc/programming/programmierhandbuch.index
new file mode 100644
index 0000000..f3f4ede
--- /dev/null
+++ b/doc/programming/programmierhandbuch.index
@@ -0,0 +1,449 @@
+#pagenr("%",1)##block##pageblock# 
+#headandbottom("1","EUMEL-Benutzerhandbuch","INDEX","Index")# 
+#headeven# 
+#center#EUMEL-Benutzerhandbuch 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#INDEX 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+#center#____________________________________________________________ 
+Index - % #right#GMD 
+#end# 
+#bottomodd# 
+#center#____________________________________________________________ 
+GMD #right#Index - % 
+#end# 
+#lpos(0.2)##lpos(6.2)# 
+ 
+INDEX  
+ 
+#table# 
+*              5-11, 5-18, 5-32, 6-19, 6-27, 6-4, 6-9 
+**           5-11, 5-19, 5-60, 6-10 
++        4-20, 5-11, 5-18, 5-32, 5-54, 6-18, 6-26, 6-3, 6-9 
+-        4-20, 5-11, 5-18, 5-54, 6-18, 6-26, 6-3, 6-9 
+/        4-20, 4-22, 5-18, 6-19, 6-4 
+:=       2-91, 5-10, 5-17, 5-30, 5-65, 6-17, 6-25, 6-3, 6-8 
+<        5-10, 5-17, 5-30, 6-8 
+<=       5-10, 5-17, 5-30, 6-8 
+<>       5-10, 5-17, 5-30, 6-18, 6-26, 6-3, 6-8 
+=        5-10, 5-17, 5-30, 6-17, 6-25, 6-3, 6-8 
+>        5-10, 5-17, 5-30, 6-9 
+>=       5-10, 5-17, 5-30, 6-9 
+ 
+Abfragekette                                      2-25 
+ABS             6-10, 6-6 
+abs                                               5-13, 5-20, 6-13 
+Abweisende Schleife                               2-29 
+ALL                                               4-17 
+all                                               4-17 
+AND                                               5-7 
+any                                               5-54 
+Archiv                                            4-44 
+Archivdiskette                                    4-47 
+archive                                           1-9, 4-24, 4-45 
+arctan                                            5-20 
+arctand                                           5-20 
+assert                                            6-39 
+assertion                                         6-36 
+Assertions                                        6-39 
+Ausgabesteuerzeichen                     5-70 
+Ausschalten des Geräts                            1-17 
+Automatische Ablaufinformation                    6-37 
+ 
+begin                                             2-78, 4-3 
+begin password                                    4-40 
+Benutzereigene Ablaufinformation                  6-37 
+BOOL-Denoter:                                     2-9 
+BOUND                                             2-83 
+bound                                             5-56 
+break                                             4-4 
+brother                                           4-23 
+bulletin                                          4-8 
+ 
+CAND                                              5-7 
+CAT                                               5-32 
+change                                            5-33 
+change                                            5-61 
+change all                                        5-33 
+check                                             4-49, 5-4 
+clear                                             4-46 
+clear removed                                     5-51 
+clock                                             5-80 
+code                                              5-34 
+col                                               5-48 
+column                                            6-31 
+COLUMNS                                           6-28 
+COMPILER ERROR                                    5-5 
+complex                                           6-5 
+complex i                                         6-5 
+complex one                                       6-5 
+complex zero                                      6-5 
+compress                                          5-34 
+configurator                                      1-9 
+CONJ                                              6-6 
+Container                                         5-26 
+continue                                          4-3 
+continue scan                                     5-83 
+copy                                              4-26, 5-67 
+COR                                               5-7 
+cos                                               5-20 
+cosd                                              5-20 
+count off                                         6-39 
+count on                                          6-39 
+cout                                              5-75 
+cursor                                            5-71 
+ 
+dataspaces                                        5-66 
+date                                              5-81 
+Datenraum                                         1-3 
+Datensicherheit                                   1-8 
+day                                               5-81 
+decimal exponent                                  5-20 
+DECR                                              5-12, 5-19, 6-10 
+delete char                                       5-34 
+delete record                                     5-50 
+Der EUMEL-Zeichensatz                             5-29 
+Der Lernmodus                                     3-17 
+DET                                               6-28 
+DIRFILE                                          2-73 
+DIV                                               5-12, 6-11 
+do                                                5-2 
+down                                              5-48, 5-57 
+downety                                           5-57 
+dphi                                              6-6 
+ds pages                                          5-66 
+ 
+e                                                 5-21 
+edit                                              3-1, 4-29, 5-62 
+editget                                           4-30, 5-63, 5-72 
+editor                                            1-9 
+Editor verlassen                                  3-2 
+Ein- bzw. Ausschalten der Markierung              3-9 
+Ein- bzw. Ausschalten des Einfügemodus            3-10 
+Einfügen von Textpassagen                         3-6 
+Eingabesteuerzeichen                     5-69 
+Eingabetaste / Absatztaste                        3-4 
+eliminate reports                                 6-39 
+Endlosschleife                                    2-28 
+enter password                                    4-41 
+eof                                               5-43 
+erase                                             4-37 
+Erweiterbarkeit                                   1-6 
+ 
+ESC )                                             3-16 
+ESC (                                             3-16 
+ESC >                                             3-16 
+ESC <                                             3-16 
+ESC 9                                             3-14 
+ESC 1                                             3-14 
+ESC a                                             3-16 
+ESC A                                             3-16 
+ESC b                                             3-14 
+ESC blank                                         3-16 
+ESC d                                             3-15 
+ESC e                                             3-14 
+ESC ESC                                           3-16 
+ESC f                                             3-14 
+ESC g                                             3-15 
+ESC HOP                                           3-17 
+ESC HOP HOP                                       3-17 
+ESC HOP taste                                     3-17 
+ESC k                                             3-16 
+ESC n                                             3-14 
+ESC O                                             3-16 
+ESC o                                             3-16 
+ESC p                                             3-15 
+ESC q                                             3-14 
+ESC RUBIN                                         3-15 
+ESC RUBOUT                                        3-15 
+ESC s                                             3-16 
+ESC ? taste                                       3-16 
+ESC ! taste                                       3-16 
+ESC U                                             3-16 
+ESC u                                             3-16 
+ESC v                                             3-14 
+ESC w                                             3-14 
+ESC k                                             3-16 
+ESC ­                                             3-16 
+ 
+EUMEL-Editor                                      3-1 
+evaluate                                          6-44 
+exp                                               5-21 
+ 
+false                                             5-7 
+family password                                   4-42 
+father                                            4-23 
+Fehlermeldungen des Archivs                       4-52 
+fetch                                             4-33, 5-67 
+fetchall                                          4-34 
+FILE                                             2-73 
+Fixpunkt                                          1-8 
+floor                                             5-21 
+forget                                            4-26, 4-47, 5-67 
+frac                                              5-21 
+ 
+Garbage Collection                                5-26 
+Gelerntes vergessen                               3-17 
+generate counts                                   6-40 
+generate reports                                  6-40 
+get               2-80, 5-44, 5-73, 6-5, 6-12, 6-21, 6-30 
+getchar                                           5-72 
+get cursor                                        5-71 
+getline                                           5-45, 5-74 
+ 
+Häufige Fehler bei der Benutzung von Datenräumen    2-85 
+Häufigkeitszählung                                6-36 
+halt                                              4-4 
+headline                                          5-43 
+heap size                                         5-27 
+help                                              4-5, 4-9 
+hour                                              5-81 
+ 
+idn                                               6-31 
+imag part                                         6-6 
+inchar                                            5-72 
+incharety                                         5-72 
+INCR                                              5-12, 5-19, 6-11 
+INITFLAG                                          2-91 
+initialized                                       2-91 
+initialize random                                 5-13, 5-21 
+input                                          2-75, 5-42 
+insert                                            5-2 
+insert char                                       5-35 
+insert record                                     5-50 
+Installation                                      6-36 
+int                                               5-21 
+int                                               6-13 
+INT-Denoter:                                      2-7 
+INV                                               6-28 
+ 
+Kommando                                          1-9 
+kommando auf taste                                4-31 
+kommando auf taste legen                          4-31 
+Kommando auf Taste legen                          3-16 
+Kommandotaste                                     3-11 
+kommastellen                                      6-44 
+Konfiguration                                     1-9 
+ 
+length                                            5-35, 6-22 
+LENGTH                                            5-35, 6-19 
+Lernen ausschalten                                3-17 
+Lernen einschalten                                3-17 
+lernsequenz auf taste                             4-32 
+lernsequenz auf taste legen                       4-32 
+Lese-Fehler (Archiv)                              4-52 
+LEXEQUAL                                          5-31 
+LEXGREATER                                        5-31 
+LEXGREATEREQUAL                                   5-31 
+lex sort                                          5-64 
+LIKE                                              4-19, 5-59 
+line                                              5-47, 5-71, 5-77 
+line no                                           5-43 
+lines                                             5-43 
+list                                              4-27 
+ln                                                5-22 
+Löschtaste                                        3-10 
+log10                                             5-22 
+log2                                              5-22 
+longint                                           6-13 
+ 
+manager task                                      1-9 
+Mantisse                                          5-16 
+Markierzustand                                    3-9 
+match                                             5-60 
+matchpos                                          5-60 
+matrix                                            6-32 
+max                    5-13, 5-22, 6-13 
+maxint                                            5-13 
+maxlongint                                        6-13 
+maxreal                                           5-22 
+max text length                                   5-35 
+merke                                             6-45 
+min                                               5-13, 5-23, 6-14 
+minint                                            5-14 
+MOD                                               5-14, 5-23, 6-11 
+modify                                           2-75, 5-42 
+Monitor                                           1-9 
+Multi-Tasking-/Multi-User-Betrieb                 1-5 
+myself                                            4-23 
+ 
+name                                              4-25 
+Namensverzeichnis                                 4-16 
+Netzwerkfähigkeit         1-6 
+new                                               5-65 
+next symbol                                       5-83 
+next symbol                                       5-85 
+Nicht abweisende Schleife                         2-29 
+nilspace                                          5-65 
+niltask                                           4-22 
+nilvector                                         6-22 
+norm                                              6-22 
+NOT                                               5-8 
+notion                                            5-56 
+ 
+old                                               5-66 
+online                                            5-79 
+Operationen auf Markierungen                      3-15 
+Operatoren                                        2-14 
+OR                                                5-8 
+OR                                                5-54 
+out                                               5-75 
+output                                            2-75, 5-42 
+out subtext                                       5-76 
+ 
+packets                                           4-8 
+page                                              5-71 
+Paketkonzept                                    2-1 
+pause                                             5-79, 5-82 
+phi                                               6-6 
+pi                                                5-23 
+pos                                               5-36 
+Positionierung                           5-71 
+Positionierung des Cursors                        3-4 
+print                                             4-38 
+PRINTER                                           4-24 
+printer                                           4-24 
+Priorität von generischen Operatoren              2-49 
+Priorität von Operatoren                          2-16 
+prot                                              5-4 
+Prozeduren als Parameter                          2-39 
+Prozeduren mit Parametern                         2-38 
+prozentsatz                                       6-45 
+Prozeßkommunikation         1-6 
+PUBLIC                                            4-24 
+public                                            4-24 
+put         5-46, 5-78, 6-12, 6-21, 6-30, 6-5 
+putline                                           5-46, 5-78 
+ 
+random                                            5-14, 5-23, 6-14 
+read record                                       5-50 
+real                                              5-14, 5-37 
+REAL-Denoter:                                     2-8 
+Realisierung von abstrakten Datentypen            2-47 
+real part                                         6-6 
+referencer                                        6-42 
+Referenzliste                                     6-41 
+Refinements                                       2-1 
+reinsert                                          5-51 
+release                                           4-45 
+remainder                                         4-18 
+remove                                            5-51 
+rename                                            4-28 
+rename myself                                     4-25 
+reorganize                                        5-52 
+replace                                           5-37, 6-22 
+replace column                                    6-34 
+replace element                                   6-34 
+replace row                                       6-35 
+report                                            6-36 
+report off                                        6-40 
+report on                                         6-40 
+reserve                                           4-25 
+REST                                              3-6 
+round                                             5-23 
+row                                               6-32 
+ROWS                                              6-29 
+run                                               5-3 
+runagain                                          5-3 
+ 
+save                                              4-35, 5-67 
+saveall                                           4-36 
+scan                                              5-86 
+Schreibarbeit beenden                             3-2 
+Schutz vor fehlerhaftem Zugriff auf Datenobjekte    2-45 
+Scratch-Datei                                   3-13 
+segments                                          5-52 
+sequential file                                   5-41 
+SHard                                             1-5 
+show                                              4-30 
+shutup                                            1-17 
+sign                                              5-15, 5-24, 6-14 
+SIGN                                              6-11 
+sin                                               5-24 
+sind                                              5-24 
+smallreal                                         5-24 
+SOME                                              2-80, 4-17 
+son                                               4-23 
+sort                                              5-64 
+Spracherweiterung                                 2-44 
+sqrt                                              5-24, 6-6 
+Standard-Datenraum                                1-9 
+std tastenbelegung                                4-32 
+STOP-Taste                                      3-20 
+storage                                           4-11, 5-66 
+storage info                                      4-5, 4-11 
+sub                                               6-33 
+SUB                                               5-37, 6-20 
+subtext                                           5-38 
+supervisor                                        4-24 
+Supervisor                                        1-9 
+SUPERVISOR-Taste                                  3-18 
+Symbole                                           5-83 
+sysin                                             5-73 
+sysout                                            5-77 
+ 
+Tabulatortaste                                    3-8 
+tan                                               5-25 
+tand                                              5-25 
+task                                              4-22 
+Task                                              1-9 
+task info                                         4-5, 4-12 
+Task-Organisation                                 1-2 
+task password                                     4-43 
+task status                                       4-15 
+taste enthaelt kommando                           4-31 
+tecal                                             6-45 
+tecalauskunft                                     6-45 
+text                                              5-15, 5-25, 5-39, 6-15 
+TEXT-Denoter:                                     2-9 
+Thesaurus                                         4-16 
+time                                              5-82 
+time of day                                       5-82 
+TIMESOUT                                          5-76 
+Titelzeile                                        3-2 
+to line                                           5-48 
+transp                                            6-33 
+TRANSP                                            6-29 
+true                                              5-8 
+type                                              5-66 
+TYPE COMPLEX                                      6-3 
+TYPE LONGINT                                      6-8 
+ 
+Überschrift in die Kopfzeile                   5-43 
+Umschalttaste                                     3-4 
+UNLIKE                                            5-59 
+Unterbrechen einer Ausgabe                        3-20 
+up                                                5-49 
+up                                                5-58 
+uppety                                            5-58 
+ 
+vector                                            6-23 
+Vereinbarung eines dyadischen Operators           2-42 
+Vereinbarung eines monadischen Operators          2-42 
+Verstärkertaste                                   3-5 
+Verwendung von Prozeduren                         2-35 
+Virtuelle Speicherverwaltung                      1-7 
+Vorbelegte Tasten                                 3-17 
+ 
+warnings                                          5-4 
+WEITER-Taste                                      3-20 
+Wertliefernde Prozeduren                          2-40 
+Wertliefernde Refinements                         2-34 
+word wrap                                         4-32 
+write                                             5-78 
+write                                             5-47 
+write record                                      5-50 
+ 
+XOR                                               5-8 
+ 
+Zählschleife                                      2-30 
+Zeichen schreiben                                 3-16 
+zero                                              6-15 
+#tableend# 
+
diff --git a/doc/programming/programmierhandbuch.inhalt b/doc/programming/programmierhandbuch.inhalt
new file mode 100644
index 0000000..45b3f1f
--- /dev/null
+++ b/doc/programming/programmierhandbuch.inhalt
@@ -0,0 +1,249 @@
+#setcount (1)# 
+#block##pageblock# 
+#pagenr ("%", 1)# 
+#headeven# 
+#center#EUMEL-Benutzerhandbuch 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#Inhalt 
+#center#____________________________________________________________ 
+ 
+#end# 
+#bottomeven# 
+ 
+#center#____________________________________________________________ 
+I - % #right#GMD 
+#end# 
+#bottomodd# 
+ 
+#center#____________________________________________________________ 
+GMD #right# I - % 
+#end# 
+ 
+#lpos(0.2)##lpos(1.8)##lpos(9.0)# 
+ 
+TEIL 1 : Einleitung 
+#table# 
+1.1  Allgemeines über EUMEL                         1 
+1.2  Struktur des Betriebssystems EUMEL             2 
+1.3  Eigenschaften des Betriebssystems              4 
+     Multi-Tasking-/Multi-User-Betrieb              5 
+     Prozeßkommunikation und Netzwerkfähigkeit      6 
+     Erweiterbarkeit                                6 
+     Virtuelle Speicherverwaltung                   7 
+     Datensicherheit                                8 
+1.4  Wichtige Begriffe                              9 
+1.5  Die Notation in diesem Buch                    10 
+1.6  Die Funktionstasten des EUMEL-Systems          11 
+1.7  Eine Beispielsitzung                           12 
+#tableend# 
+ 
+ 
+ 
+ 
+TEIL 2 : ELAN 
+#table# 
+2.1  Besondere Eigenschaften von ELAN               1 
+2.2  Lexikalische Elemente                          2 
+2.2.1  Schlüsselwörter                              2 
+2.2.2  Bezeichner                                   3 
+2.2.3  Sonderzeichen                                4 
+2.2.4  Kommentare                                   5 
+2.3  Datenobjekte                                   6 
+2.3.1   Elementare Datentypen                       6 
+2.3.1.1  Denoter für elementare Datentypen          7 
+     INT-Denoter:                                   7 
+     REAL-Denoter:                                  8 
+     TEXT-Denoter:                                  9 
+     BOOL-Denoter:                                  9 
+2.3.1.2  LET-Konstrukt für Denoter                  10 
+2.3.2   Zugriffsrecht                               11 
+2.3.3  Deklaration                                  11 
+2.3.4  Initialisierung                              12 
+2.4  Programmeinheiten                              13 
+2.4.1  Elementare Programmeinheiten                 14 
+2.4.1.1  Ausdruck                                   14 
+     Operatoren                                     14 
+     Priorität von Operatoren                       16 
+2.4.1.2  Zuweisung                                  18 
+2.4.1.3  Refinementanwendung                        19 
+2.4.1.4  Prozeduraufruf                             20 
+2.4.2  Zusammengesetzte Programmeinheiten           22 
+2.4.2.1  Folge                                      22 
+2.4.2.2  Abfrage                                    23 
+2.4.2.3  Auswahl                                    26 
+2.4.2.4  Wertliefernde Abfrage                       
+         und wertliefernde Auswahl                  27 
+2.4.2.5  Wiederholung                               27 
+     Abfragekette                                   25 
+     Endlosschleife                                 28 
+     Abweisende Schleife                            29 
+     Nicht abweisende Schleife                      29 
+     Zählschleife                                   30 
+2.4.3  Abstrahierende Programmeinheiten             32 
+2.4.3.1  Refinementvereinbarung                     32 
+     Vorteile der Refinementanwendung               33 
+     Wertliefernde Refinements                      34 
+2.4.3.2  Prozedurvereinbarung                       35 
+2.4.3.3  Operatorvereinbarung                       41 
+     Verwendung von Prozeduren                      35 
+     Prozeduren mit Parametern                      38 
+     Prozeduren als Parameter                       39 
+     Wertliefernde Prozeduren                       40 
+     Vereinbarung eines monadischen Operators       42 
+     Vereinbarung eines dyadischen Operators        42 
+2.4.3.4  Paketvereinbarung                          43 
+     Spracherweiterung                              44 
+     Schutz vor fehlerhaftem Zugriff                
+     auf Datenobjekte                           45 
+     Realisierung von abstrakten Datentypen         47 
+2.4.4  Terminatoren für Refinements,             
+       Prozeduren und Operatoren                    48 
+2.4.5  Generizität von Prozeduren und Operatoren      49 
+     Priorität von generischen Operatoren           49 
+2.4.6   Rekursive Prozeduren und Operatoren        50 
+2.5     Programmstruktur                            52 
+2.6  Zusammengesetzte Datentypen                    56 
+2.6.1  Reihung                                      56 
+2.6.2  Struktur                                     61 
+2.6.3  LET-Konstrukt für                        
+       zusammengesetzte Datentypen      64 
+2.6.4  Denoter für zusammengesetzte     
+       Datentypen (Konstruktor)      65 
+2.7  Abstrakte Datentypen                           67 
+2.7.1  Definition neuer Datentypen                  67 
+2.7.2  Konkretisierung                              69 
+2.7.3  Denoter für abstrakte Datentypen (Konstruktor)      70 
+2.8  Dateien                                        73 
+2.8.1  Datentypen FILE und DIRFILE                  73 
+     FILE:                                          73 
+     DIRFILE:                                       73 
+2.8.2  Deklaration und Assoziierung                 74 
+     input:                                         75 
+     output:                                        75 
+     modify:                                        75 
+2.9  Abstrakte Datentypen im EUMEL-System          77 
+2.9.1  Datentyp TASK                                77 
+2.9.2   Datentyp THESAURUS                          79 
+2.9.3  Datenräume                                   81 
+2.9.3.1  Datentyp DATASPACE                         82 
+2.9.3.2  BOUND-Objekte                              83 
+     Häufige Fehler bei der Benutzung von Datenräume  85 
+2.9.3.3  Definition neuer Dateitypen                88 
+2.9.4  Datentyp INITFLAG                            91 
+#tableend# 
+ 
+ 
+ 
+ 
+TEIL 3 : Der Editor 
+#table# 
+3.1  Ein- und Ausschalten des Editors               1 
+3.2  Die Funktionstasten                            3 
+3.3  Die Wirkung der Funktionstasten                4 
+3.4  ESC Kommandos                                  11 
+     Operationen auf Markierungen                   15 
+     Zeichen schreiben                              16 
+     Kommando auf Taste legen                       16 
+     Vorbelegte Tasten                              17 
+     Der Lernmodus                                  17 
+3.5  Positionieren, Suchen, Ersetzen          
+     im Kommandodialog                          21 
+     Weitere Hilfen                                 23 
+#tableend# 
+ 
+ 
+ 
+ 
+TEIL 4 : Kommandosprache 
+#table# 
+4.1  Supervisor                                     2 
+4.2  Monitor                                        6 
+4.2.1  Hilfsprozeduren                              8 
+     Informationsprozeduren                         11 
+4.2.2  Thesaurus                                    16 
+4.2.3  Tasks                                        21 
+4.2.4  Handhabung von Dateien                       26 
+4.2.5  Editor-Prozeduren                            29 
+4.2.6  Dateitransfer                                33 
+4.2.7  Passwortschutz                               39 
+4.2.8  Das Archiv                                   44 
+     Fehlermeldungen des Archivs                    52 
+#tableend# 
+ 
+ 
+ 
+ 
+TEIL 5 : Programmierung 
+#table# 
+5.1  Der ELAN-Compiler                              1 
+5.1.1  Fehlermeldungen des ELAN-Compilers           5 
+5.2  Standardtypen                                  7 
+5.2.1  Bool                                         7 
+5.2.2  Integer-Arithmetik                           9 
+5.2.3  Real-Arithmetik                              16 
+5.2.4  Text                                         26 
+     Der EUMEL-Zeichensatz                          29 
+5.3.1  Assoziierung                                 41 
+5.3.2  Informationsprozeduren                       43 
+5.3.3  Betriebsrichtung INPUT                       44 
+5.3.4  Betriebsrichtung OUTPUT                      46 
+5.3.5  Betriebsrichtung MODIFY                      48 
+5.3.6  FILE -Ausschnitte                            51 
+5.4  Suchen und Ersetzen in Textdateien             53 
+5.4.1  Aufbau von Textmustern                       54 
+5.4.2  Suche nach Textmustern                       57 
+5.4.3  Treffer registrieren                         59 
+5.4.4  Treffer herausnehmen                         60 
+5.4.5  Ändern in Dateien                            61 
+5.4.6  Editor-Prozeduren                            62 
+5.4.7  Sortierung von Textdateien                   64 
+5.4.8  Prozeduren auf Datenräumen                   65 
+5.5  Eingabe/Ausgabe                                68 
+5.5.1  E/A auf Bildschirm                           69 
+5.5.1.1  Eingabesteuerzeichen                       69 
+5.5.1.2  Ausgabesteuerzeichen                       70 
+5.5.1.3  Positionierung                             71 
+     Grundlegende Prozeduren                        72 
+     Umleitbare Eingabeprozeduren                   73 
+     Grundlegende Prozeduren                        75 
+     Umleitbare Ausgabeprozeduren                   77 
+5.5.1.4  Eingabe                                    72 
+5.5.1.5  Ausgabe                                    75 
+5.5.1.6  Kontrolle                                  79 
+5.5.2  Zeitmessung                                  80 
+5.6  Scanner                                        83 
+     Scanner-Kommandos                              85 
+#tableend# 
+ 
+ 
+ 
+ 
+TEIL 6 : Das Archiv 'std zusatz' 
+#table# 
+6.1   Erweiterungen um Mathematische Operationen      2 
+6.1.1  COMPLEX                                      2 
+6.1.2  LONGINT                                      7 
+6.1.3  VECTOR                                       16 
+6.1.4  MATRIX                                       24 
+6.2  Programmanalyse                                36 
+     reporter - Kommandos                           39 
+     Referencer                                     41 
+     referencer - Kommandos                         42 
+6.3  Rechnen im Editor                              43 
+     Arbeitsweise                                   43 
+     TeCal Prozeduren                               44 
+#tableend# 
+ 
+ 
+ 
+ 
+Anhang : ELAN-Syntaxdiagramme 
+ 
+ 
+ 
+ 
+INDEX 
+
diff --git a/doc/programming/programmierhandbuch.titel b/doc/programming/programmierhandbuch.titel
new file mode 100644
index 0000000..79b09b0
--- /dev/null
+++ b/doc/programming/programmierhandbuch.titel
@@ -0,0 +1,52 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#Programmierhandbuch 
+ 
+ 
+ 
+ 
+#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# 
+#block##pageblock# 
+#start(5.0,1.5)# 
+ 
+#lpos(3.0)# 
+#table# 
+ 
+ 
+ 
+ 
+ 
+ 
+Benutzerhandbuch 
+ 
+Programmierung 
+ 
+ 
+ 
+Stand:  1.7.87 
+ 
+#tableend##page# 
+
+
diff --git a/doc/prolog/prolog handbuch b/doc/prolog/prolog handbuch
new file mode 100644
index 0000000..ea7c6a5
--- /dev/null
+++ b/doc/prolog/prolog handbuch	
@@ -0,0 +1,581 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#Prolog 
+ 
+ 
+ 
+ 
+#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# 
+ 
+Dr.P.Heyderhoff                                                  12.03.1987 
+GMD.F2.G2 
+ 
+ 
+ 
+ 
+ 
+ 
+                           E L A N - P R O L O G 
+                           _____________________ 
+ 
+               (Die Fachsprache der künstlichen Intelligenz) 
+ 
+#on("u")#Benutzungsanleitung und technische Beschreibung#off("u")# 
+ 
+ 
+Elan-Prolog ist eine Computersprache der fünften Generation, die für
+die Praxis der Programmierung und die Lehre in Informatik eine neue
+Dimension erschließt. Für den professionellen Programmierer eröffnet sie
+neue Möglichkeiten, mächtige Anwendungen, wie Expertensysteme und andere
+neuartige Systeme der Wissensverarbeitung zu entwickeln. 
+ 
+Elan-Prolog unterscheidet sich grundsätzlich von üblichen konventionellen
+Programmiersprachen. In Sprachen wie Elan und Pascal muß der Programmierer
+genau angeben, wie ein gewünschtes Ergebnis errechnet werden soll. Um was es
+sich dabei handelt, steht bestenfalls dann in der Dokumentation. Ganz anders
+ist es in Prolog. PROLOG steht für PROgrammieren in LOgik und basiert auf
+dem Prädikaten-Kalkül, der bekanntesten Form der formalen Logik. Also in
+Prolog schreibt der Programmierer hin, worin das Problem besteht. Er bedient
+sich dabei dieser formalen Logik. Prolog versucht dann eine Lösung zu
+finden. Der Lösungsweg ist dabei im Programm nicht vorgeschrieben. Das
+entlastet den Programmierer, und er kann seine ganze Kraft auf die logische
+Beschreibung des Problems konzentrieren. 
+ 
+Elan-Prolog ist ein interpretatives System, das voll kompatibel ist mit dem
+Edinburgh Standard Prolog und in in komfortabler Weise in das Betriebssystem
+Eumel eingebettet ist. 
+ 
+Eigenschaftes von Elan-Prolog: 
+ 
+-  Syntax gemäß dem Edinburgh Standard Prolog nach Clocksin-Mellish 
+ 
+-  Interpretierendes System mit inkrementellem Einpass-Compiler 
+ 
+-  Interaktiver Mehrfenster-Texteditor des Eumelsystems 
+ 
+-  Zugriff auf Elan-Prozeduren als Prolog-Regeln 
+ 
+-  Geschwindigkeit ca. 100 LIPS auf IBM/PC-XT 
+ 
+-  optionale dynamische Ablaufverfolgung 
+ 
+-  Erklärungskomponente 
+ 
+-  Eingabe und Ausgabe von Prolog-Ausdrücken und Klartext 
+ 
+-  Programmiert und dokumentiert in ELAN (über 2000 Zeilen) 
+ 
+-  daher besonders für den Informatik-Unterricht geeignet 
+#page# 
+#on("u")#Beschränkungen des Elan-Prolog:#off("u")# 
+ 
+Folgende Beschränkungen gelten für die Implementierung von Elan-Prolog im 
+Eumel-Systems: 
+ 
+-  Maximal 16000 Fakten und Regeln 
+ 
+-  Maximal 16000 Terme zur Konstruktion von Ausdrücken, Listen und Regeln 
+ 
+-  Maximal 800 Variablenbindungen 
+ 
+-  Maximal 800 Einträge im Beweisbaum 
+ 
+-  Maximal 4000 Bezeichner für Atome und Variablen  
+ 
+-  Maximal 16000 Buchstaben für alle Bezeichner zusammen 
+ 
+ 
+Wie sieht ein Prolog-Programm aus? 
+ 
+Ein Prolog-Programm besteht aus 
+ 
+    -  Fakten über Objekte und ihre Beziehungen 
+ 
+    -  Regeln über Objekte und ihre Beziehungen 
+ 
+und besonders wichtig: 
+ 
+    -  Der Benutzer kann Prolog über die Fakten und Regeln ausfragen. 
+ 
+Fakten aus einer Wissensbasis, nämlich dem Prolog-Programm, sind z.B.: 
+ 
+       enthaelt (wisky, aethanol). 
+ 
+Das wird gelesen als: "Wisky enthält Aethanol.". Grundzüge der sehr
+einfachen Syntax lassen sich hieran erklären. Ein Faktum wird geschrieben
+wie in diesem Beispiel:
+ 
+    -  Erst kommt der Name der Relation, geschrieben wie ein Elan-Name in
+       kleinen Buchstaben. 
+ 
+    -  Dann folgt in runden Klammern und durch Kommata getrennt eine Liste
+       von Objektnamen. 
+ 
+    -  Zum Schluß steht ein Punkt. 
+ 
+Regeln sind Problembeschreibungen in der Form von logischen Ausdrücken der
+symbolischen Logik, wie z.B. die folgende Regel: 
+ 
+       bewirkt (A, B, kopfschmerz) :-   enthaelt (A, aethanol), 
+                                        enthaelt (B, aspirin ). 
+ 
+Das wird gelesen als: "Wenn man eine Droge A, die Aethanol enthält,
+und eine Droge B, die Aspirin enthält gleichzeitig einnimmt, dann bewirkt
+das Kopfschmerzen."  Wie man sieht werden logische Variablen mit großen
+Buchstaben (wie Elan-Operatoren) geschrieben. Das Zeichen ":-" steht für das
+logische Wenn, und das Komma(",") für die logische Konjunktion. Die logische
+Disjunktion wird durch Semikolon(";") ausgedrückt. 
+#page# 
+Neben der hiermit vorgestellten Prefix-Schreibweise für Relationen gibt es in
+ELAN-Prolog auch noch eine Infix-Schreibweise für zweistellige Relationen.
+Hierbei werden die Relationen als Infix-Operatoren in großen
+Buchstaben geschrieben (wie in ELAN) und zwischen die beiden Operanden
+gesetzt. Als Operatoren sind auch die in Elan üblichen Operatoren 
+ 
+              ( +, -, *, /, MOD, =, <, >, <=, >=, <> ) 
+zulässig. 
+ 
+In Infixausdrücken (wie z.B. 2+3*4) gelten die bekannten Vorrangregeln. Auch
+Klammern sind zulässig. Selbstdefinierte Operatoren haben niedrigste 
+Priorität. 
+ 
+Obiges Beispiel in Infix-Schreibweise: 
+ 
+       wisky ENTHAELT aethanol. 
+ 
+       bewirkt (A, B, kopfschmerz) :-  A ENTHAELT aethanol, 
+                                       B ENTHAELT aspirin. 
+ 
+ 
+Objekte in Prolog können Atome oder Listen sein. Für Atome gibt es zwei 
+Schreibweisen: 
+ 
+   -  genau so wie Elan-Bezeichner, also bestehend aus kleinen Buchstaben
+      und Blanks. Dabei werden die Blanks eliminiert. 
+ 
+   -  genauso wie Elan-Texte, nämlich in Gänsefüßchen eingeschlossen. 
+
+Für Listen von Objekten gibt es wiederrum zwei Schreibweisen, wie folgende
+zwei unterschiedlichen Notationen des gleichen Beispiels zeigen: 
+  
+   -  [ das, ist, [ zum, beispiel ], eine, liste ] 
+ 
+   -  [ das, ist, [ zum | [ beispiel | [] ] ], eine, liste ] 
+ 
+Im zweiten Fall ist die als drittes Element in der Gesamtlisten enthaltene
+Teilliste mit dem Konstruktor "|" und der leeren Liste "[]" zusammengesetzt.
+Die Grundoperationen, die aus der Programmiersprache LISP bekannt sind,
+können als Prolog-Fakten unmittelbar wie folgt definiert werden: 
+ 
+            eq (X, X). 
+            head ([X|Y], X). 
+            tail ([X|Y], Y). 
+            cons (X, Y, [X|Y]). 
+#page# 
+#on("u")#Standard - Operatoren von Elan-Prolog:#off("u")# 
+ 
+Im System sind nur ganz wenige Standardoperatoren eingebaut. Es sind die
+folgenden Fakten: 
+ 
+  -  ! .              der CUT-Operator schaltet des Backtracking ab. 
+ 
+  -  bye.             beendet die prolog Anwendung. 
+ 
+  -  listing.         zeigt alle insertierten Regeln. 
+ 
+  -  listing (X).     zeigt alle insertierten Regeln über X. 
+ 
+  -  call (X).        X wird ausgeführt. 
+ 
+  -  write (X).       das an X gebundenen Prolog-Objekts wird ausgegeben, 
+     writeq (X).      und wenn nicht eindeutig, gequotet, 
+     put (X).         das Zeichen, dessen ASCII-Code X ist wird ausgegeben, 
+     name (X,[Y]).    unifiziert das Atom X mit der Liste seiner Buchstaben. 
+ 
+  -  read (X).        ein Objekt wird gelesen und an die Variable gebunden. 
+     get0 (X).        das nächste Zeichen wird gelesen, 
+     get  (X).        das nächste druckbare Zeichen wird gelesen, 
+ 
+  -  X =  Y .         Die an X und Y gebundenen Objekte sind gleich, 
+     X <> Y .         sie sind ungleich, 
+     X <= Y .         sie sind kleiner oder gleich, 
+     X == Y .         sie sind wörtlich gleich, 
+     X =.. [F|A] .    X ist der Term mit Funktor F und Argumentliste A. 
+ 
+  -  X +  Y .         sie sollen addiert, 
+     X -  Y .         subtrahiert, 
+     X *  Y .         multipliziert, 
+     X /  Y .         dividiert, 
+     X MOD Y .        der Divisionsrest soll ermittelt werden, 
+                      die Auswertung geschieht durch den 'is'-Operators. 
+ 
+  -  X IS EXPR .      Das Ergebnis des arithmetischen Ausdrucks EXPR wird
+                      gebildet und mit X unifiziert. 
+ 
+  -  incr (X).        der arithmetische Wert von X wird um eins erhöht. 
+ 
+  -  assertz ([X]).   insertiert die Regel X am Ende einfügend. 
+     asserta ([Χ]).   insertiert die Regel X am Anfang einfügend. 
+     retract ([X]).   entfernt die Regel X wieder. 
+     clause (X,[Y]).  holt die Regel Y mit dem Kopf X aus der Knowledgebase. 
+ 
+  -  functor (X,Y,Z)  Y ist der Funktor von X und Z ist seine Arität. 
+     arg (X,Y,Z).     Z ist das x-te Argument der Funktion Y. 
+ 
+  -  elan (X).        Ausführung der insertierten ELAN-Prozedur X 
+     elan (X,Y).      Ausführung von X mit dem TEXT-CONST-Parameter Y 
+ 
+  -  elan(trace,on).  schaltet den dynamischen Ablaufverfolger ein und 
+     elan(trace,off)  schaltet ihn wieder ab. 
+ 
+  -  elan(consult,X)   lädt das Prologprogramm aus der Datei namens X hinzu. 
+     elan(reconsult,X)   ersetzt das Prologprogramm aus der Datei X. 
+     elan(abolish,X)     entfernt alle Regeln mit dem Namen X. 
+#page# 
+#on("u")#Das Dialogverhalten von Elan-Prolog:#off("u")# 
+ 
+Elan-Prolog wird, sobald es in das Eumel-System insertiert ist, als Prozedur
+mit dem Namen "prolog" und einem optionalen TEXT-Parameter aufgerufen. Der
+Textparameter enthält den Namen einer Datei, die ein Prolog-Programm enthält,
+das geladen werden soll. Fehlt der Parameter, wird, wie üblich, die zuletzt
+bearbeitete Datei genommen. Im Prolog-Dialog können später weitere
+Prolog-Programme mit der Prozedur namens "consult" hinzugeladen werden. 
+ 
+Also 
+einfachster Aufruf:     prolog ("") 
+ 
+Antwort:                ?- 
+Beispiel-Eingabe:           3 = 3 
+Antwort:                    yes 
+                        ?- 
+Eingabe:                    4 = -5 
+Antwort:                    no 
+                        ?- 
+ 
+Besondere Dialogkommandos: 
+ 
+                        ?- 
+Eingabe:                    ? 
+Antwort z.B.:               13.5 SEC 
+                        ?- 
+Eingabe:                    listing 
+Antwort:                    { zeigt alle aktuell verfügbaren Regeln } 
+                        ?- 
+Eingabe:                    {ESCAPE} q 
+Ausgabe:                gib kommando: 
+ 
+Eingabe:                    prolog again 
+Ausgabe:                ?- 
+Eingabe:                    [sum, permute]    {in eckigen Klammern!} 
+                            { konsultiert diese beiden Dateien } 
+Antwort z.B.:           25 rules inserted. 
+                        ?- 
+Eingabe:                    [-sum, -permute] 
+                            { löscht und rekonsultiert aus diesen Dateien } 
+Antwort z.B.:           25 rules inserted. 
+ 
+Eingabe:                    {ESCAPE} {ESCAPE} 
+Antwort:                gib kommado: 
+Elan-Eingabe z.B.:                   show ("standard") 
+                            { zeigt die Datei dieses Namens } 
+                        ?- 
+ 
+Auf diese Weise können bequem Eumel-Kommandos gegeben werden. Die
+Umschaltung vom Prolog- zum Eumelmonitor-Betrieb erfolgt durch die Tasten
+{ESCAPE},{ESCAPE} und {RETURN}. Wie üblich ist das zuletzt verwendete
+Kommando auch im Prolog-Dialog mit dem Escapekommando "{ESCAPE} k"
+wiederzubekommen. Das Kommando "{ESCAPE} q" beendet den Dialog. 
+#page# 
+#on("u")#Ausprobieren der Prolog-Programmbeispiele:#off("u")# 
+ 
+Zum Ausprobieren sind die Prologbeispiele "eq", "permute" und "mann"
+beigefügt. 
+ 
+Beispiel:               ?- 
+Eingabe:                   [permute]       {in eckigen Klammern!} 
+Antwort:                5 rules inserted. 
+                        ?- 
+Eingabe:                    marquise(X) 
+Antwort:         beautiful marquise your beautiful eyes make me die of love 
+Eingabe:         {Semicolon} 
+Antwort:         your beautiful eyes beautiful marquise make me die of love 
+                 { usw } 
+Eingabe:         {Return} 
+Antwort:         ?- 
+ 
+Jede #on("u")#Eingabe von Semicolon#off("u")# liefert als Antwort die nächste Permutation. Wenn
+eine andere Taste gedrückt wird, bricht die Ausgabe weiterer Ergebnisse ab. 
+ 
+#on("u")#Eingabe von Fragezeichen#off("u")# liefert neben der Angabe der benötigten
+Rechenzeit eine Erklärung der letzten Antwort durch Ausgabe aller zu dieser
+Antwort führenden Schlußfolgerungen. Dabei wird der Beweisbaum in Form einer
+Einrückstruktur dargestellt. Die Einrückung stellt die Erklärungstiefe dar. 
+ 
+ 
+#on("u")#Benutzung von Prolog von Elan-Programmen aus#off("u")# 
+ 
+Wenn man Prolog als Unterprogramm von Elan aus aufrufen will, geht man
+folgendermaßen vor: 
+ 
+1.  Laden einer Wissensbasis, 
+    die in einer Datei namens <knowledgebase> z.B."permute" bereitsteht: 
+ 
+         push ("bye"13""); 
+         prolog ("permute"); 
+ 
+ 
+2.  Abfragen an diese Wissensbasis: 
+ 
+         TEXT VAR query, answer; 
+         query:= "marquise (X)"; 
+         IF   prolog ( query, answer) 
+         THEN put (answer) 
+         ELSE put ("NO") 
+         FI; 
+ 
+In diesem Anwendungsbeispiel liefert die Ausgabeanweisung 'put (answer)': 
+ 
+         beautiful marquise your beatiful eyes make me die of love 
+ 
+#page# 
+#on("u")#Literatur:#off("u")# 
+ 
+ 
+1.)  W.F.Clocksin, C.S.Mellish: 
+     Programming in Prolog 
+     Springer 1984 
+ 
+2.)  M.H.van Emden: 
+     An interpreting algorithm for prolog programs 
+     in Implementations of Prolog, Ellis Herwood Ltd, 1984 
+ 
+3.)  Alain Colmerauer: 
+     Prolog in 10 Figures 
+     Communications of the ACM December 1985 
+ 
+4.)  J. Cohen: 
+     Describing Prolog by its Interpretation and Compilation 
+     Communications of the ACM December 1985 
+  
+5.)  Alain Colmerauer: 
+     Les system q ou un formalisme pour alalyser et synthetiser des phrases
+     sur ordinateur. 
+     Intern.Rep. 43, Departement d'informatique. Universite de Montreal 
+     Sept. 1970 
+#page# 
+(*************************************************************************) 
+(*                                                                       *) 
+(* Elan-Prolog                                                           *) 
+(*                                                                       *) 
+(* Programm-Beispiele:                                                   *) 
+(*                                                                       *) 
+(****************** standard  (nach Clocksin-Mellish) ********************) 
+ 
+abolish    (X)                :-  elan (abolish, X). 
+append     ([], X, X)         :-  !. 
+append     ([X|Y], Z, [X|W])  :-  append (Y, Z, W). 
+atom       (X)                :-  functor (X, Y, 0). 
+atomic     (X)                :-  atom (X); integer (X). 
+consult    (X)                :-  elan (consult, X). 
+end                           :-  bye. 
+fail                          :-  []. 
+findall    (X, Y, Z)          :-  tell ("$$"), write ("("), findall (X,Y); 
+                                  write (")"), told, see  ("$$"), read (Z), 
+                                  seen, elan (forget, "$$"). 
+findall    (X, Y)             :-  call (Y), writeq (X), write (","), []. 
+integer    (X)                :-  functor (X, Y, -1). 
+listing    (X). 
+member     (X, [X|Z]).        
+member     (X, [Y|Z])         :-  member (X, Z). 
+nl                            :-  elan (line). 
+non var    (X)                :-  var (X), !, []; . 
+not        (X)                :-  call (X), !, []; . 
+notrace                       :-  elan (trace, off). 
+reconsult  (X)                :-  elan (reconsult, X). 
+repeat. 
+repeat                        :-  repeat. 
+see        (X)                :-  elan (sysin, X). 
+seen                          :-  elan (sysin, ""). 
+tab        (X)                :-  tab(X,1). 
+tab        (X,Y)              :-  Y<=X, !, put (32), incr(Y), tab(X,Y);. 
+tell       (X)                :-  elan (sysout, X). 
+told                          :-  elan (sysout, ""). 
+trace                         :-  elan (trace, on). 
+true. 
+<          (X, Y)             :-  <= (X, Y), <> (X, Y). 
+>          (X, Y)             :-  <= (Y, X). 
+>=         (X, Y)             :-  <  (Y, X). 
+#page# 
+(****************************   sum    ***********************************) 
+ 
+suc (0, 1). suc (1, 2). suc (2, 3). suc (3, 4). suc (4, 5). 
+suc (5, 6). suc (6, 7). suc (7, 8). suc (8, 9). 
+sum (0, X, X). 
+sum (X, Y, Z):-  suc (V, X), sum (V, Y, W), suc (W, Z). 
+plus (X, [0,0], X):-  !. 
+plus (X, Y, Z):-  plus one (V, Y), plus (X, V, W), !, plus one (W, Z). 
+plus one ([X, Y], [V, W]):-  suc (Y, W), X = V, !; 
+                             Y = 9, suc (X, V), W = 0. 
+treereverse (X,Y):-  rev (X,Y), !; rev (Y,X), !. 
+rev ([], []). 
+rev ([X|Y], Z):-  X <> [H|T], rev (Y, W), !, append (W, [X], Z); 
+                  rev (X, V), rev (Y, W), !, append (W, [V], Z). 
+       
+(**************************** permute ************************************) 
+ 
+permute ([], []). 
+permute ([E|X], Z):- 
+        permute (X, Y), insert (E, Y, Z). 
+insert  (E, X, [E|X]). 
+insert  (E, [F|X], [F|Y]):- 
+        insert (E, X, Y). 
+marquise(RESULT):- 
+  permute (["beautiful marquise", 
+                "your beautiful eyes", 
+                  "make me", 
+                    "die", 
+                      "of love" 
+                        ], 
+                          RESULT). 
+ 
+(**************************** puzzle  ************************************) 
+ 
+                {Solution: 9,5,6,7,0,8,2} 
+puzzle:- repeat, permute ((9,8,7,6,5,2,0), SENDMORY), 
+                 write (SENDMORY), 
+                 puzzle (SENDMORY, SEND, MORE, MONEY), 
+                 elan (line), 
+                 write (SEND), write (+), 
+                 write (MORE), write (=), 
+                 write (MONEY). 
+ 
+puzzle([S,E,N,D,O,R,Y], SEND, MORE, MONEY):- 
+  SEND   IS  ((S * 10 + E) * 10 + N) * 10 + D, 
+  MORE   IS  ((10 + O) * 10 + R) * 10 + E, 
+  MONEY  IS  (((10 + O) * 10 + N) * 10 + E) * 10 + Y, 
+  MONEY  IS  SEND + MORE. 
+ 
+permute ([], []). 
+permute ([E|X], Z):- permute (X, Y), insert (E, Y, Z). 
+ 
+insert  (E, X, [E|X]). 
+insert  (E, [F|X], [F|Y]):- insert (E, X, Y). 
+ 
+repeat. 
+repeat:- repeat. 
+#page# 
+(****************************  prieks  ***********************************) 
+ 
+ist priek (bo priek). 
+ist priek (ki priek). 
+ist priek (bla priek). 
+ 
+WER GNASELT WEN :- population (B), 
+                   member ([WEN, WER, _], B), 
+                   bedingungen (B). 
+ 
+WER KNAUDERT WEN:- population (B), 
+                   member ([WER, _, WEN], B), 
+                   bedingungen (B). 
+ 
+population (B):-   sind prieks (U, V, W), 
+                   sind knauderarten (R, S, T), 
+                   B = [ [drausla puemfe, U, R], 
+                         [glessla puemfe, V, S], 
+                         [hapla puemfe, W, T]    ]. 
+ 
+sind prieks (X,Y,Z):- ist priek (G), 
+                      ist priek (H), H<>G, 
+                      ist priek (I), I<>G, I<>H, !, 
+                          permute ([G,H,I], [X,Y,Z]). 
+ 
+sind knauderarten (X,Y,Z):- ist knauderart (G), 
+                            ist knauderart (H), H<>G, 
+                            ist knauderart (I), I<>G, I<>H, !, 
+                                permute ([G,H,I],[X,Y,Z]). 
+ 
+ist knauderart (an). 
+ist knauderart (ab). 
+ist knauderart (ueber). 
+ 
+bedingungen (B):-  not member ([hapla puemfe,ki priek,_],B) , 
+                   not member ([hapla puemfe,_,ueber],B) , 
+                   not member ([drausla puemfe,bo priek,_],B) , 
+                   not member ([_,bo priek,ab],B) , 
+                   noch ne bedingung (B) , 
+                   weitere bedingungen (B) , !. 
+ 
+weitere bedingungen (B):-  not member([_,ki priek,ueber],B), 
+                           not member([_,bo priek,ueber],B) 
+                           ; 
+                           member([drausla puemfe,_,an],B). 
+ 
+noch ne bedingung (B):-    not member ([drausla puemfe,ki priek,_],B) 
+                           ; 
+                           not member ([glessla puemfe,_,ueber],B). 
+ 
+permute ([], []). 
+permute (X, [Y|Z]):- delete (Y ,X, E), permute (E, Z). 
+delete (X, [X|Z], Z). 
+delete (X, [Y|Z], [Y|E]):- delete (X, Z, E). 
+member (X, [X|Z]).        
+member (X, [Y|Z]):-  member (X, Z). 
+not member (X, []). 
+not member (X, [Y|Z]):- X <> Y, not member (X,Z). 
+#page# 
+(****************************  calc   ************************************) 
+ 
+{ CALC evaluates arithmetic expressions with store } 
+ 
+calc:- eval ([], RS), write (result store), write (RS), nl. 
+ 
+eval (SI, SO):- 
+   read (CALC), nonvar (CALC), eval member (CALC, SI, SO). 
+ 
+eval member (CALC, SI, SO):- 
+   member (CALC, [stop,end,bye,eof]), SO=SI; 
+   eval (CALC,I,SI,ST), write (I), eval (ST,SO); 
+   write (error in), write (CALC), nl, eval (SI, SO). 
+ 
+eval (I, I, S, S):- integer (I). 
+eval (N, I, S, S):- atom (N), eval atom (N, I, S). 
+ 
+eval atom (N, I, S):- 
+  member (N=I, S); 
+  write ("error:  Cell"), write (N), 
+    write("not found in store. 0 substituted."), nl, I=0. 
+ 
+eval ( L+R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J+K. 
+eval ( L-R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J-K. 
+eval ( L*R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J*K. 
+eval ( L/R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J/K. 
+ 
+eval (N=O, I, SI, SO):- 
+  atom (N), eval (O,I,SI,ST), eval repl (N,I,ST,SO). 
+ 
+eval repl (N, I, [], [=(N,I)]). 
+eval repl (N, I, [=(N,_)|S], [=(N,I)|S]). 
+eval repl (N, I, [=(M,J)|SI], [=(M,J)|SO]):- eval repl (N, I, SI, SO). 
+
diff --git a/doc/prozess/Anhang Prozess b/doc/prozess/Anhang Prozess
new file mode 100644
index 0000000..8415268
--- /dev/null
+++ b/doc/prozess/Anhang Prozess	
@@ -0,0 +1,92 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess 
+ 
+#end# 
+#center#1 
+ 
+#center##on("b")#Anhang#off("b")# 
+ 
+#center##on("b")#Bezugsquellenverzeichnis#off("b")# 
+ 
+ 
+   -  AKTRONIK 
+      Elektronik-Großhandel 
+      A. Kaup 
+      Teichstraße 9 
+      4401 Saerbeck 
+      Tel.: 02574/8008 - 8009 
+ 
+ 
+ 
+   -  BICOS Computer GmbH 
+      Werkering 6 
+      Postfach 1229 
+      4800 Bielefeld 1 
+      Tel.: 0521/34011 
+ 
+ 
+ 
+   -  lattasoft 
+      Eva Latta-Weber 
+      Software-  und 
+      Hardware-Systeme 
+      Brehmstraße 7 
+      4800 Bielefeld 1 
+      Tel.: 0521/38919 
+ 
+ 
+ 
+   -  Landesinstitut für Schule 
+      und Weiterbildung 
+      Paradieser Weg 64 
+      4770 Soest 
+      Tel.: 02921/683-1 
+ 
+#page# 
+#on("b")#Anhang#off("b")# 
+ 
+#on("b")#Verzeichnis der Abbildungen#off("b")# 
+ 
+Abb. 1:  MUFI geöffnet 
+Abb. 2:  Mögliche DIP-Schalter-Stellung beim MUFI 
+Abb. 3:  Einbau des MUFIs in den Terminalkanal 
+Abb. 4:  RS232-Adapter geöffnet 
+Abb. 5:  Mögliche Jumperposition beim RS232-Adapter 
+Abb. 6:  Auswahl der Interface-Anpassung 
+Abb. 7:  Anschluß Leuchtdiodenanzeige -Kombikarte 
+Abb. 8:  Pinbelegung auf der E/A-Karte 
+Abb. 9:  Eingangsbildschirm ls-Prozess 
+Abb.10:  Menubildschirm zum Oberbegriff 'Interface' 
+Abb.11:  Information bei unkonfiguriertem System 
+Abb.12:  Auswahl der Steckplatzart 
+Abb.13:  Compact-Box: Belegung der Kanäle 
+Abb.14:  Auswahl einer Interfacekarte 
+Abb.15:  Kanalbelegung D/A-Karte (Einzelsteckplatz) 
+Abb.16:  A/D-Karte: Angabe der Schalterstellung 
+Abb.17:  A/D-Karte: Kanalbel./Spannungsber.(Bspl.) 
+Abb.18:  Ausgabetest - Einblendung 
+Abb.19:  Eingabetest - Einblendung 
+Abb.20:  Beispiellochkarte 
+Abb.21:  Aufbau eines Drehpotentiometers 
+Abb.22:  Eingangsbildschirm ls-Prozess 
+Abb.23:  Befehlsübersicht 
+Abb.24:  Auswahl Ausgabebefehle 
+Abb.25:  Auswahl Eingabebefehle 
+Abb.26:  Auswahl Testbefehle 
+Abb.27:  Auswahl 'Weitere Befehle' 
+Abb.28:  Menubildschirm zum Oberbegriff 'Interface' 
+Abb.29:  Menubildschirm zum Oberbegriff 'Programm' 
+Abb.30:  Informationsauswahl zum EUMEL-Editor 
+Abb.31:  Menubildschirm zum Oberbegriff 'Archiv' 
+Abb.32:  Auswahl der Archiv-Formate 
+Abb.33:  Auswahl der Zieltask 
+ 
+ 
+
diff --git a/doc/prozess/Inhalt Prozess b/doc/prozess/Inhalt Prozess
new file mode 100644
index 0000000..ab9616a
--- /dev/null
+++ b/doc/prozess/Inhalt Prozess	
@@ -0,0 +1,84 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess 
+ 
+#end# 
+#center#1 
+ 
+#center##on("b")#Inhaltsverzeichnis#off("b")# 
+ 
+1      Was kann gs-Prozess                              
+ 
+2      Allgemeines zur Prozeßdatenverarbeitung          
+2.1    Welche Hardware-Lösungen gibt es zur Zeit ?    
+2.2    Die besonderen Probleme unter EUMEL            
+2.3    Die Wahl des Interface-Systems                 
+ 
+3      Installation des Interface-Systems               
+3.1    Das MUFI der Firma BICOS als Adapter           
+3.1.1  Einstellung der DIP-Schalter am MUFI         
+3.1.2  Einbau des MUFIs in den Terminalkanal        
+3.1.3  Das MUFI an separater serieller Schnittstelle
+3.2    Der RS232-Adapter der Firma AKTRONIK           
+3.3    Verbindung Adapter - Interface-System          
+3.4    Bereitstellung des Interface-Systems           
+ 
+4      Installation von gs-Prozess                      
+4.1    Voraussetzungen                                
+4.2    Lieferumfang                                   
+4.3    Installation                                   
+4.4    Anmerkungen zur Erstinstallation               
+ 
+5      Konfiguration von gs-Prozess                   
+5.1    Kontrolle der Konfigurationen/Anschlüsse       
+5.2    Vorbereitungen für den Ein-/Ausgabetest        
+5.2.1  Anschluß einer Leuchtdiodenanzeige an die Kombikarte 
+5.2.2  Anschluß des Codekartenlesers (Drahtstück)   
+5.3    Konfiguration von gs-Prozess                   
+5.3.1  Auswahl der Steckplatzart/Interfacekarte     
+5.3.2  Bedeutung der Kanalnummern                   
+5.4    Aus- und Eingabetest                           
+5.5    Mögliche Fehlerfälle                           
+ 
+6      Arbeiten mit gs-Prozess                          
+6.1    Kleine Beispiele zur digitalen Ausgabe         
+6.1.1  Möglichkeit eines Programmabbruchs           
+6.1.2  Die "sonstigen" Befehle                      
+6.1.3  Schreibweise für Bitmuster/Bitsymbole        
+6.1.4  Befehle für die digitale Ausgabe             
+6.1.5  Befehle für die analoge Ausgabe              
+6.2    Kleine Beispiele zur digitalen Eingabe         
+6.2.1  Befehle für die digitale Eingabe             
+6.2.2  Eingabetests                                 
+6.2.3  Befehle für die analoge Eingabe              
+6.3    Hinweise auf Aufgabenmaterial                  
+ 
+7      Beschreibung der Menufunktionen                  
+7.1    Kurzhinweise zur Bedienung der Menus           
+7.2    Menufunktionen zum Oberbegriff 'Info'          
+7.3    Menufunktionen zum Oberbegriff 'Interface'     
+7.4    Menufunktionen zum Oberbegriff 'Programm'          
+7.5    Menufunktionen zum Oberbegriff 'Archiv'            
+ 
+8      Detailbeschreibung der Basisbefehle und Tests        
+ 
+9      Hinweise für den Systembetreuer/     Programmierer   
+9.1    Vergabe der Kanäle/Organisation des Tasksystems    
+9.2    Informationsprozeduren                             
+9.3    Neufestlegung des Interfacekanals                  
+9.4    Fixieren der Konfiguration                         
+9.5    Mögliche Fehlerfälle                               
+9.6    Weitere Möglichkeiten                              
+ 
+Anhang:   Bezugsquellenverzeichnis 
+          Verzeichnis der Abbildungen 
+
+
+
+
diff --git a/doc/prozess/gs-Prozess handbuch.impressum b/doc/prozess/gs-Prozess handbuch.impressum
new file mode 100644
index 0000000..ca22b10
--- /dev/null
+++ b/doc/prozess/gs-Prozess handbuch.impressum	
@@ -0,0 +1,104 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#gs-Prozess
+ 
+ 
+ 
+ 
+#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# 
+ 
+#free (4.0)##on("b")# 
+#center#gs-Prozess
+ 
+ 
+#center#Benutzerhandbuch 
+ 
+ 
+#center#Version 1.0 
+ 
+ 
+#off("b")##center#copyright 
+#center#Eva Latta-Weber 
+#center#Software- und Hardware-Systeme, 1988 
+#center#ERGOS GmbH, 1990 
+#page# 
+#block# 
+#center#____________________________________________________________________________ 
+ 
+ 
+Copyright:  ERGOS GmbH   März 1990 
+ 
+            Alle Rechte vorbehalten. Insbesondere ist die Überführung in 
+            maschinenlesbare Form sowie das Speichern in Informations­ 
+            systemen, auch auszugsweise, nur mit schriftlicher Einwilligung 
+            der ERGOS GmbH gestattet. 
+ 
+ 
+#center#____________________________________________________________________________ 
+ 
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender. 
+ 
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden. 
+ 
+Texterstellung   :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+                   erstellt und aufbereitet und auf einem Kyocera Laser­
+                   drucker gedruckt. 
+ 
+ 
+ 
+ 
+#center#___________________________________________________________________________ 
+ 
+ 
+ 
+Ergonomic Office Software GmbH 
+ 
+Bergstr. 7              Telefon: (02241) 63075 
+5200 Siegburg           Teletex: 2627-2241413=ERGOS 
+                        Telefax: (02241) 63078 
+ 
+ 
+#center#____________________________________________________________________________ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/prozess/gs-Prozess-2 b/doc/prozess/gs-Prozess-2
new file mode 100644
index 0000000..376143e
--- /dev/null
+++ b/doc/prozess/gs-Prozess-2
@@ -0,0 +1,255 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess
+ 
+#end# 
+#center#1 
+ 
+#on("b")#2  Allgemeines zur Prozeßdatenverarbeitung#off("b")# 
+ 
+In diesem Kapitel erfahren Sie, warum unter EUMEL/ELAN die Prozeßdatenver­
+arbeitung bisher kaum Berücksichtigung gefunden hat und welche Probleme zu
+überwinden waren. Es wird aufgezeigt, warum unter EUMEL/ELAN nicht jedes Inter­
+facesystem verwendet werden kann; außerdem werden die Gründe für die Wahl eines
+bestimmten Interfacesystems genannt. 
+ 
+ 
+#on("b")#2.1  Welche Hardware-Lösungen gibt es zur Zeit ?#off("b")# 
+ 
+Wie schon in Kapitel 1 erwähnt, ist zum Messen, Steuern und Regeln mit dem
+Computer ein Hardware-Interface notwendig, über das der "Kontakt zur Außenwelt"
+hergestellt wird. 
+ 
+ 
+#on("b")# 
+     Computer <--------> Interface <--------> Modell 
+#off("b")# 
+ 
+ 
+Interfaces (zu deutsch etwas mißverständlich: Schnittstellen) verbinden innerhalb
+eines Systems Teilsysteme und einzelne Funktionseinheiten miteinander. Dabei
+werden z.B. #on("b")#Hardware-Schnittstellen#off("b")# (Um diese geht es vornehmlich in diesem
+Kapitel), #on("b")#Hardware-Software-Schnittstellen#off("b")# (Nach Festlegung, welche Funktionen
+eines Rechnersystems von der Hardware und welche von der Software übernommen
+werden, erfolgt hierüber die Verknüpfung der beiden Komponenten), #on("b")#Software-
+Schnittstellen#off("b")# (zwischen Programmoduln), #on("b")#Mensch-Maschine-Schnittstellen#off("b")#
+(Benutzerschnittstellen - wie z.B. #on("b")#gs-DIALOG#off("b")#) unterschieden. 
+ 
+Wenn wir im folgenden von 'Interface' reden, ist damit immer eine 'Hardware-
+Schnittstelle' gemeint. 
+ 
+Über ein solches Interface (eine Hardware-Schnittstelle) können an den Computer
+externe Geräte/Modelle angeschlossen werden, die vom Computer aus gesteuert
+werden. Dabei setzt das Interface die vergleichsweise schwachen Signale des
+Computers in Ströme und Spannungen um, mit denen z.B. eine Lampe oder ein
+Motor betrieben werden kann. Umgekehrt senden externe Geräte/Modelle über das
+Interface Signale an den Computer, die von ihm ausgewertet werden. So müssen z.B.
+Widerstandsveränderungen eines Temperaturfühlers oder die Stellung eines Schalters
+in eine vom Computer erfaßbare Form umgewandelt werden. 
+ 
+Inzwischen bieten verschiedene Hersteller (FISCHER, LEGO, AKTRONIK, PHYWE,
+etc.) und Lehrmittelverlage (METZLER, CVK, etc.) eine Reihe von Lösungen an.
+Leider sind die meisten Lösungen auf ganz spezielle Computertypen zugeschnitten
+und somit nicht an anderen Computertypen verwendbar - außerdem unterscheiden
+sich die verschiedenen Lösungen z.T. ganz erheblich im Leistungsumfang. 
+ 
+Einzellösungen, insbesondere an den gängigen Homecomputern, gibt es schon seit
+langem. Voraussetzung ist zumeist, daß der Computer über einen speziellen
+Anschluß ('Userport' oder 'Joystick-Eingang') verfügt. Oder es werden Platinen
+geliefert, die in spezielle Steckplätze (Slots) einzustecken sind, wo sie vom Computer
+aus angesprochen werden können. 
+ 
+Bei all diesen Lösungen konnten wir 'EUMELaner' nur neidvoll zuschauen. Der
+Vorteil, den wir sonst so zu schätzen wissen, ein einheitliches Betriebssystem auf ganz
+unterschiedlicher Hardware zur Verfügung zu haben, wird hier zum Nachteil. Eine
+einheitliche Lösung schien zu Anfang völlig aussichtslos zu sein. 
+ 
+ 
+#on("b")#2.2  Die besonderen Probleme unter EUMEL#off("b")# 
+ 
+Das Betriebssystem EUMEL gestattet es nicht, beliebig auf Hardwarekomponenten des
+Rechners zuzugreifen - und das aus gutem Grund, denn sonst wäre ein reibungsloser
+Multi-User-Betrieb nicht gewährleistet. Man kann aber den Zugriff auf neue Hard­
+warekomponenten im EUMEL-System etablieren. Allerdings ist das etwas aufwendiger
+als in anderen Systemen, denn das sogenannte 'Shard', die 'Software-Hardware-
+Schnittstelle', muß angepaßt werden. 
+ 
+Unsere ersten "Gehversuche" mit der Prozeßdatenverarbeitung unter EUMEL haben
+so angefangen. Es ist aber leicht einzusehen, daß dieser Weg nicht sinnvoll ist. Denn
+dann müßten alle EUMEL-Shards (es gibt ja für jeden Rechnertyp mindestens eines)
+entsprechend geändert werden, ggf. müßten für verschiedene Lösungen verschiedene
+Versionen entwickelt werden - eine Aufgabe, die niemand bereit wäre zu überneh­
+men. 
+ 
+ 
+#on("b")#2.3  Die Wahl des Interface-Systems#off("b")# 
+ 
+Unser Ziel war klar: Wir wollten ein gängiges, käuflich zu erwerbendes Hardware-
+Interface möglichst universell an Computern verschiedener Hersteller unter dem
+Betriebssystem EUMEL ansprechen können. 
+ 
+Nach Sichtung der angebotenen Systeme kamen nur drei in die engere Wahl: das
+LEGO-Interface, das FISCHER-Technik-Interface und das AKTRONIK-Interface (Soft­
+ware-kompatibel dazu ist das PHYWE-Interface). 
+ 
+Bei der Auswahl hielten wir es für sinnvoll, die Empfehlung des Landesinstituts für
+Schule und Weiterbildung in Soest zu berücksichtigen, in der folgende Anforderungen
+an Interfaces formuliert sind: 
+ 
+               -  8 digitale Eingänge 
+               -  8 digitale Ausgänge 
+               -  optional: analoge Ein- und Ausgabe. 
+ 
+Allen gestellten Anforderungen wird nur das AKTRONIK-Interface gerecht. Das System
+ist modular aufgebaut, je nach Anforderungen kann mit verschiedenen Steckkarten
+gearbeitet werden. Es gibt eine "Kompaktlösung", bei der die wichtigsten Funktionen
+bereitgestellt werden (8 digitale Eingänge, 8 digitale Ausgänge, 2 analoge Eingänge).
+Darüber hinaus kann auch noch mit dem sog. 'Modul-Bus' gearbeitet werden, bei
+dem gleichzeitig mehrere Steckkarten angesprochen werden können. Mit ent­
+sprechender Steckkarte ist auch die analoge Ausgabe möglich. 
+ 
+Die beiden anderen Interfaces erfüllen die oben genannten Anforderungen nicht: Das
+LEGO-Interface verfügt über nur 6 digitale Ausgänge und 2 digitale Eingänge; analoge
+Ein- und Ausgabe ist gar nicht möglich. 
+ 
+Das FISCHER-Technik-Inteface verfügt über 8 digitale Ausgänge und 8 digitale Ein­
+gänge. Das Interface verfügt auch über einen analogen Eingang - allerdings nicht
+über einen Analog-Digital-Wandler-Baustein! Das bedeutet, daß der angeschlossene
+Rechner die Auswertung der eingehenden Daten übernehmen muß - ein zeit­
+kritischer Prozeß, der in einem Multi-User-System nicht garantiert werden kann. Die
+analoge Ausgabe ist grundsätzlich nicht möglich, das System ist in sich abgeschlossen
+und kann sich ändernden Anforderungen ebensowenig angepaßt werden wie das
+LEGO-Interface. 
+ 
+ 
+Wir entschieden uns also dafür, die weitere Entwicklung auf der Basis des
+AKTRONIK-Interfaces zu betreiben. Es galt jedoch noch, dieses Interface mit dem
+Computer zu verbinden - und das möglichst universell: möglichst unabhängig von der
+verwendeten Computerhardware. 
+ 
+Dieses Ziel ist nur dann zu erreichen, wenn man die 'Standardschittstellen' des
+Computers berücksichtigt, die unter EUMEL problemlos ansprechbar sind: die
+parallelen (Centronics) und seriellen (V24) Schnittstellen. Diese 'Standardschnitt­
+stellen' sind zwar nicht für den direkten Anschluß der Modelle/Interfaces geeignet,
+über einen "Adapter" aber ist ein Anschluß möglich. 
+ 
+Die Entscheidung fiel schnell gegen eine Verwendung der parallelen (Centronics)
+Schnittstelle. Die meisten Computer verfügen nur über eine dieser Schnittstellen, die
+zumeist auch schon durch den Drucker belegt ist. Außerdem handelt es sich dabei in
+der Regel um eine unidirektionale Schnittstelle - d.h. die Daten können vom
+Computer zum Endgerät (z.B. Drucker) gelangen, nicht aber vom Endgerät zum
+Computer. Somit wären zwar Steuerungsvorgänge, nicht aber Meß- und Regelungs­
+vorgänge über die Schnittstelle möglich. 
+ 
+Einige Hersteller nutzen die Datenleitungen, über die z.B. der Drucker dem Rechner
+mitteilt, daß der interne Speicher voll bzw. das Papier zuende ist. Über diese Leitung
+werden Daten seriell übertragen und vom Rechner ausgewertet. Unter EUMEL
+scheidet diese Lösung aber aus, denn um hier eine sichere Auswertung zu gewähr­
+leisten, müßten Maschinenspracheprogramme eingebunden werden; das ist aber
+unter EUMEL nicht möglich. 
+ 
+Damit war festgelegt, daß die weitere Entwicklung auf der Basis des AKTRONIK-Inter­
+faces über die serielle Schnittstelle erfolgen sollte. Wie schon erwähnt, ist das Inter­
+face auf keinen Fall direkt an die serielle Schnittstelle anschließbar. Wie der Name
+schon sagt, werden die Daten bei einer seriellen Schnittstelle seriell übertragen - um
+Prozeßdatenverarbeitung zu betreiben, müssen die Daten aber parallel vorliegen. 
+ 
+Notwendig ist also ein "Adapter", der einen Seriell-Parallel-/Parallel-Seriell-Wandler
+beinhaltet, so daß die Verbindung zwischen Computer und Interface hergestellt
+werden kann. 
+ 
+Inzwischen sind uns hier zwei (käuflich zu erwerbende) Lösungen bekannt - der
+"RS232-Adapter" der Firma AKTRONIK und das "MUFI" (Multifunktionales Interface)
+der Firma BICOS: 
+ 
+Das MUFI ist sicherlich der universeller verwendbare "Adapter" (leider aber auch die
+kostspieligere Lösung). Einerseits kann es ebenso wie der "RS232-Adapter" an eine
+separate serielle Schnittstelle angeschlossen werden, andererseits verfügt es über
+einen zweiten - den eigentlich interessanten Betriebsmodus: Es kann nämlich auch
+in den Terminalkanal eingebaut werden. 
+ 
+Die Idee, die dahintersteckt, ist folgende: Das MUFI verfügt (neben der eigentlich
+wichtigen bidirektionalen parallelen Schnittstelle) über einen (seriellen) Eingang und
+einen (seriellen) Ausgang. So kann das MUFI einfach in eine Leitung zwischen
+Computer und Terminal eingebaut werden. In ausgeschaltetem Zustand hat es
+keinen Einfluß auf den Datenaustausch zwischen Rechner und Terminal - als ob es
+gar nicht vorhanden wäre. In eingeschaltetem Zustand dagegen "horcht es den
+Datenfluß zwischen Rechner und Terminal ab". Auf eine vereinbarte Parole
+(Zeichenkombination) hin, "weiß es", daß die folgenden Daten nicht für das
+Terminal, sondern eben für sich bestimmt sind. Diese, und nur diese Daten werden
+aus dem Datenstrom vom MUFI "herausgefischt" und intern sachgerecht weiterver­
+arbeitet. Alle anderen Daten werden unbeeinflußt an das Terminal weitergeleitet,
+damit ja nicht der reibungslose Betrieb gestört wird. Natürlich ist das MUFI ebenso in
+der Lage, die gerade extern anliegenden Daten zu ermitteln und in den Datenstrom
+zum Computer "einzuschleusen". 
+ 
+Um diese Aufgaben bewältigen zu können, wurde das MUFI mit einem eigenen,
+schnellen Mikroprozessor ausgestattet, der in der Lage ist, den Datenfluß zu
+bewältigen. Zudem wurde versucht, das MUFI mit soviel Intelligenz (Firmware)
+auszustatten, daß alle zeitkritischen Prozesse bei der Ansteuerung des Interface-
+Systems vom MUFI selbst erledigt und die Daten vom MUFI so aufbereitet werden,
+daß sie möglichst einfach weitergegeben und verarbeitet werden können. 
+ 
+Durch die Beschränkung der Baud-Rate auf maximal 19200 ist die Verarbeitungs­
+geschwindigkeit allerdings auch beschränkt. Die rechnerisch maximale Ausgabetakt­
+rate von 320 Hz bei 19200 Baud und 160 Hz bei 9600 Baud wird von #on("b")#gs-Prozess#off("b")# auf
+einem 80386-Rechner im Alleinbetrieb tatsächlich erreicht. Natürlich bedeuten
+mehrere gleichzeitig betriebene MUFIs an einem Rechner Geschwindigkeitseinbußen.
+Ebenso sinkt die Ausgabetaktrate bei Prozessoren mit geringerem Durchsatz (8088:
+maximal 120 Hz). Für die Anwendungen in der Schule sind diese Geschwindigkeiten
+aber hinreichend. 
+ 
+Die Vorteile des MUFI für diejenigen, die EUMEL im Multi-User-Betrieb nutzen, liegen
+dennoch klar auf der Hand: 
+ 
+    -  Es werden keine weiteren seriellen Schnittstellen benötigt. (Die vorhandenen
+       sind sowieso schon weitgehend belegt. Gegebenenfalls würden zusätzliche
+       Kosten verursacht.) 
+ 
+    -  Es sind keine weiteren Kabelverlegungen zwischen Rechner und Arbeitsplatz
+       notwendig, trotzdem befindet sich das MUFI direkt am Bildschirmarbeits­
+       platz. 
+ 
+    -  Das beim Anschluß an eine separate Schnittstelle notwendige, zeitauf­
+       wendige Ansteuern des Interface-Kanals entfällt. 
+ 
+ 
+Arbeiten Sie an einem Einzelplatz-System (z.B. IBM-kompatibler Rechner nur mit
+Monitor) so ist ein Betrieb des MUFIs im Terminal-Kanal nicht möglich. Hier bleibt
+nur der Betrieb des Interface-Systems an einer separaten seriellen Schnittstelle.
+Sinnvoll ist aber auch ein solcher Betrieb, wenn (zunächst) nur die Hardware für
+einen Arbeitsplatz zur Verfügung steht. Das Interface kann dann nämlich von meh­
+reren Tasks abwechselnd angesprochen werden. 
+ 
+Beim Anschluß an eine separate serielle Schnittstelle sind die Leistungen des MUFIs
+und des RS232-Adapters gleichwertig. Da das abwechselnde Ansprechen einer
+seriellen Schnittstelle und der Tastatur/des Monitors unter EUMEL relativ zeitauf­
+wendig ist, sind hier keine hohe Ausgabegeschwindigkeiten zu erwarten: bei einem
+8088-Rechner ca. 40 Hz, bei Prozessoren mit höherem Durchsatz eben entsprechend
+mehr. Dennoch ist das für die meisten Anwendungen in der Schule schnell genug. 
+ 
+Für Spezialanwendungen ist auch die direkte Ansprache der Schnittstelle möglich.
+Hierbei sind Ausgabetaktraten von 960 Hz bei 19200 Baud bzw. 480 Hz bei 9600
+Baud möglich. Für die schulische Praxis (in der Sekundarstufe I) ist diese "direkte
+Ansprache" aber ungeeignet, da weitergehende Programmierkenntnisse erforderlich
+sind. Zudem kann bei Programmierfehlern "die Task am Kanal hängenbleiben".
+Genaueres dazu sehen Sie bitte im Kapitel 'Hinweise für den Systembetreuer/
+Programmierer'. 
+ 
+Die Hardware-Konstellation stellt sich im Überblick also folgendermaßen dar: 
+#on("b")# 
+ 
+       Computer <---> Adapter <---> Interface <---> Modell 
+ 
+       (mit se-       ('MUFI'       (AKTRONIK) 
+        rieller         oder 
+        Schnitt-       'RS232- 
+        stelle)        Adapter') 
+#off("b")# 
+
diff --git a/doc/prozess/gs-Prozess-3 b/doc/prozess/gs-Prozess-3
new file mode 100644
index 0000000..3fae1bd
--- /dev/null
+++ b/doc/prozess/gs-Prozess-3
@@ -0,0 +1,346 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess 
+ 
+#end# 
+#center#1 
+ 
+#on("b")#3  Installation des Interface-Systems#off("b")# 
+ 
+In diesem Kapitel erfahren Sie, wie Sie Ihr Interface-System an den Rechner an­
+schließen und welche Einstellungen noch vorzunehmen sind. Für Details und weiter­
+gehende Informationen sehen Sie bitte in den Handbüchern / Begleitmaterialien der
+Firmen BICOS bzw. AKTRONIK nach. 
+ 
+Am Ende des Kapitels 2 haben wir festgestellt, daß das Interface-System über einen
+Adapter mit dem Computer verbunden werden muß. An das Interface-System lassen
+sich dann entsprechende Modelle anschließen: 
+ 
+#on("b")#   Computer <----> Adapter <----> Interface <----> Modell 
+ 
+   (mit se-       ('MUFI'       (AKTRONIK) 
+    rieller         oder 
+    Schnitt-       'RS232- 
+    stelle)        Adapter') #off("b")# 
+ 
+Wir möchten Ihnen zuerst erklären, wie Sie den jeweiligen Adapter mit dem
+Computer verbinden und welche Einstellungen am Adapter vorzunehmen sind. An­
+schließend beschreiben wir, wie Sie das Interface-System an den Adapter anschlie­
+ßen. 
+ 
+Wie schon in Kapitel 2 erwähnt, können Sie zwischen zwei Adaptern wählen - dem
+MUFI der Firma BICOS und dem RS232-Adapter der Firma AKTRONIK. Letztge­
+nannter kann nur an einer separaten seriellen Schnittstelle betrieben werden,
+während das MUFI zusätzlich auch in den Terminalkanal eingebaut werden kann. 
+ 
+ 
+#on("b")#3.1  Das MUFI der Firma BICOS als Adapter#off("b")# 
+ 
+Für den Betrieb in einem Terminalkanal sollte das MUFI über eine sog. "Schnitt­
+stellen-Automatik" verfügen, die verhindert, daß das MUFI in ausgeschaltetem
+Zustand oder mit abgezogenem Netzstecker den Datenfluß zwischen Rechner und
+Terminal unterbricht. Diese sehr sinnvolle Automatik wird von BICOS #on("b")#nicht
+standardmäßig#off("b")# eingebaut. Sie sollten bei eventuellen Bestellungen darauf achten.
+Bevor Sie das MUFI in den Terminalkanal einbauen oder an eine separate serielle
+Schnittstelle anschließen, ist noch die Einstellung der DIP-Schalter zu kontrollieren
+bzw. eine Neueinstellung vorzunehmen. 
+ 
+ 
+#on("b")#3.1.1  Einstellung der DIP-Schalter am MUFI#off("b")# 
+ 
+Versichern Sie sich, daß das MUFI noch nicht an das Netz angeschlossen ist. Öffnen
+Sie dann das Gehäuse, indem Sie die vier Schrauben an der Unterseite des MUFIs
+(direkt neben den Füßen) lösen. Heben Sie nun #on("b")##on("b")#vorsichtig#off("b")##off("b")# den hellen Deckel des
+Gehäuses ab. Aber Achtung! Der Deckel bleibt über Kabel mit dem Fußteil ver­
+bunden! Legen Sie vorsichtig den Deckel neben das MUFI, so daß die Kabelver­
+bindungen nicht belastet werden. 
+ 
+          +---------------------------------------------------+
+          |    +-------+   +------------+                     |
+          |    |       |   |            |        +---------+  |
+          |    +-------+   |            |        | DIP-    |  |
+          |    +-------+   |            |        | Schalter|  |
+Rück-     |    |       |   |            |        +---------+  |  Vorder-
+seite     |    +-------+   |            |   +--------------+  |  seite
+          |    +-------+   |  SCN68000  |   |              |  |
+          |    |       |   |            |   +--------------+  |
+          |    +-------+   |            |                     |
+          |    +-------+   |            |                     |
+          |    |       |   |            |                     |
+          |    +-------+   +------------+                     |
+          +---------------------------------------------------+
+ 
+ 
+ 
+#center#Abb.1:  MUFI geöffnet 
+ 
+ 
+Im Inneren des Fußteiles fällt Ihnen sofort der größte CHIP auf, der u.a. die
+Bezeichnung 'SCN68000' trägt. Drehen Sie das MUFI so vor sich, daß an der linken
+Seite dieses Chips die vier gleichen, mittelgroßen Chips zu liegen kommen. Dann
+sehen Sie rechts vom großen Chip, ganz hinten im Gehäuse eine kleine Plastikbox
+mit DIP-Schaltern, die die folgende Aufschrift trägt: 
+ 
+#on("b")# 
+                           O N 
+                          1 2 3 4 
+#off("b")# 
+ 
+Den durchsichtigen Deckel dieser kleinen Plastikbox müssen Sie nun öffnen, um die
+Stellung der DIP-Schalter einsehen zu können. Dazu verwenden Sie am besten einen
+Kugelschreiber oder einen kleinen Schraubendreher. Heben Sie damit den Deckel an
+der rechten Seite leicht an, dann läßt sich der Deckel nach links herüberlegen. Weist
+ein Schalter nach hinten (in dieser Lage des MUFIs von Ihrem Körper weg), so hat er
+die Stellung 'ON', weist er nach vorn (zu Ihrem Körper hin), so hat er die Stellung
+'OFF'. 
+ 
+ 
+Beispiel: 
+ 
+              +---------------------------------------+
+              |  +-----+  +-----+  +-----+  +-----+   |
+              |  |+++++|  |     |  |     |  |     |   |
+              |  |+++++|  |     |  |     |  |     |   |   ON
+              |  |+++++|  |     |  |     |  |     |   |
+              |  |+++++|  |     |  |     |  |     |   |
+              |  |     |  |     |  |     |  |     |   |
+              |  |     |  |     |  |     |  |     |   |
+              |  |     |  |     |  |     |  |     |   |
+              |  |     |  |+++++|  |+++++|  |+++++|   |
+              |  |     |  |+++++|  |+++++|  |+++++|   |
+              |  |     |  |+++++|  |+++++|  |+++++|   |  OFF
+              |  |     |  |+++++|  |+++++|  |+++++|   |
+              |  +-----+  +-----+  +-----+  +-----+   |
+              +---------------------------------------+
+
+                   1         2        3        4
+
+#center#Abb.2:  Mögliche DIP-Schalter-Stellung beim MUFI 
+ 
+ 
+Dabei haben die DIP-Schalter folgende Bedeutung: 
+ 
+#on("b")# 
+   1  ON   :   Modulbusbetrieb 
+      OFF  :   Parallelportbetrieb 
+ 
+   2  ON   :   RTS/CTS Hardware Handshake 
+      OFF  :   XON-/XOFF-Protokoll 
+ 
+   3  ON   :   9600 Baud 
+      OFF  :   19200 Baud 
+ 
+   4  ON   :   Even Parity 
+      OFF  :   No Parity 
+ 
+#off("b")# 
+Wenn Sie das MUFI im Terminalkanal betreiben wollen, müssen Sie je nachdem, wie
+Sie Ihr Terminal konfiguriert haben, die entsprechende Einstellung vornehmen. 
+ 
+Betreiben Sie das Terminal mit einer Übertragungsrate von 19200 Baud, so sollten
+Sie unbedingt mit XON/XOFF-Protokoll arbeiten - es sei denn, das Terminal unter­
+stützt RTS/CTS! In jedem Falle muß der DIP-Schalter 1 in die Stellung ON gebracht
+werden (der Betrieb des Interface-Systems der Firma AKTRONIK wird hier "Modul­
+busbetrieb" genannt). 
+ 
+Wenn Sie das MUFI an einer separaten seriellen Schnittstelle betreiben wollen, #on("b")#muß#off("b")#
+der Datenaustausch mit dem RTS/CTS-Protokoll abgewickelt werden. Versichern Sie
+sich, daß Ihr Kabel darauf ausgelegt ist! 
+ 
+Nach dieser Einstellung der DIP-Schalter ist das MUFI betriebsbereit. Schrauben Sie
+bitte den Gehäusedeckel mit den vier Schrauben wieder fest. 
+ 
+ 
+#on("b")#3.1.2  Einbau des MUFIs in den Terminalkanal#off("b")# 
+ 
+Um das MUFI in den Terminalkanal einbauen zu können, müssen Sie zunächst die
+Zuleitung vom Rechner zum Terminal am Terminal lösen. Auf der Rückseite des
+MUFIs befinden sich zwei Stecker, die mit V24/1 und V24/2 bezeichnet sind. Ver­
+inden Sie nun das Kabel, was ursprünglich vom Computer zum Terminal führte, mit
+dem MUFI, indem Sie es an den mit V24/2 gekennzeichneten Stecker anstecken. Sie
+benötigen jetzt noch ein weiteres (kurzes) V24-Kabel, um das MUFI mit dem
+Terminal zu verbinden. Es wird einerseits auf den mit V24/1 gekennzeichneten
+Stecker am MUFI aufgesteckt; das andere Ende wird mit dem Terminal in gleicher
+Weise verbunden, wie das ursprüngliche Kabel zwischen Rechner und Terminal. 
+ 
+ 
+          +--------------------------+
+          | +----------------------+ |
+          | |  V24/1       V24/2   | |
+          | |    |           |     | |
+          | +----|-----------|-----+ |
+          +------|-----------|-------+
+                 |           |
+                 |           |
+   ZUM     <-----+           +----->   ZUM
+   TERMINAL                            COMPUTER
+
+
+#center#Abb.3:  Einbau des MUFIs in den Terminalkanal 
+ 
+ 
+Beachten Sie bitte, daß die V24-Schnittstellen des MUFIs auf 8 Datenbits und 1 Stop­
+bit fest eingestellt sind - ggf. müssen Sie Ihre Terminalkonfiguration hieran anpassen.
+Kontrollieren Sie aber in jedem Falle, ob die Konfiguration mit diesen Daten überein­
+stimmt! 
+ 
+Koppeln Sie dazu die Task 'configurator' an Ihr Terminal (mit 'continue
+("configurator") <RETURN>') und geben Sie dann das Kommando 'configurate
+<RETURN>'. Für alle vorhandenen Kanäle werden Sie nun nacheinander gefragt,
+ob Sie eine Konfiguration vornehmen wollen. Bei den "interessanten Kanälen" ant­
+worten Sie mit 'ja' (<j>). 
+ 
+Wollen Sie sich nur die aktuelle Konfiguration ansehen, so beantworten Sie alle dann
+gestellten Fragen zum Kanal mit 'ja' (<j>), dann bleibt die aktuelle Einstellung
+erhalten. Der Konfigurationsdialog ist im EUMEL-Systemhandbuch auf den Seiten 6 -
+8 detailliert beschrieben. 
+ 
+Die Verschaltung der V24-Kabel ist in der Bedienungsanweisung zum MUFI erläutert,
+ggf. können Sie entsprechende Kabel von der Firma BICOS beziehen. 
+ 
+Wenn alle Kabelverbindungen gesteckt sind, sollten Sie auf alle Fälle erst einmal #on("b")#bei
+ausgeschaltetem MUFI#off("b")# prüfen, ob das Terminal sich noch bedienen läßt. Wenn das
+Terminal keine Reaktion mehr zeigt, obwohl es vorher (ohne MUFI) reibungslos
+funktioniert hat, dann haben Sie entweder ein MUFI ohne "Schnittstellen-Automatik"
+vor sich (vergl. Sie dazu Kap. 3.1), oder an den Kabelverbindungen stimmt irgend­
+etwas nicht. In diesem Falle sollten Sie noch einmal alle Anschlüsse und eventuell
+auch die interne Verschaltung der Kabel überprüfen. 
+ 
+ 
+#on("b")#3.1.3  Das MUFI an separater serieller Schnittstelle#off("b")# 
+ 
+Wenn Sie das MUFI als Endgerät an einer separaten seriellen Schnittstelle betreiben,
+dann stecken Sie das vom Computer kommende Kabel auf den mit V24/2
+bezeichneten Stecker an der Rückseite des MUFIs. Damit ein einwandfreier Betrieb
+gewährleistet ist, sollten Sie einen sog. "Kurzschlußstecker" auf die dann freie
+25polige D-Subminiatur-Buchse (V24/1) am MUFI aufstecken. Haben Sie eine solche
+nicht zur Hand, können Sie zwei kleine Brücken einsetzen: Nehmen Sie dazu zwei
+kleine Drahtstücke und verbinden Sie einmal Pin (Öffnung) 2 mit Pin 3 und außer­
+dem Pin 4 mit Pin 5. 
+ 
+In der Task 'configurator' muß der Kanal, an dem das MUFI angeschlossen ist, auf
+'transparent, 8 Bit, 1 Stopbit, RTS/CTS-Protokoll' eingestellt werden, weiterhin je nach
+MUFI-DIP-Schalter-Stellung auf '9600' bzw. '19200 Baud' und 'no parity' bzw. 'even
+parity'. 
+ 
+ 
+#on("b")#3.2  Der RS232-Adapter der Firma AKTRONIK#off("b")# 
+ 
+Bevor Sie den Adapter an die serielle Schnittstelle anschließen, ist noch die einge­
+stellte Baudrate zu überprüfen bzw. eine Neueinstellung vorzunehmen. 
+ 
+Öffnen Sie das Gehäuse des Adapters, indem Sie die vier Schrauben an der Unterseite
+lösen. Drehen Sie den Adapter so vor sich, daß die 25polige D-Subminiatur-Buchse
+von Ihrem Körper wegzeigt. Vorn rechts sind dann zwei parallele 8polige Pfosten­
+steckerleisten sichtbar. 
+ 
+#center#25-pol. D-Subminiatur-Stecker 
+ 
+                  +---------------+
+                  |               |
+              +---+               +---+
+              | +------+              |
+              | |      |              |
+              | |      |              |
+              | |      |              |
+              | |      |              |
+              | +------+              |
+              | +------+              |
+              | |      |    +-------+ |
+              | +------+    |       | |
+              | +------+    +-------+ |
+              | |      |    +-------+ |
+              | +------+    |     <-|---------Jumper-Leiste
+              |             +-------+ |
+              +---+               +---+
+                  |   Baudrate    |
+                  +---------------+
+
+ 
+#center#Abb.4:  RS232-Adapter geöffnet 
+ 
+ 
+Auf einem Paar steckt ein 'Jumper', mit dem die Baudrate eingestellt wird.
+Gegebenenfalls ist dieser Jumper umzustecken. Anschließend schrauben Sie das
+Gehäuse mit den vier entfernten Schrauben wieder zu. 
+ 
+                            +---------+
+                            | o    o  |     300 
+                            | o    o  |     600 
+                            | o    o  |    1200 
+                            | o    o  |    2400 
+                            | o    o  |    4800 
+                            | o    o  |    9600 
+               Jumper  ---> | o    o  |   19200 
+                            | o    o  |   38400 
+                            +---------+
+                                          Baudrate 
+ 
+ 
+#center#Abb.5:  Mögliche Jumperposition beim RS232-Adapter 
+ 
+ 
+Nun muß noch in der Task 'configurator' der entsprechende Kanal konfiguriert
+werden. Koppeln Sie dazu die Task 'configurator' an Ihr Terminal (mit 'continue
+("configurator") <RETURN>') und geben Sie dann das Kommando 'configurate
+<RETURN>'. Für alle vorhandenen Kanäle werden Sie nun nacheinander gefragt,
+ob Sie eine Konfiguration vornehmen wollen. Beim vorgesehenen Kanal antworten Sie
+mit 'ja' (<j>). 
+ 
+Wollen Sie sich nur die aktuelle Konfiguration ansehen, so beantworten Sie alle dann
+gestellten Fragen zum Kanal mit 'ja' (<j>), dann bleibt die aktuelle Einstellung
+erhalten. Der Konfigurationsdialog ist im EUMEL-Systemhandbuch auf den Seiten 6 -
+8 detailliert beschrieben. 
+ 
+Folgende Konfigurationsmerkmale müssen eingestellt werden: 
+ 
+   transparent, 8 Bit, 2 Stopbit, no Parity, #on("b")#kein#off("b")# Protokoll 
+ 
+Die Baudrate ist entsprechend der Jumper-Stellung einzustellen. 
+ 
+Am Adapter ist ein Kabel mit 25poligem D-Subminiatur-Stecker bereits fest montiert.
+Sollte der Stecker nicht an Ihren Rechner passen, so müßten Sie ein entsprechendes
+Adapterkabel basteln oder kaufen. 
+ 
+ 
+ 
+#on("b")#3.3  Verbindung Adapter - Interface-System#off("b")# 
+ 
+Nachdem Sie nun den Adapter (MUFI oder RS232-Adapter) an den Rechner ange­
+schlossen haben, müssen Sie noch die Verbindung zum Interface-System herstellen.
+Dabei ist es gleichgültig, ob Sie eine Compact-Box, einen Einzelsteckplatz oder einen
+Mehrfachsteckplatz benutzen, denn alle diese Geräte verfügen über den gleichen
+Anschlußstecker. Den RS232-Adapter können Sie direkt an das Interface-System
+anschließen, denn er verfügt bereits über einen entsprechenden Stecker. 
+ 
+Für das MUFI benötigen Sie ein Anschlußkabel, das auf der einen Seite einen
+36poligen Centronics-Stecker und auf der anderen Seite einen 25poligen D-Sub­
+miniatur-Stecker besitzt (von der Firma BICOS zu beziehen). 
+ 
+ 
+#on("b")#3.4  Bereitstellung des Interface-Systems#off("b")# 
+ 
+Sofern Sie eine Compact-Box angeschlossen haben, brauchen Sie nur noch das mitge­
+lieferte Netzteil mit der Compact-Box und dem Netz zu verbinden und die ent­
+sprechende Spannung laut beiliegender Bedienungsanweisung der Fa. AKTRONIK
+einzustellen. 
+ 
+Wenn Sie mit einem Einzelsteckplatz oder einem Mehrfachsteckplatz arbeiten,
+müssen Sie zunächst noch eine Interface-Karte einstecken. Für einen anschließenden
+Test des Systems (sehen Sie dazu Kapitel 5) empfiehlt es sich, eine Kombikarte oder
+eine E/A-Karte zu verwenden. Nach dem Einstecken der Interface-Karte ist der Steck­
+platz noch mit dem Netzstecker an das Stromnetz anzuschließen, um eine
+Spannungsversorgung zu gewährleisten. 
+
+
+
+
+
+
+
diff --git a/doc/prozess/gs-Prozess-4 b/doc/prozess/gs-Prozess-4
new file mode 100644
index 0000000..e106df1
--- /dev/null
+++ b/doc/prozess/gs-Prozess-4
@@ -0,0 +1,173 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess
+ 
+#end# 
+#center#1 
+ 
+#on("b")#4  Installation von gs-Prozess#off("b")# 
+ 
+ 
+Bevor Sie #on("b")#gs-Prozess#off("b")# auf Ihrem Computer benutzen können, müssen Sie das
+Programm zunächst installieren. Wenn #on("b")#gs-Prozess#off("b")# auf Ihrem System schon zur
+Verfügung steht, können Sie dieses Kapitel ruhig überspringen. 
+ 
+ 
+ 
+#on("b")#4.1  Voraussetzungen#off("b")# 
+ 
+ 
+Um #on("b")#gs-Prozess#off("b")# auf Ihrem Computer betreiben zu können, muß das EUMEL-
+Betriebssystem installiert sein. #on("b")#gs-Prozess#off("b")# setzt die Multi-User-Version voraus und ist
+lauffähig ab Version 1.8.x. #on("b")#gs-Prozess#off("b")# setzt weiterhin voraus, daß auf Ihrem
+Computer bereits das Programm #on("b")#gs-DIALOG#off("b")# (Version 1.1) installiert ist. 
+ 
+ 
+ 
+#on("b")#4.2  Lieferumfang#off("b")# 
+ 
+ 
+#on("b")#gs-Prozess#off("b")# wird auf einer Diskette geliefert, die alle notwendigen Programme ent­
+hält (die Installation von #on("b")#gs-DIALOG#off("b")# wird dabei vorausgesetzt!). Um den Inhalt der
+Diskette feststellen zu können, starten Sie Ihr System und bringen es dazu, daß 'gib
+kommando:' erscheint. Dann legen Sie die Diskette ein und geben das Kommando: 
+ 
+ 
+#on("b")##center#archive("gs-Prozess");list(archive);release(archive) <RETURN>#off("b")# 
+#page# 
+Anschließend erscheint eine Übersicht der auf dem Archiv vorhandenen Programme.
+Folgende Programme sollten sich in der Übersicht befinden: 
+ 
+ 
+         "gs-Prozess 1 für MUFI im Terminalkanal" 
+         "gs-Prozess 1 für MUFI als Endgerät" 
+         "gs-Prozess 1 für AKTRONIK Adapter" 
+         "gs-Prozess 2" 
+         "gs-Prozess 3" 
+         "gs-Prozess 4" 
+         "gs-Prozess 5" 
+         "gs-MENUKARTE:Prozess" 
+         "gs-Prozess/gen" 
+ 
+ 
+Eventuell können noch weitere Namen auf der Diskette vorhanden sein. Wenn Sie den
+Inhalt der Diskette kontrolliert haben und diese Programme auf der Diskette vor­
+handen sind, können Sie #on("b")#gs-Prozess#off("b")# installieren. 
+ 
+Sollten Sie statt der Übersicht eine Fehlermeldung erhalten, überprüfen Sie bitte, ob
+die Diskette das richtige Format besitzt oder ob Ihr Diskettenlaufwerk Probleme
+macht. Sollten dagegen Programme fehlen, so reklamieren Sie die Diskette. 
+ 
+ 
+#on("b")#4.3  Installation#off("b")# 
+ 
+#on("b")#gs-Prozess#off("b")# muß in einer Task installiert werden, in der bereits das Programm
+#on("b")#gs-DIALOG#off("b")# zur Verfügung steht. Alle Söhne und Enkel der neuen Task können
+anschließend mit #on("b")#gs-Prozess#off("b")# arbeiten. Richten Sie also eine Task als Sohn der Task
+ein, in der auf Ihrem Computer bereits #on("b")#gs-DIALOG#off("b")# installiert ist. Wir nehmen hier
+an, daß #on("b")#gs-DIALOG#off("b")# in der Task 'MENU' installiert ist und die neue Task den Namen
+'PDV' erhalten soll. (Sie können für die Task auch einen beliebigen anderen Namen
+wählen): 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+ 
+  -->     gib supervisor kommando: 
+ 
+          begin ("PDV","MENU") <RETURN> 
+ 
+  -->     gib kommando: 
+ 
+ 
+#off("b")# 
+(Arbeiten mehrere Personen mit dem Computer, dann ist es sinnvoll, diese Task vor
+unbefugtem Zugriff durch ein Passwort zu schützen. Wie das gemacht wird, können
+Sie in Ihrem EUMEL-Benutzerhandbuch erfahren.) 
+ 
+ 
+Legen Sie dann die Archivdiskette ein, auf der sich #on("b")#gs-Prozess#off("b")# befindet, und geben
+Sie das folgende Kommando: 
+ 
+ 
+#on("b")# 
+          archive("gs-Prozess") <RETURN> 
+ 
+          fetch("gs-Prozess/gen",archive) <RETURN> 
+ 
+          run <RETURN> 
+ 
+#off("b")# 
+ 
+Sie haben damit das Generatorprogramm gestartet. Bevor die Generierung allerdings
+ausgeführt werden kann, müssen Sie dem System noch Angaben über den ver­
+wendeten Adapter machen. Die zur Verfügung stehenden Anpassungen werden Ihnen
+zur Auswahl angeboten: 
+      +--------------------------------------------------------+
+      |          Auswahl der Interface-Anpassung               |
+      |       Bitte gewünschte Anpassung ankreuzen!            |
+      |--------------------------------------------------------|
+      | Auswahl  e i n e r  Datei durch Ankreuzen              |
+      |--------------------------------------------------------|
+      |==>   > gs-Prozess 1 für MUFI im Terminalkanal          |
+      |      > gs-Prozess 1 für MUFI als Endgerät              |
+      |      > gs-Prozess 1 für AKTRONIC-Adapter               |
+      |                                                        |
+      +--------------------------------------------------------|
+      |   Info: <?>    Fertig: <ESC><q>    Abbrechen: <ESC><h> |
+      +--------------------------------------------------------+
+#center#Abb.6:  Auswahl der Interface-Anpassung 
+ 
+ 
+Bringen Sie den Pfeil mit den Pfeiltasten vor die gewünschte Anpassung und drücken
+Sie die <RETURN>-Taste. 
+ 
+Haben Sie als Anpassung "gs-Prozess für AKTRONIK Adapter" oder "gs-Prozess für
+MUFI als Endgerät" gewählt, so erscheint als nächstes die Aufforderung: 
+ 
+#center##on("b")#'Gib Interface-Kanal:'#off("b")# 
+ 
+Geben Sie hier die Kanalnummer der seriellen Schnittstelle ein, an der der Adapter
+betrieben werden soll. 
+ 
+Die Installation wird automatisch durchgeführt. Lassen Sie während des gesamten
+Vorgangs die Archivdiskette eingelegt. Die Generierung ist beendet, wenn der
+EUMEL-Eingangsbildschirm erscheint. Die Task, in der die Generierung stattfin­
+det, wird automatisch zur Managertask, das heißt, daß Söhne von ihr eingerichtet
+werden können. 
+ 
+ 
+#on("b")#4.4  Anmerkungen zur Erstinstallation#off("b")# 
+ 
+Mit der Installation der Software ist das Gesamtsystem allerdings noch nicht betriebs­
+bereit. Dazu fehlen #on("b")#gs-Prozess#off("b")# noch einige Informationen. Bisher ist #on("b")#gs-Prozess#off("b")#
+nämlich nur bekannt, welchen Adapter Sie verwenden und ob Sie ihn im Terminal­
+kanal oder an einer separaten Schnittstelle betreiben wollen. 
+ 
+Um das angeschlossene Interface-System sachgerecht ansteuern zu können, benötigt
+#on("b")#gs-Prozess#off("b")# aber noch Informationen über die Hardware-Konstellation. Diese Mit­
+teilungen, die noch gemacht werden müssen, nennen wir "Konfiguration von
+#on("b")#gs-Prozess#off("b")#". Wie diese Konfiguration vorgenommen wird und wie Sie anschließend
+Ihr Interface-System testen, ist im Kapitel 5 detailliert beschrieben. 
+ 
+#on("b")#gs-Prozess#off("b")# bietet Ihnen eine Reihe von Möglichkeiten, die vorhandene Hardware
+möglichst effektiv zu nutzen. So ist es möglich, wenn Sie Ihre(n) Adapter an
+separater/separaten Schnittstelle(n) betreiben, von verschiedenen Tasks aus auf
+einen Adapter zuzugreifen. Gerade in der Anschaffungsphase, wenn noch nicht
+genügend Hardware zur Verfügung steht, ist das eine sinnvolle/preiswerte Möglich­
+keit, von verschiedenen Arbeitsplätzen aus Prozeßdatenverarbeitung zu betreiben. 
+ 
+Zu diesem Zeitpunkt würde es aber zu weit führen, hierzu Details zu erläutern.
+Beschreibungen dieser Möglichkeiten finden Sie im Kapitel "Hinweise für den
+Systembetreuer/ Programmierer". 
+ 
+#on("b")# 
+Sie sollten sich zunächst darauf beschränken, ein Interface-System "zum
+Laufen zu bringen". Verfahren Sie dazu bitte genau, wie im Kapitel 5
+beschrieben.#off("b")# 
+
diff --git a/doc/prozess/gs-prozess-1 b/doc/prozess/gs-prozess-1
new file mode 100644
index 0000000..f6a3696
--- /dev/null
+++ b/doc/prozess/gs-prozess-1
@@ -0,0 +1,99 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess
+ 
+#end# 
+#center#1 
+ 
+#on("b")#1  Was kann gs-Prozess#off("b")# 
+ 
+#on("b")#gs-Prozess#off("b")# ist ein Programmsystem unter dem Betriebssystem EUMEL, mit dem ein
+Anwendungsbereich erschlossen werden kann, der bisher in der Schule zumeist sehr
+stiefmütterlich behandelt wurde: die Prozeßdatenverarbeitung - das Messen, Steuern
+und Regeln mit dem Computer. 
+ 
+Es wird dadurch möglich, externe Modelle/Geräte (z.B. eine Ampelanlage) zu steuern
+oder von externen Meßfühlern (z.B. einem Temperaturfühler) oder Eingabeeinheiten
+(z.B. einem Lochkartenleser) Daten aufzunehmen. Durch die Kombination der
+beiden Vorgänge können sogar komplexe geregelte Systeme in Modellen nachgebildet
+werden. 
+ 
+Eigentlich ist eine solch stiefmütterliche Behandlung dieses Anwendungsbereiches
+von Computern in der Schule gar nicht einzusehen, denn in der Forschung, im
+Dienstleistungsbereich, im privaten Bereich und vor allem in der Produktion gibt es
+eine Vielzahl von Anwendungen, z.B.: 
+ 
+   Meßdatenerfassung und -auswertung bei Experimenten, Wetterbeobachtung,
+   seismologische Untersuchungen, ..., Ampelsteuerungen, Verkehrsleitsysteme, ...,
+   Scannerkassen, Scheckkartenleser, Geldautomaten, ..., Waschmaschinen,
+   Heizungsanlagen, Modelleisenbahnen, ..., CNC-Maschinen, Universalhand­
+   habungsautomaten (Roboter),... 
+ 
+In den meisten Fällen werden Computer eingesetzt, die speziell für diesen
+Anwendungsbereich entwickelt wurden. Insbesondere an die Verarbeitungsge­
+schwindigkeit solcher Systeme werden sehr hohe Anforderungen gestellt. Solche
+Systeme sind für die schulische Verwendung viel zu teuer. Zumeist sind auch die in
+der Realität ablaufenden Vorgänge so komplex, daß sie als Ganzes gar nicht im
+Unterricht nachgebildet werden können. 
+ 
+Das aber kann auch nicht Ziel einer Auseinandersetzung mit diesem Anwendungs­
+bereich in der Schule sein. Hier gilt es, unter didaktisch-methodischen Gesichts­
+punkten, Grundprinzipen der Prozeßdatenverarbeitung zu vermitteln und beispiel­
+hafte Anwendungen an Modellen zu erarbeiten und zu erproben. In einem zeitge­
+mäßen Informatikunterricht darf dieser wichtige Anwendungsbereich von Computern
+nicht ausgespart bleiben. 
+ 
+Bisher scheiterte das Messen, Steuern und Regeln mit dem Computer in der Schule
+meistens daran, daß es keine standardisierten Software- und Hardware-Systeme und
+auch keine geeigneten Modelle gab. Das aber hat sich inzwischen geändert.
+Verschiedene Hersteller bieten Interface-Systeme und Modelle an, die gut verwendet
+werden können. 
+ 
+Auch #on("b")#gs-Prozess#off("b")# greift auf ein solches Interface-System zu, das aus mehreren
+Einzelkomponenten besteht (mehr dazu in den folgenden Kapiteln). Das sind Geräte,
+über die der Computer "Kontakt" mit den 'Endgeräten' (z.B. Modellen) aufnimmt:
+Hier werden Ausgaben des Computers in "elektrische Impulse" umgesetzt, mit denen
+Modelle angesprochen werden können (z.B. Lämpchen ein- und ausgeschaltet,
+Motoren zu Drehungen nach links oder rechts veranlaßt werden können). Ein­
+gehende "Impulse" werden in "computerangemessene Form" umgewandelt und an
+den Computer weitergegeben. 
+ 
+Der Aufwand, der betrieben werden muß, um ein Interfacesystem sachgerecht anzu­
+steuern, ist erheblich. Es kostet einige Mühe und vor allem viel Zeit, um alle Details
+des Interfacesystems und seiner Programmierung kennenzulernen, und es gehört
+eine gehörige Portion Erfahrung und vor allem viel Geduld dazu, um Fehlfunktionen
+zu analysieren und letztlich zu beheben. Das alles ist einem Anwender, dem es z.B.
+darum geht, ein bestimmtes Modell anzusteuern, nicht zumutbar. 
+ 
+Hier schafft nun #on("b")#gs-Prozess#off("b")# Abhilfe! #on("b")#gs-Prozess#off("b")# ist eingebettet in die komfortable
+Benutzerschnittstelle #on("b")#gs-DIALOG#off("b")#, so daß der Einarbeitungsaufwand in das
+Programmsystem gering und eine einfache Bedienung des Systems gewährleistet ist. 
+ 
+Ähnlich wie bei #on("b")#gs-Herbert und Robbi#off("b")# wird eine komplette Programmier­
+umgebung zur Verfügung gestellt, die alle Funtionen enthält (Informationen,
+Konfiguration des Systems, Erstellung und Ausführung von Programmen, Archiv­
+handling), die bei der Arbeit von Bedeutung sein können - natürlich jetzt auf das
+Messen, Steuern und Regeln bezogen. Durch diese Programmierumgebung wird
+selbst dem Computerneuling ermöglicht, einen einfachen, eingängigen Zugang zu
+diesem Anwendungsbereich zu finden. 
+ 
+#on("b")#gs-Prozess#off("b")# stellt einen Basisbefehlssatz (Eingabe-, Ausgabebefehle und Tests) zur
+Verfügung, mit dessen Hilfe Lösungsalgorithmen aus diesem Anwendungsbereich
+angemessen formuliert werden können. Dabei kann sich der Anwender ganz auf sein
+Problem konzentrieren, da er sich um die spezifische Ansteuerung des Interfaces
+nicht zu kümmern braucht - das erledigt #on("b")#gs-Prozess#off("b")#. 
+ 
+Der Basisbefehlssatz besteht aus nur wenigen Befehlen, um das Erlernen und den
+Umgang damit möglichst einfach zu gestalten. Andererseits ist der Befehlssatz so
+umfangreich und universell, daß alle schulisch relevanten Problemstellungen aus
+diesem Anwendungsbereich angemessen bearbeitet werden können. 
+
+
+
+
diff --git a/doc/prozess/gs-prozess-5 b/doc/prozess/gs-prozess-5
new file mode 100644
index 0000000..5c44f29
--- /dev/null
+++ b/doc/prozess/gs-prozess-5
@@ -0,0 +1,819 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess
+ 
+#end# 
+#center#1 
+ 
+#on("b")#5  Konfiguration von gs-Prozess#off("b")# 
+#on("b")#    Test des Interface-Systems#off("b")# 
+ 
+In diesem Kapitel erfahren Sie, wie Sie #on("b")#gs-Prozess#off("b")# entsprechend der angeschlossenen
+Hardware konfigurieren müssen. Anschließend zeigen wir Ihnen, wie Sie Ihr Inter­
+face-System testen können. 
+ 
+Wir gehen hier davon aus, daß die Hardware-Voraussetzungen erfüllt, das Interface-
+System über einen Adapter (MUFI / RS232-Adapter) angeschlossen und #on("b")#gs-Prozess#off("b")#
+auf dem Rechner installiert sind. 
+ 
+ 
+#on("b")#5.1  Kontrolle der Konfigurationen/Anschlüsse#off("b")# 
+ 
+Bevor Sie mit der Arbeit beginnen, überzeugen Sie sich unbedingt (noch einmal)
+davon, daß die Konfigurationen und die Steckverbindungen den Vorgaben ent­
+sprechen: 
+ 
+-   #on("b")#MUFI im Terminalkanal:#off("b")# 
+ 
+    Sind die beiden Kabel zum Rechner und zum Terminal an der Rückseite des
+    MUFIs korrekt aufgesteckt (sehen Sie Abb.3)? Haben Sie die notwendigen
+    Konfigurationen vorgenommen (Task 'configurator', MUFI-DIP-Schalter, Ter­
+    minal)? Ist das Netzkabel des MUFIs mit dem Stromnetz verbunden? Ist das
+    Verbindungskabel zwischen MUFI und Interface-System an der Vorderseite des
+    MUFIs und am Interface-System (Compact-Box, Einzel- oder Mehrfachsteck­
+    platz) aufgesteckt? 
+#page# 
+-   #on("b")#MUFI als Endgerät:#off("b")# 
+ 
+    Ist das vom Computer kommende Kabel auf den mit V24/2 gekennzeichneten
+    Stecker aufgesteckt? Haben Sie auf den freien Stecker (V24/1) einen "Kurz­
+    schlußstecker" aufgesteckt? Haben Sie ein Kabel verwendet, über welches das
+    RTS/CTS-Protokoll abgewickelt werden kann? Haben Sie den Kanal, an dem das
+    MUFI betrieben wird, den Anweisungen in Kapitel 3.1.3 entsprechend kon­
+    figuriert? Sind die DIP-Schalter im MUFI entsprechend eingestellt? Ist das
+    Netzkabel des MUFIs mit dem Stromnetz verbunden? Ist das Verbindungskabel
+    zwischen MUFI und Interface-System an der Vorderseite des MUFIs und am
+    Interface-System (Compact-Box, Einzel- oder Mehrfachsteckplatz) aufgesteckt? 
+ 
+ 
+-   #on("b")#RS232-Adapter:#off("b")# 
+ 
+    Ist das Schnittstellen-Kabel korrekt am Computer angeschlossen? Haben Sie den
+    Kanal, an dem der RS232-Adapter betrieben wird, den Anweisungen in Kapitel
+    3.2 entsprechend konfiguriert? Ist der Jumper im RS232-Adapter korrekt aufge­
+    steckt? Ist der RS232-Adapter an das Interface-System (Compact-Box, Einzel-
+    oder Mehrfachsteckplatz) angesteckt? Ist der 3polige Platinenstecker des
+    Adapters in die 12V-Spannungsversorgungs-Buchse des Interface-Systems
+    eingesteckt? 
+ 
+ 
+-   #on("b")#Compact-Box#off("b")# 
+ 
+    Ist die Compact-Box an das zugehörige Netzgerät angeschlossen? Ist der Stecker
+    wirklich richtig herum eingesteckt? Ist das Netzteil mit dem Stromnetz ver­
+    bunden? 
+ 
+-   #on("b")#Einzelsteckplatz#off("b")# 
+ 
+    Ist eine Kombi-Karte oder eine E/A-Karte eingesteckt? Ist das Netzkabel des
+    Steckplatz-Netzgerätes mit dem Stromnetz verbunden? 
+#page# 
+-   #on("b")#Mehrfachsteckplatz#off("b")# 
+ 
+    Ist ein passendes Netzteil an den Mehrfachsteckplatz angeschlossen? Ist das
+    zugehörige Netzkabel mit dem Stromnetz verbunden? Ist eine Kombi- oder
+    E/A-Karte in einen Steckplatz eingesteckt? 
+ 
+ 
+#on("b")#5.2  Vorbereitungen für den Ein-/Ausgabetest#off("b")# 
+ 
+Für den Ausgabetest sollte eine 8elementige Leuchtdiodenanzeige zur Verfügung
+stehen, um am Interface-System die Ausgaben kontrollieren zu können. Sofern Sie
+mit der Compact-Box arbeiten oder eine E/A-Karte verwenden, brauchen Sie sich
+darum nicht weiter zu kümmern, denn in diese Systeme ist eine Leuchtdioden­
+anzeige integriert. Wenn Sie dagegen mit einer Kombikarte arbeiten, muß eine
+gesonderte Anzeige (kann leicht selbst gebaut werden oder ist fertig zu kaufen bei der
+Fa. AKTRONIK) angeschlossen werden. 
+ 
+Für den Eingabetest reicht ein kleines Drahtstück, an dem zwei kleine Lötschuhe
+angelötet sind - schön wäre es, wenn ein Codekarten-Leser zur Verfügung stünde. 
+ 
+ 
+#on("b")#5.2.1  Anschluß einer Leuchtdiodenanzeige an die Kombikarte#off("b")# 
+ 
+Stecken Sie den 8poligen Platinenstecker, der an der Leuchtdiodenanzeige befestigt
+ist, auf die mit "AUSG." gekennzeichnte Buchse der Kombikarte. Den Lötschuh des
+einzelnen Drahtes an der Leuchtdiodenanzeige stecken Sie auf den Masse-Lötstift
+direkt neben der "Ausgangs-Buchse" der Kombikarte (sehen Sie Abb. 7). Da die
+Leuchtdiodenanzeige mit Spannung versorgt werden muß, müssen jetzt noch zwei
+Kabel - wie in der Abb. 7 dargestellt (Kabel 1 und Kabel 2) - aufgesteckt werden. 
+#page# 
+
+ 
+ 
+      +---------------------------------------------------------------+
+      |        4-7                   o----------+                     |
+      |   +-+-----------+-+                     |                     |
+      |   | |     O     | |        GMD o        |                     |
+      |   | |           | |                     | Kabel 1             |
+      |   | |           | |                     |                     |
+      | v | |     O     | |                     |                     |
+      |   | |           | |                     |                     |
+      |  E| |           | |                     |                     |
+      |   | |     O     | |                     |                     |
+      |   +-+-------------+          ___________|                     |
+      |                            o -----------|                     |
+      |      Ausg.                              |                     |
+      |   +---------------+   O 0               |                     |
+      |   | +-----------+ |     1 O             |                    |
+   ---+---|-|---|       | |   O 2               |                     |
+   ---+---|-|---|       | |     3 O             |                     |
+   ---+---|-|---|       | |   O 4               |                     |
+   ---|---|-|---|       | |     5 O             |                     |
+   ---|---|-|---|       | |   O 6               |                     |
+   ---|---|-|---|       | |     7 O             |                     |
+      |   | +-----------+ |                     |                     |
+      |   +---------------+                     |                     |
+<-----------------o                             | Kabel 2             |
+ Zur Leuchtdiodenanzeige                        |                     |
+      |   +---------------+                     |                     |
+      |   |       O       |   O 0               |                     |
+      |   |       O       |     1 O             |                     |
+      |   |       O       |   O 2               |                     |
+      |   |       O       |     3 O             |                     |
+      |   |       O       |   O 4               |                     |
+      |   |       O       |     5 O             |                     |
+      |   |       O       |   O 6               |                     |
+      |   |       O       |     7 O             |                     |
+      |   +---------------+                     |                     |
+      |     GMD o  o  +5V                       |                     |
+      |            |                            |                     |
+      |            +----------------------------+                     |
+      |                                                               |
+      |   +---------------+                                           |
+      |   |      O        |      +  O                                 |
+      |   |      O        |   O E2                                    |
+      |   |      O        |     GMD O                                 |
+      |   +---------------+                                           |
+      |                                                               |
+      |   +---------------+                                           |
+      |   |      O        |      +  O                                 |
+      |   |      O        |   O E2                                    |
+      |   |      O        |     GMD O                                 |
+      |   +---------------+                                           |
+      |            o   o   o   o   o   o   o   o   o   o              |
+      |            |   |   |   |   |   |   |   |   |   |              |
+      |        +-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+          |
+      |        |                                           |          |
+      +----------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+----------+
+                 | | | | | | | | | | | | | | | | | | | | |
+                 | | | | | | | | | | | | | | | | | | | | |
+ 
+#center#Abb.7:  Anschluß Leuchtdiodenanzeige - Kombikarte 
+      
+#on("b")#ACHTUNG!#off("b")# Bei dieser Spannungversorgung auf der Kombikarte (+5V) darf #on("b")#auf
+keinen Fall#off("b")# eine größere Last (z.B. Motor oder auch nur eine Glühbirne) ange­
+schlossen werden, da dadurch die Interfacekarte bzw. das Netzteil im Einzelsteck­
+platz beschädigt werden könnte. 
+#page# 
+Möchten Sie eine größere Last anschließen, so benötigen Sie ein stabilisiertes Netzteil
+mit "ordentlich geglättetem" Gleichstrom. Die Masse (Minuspol) des Netztteils be­
+festigen Sie an dem Lötschuh (oder der davorliegenden Klemme), der zwischen den
+beiden Lötstiften liegt, an denen in der Abb.7 das Kabel 1 befestigt ist. Den Pluspol
+des Netzteiles verbinden Sie mit mit einem der Lötstifte (bzw. an der davorliegenden
+Klemme), auf dem jetzt das Kabel 1 befestigt ist. Damit alle 8 Ausgänge mit Span­
+nung versorgt werden, müssen Sie auch hier ebenfalls eine Brücke zum zweiten
+Lötschuh (oder der Klemme davor), an dem in der Zeichnung Kabel 1 befestigt ist,
+anbringen. 
+ 
+Da die Compact-Box ohnehin durch das Netzteil versorgt wird, kann es hier nicht zu
+Komplikationen kommen. Wollen Sie eine größere Last an die E/A-Karte anschließen,
+so benötigen Sie z.B. eine Relais-Box. 
+ 
+ 
+ 
+#on("b")#5.2.2  Anschluß des Codekartenlesers (Drahtstück)#off("b")# 
+ 
+Stecken Sie den 8poligen Platinenstecker, der am Codekartenleser befestigt ist, auf
+die Eingangsbuchse an Ihrem Interface-System. Dann muß noch der 3polige
+Platinenstecker, der ebenfalls am Codekartenleser befestigt ist, an die 12V-Span­
+nungsversorgungs-Buchse an Ihrem Interface-System aufgesteckt werden. 
+ 
+haben Sie keinen Codekartenleser zur Hand, so reicht für den Eingabetest auch ein
+kleines Kabelstück aus, an dessen Enden jeweils ein Lötschuh angelötet sein sollte.
+Stecken Sie den einen Lötschuh auf einen +5V-Lötstift Ihres Interface-Systems. Das
+andere Ende des Kabels wird zunächst noch nicht befestigt. 
+ 
+Auf der Kombikarte sind die +5V-Lötstifte beschriftet und damit leicht zu finden. Wo
+Sie einen +5V-Lötstift auf der E/A-Karte finden, können Sie der folgenden Abbildung
+entnehmen: 
+#page# 
+                                           Leuchtdiodenanzeige 
+                                                      |
+              +---------------------------------------+------------+
+              |   +---------------+                   |            |
+              |   |       O       |   O 0             V            |
+Digital-      |   |       O       |     1 O     o o o o o o o o    |
+Ausgang       |   |       O       |   O 2                          |
+              |   |       O       |     3 O                        |
+              |   |       O       |   O 4                          |
+              |   |       O       |     5 O                        |
+              |   |       O       |   O 6                          |
+              |   |       O       |     7 O                        |
+              |   +---------------+                                |
+              |   +---------------+                                |
+              |   |       O       |   O 0                          |
+Digital-      |   |       O       |     1 O                        |
+Eingang       |   |       O       |   O 2                          |
+              |   |       O       |     3 O                        |
+              |   |       O       |   O 4                          |
+              |   |       O       |     5 O                        |
+              |   |       O       |   O 6                          |
+              |   |       O       |     7 O                        |
+              |   +---------------+                                |
+              |   +---------------+                                |
+              |   |       O       |   O 0                          |
+Versorgungs-  |   |       O       |     1 O                        |
+und           |   |       O       |   O 2                          |
+Steuer-       |   |       O       |     3 O                        |
+leitung       |   |       O       |   O 4                          |
+              |   |       O       |     5 O                        |
+              |   |       O---5V------O 6                          |
+              |   |       O       |     7 O                        |
+              |   +-------|-------+       |                        |
+              |           |               |                        |
+              |           +---------------+                        |
+              |           |                                        |
+              |          GMD                                       |
+              |                                                    |
+              |        o   o   o   o   o   o   o   o   o   o       |
+              |        |   |   |   |   |   |   |   |   |   |       |
+              |    +-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+-o-+   |
+              |    |                                           |   |
+              +----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+---+
+                     | | | | | | | | | | | | | | | | | | | | |
+                     | | | | | | | | | | | | | | | | | | | | |
+ 
+ 
+#center#Abb.8:  Pinbelegung auf der E/A-Karte 
+ 
+ 
+#on("b")#5.3  Konfiguration von gs-Prozess#off("b")# 
+ 
+Normalerweise kann in jeder Task, in der #on("b")#gs-Prozess#off("b")# zur Verfügung steht, die
+Konfiguration vorgenommen werden (beachten Sie aber bitte die Bemerkungen im
+Kapitel "Hinweise für den Systembetreuer/Programmierer"). 
+ 
+Richten Sie eine Sohntask der Task ein, in der #on("b")#gs-Prozess#off("b")# installiert ist - in unserem
+Fall soll das die Task 'PDV' sein. Die Sohntask soll den Namen 'pdvtest' erhalten: 
+#page# 
+#on("b")# 
+             <SV>      (Supervisor - Taste) 
+#off("b")# 
+       -->   gib supervisor kommando: 
+#on("b")# 
+             begin ("pdvtest","PDV") <RETURN> 
+#off("b")# 
+       -->   gib kommando: 
+#on("b")# 
+             pdv <RETURN> 
+#off("b")# 
+ 
+Daraufhin erscheint der in Abb.9 dargestellte Menubildschirm. Über die Menupunkte
+im dann sichtbaren Pull-Down-Menu können Sie diverse Informationen zu
+#on("b")#gs-Prozess#off("b")# abrufen, auf die wir hier allerdings nicht weiter eingehen wollen. Statt­
+dessen drücken Sie bitte die 'Pfeiltaste rechts'. Sie gelangen so zum Menu unter dem
+Oberbegriff "Interface" (Abb. 10). 
+ 
+ 
++---------------------------------------------------------------------+
+|    PDV:  Info Interface Programm Archiv                             |
+|-------+------------------------+------------------------------------+
+|       | u  Übersicht Befehle   |                                    |
+|       | ---------------------  |                                    |
+|       | a  Ausgabebefehle      |                                    |
+|       | e  Eingabebefehle      |                                    |
+|       | t  Testbefehle         |                                    |
+|       | w  Weitere Befehle     |                                    |
+|       | ---------------------  |                                    |
+|       | b  Bitmuster           |                                    |
+|       | s  Symbole/Zeichen     |                                    |
+|       | d  Digital-/Analogwerte|                                    |
+|       +------------------------+                                    |
+|                                                                     |
+|                       +----------------------------------------+    |
+|                       |             gs-Prozess                 |    |
+|                       |             Version 1.0                |    |
+|                       |                                        |    |
+|                       |  Copyright Ρ 1988 bei Eva Latta-Weber, |    |
+|                       |                   Bielefeld            |    |
+|                       +----------------------------------------+    |
++---------------------------------------------------------------------+
+|Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>|
++---------------------------------------------------------------------+
+ 
+ 
+     Abb.9:  Eingangsbildschirm #on("b")#gs-Prozess#off("b")# 
+#page# 
+ 
++-----------------------------------------------------------------------+
+|    PDV:  Info Interface Programm Archiv                               |
++-------+-------------------+-------------------------------------------+
+|       | i  Informationen  |                                           |
+|       | ----------------  |                                           |
+|       | k  Konfigurieren  |                                           |
+|       | ----------------  |                                           |
+|       | a  Ausgabetest    |                                           |
+|       | e  Eingabetest    |                                           |
+|       +-------------------+                                           |
+|                                                                       |
+|                                                                       |
+|                                                                       |
++---------------------------------------------------------------------- +
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++-----------------------------------------------------------------------+
+
+ #center#Abb.10:  Menubildschirm zum Oberbegriff 'Interface' 
+ 
+ 
+Über den ersten Menupunkt ("Informationen") kann die aktuelle Konfiguration des
+Interfaces erfragt werden. Wenn Sie diesen Menupunkt aktivieren und es ist weder in
+dieser Task noch in einer übergeordneten Task eine Konfiguration vorgenommen
+worden, erhalten Sie die folgende Warnung: 
+ 
+         +----------------------------------------+
+         | Interface ist noch nicht konfiguriert! |
+         +----------------------------------------+
+#center#Abb.11:  Information bei unkonfiguriertem System 
+ 
+ 
+Ist schon eine Konfiguration, z.B. in der Vatertask vorgenommen worden, so wird
+Ihnen die aktuellen Einstellung angezeigt (s.u.). 
+#page# 
+#on("b")#5.3.1  Auswahl der Steckplatzart/Interfacekarte#off("b")# 
+ 
+Da Sie in jedem Falle eine Konfiguration von #on("b")#gs-Prozess#off("b")# vornehmen sollen,
+aktivieren Sie jetzt bitte den Menupunkt "Konfigurieren". Daraufhin erscheint die
+folgende Auswahl: 
+            +-----------------------------+
+            |  Auswahl der Steckplatzart  |
+            |                             |
+            |   c Compactbox              |
+            |   e Einzelsteckplatz        |
+            |   m Mehrfachsteckplatz      |
+            |                             |
+            | Compact   Einzel   Mehrfach |
+            +-----------------------------+
+ 
+#center#Abb.12:  Auswahl der Steckplatzart 
+ 
+ 
+Haben Sie eine Compact-Box angeschlossen, so ist die Konfiguration schnell erledigt:
+Sie tippen die Taste <c>. Daraufhin wird die komplette Konfiguration ausgeführt
+und die Einstellung eingeblendet. 
+                 +------------------------------------+
+                 |  Eingestellt: Compactbox           |
+                 |                                    |
+                 |  Belegung der Kanäle:              |
+                 |                                    |
+                 |  Kanal 1:   Analogeingang 1 (E1)   |
+                 |                                    |
+                 |  Kanal 2:   Analogeingang 2 (E2)   |
+                 |                                    |
+                 |  Kanal 3:   Digitaleingang         |
+                 |                                    |
+                 |  Kanal 4:   Digitalausgang         |
+                 +------------------------------------+
+ 
+#center#Abb.13:  Compact-Box: Belegung der Kanäle 
+#page# 
+Die Anzeige verschwindet, wenn Sie eine beliebige Taste tippen. 
+ 
+Anders dagegen, wenn Sie zuvor dem System mitgeteilt haben, daß ein Einzelsteck­
+platz bzw. ein Mehrfachsteckplatz angeschlossen ist. In diesem Fall müssen Sie
+#on("b")#gs-Prozess#off("b")# noch mitteilen, welche Steckkarten Sie verwenden. Dazu wird Ihnen die
+folgende Auswahl angeboten: 
+ 
+               +----------------------------------+
+               | Angabe der Interfacekarte:       |
+               |                                  |
+               |       k  Kombikarte              |
+               |       e  E/A - Karte             |
+               |       d  D/A - Wandler - Karte   |
+               |       a  A/D - Wandler - Karte   |
+               |       0  Keine Steckkarte        |
+               |                                  |
+               |    Kombi  E/A  D/A  A/D  Keine   |
+               +----------------------------------+
+ 
+ 
+#center#Abb.14:  Auswahl einer Interfacekarte 
+ 
+ 
+Wenn Sie eine Kombikarte, eine E/A-Karte oder eine D/A-Wandler-Karte verwenden,
+ist durch die jeweilige Angabe der Einstellvorgang abgeschlossen. #on("b")#gs-Prozess#off("b")# teilt
+Ihnen daraufhin - ähnlich wie bei der Compact-Box - jeweils die Belegung der Kanäle
+mit. Bei Nutzung der D/A-Wandler-Karte wird zusätzlich der gültige Spannungs­
+bereich angezeigt. 
+#page# 
+ 
+         +------------------------------------------------------+
+         |      Einzelsteckplatz mit D/A - Karte:               |
+         |                                                      |
+         |         Belegung der Kanäle:                         |
+         |                                                      |
+         | Die Karte stellt einen Analogausgang zur Verfügung,  |
+         | der auf zwei Arten angesprochen werden kann:         |
+         |                                                      |
+         |       Kanal 1:    Spannungsbereich  -5 V  -  +5 V    |
+         |                                                      |
+         |       Kanal 2:    Spannungsbereich   0 V  -  +5 V    |
+         |                                                      |
+         +------------------------------------------------------+
+ 
+#center#Abb.15:  Kanalbelegung D/A-Karte (Einzelsteckplatz) 
+ 
+ 
+Haben Sie dagegen eine A/D-Wandler-Karte angegeben, so erfragt #on("b")#gs-Prozess#off("b")# noch
+die Schalterstellung der DIP-Schalter auf der A/D-Wandler-Karte. Über diese Schalter­
+stellung kann der Spannungsbereich der Analogeingänge festgelegt werden. Das
+erfolgt nach folgendem Prinzip: 
+ 
+Das Spannungsintervall wird jeweils über 3 Schalter festgelegt. Für den Eingang 1
+stehen die Schalter 1, 2 und 3 zur Verfügung, für denn Eingang 2 die Schalter 4, 5
+und 6. Im folgenden werden wir die Einstellung für den Eingang 1 aufzeigen - für den
+Eingang 2 ist mit den drei genannten Schaltern synonym zu verfahren. 
+ 
+Steht Schalter 1 in der Position 'ON', so ist ein Spannungsintervall von 0V - 25V einge­
+stellt (Fall 1) - unabhängig von der Stellung der anderen beiden Schalter. Innerhalb
+eines Schaltertripletts "dominiert" nämlich ein Schalter mit kleinerer Nummer über
+den/die mit größerer Nummer.  Ist Schalter 1 in Stellung 'OFF' und Schalter 2 in
+Stellung 'ON', so ist ein Spannungsbereich von 0V - 2,5V eingestellt (Fall 2). Sind die
+beiden ersten Schalter in der Position 'OFF' und nur der Schalter 3 in der Position
+'ON', so ist ein Spannungsintervall von 0V - 0,25V eingestellt (Fall 3). 
+#page# 
+Eine besondere Bedeutung kommt noch den Schaltern 7 und 8 zu, denn sie beein­
+flussen noch die eben genannten Intervalle. Dabei ist überraschenderweise der
+Schalter 7 für den Eingang 2 und der Schalter 8 für den Eingang 1 zuständig. Die drei
+oben genannten Fälle gelten nämlich nur, wenn Schalter 8 in der Position 'OFF' steht.
+In der Position 'ON' werden die durch das Schaltertriplett eingestellten Spannungs­
+intervalle dagegen symmmetrisch um 0V angelegt: im Fall 1 also der Bereich von
+-12,5V - +12,5V, im Fall 2 von -1,25V - +1,25V und im Fall 3 von -0,125V -
++0,125V. 
+       +----------------------------------------------------+
+       | Angabe der Schalterstellungen auf der A/D - Karte: |
+       |                                                    |
+       | Bitte die aktuelle Schalterstellung eintragen:     |
+       |                                                    |
+       | Es bedeutet:  1 - Schalterstellung "on"            |
+       |                       0 - Schalterstellung "off"   |
+       |                                                    |
+       | Nummer:   12345678                                 |
+       |                                                    |
+       | Eingabe:  10010010                                 |
+       +----------------------------------------------------+
+#center#Abb.16:  A/D-Karte: Angabe der Schalterstellung 
+ 
+ 
+Der Spannungsbereich wird von #on("b")#gs-Prozess#off("b")# aus der Schalterstellung automatisch
+ermittelt und neben den festgelegten Kanalnummer angezeigt. Die obige Schalter­
+stellung führt somit zu folgender Meldung: 
+ 
+    +----------------------------------------------------------------+
+    |             Einzelsteckplatz mit A/D - Karte:                  |
+    |                                                                |
+    |             Zwei analoge Einträge stehen zur Vefügung:         |
+    |                                                                |
+    | Kanal 1:   (E1)   Spannungsbereich    0.000 V  -  +25.000 V    |
+    |                                                                |
+    | Kanal 2:   (E2)   Spannungsbereich  -12.500 V  -  +12.500 V    |
+    |                                                                |
+    +----------------------------------------------------------------+
+#center#Abb.17:  A/D-Karte: Kanalbel./Spannungsber.(Bspl.) 
+#page# 
+Während Sie bei Verwendung eines Einzelsteckplatzes nur einmal nach all diesen
+Angaben gefragt werden, erfolgt die Abfrage bei einem Mehrfachsteckplatz viermal
+hintereinander. Haben Sie einen Steckplatz nicht belegt, so tippen Sie bei der Angabe
+der Interfacekarte die Taste <0> (keine Steckkarte). 
+ 
+ 
+#on("b")#5.3.2  Bedeutung der Kanalnummern#off("b")# 
+ 
+Nachdem Sie #on("b")#gs-Prozess#off("b")# die Angaben zur Konfiguration (Steckplatzart/Interface­
+kartenart) mitgeteilt haben, teilt Ihnen das System jeweils die Kanalnummern mit.
+Diese Nummern sollten Sie sich merken, denn wenn Sie mit dem von #on("b")#gs-Prozess#off("b")# zur
+Verfügung gestellten Befehlen programmieren wollen, müssen Sie jeweils diese
+Kanalnummern angeben. Fordern Sie von einem Kanal eine Aktion, die nicht ausge­
+führt werden kann/nicht sinnvoll ist, so kann Ihnen dadurch eine Fehlermeldung
+zugestellt werden. 
+ 
+Auf der Compact-Box bzw. der Kombikarte an einem Einzelsteckplatz ist die
+Numerierung identisch: die beiden Analogeingänge haben die Kanalnummern 1 und
+2, der Digitaleingang hat die Nummer 3 und der Digitalausgang die Nummer 4. 
+ 
+Die E/A-Karte verfügt nur über je einen digitalen Eingang und digitalen Ausgang, die
+über die Kanäle 1 und 2 angesprochen werden können. Damit nun aber auch
+Programme, die für die Compact-Box bzw. eine Kombikarte geschrieben sind, auch
+auf der E/A-Karte laufen, können diese beiden Kanäle auch unter der Kanalnummer
+3 (Eingang) bzw. 4 (Ausgang) angesprochen werden. Natürlich ist ein solches
+Programm nur dann auf der E/A-Karte lauffähig, wenn keine Analogeingänge ange­
+sprochen werden, denn die sind ja auf der E/A-Karte gar nicht vorhanden! 
+ 
+Die Kanalnummern auf einem Mehrfachsteckplatz werden nach folgendem System
+vergeben: Die Kanalnummern sind immer zweistellig. Über die erste Ziffer wird der
+Steckplatz (1 - 4) identifiziert, über die zweite Ziffer der eigentliche Kanal auf der
+Steckkarte. Steckt also z.B. in Steckplatz 3 eine Kombikarte (4 mögliche Kanäle) und
+möchten Sie hier den Digitalausgang (Kanal 4) ansprechen, so muß als Kanal die
+Nummer 34 angegeben werden. 
+#page# 
+Aber auch hier gibt es eine zusätzliche Vereinbarung: Der erste Steckplatz eines
+Mehrfachsteckplatzes kann (zusätzlich) wie ein Einzelsteckplatz angesprochen
+werden. Bei Belegung des ersten Steckplatzes mit einer Kombikarte, können Sie die
+Karte also über die Kanalnummern 11, 12, 13 und 14 ansprechen und zusätzlich
+über die Nummern 1, 2, 3 und 4. Der Sinn der dahintersteckt ist Ihnen sicher sofort
+klar geworden: Dadurch kann ein Programm, das z.B. für die Compact-Box ge­
+schrieben wurde, ohne Änderung übernommen werden, wenn eine Kombikarte auf
+Steckplatz 1 des Mehrfachsteckplatzes steckt etc.. 
+ 
+ 
+#on("b")#5.4  Aus- und Eingabetest#off("b")# 
+ 
+Nun wird es spannend, denn Sie sollen jetzt testen, ob Sie mit Ihrem Interface-System
+arbeiten können. Sofern Sie mit dem MUFI als Adapter arbeiten, schalten Sie das
+MUFI mit dem Schalter an der Vorderseite ein. 
+ 
+Wenn Sie das MUFI im Terminalkanal betreiben, kann das Einschalten dazu führen,
+daß eine unsinnige Zeichenkette auf dem Bildschirm erscheint. Diese Zeichen
+werden durch den "Einschaltknack" verursacht und haben eigentlich nichts zu
+bedeuten. Allerdings läßt sich die Ausgabe auch nicht verhindern. Die Zeichen ver­
+schwinden bei der nächsten Menubedienung. 
+ 
+Wenn Sie alle Hinweise in Kapitel 5.1 beachtet haben, müßte spätestens jetzt das
+Interface-System betriebsbereit sein - gleichgültig, welchen Adapter und welche
+Interface-Komponenten Sie verwenden. 
+ 
+Aktivieren Sie nun den Menupunkt 'Ausgabetest', indem Sie z.B. die Taste <a>
+tippen. Wenn Sie eine Compact-Box angeschlossen haben, müßte die folgende Ein­
+blendung in Ihrem Menubildschirm erscheinen: 
+#page# 
+   +-------------------------------------------------------------+
+   |                        Ausgabetest                          |
+   |                                                             |
+   |  Ausgabe an Kanal 4 (= Digitalausgang der Compact-Box)      |
+   |-------------------------------------------------------------|
+   |                                                             |
+   |                                                             |
+   |                                                             |
+   |  Ausgabewert: 129                                           |
+   |                                                             |
+   |-------------------------------------------------------------|
+   |  Bitte einen Wert zwischen 0 und 255 eingeben!              |
+   |                                                             |
+   +-------------------------------------------------------------+
+#center#Abb.18:  Ausgabetest - Einblendung 
+ 
+ 
+Eine nahezu identische Einblendung erhalten Sie, wenn Sie einen Einzelsteckplatz
+mit Kombi- oder E/A-Karte angeschlossen haben. 
+ 
+Da beim Ausgabetest nur die Ausgänge einer Karte angesprochen werden, ist ein
+Ausgabetest an einer A/D-Wandler-Karte nicht möglich! An einer D/A-Wandler-Karte
+kann zwar prinzipiell ein Ausgabetest erfolgen - ist aber nicht sinnvoll, da die zur
+Kontrolle notwendige Leuchtdiodenanzeige hier nicht angeschlossen werden kann. 
+ 
+Wenn Sie einen Mehrfachsteckplatz angeschlossen haben, werden Sie zuvor noch
+gefragt, welchen Steckplatz Sie testen wollen. Bitte beachten Sie hier das im vorigen
+Abschnitt Gesagte. Ansonsten ist auch hier die anschließende Einblendung nahezu
+identisch. 
+ 
+Zum Testen geben Sie jetzt einige Werte zwischen 0 und 255 ein. Nach jeder Eingabe
+tippen Sie bitte die <RETURN>-Taste. Bei Eingabe der '0' müßten alle Leucht­
+dioden dunkel sein. Bei '1' dürfte nur die letzte Leuchtdiode (rechts) aufleuchten,
+bei 128 nur die erste (links); bei 255 müßten alle 8 Leuchtdioden der Anzeige auf­
+leuchten. 
+#page# 
+Sollten wider Erwarten Fehler aufgetreten sein, lesen Sie bitte im Kapitel 5.5 nach.
+Wenn alles wie beschrieben funktioniert hat, gehen Sie gleich zum Eingabetest über.
+Verlassen Sie dazu den Ausgabetest durch die Tastenfolge <ESC><q> und
+aktivieren Sie anschließend den Menupunkt 'Eingabetest' indem Sie z.B. die Taste
+<e> tippen. 
+ 
+Außer bei der E/A-Karte im Einzelsteckplatz werden Sie hier zusätzlich nach der
+Nummer des Kanals gefragt, über den der Einlesetest erfolgen soll. Das liegt daran,
+daß sich auf den meisten Interfacesystemen mehrere Eingänge befinden. Beim
+Einzelsteckplatz werden die Auswahlmöglichkeiten vorgegeben; beim Mehrfachsteck­
+platz erfolgt eine freie Eingabe der Kanalnummern. 
+ 
+Wenn Sie eine Compact-Box angeschlossen haben, müßte die folgende Einblendung
+in Ihrem Menubildschirm erscheinen: 
+ 
+   +-------------------------------------------------------------+
+   |                          Eingabetest                        |
+   |                                                             |
+   |   Eingabe von Kanal 3 (= Digitaleingang der Compact-Box)    |
+   |                                                             |
+   |-------------------------------------------------------------|
+   |                                                             |
+   |                                                             |
+   |   Eingelesener Wert: 129                                    |
+   |-------------------------------------------------------------|
+   |                                                             |
+   +-------------------------------------------------------------+
+ 
+#center#Abb.19:  Eingabetest - Einblendung 
+ 
+ 
+Wenn Sie den Codekartenleser am Digitaleingang angeschlossen haben und alles
+korrekt funktioniert, müßte als eingelesener Wert die Zahl 255 erscheinen. Legen Sie
+eine Lochkarte ein oder legen Sie einen Finger zwischen Beleuchtung und Licht­
+sensoren. Daraufhin müßte sich die Anzeige auf dem Bildschirm ändern. Nun
+können Sie versuchen, durch Abdecken der Sensoren die bei der Ausgabe schon
+angesprochenen Testwerte zu erhalten. 
+#page# 
+Wenn Sie über keinen Codekartenleser verfügen, so benutzen Sie jetzt bitte das kleine
+Kabelstück, das Sie auf den +5V-Lötschuh aufgesteckt haben und dessen anderes
+Ende bisher noch nirgendwo aufgesteckt ist. Berühren Sie nun mit diesem freien
+Ende die Stifte, die im 8poligen Eingangs-Platinenstecker sichbar sind. Wird kein Pin
+berührt, müßte auf dem Bildschirm der Wert '0' erscheinen. Berühren Sie einen der
+Pins an der Seite, müßte der Wert '1', berühren Sie den an der anderen Seite, müßte
+der Wert '128' erscheinen. Wenn Sie also nacheinander die Pins berühren, müßten
+die Zahlenwerte 1, 2, 4, 8, 16, 32, 64, 128 erscheinen. 
+ 
+Wenn sowohl Ausgabe- als auch Eingabetest korrekt abgewickelt werden konnten,
+brauchen Sie das Kapitel 5.5 nicht zu lesen, denn das beschäftigt sich nur mit
+Fehlern, die bisher aufgetreten sein könnten. Den Eingabetest verlassen Sie bitte
+durch die Tastenfolge <ESC><q>. 
+ 
+ 
+#on("b")#5.5  Mögliche Fehlerfälle#off("b")# 
+ 
+#on("b")# 
+-  Das MUFI wurde in den Terminalkanal eingebaut. Selbst beim vom Netz
+   getrennten MUFI ist kein Terminalbetrieb möglich: 
+#off("b")# 
+ 
+   -->  Das neu eingefügte Kabel ist unzureichend oder falsch verdrahtet. Bitte
+        Hinweise im MUFI-Handbuch lesen bzw. Informationen von BICOS ein­
+        holen. 
+ 
+ 
+#on("b")# 
+-  Das MUFI wurde in den Terminalkanal eingebaut. Beim Einschalten des
+   MUFIs erscheinen unsinnige Zeichenketten auf dem Bildschirm bzw. das
+   Einschalten hat noch schwerwiegendere Folgen: #off("b")# 
+ 
+   -->  Der "Einschaltknack" des MUFI "schlägt auf andere Systemkomponenten
+        durch". Sofern nur Zeichen auf dem Bildscchirm erscheinen, ist das weit­
+        gehend unproblematisch - kann auch nicht beseitigt werden. Ansonsten
+        erst das MUFI, dann das Terminal bzw. den Rechner einschalten. Ggf.
+        Rücksprache mit BICOS. 
+#page# 
+#on("b")# 
+-  Das MUFI wurde in den Terminalkanal eingebaut. Bei ausgeschaltetem
+   MUFI ist ein einwandfreier Terminalbetrieb möglich, bei einge­
+   schaltetem MUFI reagiert das Terminal nicht mehr: 
+#off("b")# 
+ 
+   -->  MUFI- und Terminalkonfiguration passen nicht zueinander (Baudrate,
+        Protokoll, Anzahl der Stopbits). Einstellungen am Terminal, in der Task
+        'configurator' und die DIP-Schalter-Stellung im MUFI kontrollieren; ggf.
+        Neueinstellung. 
+ 
+   -->  MUFI defekt - Rücksprache mit BICOS. 
+ 
+ 
+#on("b")# 
+-  Beim Austest erscheint die Einblendung "Interface ist noch nicht
+   konfiguriert!": 
+#off("b")# 
+ 
+   -->  #on("b")#gs-Prozess#off("b")# wurde noch nicht konfiguriert. Unter dem Oberbegriff 'Inter­
+        face' den Menupunkt 'Konfigurieren' aktivieren und den Ausführungen in
+        Kapitel 5.3 folgend die Konfiguration vornehmen. 
+ 
+   -->  Bei Betrieb des Interface Systems an separater serieller Schnittstelle werden
+        unbenannte Sohntasks eingerichtet (unter der eigenen Task bzw. unter
+        einer "zentralen Abwicklungstask"). Diese unbenannte Sohntask wurde
+        irrtümlich gelöscht. Abhilfe: Neukonfiguration vornehmen. #on("b")#*)#off("b")# 
+ 
+   -->  Bei Betrieb des Interface-Systems an separater serieller Schnittstelle und
+        "zentraler Abwicklungstask" wurde in der "zentralen Abwicklungs-Task"
+        eine Neukonfiguration von #on("b")#gs-Prozess#off("b")# vorgenommen. Die dabei ent­
+        standene unbenannte Sohntask wird von den "alten" Sohntasks nicht mehr
+        erkannt. Abhilfe: Alle Sohntasks, die auf die "zentrale Abwicklungstask"
+        zugreifen, löschen und neu einrichten. #on("b")#*)#off("b")# 
+#page# 
+#on("b")# 
+-  Es erscheint die Fehlermeldung "Interface meldet sich nicht!": 
+#off("b")# 
+ 
+   -->  Der angeschlossene Adapter ist ohne Spannungsversorgung. Netzstecker
+        des Adapters überprüfen. Beim MUFI den Schalter an der Vorderseite in
+        Stellung 'Ein' bringen. Beim RS232-Adapter den 3poligen Platinenstecker
+        in die 12V-Spannungsversorgungsbuchse am Interface-System einstecken. 
+ 
+   -->  Es wurde bei der Installation von #on("b")#gs-Prozess#off("b")# eine falsche Interface-
+        Kanal-Nummer angegeben. Die Kanalnummer kann mit 'put(interface­
+        kanal) <RETURN>' erfragt werden. Kanalnummer überprüfen. Ggf. neue
+        Kanalnummer angeben. Dafür steht die Prozedur 'PROC interfacekanal
+        (INT CONST nummer)' zur Verfügung. 
+ 
+   -->  Speziell beim MUFI: Das MUFI wurde zwischenzeitlich (versehentlich)
+        ausgeschaltet oder es kam zu einem "ungeregeltem Bedienungsabbruch"
+        z.B. durch Drücken der SV-Taste im laufenden Betrieb. Die interne Ein­
+        stellung des MUFIs ist verändert. Abhilfe: Menupunkt verlassen, MUFI
+        ausschalten, einige Sekunden warten, MUFI anschalten, Menupunkt neu
+        anwählen. 
+ 
+ 
+#on("b")# 
+-  Es erscheint die Fehlermeldung "Interface-Kanal ist belegt!: 
+#off("b")# 
+ 
+   -->  Das Interface-System ist an einer separaten seriellen Schnittstelle ange­
+        schlossen. Am Kanal wurden schon andere Geräte betrieben, die nicht
+        ordentlich abgemeldet wurden. Mit 'taskinfo (2) <RETURN>' kann die
+        Belegung der Kanäle eingesehen werden. Ggf. erst ein Terminal an den
+        Kanal anschließen (Kanal umkonfigurieren!) und dort 'break
+        <RETURN>' geben. Oder von einer privilegierten Task aus die ange­
+        koppelte Task "abschießen". 
+ 
+   -->  Das Interface-System ist an einer separaten seriellen Schnittstelle ange­
+        schlossen. Eine andere Task greift bereits auf das Interface-System am
+        eingestellten Kanal zu. Benutzer bitten, den Kanal freizugeben. #on("b")#*)#off("b")# 
+#page# 
+#on("b")# 
+-  Es erscheint die Fehlermeldung "Interface-Task ist besetzt!": 
+#off("b")# 
+ 
+   -->  Das Interface-System ist an einer separaten seriellen Schnittstelle ange­
+        schlossen. Die Kommunikation erfolgt über eine "zentrale Abwicklungs­
+        task". Auf diese Task greift zur Zeit ein anderer Benutzer zu. Mit dem
+        anderen Benutzer verständigen und warten, bis die Task freigegeben wird.
+        #on("b")#*)#off("b")# 
+ 
+ 
+#on("b")# 
+-  Es erschient die Fehlermeldung "An Kanal ... ist keine Digitaleingabe
+   (Digiatalausgabe, Analogeingabe, Analogausgabe) möglich!": 
+#off("b")# 
+ 
+   -->  Laut Konfiguration ist die gewünschte Leistung am angegebenen Kanal auf
+        der angeschlossenen Interfacekarte nicht möglich. Kanal neu konfigurieren
+        oder anderen Kanal ansprechen bzw. Interface-Karte wechseln und neu
+        konfigurieren. 
+ 
+ 
+#on("b")# 
+-  Es erschient die Fehlermeldung "Kanalnummer ... ist unzulässig!": 
+#off("b")# 
+ 
+   -->  Es wurde eine - bezogen auf das angeschlossene Interface-System - un­
+        sinnige Kanalnummer angegeben. Diese Fehlermeldung erscheint in jedem
+        Falle, wenn die Kanalnummer kleiner als 1 oder größer als 49 ist! Abhilfe:
+        korrekte Kanalnummer angeben. 
+ 
+ 
+#on("b")# 
+-  Es erschient die Fehlermeldung "Interface kann nicht geöffnet werden!": 
+#off("b")# 
+ 
+   -->  Interessanter Fehler! Bitte alle Details der Fehlersituation notieren und an
+        ERGOS einsenden! 
+#page# 
+#on("b")# 
+-  Beim Austest erscheint zwar keine Fehlermeldung, aber die Leucht­
+   diodenanzeige zeigt auf verschiedene Ausgabewerte keine Reaktion
+   (bleibt dunkel oder unsinnige fixe Anzeige): 
+#off("b")# 
+ 
+   -->  Die angeschlossene Leuchtdiodenanzeige ist nicht korrekt angeschlossen.
+        Platinenstecker (Digitalausgang) überprüfen; Massekabel überprüfen; die
+        beiden Überbrückungskabel (Abb.7) überprüfen. 
+ 
+   -->  Steckplatz/Compact-Box wird nicht mit Spannung versorgt. Netzkabel/An­
+        schluß zum Netzteil überprüfen. 
+ 
+   -->  Verbindungskabel Adapter - Interface-System nicht richtig aufgesteckt oder
+        intern falsch verdrahtet. 
+ 
+ 
+#on("b")# 
+-  Beim Austest erscheinen verschiedene Ausgabemuster an den Leucht­
+   dioden, die Muster sind aber nicht korrekt: 
+#off("b")# 
+ 
+   -->  Kabel vom Adapter zum Interface ist falsch verdrahtet. 
+ 
+   -->  Kabel in der Leuchtdiodenanzeige (Selbstbau ?) sind falsch verdrahtet. 
+ 
+ 
+#on("b")#*)#off("b")#  Die hier genannten Fehlermeldungen sind bei der oben beschriebenen Erst­
+    installation (noch) nicht möglich. Sie können erst auftreten, wenn weiter­
+    gehende Installationen erfolgt sind (z.B. Installation einer "zentralen Abwick­
+    lungs-Task" etc.). Zum Verständnis lesen Sie bitte das Kapitel "Hinweise für den
+    Systembetreuer/Programmierer". 
+
+
+
+
+
+
+
+
diff --git a/doc/prozess/gs-prozess-6 b/doc/prozess/gs-prozess-6
new file mode 100644
index 0000000..a3835cd
--- /dev/null
+++ b/doc/prozess/gs-prozess-6
@@ -0,0 +1,641 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess
+ 
+#end# 
+#center#1 
+ 
+#on("b")#6  Arbeiten mit gs-Prozess#off("b")# 
+ 
+In diesem Kapitel werden wir Ihnen die Basisbefehle von #on("b")#gs-Prozess#off("b")# vorstellen und
+erläutern, was die einzelnen Befehle bewirken. Dabei werden wir an einfachen
+Beispielen aufzeigen, wie Sie mit #on("b")#gs-Prozess#off("b")# arbeiten können. 
+ 
+Wir gehen hier davon aus, daß die Hardware-Voraussetzungen erfüllt, das Interface-
+System angeschlossen und die Software (#on("b")#gs-Prozess#off("b")#) auf dem Rechner installiert
+sind. Sie sollten #on("b")#gs-Prozess#off("b")# bereits konfiguriert und einen Ein- und Ausgabetest
+durchgeführt haben. 
+ 
+In unserer Beschreibung gehen wir weiterhin davon aus, daß als Interface-System
+eine Compact-Box verwendet wird. Alle hier beschriebenen Beispiele gelten ganz
+genauso für einen Einzelsteckplatz mit Kombikarte (hier müssen Sie nur zusätzlich
+eine Leuchtdiodenanzeige anschließen - aber Sie wissen ja schon, wie das gemacht
+wird.) Bei anderen Hardware-Konfigurationen ist darauf zu achten, daß ggf. andere
+Kanalnummern anzugeben sind. 
+ 
+Die Compact-Box verfügt - genau wie die Kombikarte - über zwei analoge Eingänge
+(Kanal 1 und Kanal 2), über einen digitalen Eingang (Kanal 3) sowie über einen
+digitalen Ausgang (Kanal 4). Wie Sie schon bei der Konfiguration von #on("b")#gs-Prozess#off("b")#
+gesehen haben, haben Sie keinen Einfluß auf die Numerierung der Kanäle - die wird
+vom #on("b")#gs-Prozess#off("b")# vorgegeben. Diese Kanalnummer müssen Sie kennen, wenn Sie das
+System ansprechen (programmieren) wollen (ggf. können Sie die Kanalnummern
+durch Aktivieren des Menupunktes 'Information' unter dem Oberbegriff 'Interface'
+erfragen). 
+ 
+ 
+#on("b")#6.1  Kleine Beispiele zur digitalen Ausgabe#off("b")# 
+ 
+Bei diesem Einführungsbeispiel wollen wir uns zunächst ausschließlich auf die
+digitale Ausgabe beschränken. Wenn Sie die Compact-Box (oder eine E/A-Karte)
+angeschlossen haben, benötigen Sie hierzu keine zusätzliche Hardware, ansonsten
+schließen Sie bitte an Ihren digitalen Ausgang eine 8-elementige Leuchtdiodenanzeige
+an. 
+#page# 
+Sie haben sicher schon an einer Autobahnbaustelle ein sogenanntes "Lauflicht"
+gesehen. Es erscheint, als ob ein Licht über die aufgestellten Barken hinwegläuft.
+Dadurch soll auf die Baustellenein- bzw. -ausfahrt hingewiesen werden. Dieser Effekt
+wird dadurch erreicht, daß die Lampen, die an den Barken angebracht sind, nach­
+einander ein- und auch wieder ausgeschaltet werden. 
+ 
+Wir wollen jetzt auf unserer 8-elementigen Leuchtdiodenanzeige ein solches Lauflicht
+nachbilden. Dabei soll das "Licht von rechts nach links über die Anzeige wandern". 
+ 
+Um das Programm zu schreiben, aktivieren Sie im #on("b")#gs-Prozess#off("b")#-Menu unter dem
+Oberbegriff "Programm" den Menupunkt "Neu erstellen". Sie werden dann nach
+einem Namen gefragt, den Sie der Programmdatei geben wollen. Tragen Sie hier
+einen beliebigen Namen ein, und tippen Sie anschließend die <RETURN>-Taste.
+Notieren Sie dann das folgende ELAN-Programm: 
+ 
+#on("b")# 
+     initialisiere interface; 
+     REP 
+        lauflichtdurchgang; 
+        warte (2.0) 
+     UNTIL abbruch gewuenscht PER. 
+ 
+     lauflichtdurchgang: 
+       bitmuster ausgeben (4, "OOOOOOOI"); 
+       bitmuster ausgeben (4, "OOOOOOIO"); 
+       bitmuster ausgeben (4, "OOOOOIOO"); 
+       bitmuster ausgeben (4, "OOOOIOOO"); 
+       bitmuster ausgeben (4, "OOOIOOOO"); 
+       bitmuster ausgeben (4, "OOIOOOOO"); 
+       bitmuster ausgeben (4, "OIOOOOOO"); 
+       bitmuster ausgeben (4, "IOOOOOOO") 
+#off("b")# 
+ 
+ 
+Wenn Sie das Programm fertiggeschrieben haben, verlassen Sie die Datei durch die
+Tastenfolge <ESC><q>. Sie gelangen wieder zum Menu und aktivieren jetzt den
+Menupunkt "Starten". Daraufhin wird das Programm übersetzt und ausgeführt. 
+#page# 
+#on("b")#6.1.1  Möglichkeit eines Programmabbruchs#off("b")# 
+ 
+Wir hoffen natürlich, daß das Programm genau die Ausgabe an der Leuchtdioden­
+anzeige erzeugt, die Sie erwartet haben. 
+ 
+Als Ausgangsbedingung der Schleife haben wir den Testbefehl 'abbruch gewuenscht'
+verwendet. Dieser Befehl wird von #on("b")#gs-Prozess#off("b")# zur Verfügung gestellt. Durch den
+Testbefehl wird überprüft, ab zwischenzeitlich die Tastenkombination <ESC><q>
+eingegeben wurde. Ist das bei unserem Programm der Fall, so wird die Schleife
+('regulär') beendet. 
+ 
+Aber bitte etwas Geduld: Das Programm wird nicht sofort nach Eingabe der Tasten­
+folge "abgebrochen". Hat nämlich gerade ein neuer 'lauflichtdurchgang' begonnen,
+so wird das Refinement natürlich erst vollständig abgearbeitet. Erst dann wird
+geprüft, ob die Tastenfolge zwischenzeitlich eingegeben wurde. 
+ 
+Sollten Sie einmal in einer Situation sein, in der Sie ein Programm tatsächlich
+abbrechen müssen, so ist das (in den meisten Fällen) über die Tastenfolge
+<ESC><h> möglich. Diese Tastenkombination sollten Sie sich für "Notfälle"
+merken. Vielleicht probieren Sie sie gleich an unserem Beispiel aus. 
+ 
+ 
+#on("b")#6.1.2  Die "sonstigen" Befehle#off("b")# 
+ 
+Gehen wir zunächst auf die beiden Befehle 'initialisiere interface' und 'warte' sowie
+auf den Testbefehl 'abbruch gewuenscht ein: 
+ 
+#on("b")# 
+PROC initialisiere interface 
+#off("b")# 
+ 
+   Jedes Programm zur Prozeßdatenverarbeitung, das auf das Interface-System
+   zugreift, sollte mit diesem Befehl beginnen. Durch diesen Befehl wird das System
+   in einen definierten Anfangszustand versetzt; systeminterne Variablen werden
+   initialisiert, so daß vom Programm aus darauf zugegriffen werden kann. 
+#page# 
+#on("b")# 
+PROC warte (REAL CONST wert) 
+PROC warte (INT CONST wert) 
+#off("b")# 
+ 
+   Der Befehl 'warte' ähnelt dem Ihnen sicher bekannten Befehl 'pause'. Allerdings
+   wird hier als Parameter (INT oder REAL) die Wartezeit in Sekunden angegeben -
+   bei 'pause' dagegen die Anzahl der Zehntelsekunden. Der eigentliche Unterschied
+   besteht aber darin, daß 'warte' im Gegensatz zu 'pause' ein "Nothalt" - d.h. die
+   Tastenkombination <ESC><h>, die wir im vorigen Kapitel beschrieben haben
+   - registriert. Aus diesem Grunde sollte in Prozeßdatenverarbeitungsprogrammen
+   mit 'warte' statt mit 'pause' gearbeitet werden. 
+ 
+ 
+#on("b")# 
+BOOL PROC abbruch gewuenscht 
+#off("b")# 
+ 
+   Die Prozedur liefert den Wert 'TRUE', wenn zwischenzeitlich die Tasten­
+   kombination <ESC><q> eingegeben wurde, sonst den Wert 'FALSE'. 
+ 
+ 
+#on("b")#6.1.3  Schreibweise für Bitmuster/Bitsymbole#off("b")# 
+ 
+Beim Befehl 'bitmuster ausgeben', wird eine Zeichenkette, die aus 8 Zeichen besteht,
+übergeben - das sog. Bitmsuster. In unserem Falle kommen hier nur die Zeichen 'I'
+und 'O' vor. Ihnen ist sicher die Bedeutung sofort klar gewesen: 
+ 
+   'I'  bedeutet, daß an der entsprechenden Position ein High-Pegel (5V) angelegt
+        werden soll; 'O' bedeutet, daß an der entsprechenden Position ein Low-
+        Pegel (0V) angelegt werden soll. 
+ 
+So werden über den ersten Befehl im Refinement 'lauflichtdurchgang' alle Leucht­
+dioden ausgeschaltet, nur die Leuchtdiode ganz rechts wird angeschaltet. Über den
+zweiten Befehl wird diese wieder ausgeschaltet und dafür aber die zweite von rechts
+eingeschaltet usw. 
+#page# 
+Neben den Zeichen 'I' und 'O' dürfen auch die Zeichen 'X' und 'T' in der über­
+gebenen Zeichenkette auftauchen. Um die Bedeutung zu verstehen, muß man
+wissen, daß #on("b")#gs-Prozess#off("b")# den jeweils letzten Zustand des digitalen Ausgangs speichert
+(durch 'initialisiere interface' werden alle Ausgänge auf 'O' gesetzt). 
+ 
+   'X'  bedeutet, daß an der entsprechenden Position der zuletzt dagewesene
+        Zustand erhalten bleibt, d.h. durch diese Ausgabe nicht beeinflußt wird. 
+ 
+   'T'  bedeutet, daß an der entsprechenden Position der zuletzt dagewesene
+        Zustand "umgekehrt" wird. Lag zuletzt ein Low-Pegel (O) an, so wird
+        daraus ein High-Pegel (I) und umgekehrt. 
+ 
+Sie können sich nun sicher sofort erklären, was das folgende Programm bewirkt: 
+ 
+ 
+#on("b")# 
+    initialisiere interface; 
+    bitmuster ausgeben (4, "OIOIOIOI"); 
+    REP 
+      bitmuster ausgeben (4, "TTTTTTTT"); 
+      warte (1) 
+    UNTIL abbruch gewuenscht PER 
+#off("b")# 
+ 
+ 
+Durch den ersten Befehl 'bitmuster ausgeben' wird jede zweite Leuchtdiode ange­
+schaltet, die anderen werden ausgeschaltet. Durch den zweiten Befehl in der Schleife
+wird nun jeweils jeder Zustand in "das Gegenteil umgekehrt", so daß ein Blinklicht
+entsteht, bei dem abwechselnd einmal die einen vier, dann die anderen vier Leucht­
+dioden aufleuchten - und das jeweils für eine Sekunde. 
+ 
+ 
+#on("b")#6.1.4  Befehle für die digitale Ausgabe#off("b")# 
+ 
+Einen Befehl, mit dem der digitale Ausgang des Interfaces angesprochen werden
+kann, haben Sie schon in Kapitel 6.1 kennengelernt: 
+#page# 
+#on("b")# 
+PROC bitmuster ausgeben (INT CONST kanal, 
+                         TEXT CONST zeichenkette) 
+#off("b")# 
+ 
+Über den ersten Parameter wird der Kanal angegeben, über den der digitale Ausgang
+angesprochen werden kann; bei uns ist das der Kanal 4 auf der Compact-Box. Über
+den zweiten Parameter wird das sogenannte Bitmuster übergeben; ein Text, der aus
+genau 8 Zeichen besteht. Dabei dürfen die Zeichen "I, O, X und T verwendet werden
+(sehen Sie dazu auch Kapitel 6.1.3). 
+ 
+#on("b")#gs-Prozess#off("b")# stellt noch zwei weitere Befehle für die digitale Ausgabe zur Verfügung.
+Um die Wirkungsweise der Befehle zu verdeutlichen, hier das erste Beispiel (das
+Lauflicht) in einer zweiten Version: 
+ 
+#on("b")# 
+   initialisiere interface; 
+   REP 
+      lauflichtdurchgang; 
+      warte (2.0) 
+   UNTIL abbruch gewuenscht PER. 
+ 
+   lauflichtdurchgang: 
+     INT VAR zeiger; 
+     FOR zeiger FROM 0 UPTO 7 REP 
+        schalte aktuelle leichtdiode an; 
+        schalte vorgaenger aus 
+     PER. 
+ 
+   schalte aktuelle leuchtdiode an: 
+     bitsymbol ausgeben (4, zeiger, "I"). 
+ 
+   schalte vorgaenger aus: 
+     IF zeiger = 0 
+        THEN bitsymbol ausgeben (4, 7, "O") 
+        ELSE bitsymbol ausgeben (4, zeiger - 1, "O") 
+     FI. 
+#off("b")# 
+ 
+#on("b")# 
+PROC bitsymbol ausgeben (INT CONST kanal, bitnummer, 
+                         TEXT CONST zeichen) 
+#off("b")# 
+#page# 
+Während durch den Befehl 'bitmuster ausgeben' auf alle 8 Ausgänge gleichzeitig
+Einfluß genommen werden kann, wird mit dem Befehl 'bitsymbol ausgeben' gezielt
+nur genau einer der 8 Ausgänge, d.h. eines der 8 Bits manipuliert. Welcher Ausgang /
+welches Bit manipuliert werden soll, wird über den zweiten Parameter festgelegt: hier
+kann einer der Werte 0...7 angegeben werden (Beachten Sie die Numerierung der
+Ausgänge (!)). 
+ 
+Als dritter Parameter wird ein Text übergeben, der aus genau einem Zeichen
+bestehen muß. Ebenso wie beim Befehl 'bitmuster ausgeben' sind hier die Zeichen I,
+O, X und T zulässig. Sie haben hier auch die gleiche Bedeutung. 
+ 
+Mit dem dritten Ausgabebefehl für den digitalen Ausgang können wir das Beispiel
+noch in einer dritten Version notieren: 
+ 
+#on("b")# 
+   initialisiere interface; 
+   REP 
+      lauflichtdurchgang; 
+      warte (2.0) 
+   UNTIL abbruch gewuenscht PER. 
+ 
+   lauflichtdurchgang: 
+     INT VAR wert :: 1; 
+     REP 
+       dezimalwert ausgeben (4, wert); 
+       wert := 2 * wert 
+     UNTIL wert > 128 PER. 
+#off("b")# 
+ 
+#on("b")# 
+PROC dezimalwert ausgeben (INT CONST kanal, wert) 
+#off("b")# 
+ 
+'wert' kann Werte zwischen 0 und 255 annehmen. Das zugehörige Bitmuster wird
+dann am angegebenen Kanal ausgegeben. Anhand dieses Befehls wird Ihnen sicher
+auch klar, warum gerade die oben beschriebene Numerierung der Bits gewählt
+wurde. 
+#page# 
+#on("b")#6.1.5  Befehle für die analoge Ausgabe#off("b")# 
+ 
+Neben der 'digitalen' Ausgabe ist auch eine 'analoge' Ausgabe möglich. Allerdings
+wollen wir die Beschreibung der Befehle an dieser Stelle sehr kurz halten, denn eine
+"analoge" Ausgabe ist nur möglich, wenn Sie eine D/A-Karte besitzen. 
+ 
+Auf der D/A-Karte steht nur ein physikalischer Ausgabekanal zur Verfügung, der von
+#on("b")#gs-Prozess#off("b")# jedoch über zwei Kanalnummern angesprochen werden kann. 
+ 
+Über den Ausgabekanal 1 können Spannungswerte zwischen -5V und +5V aus­
+gegeben werden, über den Ausgabekanal 2 Spannungswerte zwischen 0V und +5V. 
+ 
+Dafür stellt #on("b")#gs-Prozess#off("b")# zwei Befehle bereit: 
+ 
+#on("b")# 
+PROC spannungswert ausgeben (INT  CONST kanal, 
+                             REAL CONST wert) 
+#off("b")# 
+ 
+'wert' kann, in Abhängigkeit vom angegebenen Kanal, Werte zwischen -5.0 und +5.0
+(bei Kanal 1) bzw. 0.0 und +5.0 (bei Kanal 2) annehmen. Bei dem Versuch, Werte
+außerhalb dieser Grenzen anzugeben, erhalten Sie die Fehlermeldung "Der
+Spannungswert ... ist nicht zulässig!". 
+ 
+ 
+#on("b")# 
+PROC wert an analogausgang ausgeben (INT CONST kanal, wert) 
+#off("b")# 
+ 
+Für 'wert' kann eine Zahl zwischen 0 und 255 angegeben werden. Dabei wird 0 auf
+den kleinstmöglichen Spannungswert am jeweilgen Kanal (bei Kanal 1 also auf -5V,
+bei Kanal 2 auf 0V) und 255 auf den größtmöglichen Spannungswert am jeweilgen
+Kanal (bei beiden Kanälen auf +5V) abgebildet. Das Intervall zwischen kleinst- und
+größtmöglichem Spannungswert wird in 255 gleichgroße Teilintervalle eingeteilt. Es
+wird nun die Spannung ausgegeben, die der Intervallnummer entspricht. 
+Anmerkung: Dieser Befehl hat nur einen "geringen praktischen Nutzwert"; er dient
+           vornehmlich dazu, den Wandlungsprozeß zu verdeutlichen. 
+#page# 
+#on("b")#6.2  Kleine Beispiele zur digitalen Eingabe#off("b")# 
+ 
+Für die im folgenden beschriebenen kleinen Beispiele benötigen Sie einen Code­
+kartenleser und einige Codekarten (können auch von der Fa. AKTRONIK bezogen
+werden). Der Anschluß des Codekartenlesers an Ihr Interface-System ist denkbar
+einfach. Stecken Sie den 8poligen Platinenstecker des Codekartenlesers in die Buchse
+des Digitaleinganges der Steckkarte bzw. der Compact-Box und den 3poligen
+Platinenstecker in die passende Spannungsversorgungsbuchse (12V) am Steckplatz
+bzw. auf der Compact-Box - fertig! Bei eingeschalteter Betriebsspannung müßte nun
+der Codekartenleser beleuchtet sein. 
+ 
+Auf den Lochkarten sind bis zu 8 Löcher eingestanzt. Dabei können bestimmte
+Löcher (Bits) für die Erfassung definierter Merkmale verwendet werden. Dazu kann
+eine Karte in bestimmte Bereiche aufgeteilt werden. 
+ 
+In unserem kleinen Beispiel stellen wir uns vor, daß eine (Modell-)Sparkasse zwei
+Filialen hat. Sie hat an Ihre "Kunden" Codekarten verteilt. Die Filialen sind durch
+Farben gekennzeichnet. Die oberen (höchstwertigen) zwei Bits der Karte sollen diese
+Farbe kodiert enthalten, damit auch der "Sparkassen-Computer" die Farbe schnell
+ermitteln kann. Die Karte soll folgenden Aufbau haben: 
+ 
+           +---------------------------------+
+           |   O   o   o   O   o   o   O     |
+           |              |                  |
+           |      Farbbits| Kundennummer     |
+           |              |                  |
+           |              |                  |
+           |              |                  |
+           |                                 |
+           +---------------------------------+
+ 
+ 
+#center#Abb.20  Beispiellochkarte 
+#page# 
+Bit 7 sei für rote, Bit 6 für grüne Farbe gesetzt, d.h. gelocht. Wie wollen jetzt ein
+Programm erstellen, das auf Eingabe einer Karte deren Farbe und den durch die
+ersten 6 Bits bestimmten Wert (Kundennummer) ausgibt: 
+ 
+#on("b")# 
+   initialisiere interface; 
+   REP 
+     erfasse lochkarte 
+   UNTIL abbruch gewuenscht PER. 
+ 
+   erfasse lochkarte: 
+     warte bis karte im leser; 
+     gib farbe aus; 
+     gib kundennummer aus; 
+     warte bis keine karte im leser. 
+ 
+   warte bis karte im leser: 
+     put ("Bitte eine Codekarte einlegen!"); line; 
+     WHILE NOT alles abgedunkelt REP 
+        tue nichts 
+     END REP; 
+     WHILE alles abgedunkelt REP 
+        tue nichts 
+     END REP; 
+     warte (1). 
+ 
+   warte bis keine karte im leser: 
+     put ("Bitte die Karte entnehmen!"); 
+     REP 
+       tue nichts 
+     UNTIL alles beleuchtet PER. 
+ 
+   alles abgedunkelt: 
+     bitmuster (3) = "OOOOOOOO". 
+ 
+   alles beleuchtet: 
+     bitmuster (3) = "IIIIIIII". 
+ 
+   gib farbe aus: 
+     IF bitsymbol (3, 7) = "I" 
+        THEN put ("rote Karte"); line 
+        ELSE put ("grüne Karte");line 
+     FI; 
+#page# 
+   gib kundennummer aus: 
+     INT VAR kundennummer :: 0, bitnummer; 
+     FOR bitnummer FROM 0 UPTO 5 REP 
+       registriere gesetztes bit 
+     PER; 
+     put ("Kundennummer:"); put (kundennummer): line. 
+ 
+   registriere gesetztes bit: 
+     IF bit ist gesetzt (3, bitnummer) 
+        THEN kundennummer INCR (2 ** bitnummer) 
+     FI. 
+ 
+ 
+#off("b")# 
+   (Hinweis: Es handelt sich hier um ein Beispielprogramm, an dem diverse
+             Befehle erläutert werden sollen - die Programmierung ist nicht
+             optimal! Im Refinement 'warte bis karte im leser' ist es z.B.
+             günstiger, solange einzulesen, bis der eingelesene Wert "stabil" ist.
+             Auch das Refinement 'registriere gesetztes bit' würde man so nicht
+             programmieren, sondern nach einem Einlesevorgang (Bitmuster)
+             über Textoperationen aus dem Bitmuster die 'kundennummer'
+             ermitteln...). 
+ 
+Bevor wir Ihnen die Funktionsweise der von #on("b")#gs-Prozess#off("b")# bereitgestellten Prozeduren
+im Detail erläutern, möchten wir Ihnen noch ein paar kurze Erläuterungen zum
+obigen Programm geben. 
+ 
+Besondere Aufmerksamkeit sollten Sie den Refinements 'warte bis karte im leser' und
+'warte bis keine karte im leser' schenken. Im erstgenannten Refinement ist sicherzu­
+stellen, daß das Einschieben der Karte (erst muß alles abgedunkelt werden - dann
+müssen einige Positionen beleuchtet sein) registriert wird. Um Fehlauswertungen der
+Karte zu vermeiden (z.B. beim Verkanten einer Karte) wird zur Sicherheit vor der
+Auswertung eine Sekunde gewartet. Am Ende des Lesevorgangs soll sichergestellt
+werden, daß die Karte auch entnommen worden ist (alle Positionen wieder beleuchtet
+sind). 
+#page# 
+Wir prüfen im Refinement 'gib farbe aus' nur das 7. Bit (sehen Sie die Erklärung zu
+'bitsymbol'). Ist das Bit gesetzt (die Karte hier gelocht), so identifizieren wir die Farbe
+Rot, sonst Grün. Natürlich ist es möglich, mit 2 "Farbbits" vier Farben zu ver­
+schlüsseln: z.B. Rot, wenn nur Bit 7 gesetzt ist; Grün, wenn nur Bit 6 gesetzt ist; Blau,
+wenn Bit 7 und Bit 6 gesetzt sind; Gelb, wenn weder Bit 7 noch Bit 6 gesetzt sind.
+Dadurch wird der Auswertalgorithmus aber etwas aufwendiger. Vielleicht probieren
+Sie es nacher einmal. 
+ 
+Die Prozedur 'tue nichts' wird schon von #on("b")#gs-Prozess#off("b")# bereitgestellt. Es wird keine
+Aktion ausgeführt - jedoch überprüft, ob zwischenzeitlich die Tastenfolge
+<ESC><h> ("Notbremse") eingegeben wurde. Es empfiehlt sich, diese Prozedur
+gerade in Schleifenrümpfen einzusetzten, damit die Möglichkeit besteht, bei einer
+"Endlosschleife" einen Abbruch herbeizuführen (sonst "hängt" die Task ggf. am
+Interfacekanal)! 
+ 
+ 
+#on("b")#6.2.1  Befehle für die digitale Eingabe#off("b")# 
+ 
+In Kapitel 6.1.4 haben Sie die Befehle für die digitale Ausgabe kennengelernt, die
+Ihnen #on("b")#gs-Prozess#off("b")# zur Verfügung stellt. Zu jedem dieser drei Befehle gibt es das
+"Gegenstück" auch als Eingabebefehl. Alle Eingabebefehle sind als werteliefernde
+Prozeduren (Funktionen) ausgelegt. 
+ 
+In den Refinements 'alles abgedunkelt' und 'alles beleuchtet' benutzen wir den
+Befehl: 
+ 
+#on("b")# 
+TEXT PROC bitmuster (INT CONST kanal) 
+#off("b")# 
+ 
+Über den Parameter wird der Kanal angegeben, über den der digitale Eingang ange­
+sprochen werden kann; bei uns ist das der Kanal 3 auf der Compact-Box. Die
+Prozedur liefert einen Text, der aus acht Zeichen besteht. Dabei können nur die
+Zeichen "I und "O" auftreten (sehen Sie dazu auch Kapitel 6.1.3). 
+#page# 
+Die beiden gerade genannten Refinements hätten aber auch so notiert werden
+können: 
+ 
+#on("b")# 
+  alles abgedunkelt: 
+    dezimalwert (3) = 0. 
+ 
+  alles beleuchtet: 
+    dezimalwert (3) = 255. 
+#off("b")# 
+ 
+#on("b")# 
+INT PROC dezimalwert (INT CONST kanal) 
+#off("b")# 
+ 
+Über den Parameter wird der Kanal angegeben, über den der digitale Eingang ange­
+sprochen werden kann; bei uns ist das wieder der Kanal 3 auf der Compact-Box. Die
+Prozedur liefert einen Integer-Wert zwischen 0 und 255 (sehen Sie dazu auch unter
+'dezimalwert ausgeben' im Kapitel 6.1.4). 
+ 
+Den dritten Eingabebefehl für den Digitaleingang, den #on("b")#gs-Prozess#off("b")# bereitstellt, finden
+Sie im Refinement 'gib farbe aus': 
+ 
+#on("b")# 
+TEXT PROC bitsymbol (INT CONST kanal, bitnummer) 
+#off("b")# 
+ 
+Wie schon bei den anderen beiden Eingabebefehlen wird hier über den ersten
+Parameter der Eingabekanal festgelegt; bei uns auf der Compact-Box ist das wieder
+der Kanal 3. Über den zweiten Parameter wird die Nummer des Bits angegeben,
+dessen Wert ermittelt werden soll. Ist das betreffende Bit gesetzt, so liefert die
+Prozedur das Zeichen "I", sonst das Zeichen "O" (sehen Sie dazu auch das Kapitel
+6.1.3 'Schreibweise für Bitmuster/Bitsymbole'). 
+ 
+ 
+#on("b")#6.2.2  Eingabetests#off("b")# 
+ 
+Neben diesen drei Eingabebefehlen stellt #on("b")#gs-Prozess#off("b")# noch zwei Testbefehle zur
+Verfügung, die man häufig gut verwenden kann. Auf einen greifen wir schon im
+Refinement 'registriere gesetztes bit' zurück: 
+#page# 
+#on("b")# 
+BOOL PROC bit ist gesetzt (INT CONST kanal, bitnummer) 
+#off("b")# 
+ 
+Die Parameter sind die gleichen wie beim Befehl 'bitsymbol'. Zunächst liest die
+Prozedur die aktuelle Einstellung am angegebenen Digitaleingang ('kanal') ein und
+untersucht dann das Bit mit der angegebenen Bitnummer (0, ..., 7). Die Prozedur
+liefert den Wert 'TRUE', wenn das Bit mit der entsprechenden Bitnummer gesetzt ist
+(die Prozedur bitsymbol' mit gleichen Parametern also den Wert "I" liefern würde),
+sonst 'FALSE' (die Prozedur bitsymbol' mit gleichen Parametern also den Wert "O"
+liefern würde). 
+ 
+Den zweiten Testbefehl haben wir im obigen Programm noch nicht verwendet. Wir
+könnten damit aber auch die Refinements 'alles abgedunkelt' und 'alles beleuchtet'
+folgendermaßen notieren: 
+ 
+#on("b")# 
+  alles abgedunkelt: 
+    bitmuster gleich (3, "OOOOOOOO"). 
+ 
+  alles beleuchtet: 
+    bitmuster gleich (3, "IIIIIIII"). 
+#off("b")# 
+ 
+ 
+#on("b")# 
+BOOL PROC bitmuster gleich (INT CONST kanal, 
+                            TEXT CONST vorgabe) 
+#off("b")# 
+ 
+Wie bereits zuvor wird über den ersten Parameter der Kanal angegeben, über den der
+Digitaleingang angesprochen werden kann. Zunächst liest die Prozedur am ange­
+gebenen Kanal die aktuelle Einstellung ein und vergleicht es mit der 'vorgabe'. Der
+eigentliche Vorteil der Prozedur liegt darin, daß bei der Beschreibung der 'vorgabe'
+neben den Zeichen "I" und "O" auch das Zeichen "X" verwendet werden darf. z.B.
+"IOXXXXX". Entspricht das eingelesene Bitmuster der 'vorgabe', so liefert die Prozedur
+den Wert 'TRUE', sonst den Wert 'FALSE'. In gerade genannten Beispiel liefert die
+Prozedur also immer dann 'TRUE', wenn eine Karte mit der Markierung für Rot
+eingeschoben wurde - gleichgültig, welche Kundennummer eingestanzt ist. 
+#page# 
+#on("b")#6.2.3  Befehle für die analoge Eingabe#off("b")# 
+ 
+Die analoge Eingabe möchten wir Ihnen an einem ganz einfachen Beispiel vor Augen
+führen. Sie brauchen dazu nur ein ganz normales Drehpotentiometer (ca. 5kOhm),
+das Sie in jedem Elektronik-Fachgeschäft für wenig Geld erhalten können. Ein
+solches Drehpotentiometer verfügt über drei Anschlüsse. Wenn man sich den inneren
+Aufbau vor Augen führt, ist die Belegung der drei Anschlüsse auch recht einsichtig. 
+ 
+ 
+         siehe Physikbuch!! 
+ 
+ 
+ 
+#on("b")##center#Abb.21 Aufbau eines Drehpotentiometers#off("b")#
+ 
+Löten Sie ggf. auf die drei Anschlüsse je einen Lötschuh, um eine einfache Steckver­
+bindung zur Kombikarte/Compact-Box herstellen zu können. Wichtig ist vor allem,
+daß der mittlere Anschluß am Drehpotentiometer auf den mittleren Stecksockel am
+Analogeingang auf der Kombikarte/Compact-Box aufgesteckt wird. Die beiden
+anderen Anschlüsse können können Sie beliebig auf die beiden dann noch freien
+Lötstifte (+ und �) des gleichen Analogeingangs aufstecken. 
+ 
+Starten Sie dann das folgende Programm: 
+ 
+#on("b")# 
+   initialisiere interface; 
+   page; 
+   REP 
+     notiere potentiometerwert 
+   UNTIL abbruch gewuenscht PER. 
+ 
+   notiere potentiometerwert: 
+     put (wert von analogeingang (1)); 
+     line. 
+#off("b")# 
+#page# 
+Nach dem Start des Programms müßten auf dem Bildschirm untereinander immer
+wieder die gleiche Zahl (ein Wert zwischen 0 und 255) auftauchen. Wenn Sie dann
+am Potentiometer drehen, müßten sich auch die Werte auf dem Bildschirm ändern. 
+ 
+Sie hätten das Refinement 'notiere potentiometerwert' auch folgendermaßen notieren
+können: 
+ 
+#on("b")# 
+   notiere potentiometerwert: 
+     put (spannungswert (1)); 
+     line. 
+#off("b")# 
+ 
+Statt Wert zwischen 0 und 255 zu erhalten, müßten Sie jetzt Werte zwischen 0.0 und
+5.0 erhalten. 
+ 
+ 
+#on("b")# 
+REAL PROC spannungswert (INT CONST kanal) 
+#off("b")# 
+ 
+Über den Parameter wird der Kanal angegeben, über den der analoge Eingang ange­
+sprochen werden kann; bei uns ist das der Kanal 1 (oder 2) auf der Kombikarte/
+Compact-Box. Auf der Kombikarte/Compact-Box können nur Spannungswerte
+zwischen 0.0V und 5.0V eingelesen werden. Auf der A/D-Karte kann der Bereich für
+die einzulesenden Sapnnungwerte durch die Schalterstellung auf der Karte eingestellt
+werden (Sehen Sie dazu auch Kapitel 5.3.1). 
+ 
+ 
+#on("b")# 
+REAL PROC wert von analogeingang (INT CONST kanal) 
+#off("b")# 
+ 
+Über den Parameter wird der Kanal angegeben, über den der analoge Eingang ange­
+sprochen werden kann; bei uns ist das der Kanal 1 (oder 2) auf der Kombikarte/
+Compact-Box. Geliefert werden Werte zwischen 0 und 255. 
+ 
+Tatsächlich wird aber ein Spannungswert vom Analogeingang eingelesen. Dieser
+Spannungswert wird vom Analog-Digital-Wandler auf der Karte nach folgendem
+Verfahren gewandelt: 
+#page# 
+Dem größtmöglichen Spannungswert an diesem Eingang wird der Wert 255, dem
+kleinstmöglichen der Wert 0 zugeordnet. Das Intervall zwischen dem kleinst- und
+größtmöglichen Spannungswert wird in 255 gleichgroße Teilintervalle eingeteilt. Es
+wird nun die Nummer des Intervalls geliefert, in das die eingelesene Spannung fällt.
+Kleinst- und größtmögliche Spannungswerte sind abhängig von der aktuellen Steck­
+karte, Interface-Konfiguration). 
+ 
+ 
+#on("b")#6.3  Hinweise auf Aufgabenmaterial#off("b")# 
+ 
+Eine Fülle von Beispielanwendungen sind beschrieben in: 
+ 
+   Landesinstitut für Schule und Weiterbildung (Hrsg.), Materialien zur Lehrerfort­
+   bildung in Nordrhein-Westfalen, Heft 2, Neue Technologien - Informations­
+   technologische Inhalte im Wahlpflichtunterricht der Klassen 9/10, 2. über­
+   arbeitete Auflage 1987 
+
diff --git a/doc/prozess/gs-prozess-7 b/doc/prozess/gs-prozess-7
new file mode 100644
index 0000000..db3b9d1
--- /dev/null
+++ b/doc/prozess/gs-prozess-7
@@ -0,0 +1,1121 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess
+ 
+#end# 
+#center#1 
+ 
+#on("b")#7  Beschreibung der Menufunktionen#off("b")# 
+ 
+Nach Aufruf meldet sich #on("b")#gs-Prozess#off("b")# zunächst mit dem #on("b")#gs-DIALOG#off("b")#-Emblem. Kurze
+Zeit später erscheint das folgende Menu auf dem Bildschirm: 
+ 
++---------------------------------------------------------------------+
+|    PDV:  Info Interface Programm Archiv                             |
+|-------+------------------------+------------------------------------+
+|       | u  Übersicht Befehle   |                                    |
+|       | ---------------------  |                                    |
+|       | a  Ausgabebefehle      |                                    |
+|       | e  Eingabebefehle      |                                    |
+|       | t  Testbefehle         |                                    |
+|       | w  Weitere Befehle     |                                    |
+|       | ---------------------  |                                    |
+|       | b  Bitmuster           |                                    |
+|       | s  Symbole/Zeichen     |                                    |
+|       | d  Digital-/Analogwerte|                                    |
+|       +------------------------+                                    |
+|                                                                     |
+|                       +----------------------------------------+    |
+|                       |             gs-Prozess                 |    |
+|                       |             Version 1.0                |    |
+|                       |                                        |    |
+|                       |  Copyright Ρ 1988 bei Eva Latta-Weber, |    |
+|                       |                   Bielefeld            |    |
+|                       +----------------------------------------+    |
++---------------------------------------------------------------------+
+|Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>|
++---------------------------------------------------------------------+
+ 
+#center#Abb.22:  Eingangsbildschirm #on("b")#gs-Prozess#off("b")# 
+ 
+ 
+Bevor wir Ihnen die Bedeutung der einzelnen Menupunkte erklären, geben wir erst
+noch einige grundsätzliche Hinweise zur Bedienung des Menusystems für diejenigen
+Leser, die im Umgang mit Menus unter #on("b")#gs-DIALOG#off("b")# nicht geübt sind. 
+#page# 
+#on("b")#7.1  Kurzhinweise zur Bedienung der Menus#off("b")# 
+ 
+Die Bedienung des Menus ist sehr einfach. Eine ausführliche Beschreibung dazu
+finden Sie in den Unterlagen zum Programmsystem #on("b")#gs-DIALOG#off("b")#. An dieser Stelle
+sollen nur die wesentlichen Bedienungsvorgänge beschrieben werden. 
+ 
+-  Mit der Tastenfolge <ESC><?> können Sie sich Informationen zur Bedienung
+   des Menusystems in das Menu einblenden lassen. 
+ 
+-  Mit den Pfeiltasten <rechts> und <links> können Sie zwischen den "Ober­
+   begriffen" in der Kopfzeile wählen. Der aktuelle Oberbegriff ist jeweils invers
+   dargestellt. Das ausgeklappte 'Pull-Down-Menu' bezieht sich auf diesen invers
+   dargestellten Oberbegriff. 
+ 
+-  Mit den Pfeiltasten <hoch> und <runter> können Sie zwischen den Menu­
+   funktionen wählen, die Ihnen im aktuellen Pull-Down-Menu zur Auswahl ange­
+   boten werden. Die aktuell angewählte Menufunktion wird jeweils invers darge­
+   stellt. Die Trennlinien, die in einigen Pull-Down-Menus sichtbar sind, dienen nur
+   der optischen Untergliederung; sie können nicht angewählt werden und werden
+   deshalb automatisch übersprungen. Die einzelnen Menupunkte sind "zyklisch
+   miteinander verknüpft", das heißt, man gelangt vom untersten Menupunkt
+   wieder zum obersten und umgekehrt. Menupunkte, vor denen ein Minuszeichen
+   steht ('-'), sind (zur Zeit) nicht aktivierbar; auch sie können nicht angewählt
+   werden und werden einfach übersprungen. 
+ 
+-  Durch Tippen der Fragezeichentaste (<?>) können Sie sich jeweils zur
+   aktuellen Menufunktion (invers im Pull-Down-Menu) Informationen in das
+   Menu einblenden lassen. 
+ 
+-  Um eine Menufunktion ausführen zu lassen, bewegen Sie sich mit den Pfeiltasten
+   auf die gewünschte Menufunktion im aktuellen Pull-Down-Menu und tippen
+   dann die <RETURN>-Taste. Steht vor dem gewünschten Menupunkt ein
+#page# 
+   einzelner Buchstabe oder eine Ziffer, so kann durch Tippen der entsprechenden
+   Taste diese Menufunktion dadurch direkt aufgerufen werden. Sobald eine Menu­
+   funktion aufgerufen worden ist, erscheint davor ein Stern ('*'). Daraus können
+   Sie entnehmen, daß das System bereits den Auftrag ausführt. 
+ 
+-  An verschiedenen Stellen werden Fragen an Sie gerichtet, die Sie mit 'ja' oder
+   'nein' beantworten müssen. Tippen Sie dazu entsprechend der Entscheidung die
+   Taste <j> (für 'ja') bzw. <n> (für 'nein'). 
+ 
+-  Werden Ihnen vom Menu aus Dateinamen zur Auswahl angeboten, so können Sie
+   den auf dem Bildschirm sichtbaren Pfeil vor den gewünschten Namen
+   positionieren. Mit den Tasten <x> oder <RETURN> können Sie den Namen
+   ankreuzen. Ist die Auswahl mehrerer Dateinamen möglich, so können Sie den
+   Vorgang wiederholen. Mit den Tasten <o> oder <RUBOUT> können Sie auch
+   ein Kreuz vor einem Namen wieder löschen. Daneben gibt es noch einige Ta­
+   stenfunktionen, die für die Bedienung recht hilfreich sein können. Tippen Sie
+   während der Auswahl die Fragezeichentaste (<?>), so werden Ihnen alle
+   Bedienungsmöglichkeiten auf dem Bildschirm angezeigt. Eine Auswahl, in der
+   mehrere Dateien angekreuzt werden dürfen, wird durch die Tastenfolge
+   <ESC><q> verlassen. Anschließend wird die eingestellte Operation mit den
+   angekreuzten Dateien ausgeführt. Sind Sie versehentlich in eine solche Auswahl
+   gelangt, so können Sie den Vorgang durch die Tastenkombination <ESC><h>
+   abbrechen. 
+ 
+-  An einigen Stellen werden Sie aufgefordert, eine Eingabe zu machen (z.B. einen
+   Dateinamen einzugeben). Wird Ihnen hier ein Vorschlag gemacht, den Sie
+   akzeptieren, so brauchen Sie zur Bestätigung nur die <RETURN>-Taste zu
+   tippen. Gefällt Ihnen der Vorschlag nicht oder wird Ihnen kein Vorschlag ge­
+   macht, so machen Sie bitte die gewünschte Eingabe. Zum Schreiben stehen
+   Ihnen alle aus dem Editor bekannten Funktionen zur Verfügung. Mit der Taste
+   <RUBOUT> können Sie Buchstaben löschen, mit <RUBIN> einfügen. Die
+#page# 
+   Eingabe wird durch Tippen der <RETURN>-Taste abgeschlossen. Ist der von
+   Ihnen gewünschte Name schon in Ihrer Task vorhanden und steht in der Fußzeile
+   der Hinweis 'Zeigen: <ESC><z>', dann können Sie sich auch alle vor­
+   handenen Namen zur Auswahl anbieten lassen und durch Ankreuzen den beab­
+   sichtigten Namen auswählen. 
+ 
+-  Ihnen können auch mehrere Alternativen angeboten werden, zwischen denen Sie
+   wählen müssen. In der untersten Zeile eines solchen Kastens, in denen Ihnen die
+   Alternativen auf dem Bildschirm eingeblendet werden, sind die Möglichkeiten
+   aufgeführt, die darüber beschrieben sind. Mit den Pfeiltasten können sie die
+   Markierung auf die gewünschte Alternative positionieren und dann durch die
+   <RETURN>-Taste zur Ausführung bringen. (Manchmal ist das auch durch
+   Tippen der den Alternativen vorangestellten Buchstaben oder Ziffern möglich). 
+ 
+-  Durch die Tastenfolge <ESC><q> kann das Menu insgesamt verlassen
+   werden. Damit das nicht versehentlich geschieht, wird jeweils die Frage gestellt,
+   ob Sie das Menu tatsächlich verlassen wollen. Diese Frage beantworten Sie bitte je
+   nach Wunsch mit 'ja' oder 'nein' durch Tippen der Tasten <j> bzw. <n>. 
+ 
+ 
+#on("b")#7.2  Menufunktionen zum Oberbegriff 'Info'#off("b")# 
+ 
+Das auf dem Bildschirm sichtbare Pull-Down-Menu ist oben abgebildet. 
+ 
+#on("b")#u   Übersicht Befehle#off("b")# 
+ 
+Mit dieser Funktion können Sie sich eine Übersicht der Befehle, die Ihnen
+#on("b")#gs-Prozess#off("b")# zur Verfügung stellt, in den aktuellen Bildschirm einblenden lassen: 
+#page# 
+#free(2.0)# 
+         +------------------------------------------------------------+
+         |   Ausgabebefehle:                  Eingabebefehle:         |
+         |                                                            |
+         |  dezimalwert ausgeben             dezimalwert              |
+         |  bitmuster ausgeben               bitmuster                |
+         |  bitsymbol ausgeben               bitsymbol                |
+         |  spannungswert ausgeben           spannungswert            |
+         |  wert an analogausgang ausgeben   wert von analogeingang   |
+         |                                                            |
+         |                                                            |
+         |   Testbefehle:                     Weitere Befehle:        |
+         |                                                            |
+         |  bitmuster gleich                 initialisiere interface  |
+         |  bit ist gesetzt                  warte                    |
+         |                                                            |
+         +------------------------------------------------------------+
+#center#Abb.23:  Befehlsübersicht 
+ 
+     Es werden 'Eingabebefehle', 'Ausgabebefehle' und 'Testbefehle' unterschieden.
+     Darüberhinaus werden 'Weitere Befehle' angegeben. Eine ausführliche
+     Beschreibung der einzelnen Befehle ist unter den gleichnamigen Menupunkten
+     abrufbar. 
+ 
+ 
+#on("b")#a   Ausgabebefehle#off("b")#
+ 
+     Mit dieser Funktion können Sie sich die zur Verfügung stehenden Ausgabe­
+     befehle detailliert erläutern lassen. Zuerst gelangen Sie in eine Auswahl, von
+     der aus zu jedem einzelnen Ausgabebefehl eine Informationstafel abgerufen
+     werden kann: 
+#page# 
+#free(2.0)# 
+                       +-------------------------------------+
+                       |        Ausgabebefehle:              |
+                       |                                     |
+                       |  1  dezimalwert ausgeben            |
+                       |                                     |
+                       |  2  bitmuster ausgeben              |
+                       |  3  bitsymbol ausgeben              |
+                       |                                     |
+                       |  4  spannungswert ausgeben          |
+                       |  5  wert an analogausgang ausgeben  |
+                       |                                     |
+                       |  z  Zurück in das Menu              |
+                       |                                     |
+                       |     1   2   3   4   5   z           |
+                       +-------------------------------------+
+ 
+#center#Abb.24:  Auswahl Ausgabebefehle 
+ 
+     Auf jeder Informationstafel ist ein kleines Beispiel zur Verwendung des Befehls
+     angegeben, das auch erläutert wird. Anschließend wird ausführlich auf die
+     Parameter der Befehle eingegangen (Datentyp, Wertebereich, etc.). Aus den
+     einzelnen Informationstafeln gelangen Sie immer wieder zur Auswahl zurück.
+     Wird die Auswahl selbst verlassen, gelangen Sie zurück ins Ausgangsmenu. 
+ 
+ 
+#on("b")#e   Eingabebefehle#off("b")# 
+ 
+     Mit dieser Funktion können Sie sich die zur Verfügung stehenden Eingabe­
+     befehle detailliert erläutern lassen. Zuerst gelangen Sie in eine Auswahl, von
+     der aus zu jedem einzelnen Eingabebefehl eine Informationstafel abgerufen
+     werden kann: 
+#page# 
+#free(1.0)# 
+                            +------------------------------+
+                            |   Eingabebefehle:            |
+                            |                              |
+                            |  1  dezimalwert              |
+                            |                              |
+                            |  2  bitmuster                |
+                            |  3  bitsymbol                |
+                            |                              |
+                            |  4  spannungswert            |
+                            |  5  wert von analogeingang   |
+                            |                              |
+                            |  z  Zurück in das Menu       |
+                            |                              |
+                            |   1   2   3   4   5   z      |
+                            +------------------------------+
+ 
+ 
+#center#Abb.25:  Auswahl Eingabebefehle 
+ 
+     Auf jeder Informationstafel ist ein kleines Beispiel zur Verwendung des Befehls
+     angegeben, das auch erläutert wird. Anschließend wird ausführlich auf die
+     Parameter der Befehle (Datentyp, Wertebereich, etc.) und die Werte, die
+     geliefert werden, eingegangen. 
+ 
+     Aus den einzelnen Informationstafeln gelangen Sie immer wieder zur Auswahl
+     zurück. Wird die Auswahl selbst verlassen, gelangen Sie zurück ins Ausgangs­
+     menu. 
+ 
+ 
+#on("b")#t   Testbefehle#off("b")#
+ 
+     Mit dieser Funktion können Sie sich die zur Verfügung stehenden Testbefehle
+     detailliert erläutern lassen. Zuerst gelangen Sie in eine Auswahl, von der aus zu
+     jedem einzelnen Testbefehl eine Informationstafel abgerufen werden kann: 
+#page# 
+                          +------------------------+
+                          |    Testbefehle:        |
+                          |                        |
+                          |  1  bitmuster gleich   |
+                          |  2  bit ist gesetzt    |
+                          |                        |
+                          |  z  Zurück in das Menu |
+                          |                        |
+                          |        1   2   z       |
+                          +------------------------+
+ 
+#center#Abb.26:  Auswahl Testbefehle 
+ 
+     Auf jeder Informationstafel ist ein kleines Beispiel zur Verwendung des Befehls
+     angegeben, das auch erläutert wird. Anschließend wird ausführlich auf die
+     Parameter der Befehle (Datentyp, Wertebereich, etc.) und die Werte, die ge­
+     liefert werden, eingegangen. 
+     Aus den einzelnen Informationstafeln gelangen Sie immer wieder zur Auswahl
+     zurück. Wird die Auswahl selbst verlassen, gelangen Sie zurück ins Ausgangs­
+     menu. 
+ 
+ 
+#on("b")#w   Weitere Befehle#off("b")# 
+ 
+     Hier werden noch weitere zur Verfügung stehende Befehle erläutert, die für die
+     Programmierung ganz hilfreich sind. Zuerst gelangen Sie in eine Auswahl, von
+     der aus zu jedem Befehl eine Informationstafel abgerufen werden kann: 
+ 
+ 
+                           +----------------------------+
+                           |    Weitere Befehle:        |
+                           |                            |
+                           | 1  initialisiere interface |
+                           | 2  warte                   |
+                           |                            |
+                           | z  Zurück in das Menu      |
+                           |                            |
+                           |       1   2   z            |
+                           +----------------------------+
+ 
+#center#Abb.27:  Auswahl 'Weitere Befehle' 
+#page# 
+     Aus den einzelnen Informationstafeln gelangen Sie immer wieder zur Auswahl
+     zurück. Wird die Auswahl selbst verlassen, gelangen Sie zurück ins Ausgangs­
+     menu. 
+ 
+ 
+#on("b")#b   Bitmuster#off("b")# 
+ 
+     Nach Aufruf dieser Funktion wird der Aufbau der Bitmuster erläutert, die als
+     Parameter übergeben oder auch von Prozeduren geliefert werden. 
+ 
+     Insbesondere wird auf die Numerierung der einzelnen Bits eingegangen. 
+ 
+ 
+#on("b")#s   Symbole/Zeichen#off("b")# 
+ 
+     Nach Aufruf der Funktion werden die Zeichen erläutert, die bei der Be­
+     schreibung von Bitmustern und Bitsymbolen Verwendung finden. 
+ 
+ 
+#on("b")#d   Digital-/Analogwerte#off("b")# 
+ 
+     Bei den beiden Befehlen 'wert an analogausgang ausgeben' und 'wert von
+     analogeingang', wird ein Wert zwischen 0 und 255 als Parameter übergeben
+     bzw. von der Prozedur geliefert. Am Analogausgang wird aber eine Spannung
+     ausgegeben bzw. eingelesen. Hier wird erläutert, wie die Spannungswerte
+     innerhalb der Prozeduren gewandelt werden. 
+ 
+ 
+#on("b")#7.3  Menufunktionen zum Oberbegriff 'Interface'#off("b")# 
+ 
+Über die Menufunktionen unter diesem Oberbegriff nehmen Sie die Konfiguration
+von #on("b")#gs-Prozess#off("b")# vor. Ebenso ist von hier aus ein Test des Interface-Systems möglich. 
+#page# 
+ 
++-----------------------------------------------------------------------+
+|    PDV:  Info Interface Programm Archiv                               |
++-------+-------------------+-------------------------------------------+
+|       | i  Informationen  |                                           |
+|       | ----------------  |                                           |
+|       | k  Konfigurieren  |                                           |
+|       | ----------------  |                                           |
+|       | a  Ausgabetest    |                                           |
+|       | e  Eingabetest    |                                           |
+|       +-------------------+                                           |
+|                                                                       |
+|                                                                       |
+|                                                                       |
++---------------------------------------------------------------------- +
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++-----------------------------------------------------------------------+
+ 
+#center#Abb.28:  Menubildschirm zum Oberbegriff 'Interface' 
+ 
+ 
+#on("b")#i   Informationen#off("b")# 
+ 
+     Mit dieser Menufunktion können Sie sich zu jedem Zeitpunkt die aktuell
+     eingestellte Konfiguration von #on("b")#gs-Prozess#off("b")# anzeigen lassen. Sie können er­
+     sehen, welches Interface-System eingestellt ist, wie die Kanäle belegt und
+     numeriert sind (sehen Sie das Beispiel in Abb.13). 
+ 
+     Ist eine Compact-Box oder ein Einzelsteckplatz eingestellt, erhalten Sie die
+     Informationen direkt eingeblendet. Ist dagegen ein Mehrfachsteckplatz einge­
+     stellt, gelangen Sie in eine Auswahl. Von hier aus können Sie Informationen zu
+     jedem einzelnen Steckplatz getrennt abrufen. 
+ 
+     Fehlerfälle: 
+     -  Wurde #on("b")#gs-Prozess#off("b")# bisher noch nicht konfiguriert, so erhalten Sie eine
+        Warnung (sehen Sie Abb.11). In diesem Falle ist zunächst eine Konfigura­
+        tion von #on("b")#gs-Prozess#off("b")# vorzunehmen (sehen Sie die Beschreibung zur
+        nächsten Menufunktion). 
+#page# 
+#on("b")#k   Konfigurieren#off("b")# 
+ 
+     Mit dieser Menufunktion können Sie #on("b")#gs-Prozess#off("b")# auf das aktuell angeschlos­
+     sene Interface-System einstellen. Dazu haben Sie verschiedene Angaben zu
+     machen. 
+ 
+     Zunächst wird Ihnen eine Auswahl der Steckplatzart angeboten (sehen Sie
+     dazu Abb.12). Hier können Sie zur Zeit zwischen Compact-Box, Einzelsteck­
+     platz und Mehrfachsteckplatz wählen. 
+ 
+     Ist eine Compact-Box angeschlossen, ist mit der hier gemachten Angabe die
+     Konfiguration abgeschlossen; die aktuelle Kanalbelegung wird Ihnen dann nur
+     noch zur Information eingeblendet. 
+ 
+     Bei Einzel- und Mehrfachsteckplatz haben Sie noch anzugeben, welche Inter­
+     facekarte eingesteckt ist. Beim Einzelsteckplatz ist diese Angabe nur einmal zu
+     machen, beim Mehrfachsteckplatz halt mehrfach. Hierzu wird Ihnen aber
+     ebenfalls eine Auswahl angeboten (sehen Sie Abb.14). Nach jeder vorge­
+     nommenen Einstellung wird Ihnen zur Information die Kanalbelegung mitge­
+     teilt. Sofern Sie eine A/D-Karte verwenden, wird noch die Schalterstellung auf
+     der Karte erfragt, denn daraus kann #on("b")#gs-Prozess#off("b")# die eingestellte Eingangsem­
+     pfindlichkeit ermitteln. 
+ 
+ 
+#on("b")#a   Ausgabetest#off("b")# 
+ 
+     Mit dieser Menufunktion können Sie auf einfache Weise testen, ob Ihr Inter­
+     face-System korrekte Ausgaben erzeugt. Nach Aktivieren der Menufunktion
+     erhalten Sie die Möglichkeit, Ausgabewerte einzutragen (sehen Sie Abb.18).
+     Jede Eintragung ist durch <RETURN> abzuschließen. 
+ 
+     Für den Ausgabetest sollte eine Leuchtdiodenanzeige zur Verfügung stehen, um
+     die Ausgaben am Interface kontrollieren zu können. Für detailliertere Informa­
+     tionen lesen Sie bitte unbedingt Kapitel 5. 
+#page# 
+     Fehlerfälle: 
+     -  Interface meldet sich nicht! 
+        Abhilfe:  Überprüfen, ob der Adapter ordnungsgemäß angeschlossen
+                  und eingeschlatet ist (sehen Sie Kapitel 5). Wenn ein MUFI
+                  verwendet wird, MUFI aus- und nach kurzer Pause wieder
+                  einschalten. Noch einmal den Ausgabetest versuchen. 
+     -  Interface-Kanal belegt! 
+        (Kann nur beim Betrieb von MUFI als Endgerät oder bei RS232-Adapter
+        auftreten!) 
+        Abhilfe:  Feststellen, welche Task an den Interface-Kanal gekoppelt ist
+                  ('taskinfo (2) <RETURN>') und diese dann abmelden
+                  ('break' oder 'end'). Die Nummer des Interfacekanals kann
+                  mit dem Kommando 'put (interfacekanal) <RETURN>'
+                  erfragt werden. 
+     -  Sehen Sie bitte die detaillierte Fehlerliste in Kapitel 5.5. 
+ 
+ 
+#on("b")#e   Eingabetest#off("b")# 
+ 
+     Mit dieser Menufunktion können Sie auf einfache Weise testen, ob über Ihr
+     Interface-System korrekte Eingaben möglich sind. Nach Aktivieren der Menu­
+     funktion erhalten Sie die Möglichkeit, am Interface angelegte Eingabewerte
+     abzulesen (sehen Sie Abb.19). 
+ 
+     Für den Eingabetest sollte ein Codekartenleser oder zumindest ein kurzer
+     Draht zur Verfügung stehen. Für detailliertere Informationen lesen Sie bitte
+     unbedingt Kapitel 5. 
+ 
+     Fehlerfälle: 
+     -  Interface meldet sich nicht! 
+        Abhilfe:  Überprüfen, ob der Adapter ordnungsgemäß angeschlossen
+                  und eingeschlatet ist (sehen Sie Kapitel 5). Wenn ein MUFI
+                  verwendet wird, MUFI aus- und nach kurzer Pause wieder
+                  einschalten. Noch einmal den Ausgabetest versuchen. 
+#page# 
+     -  Interface-Kanal belegt! 
+        (Kann nur beim Betrieb von MUFI als Endgerät oder bei RS232-Adapter
+        auftreten!) 
+        Abhilfe:  Feststellen, welche Task an den Interface-Kanal gekoppelt ist
+                  ('taskinfo (2) <RETURN>') und diese dann abmelden
+                  ('break' oder 'end'). Die Nummer des Interfacekanals kann
+                  mit dem Kommando 'put (interfacekanal) <RETURN>'
+                  erfragt werden. 
+     -  Sehen Sie bitte die detaillierte Fehlerliste in Kapitel 5.5. 
+ 
+ 
+#on("b")#7.4  Menufunktionen zum Oberbegriff 'Programm'#off("b")# 
+ 
+ 
++-------------------------------------------------------------------------+
+|    PDV:  Info Interface Programm Archiv                                 |
+|---------------------+---------------------+-----------------------------|
+|                     |  n  Neu erstellen   |                             |
+|                     |  a  Ansehen/Ändern  |                             |
+|                     |                     |                             |
+|                     |  s  Starten         |                             |
+|                     |  w  Wiederholen     |                             |
+|                     |                     |                             |
+|                     |  v  Verzeichnis     |                             |
+|                     |                     |                             |
+|                     |  l  Löschen         |                             |
+|                     |  d  Drucken         |                             |
+|                     |                     |                             |
+|                     |  k  Kopieren        |                             |
+|                     |  u  Umbenennen      |                             |
+|                     +---------------------+                             |
+|-------------------------------------------------------------------------|
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>   |
++-------------------------------------------------------------------------+
+ 
+#center#Abb.29:  Menubildschirm zum Oberbegriff 'Programm' 
+#page# 
+#on("b")#n   Neu erstellen#off("b")# 
+ 
+     Mit dieser Funktion können Sie eine neue Programmdatei anlegen und be­
+     schreiben. 
+ 
+     Sie werden zunächst nach einem Namen für die #on("b")#neue#off("b")# Programmdatei gefragt.
+     Geben Sie einen beliebigen Namen (#on("b")#ohne Anführungszeichen (!)#off("b")#) ein und
+     schließen Sie die Eingabe durch <RETURN> ab. Daraufhin wird Ihnen auf
+     dem Bildschirm eine neue Datei zum beschreiben angeboten. 
+ 
+     Sollte schon eine Programmdatei mit diesem Namen in der Task vorhanden
+     sein, so werden Sie darauf aufmerksam gemacht. 
+ 
+     Sie können sich während des Schreibens die wichtigsten Tastenfunktionen des
+     Editors einblenden lassen. Tippen Sie dazu die Tastenfolge <ESC><?>. Es
+     erscheint dann das folgende Angebot aus dem Sie auswählen können: 
+ 
+ 
+                 +------------------------------------------------+
+                 |         Der EUMEL - Editor                     |
+                 |                                                |
+                 |   b ... Beschreibung desEditors                |
+                 |   w ... Wichtige Tasten                        |
+                 |   p ... Positionieren der Schreibmarke         |
+                 |   k ... Korrigieren im Text (Einfügen/Löschen) |
+                 |   m ... Markierte Textpassagen bearbeiten      |
+                 |   l ... Lernen im Editor                       |
+                 |   a ... Anweisungen im Editor (Kommandodialog) |
+                 |                                                |
+                 |   z ... Zurück in den Schreibmodus             |
+                 |                                                |
+                 |   b   w   p   k   m   l   a   z                |
+                 |                                                |
+                 +------------------------------------------------+
+ 
+#center#Abb.30:  Informationsauswahl zum EUMEL-Editor 
+#page# 
+     Fehlerfälle: 
+     -  Eine Datei mit dem vorgeschlagenen Namen existiert schon. 
+ 
+ 
+#on("b")#a   Ansehen/Ändern#off("b")# 
+ 
+     Mit dieser Funktion können Sie sich Dateien, die schon in Ihrer Task
+     existieren, ansehen oder auch verändern. 
+ 
+     Sie werden zunächst gefragt, ob Sie #on("b")#die zuletzt bearbeitete Programmdatei#off("b")#
+     ansehen bzw. verändern möchten (sofern Sie schon vorher mit #on("b")#gs-Prozess#off("b")# in
+     der Task gearbeitet haben). 
+ 
+     Bejahen Sie diese Frage, dann wird Ihnen diese Programmdatei zur Be­
+     arbeitung angeboten. Verneinen Sie die Frage dagegen, so gelangen Sie in die
+     'Auswahl' (d.h es werden Ihnen alle Programmdateien in der Task zur Auswahl
+     angeboten). Nachdem Sie einen der Namen angekreuzt haben, wird Ihnen die
+     ausgewählte Programmdatei zur Bearbeitung auf dem Bildschirm angebo­
+     ten. 
+ 
+     Fehlerfälle: 
+     -  In der Task existiert noch keine Programmdatei. 
+ 
+ 
+#on("b")#s   Starten#off("b")# 
+ 
+     Mit dieser Menufunktion können Sie eine Programmdatei übersetzen und
+     ausführen lassen. 
+ 
+     Sie werden zunächst gefragt, ob #on("b")#das zuletzt bearbeitete Programm#off("b")# ausgeführt
+     werden soll. Bejahen Sie die Frage, so wird dieses Programm gestartet; ver­
+     neinen Sie die Frage dagegen, so gelangen Sie in die 'Auswahl'. Nach An­
+     kreuzen des gewünschten Programmnamens wird das ausgewählte Programm
+     ausgeführt. 
+#page# 
+     Sind im Programm noch Fehler enthalten, so werden das Programm und die
+     Fehlermeldungen gleichzeitig auf dem Bildschirm dargestellt (Paralleleditor)
+     und zur Korrektur angeboten. Für die Programmkorrektur stehen ebenfalls alle
+     Editorfunktionen zur Verfügung. 
+ 
+     Sollte Ihnen beim Programmieren ein Fehler unterlaufen sein (z.B. eine
+     Endlosschleife), so kann mit der Tastenfolge <ESC><h> der Programmlauf
+     abgebrochen werden ("Notbremse"). 
+ 
+ 
+#on("b")##on("b")#w   Wiederholen#off("b")# 
+ 
+     Mit dieser Funktion können Sie den Ablauf des zuletzt ausgeführten
+     Programms wiederholen, ohne daß das Programm neu übersetzt wird. 
+ 
+     Beachten Sie aber bitte, daß Veränderungen am Programmtext, die seit dem
+     letzten Prtogrammlauf vorgenommen wurden, #on("b")#nicht#off("b")# berücksichtigt werden;
+     dazu muß das Programm erneut mit der Menufunktion 's Starten' übersetzt
+     werden. 
+ 
+     Ist die Wiederholung eines Programmlaufs nicht möglich, so erfolgt ein Hin­
+     weis darauf. 
+ 
+ 
+#on("b")#v   Verzeichnis#off("b")# 
+ 
+     Mit dieser Funktion können Sie sich einen Überblick über die in Ihrer Task
+     vorhandenen Programmdateien verschaffen. 
+ 
+     Nach Aufruf dieser Funktion wird eine Liste der Programmdateien auf dem
+     Bildschirm ausgegeben, die sich in Ihrer Task befinden. Da die Liste selbst
+     eine Datei ist, kann Sie mit der Tastenkombination <ESC><q> verlassen
+     werden - hierauf wird auch in der Kopfzeile der Datei hingewiesen. Falls nicht
+     alle Namen auf den Bildschirm passen, können Sie das Fenster mit
+     <HOP><runter> und <HOP><hoch> verschieben. 
+#page# 
+#on("b")#l   Löschen#off("b")# 
+ 
+     Mit dieser Funktion können Sie Programmdateien, die Sie nicht mehr
+     benötigen, die unnötig Platz belegen, löschen. Aber Vorsicht! Die Programm­
+     dateien verschwinden durch diese Funktion unwiederbringlich! 
+ 
+     Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+     Ihrer Task befinden, zur Auswahl angeboten. Hier können Sie die gewünschten
+     Namen ankreuzen. Die Auswahl wird dann durch die Tastenfolge
+     <ESC><q> verlassen. 
+ 
+     Für jede einzelne Programmdatei wird noch einmal zur Sicherheit gefragt, ob
+     sie auch tatsächlich gelöscht werden soll. Zur Bestätigung tippen Sie bitte die
+     Taste <j> ('ja') - zur Verhinderung <n> ('nein'). 
+ 
+     Fehlerfälle: 
+     -  In der Task exsitiert noch keine Programmdatei. 
+ 
+ 
+#on("b")#d   Drucken#off("b")# 
+ 
+     Mit dieser Funktion können Sie Programmdateien über einen angeschlossenen
+     Drucker ausgeben lassen. 
+ 
+     Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+     Ihrer Task befinden, zur Auswahl angeboten. Hier können Sie die gewünschten
+     Namen ankreuzen. Die Auswahl wird dann durch die Tastenfolge
+     <ESC><q> verlassen. 
+ 
+     Die angekreuzten Programmdateien werden anschließend zum Drucker ge­
+     schickt. Der Vorgang wird auf dem Bildschirm protokolliert. 
+#page# 
+     Fehlerfälle: 
+     -  In der Task existiert noch keine Programmdatei. 
+     -  Der Drucker ist nicht funktionsbereit. 
+     -  Der Drucker wird nicht über die Task 'PRINTER' betrieben. 
+     -  Auf Ihrem System werden die Druckkosten abgerechnet. Sie müssen sich
+        mit einer Codenummer identifizieren. 
+ 
+ 
+#on("b")#k   Kopieren#off("b")# 
+ 
+     Mit dieser Funktion können Sie sich eine Kopie einer bereits in der Task
+     vorhandenen Programmdatei anlegen. Das ist z.B. dann sinnvoll, wenn Sie sich
+     einen bestimmten 'Stand' aufbewahren wollen oder wenn Sie ein Programm
+     schreiben wollen, das einem bereits vorhandenen ähnelt. 
+ 
+     Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+     Ihrer Task befinden, zur Auswahl angeboten. Nach Ankreuzen eines Namens
+     wird die Auswahl automatisch verlassen. 
+ 
+     Anschließend wird der angekreuzte Name angezeigt und der Name für die
+     Kopie erfragt. Es muß ein Name eingetragen werden, der in dieser Task noch
+     nicht für eine Programmdatei vergeben wurde; ansonsten erfolgt ein Hinweis
+     darauf und es wird nicht kopiert! 
+ 
+     Da man aber oft für die Kopie einen ähnlichen Namen wie für das Original
+     wählt, wird der 'alte' Name vorgeschlagen. Aus genannten Gründen muß er
+     aber verändert werden. Sie können diesen Namen mit den üblichen Editier­
+     funktionen verändern oder mit <HOP><RUBOUT> löschen und ganz neu
+     eingeben. Sie sparen aber eine Menge Tipparbeit, wenn Sie einen langen
+     Namen nur an einer Stelle ändern wollen. 
+ 
+     Fehlerfälle: 
+     -  Eine Programmdatei mit dem gewünschten Namen existiert bereits in der
+        Task. 
+#page# 
+#on("b")#u   Umbenennen#off("b")# 
+ 
+     Mit dieser Funktion können Sie einer bereits vorhandenen Programmdatei
+     einen neuen Namen geben. 
+ 
+     Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+     Ihrer Task befinden, zur Auswahl angeboten. Nach Ankreuzen eines Namens
+     wird die Auswahl automatisch verlassen. 
+ 
+     Anschließend wird dieser Name angezeigt und der zukünftige Name für die
+     Programmdatei erfragt. Es muß ein Name eingetragen werden, der in dieser
+     Task noch nicht für eine Programmdatei vergeben wurde - ansonsten erfolgt
+     ein Hinweis darauf und die Programmdatei wird nicht umbenannt! 
+ 
+     Da man aber oft den 'neuen' Namen in Anlehnung an den 'alten' Namen
+     wählt, wird der 'alte' Name vorgeschlagen. Aus genannten Gründen muß er
+     aber verändert werden. Sie können diesen Namen mit den üblichen Editier­
+     funktionen verändern oder mit <HOP><RUBOUT> löschen und ganz neu
+     eingeben. Sie sparen aber eine Menge Tipparbeit, wenn Sie einen langen
+     Namen nur an einer Stelle ändern wollen. 
+ 
+     Fehlerfälle: 
+     -  Eine Programmdatei mit dem gewünschten Namen existiert bereits in der
+        Task. 
+#page# 
+#on("b")#7.5  Menufunktionen zum Oberbegriff 'Archiv'#off("b")# 
+ 
+ 
++-----------------------------------------------------------------------+
+|    PDV:  Info Interface Programm Archiv                               |
+|------------------+------------------------+---------------------------|
+|                  | r  Reservieren         |                           |
+|                  | -  Neue Diskette       |                           |
+|                  |                        |                           |
+|                  | -  Schreiben           |                           |
+|                  | -  Checken             |                           |
+|                  | -  Kombination         |                           |
+|                  | -  Holen/Lesen         |                           |
+|                  | -  Löschen             |                           |
+|                  |                        |                           |
+|                  | -  Verzeichnis         |                           |
+|                  | -  Drucken             |                           |
+|                  |                        |   +---------------------+ |
+|                  | i  Initialisieren      |   |  Dateiaustausch mit:| |
+|                  | z  Zieltask einstellen |   |   Archiv            | |
+|                  +------------------------+   | Archivname:         | |
+|                                               |  __________         | |
+|                                               +---------------------+ |
+|-----------------------------------------------------------------------|
+| Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++-----------------------------------------------------------------------+
+ 
+#center#Abb.31:  Menubildschirm zum Oberbegriff 'Archiv' 
+ 
+ 
+In diesem Kapitel werden alle die Menufunktionen beschrieben, die Ihnen unter dem
+Oberbegriff 'Archiv' im Menu angeboten werden. Mit den Funktionen in diesem Menu
+können Sie aber nicht nur Dateien auf dem Archiv behandeln, sondern auch in
+anderen Tasks im Multi-User-System oder über das EUMEL-Netz sogar auf anderen
+Rechnern! 
+ 
+Wenn Sie dieses Pull-Down-Menu gerade aufgeschlagen haben, sind nicht alle Funk­
+tionen aktivierbar! Um weitere Funktionen zu aktivieren, muß erst einer der aktivier­
+baren Menupunkte gewählt werden. 
+#page# 
+#on("b")#r   Reservieren#off("b")# (des Archivlaufwerks) 
+ 
+     Im EUMEL-Multi-User-System haben normalerweise mehrere Personen das
+     Zugriffsrecht auf das Archivlaufwerk. Allerdings muß der Zugriff so geregelt
+     werden, daß sich die Beteiligten dabei nicht gegenseitig "in die Quere
+     kommen". Ein Zugriff auf das Archivlaufwerk erfordert zunächst eine An­
+     meldung. Ist diese Anmeldung erfolgt, kann von den anderen Beteiligten so
+     lange nicht mehr auf das Laufwerk zugegriffen werden, bis es wieder freige­
+     geben worden ist. 
+ 
+     Diese Anmeldung des Archivlaufwerkes erfolgt über die Menufunktion 'r Reser­
+     vieren'. Greift bereits eine andere Task auf das Laufwerk zu, so erhalten Sie
+     darüber einen Hinweis auf dem Bildschirm. Ansonsten wird an Sie die Frage
+     gestellt, ob die Diskette eingelegt und das Laufwerk geschlossen ist. 
+ 
+     Erst zu diesem Zeitpunkt ist sichergestellt, daß Sie den alleinigen Zugriff auf
+     das Laufwerk haben. Deshalb sollten Sie, wenn Sie mit mehreren Personen am
+     Computer arbeiten, erst zum Zeitpunkt der Fragestellung die Diskette ins
+     Laufwerk einlegen. 
+ 
+     Nachdem Sie die Diskette eingelegt und die Frage bejaht haben, ermittelt das
+     System selbständig den Namen der eingelegten Diskette, zeigt den Namen auf
+     dem Bildschirm (im kleinen Kasten unten) an und aktiviert die anderen
+     Menupunkte des Pull-Down-Menus. 
+ 
+     Beim Verlassen des Pull-Down-Menus, wenn eine andere Zieltask eingestellt
+     wird oder wenn das Menu gänzlich verlassen wird, wird die Reservierung
+     automatisch aufgehoben! 
+#page# 
+     Fehlerfälle: 
+     -  Das Laufwerk ist von einer anderen Task belegt. 
+     -  Die Diskette ist falsch eingelegt oder das Laufwerk ist nicht richtig ge­
+        schlossen. 
+     -  Die Diskette ist nicht formatiert bzw. initialisiert. 
+     -  Die Diskette kann nicht gelesen werden (keine EUMEL-Diskette, Diskette
+        hat ein falsches Format, Diskette ist verschmutzt...). 
+ 
+ 
+#on("b")#n   Neue Diskette#off("b")# (anmelden) 
+ 
+     Der Dateiaustausch mit einer Diskette ist nur dann möglich, wenn der im
+     System eingestellte Diskettenname (auf dem Bildschirm im kleinen Kasten
+     unten sichtbar) mit dem tatsächlichen Namen der Diskette übereinstimmt.
+     Nach einem Diskettenwechsel ist das aber in der Regel nicht mehr der Fall.
+     Greift man dann auf die neu eingelegte Diskette zu, so erscheint die Fehlermel­
+     dung: 'Falscher Archivname! Bitte neue Diskette anmelden!'. 
+ 
+     Das Anmelden einer neuen Diskette - ohne einen neuen Reservierungsvorgang
+     - wird durch diese Menufunktion ermöglicht. Nach Aktivieren dieses Menu­
+     punktes wird der Name der eingelegten Diskette ermittelt, im System eingestellt
+     und auf dem Bildschirm angezeigt. 
+ 
+     Im Gegensatz zur Menufunktion 'r Reservieren' greift das System ohne Anfrage
+     an den Benutzer auf das Archivlaufwerk zu (die Reservierung bleibt ja
+     bestehen). Ist das Archivlaufwerk reserviert, so ist die Neuanmeldung einer
+     Diskette über diese Menufunktion weniger zeitaufwendig. 
+ 
+     Fehlerfälle: 
+     -  wie unter 'r Reservieren'. 
+#page# 
+#on("b")#s   Schreiben#off("b")# (Kopieren) 
+ 
+     Alle Dateien der eigenen Task werden zur Auswahl angeboten. Wenn Sie die
+     Auswahl durch die Tastenfolge <ESC><q> verlassen, überprüft das System
+     zunächst, ob die Dateien in der eingestellten Zieltask schon vorhanden sind. Ist
+     das der Fall, wird erfragt, ob die dort vorhandenen Dateien überschrieben, d.h.
+     gelöscht werden dürfen (s.u.). Anschließend werden alle angekreuzten Dateien
+     in der Reihenfolge, in der Sie sie angekreuzt haben, in die eingestellte Zieltask
+     kopiert. Der Vorgang wird auf dem Bildschirm protokolliert. Die Original­
+     dateien in der eigenen Task bleiben dabei erhalten. 
+ 
+     Wenn in der Zieltask schon eine Datei existiert, die den gleichen Namen hat
+     wie eine Datei, die Sie dorthin kopieren möchten, so wird angefragt, ob die
+     vorher schon existierende Datei überschrieben (gelöscht!) werden soll. Bejahen
+     Sie diese Frage, so wird die bereits in der Zieltask existierende Datei (un­
+     wiederbringlich) gelöscht und die gewünschte Datei dorthin transportiert. Ein
+     Überschreiben aus Versehen ist nicht möglich, wenn Sie die an Sie gestellte
+     Frage sorgfältig beantworten. 
+ 
+     Verneinen Sie die Frage, so wird die Datei auch nicht hinübertransportiert! Sie
+     können die Datei aber umbenennen (Menufunktion 'u Umbenennen' unter
+     den Oberbegriffen 'Landschaft'/Arbeitsfeld' bzw. 'Programm') und an­
+     schließend mit anderem Namen hinüberschreiben. 
+ 
+     Beachten Sie, daß beim Überschreiben einer Datei auf einer Archivdiskette der
+     Speicherplatz der alten (überschriebenen) Version im allgemeinen nicht
+     wiederverwendet werden kann. In einem solchen Fall könnte die Diskette voll
+     geschrieben werden, obwohl eigentlich genügend Platz vorhanden wäre. Zur
+     Optimierung wird deshalb zuerst überprüft, ob die angekreuzten Dateien
+     schon in der Zieltask vorhanden sind und löscht diese, wenn Sie Ihr Einver­
+     ständnis geben. Erst anschließend werden die Dateien insgesamt kopiert. 
+#page# 
+     Normalerweise ist als Zieltask das Archivlaufwerk der eigenen Station einge­
+     stellt. Mit der Menufunktion 'z Zieltask einstellen' kann diese Einstellung aber
+     verändert werden. 
+ 
+     Fehlerfälle: 
+     -  Die Diskette ist falsch eingelegt oder beschädigt. 
+     -  Die Diskette kann nicht beschrieben werden (Schreibfehler). 
+     -  Die Diskette ist voll. 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#c   Checken#off("b")# 
+ 
+     Diese Menufunktion kann nur ausgeführt werden, wenn der Dateiaustausch
+     mit einem Archiv(manager) erfolgt - ansonsten ist diese Menufunktion auch
+     nicht aktivierbar. Die Menufunktion dient dazu, auf Diskette geschriebene
+     Dateien auf Lesefehler hin zu prüfen. Es empfiehlt sich, diese Prüfroutine auf
+     neu auf die Diskette geschriebene Dateien anzuwenden. Sehen Sie dazu auch
+     'k Kombination'. 
+ 
+     Alle Dateien der eingestellten Zieltask (Archiv) werden zur Auswahl angeboten.
+     Wenn Sie die Auswahl durch die Tastenfolge <ESC><q> verlassen, werden
+     alle angekreuzten Dateien in der Reihenfolge, in der Sie sie angekreuzt haben,
+     "gecheckt", d.h. auf Lesefehler hin überprüft. Der Vorgang wird auf dem Bild­
+     schirm protokolliert. 
+ 
+     Fehlerfälle: 
+     -  Lesefehler auf dem Archiv. 
+     -  Sehen Sie auch unter  'r Reservieren'. 
+ 
+#page# 
+#on("b")#k   Kombination#off("b")# 
+ 
+     Diese Menufunktion ist eine Kombination aus den beiden Menufunktionen 's
+     Schreiben' und 'c Checken' (Sehen Sie weitere Informationen auch dort!). 
+ 
+     Alle Dateien der eigenen Task werden zur Auswahl angeboten. Wenn Sie die
+     Auswahl durch die Tastenfolge <ESC><q> verlassen, werden alle ange­
+     kreuzten Dateien in der Reihenfolge, in der Sie sie angekreuzt haben, in die
+     eingestellte Zieltask kopiert (gegebenenfalls müssen bereits vorhandene
+     Dateien gleichen Namens in der Zieltask gelöscht werden). Anschließend
+     werden alle Dateien, die gerade geschrieben wurden, gecheckt, d.h. auf Lese­
+     fehler hin untersucht. Beide Vorgänge werden auf dem Bildschirm
+     protokolliert. 
+ 
+     Da die 'Check' - Operation nur bei Archivmanagern zulässig ist, ist diese Menu­
+     funktionen ebenfalls nur bei Archivmanagern aktivierbar. Zur Erläuterung
+     sehen Sie bitte auch unter 'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#h   Holen/Lesen#off("b")# 
+ 
+     Die Menufunktion dient dazu, Dateien, die bereits auf einer Archivdiskette oder
+     in einer anderen Task existieren, in die eigene Task zu kopieren. 
+ 
+     Alle Dateien der eingestellten Zieltask werden zur Auswahl angeboten. An­
+     schließend werden Kopien der angekreuzten Dateien in der Reihenfolge des
+     Ankreuzens in die eigene Task geholt. Das Original in der Zieltask bleibt dabei
+     unverändert! Der Vorgang wird auf dem Bildschirm protokolliert. 
+ 
+     Sind in der eigenen Task schon Dateien mit gleichem Namen vorhanden, so
+     wird gefragt, ob die 'alten' Dateien überschrieben (gelöscht) werden dürfen.
+     Nur wenn Sie zustimmen, werden die in Ihrer Task existierenden Dateien
+     (unwiederbringlich!) gelöscht und Kopien der gleichnamigen Dateien aus der
+     Zieltask angefertigt. 
+#page# 
+     Stimmen Sie dem Löschvorgang nicht zu, dann bleiben die bisherigen Dateien
+     in Ihrer Task erhalten - die Dateien aus der Zieltask werden dann aber auch
+     nicht in Ihre Task kopiert! Um dennoch die Kopien zu erhalten, können Sie die
+     namensgleichen Dateien in Ihrer Task umbenennen und dann erst die Dateien
+     aus der anderen Task anfordern. 
+ 
+     Normalerweise werden die Dateien vom Archiv der eigenen Station geholt. Mit
+     dem Menupunkt 'z Zieltask einstellen' kann diese Einstellung verändert
+     werden. 
+ 
+     Fehlerfälle: 
+     -  Lesefehler auf dem Archiv. 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              's Schreiben' 
+                              'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#l   Löschen#off("b")#
+ 
+     Die Menufunktion dient dazu, Dateien in der Zieltask (unwiederbringlich!) zu
+     löschen. Dazu werden alle Dateien der eingestellten Zieltask zur Auswahl ange­
+     boten. Anschließend werden die angekreuzten Dateien in der Reihenfolge ihres
+     Ankreuzens gelöscht. Zur Sicherheit muß noch einmal für jede einzelne Datei
+     bestätigt werden, daß sie auch tatsächlich gelöscht werden soll. 
+ 
+     Beachten Sie, daß beim Löschen einer Datei auf einer Archivdiskette der
+     Speicherplatz im allgemeinen nicht wieder verwendet werden kann. In einem
+     solchen Fall könnte die Diskette voll geschrieben werden, obwohl eigentlich
+     genügend Platz vorhanden wäre. Diese Probleme treten bei anderen Tasks, die
+     keine Archivmanager sind, nicht auf, da deren Speicherplatz intelligenter
+     verwaltet wird. 
+#page# 
+     Normalerweise ist als Zieltask das Archiv der eigenen Station eingestellt. Mit
+     dem Menupunkt 'z Zieltask einstellen' kann diese Einstellung verändert
+     werden. 
+ 
+     Fehlerfälle: 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              's Schreiben' 
+                              'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#v   Verzeichnis#off("b")# 
+ 
+     Mit dieser Menufunktion können Sie sich einen Überblick über die in der
+     Zieltask (z.B. auf dem Archiv) vorhandenen Dateien verschaffen. 
+ 
+     Nach Aufruf der Funktion wird eine Liste der Dateien auf dem Bildschirm
+     ausgegeben, die sich in der Zieltask (z.B. auf dem Archiv) befinden. Ist die
+     Zieltask ein Archiv(manager), so wird auch angezeigt, wieviel Platz auf der
+     Diskette belegt ist. Da die Liste selbst eine Datei ist, kann sie mit der Tasten­
+     kombination <ESC><q> verlassen werden. Falls nicht alle Dateinamen auf
+     den Bildschirm passen, können Sie das Fenster mit <HOP><hoch> und
+     <HOP><runter> verschieben. 
+ 
+     Fehlerfälle: 
+     -  Sehen Sie unter  'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#d   Drucken#off("b")# 
+ 
+     Das Verzeichnis der Dateien in der Zieltask, das man mit der Menufunktion 'v
+     Verzeichnis' auf dem Bildschirm angezeigt bekommt, kann mit dieser Menu­
+     funktion ausgedruckt werden. 
+#page# 
+     Zur Sicherheit wird angefragt, ob wirklich ein solches Dateiverzeichnis der
+     Zieltask gedruckt werden soll. Bejaht man die Frage, so wird ein Dateiver­
+     zeichnis erstellt und zum Drucker geschickt. 
+ 
+     Fehlerfälle: 
+     -  Der Drucker ist nicht funktionsbereit. 
+     -  Der Drucker wird nicht über die Task 'PRINTER' betrieben. 
+     -  Auf Ihrem System werden die Druckkosten abgerechnet. Sie müssen sich
+        mit einer Codenummer identifizieren. 
+ 
+ 
+#on("b")#i  Initialisieren#off("b")# 
+ 
+     Diese Menufunktion gestattet es, frische Disketten zu formatieren, zu
+     initialisieren bzw. beschriebene Disketten vollständig zu löschen und ggf. dabei
+     umzubenennen. Bei Aufruf dieser Menufunktion wird - sofern noch nicht
+     geschehen - das Archivlaufwerk automatisch reserviert. 
+ 
+     Wenn Sie eine fabrikneue Diskette aus der Verpackung nehmen, müssen Sie
+     diese zunächst #on("b")#formatieren#off("b")#. Dabei wird die Diskette auf ein festgelegtes
+     physikalisches Format eingestellt. Ohne daß diese Operation vorausgegangen
+     ist, kann eine Diskette weder beschrieben noch gelesen werden. 
+ 
+     Prinzipiell braucht eine Diskette nur ein einziges Mal formatiert zu werden. Sie
+     können Sie jedoch jederzeit wieder formatieren - z.B. wenn Sie Disketten ha­
+     ben, von denen Sie nicht genau wissen, für welche Zwecke sie zuvor verwendet
+     wurden. 
+ 
+     Wenn Sie diese Menufunktion aktivieren, werden Sie so zunächst gefragt, ob Sie
+     die Diskette auch formatieren wollen. Bejahen Sie die Frage, so werden Ihnen
+     mehrere Formate zur Auswahl angeboten: 
+#page# 
+                   +----------------------------------+
+                   |   Formatieren einer Diskette     |
+                   |                                  |
+                   | Dies sind die möglichen Formate: |
+                   |                                  |
+                   |  1 ....  40 Spur     -   360 KB  |
+                   |  2 ....  80 Spur     -   720 KB  |
+                   |  3 ....  5 1/4"      -   1,2 MB  |
+                   |  4 ....  3 1/2"      -   1,4 MB  |
+                   |  s ....  Standard    -   Format  |
+                   |                                  |
+                   |                                  |
+                   |            1   2   3   4   s     |
+                   +----------------------------------+
+ 
+#center#Abb.32:  Auswahl der Archiv-Formate 
+ 
+     Erkundigen Sie sich bei Ihrem Händler, welches Format Sie bei Ihrem Rechner
+     und den von Ihnen verwendeten Disketten einstellen müssen. Manche Rechner
+     unterstützen diese Operation innerhalb des EUMEL-Systems auch gar nicht,
+     das Formatieren muß dann irgendwie anders außerhalb des EUMEL-Systems
+     geschehen. 
+ 
+     Wenn Sie die Formatierung abgeschlossen oder auch übersprungen haben,
+     beginnt die eigentliche Initialisierung der Diskette. Dabei wird als erstes der
+     Archivname auf die Diskette geschrieben. Alle alten Daten, die sich ggf. auf der
+     Diskette befinden, werden bei diesem Vorgang unwiederbringlich (!) gelöscht. 
+ 
+     Zur Sicherheit überprüft das System in jedem Falle, ob es sich um eine EUMEL
+     - Diskette handelt, und erfragt Ihr Einverständnis, ob die Diskette wirklich
+     initialisiert werden soll. Geben Sie hierzu Ihr Einverständnis, dann wird noch
+     der (neue) Archivname erfragt. Hatte die Diskette schon einen Namen, dann
+     wird dieser zum Überschreiben angeboten. Wollen Sie den alten Archivnamen
+     beibehalten, so brauchen Sie nur die <RETURN>-Taste zu tippen, ansonsten
+     können Sie den Namen auch zuvor verändern oder einen ganz neuen Namen
+     hinschreiben. Anhand des ausgegebenen Namens können Sie auch über­
+     prüfen, ob Sie die richtige Diskette eingelegt haben. 
+#page# 
+     Das Initialisieren funktioniert natürlich nur, wenn Sie als Zieltask einen
+     Archivmanager eingestellt haben - ansonsten ist diese Menufunktion gesperrt
+     (nicht aktivierbar!). 
+ 
+     Fehlerfälle: 
+     -  Formatieren ist nicht auf dem System möglich. 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#z   Zieltask einstellen#off("b")# 
+ 
+    Mit dieser Menufunktion können Sie festlegen, mit welcher Zieltask Sie
+    kommunizieren, d.h. z.B. Dateien austauschen möchten. Normalerweise ist hier
+    das Archiv am eigenen Rechner eingestellt. Das wird auch nach Aufklappen des
+    Pull-Down-Menus im Kasten unten angezeigt. 
+ 
+    Diese Menufunktion kann im Unterricht z.B. dazu genutzt werden, um fertig­
+    gestellte Hausaufgaben in eine bestimmte Task zu schicken (Vatertask) oder um
+    von dort z.B. vorgefertigte Landschaften oder/und Programme abzuholen. 
+ 
+    Sie können aber auch eine andere Task einstellen (z.B. die Vatertask oder die
+    Task 'PUBLIC'), um mit diesen Dateien auszutauschen oder um sich auch nur
+    einen Überblick über die dort vorhandenen Dateien zu verschaffen. Wenn Sie
+    mit Ihrem Rechner in ein EUMEL-Netz integriert sind, können Sie auch auf
+    Tasks anderer Rechner zugreifen oder auch Disketten von Laufwerken anderer
+    Rechner einlesen (z.B. wenn Sie Disketten anderer Formate haben, die von
+    Ihrem Rechner nicht gelesen werden können). 
+ 
+    Dabei werden zwei Anforderungen an die Zieltask gestellt: Sie muß existieren
+    und bereit für den Dateiaustausch sein, d.h es muß eine Managertask sein, auf
+    die Sie Zugriff haben. Versuchen Sie auf andere Tasks zuzugreifen, so erhalten
+    Sie entsprechende (Fehler-)Meldungen. 
+#page#
+    Zu beachten ist noch, daß es im EUMEL-System verschiedene Arten von
+    Managertasks gibt - Archivmanager und normale Dateimanager. Der Unter­
+    schied besteht darin, daß ein Archivmanager vom Benutzer vor dem Zugriff
+    reserviert werden muß - anschließend hat nur dieser Benutzer (bis zur Aufgabe
+    der Reservierung) ein Zugriffsrecht auf den Manager. Normale Dateimanager
+    können dagegen von mehreren Benutzern in beliebiger Reihenfolge ange­
+    sprochen werden. 
+ 
+    Ein Archivmanager kann auch auf bestimmte Diskettenformate spezialisert sein
+    (z.B. auf das Lesen von DOS-Disketten). Manche Rechner haben auch mehrere
+    Archivmanager für verschiedene Laufwerke etc. Durch Einstellen unterschied­
+    licher Archivmanager können Sie dann auf verschiedenen Laufwerken
+    archivieren. 
+ 
+    Nach Aktivieren dieses Menupunktes werden Ihnen die folgenden Alternativen
+    angeboten: 
+ 
+ 
+                      +-----------------------------------------+
+                      |   Dateiaustausch gewünscht mit:         |
+                      |                                         |
+                      |  a ...   Archiv (Eigene Station)        |
+                      |                                         |
+                      |  v ...   Vatertask                      |
+                      |                                         |
+                      |  p ...   'PUBLIC' (Eigene Station)      |
+                      |                                         |
+                      |  s ...   Sonstige Task                  |
+                      |                                         |
+                      | Archiv   Vatertask   PUBLIC   Sonstige  |
+                      +-----------------------------------------+
+ 
+#center#Abb.33:  Auswahl der Zieltask 
+ 
+     Da der Dateiaustausch mit dem Standardarchiv der eigenen Station (Task:
+     'ARCHIVE'), mit der Vatertask und der Task 'PUBLIC' recht häufig in Anspruch
+     genommen wird, sind diese drei Optionen unter den Alternativen direkt ange­
+#page# 
+     geben. Entscheiden Sie sich für eine dieser drei Tasks, so nimmt das System
+     alle notwendigen Einstellungen vor. Möchten Sie dagegen in Kontakt mit einer
+     anderen Task treten, so wählen Sie die Alternative 's ... Sonstige Task'. In
+     diesem Falle haben Sie noch 3 Angaben zu machen: 
+ 
+     -  Zunächst werden Sie nach dem Namen der Zieltask gefragt. Geben Sie den
+        Namen der Zieltask - ohne Anführungsstriche (!) - ein und schließen Sie
+        die Eingabe mit der <RETURN>-Taste ab. (Den ausgegebenen Namen der
+        z.Z. eingestellten Task können Sie dabei verändern bzw. überschreiben.) 
+ 
+     -  Dann wird die Nummer der Station im EUMEL-Netz erfragt, auf der sich
+        die Zieltask befindet. Die Nummer Ihrer Station wird als Vorschlag ausge­
+        geben. Wollen Sie mit einer Task auf Ihrem Rechner kommunizieren, so
+        brauchen Sie diesen Vorschlag nur durch Drücken der <RETURN>-Taste
+        bestätigen - ansonsten tragen Sie zuvor die entsprechende Stationsnummer
+        ein. Ist Ihr Rechner nicht in ein EUMEL-Netz integriert, so wird die
+        Stationsnummer 0 (Null) ausgegeben. Bitte bestätigen Sie diese Stations­
+        nummer durch Tippen der <RETURN>-Taste. 
+ 
+     -  Zum Abschluß müssen Sie noch angeben, ob die eingestellte Zieltask ein
+        Archivmanager ist oder nicht. 
+ 
+     Das System versucht dann den Kontakt herzustellen. Je nachdem, welche
+     Einstellung Sie vorgenommen haben, sind bestimmte Funktionen innerhalb
+     des Menus nicht aktivierbar. Das System läßt nur die Funktionen zu, die
+     aufgrund Ihrer Einstellungen zulässig sind. 
+ 
+     Im Kasten unten auf dem Bildschirm wird jeweils angezeigt, welche Zieltask
+     eingestellt ist. Erscheint in diesem Kasten auch ein Hinweis auf den Archiv­
+     namen, so haben Sie einen Archivmanager eingestellt. Ist dagegen vor dem
+     Namen der Zieltask noch eine Zahl und ein Schrägstrich angegeben, so haben
+     Sie eine Zieltask auf einem anderen Rechner eingestellt. 
+#page# 
+     Bedenken Sie, daß Operationen mit Tasks auf anderen Stationen länger an­
+     dauern können - werden Sie nicht ungeduldig! 
+ 
+     Sie können die Einstellung der Zieltask jederzeit wieder verändern! 
+ 
+     Fehlerfälle: 
+     -  Die eingestellte Zieltask existiert nicht. 
+     -  Die eingestellte Zieltask existiert zwar, ist aber nicht empfangsbereit, d.h.
+        ein Zugriff von Ihrer Task aus ist nicht möglich! 
+     -  Das Netz ist nicht funktionsbereit (Collector-Task fehlt). 
+     -  Die Kommunikation war nicht erfolgreich. 
+     -  Die gewünschte Operation kann mit der eingestellten Zieltask nicht ausge­
+        führt werden (Zieltask ist z.B. gar kein Archivmanager - Sie aber ver­
+        suchen, das Laufwerk zu reservieren). 
+
diff --git a/doc/prozess/gs-prozess-8 b/doc/prozess/gs-prozess-8
new file mode 100644
index 0000000..c36ccc9
--- /dev/null
+++ b/doc/prozess/gs-prozess-8
@@ -0,0 +1,377 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess
+ 
+#end# 
+#center#1 
+ 
+#on("b")#8  Detailbeschreibung der Basisbefehle und Tests#off("b")# 
+ 
+ 
+#on("b")# 
+BOOL PROC abbruch gewuenscht 
+#off("b")# 
+ 
+   -  erfragt, ob inzwischen durch einen Basisbefehl die Tastenfolge <ESC><q>
+      im Eingabestrom registriert worden ist. Ist das der Fall, liefert die Prozedur
+      den Wert 'TRUE', sonst 'FALSE'. 
+ 
+ 
+#on("b")# 
+BOOL PROC bit ist gesetzt (INT CONST kanal, bitnummer) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")# 
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Ein­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Digital-Eingabe möglich!". 
+   -  untersucht, ob die angegebene Bitnummer zulässig ist (0 #on("b")#<#off("b")# 'bitnummer' #on("b")#<#off("b")#
+      7). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung "Bit­
+      nummer ... ist nicht zulässig!". 
+   -  liest den aktuell anliegenden Wert am angegebenen Kanal. 
+   -  liefert den Wert 'TRUE', wenn in der binären Darstellung das Bit mit der
+      angegebenen Bitnummer gesetzt ist ("I"), sonst den Wert 'FALSE'. 
+ 
+#on("b")# 
+TEXT PROC bitmuster (INT CONST kanal) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+#page# 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Ein­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Digital-Eingabe möglich!". 
+   -  liest den aktuell anliegenden Wert am angegebenen Kanal ein und wandelt
+      ihn in die binäre Darstellung. 
+   -  liefert einen Text der Länge 8, bestehend aus den Zeichen "I" und/oder "O". 
+ 
+ 
+#on("b")# 
+PROC bitmuster ausgeben (INT CONST kanal, 
+                         TEXT CONST bitmuster) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Aus­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Digital-Ausgabe möglich!". 
+   -  untersucht die übergebene Zeichenkette (bitmuster) auf korrekte Länge (8
+      Zeichen). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung
+      "Das Bitmuster ... hat eine unzulässige Länge!". 
+   -  überprüft die in der übergebenen Zeichenkette (bitmuster) vorkommenden
+      Symbole auf ihre Zulässigkeit ("I", "O", "X", "T"). Taucht ein unzulässiges
+      Symbol auf, erfolgt ein Abbruch mit der Fehlermeldung "... ist ein unzu­
+      lässiges Bitsymbol in ...!". 
+#page# 
+   -  aus dem am angegebenen Kanal zuletzt ausgegeben Wert und der über­
+      gebenen Zeichenkette (bitmuster) wird der auszugebende Dezimalwert er­
+      mittelt. Dieser Dezimalwert wird am angegebenen Kanal ausgegeben. Dabei
+      bedeuten "I", daß das betreffende Bit gesetzt wird,  "O", daß das betreffende
+      Bit nicht gesetzt wird,  "X", daß das betreffende Bit gegenüber der zuvor
+      erfolgten Ausgabe am gleichen Kanal nicht verändert wird und   "T", daß das
+      betreffende Bit gegenüber der zuvor erfolgten Ausgabe am gleichen Kanal
+      invertiert wird. 
+ 
+ 
+#on("b")# 
+BOOL PROC bitmuster gleich (INT CONST kanal, 
+                            TEXT CONST vergleichsmuster) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Ein­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Digital-Eingabe möglich!". 
+   -  untersucht die übergebene Zeichenkette (bitmuster) auf korrekte Länge (8
+      Zeichen). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung
+      "Das Bitmuster ... hat eine unzulässige Länge!". 
+   -  überprüft die im 'vergleichsmuster' vorkommenden Symbole auf ihre Zu­
+      lässigkeit ("I", "O", "X"). Taucht ein unzulässiges Symbol auf, erfolgt ein
+      Abbruch mit der Fehlermeldung "... ist ein unzulässiges Bitsymbol in ...!". 
+   -  liest den aktuell anliegenden Wert am angegebenen Kanal ein und wandelt
+      ihn in die binäre Darstellung. 
+   -  überprüft, ob das eingelesene Bitmuster zum 'vergleichsmuster' "paßt". Ist
+      das der Fall, wird der Wert 'TRUE' geliefert, sonst der Wert 'FALSE'. 
+#page# 
+#on("b")# 
+TEXT PROC bitsymbol (INT CONST kanal, bitnummer) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Ein­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Digital-Eingabe möglich!". 
+   -  untersucht, ob die angegebene Bitnummer zulässig ist (0 #on("b")#<#off("b")# 'bitnummer' #on("b")#<#off("b")#
+      7). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung "Bit­
+      nummer ... ist nicht zulässig!". 
+   -  liest den aktuell anliegenden Wert am angegebenen Kanal ein und wandelt
+      ihn in die binäre Darstellung. 
+   -  liefert einen Text der Länge 1, nämlich "I" oder "O". 
+ 
+ 
+#on("b")# 
+PROC bitsymbol ausgeben (INT CONST kanalnummer, bitnummer, 
+                         TEXT CONST bitsymbol) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Aus­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Digital-Ausgabe möglich!". 
+#page# 
+   -  untersucht, ob die angegebene Bitnummer zulässig ist (0 #on("b")#<#off("b")# 'bitnummer' #on("b")#<#off("b")#
+      7). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung "Bit­
+      nummer ... ist nicht zulässig!". 
+   -  überprüft das übergebene Bitsymbol auf Zulässigkeit ("I", "O", "X", "T").
+      Taucht ein unzulässiges Symbol auf oder besteht das Bitsymbol aus mehr als
+      einem Zeichen, erfolgt ein Abbruch mit der Fehlermeldung "... ist ein unzu­
+      lässiges Bitsymbol!". 
+   -  ermittelt aus dem am angegebenen Kanal zuletzt ausgegeben Wert und der
+      übergebenen Bitnummer/dem übergebenen Bitsymbol den auszugebende
+      Dezimalwert. Dieser Dezimalwert wird am angegebenen Kanal ausgegeben.
+      Dabei bedeuten "I", daß das betreffende Bit gesetzt wird,  "O", daß das be­
+      treffende Bit nicht gesetzt wird,  "X", daß das betreffende Bit gegenüber der
+      zuvor erfolgten Ausgabe am gleichen Kanal nicht verändert wird und  "T", daß
+      das betreffende Bit gegenüber der zuvor erfolgten Ausgabe am gleichen Kanal
+      invertiert wird. 
+ 
+ 
+#on("b")# 
+INT PROC dezimalwert (INT CONST kanal) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Ein­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Digital-Eingabe möglich!". 
+   -  liest den aktuell anliegenden Wert am angegebenen Kanal ein. 
+   -  liefert einen INT-Wert mit  0 #on("b")#<#off("b")# 'wert' #on("b")#<#off("b")# 255. 
+#page# 
+#on("b")# 
+PROC dezimalwert ausgeben (INT CONST kanal, wert) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine digitale Aus­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Digital-Ausgabe möglich!". 
+   -  ermittelt den auszugebenden Wert durch die Rechnung 
+#on("b")# 
+#center#ausgabe = wert MOD 256, 
+#off("b")# 
+      und gibt diesen am angegebenen Kanal aus. 
+ 
+ 
+#on("b")# 
+PROC initialisiere interface 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob das Programm korrekt (mit 'run pdv') gestartet wurde. Ist das
+      nicht der Fall, erfolgt ein Abbruch mit der Fehlermeldung "PDV-Programme
+      müssen mit 'run pdv' gestartet werden!". Dieser Fehler kann nicht auftreten,
+      wenn die Programme vom #on("b")#gs-Prozess#off("b")#-Menu gestartet werden! 
+   -  An jeden Digitalausgang des angeschlossenen Interface-Systems wird der Wert
+      '0', an jeden Analogausgang eine "Nullspannung" angelegt (d.h. alles wird
+      "ausgeschaltet"). Die internen Variablen werden dabei initialisiert. 
+#page# 
+#on("b")# 
+PROC spannungswert (INT CONST kanal) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine analoge Ein­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Analog-Eingabe möglich!". 
+   -  ermittelt die laut Konfiguration aktuelle Obergrenze (u max) und Untergrenze
+      (u min) des Spannungsbereiches am angegebenen Analogeingang. 
+   -  liest den aktuell anliegenden Wert (0 #on("b")#<#off("b")# 'wert' #on("b")#<#off("b")# 255) am angegebenen
+      Kanal ein und wandelt ihn nach folgender Rechnung: 
+ 
+#on("b")# 
+                    real(wert) * (u max - u min) 
+      lieferwert =  ---------------------------- + u min 
+                               255.0 
+ 
+#off("b")# 
+   -  liefert einen REAL-Wert mit  u min #on("b")#<#off("b")# 'lieferwert' #on("b")#<#off("b")# u max, gerundet auf drei
+      Nachkommastellen. 
+ 
+ 
+#on("b")# 
+PROC spannungswert ausgeben (INT CONST kanal, 
+                             REAL CONST spannung) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+#page# 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine analoge Aus­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Analog-Ausgabe möglich!". 
+   -  ermittelt die laut Konfiguration aktuelle Obergrenze (u max) und Untergrenze
+      (u min) des Spannungsbereiches am angegebenen Analogausgang und prüft,
+      ob  u min #on("b")#<#off("b")# 'spannung' #on("b")#<#off("b")# u max. Ist das nicht der Fall, erfolgt ein Abbruch
+      mit der Fehlermeldung 'Der Spannungswert ... ist nicht zulässig!". 
+   -  wandelt die angegebene 'spannung' nach der Rechnung: 
+ 
+#on("b")# 
+                           (wert - u min) * 255.0 
+      ausgabewert  = int ( ---------------------- + 0.5 ) 
+                               u max - u min 
+ 
+#off("b")# 
+   -  gibt den ermittelten 'ausgabewert' am angegebenen Kanal aus. 
+ 
+ 
+#on("b")# 
+REAL PROC temperatur (REAL CONST spannungswert) 
+#off("b")# 
+ 
+   -  errechnet aus dem Spannungswert, der vom Temperaturfühler eingelesen
+      wurde, der Thermometerkonstanten und der Minimaltemperatur die
+      Temperatur in �C. 
+   -  liefert einen REAL-Wert (die Temperatur in �C). 
+      So nur anwendbar auf den Temperaturfühler der Fa. AKTRONIK! 
+ 
+ 
+#on("b")# 
+PROC tue nichts 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+#page# 
+#on("b")# 
+PROC warte (INT CONST sekunden) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  wirkt sonst wie 'pause (sekunden * 10)'. 
+ 
+ 
+#on("b")# 
+PROC warte (REAL CONST sekunden) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  wirkt sonst wie 'pause (int (sekunden * 10.0 + 0.5))'. 
+ 
+ 
+#on("b")# 
+PROC wert an analogausgang ausgeben (INT CONST kanal, wert) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine analoge Aus­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Analog-Ausgabe möglich!". 
+   -  ermittelt den auszugebenden Wert durch die Rechnung 
+ 
+#on("b")# 
+#center#ausgabe = wert MOD 256, 
+ 
+#off("b")# 
+      und gibt diesen Wert am angegebenen Kanal aus. Die am Analogausgang
+      auszugebende Spannung wird vom D/A-Wandler des Interface-Systems er­
+      mittelt. 
+#page# 
+#on("b")# 
+INT PROC wert von analogeingang (INT CONST kanal) 
+#off("b")# 
+ 
+   -  untersucht, ob inzwischen die Tastenfolge <ESC><h> eingegeben wurde.
+      Ist das der Fall, dann erfolgt ein Abbruch mit der Fehlermeldung
+      "Programm-Abbruch durch <ESC><h>!". 
+   -  registriert, ob inzwischen die Tastenfolge <ESC><q> eingegeben wurde. 
+   -  untersucht, ob die angegebene Kanalnummer grundsätzlich zulässig ist (1 #on("b")#<#off("b")#
+      'kanal' #on("b")#<#off("b")# 49). Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "Kanalnummer ... ist unzulässig!". 
+   -  untersucht, ob am angegebenen Kanal laut Konfiguration eine analoge Ein­
+      gabe möglich ist. Ist das nicht der Fall, erfolgt ein Abbruch mit der Fehler­
+      meldung "An Kanal ... ist keine Analog-Eingabe möglich!". 
+   -  liefert den vom A/D-Wandler des Interface-Systems gelieferten Wert mit 0 #on("b")#<#off("b")#
+      'lieferwert' #on("b")#<#off("b")# 255. 
+
diff --git a/doc/prozess/gs-prozess-9 b/doc/prozess/gs-prozess-9
new file mode 100644
index 0000000..6551b01
--- /dev/null
+++ b/doc/prozess/gs-prozess-9
@@ -0,0 +1,477 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (1)# 
+#headodd# 
+#center#gs-Prozess#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Prozess
+ 
+#end# 
+#center#1 
+ 
+#on("b")#9  Hinweise für den Systembetreuer/   Programmierer#off("b")# 
+ 
+Sie haben wahrscheinlich bisher - ausschließlich zu Testzwecken - mit nur einem
+Interface-System gearbeitet. In diesem Kapitel möchten wir Ihnen Vorschläge
+machen, wie Sie Ihr Tasksystem organisieren können, um möglichst effektiv und
+störungsfrei mit der vorhandenen Hardware zu arbeiten. 
+ 
+Neben den Möglichkeiten der Organisation des Systems werden wir Ihnen zeigen, wie
+Sie eine einmal vorgenommene Konfiguration/Organisation "fixieren", d.h. schützen
+können. 
+ 
+Im letzten Teil dieses Kapitels werden wir für den #on("b")#routinierten(!) Programmierer#off("b")#,
+Möglichkeiten aufzeigen, wie man, unter weitgehender Umgehung von #on("b")#gs-Prozess#off("b")#,
+Programme für spezielle Anwendungen entwickeln kann. Schon an dieser Stelle sei
+ausdrücklich gesagt, daß dabei alle "Sicherheiten", die #on("b")#gs-Prozess#off("b")# normalerweise
+bietet, nicht (mehr) vorhanden sind. 
+ 
+ 
+#on("b")#9.1  Vergabe der Kanäle/Organisation des Tasksystems#off("b")# 
+ 
+Zur optimalen Organisation Ihres Systems sollten Sie wissen, in welcher Task die
+Konfiguration sinnvollerweise vorzunehmen ist. Da die Aspekte sehr vielfältig sind,
+werden wir verschiedene Situationen beschreiben. Lesen Sie die Ausführungen zu der
+Situation, die der Ihren am ehesten entspricht. 
+ 
+ 
+#on("b")# 
+1)  Es stehen mehrere MUFIs als Adapter zur Verfügung. Alle MUFIs sollen
+    im Terminalkanal betrieben werden. Die Arbeitsplätze sind alle mit
+    dem gleichen Interfacesystem ausgestattet. 
+#off("b")# 
+#page# 
+    Sie sind hervorragend ausgestattet. Die Organisation und Konfiguration des
+    Systems ist sehr einfach: 
+ 
+    Es ist sinnvoll, die Konfiguration von #on("b")#gs-Prozess#off("b")# in der Task vorzunehmen, in
+    der Sie #on("b")#gs-Prozess#off("b")# installiert haben. Das hat den Vorteil, daß alle Sohntasks,
+    die sich anschließend anmelden, diese Konfiguration "erben". 
+ 
+    Bei dieser Ausstattung ist es sinnvoll die Konfiguration zu "fixieren", um irrtüm­
+    lichen oder "böswilligen" Umkonfigurationen vorzubeugen. Sehen Sie dazu
+    Kapitel 9.4. 
+ 
+ 
+#on("b")# 
+2)  Es stehen mehrere MUFIs als Adapter zur Verfügung. Alle MUFIs sollen
+    im Terminalkanal betrieben werden. Die Arbeitsplätze sind aber mit
+    verschiedenen Interface-Systemen ausgestattet. 
+#off("b")# 
+ 
+    Wenn die Bestückung der einzelnen Arbeitsplätze ständig wechselt, ist es nicht
+    sinnvoll, eine generelle Konfiguration vorzugeben. Teilen Sie jedem Anwender
+    mit, daß er selbst für die Konfiguration seines Systems zuständig ist. Er sollte bei
+    jedem Neuankoppeln seiner Task zumindest die Konfiguration überprüfen und
+    ggf. den Vorgaben entsprechend eine Anpassung vornehmen. Es ist nicht sinn­
+    voll, die jeweilige Konfiguration zu fixieren. 
+ 
+    Wenn Sie zwar unterschiedliche Interface-Systeme verwenden, aber die Inter­
+    face-Systeme einzelnen MUFIs eindeutig zuordnen können, lohnt es sich schon,
+    eine Konfiguration des Systems vorzugeben. 
+ 
+    Richten Sie zu diesem Zwecke so viele Tasks ein, wie Sie unterschiedliche
+    Interface-Systeme zur Verfügung haben, und ordnen Sie jedem Interface-System
+    eindeutig je eine Task zu. Die Namen der Tasks sollten Sie so wählen, daß sofort
+    ersichtlich ist, welchem Interface-System sie zugeordnet ist. 
+ 
+    Nehmen Sie in jeder Task eine Konfiguration von #on("b")#gs-Prozess#off("b")# entsprechend
+    dem zugeordneten Interface-System vor. 
+#page# 
+    Auch hier ist es sinnvoll, die vorgenommenen Konfigurationen zu "fixieren", um
+    irrtümlichen oder "böswilligen" Umkonfigurationen vorzubeugen. Sehen Sie
+    dazu Kapitel 9.4. 
+ 
+    Die Anwender sollten sich später jeweils als Sohntask der Task anmelden, die
+    sich dem an ihrem Arbeitsplatz vorhandenen Interface-System eindeutig zu­
+    ordnen läßt. 
+ 
+ 
+#on("b")# 
+3)  Es steht nur ein MUFI als Adapter zur Verfügung. Das MUFI soll im
+    Terminalkanal betrieben werden. 
+#off("b")# 
+ 
+    Je nachdem, ob Sie eine feste Hardware am MUFI betreiben oder nicht, sollten
+    Sie sich an den beiden zuvor beschriebenen Fällen orientieren. 
+ 
+ 
+#on("b")# 
+4)  Es steht nur ein RS232-Adapter oder ein MUFI, das als Endgerät an
+    einer separaten Schnittstelle betrieben werden soll, zur Verfügung. Es
+    soll nur von einem Arbeitsplatz/einer Task aus mit dem angeschlos­
+    senen Interface-System gearbeitet werden. 
+#off("b")# 
+ 
+    Nehmen Sie die Installation/Konfiguration wie unter 5) beschrieben vor.
+    Arbeiten Sie nur in der Task, in der Sie die Konfiguration vorgenommen haben. 
+ 
+ 
+#on("b")# 
+5)  Es steht nur ein Adapter zur Verfügung. Sie wollen aber die Möglichkeit
+    schaffen, daß von verschiedenen Tasks abwechselnd darauf zugegriffen
+    werden kann. 
+#off("b")# 
+ 
+    Es ist gleichgültig, ob Sie ein MUFI oder einen RS232-Adapter verwenden - sie
+    sollten den Adapter an einer separaten seriellen Schnittstelle betreiben. 
+#page# 
+    Auch wenn Sie ein MUFI besitzen, kann es vorteilhaft sein, das MUFI nicht im
+    Terminalkanal, sondern an einer separaten Schnittstelle zu betreiben: 
+ 
+    Beim Betrieb im Terminalkanal kann nämlich nur die Task mit dem MUFI
+    kommunizieren, die an das Terminal gekoppelt ist, in dessen Zuleitung das
+    MUFI eingebaut ist. Das wird hier zum Nachteil, denn wenn eine andere Task
+    auf das Interface-System zugreifen möchte, muß erst die alte Task abgekoppelt
+    und die neue an das Terminal mit dem MUFI angekoppelt werden. 
+ 
+    Der Betrieb an einer separaten Schnittstelle bietet hier wahrscheinlich viel­
+    fältigere Möglichkeiten, wenngleich Sie dadurch auch Geschwindigkeitsein­
+    bußen hinnehmen müssen. 
+ 
+    #on("b")#gs-Prozess#off("b")# bietet Ihnen bei Betrieb eines Adapters an einer separaten seriellen
+    Schnittstelle nämlich die Möglichkeit, abwechselnd von verschiedenen Tasks auf
+    den Adapter und das angeschlossene Interface-System zugreifen zu können. 
+ 
+    Teilen Sie bei der Installation (automatischen Generierung) von #on("b")#gs-Prozess#off("b")#
+    dem System gleich mit, daß Sie Ihren Adapter (ob nun MUFI oder
+    RS232-Adapter) an einer separaten seriellen Schnittstelle betreiben wollen.
+    Schon bei dieser Installation werden Sie nach der Kanalnummer gefragt. 
+ 
+    Wir gehen hier davon aus, daß Sie immer mit dem gleichen Interface-System an
+    diesem Adapter arbeiten werden. In diesem Falle empfiehlt es sich, gleich in der
+    Task, in der Sie die Installation vorgenommen haben, auch die Konfiguration
+    von #on("b")#gs-Prozess#off("b")# vorzunehmen und die Konfiguration zu "fixieren". Durch die
+    Konfiguration in dieser Task, "erben" alle Sohntasks, die anschließend ange­
+    meldet werden, diese Konfiguration. 
+ 
+    Wenn Sie sich mit 'taskinfo <RETURN>' einen Katalog ausgeben lassen,
+    werden Sie feststellen, daß eine weitere Task als unbenannter Sohn ("-") Ihrer
+    Task eingerichtet worden ist. Sie haben nämlich Ihre Task zu einer "zentralen
+    Abwicklungstask" gemacht - genauer gesagt die unbenannte Sohntask. 
+#page# 
+    Wenn Sie aus Ihrer Task, in der Sie die Konfiguration vorgenommen haben, mit
+    dem Interface-System kommunizieren, erfolgt der Zugriff über diese unbe­
+    nannte Sohntask! 
+ 
+    Sie schaffen dadurch aber zusätzlich die Möglichkeit, daß mehrere Sohntasks -
+    natürlich abwechselnd - über diese "zentrale Abwicklungstask" mit dem Inter­
+    face-System kommunizieren. Selbstverständlich setzt der Zugriff auf das Inter­
+    face-System eine Absprache zwischen den Beteiligten voraus! 
+ 
+ 
+    Gerade in der Aufbauphase, wenn erst wenige Geräte zur Verfügung stehen, ist
+    das eine Möglichkeit, von verschiedenen Arbeitsplätzen aus mit nur einem Adap­
+    ter/Interface-System Prozeßdatenverarbeitung zu betreiben. 
+ 
+ 
+#on("b")# 
+6)  Sie wollen mehrere Adapter an separaten seriellen Schnittstellen
+    betreiben. 
+#off("b")# 
+ 
+    In diesem Falle ist es sinnvoll - bevor Sie eine Konfiguration vornehmen - gleich
+    nach der Installation von #on("b")#gs-Prozess#off("b")# für jeden einzelnen Adapter eine Sohntask
+    unter der Task einzurichten, in der #on("b")#gs-Prozess#off("b")# installiert ist. Jede dieser Sohn­
+    tasks koppeln Sie mit einem festen Kanal, an dem ein Adapter/Interface-System
+    angeschlossen ist. 
+ 
+    Sie brauchen dazu #on("b")#gs-Prozess#off("b")# nicht mehrfach zu installieren; wir haben für
+    diesen Fall vorgesorgt. Für die Kopplung der Tasks an die einzelnen Kanäle steht
+    die Prozedur 'PROC interfacekanal (INT CONST kanalnummer)' zur Verfügung.
+    Geben Sie also in einer Task z.B. das Kommando 'interfacekanal (5)
+    <RETURN>', so wird von dieser Task aus das Interface-System am Kanal 5
+    angesprochen. 
+ 
+    Über die Prozedur 'INT PROC interfacekanal' können Sie sich in jeder Task
+    informieren, über welchen Kanal die Kommunikation mit dem Interface-System
+    abgewickelt wird: z.B. mit 'put (interfacekanal) <RETURN>'. 
+#page# 
+    Ihnen ist sicher klar, daß es auch hier sinnvoll ist, den Namen der jeweiligen
+    Task so zu wählen, daß daraus sofort der betreffende Interfacekanal ablesbar
+    ist. 
+ 
+    In jeder so an einen Kanal gekoppelten Task sollten Sie die Konfiguration von
+    #on("b")#gs-Prozess#off("b")# vornehmen und ggf. "fixieren". Jede solche Task richtet auto­
+    matisch eine unbenannte Sohntask ("-") ein, die sich wie eine "zentrale Ab­
+    wicklungstask" verhält. Wenn Sie also aus Ihrer Task oder aus neu einge­
+    richteten Sohntasks mit dem Interface-System kommunizieren, so erfolgt das
+    über die "zentrale Abwicklungstask". 
+ 
+ 
+#on("b")#9.2  Informationsprozeduren#off("b")# 
+ 
+Zur Information stehen dem Systembetreuer drei wichtige Prozeduren zur Verfügung: 
+ 
+#on("b")# 
+TEXT PROC adapterart 
+#off("b")# 
+ 
+Hiermit können Sie in Erfahrung bringen, welche Interfaceanpassung z.Z. in der
+aktuellen Task insertiert ist: MUFI im Terminalkanal, MUFI als Endgerät oder
+AKTRONIK-Adapter (RS232-Adapter). 
+ 
+ 
+#on("b")# 
+INT PROC interfacekanal 
+#off("b")# 
+ 
+Hiermit können Sie in Erfahrung bringen, über welchen Kanal z.Z. mit dem Inter­
+face-System aus der Task kommuniziert wird. Die Prozedur steht allerdings nur dann
+zur Verfügung, wenn das Interface-System an einer separaten Schnittstelle betrieben
+wird - sonst erscheint der Hinweis 'FEHLER: unbekanntes Kommando'. 
+ 
+Es gibt noch einen Befehl, mit dem Sie sich über den Zustand des Interface-Systems
+informieren können: 
+#page# 
+#on("b")# 
+PROC oeffne interface (INT VAR testwert) 
+#off("b")# 
+ 
+Die Prozedur versucht, die aktuelle Betriebsart einzustellen. Anschließend erhalten
+Sie eine 'Erfolgsauskunft'. Dabei bedeuten: 
+ 
+     0  -  alles okay 
+    -1  -  Interface ist noch nicht konfiguriert 
+    -2  -  Interface-Task ist besetzt 
+    -3  -  Interfacekanal ist belegt 
+    -4  -  Interface meldet sich nicht 
+    -5  -  Interface kann nicht geöffnet werden 
+ 
+Ist der Adapter an einer separaten Schnittstelle angeschlossen, so arbeitet der Befehl
+über die "zentrale Abwicklungstask". Als Antwort können alle genannten Codes auftre­
+ten; beim MUFI im Terminalkanal allerdings nur die Codes 0, -1 und -4. Die oben
+genannten Fehlermeldungen sind detailliert in Kapitel 5.5 erläutert. 
+ 
+Sie sollten anschließend #on("b")#unbedingt#off("b")# das Kommando 'schliesse interface' geben: Eine
+eventuell durch 'oeffne interface' vollzogene Betriebsartumstellung wird dadurch
+rückgängig gemacht. 
+ 
+ 
+ 
+#on("b")#9.3  Neufestlegung des Interfacekanals#off("b")# 
+ 
+Wenn Sie mit MUFI(s) im Terminalkanal arbeiten, spielen Kanalnummern für das
+Ansprechen des/der MUFIs keine Rolle. Das jeweilige MUFI kann in diesem Falle
+nämlich immer nur von der Task aus angesprochen werden, die an das Terminal
+gekoppelt ist, in dessen Zuleitung das MUFI eingebaut wurde. 
+ 
+Wenn Sie Adapter (MUFI oder RS232-Adapter) an separaten seriellen Schnittstellen
+betreiben, so legen Sie schon bei der Installation von #on("b")#gs-Prozess#off("b")# den Kanal fest,
+über den die Task mit dem Interface-System kommuniziert. Wie wir schon oben be­
+schrieben haben, können Sie den Interface-Kanal mit der Prozedur 'PROC interface­
+kanal (INT CONST kanalnummer)' neu festlegen. Beachten Sie dabei aber bitte
+folgendes: 
+#page# 
+Wenn Sie in einer Task #on("b")#gs-Prozess#off("b")# konfigurieren und zuvor entschieden haben, daß
+der Adapter an einer separaten Schnittstelle betrieben wird, so wird automatisch eine
+unbenannte Sohntask ("-") eingerichtet. Diese Sohntask wird zur "zentralen Abwick­
+lungstask". Wenn Sie nun aus der Task, in der Sie die Konfiguration vorgenommen
+haben, oder aus einer Sohntask dieser Task, die anschließend eingerichtet wird, mit
+dem Interface-System kommunizieren, so erfolgt diese Kommunikation über diese
+unbenannte Sohntask. Daher wählten wir die Bezeichnung "zentrale Abwicklungs­
+task". 
+ 
+Da die "zentrale Abwicklungstask" den "Zustand der Vatertask" in dem Augenblick
+erbt, in dem Sie eingerichtet wird, würde eine später erfolgende Neufestlegung des
+Interfacekanals nicht von Ihr registriert und damit auch nicht wirksam. 
+ 
+#on("b")#Es ist unbedingt notwendig#off("b")#, in der Task, in der Sie eine Neufestlegung des Interface-
+Kanals vornehmen, #on("b")#gs-Prozess#off("b")# auch neu zu konfigurieren! Bei der Neukonfiguration
+wird nämlich die unbenannte Sohntask gelöscht und neu eingerichtet. 
+ 
+(Das hier beschriebene Phänomen ist Ihnen wahrscheinlich schon aus der
+PRINTER-Task bekannt). 
+ 
+Hinsichtlich der Sicherheit des Systems hat dieses Vorgehen aber einen Vorteil: wenn
+in den "zugänglichen Sohntask", die über eine "zentrale Abwicklungstask" mit dem
+Interface-System kommunizieren eine Neueinstellung des Interface-Kanals vorge­
+nommen wird, so bleibt diese unwirksam (solange in der Sohntask nicht umkonfigu­
+riert wird - was sich aber verhindern läßt! Sehen Sie dazu das folgende Kapitel!). 
+ 
+ 
+#on("b")#9.4  Fixieren der Konfiguration#off("b")# 
+ 
+Prinzipiell kann in jeder Task, in der #on("b")#gs-Prozess#off("b")# zur Verfügung steht, die Konfigura­
+tion (von #on("b")#gs-Prozess#off("b")#) vorgenommen werden. Gerade von unerfahrenen Anwendern
+könnte aber irrtümlich eine Umkonfiguration vorgenommen werden. Aber nicht nur
+das: auch erfahrene Anwender könnten "böswillig" die Konfiguration verändern. Aus
+diesem Grunde ist es ggf. sinnvoll, eine vorgenommene Konfiguration zu fixieren
+(schützen). 
+#page# 
+Dazu steht die Prozedur 'PROC pdv konfiguration zugelassen (BOOL CONST ent­
+scheidung)' zur Verfügung. Mit dem Kommando 'pdv konfiguration zugelassen
+(FALSE) <RETURN>' sperren Sie in der aktuellen Task und in allen Sohntasks, die
+sich #on("b")#anschließend#off("b")# unter dieser Task anmelden, den Menupunkt 'k Konfigurieren'
+unter dem Oberbegriff 'Interface'. 
+ 
+Sofern nötig, können Sie diese Sperre mit dem Kommando 'pdv konfiguration zuge­
+lassen (TRUE) <RETURN>' wieder aufheben, #on("b")#allerdings nur in der Task, in der Sie
+auch die Sperre gesetzt haben#off("b")#, denn #on("b")#gs-Prozess#off("b")# merkt sich diesen Tasknamen!
+Wenn Sie also ein Password auf diese Task legen, und damit anderen den Zugang
+verwehren, kann auch eine "böswilligie Umkonfiguration" verhindert werden. 
+ 
+ 
+#on("b")#9.5  Mögliche Fehlerfälle#off("b")# 
+ 
+Wenn Fehlermeldungen auftreten, so finden Sie Fehlerbeschreibungen und Möglich­
+keiten zur Abhilfe im Kapitel 5.5 beschrieben. Auf einen Fehlerzustand möchten wir
+Sie hier noch besonders hinweisen: 
+ 
+#on("b")#Interfacekanal ist belegt!#off("b")# 
+ 
+   Über den angegebenen Kanal greift schon eine andere Task auf das angeschlos­
+   sene Interface-System zu. Vielleicht wurde der betreffende Kanal auch zuvor für
+   andere Zwecke verwendet - anschließend hat der Benutzer den Kanal nicht
+   ordentlich freigegeben. Geben Sie in der 'gib kommmando'-Ebene den Befehl
+   'taskinfo (2) <RETURN>'. In der Spalte mit der Überschrift 'CHAN' müßte jetzt
+   irgendwo die Kanalnummer auftauchen. Steht die Kanalnummer bei einem Sohn
+   der Task 'SUPERVISOR', so liegt der letztgenannte Fall vor, sonst der erstge­
+   nannte. 
+ 
+   Abhilfe:  Schließen Sie Ihr Interface-System an einen anderen Kanal an oder
+             bitten Sie den betreffenden Anwender, den Kanal freizugeben. 
+             Ist das nicht möglich, so kann aus einer Systemtask das Kommando
+             'end (canal (kanalnummer))' <RETURN>' gegeben werden. Statt
+             'kanalnummer' ist natürlich die tatsächliche Nummer (z.B. '4')
+             anzugeben. 
+#page# 
+#on("b")#9.6  Weitere Möglichkeiten#off("b")# 
+ 
+Ihnen ist sicher aufgefallen, daß wir uns bemüht haben, einen sinnvollen Kompro­
+miß zwischen Sicherheit in der Handhabung und Geschwindigkeit des Systems zu
+finden. In Zweifelsfällen haben wir uns eher zugunsten der Sicherheit entschieden. 
+ 
+Sicher werden Sie inzwischen bemerkt haben, daß die Kommunikation mit einem
+Adapter (MUFI oder RS232-Adapter) an einer separaten seriellen Schnittstelle recht
+zeitaufwendig ist. 
+ 
+Prinzipiell standen uns bei der Konzeption zwei Möglichkeiten zur Verfügung: Ent­
+weder wir gestalten jeden Basisbefehl so, daß wir uns zu Beginn der Ausführung
+jeweils direkt an den betreffenden Kanal ankoppeln und am Ende der Ausführung
+des Befehls wieder abkoppeln - oder wir richten eine "zentrale Abwicklungstask" ein
+und nutzen die Intertaskkommunikation des EUMELs. Wir haben uns nach diversen
+Tests für die zweite Variante entschieden: Einmal zeigte sich, daß dieses Verfahren
+weit weniger zeitaufwendig ist als das ständige An- und Abkoppeln an den Interface-
+Kanal. Zum anderen konnten wir so die Möglichkeit schaffen, über diese "zentrale
+Abwicklungstask" den abwechselnden, koordinierten Zugriff mehrerer Tasks auf ein
+Interface-System zu realiseren. 
+ 
+Wenn Sie nun aber spezielle Anwendungen schreiben wollen, für die die Geschwin­
+digkeit beim Ansprechen des Interface-Systems an einer separaten Schnittstelle nicht
+ausreicht, so möchten wir Ihnen hier noch eine Möglichkeit aufzeigen, dieses
+Problem zu bewältigen. 
+ 
+Auch an dieser Stelle sei noch einmal ausdrücklich darauf hingewiesen, daß Sie bei
+dieser Programmiermöglichkeit auf alle Sicherheiten, die Ihnen #on("b")#gs-Prozess#off("b")# bietet,
+verzichten müssen. Deshalb sollten Sie diesen Weg nur beschreiten, wenn Sie ein
+hinlängliches Maß an Programmierroutine besitzen! Die zur Verfügung stehenden
+Befehle und die Besonderheiten möchten wir Ihnen an einem kleinen Beispiel­
+programm aufzeigen: 
+#page# 
+#on("b")# 
+   LET ausgabekanal = 4, 
+       eingabekanal = 3; 
+ 
+  INT VAR test, eingabewert; 
+  INT VAR terminalkanal :: channel (myself); 
+  schliesse interface; 
+  continue (interfacekanal); 
+  oeffne interface direkt (test); 
+  IF test < 0 
+     THEN continue (terminalkanal); 
+          errorstop ("Funktionsfehler Interface-System") 
+  FI; 
+  initialisiere interface direkt; 
+  eigentliches programm; 
+  schliesse interface direkt; 
+  continue (terminalkanal). 
+ 
+  eigentliches programm: 
+    direkt ausgeben (ausgabekanal, 3); 
+    eingabewert := direkteingabe (eingabekanal). 
+#off("b")# 
+ 
+Wenn Sie ein solches Programm geschrieben haben, starten Sie es bitte mit dem
+Befehl 'run pdv' oder aus dem Menusystem heraus mit der Menufunktion 's Starten'.
+(Bei 'run' kann der Befehl 'schliesse interface' gestrichen werden!). 
+ 
+Für die eigentliche Programmierung des Interface-Systems stehen Ihnen nur zwei
+Befehle zur Verfügung: 
+ 
+#on("b")# 
+PROC direkt ausgeben (INT CONST kanal, wert) 
+#off("b")# 
+ 
+   -  ermittelt den auszugebenden Wert durch die Rechnung 
+ 
+#on("b")##center#ausgabe = wert MOD 256#off("b")# 
+ 
+      und gibt diesen am Ausgabekanal aus. 
+ 
+      Der Befehl ähnelt dem Befehl 'dezimalwert ausgeben' - hat aber im Gegensatz
+      dazu keinerlei "Fehlerfänger": so werden Sie z.B. nicht darauf aufmerksam
+      gemacht, wenn der angegebene Kanal gar kein Ausgang ist, etc.) 
+#page# 
+#on("b")# 
+INT PROC direkteingabe (INT CONST kanal) 
+#off("b")# 
+ 
+   -  liest den aktuell anliegenden Wert am angegebenen Kanal ein. 
+   -  liefert einen INT-Wert mit 0 � 'wert' � 255. 
+ 
+      Der Befehl ähnelt dem Befehl 'dezimalwert' - hat aber im Gegensatz dazu
+      ebenfalls keinerlei "Fehlerfänger"! 
+ 
+ 
+Das obige Programm beginnt mit dem Befehl 'schliesse interface'. Sicher kommt es
+Ihnen sonderbar vor, daß zu Beginn des Programms das Interface geschlossen wird,
+wo wir es doch eigentlich "öffnen" müßten. Ihnen wird die Funktion aber sofort klar,
+wenn Sie sich die Situation vor Augen führen: 
+ 
+Als Sie #on("b")#gs-Prozess#off("b")# in Ihrer Task konfiguriert haben, und festlegten, daß der Adapter
+an einer separaten Schnittstelle "hängt", richtete #on("b")#gs-Prozess#off("b")# automatisch eine
+unbenannte Sohntask ("-") als "zentrale Abwicklungstask" ein, die durch das
+Kommando 'run pdv' bzw. durch die Menufunktion 's Starten' an den Interfacekanal
+gekoppelt wird. Der Befehl 'schliesse interface' koppelt die Task "-" wieder vom Inter­
+face-Kanal ab, so daß Sie direkt darauf zugreifen können. Außerdem werden die
+internen Einstellungen im Adapter wieder in Ausgangsstellung gebracht. 
+ 
+Mit der Prozedur 'PROC oeffne interface direkt (INT VAR testwert)' sprechen Sie das
+Interface neu an. Dabei wird ein angeschlossener Adapter automatisch auf Betriebs­
+bereitschaft getestet und dann auf den Betrieb an einer separaten seriellen Schnitt­
+stelle umgestellt (nur beim MUFI). 
+ 
+Über 'testwert' erhalten Sie eine Rückmeldung. Dabei haben die gelieferten 'test­
+werte' folgende Bedeutung: 
+ 
+     0  -  Interface betriebsbereit 
+    -4  -  Interface #on("b")#nicht#off("b")# betriebsbereit 
+           (Interface meldet sich nicht) 
+#page# 
+Der Befehl 'initialisiere interface direkt' wirkt ähnlich wie der schon oben be­
+schriebene Befehl 'initialisiere interface', jedoch #on("b")#nicht#off("b")# über den "Umweg zentrale
+Abwicklungstask" - sondern halt 'direkt' am Interface-Kanal. Einzige Aufgabe hier:
+Alle Ausgabe-Kanäle auf Wert '0' bzw. Nullspannung setzen. 
+ 
+Durch das abschließende 'schliesse interface direkt' bringen Sie ein angeschlossenes
+MUFI wieder in die "Ausgangsstellung". 
+ 
+Beachten Sie bei der Programmierung bitte unbedingt, daß Sie ständig zwischen dem
+Kanal, an dem Sie arbeiten (Terminal) und dem Interfacekanal hin- und herschalten
+(müssen), wenn Ein- oder Ausgaben auf dem Terminal erfolgen sollen. Die direkte
+Programmierung lohnt sich demnach nur, wenn aufeinanderfolgende Aktionen am
+Interfacekanal durchgeführt werden (z.B. Schrittmotorsteuerungen etc.). 
+ 
+Treten Programmfehler auf, während Sie an den Interfacekanal gekoppelt sind,
+haben Sie keine Chance, von Ihrem Terminalkanal aus auf das Interface zuzugreifen
+- denn das "hängt am Interfacekanal" (z.B. bei "Programmabsturz" oder Endlos­
+schleife). 
+ 
+Bei Ihrer Programmierung sollten Sie diesem Fall vorbeugen (disable stop - enable
+stop). Ansonsten müßten Sie aus einer Systemtask den Kanal "abschießen". Geben
+Sie dazu in einer Systemtask z.B. das Kommando 'end (canal (5)) <RETURN>',
+wenn das Interface-System über den Kanal 5 angesprochen wird. 
+
diff --git a/doc/system/systemhandbuch.1 b/doc/system/systemhandbuch.1
new file mode 100644
index 0000000..a8f53bb
--- /dev/null
+++ b/doc/system/systemhandbuch.1
@@ -0,0 +1,1685 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#Systemhandbuch 
+ 
+ 
+ 
+ 
+#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# 
+#start(5.1,1.5)# 
+#free(4.0)# 
+#center#EUMEL 
+ 
+ 
+#center#Systemhandbuch 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+#center#copyright ERGOS GmbH, 1990 
+ 
+ 
+#page# 
+#block# 
+ 
+Copyright:  ERGOS GmbH   April 1990 
+ 
+                     Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+                     maschinenlesbare Form sowie das Speichern in Informations­
+                     systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+                     der ERGOS GmbH gestattet. 
+ 
+ 
+           +-----------------------------------------------------+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+Autoren                  :  Jochen Liedtke 
+                   Dietmar Heinrichs 
+                   Rainer Hahn 
+                   Christian Szymanski 
+                   Thomas Müller 
+ 
+Texterstellung   :  Dieser Text wurde mit der ERGOS-EUMEL Textverarbeitung erstellt 
+                   und aufbereitet und auf einem Kyocera Laserdrucker ge­
+                   druckt. 
+#page#
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+            +----------------------------------------------+ 
+ 
+ 
+ 
+ 
+#page# 
+ 
+#start(2.5,1.5)# 
+#pageblock# 
+#block# 
+#headeven# 
+ 
+%#center#EUMEL-Systemhandbuch 
+ 
+ 
+#end# 
+#headodd# 
+ 
+#center#Einführung#right#% 
+ 
+ 
+#end# 
+ 
+#ib(9)#Einführung#ie(9)# 
+ 
+Der größte Teil dieses Systemhandbuchs ist für Anwender geschrieben, die tiefer in
+das EUMEL-System einsteigen und evtl. Systemergänzungen oder Systemänderun­
+gen programmieren wollen. Der erste Teil ist allerdings für alle interessant, die ein
+EUMEL-System verwenden, selbst für Anfänger, die ihr System zum ersten Mal in
+Betrieb nehmen wollen. Entsprechend der verschiedenen Adressatenkreise unter­
+scheiden sich die einzelnen Kapitel stark in der Beschreibungsart. Deshalb: 
+ 
+#on("b")##on("i")#Sind Sie EUMEL-Neuling?#off("b")##off("i")# 
+ 
+     Dann sollten Sie #on("b")##on("i")#vor#off("b")##off("i")# dem Einschalten Ihres Systems die Einführung des Kapi­
+     tels "System einrichten" lesen. Dort werden keine weiteren Kenntnisse voraus­
+     gesetzt. Danach sollten Sie erst einmal durch praktisches Arbeiten mit Hilfe des
+     Benutzerhandbuchs etwas mit dem System vertraut werden. 
+ 
+ 
+#on("b")##on("i")#Haben Sie schon einige Zeit mit dem EUMEL gearbeitet?#off("b")##off("i")# 
+#on("b")##on("i")#Sind Sie mit dem System einigermaßen vertraut?#off("b")##off("i")# 
+ 
+     Dann lesen Sie den kompletten Teil 1 ("System einrichten") dieses Systemhand­
+     buchs. 
+     Das Lesen der folgenden Kapitel ist für den einfachen Betrieb des EUMEL-
+     Systems nicht erforderlich. Sie setzen auch intime Kenntnis des Systems auf
+     dem Niveau des Benutzerhandbuchs voraus und würden Anfänger leicht verwir­
+     ren. 
+ 
+ 
+#on("b")##on("i")#Haben Sie Probleme mit Ihrer Hardware?#off("b")##off("i")# 
+ 
+     #on("i")#Wenn Sie nichts von Hardware verstehen, wenden Sie sich an einen Fachmann!#off("i")# 
+ 
+     Wenn Sie ein gewisses Grundwissen über Hardware haben, dann lesen Sie Teil 2
+     ("Hardware und ihre Steuerung"). In diesem Kapitel sollten Sie "3. Kanä­
+     le und Konfigurierung" erst einmal auslassen. 
+ 
+ 
+#on("b")##on("i")#Wollen Sie tiefer in das Betriebssystem einsteigen?#off("b")##off("i")# 
+#on("b")##on("i")#Haben Sie EUMEL-Erfahrung?#off("b")##off("i")# 
+#on("b")##on("i")#Haben Sie Programmiererfahrung?#off("b")##off("i")# 
+ 
+     Dann lesen Sie im Systemhandbuch alles, was Ihnen interessant erscheint. 
+#page# 
+#headeven# 
+ 
+%#center#EUMEL-Systemhandbuch 
+ 
+ 
+#end# 
+#headodd# 
+ 
+#center#1. System einrichten#right#% 
+ 
+ 
+#end# 
+ 
+#ib(9)#1. #ib#System einrichten#ie##ie(9)# 
+ 
+#ib(9)#1.1. Einführung#ie(9)# 
+ 
+#ib(9)#Wie Ihr System aufgebaut ist#ie(9)# 
+ 
+Der kleinstmögliche EUMEL-Rechner besteht aus einem #ib#Rechnerkern#ie# und einem Ter­
+minal: 
+ 
+ 
+           Rechnerkern              Terminal 1 
+ 
+ 
+     #on("i")#Anmerkung: In manchen Fällen ist das Terminal hardwaremäßig in den Rechner
+                integriert. Trotzdem fassen wir diese physische Einheit dann als
+                zwei logisch getrennte Komponenten auf, nämlich Rechnerkern
+                und Terminal!#off("i")# 
+ 
+Wie man sieht, hat das #ib#Terminal#ie# die Nummer 1. Das bedeutet, daß es über Kanal 1 mit
+dem Rechnerkern verbunden ist. Das EUMEL-System kennt 16 solche #ib#Kanäle#ie#, wobei es
+von der konkreten Hardware abhängt, welche Kanäle wirklich vorhanden sind und
+welche Geräte man daran anschließen kann. (Allerdings ist der Kanal 1 als Verbindung
+zum Terminal 1 immer vorhanden.) 
+ 
+In den meisten Fällen wird auch ein #ib#Drucker#ie# angeschlossen sein. Die genaue An­
+schlußart ist wieder von der konkret verwendeten Hardware abhängig. Nehmen wir an,
+er sei an Kanal 4 angeschlossen: 
+ 
+ 
+ 
+           Rechnerkern              Terminal 1 
+ 
+                                    Drucker (Kanal 4) 
+ 
+ 
+ 
+Man sieht also, daß Lücken bei der Verwendung der Kanäle auftreten dürfen. Bei
+Multi-User-Systemen können, sofern die entsprechenden Schnittstellen vorhanden
+sind, weitere Terminals und andere Geräte (z.B. #ib#Plotter#ie#) angeschlossen werden: 
+ 
+ 
+ 
+           Rechnerkern               Terminal 1 
+ 
+                                     Terminal 2 
+ 
+                                     Plotter (Kanal 3) 
+ 
+                                     Drucker (Kanal 4) 
+ 
+                                     Terminal 5 
+ 
+                                     Terminal 6 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#1.2. Wie Sie die EUMEL-Software erhalten und 
+     installieren#ie(9)# 
+ 
+ 
+ 
+Betriebssystem  :  EUMEL (Version 1.8) 
+Hardware        :  IBM-PC/AT, IBM-PC/XT und Kompatible 
+SHard-Version   :  4.9 und 5.0 
+ 
+Erforderliche Disketten 
+ 
+   -  EUMEL-Generierungsdiskette   :  "SETUP-EUMEL AT" (bzw. "SETUP-
+                                      EUMEL XT") 
+   -  EUMEL-Systemdisketten        :  "HG0" und "HG1" (EUMEL0-Maschine
+                                       und Hintergrund) evtl. auch nur eine 1,2
+                                       MB Hintergrunddiskette 
+ 
+Die Diskette "SETUP-EUMEL" ist ein kleines EUMEL-System zur Installation des Be­
+triebssystems EUMEL auf einem AT/XT kompatiblen Rechner. Auf diesem System
+laufen Programme ab, die im Dialog mit dem Benutzer das Einrichten einer oder
+mehrerer EUMEL-Partitionen ermöglichen. 
+#on("b")#Diese Diskette darf nicht schreibgeschützt sein!#off("b")# 
+ 
+Beim Einrichten einer EUMEL-Partition wird nach Prüfung der Festplatte durch
+"SETUP-EUMEL" der hardwarenahe Teil des EUMEL-Systems, 'SHard' (Software/
+Hardware-Interface), auf die Festplatte geschrieben. 
+ 
+Die Hintergrunddisketten beinhalten das eigentliche Betriebssystem EUMEL (den
+Systemkern (EUMEL-0-Maschine)) und die darauf aufbauenden Systemteile (Hinter­
+grund)). 
+ 
+ 
+Leistungen des SETUP EUMEL 
+ 
+Wenn Sie bereits ein Betriebssystem auf Ihrer Festplatte installiert haben, müssen Sie
+darauf achten, daß noch ausreichend Platz für ein EUMEL-System übrig ist. Die Min­
+destgröße einer Partition für ein EUMEL-System beträgt ca. 1MB, die maximale Größe
+ist vom benutzten Systemkern abhängig: der in der Version 1.8.6 M+ verwendete
+Systemkern u186+ \#1523 erlaubt eine maximale Größe von 128 MB. Andere, ältere
+EUMEL Versionen erlauben nur eine Partitionsgröße von 16 MB. Aus Kompatibilitäts­
+gründen stellt das Installationsprogramm eine Kontrollfrage bei Überschreiten der 16
+MB Grenze. 
+ 
+Soll neben EUMEL auch eine MS-DOS Partition auf der Festplatte sein, muß, da
+MS-DOS standardmäßig die gesamte Festplatte belegt, dieses System gesichert, mit
+dem MS-DOS-Kommando 'fdisk' (o.ä.) die Partition gelöscht und entsprechend kleiner
+neu eingerichtet werden. Sie können auch bei der EUMEL-Installation alle bereits
+bestehenden Systeme löschen; dazu bietet Ihnen der SETUP-EUMEL die Option
+'Löschen der gesamten Partitionstabelle' an. Dabei gehen jedoch alle Daten auf der
+Festplatte verloren. Achten Sie also darauf, daß sie alle Daten vorher gesichert haben! 
+ 
+Um nun die Partitionierung für Ihr EUMEL-System vorzunehmen, legen Sie die Diskette
+"SETUP-EUMEL" ohne Schreibschutzmarke in das Start-Laufwerk. Sollten Sie ein Gerät
+mit zwei Laufwerken besitzen, dann ist es das Laufwerk A:. (Bei Unklarheiten im Benut­
+zerhandbuch des Herstellers nachsehen.) 
+ 
+Schalten Sie nun den Rechner ein bzw. betätigen Sie den Tastatur-RESET, wenn Ihr
+Gerät bereits eingeschaltet ist (meistens mit dem gleichzeitigen Druck der Tasten
+CTRL, ALT und DEL). 
+ 
+Der SETUP-EUMEL gibt zunächst folgende SHard-Meldung aus: 
+ 
++--------------------------------------------+ 
+i                                            i 
+i Setup-SHard für EUMEL auf IBM PC/AT, V 4.8 i 
+i Copyright (C) 1989 ERGOS GmbH, Siegburg    i 
+i                                            i 
++--------------------------------------------+ 
+ 
+Warten Sie beim Hochfahren des SETUP-EUMELs, bis Ihnen nach einem Zwischen­
+bildschirm ("SETUP-EUMEL für Modul-SHard") eine Partitionstabelle angezeigt wird.
+Dieser können Sie entnehmen, ob bereits Partitionen auf der Festplatte eingerichtet
+und wie diese spezifiziert sind. 
+ 
+Angezeigt werden neben Größe, Start- und Endspur der einzelnen Partitionen auch
+eine Typ-Nummer. Für EUMEL-Partitionen werden in aufsteigender Reihenfolge die
+Typ-Nummern 69 bis 72, für MS-DOS je nach Größe der eingerichteten Partition die
+Nummern 1 oder 4 vergeben. Außerdem wird die gerade aktive Partition durch einen
+entsprechenden Eintrag in der Tabelle kenntlich gemacht. "Aktiv" ist die Partition, die
+nach dem nächsten Einschalten des Rechners bzw. nach dem nächsten Tastatur-
+RESET gestartet würde. 
+ 
+ 
+Sie sehen zusätzlich ein Menü mit folgenden zur Auswahl stehenden Funktionen: 
+ 
++------------------------------------------------------------+ 
+i                                                            i 
+i   -  EUMEL-Partition einrichten                  1         i 
+i   -               erneuern (Neuer SHard)         2         i 
+i   -               aktivieren                     3         i 
+i   -               löschen                        4         i 
+i   -  Partitionstabelle löschen                   5         i 
+i   -  SHard-Konfiguration anzeigen                6         i 
+i   -  SHard konfigurieren                         7         i 
+i   -  SHardmodule laden oder löschen              8         i 
+i   -  SETUP-EUMEL beenden                         0         i 
+i                                                            i 
++------------------------------------------------------------+ 
+ 
+#on("i")##on("u")#EUMEL - Partition einrichten #off("u")##off("i")# 
+ 
+Eine neue EUMEL-Partition wird gemäß den im weiteren erfragten Angaben eingerich­
+tet. In die Partition wird ein SHard geschrieben, dessen Konfiguration die gelieferte
+Grundkonfiguration oder die von Ihnen eingestellte ist (s. Partitionieren der Festplatte,
+Seite 3). 
+ 
+ 
+#on("i")##on("u")#EUMEL - Partition erneuern (Neuer SHARD)#off("u")##off("i")# 
+ 
+In eine bereits vorhandene Partition wird ein SHard in der eingestellten Konfiguration
+geschrieben. Der bis dahin vorhandene SHard wird überschrieben. Die Möglichkeit
+besteht jedoch nur, wenn die Partition mit einem SETUP-EUMEL eingerichtet worden
+ist. 
+ 
+Erneuern bedeutet, nur den SHard #on("u")#auszutauschen#off("u")# auf einer Partition, die schon einen
+fertigen EUMEL enthält, ohne daß man dabei den EUMEL löscht. Das ist dann sinnvoll,
+wenn man eine neue Version des SHard benutzen möchte oder den SHard aus ir­
+gendwelchen Gründen (z.B. Streamer gekauft) um einen oder mehrere Module erwei­
+tern will. 
+ 
+Diese Aktion kann nur durchgeführt werden, wenn bereits ein SHard mit der Versions­
+nummer 4.x in dieser Partion vorhanden ist. Ältere (Version 2.7, 2.8 etc.) können #on("u")#nicht#off("u")#
+ersetzt werden. 
+ 
+ 
+#on("i")##on("u")#EUMEL - Partition aktivieren#off("u")##off("i")# 
+ 
+Eine Partition wird ausgewählt und aktiv gesetzt, d.h. beim nächsten Start des Re­
+chners wird das System, das auf dieser Partition steht, hochgefahren. 
+ 
+ 
+#on("i")##on("u")#EUMEL - Partition löschen #off("u")##off("i")# 
+ 
+Hierbei wird ein Eintrag aus der Partitionstabelle entfernt. Die EUMEL-Partition wird
+nicht wirklich gelöscht, d.h. wenn man nach dem Löschen den Plattenbereich noch
+nicht anderweitig verwendet hat, kann das EUMEL-System auf dieser Partition durch
+ein "EUMEL-Partition einrichten" auf genau demselben Plattenbereich (Start-/Endzy­
+linder) wieder hergestellt werden. 
+ 
+ 
+#on("i")##on("u")#Partitionstabelle löschen#off("u")##off("i")# 
+ 
+Dies ist eine sehr gefährliche Option ! 
+Es werden hiermit #on("u")##on("b")#alle#off("b")##off("u")# Partitionen auf der Platte gelöscht (nicht nur die von EUMEL).
+Auch hier gilt zwar, daß die Partitionen selbst an sich unangetastet bleiben und wie­
+derhergestellt werden könnten, aber dies ist bei anderen Betriebssystemen oft nicht
+möglich. Also #on("u")#VORSICHT#off("u")#. 
+ 
+ 
+#on("i")##on("u")#SHard-Konfiguration anzeigen #off("u")##off("i")# 
+ 
+Die Module des SHard, der bereitgestellt ist, um auf die Platte geschrieben zu werden,
+werden angezeigt. Es werden alle definierten Kanäle angezeigt und zu jeder Kanal­
+nummer der assoziierte Modulname. Aufgelistet ist die zuletzt mit dem SETUP-EUMEL
+zusammengestellte Konfiguration. 
+ 
+ 
+#on("i")##on("u")#SHard konfigurieren #off("i")##off("u")# 
+ 
+Zusammenstellen von einer SHardbasis und SHardmodulen zu einem neuen SHard,
+um eine neue Partition einzurichten oder den SHard einer bestehenden Partition zu
+ersetzen. 
+ACHTUNG:   Bitte diesen Menuepunkt nicht experimentell benutzen! Eine Anleitung
+           zum Thema Module etc. wird separat erscheinen. 
+#page# 
+#on("i")##on("u")#SHardmodule laden oder löschen #off("u")##off("i")# 
+ 
+Hiermit können neue Module oder neue Versionen von Modulen in den SETUP-EUMEL
+geladen werden oder nicht mehr benötigte Module gelöscht werden. Die neuen Modu­
+le werden von einer EUMEL-Archivdiskette gelesen, deren Name zuvor eingegeben
+werden muß. 
+ACHTUNG:   Bitte diesen Menüpunkt nicht experimentell benutzen! Eine Anleitung
+           zum Thema Module etc. wird separat erscheinen. 
+ 
+ 
+#on("i")##on("u")#SETUP-EUMEL beenden #off("u")##off("i")# 
+ 
+SETUP-Programm ordnungsgemäß beenden. 
+ENDE-Meldung abwarten! 
+ 
+ 
+ 
+ 
+Die eigentliche Partitionierung beginnt nun, indem Sie Menü-Punkt 1 "EUMEL-Partition
+einrichten" anwählen. (Punkt 1 wird Ihnen nur dann #on("b")#nicht#off("b")# angeboten, wenn die Fest­
+platte bereits vollständig belegt ist. Sichern Sie dann das alte System und löschen eine
+oder alle Partitionen.) Die Kontrollabfrage "Neue EUMEL-Partition einrichten? (j/n)"
+beantworten Sie entsprechend mit "j". 
+ 
+Beim Generieren einer EUMEL-Partition werden Angaben zu Größe und Startzylinder
+abgefragt. Dafür werden Vorgaben gemacht, die Sie bestätigen, indem Sie die
+<RETURN>-Taste betätigen, oder die Sie überschreiben können. Die abschließende
+Abfrage "Sind die Partitionsangaben korrekt?" fordert Sie zur Überprüfung Ihrer Einga­
+ben auf. 
+ 
+Nach der Eingabe und der Überprüfung der Sektoren erscheint eine Meldung wie z.B.: 
+ 
++--------------------------------------------------+ 
+i                                                  i 
+i   Ich habe keine schlechten Sektoren gefunden    i 
+i   SHard wird auf die Partition geschrieben       i 
+i   Bitte betätigen Sie eine Taste!                i 
+i                                                  i 
++--------------------------------------------------+ 
+ 
+oder 
+ 
++--------------------------------------------------+ 
+i                                                  i 
+i   Ich habe 2 schlechte Sektoren gefunden         i 
+i   SHard wird auf die Partition geschrieben       i 
+i   Bitte betätigen Sie eine Taste!                i 
+i                                                  i 
++--------------------------------------------------+ 
+ 
+Danach gelangen Sie wieder in das Generierungsmenü. Wählen Sie "0" für "SETUP-
+EUMEL beenden". Über eine Sicherheitsfrage verlassen Sie nun den ersten Teil der
+Installation. Warten Sie #on("b")#unbedingt#off("b")#, bis auf dem Bildschirm die Meldung "ENDE" er­
+scheint, bevor Sie die Diskette "SETUP EUMEL" aus dem Laufwerk nehmen. 
+ 
+ 
+ 
+Installieren eines EUMEL-Hintergrundes 
+ 
+Im nächsten Schritt wird auf ihrer Festplatte das vollständige EUMEL-System instal­
+liert. 
+ 
+Bitte betätigen Sie den Tastatur-Reset an Ihrem Rechner (oder die Tasten CTRL, ALT
+und DEL oder den AUS-/EIN-Schalter). 
+ 
+Auf dem Bildschirm erscheint die folgende Meldung: 
+ 
++--------------------------------------------------------------------------+ 
+i                                                                          i 
+i  SHard für EUMEL auf IBM PC,AT,XT, V 4.7                                 i 
+i  Copyright (c) 1985, 86, 87, 88, 89 Martin Schönbeck Beratungen GmbH,    i 
+i     Spenge                                                               i 
+i  Ladevorgang kann durch Tastendruck unterbrochen werden                  i 
+i  Habe leider keine EUMEL-0-Maschine gefunden                             i 
+i  Ladevorgang unterbrochen, drücken Sie eine Taste um fortzufahren.       i 
+i                                                                          i 
++--------------------------------------------------------------------------+ 
+ 
+Legen Sie nun die erste Hintergrunddiskette (HG0) in das Laufwerk ein und betätigen
+Sie eine Taste. Der Systemkern wird geladen und es erscheinen Angaben zu HG-,
+RAM-, und Pufferkapazität sowie zu den angeschlossenen Kanälen, diesmal jedoch
+bezogen auf die Festplatten-Partition. Warten Sie nun, bis die Meldung "HG ungültig"
+kommt. Drücken Sie anschließend eine beliebige Taste. 
+Falls Sie in ein bereits bestehendes EUMEL-System einen neuen Urlader einspielen
+wollen, lesen Sie bitte den Abschnitt "Installation eines neuen Urladers". 
+ 
+#page# 
+#free(1.0)# 
+Ein Menü bietet Ihnen dann folgende Auswahl: 
+ 
++-----------------------------------------+ 
+i                                         i 
+i    (1)  Systemstart                     i 
+i    (2)  Hintergrund vom Archiv laden    i 
+i    (3)  Hardwaretest                    i 
+i    (4)  neuen Urlader vom Archiv laden  i 
+i                                         i 
++-----------------------------------------+ 
+ 
+Wählen Sie Menü-Punkt (2) "Hintergrund vom Archiv laden" und bestätigen Sie die
+Abfrage "Alten HG überschreiben?" mit "j". 
+ 
+Das Laden des Hintergrundes kann einige Minuten in Anspruch nehmen. Sie werden
+mit der Meldung "Nächstes HG-Archiv eingelegt? (j/n)" zum Einlegen der Folgedisket­
+te(n) aufgefordert, was Sie anschließend mit der Eingabe von "j" quittieren. 
+ 
+Es können bei beschädigten Disketten Lesefehler auftreten; dann gibt das System eine
+der Meldungen 'Harter Lesefehler' bzw. 'Softerror' aus. Bei letzterem könnte der ent­
+sprechende Sektor nach mehrmaligem Versuch noch gelesen werden. Bei einem
+harten Lesefehler können Sie die Diskette nicht verwenden. Bitte benachrichtigen Sie
+die Firma, von der Sie die Disketten erhalten haben. 
+ 
+Wenn der Hintergrund eingelesen ist, erscheint die Aufforderung 'fertig, bitte RESET'.
+#on("b")#Vergessen Sie nicht#off("b")#, vor der Betätigung des Tastatur-RESET die Hintergrunddiskette
+aus dem Diskettenlaufwerk zu entfernen. 
+ 
+Wenn Sie während des Hochfahrens keine Taste drücken, dann startet der Lader durch
+und das EUMEL-System meldet sich mit einer Tabelle von Geräteanpassungen: 
+ 
++--------------------------------------------------------------------------+ 
+i                                                                          i 
+i  psi                 transparent       pc.1.25 pc.2.25                   i 
+i  pc.3.25             pc.1.24           pc.2.24 pc.3.24                   i 
+i  psi25               tandberg.2244s    DEC.VT100.ascii   DEC.VT100       i 
+i  DEC.VT220.ascii     DEC.VT220.german  FT10/20.german    FT10/20.ascii   i 
+i  ampex210.ascii      ampex210.german   ampex220.german   ampex232        i 
+i  Wyse.WY50.ascii     Wyse.WY50.german  Wyse.WY60.german                  i 
+i  Wyse.WY120.german                                                       i 
+i                                                                          i 
+i  Kanal 1 (j/n)                                                           i 
+i                                                                          i 
++--------------------------------------------------------------------------+ 
+ 
+Da unterschiedliche Tastaturen auch unterschiedliche Tastenbelegungen haben, ist es
+notwendig, mit Hilfe der Konfigurationstabelle Ihre Tastatur und Ihren Bildschirm an
+das EUMEL-System anzupassen. Dafür bietet Ihnen das System "Kanäle" an. #on("u")#Kanal 1#off("u")#
+entspricht dem Haupt-Terminal des Rechners, #on("u")#muß also auf jeden Fall konfiguriert
+werden#off("u")#. Beantworten Sie also die Frage "Kanal 1 (j/n)" mit "j". 
+Das EUMEL-System funktioniert auch, wenn Sie zunächst nur Kanal 1 mit der Anpas­
+sung konfigurieren, die Ihrem Gerätetyp entspricht. Wenn Ihr Rechner eine AT-Tastatur
+hat, ist die korrekte Konfiguration "pc.1"; die Konfigurationen "pc.2" und "pc.3" decken
+die meisten der Rechner ab, deren Tastenbelegung von der Standard-AT Tastatur
+geringfügig abweicht. Die Erweiterung ".24" bzw. ".25" gibt die Anzahl der Bildschirm­
+zeilen wieder. Standardmäßig sind im SHard 24 Zeilen eingestellt. 
+ 
+Weitere Kanäle zum Anschluß von Druckern oder weiteren Terminals können jederzeit
+bei Bedarf vorgenommen werden (EUMEL Systemhandbuch Teil 1). 
+Die Anfrage nach der Konfiguration weiterer Kanäle kann deshalb verneint werden. Die
+Abfrage 'koennen unbenutzte Geraetetypen geloescht werden (j/n)' beantworten Sie
+einstweilen mit 'n'. Anschließend werden noch Datum und Uhrzeit abgefragt. Damit ist
+das Erstinstallationsprogramm abgeschlossen und es erscheint die Meldung 'mainten­
+ance :'. Geben Sie an dieser Stelle <ESC> <q> (nacheinander) ein. Sie haben damit
+die Task 'configurator' ordnungsgemäß verlassen. Erst damit ist sichergestellt, daß die
+eingestellte Konfiguration wirksam wird. 
+ 
+ 
+Installation eines neuen Urladers
+ 
+Wenn Sie den alten Urlader mit einem neuen (z.B. protected mode) überschreiben
+wollen, starten Sie das EUMEL-System zunächst neu. Sobald die Meldung 
+ 
+   #on("b")#Ladevorgang kann durch Tastendruck unterbrochen werden#off("b")# 
+ 
+erscheint, drücken Sie eine beliebige Taste (z.B. ENTER). Auf dem Bildschirm er­
+scheint nun zusätzlich die Meldung 
+ 
+   #on("b")#Ladevorgang unterbrochen, drücken Sie eine Taste um fortzufahren#off("b")# 
+#page# 
+Legen Sie nun die Diskette mit dem neuen Urlader in das Bootlaufwerk und drücken
+Sie wieder eine beliebige Taste. Danach werden folgende Meldungen auf dem Bild­
+schirm ausgegeben: 
+ 
++-----------------------------------------------------+ 
+i                                                     i 
+i   EUMEL wird von Diskette geladen                   i 
+i                                                     i 
+i                                                     i 
+i   E U M E L - Vortest                               i 
+i                                                     i 
+i   Terminals: 1 ....                                 i 
+i   RAM-Groesse (gesamt):        .... kB              i 
+i   Pufferbereich:               .... kB              i 
+i   Hintergrund-Speicher         .... kB              i 
+i                                                     i 
+i   Speichertest:  **********                         i 
+i                                                     i 
++-----------------------------------------------------+ 
+ 
+In der Zeit, in der die Sternchen des Speichertests erscheinen, drücken Sie bitte wieder
+die ENTER-Taste. Nach dem Speichertest erscheint dann folgendes Menü: 
+ 
++-----------------------------------------------------+ 
+i                                                     i 
+i   (1)   Systemstart                                 i 
+i   (2)   neuen Hintergrund vom Archiv laden          i 
+i   (3)   Hardwaretest                                i 
+i   (4)   neuen Urlader vom Archiv laden              i 
+i                                                     i 
++-----------------------------------------------------+ 
+ 
+Wählen Sie Menüpunkt 4 und auf dem Bildschirm erscheinen die folgenden Zeilen: 
+ 
+#box("-0.1","0.0","8.0","1.0")# 
+   \#     xxx 
+   fertig, bitte RESET 
+ 
+wobei hinter dem \#-Zeichen die übertragenen Blöcke des neuen Urladers gezählt
+werden. 
+ 
+Anschließend entfernen Sie bitte die Urladerdiskette aus dem Laufwerk und drücken
+den RESET-Schalter Ihres Rechners. Das EUMEL-Betriebssystem wird nun mit dem
+neuen Urlader gestartet. 
+ 
+ 
+Tastenbelegung:
+ 
+EUMEL-Zeichen:  Taste auf dem IBM-PC/AT 
+ 
+  MARK       :   +--------+ 
+                 i bild   i     (oder Pfeil nach oben) 
+                 +--------+ 
+ 
+  RUBIN      :   +--------+ 
+                 i Einfüg i 
+                 +--------+ 
+ 
+  RUBOUT     :   +--------+ 
+                 i Lösch  i 
+                 +--------+ 
+ 
+  TAB        :   +--------+ 
+                 i <=  => i 
+                 +--------+ 
+ 
+  HOP        :   +--------+ 
+                 i Pos 1  i 
+                 +--------+ 
+ 
+  ESC        :   +------------+ 
+                 i Eing Lösch i 
+                 +------------+ 
+ 
+  SV         :   +------------+          +-------+ 
+                 i  CTRL g    i   oder   i F1    i 
+                 +------------+          +-------+ 
+ 
+Bemerkung: Die CTRL-Taste kann auch mit STRG bezeichnet sein. 
+ 
+Sollte die Tastaturbelegung noch nicht die EUMEL-spezifischen Tasten (HOP, MARK,
+SV, RUBIN, RUBOUT) an den entsprechenden Orten anbieten, können Sie durch
+Ankoppeln der Task "configurator" und Absetzen des Befehls "configurate" die Tastatu­
+ren (auch für zusätzlich angeschlossene Terminals) kanalweise umkonfigurieren. Nähe­
+res entnehmen Sie bitte dem Systemhandbuch, S.6ff. 
+ 
+ 
+Zusatzprogramme
+ 
+Nachdem das System vollständig installiert ist, kann noch typspezifische Software
+eingespielt werden. Diese befindet sich auf der Diskette 'EUMEL-Archiv "AT" (bzw.
+"XT")'. Der folgende Ablauf skizziert schon das Prinzip jeder Arbeit in einem EUMEL-
+System: Task ankoppeln mit 'continue("taskname")' bzw. 'begin("taskname")', Eingabe
+von Kommandos wie 'edit', 'run' oder 'generate shutup dialog manager', abschließend
+Task abkoppeln durch <ESC> <q>. Eine ausführliche Beschreibung finden Sie in
+den EUMEL-Handbüchern. 
+#page# 
+Wenn Sie nach Einstellen des Kanals 1 die Task 'configurator' verlassen haben, befin­
+den Sie Sich auf Supervisor-Ebene. Um die auf der Diskette befindlichen Programme
+an der richtigen Stelle zu übersetzen, sind folgende Schritte notwendig: 
+ 
+Drücken Sie die <SV>-Taste (F1). Damit landen Sie im Supervisor-Menü, dem
+Systemverteiler. Mit <ESC> <c> und Eingabe des Tasknamens 'SYSUR' (auf Groß­
+schreibung achten!) holen Sie die Task 'SYSUR' an das Terminal. Diese Task meldet
+sich mit 'maintenance:'. Da Sie mit einem Mehrbenutzersystem arbeiten, müssen Sie
+das Diskettenlaufwerk zunächst für sich reservieren: 'archive("AT")'. Erst dann können
+Sie Dateien von der Diskette holen: 'fetch("AT install",archive)' und das Installations­
+programm ausführen: 'run'. Der weitere Ablauf erfordert keine Eingriffe. 
+ 
+Nach Ablauf der Programme sollten Sie schließlich eine besondere Task zum Abschal­
+ten einrichten. Dazu müssen Sie nocheinmal die Task 'SYSUR' an den Bildschirm
+holen und dort das durch die Zusatzsoftware (u.a.) neu hinzugewonnene Kommando
+'generate shutup dialog manager' geben. Nach Absetzen des Kommandos können Sie
+'SYSUR' durch <ESC> <q> wieder verlassen. 
+ 
+Um menügesteuert das Betriebssystem abzuschalten oder einen Partitionswechsel
+vorzunehmen, steht Ihnen die Task 'shutup dialog' zur Verfügung. Bei Ausführung des
+Supervisor-Kommandos 'continue("shutup dialog")' wird Ihnen die aktuelle Partitions­
+tabelle angezeigt, so wie Sie diese bereits bei der Generierung kennengelernt haben,
+d.h. mit Angabe von Größe, Start- und Endzylinder der eingerichteten Partitionen. Sie
+können dann eine beliebige Partition menugesteuert auswählen und starten oder das
+Betriebssystem kontrolliert abschalten (sog. 'shutup'). Dabei wird der aktuelle System­
+zustand automatisch gesichert. 
+ 
+ 
+Archivformate bei ATs und Kompatiblen mit zwei Diskettenlauf­
+werken:
+ 
+Standardmäßig ist der Archivkanal 31 an das Laufwerk 'A:' gebunden, das eine Kapazi­
+tät von 1,2 Megabyte besitzt. Ist jedoch bei Ihrem Gerät ein zweites Diskettenlaufwerk,
+z.B. mit einer Kapazität von 360 Kilobyte eingebaut, dann können Sie auf dieses Lauf­
+werk über den Kanal 30 zugreifen. 
+ 
+Dazu richten Sie unter 'SYSUR' eine Task ein, die Sie z.B. 'ARCHIVE 360' benennen.
+Geben Sie in dieser Task das Kommando 'archive manager (30)'; dann können Sie von
+jeder Benutzertask das Archiv mit dem Kommando 'archive ("Archivname",/ "ARCHIVE
+360")' anmelden. Der Zugriff auf eine Diskette in diesem Laufwerk geschieht z.B. über
+'list(/"ARCHIVE 360")' oder 'save ("Dateiname",/"ARCHIVE 360")'. Eine andere Möglich­
+keit ist ein 3,5" Laufwerk. 
+ 
+ 
+ 
+Die einzelnen Schritte der Installation im Überblick:
+ 
+ 
+  1. Die Diskette 'SETUP-EUMEL' in das Laufwerk stecken. 
+ 
+  2. Rechner einschalten oder Tastatur-RESET 
+ 
+  3. EUMEL-Partition einrichten. 
+ 
+  4. Generierung beenden und auf 'ENDE'-Meldung warten. 
+ 
+  5. Diskette 'SETUP-EUMEL AT (XT)' entnehmen. 
+ 
+  6. Tastatur-RESET. 
+ 
+  7. Die Meldung 'Leider keine EUMEL-0-Maschine gefunden' abwarten. 
+ 
+  8. Hintergrunddiskette ('HG0') einlegen und Taste drücken. 
+ 
+  9. Nach der Meldung 'HG-ungültig' eine Taste betätigen, um in den Startdialog zu
+     gelangen. 
+ 
+ 10. Menupunkt 2 anwählen: Neuen Hintergrund vom Archiv laden. Hintergrunddis­
+     kette einlegen und 'Alten HG überschreiben?' mit "j" quittieren. Folgedisketten
+     einlegen, sobald entsprechende Meldung ("weiterer Archivträger eingelegt?")
+     erscheint, und "j" eingeben. 
+ 
+ 11. Hintergrunddiskette entnehmen und anschließend Tastatur-RESET ausführen. 
+ 
+ 12. Kanal 1 konfigurieren. 
+ 
+ 
+ 
+#ib(9)#1.3. Ausführliche Beschreibung#ie(9)# 
+ 
+ 
+#ib##ib(9)#System laden#ie##ie(9)# 
+ 
+ 
+Wie Sie in der Installationsanleitung lesen konnten, geht man beim Systemstart durch
+Eingabe eines Zeichens während des Vortests in das Startmenü und wählt dort "Hin­
+tergrund vom Archiv laden" an. Falls der zu ladende Hintergrund sich über mehrere
+Archiv-Disketten erstreckt, werden die folgenden sukzessive angefordert. 
+ 
+ 
+ 
+ 
+#ib##ib(9)#System sichern#ie##ie(9)# 
+ 
+ 
+Der aktuelle eigene Hintergrund läßt sich (mit allen Tasks und allen Dateien) durch das
+Kommando 
+ 
+           #ib#save system#ie# 
+ 
+auf Archivdisketten sichern. Dabei wird der Systemzustand zunächst über einen Fix­
+punkt gesichert. Anschließend werden #on("b")##on("i")#formatierte#off("i")##off("b")# Disketten angefordert. Der Hinter­
+grund wird komprimiert gesichert, d.h. nur die belegten Blöcke werden auf das Archiv
+geschrieben. 
+ 
+#on("i")#Anmerkung: Diese Prozedur kann nur von privilegierten Tasks (Nachfahren von
+           "SYSUR"), wie dem OPERATOR, aufgerufen werden. 
+           Vor dem Aufruf von 'save system' sollten Sie genügend Disketten for­
+           matiert haben (Überprüfen Sie mit 'storage info', wieviele Disketten Sie
+           benötigen, um den gesammten Hintergrund darauf zu schreiben). #off("i")# 
+ 
+ 
+ 
+ 
+#ib(9)#System gegen Unbefugte schützen#ie(9)# 
+ 
+ 
+Falls der Benutzerkreis eines Multi-User-Systems nicht "gutartig" ist, sollte man verhin­
+dern, daß jeder Benutzer des Systems Zugang zu #ib#privilegierten Operationen#ie# hat, wie
+Löschen anderer Tasks, Konfiguration ändern und System sichern. 
+ 
+Dies erreichen Sie dadurch, daß Sie #on("b")#alle#off("b")# privilegierten Tasks, das sind 'SYSUR' und alle
+Söhne, Enkel usw. von 'SYSUR', durch #ib#Paßworte#ie# schützen. Damit wird der Zugang zu
+diesen Tasks nur möglich, wenn man das entsprechende Paßwort eingibt. Man de­
+finiert solche #on("i")##on("b")##ib#Task-Paßworte#ie##off("i")##off("b")#, indem man die zu schützende Task mit Hilfe des Super­
+visor-Kommandos "continue" an ein Terminal holt und dann das Kommando 
+ 
+           #ib#task password#ie# ("simsalabim") 
+ 
+gibt. Dabei ist "simsalabim" nur ein Beispiel. Bitte verwenden Sie ein anderes Paß­
+wort! Da die Eigenschaft, privilegiert zu sein, nur davon abhängt, im "SYSUR"-Zweig
+(und nicht im normalen "UR"-Zweig) des Systems zu sein, könnte sich ein gewitzter
+Anwender die Privilegierung einfach erschleichen, indem er eine neue Sohntask von
+"SYSUR" einrichtet. Um auch diese Möglichkeit zu unterbinden, sollte man in #on("b")#jeder#off("b")#
+Task des SYSUR-Zweiges ebenfalls ein #on("i")##on("b")#"begin"-Paßwort#off("i")##off("b")# definieren. Das geschieht mit
+dem Kommando 
+ 
+           #ib#begin password#ie# ("simsalabim") 
+ 
+Bei der Wahl der Paßworte sollte man folgendes bedenken: 
+ 
+    -  Ein zu kurzes oder offensichtliches Paßwort (beispielsweise der Name des
+       Systemverwalters) wird von "Hackern" schnell herausgefunden. 
+ 
+    -  Oft werden Paßworte bekannt, weil irgendwo ein Zettel mit den Paßworten
+       herumliegt. 
+ 
+    -  Der Paßwortschutz ist hart. Wenn man sein Paßwort vergessen hat, gibt es
+       keinen Zugang mehr zu der geschützten Task. 
+ 
+ 
+ 
+Beschreibung der Paßwortprozeduren: 
+ 
+#ib#task password#ie# 
+      PROC task password (TEXT CONST password) 
+      Zweck: Einstellen eines Paßwortes für eine Task im Monitor. 
+ 
+#ib#begin password#ie# 
+      PROC begin password (TEXT CONST password) 
+      Zweck: Verhindert das unberechtigte Einrichten einer Sohn-Task. 
+      Anmerkung: Das 'begin password' vererbt sich auf die später erzeugten Sohn-
+                 Tasks. 
+ 
+#ib#family password#ie# 
+      PROC family password (TEXT CONST password) 
+      Zweck: Setzt oder ändert das Paßwort derjenigen Familienmitglieder, die kein
+             Paßwort oder das gleiche Paßwort wie die aufrufende Task haben. 
+             Zu einer Familie gehören die Task in der man sich befindet und die ihr
+             untergeordneten Tasks. 
+             Bsp.: Das Kommando 'family password ("EUMEL")' wird in SYSUR
+                   gegeben. Dadurch wird das SYSUR-Paßwort und die Paßworte
+                   der entsprechenden Tasks unter SYSUR auf "EUMEL" gesetzt. 
+ 
+ 
+ 
+#ib##ib(9)#Konfiguration#ie##ie(9)# 
+ 
+Die #ib#Konfiguration#ie# läuft über die Task "#ib#configurator#ie#" ab. Diese Task müssen Sie also für
+die hier aufgeführten Operationen durch das Supervisor-Kommando "continue" an­
+koppeln (Dabei wird das Paßwort überprüft, falls die Task geschützt wurde). 
+ 
+#on("i")#Anmerkung: Man kann die Task "configurator" löschen und dann neu (als Sohn, En­
+           kel,... von SYSUR) wieder einrichten. Danach holt man die Konfigura­
+           tionsdatei (z.B. von std.devices) und gibt das Kommando "#ib#configuration
+           manager#ie#".#off("i")# 
+ 
+ 
+Der in der Einführung unter "Wie Sie die Konfiguration einstellen" beschriebene Konfi­
+gurationsdialog läßt sich vermittels des Kommandos 
+ 
+           #ib#configurate#ie# 
+ 
+aufrufen. Dabei wird für jeden angewählten Kanal die bis jetzt gültige Einstellung als
+Vorschlag mit ausgegeben. Die Einstellung aller Kanäle, die nicht angesprochen wer­
+den, bleibt unverändert. 
+ 
+Im Menü werden die Namen aller Dateien mit #ib#Gerätetabellen#ie# aufgeführt, die in der
+Task enthalten sind. Daraus folgt, daß nur noch die bei der letzten Konfigurierung
+benutzten Typen aufgeführt werden, wenn vorher auf die Frage "Koennen unbenutzte
+Geraetetypen geloescht werden (j/n)?" mit "j" geantwortet wurde. Löschen Sie also
+nicht alle unbenutzten Gerätetypen, wenn Sie sie später evtl. nochmal bruachen (siehe
+auch "Teil 2, 3. Kanäle und Konfigurierung"). 
+ 
+Im Konfigurationsdialog kann folgendes eingestellt werden: 
+ 
+     #ib#Typ#ie#        Es werden alle vorhandenen Gerätetabellen durchgegangen, bis
+                eine davon ausgewählt wurde. Diese manchmal etwas langwierige
+                Arbeit kann man durch Eingabe des Zeichens ESC abkürzen:
+                Danach kann man den Typnamen direkt eingeben. #on("i")#Das funktioniert
+                aber nur vernünftig, wenn das eigene Arbeitsterminal bereits richtig
+                konfiguriert worden ist!#off("i")# 
+ 
+     #ib#Baudrate#ie#   (nur für V.24-Kanäle von Bedeutung) Es werden alle einstellbaren
+                Baudraten durchgegangen, bis eine davon ausgewählt wurde. Das
+                sind die Werte 50, 75, 110, 134.5, 150, 300, 600, 1200, 1800, 2400,
+                3600, 4800, 7200, 9600, 19200, 38400 Baud. 
+ 
+     #ib#Bits#ie#       (nur für V.24-Kanäle von Bedeutung) Es werden die einstellbaren
+                Zeichengrößen durchgegangen, d.h. 7 oder 8 Bit pro Zeichen. 
+ 
+     #ib#Parität#ie#    (nur für V.24-Kanäle von Bedeutung) Möglich sind die Einstellun­
+                gen 'no', 'even' und 'odd'. 
+ 
+     #ib#Stopbits#ie#   (nur für V.24-Kanäle von Bedeutung) Stopbits geben die Pause
+                zwischen zwei aufeinanderfolgenden Zeichen an. Möglich sind 1
+                oder 2 Stopbits. 
+ 
+ 
+     #ib#Protokoll#ie#  Terminals u.ä. werden üblicherweise ohne Protokoll angeschlossen.
+                Bei langsamen Geräten wie Druckern bzw. Plottern oder aber bei
+                Rechnerkopplungen bzw. Netzen kann der Empfänger nicht immer
+                so schnell Zeichen annehmen wie sie von der Gegenstation gesen­
+                det werden. In diesem Fall kann man das #ib#XON/XOFF-#ie# oder das
+                #ib#RTS/CTS-Protokoll#ie# einstellen. 
+                #on("b")#BEACHTE:  Sender und Empfänger müssen auf das gleiche Proto­
+                          koll eingestellt sein.#off("b")# 
+ 
+                Manchmal müssen auch Terminals mit Protokoll angeschlossen
+                werden. Üblicherweise wählt man dann aber ein rein ausgabe­
+                seitiges Protokoll, damit SV den EUMEL auf jeden Fall erreicht. 
+                Es gibt folgende Protokolle: 
+ 
+                #ib#XON/XOFF-Protokoll#ie#: 
+                         Rechner und Gerät steuern die Sendungen jeweils über
+                         XON/XOFF-Zeichen. 
+                #ib#RTS/CTS-Protokoll#ie#: 
+                         Rechner und Gerät steuern ihre Sendungen jeweils über
+                         RTS/CTS- Leitungen. 
+                #ib#XON/XOFF-ausgabeseitig#ie#: 
+                         Das angeschlossene Gerät steuert die Ausgabe über
+                         XON/XOFF.Eingaben zum Rechner unterliegen keinem
+                         Protokoll. 
+                #ib#RTS/CTS-ausgabeseitig#ie#: 
+                         Das angeschlossene Gerät steuert die Ausgabe über
+                         RTS/CTS. Eingaben zum Rechner unterliegen keinem
+                         Protokoll. 
+                #ib#XON/XOFF-eingabeseitig#ie#: 
+                         Der EUMEL-Rechner steuert die angeschlossenen
+                         Geräte durch XON/XOFF. Die Ausgaben zum Gerät
+                         unterliegen keinem Protokoll. 
+                #ib#RTS/CTS-eingabeseitig#ie#: 
+                         Der EUMEL-Rechner steuert die angeschlossenen
+                         Geräte durch RTS/CTS. Die Ausgaben zum Gerät unter­
+                         liegen keinem Protokoll. 
+ 
+     #ib#Puffer#ie#     Terminals und alle Ausgabegeräte (Drucker u.ä.) haben standard­
+                mäßig die normalen "kleinen" Eingabepuffer im System zugeord­
+                net. Bei Rechner-Rechner-Kopplungen, DFÜ oder Netzen kann ein
+                "großer" #ib#Eingabepuffer#ie# von 512 Byte notwendig werden. Dement­
+                sprechend sind #ib#Großpuffer#ie# nur beim Schnittstellentyp 'transparent'
+                möglich. 
+ 
+Im #ib#Konfigurationsdialog#ie# werden bei jedem Kanal nur die dort vorhandenen Möglich­
+keiten angeboten. Dabei wird die vorherige Einstellung immer als erste angeboten. So
+kann man sich verhältnismäßig einfach "durchtasten". 
+ 
+Die Fragen des #ib#Konfigurationsdialog#ie#s werden nach folgendem Schema gestellt: 
+ 
+#linefeed(1.18)# 
+          erfrage ("Kanal") ; 
+          erfrage ("Typ") ; 
+          IF dieses ist ein v24 kanal 
+            THEN IF baudrate einstellbar 
+                   THEN erfrage ("Baudrate") 
+                 FI ; 
+                 IF zeichengroesse einstellbar 
+                   THEN erfrage ("Bits") 
+                 FI ; 
+                 IF parität einstellbar 
+                   THEN erfrage ("Parität") 
+                 FI ; 
+                 IF stopbits einstellbar 
+                   THEN erfrage ("Stopbits") 
+                 FI ; 
+          FI ; 
+         erfrage ("Protokoll") ; 
+         IF typ ist tranparent 
+           THEN erfrage ("Puffer") 
+         FI. 
+ 
+#linefeed(1.0)# 
+Will man seine eingestellte #ib#Konfiguration sichern#ie#, reicht es, alle Dateien der Task
+"#ib#configurator#ie#" auf ein Archiv zu schreiben. Diese Konfiguration kann man dann bei
+einem neuen Hintergrund einfach vom Archiv laden. Um die Konfigurierung dann auch
+auszuführen, gibt man das Kommando "setup". 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Druckersoftware einrichten#ie##ie(9)# 
+ 
+ 
+ 
+Das Standardarchive "std.printer" enthält einige Druckeranpassungen für die Ansteu­
+erung diverser Druckertypen. Soll einer dieser Druckertypen an das EUMEL-System
+angeschlossen werden, so muß zuerst eine Task "#ib#PRINTER#ie#" (als Sohntask von
+"SYSUR" mit dem Supervisorkommando) vorhanden sein bzw. durch 
+ 
+ 
+        begin ("PRINTER", "SYSUR") 
+ 
+ 
+eingerichtet werden. In dieser Task müssen dann die folgenden Schritte vollzogen
+werden: 
+ 
+-  Anmelden des Archivs: 
+ 
+        archive ("std.printer") 
+ 
+ 
+-  Holen der Druckeranpassung vom Archiv: 
+ 
+        fetch ("druckertyp.inserter", archive) 
+ 
+ 
+-  Insertieren der Druckeranpassung: 
+ 
+        insert ("druckertyp.inserter") 
+ 
+ 
+ 
+Beispiel: 
+        archive ("std.printer") 
+        fetch ("laser.inserter", archive); 
+        check off; 
+        insert ("laser.inserter") 
+ 
+ 
+Nach Beendigung der Kompilierung finden Sie sich in einem Menü wieder, daß Ihnen
+die Auswahl Ihres Drucker-Herstellers durch die Eingabe der vor dem Firmennamen
+stehenden Zahl erlaubt. Diese Eingabe schicken Sie mit RETURN ab. Da Hersteller
+mitunter verschiedene Modelle mit verschiedenen Funktionen anbieten, ist es nötig,
+daß Sie Ihr Modell auswählen. Auch diese Eingabe wird durch RETURN abgeschickt.
+Nachdem Sie die Nummer des gewünschten Druckers eingegeben haben, erfolgt noch
+einmal eine Sicherheitsabfrage, ob dieser Drucker installiert werden soll. 
+ 
+Neben den speziell zu dem gewählten Drucker passenden Fragen (z.B. NLQ-Modus
+standardmäßig) ist es erforderlich, den Kanal einzugeben, an dem der Drucker ange­
+schlossen ist (z.B. Kanal 15 für eine parallele Schnittstelle). 
+ 
+Wenn die Generierung beendet ist, muß in allen bestehenden Tasks - insbesondere in
+der Task 'PUBLIC' - die Fonttabelle mit dem fonttable-Kommando eingestellt werden.
+Mit dem Kommando 
+ 
+ 
+        print ("dateiname") 
+ 
+ 
+wird dann eine Datei ausgedruckt. 
+ 
+Befindet sich keine passende Druckeranpassung für den anzuschließenden Drucker­
+typ auf dem Standardarchiv "std.printer", so sollte die Druckeranpassung "printer.std"
+benutzt werden. Diese Druckeranpassung ist eine universelle Druckeranpassung für
+alle Drucker, die mit ASCII-Code 13 ein 'Carriage Return' (d.h. Bewegung des Druck­
+kopfes an den linken Rand) und mit ASCII-Code 10 eine Zeilenschaltung von 1/6 Zoll
+vornehmen. Mit ihr kann dann in einem Schrifttyp (entweder 10 oder 12 Zeichen pro
+Zoll, je nachdem welche Fonttabelle eingestellt ist) gedruckt werden. So erhält man
+wenigstens eine Minimalansteuerung des Druckers. Für eine bessere Ansteuerung des
+Drucker muß ein Programm geschrieben werden, das das Druckertreiber-Interface
+erfüllt (siehe Teil 6 "Der EUMEL-Drucker") und eine Fonttabelle erstellt (siehe Teil 7 "Der
+Fontspeicher") werden. 
+#page# 
+#headeven# 
+ 
+%#center#EUMEL-Systemhandbuch 
+ 
+ 
+#end# 
+#headodd# 
+ 
+#center#2. Hardware und ihre Steuerung#right#% 
+ 
+ 
+#end# 
+ 
+ 
+#ib(9)#2. Hardware und ihre Steuerung#ie(9)# 
+ 
+ 
+ 
+ 
+#ib(9)#2.1. Vorwort#ie(9)# 
+ 
+ 
+Die #ib#Hardware#ie# eines jeden EUMEL-Systems läßt sich in #ib#Rechnerkern#ie# und Peripherie
+einteilen. 
+ 
+ 
+a) Der #ib#Rechnerkern#ie# 
+ 
+ 
+In der Regel wird der Rechnerkern aus folgenden Komponenten bestehen: 
+ 
+    -  #ib#CPU#ie# 
+    -  #ib#Vordergrundspeicher#ie# (oft als RAM bezeichnet) 
+    -  #ib#Hintergrundspeicher#ie# (Floppy, Harddisk, oder auch RAM/ROM) 
+ 
+Alle Daten, Dateien und Programme werden auf dem Hintergrundspeicher abgelegt.
+Der benötigte Platz wird dabei dynamisch nach Bedarf zugewiesen. Jeder Zugriff auf
+Daten, die sich auf dem Hintergrundspeicher befinden, muß über den Vordergrund­
+speicher erfolgen. Zu diesem Zweck verlagert das EUMEL-System automatisch alle
+aktuell benötigten Daten in den Vordergrundspeicher. Das erfolgt nach dem Prinzip
+des #ib#Demand-Paging#ie# (s. Benutzerhandbuch Kap. 1). Die CPU führt die aktiven Pro­
+gramme (unter Benutzung des Speichers) aus. Dabei bearbeitet sie reihum alle re­
+chenwilligen Prozesse. 
+Die drei Komponenten des Rechnerkerns werden vollständig vom EUMEL-Betriebs­
+system verwaltet und miteinander verknüpft, so daß der Anwender sich in der Regel
+darum weder kümmern muß noch kann. Ausgenommen davon sind allerdings die
+Diagnose von Hardwarefehlern und Überlegungen zur Systemleistung. 
+ 
+ 
+b) Die #ib#Peripherie#ie# 
+ 
+ 
+Alle anderen Geräte oder Gerätekomponenten gehören aus der Sicht des EUMEL-
+Systems zur Peripherie. Wesentliches Kennzeichen ist, daß sie über Kanäle mit dem
+Rechnerkern verbunden sind und von dort aus durch System- und Anwender­
+programm gesteuert werden können. Angeschlossen werden können u.a. 
+ 
+    -  #ib#Terminal#ie#s 
+    -  #ib#Drucker#ie# und #ib#Plotter#ie# 
+    -  andere #ib#Rechner#ie# bzw. #ib#Rechnernetze#ie# 
+    -  #ib#Archivgerät#ie#e (z.B. Floppy-Laufwerke) 
+ 
+In der Regel hat jedes EUMEL-System mindestens ein #ib#Terminal#ie# und #ib#Archivlaufwerk#ie#.
+Auch wenn dieses "Terminal 1" und das Floppy-Laufwerk baulich in den Rechner
+integiert sind, gehören sie logisch zur Peripherie. Die entsprechenden Kanäle sind
+dann allerdings Teil des Rechners und brauchen den Anwender nicht zu interessie­
+ren. Die beiden wesentlichen anderen Kanaltypen sind: 
+ 
+    -  #ib#serielle Schnittstelle#ie#n (#ib#V.24#ie#) 
+    -  #ib#Parallelschnittstellen#ie# 
+ 
+Beide führen "echt" aus dem Rechner heraus und sind u.U. hardwaremäßig für den
+Anwender von Bedeutung. Normalerweise sollte zwar der Lieferant der EUMEL-
+Hardware für die Verkabelung und den Anschluß peripherer Geräte sorgen, aber
+Kenntnisse können in Fehlersituationen (z.B. Kabelbruch), bei Umkonfigurierungen
+und bei Kombinationen verschiedener Geräte helfen. 
+ 
+ 
+ 
+ 
+#ib(9)#2.2. #ib#Hardware-Test#ie##ie(9)# 
+ 
+ 
+ 
+Der EUMEL-Hardware-Test ist ein rechnerunabhängiger Test und kann demzufolge
+nicht so viel überprüfen wie Testprogramme, die genau auf eine entsprechende Hard­
+ware zugeschnitten sind. Trotzdem sollten die meisten Hardware-Fehler schon mit
+dem EUMEL-#ib#Hardware-Test#ie# gefunden werden. 
+ 
+Bei jedem Systemstart wird der "#ib#Vortest#ie#" durchgeführt. Nachdem er Terminals, Spei­
+cher und Hintergrund angezeigt hat, testet er einmal den Hauptspeicher. Danach wird
+das eigentliche EUMEL-System gestartet. 
+ 
+ 
+Durch Eingabe eines beliebigen Zeichens während des Vortests (Speichertest:
+*********) kommt man in den ausführlichen #ib#Start-Dialog#ie#. Dort wird u.a. auch die
+Möglichkeit "Hardware-Test" angeboten. Wählt man diese an, werden die verfügbaren
+Tests als Menü aufgelistet. Bei jedem EUMEL-System stehen folgende Testmöglichkei­
+ten zur Verfügung: 
+ 
+  (1) #ib#Speichertest#ie# 
+  (2) #ib#Kanaltest#ie# 
+  (3) #ib#Hintergrundtest#ie# 
+  (4) #ib#Archivtest#ie# 
+ 
+Alle Tests sind dabei Dauertests, d.h. sie beginnen nach jedem Durchlauf von neu­
+em, können aber durch <ESC> abgebrochen werden. 
+ 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Speichertest#ie##ie(9)# 
+ 
+ 
+Der #ib#Speichertest#ie# soll den Vordergrundspeicher (#ib#RAM#ie#) des Rechners untersuchen.
+Gerade #ib#Speicherfehler#ie# tendieren aber dazu, nur sporadisch aufzutreten oder wär­
+meabhängig zu sein. Deshalb sollte der Test bei Verdacht auf Speicherfehler längere
+Zeit (einige Stunden) laufen. Leider können auch dann nicht alle Fehler aufgedeckt
+werden, z.B. nicht solche, die nur in ganz speziellen Situationen entstehen, wie Spei­
+cherzugriff mit gleichzeitig anlaufendem Floppymotor und Zeichenausgabe. Generell
+gilt hier (wie für jeden Test), daß das Nichtvorhandensein von Fehlern nie Vollkommen
+sicher nachgewiesen werden kann. 
+ 
+Der Speichertest teilt den Speicher in drei verschiedene Bereiche auf: 
+ 
+                0  :  adresse MOD 3 = 0 
+                1  :  adresse MOD 3 = 1 
+                2  :  adresse MOD 3 = 2 
+ 
+Der freie Speicher wird nach folgendem Algorithmus geprüft: 
+ 
+            schreibe  (1, OLOLOLOL) ;   out ("*") ; 
+            schreibe  (2, OLOLOLOL) ;   out ("*") ; 
+            schreibe  (0, LOLOLOLO) ;   out ("*") ; 
+            pruefe    (1, OLOLOLOL) ;   out ("*") ; 
+            schreibe  (1, LOLOLOLO) ;   out ("*") ; 
+            pruefe    (2, OLOLOLOL) ;   out ("*") ; 
+            pruefe    (0, LOLOLOLO) ;   out ("*") ; 
+            pruefe    (1, LOLOLOLO) ;   out ("*") ; 
+            schreibe  (0, OLOLOLOL) ;   out ("*") ; 
+            pruefe    (0, OLOLOLOL) ;   out ("*") ; 
+            schreibe  (2, LOLOLOLO) ;   out ("*") ; 
+            pruefe    (2, LOLOLOLO) ;   out ("*") . 
+ 
+ 
+Dabei werden durch 'PROC schreibe (INT CONST bereich, BYTE CONST muster)' alle
+Bytes des entsprechenden Bereichs mit dem angegebenen Muster geladen. 'PROC
+pruefe (INT CONST bereich, BYTE CONST soll)' überprüft entsprechend alle Bytes des
+Bereichs darauf, ob sie das Sollmuster enthalten. 
+ 
+Findet der Speichertest Fehler, können u.a. folgende Ursachen vorliegen: 
+ 
+    -  Ein Speicherchip ist defekt. 
+ 
+    -  Die Versorgungsspannung für den Speicher (meistens +5V) ist zu niedrig,
+       d.h. das Netzteil ist nicht richtig eingestellt bzw. defekt. (Das kann insbeson­
+       dere dann entstehen, wenn ein Rechner so "hochgerüstet" wurde, daß das
+       Netzteil nachgeregelt werden müßte.) 
+ 
+    -  Die Kontakte der Speicherkarten sind locker oder oxidiert. 
+ 
+    -  Die Speicheransteuerung ist defekt. 
+ 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Kanaltest#ie##ie(9)# 
+ 
+ 
+Beim #ib#Kanaltest#ie# werden fortlaufend auf allen #ib#Terminalkanälen#ie# (außer auf Terminal 1)
+die jeweiligen Kanalnummern in der Form "Kanal: n" ausgegeben. Jedes Eingabe­
+zeichen wird in dezimaler Verschlüssung unter Angabe der Kanalnummer auf dem
+Terminal 1 gemeldet. 
+ 
+Mit Hilfe dieses Tests können u.a. Kabel und Geräteeinstellungen überprüft werden.
+Mögliche Fehlerursachen: 
+ 
+    -  falsche #ib#Baudrate#ie# eingestellt 
+ 
+       Symptome:  Bei Aus- und Eingabe werden vollkommen unsinnige Zeichen
+                  angeliefert. 
+       Abhilfe:   Baudrate am Endgerät oder am Rechner richtig einstellen. 
+ 
+    -  falsche #ib#Parität#ie# eingestellt 
+ 
+       Symptome:  Einige Zeichen werden richtig übertragen, andere verfälscht. In
+                  einigen Fällen können auch alle Zeichen falsch übertragen wer­
+                  den. 
+       Abhilfe:   Parität am Endgerät oder am Rechner richtig einstellen. 
+ 
+    -  falsches #ib#Kabel#ie# (z.B. Sende- und Empfangsleitungen fälschlich gekreuzt bzw.
+                      nicht gekreuzt, Kabel ohne Flußkontrolle an Schnittstelle mit
+                      Flußkontrolle, V.24-Kabel an Parallelschnittstelle oder umge­
+                      kehrt): 
+ 
+       Symptome:  Keine Ausgabe, keine Eingabe oder andauernder Strom von
+                  "Schrottzeichen". 
+       Abhilfe:   richtiges Kabel nehmen oder Kabel korrigieren. 
+ 
+    -  defektes Kabel (Kabelbruch, defekter Stecker o.ä.) 
+ 
+       Symptome:  beliebig. 
+       Testmöglichkeit: Kabel wechseln. 
+ 
+    -  defektes #ib#Endgerät#ie# 
+ 
+       Symptome:  beliebig. 
+       Testmöglichkeit: Anderes Gerät mit gleicher Einstellung (Baudrate, Parität
+                        usw.) anschließen. 
+ 
+    -  defekte #ib#Schnittstelle#ie# im Rechner 
+ 
+       Symptome:  beliebig 
+       Testmöglichkeit: Endgerät mit gleichem Kabel an eine andere Schnittstelle
+                        am Rechner anschließen (dazu evtl. die Geräteparameter
+                        wie Baudrate anpassen). 
+ 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Hintergrundtest#ie(9)##ie# 
+ 
+ 
+Zur Überprüfung des #ib#Hintergrund#ie#es werden drei Tests angeboten: 
+ 
+     (1) #ib#Lesetest#ie# 
+     (2) #ib#Lese-/Schreibtest#ie# 
+     (3) #ib#Positioniertest#ie# 
+ 
+ 
+Der #ib##on("i")##on("b")#Lesetest#off("i")##off("b")##ie# prüft, ob alle für EUMEL verfügbaren Blöcke auf der Platte bzw. Floppy
+lesbar sind. Dabei wird der Blockinhalt nicht inspiziert. Sowohl behebbare (soft) als
+auch harte #ib#Lesefehler#ie# werden gemeldet. Der Bediener kann einen Korrekturversuch
+durch Rückschreiben veranlassen. Bei einem #ib#Soft-Error#ie# (Block konnte nach mehreren
+Versuchen doch gelesen werden) wird der gelesene Block neu geschrieben. Der Fehler
+kann jetzt ohne negative Folgen behoben sein, bei defekter Hardware aber auch zu
+Folgefehlern führen. 
+Als Korrekturversuch bei harten Fehlern wird ein mit 'FFFD' gefüllter Block geschrie­
+ben. Wird ein solcher Block später vom EUMEL gelesen und als Code angesehen, führt
+das zur Fehlermeldung "#ib#code block unreadable#ie#". Wird FFFD als INT angesehen, liefert
+es den Wert -3, bei REAL oder TEXT können keine Vorhersagen gemacht werden. 
+ 
+ 
+Bei dem #ib##on("i")##on("b")#Schreib-/Lesetest#off("i")##off("b")##ie# wird jeder Block mit mehreren Bitmustern beschrieben und
+zur Kontrolle wieder gelesen. Der alte Inhalt wird vor dem Test gesichert und nachher
+wieder in den Block geschrieben. 
+ 
+    #on("b")#Achtung: Normalerweise zerstört der Test den EUMEL-Hintergrund nicht. Bei
+             defekter Platte können allerdings Blöcke durch mißlungenes Rück­
+             schreiben zerstört werden. #off("b")# 
+ 
+ 
+Der #ib##on("i")##on("b")#Positioniertest#off("i")##off("b")##ie# arbeitet ähnlich wie die Leseprüfung. Allerdings wird in der Reihen­
+folge 0, 1, 0, 2, 0, 3, ... gelesen, so daß die Platte für jeden Lesevorgang positionieren
+muß. 
+ 
+    #on("b")#Achtung: Wegen der harten Plattenbelastung sollte dieser Test nicht zu lange
+             laufen.#off("b")# 
+ 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Archivtest#ie##ie(9)# 
+ 
+ 
+Der Archivtest arbeitet ähnlich wie der Hintergrundtest - allerdings auf dem Archiv. Er
+kann sowohl zur Überprüfung von Archiv-Datenträgern (#ib#Lesetest#ie#) als auch zum Test
+des #ib#Archivlaufwerks#ie# benutzt werden. 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#2.3. #ib#Serielle Geräteschnittstelle#ie##ie(9)# 
+ 
+ 
+#ib##ib(9)#Pinbelegung und Kabel#ie(9)##ie# 
+ 
+ 
+#on("b")##on("i")#Anmerkung: Dieses Kapitel ist nur für solche Anwender von Bedeutung, die sich selbst
+           mit der Verkabelung ihrer Geräte befassen.#off("i")##off("b")# 
+ 
+Im folgenden werden die wichtigsten Leitungen der offiziellen #ib#V.24-Schnittstelle#ie# (#ib#seriel­
+le Schnittstelle#ie# zum Anschluß von Terminals, Druckern, Fremdrechnern u.ä.) beschrie­
+ben: 
+ 
+     Pin   Betriebsrichtung     Bedeutung 
+ 
+      2         out             Sendedaten 
+      3         in              Empfangsdaten 
+ 
+      4         out             Sendeaufforderung (RTS) 
+      5         in              Empfangsbereitschaft (CTS) 
+ 
+      7                         Signalerde 
+ 
+      8         in              Gegenstation bereit (DCD) 
+ 
+     20         out             eigene Station bereit (DTR) 
+ 
+ 
+Dabei dient das Paar (2,3) zur Übertragung der Daten, mit Hilfe von (4,5) ist #ib#Flußkon­
+trolle#ie# möglich (z.B. kann ein Drucker damit Sendungen vom Rechner "verlangsamen").
+Das Paar (8,20) wird bei manchen Geräten und Rechnern benutzt, um festzustellen, ob
+die Gegenstation eingeschaltet ist. 
+ 
+ 
+Die meisten Rechner haben die gleiche #ib#Pinbelegung#ie# wie oben aufgeführt. Die Kabel
+müssen dann die folgenden #ib#Pin#ie#s verbinden: 
+ 
+ 
+Rechner  2 3  4 5  7  8 20   Vollständige Verbindung mit Flußkontrolle. 
+ 
+Gerät    2 3  4 5  7  8 20 
+ 
+ 
+Rechner  2 3  4 5  7          Reicht für die meisten Anschlüsse mit Flußkontrol­
+                              le, z.B. Rechnerkopplung. 
+Gerät    2 3  4 5  7 
+ 
+ 
+Rechner  2 3    5  7          Reicht für die meisten Drucker, Flußkontrolle nur
+                              einseitig vom Drucker zum Rechner. 
+Gerät    2 3  4    7 
+ 
+ 
+Rechner  2 3       7          Reicht meistens für Terminals, Flußkontrolle ist
+                              dabei überflüssig. 
+Gerät    2 3       7 
+ 
+ 
+Rechner  2 3  4 5  7          Manchmal für Terminals. Rechnerseitig wird Fluß­
+                              kontrolle durch die Brücke 4-5 simuliert. 
+Gerät    2 3       7 
+ 
+ 
+Bei manchen Rechnern werden die notwendigen paarweisen Vertauschungen schon
+im Rechner durchgeführt. Es ergibt sich entsprechend: 
+ 
+ 
+Rechner  2 3  4 5  7  8 20   Vollständige Verbindung mit Flußkontrolle. 
+ 
+Gerät    2 3  4 5  7  8 20 
+ 
+ 
+Rechner  2 3  4 5  7          Einfacher Anschluß mit Flußkontrolle. 
+ 
+Gerät    2 3  4 5  7 
+ 
+ 
+Rechner  2 3  4    7          Drucker, einseitige Flußkontrolle. 
+ 
+Gerät    2 3  4    7 
+ 
+ 
+Rechner  2 3       7          Terminal. 
+ 
+Gerät    2 3       7 
+ 
+ 
+Rechner  2 3  4 5  7          Terminal mit simulierter Flußkontrolle. 
+ 
+Gerät    2 3       7 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#2.4. #ib#Kanäle#ie# und #ib#Konfigurierung#ie##ie(9)# 
+ 
+ 
+ 
+Im EUMEL-System dienen #ib#Kanäle#ie# zur Kommunikation mit der Außenwelt, d.h. Kanäle
+sind Verbindungen vom Rechner zu peripheren Geräten wie Terminals, Drucker, Plotter
+und Archiv. Kanäle können für zeichen- und #ib#blockorientierte Ein-/Ausgabe#ie# verwendet
+werden. Ein Kanal heißt #ub##ib#privilegiert#ie(1,"er Kanal")##ue#, wenn er nur von privilegierten Systemtasks (Nach­
+kommen des Supervisors) benutzt werden kann. 
+ 
+#ib#Kanalaufteilung#ie#: 
+ 
+          Kanal        Bedeutung 
+ 
+          1            zeichenorientiert, blockorientiert 
+                       Dieser Kanal muß mit einem Terminal verbunden sein, da
+                       über ihn der Systemstart erfolgt. 
+          2-16         zeichenorientiert, blockorientiert 
+                       Diese Kanäle werden für weitere Terminals, Drucker, Plot­
+                       ter, Rechnerkopplung usw. verwandt. 
+ 
+          15-23        blockorientiert 
+ 
+          24-30        blockorientiert, privilegiert 
+ 
+          31           blockorientiert, privilegiert 
+                       Dieser Kanal ist der #ib#Standardkanal des Archivsystems#ie#, d.h.
+                       üblicherweise wird darüber die Archivfloppy angesprochen. 
+ 
+          32           blockorientiert, privilegiert 
+                       Dieses ist ein #ib#interner Kanal#ie#, an den kein externes Gerät
+                       angeschlossen werden kann. Er wird zur Konfigurierung
+                       der anderen Kanäle benutzt. 
+ 
+Der Supervisor des EUMEL-Systems verwaltet die Kanäle. Jeder Task ist dabei kein
+oder genau ein Kanal zugeordnet. Entsprechend ist jedem Kanal keine oder genau
+eine Task zugeordnet. Solche Zuordnungen können von außen durch den Benutzer
+(nur bei interaktiven Kanälen) über die SV-Kommandos bzw. Prozeduraufrufe 'conti­
+nue' und 'break' (s. Kap. 5) verändert werden. In jedem Fall überprüft der Supervisor
+die Zugriffsberechtigung. 
+ 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Zeichenorientierte Ein-/Ausgabe#ie##ie(9)# 
+ 
+ 
+Zeichenorientierte Ein-/Ausgabe kann auf den Kanälen 1 bis 16 benutzt werden. Dafür
+stehen die Basisoperationen 
+ 
+     PROC #ib#out#ie# (TEXT CONST text) 
+     PROC #ib#outsubtext#ie# (TEXT CONST source, 
+                      INT CNST from) 
+     PROC outsubtext (TEXT CONST source, 
+                      INT CONST from, to)9 
+     PROC #ib#cursor#ie# (INT CONST x, y) 
+     PROC #ib#inchar#ie# (TEXT VAR char) 
+     TEXT PROC #ib#incharety#ie# 
+     TEXT PROC incharety (INT CONST time limit) 
+     PROC #ib#get cursor#ie# (INT VAR x, y) 
+ 
+und alle darauf aufbauenden Operationen (wie 'put', 'get', 'putline', 'getline' usw.) zur
+Verfügung. Diese Kanäle sind 'konfigurierbar' (s.u.) und erlauben den Anruf des
+Systems durch den Benutzer von außen (SV-Taste). In der Regel werden die Kanäle 1
+bis 16 für Terminals, Drucker, Plotter und andere zeichenorientierte Anschlüsse be­
+nutzt. 
+Wenn ein Kanal zum Anschluß eines Terminals verwendet wird, müssen die #ib#Standard-
+Steuerzeichen#ie# des EUMEL-Systems (s. Benutzerhandbuch Programmierung, Kap. 3
+"Der Editor", "5.2.4. Der EUMEL-Zeichensatz") auf jedem Terminal die gleiche Semantik
+haben. Das heißt beispielsweise, daß der Code ""2"" auf jedem Terminal bei Ausgabe
+den Cursor um eine Stelle nach rechts verschiebt. Da Datenendgeräte in dieser Hin­
+sicht aber faktisch keiner Norm gehorchen, müssen die EUMEL-Codes in der Regel in
+#ib#terminalspezifische Codes#ie# umgesetzt werden. Diese Umsetzregeln kann man bei der
+Konfigurierung (s.u.) festlegen. Für die meisten Terminaltypen werden allerdings
+fertige Konfigurationssätze mit dem EUMEL-System zusammen ausgeliefert, die man
+bei der Einrichtung des Systems (s. Kap. 1 Installationsanleitung) interaktiv anwählen
+kann. 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Blockorientierte Ein-/Ausgabe#ie##ie(9)# 
+ 
+ 
+Blockorientiere Ein-/Ausgabe kann auf den Kanälen 1 bis 32 benutzt werden. Dafür
+stehen die Operationen 
+ 
+     PROC #ib#control#ie# (INT CONST code1, code2, code3, 
+                   INT VAR return code) 
+     PROC #ib#blockout#ie# (DATASPACE CONST ds, 
+                   INT CONST page nr, code1, code2, INT VAR return code) 
+     PROC #ib#blockout#ie# (ROW 256 INT CONST block, 
+                   INT CONST code1, code2, INT VAR return code) 
+     PROC #ib#blockin#ie# (DATASPACE VAR ds, 
+                   INT CONST page nr, code1, code2, INT VAR return code) 
+     PROC #ib#blockin#ie# (ROW 256 INT VAR block, 
+                   INT CONST code1, code2, INT VAR return code) 
+ 
+zur Verfügung. Näheres findet man in Kap. 4.5 dieses Systemhandbuchs. 
+ 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Konfigurierung von Kanal 1 bis 15#ie(9)##ie# 
+ 
+ 
+ 
+Alle #ib#zeichenorientierten Kanäle#ie# können (mittels Block I/O auf Kanal 32) konfiguriert
+werden. Dabei werden im wesentlichen #ib#Umsetzregeln#ie# für Ein- und Ausgabe definiert,
+die den Zweck haben, 
+ 
+    -  bei der Ausgabe den EUMEL Zeichensatz auf den Zeichensatz des ange­
+       schlossenen Geräts abzubilden und 
+ 
+    -  bei der Eingabe die gerätespezifischen Zeichen auf den EUMEL Zeichensatz
+       abzubilden. 
+ 
+So ist eine geräteunabhängige Programmierung möglich. 
+ 
+Mit Hilfe der Prozedur '#ib#link#ie#' kann man einen der Kanäle 1 bis 16 auf einen bestimm­
+ten Typ setzen. Immer vorhanden sind die Typen: 
+ 
+"#ib#transparent#ie#":  Keine Codeumsetzungen (für Drucker usw.) und 
+"#ib#psi#ie#"        :  Keine Codeumsetzungen, jedoch folgende Sonderfunktionen: 
+#free(1.0)# 
+                  Code     Funktion 
+                7   (CTLg)   SV 
+                17  (CTLq)   Stop 
+                23  (CTLw)   Weiter 
+ 
+Weitere Typen müssen in Form eines DATASPACE, die nach den Gerätetypen benannt
+sind, in der Task vorliegen, in der das Kommando 'link' gegeben wird. 
+ 
+Neue Terminaltypen können mit den Prozeduren 'new type', 'enter outcode', 'enter
+incode' usw. definiert werden. Im einzelnen stehen folgende Prozeduren zur Verfü­
+gung: 
+ 
+ 
+#ib#link#ie# 
+     PROC link (INT CONST channel, TEXT CONST type) 
+     Zweck: Der angegebene Kanal (1 bis 16) wird auf den angegebenen Typ konfi­
+            guriert. 
+            Hinweis: Die Prozedur 'link' hat die angegebene Wirkung nur, wenn
+                     die Task an Kanal 32 hängt, der nur für Söhne des
+                     SUPERVISOR zugänglich ist ('continue (32)'). 
+ 
+#ib#y size#ie# 
+     PROC y size (INT CONST channel, new size, INT VAR old size) 
+     Zweck: Einstellmöglichkeiten für verschiedene Bildschirmgrößen. Diese Proze­
+            dur wirkt nur auf Kanal 32. 'channel' gibt dabei den zu konfigurierenden
+            Kanal an. 
+ 
+#ib#new type#ie# 
+     PROC new type (TEXT CONST typ) 
+     Zweck: Eröffnet einen neuen Kanaltyp mit dem Namen 'typ'. Die folgenden
+            Aufrufe von 'enter outcode', 'enter incode' usw. beziehen sich dann auf
+            diesen Typ. 
+ 
+#ib#enter outcode#ie# 
+     PROC enter outcode (INT CONST eumelcode, zielcode) 
+     Zweck: Legt fest, daß der Code 'eumelcode' bei Ausgabe auf dem Terminaltyp
+            in 'zielcode' gewandelt werden soll. 
+ 
+     PROC enter outcode (INT CONST eumelcode, TEXT CONST zeichen) 
+     Zweck: Wirkt wie 'enter outcode (eumelcode, code (zeichen))'. 
+ 
+     PROC enter outcode (INT CONST eumelcode, zeit, TEXT CONST seq) 
+     Zweck: Hiermit wird festgelegt, daß der Code 'eumelcode' als Mehrzeichenfolge
+            'seq' ausgegeben werden soll. Jedesmal, wenn diese Folge ausgegeben
+            wurde, verzögert das System die Ausgabe des nächsten Zeichens um
+            mindestens 'zeit' Millisekunden. Dies wird z.B. von den meisten Termi­
+            nals gefordert, wenn sie die Funktion 'Löschen Bildschirm' ausführen
+            sollen. 
+ 
+#ib#enter incode#ie# 
+     PROC enter incode (INT CONST eumelcode, TEXT CONST seq) 
+     Zweck: Es wird festgelegt, daß eine Eingabezeichenfolge 'seq' an das System
+            als ein (!) Zeichen mit dem Code 'eumelcode' weitergegeben werden
+            soll. Die ganze Sequenz muß dabei innerhalb von ca. 40 Millisekunden
+            eintreffen, andernfalls werden die Zeichen einzeln gemeldet. Diese
+            Logik ist erforderlich, um auch Terminals anzuschließen, die z.B. Cursor­
+            tasten als ESC-Sequenzen melden. Ohne die Zeitüberwachung würde
+            das Betätigen der ESC-Taste sonst die Eingabe blockieren, bis die Folge
+            'seq' vollständig ist. 
+            Folgende Eumelcodes sind für die Sondertasten (SV usw.) anzugeben: 
+ 
+                     17   :  STOP 
+                     23   :  WEITER 
+                     7    :  SV 
+ 
+            Weitere Codes ('HOP',...) sind im Benutzerhandbuch Programmierung
+            (5 - 29, Der EUMEL-Zeichensatz) angegeben. 
+ 
+            #on("i")#Hinweis: Liefert die SV-Taste eines Terminals von sich aus schon Code
+                     7, so ist dennoch 'enter incode (7, ""7"")' anzugeben. Entspre­
+                     chendes gilt für die zwei anderen "Ereignistasten" STOP und
+                     WEITER. Bei allen anderen Tasten brauchen jedoch nur echte
+                     Umcodierungen vermerkt zu werden.#off("i")# 
+ 
+ 
+#ib#cursor logic#ie# 
+     PROC cursor logic (INT CONST offset, modus, TEXT CONST pre, mid, post) 
+     Zweck: Es wird festgelegt, daß der EUMEL-Code 6 (Cursorposition) mit den
+            folgenden beiden Zeichen, deren Codes y und x seien, 
+ 
+            bei modus = 255 als 
+                pre + code (offset+y) + mid + code (offset+x) + post 
+            und bei modus = 1 als 
+                pre + text (offset+y) + mid + text (offset+x) + post 
+ 
+            ausgegeben wird. 
+            Hinweis: 'offset' ist üblicherweise 32 (manchmal 0) und 
+                      mid = post = "". 
+ 
+#ib#cursor logic#ie# 
+     PROC cursor logic (INT CONST dist, TEXT CONST pre, mid, post) 
+     Zweck: Diese Prozedur wird von den Konfigurationsdateien alter Versionen
+            benutzt. 
+ 
+#ib#ansi cursor#ie# 
+     PROC ansi cursor (TEXT CONST pre, mid, post) 
+     Zweck: Diese Prozedur ist anstelle von 'cursor logic' zu verwenden, wenn die
+            Cursor-Positionierungen bei dem Terminal so erfolgt, wie im Ansi-
+            Standard definiert wird. 
+ 
+#ib#elbit cursor#ie# 
+     PROC elbit cursor 
+     Zweck: Diese Prozedur ist bei Elbit-Terminals anstelle von 'cursor logic' zu
+            verwenden. 
+ 
+ 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Konfigurations-Manager#ie##ie(9)# 
+ 
+ 
+Wenn das System gestartet wird, weiß der Urlader noch nicht, welche #ib#Terminaltypen#ie#
+an welchen Kanälen hängen. (Der Vortest kann deshalb auch nicht bildschirmorien­
+tiert arbeiten). 
+ 
+Falls eine Task 'configurator' im System ist, schickt der SUPERVISOR dieser eine Start­
+sendung zu. Diese Task kann daraufhin die nötigen Konfigurierkommandos ('link',...)
+ausführen. 
+ 
+Ansonsten ist 'configurator' ein normaler Fontmanager, der die Fonttabellen verwaltet
+(siehe Kap. 7). Deshalb sollte im System immer eine Task 'configurator' existieren und
+nach Möglichkeit immer im 'wait' stehen. Man kann ihn also auch mit 'continue' an ein
+Terminal holen und dann wie üblich Kommandos geben. 
+ 
+#ib#configurate#ie# 
+     PROC configurate 
+     Zweck: Führt den Konfigurationsdialog und anschließendes 'setup' durch. 
+ 
+#ib#setup#ie# 
+     PROC setup 
+     Zweck: Alle Kanäle werden gemäß der im letzten Konfigurationsdialog bestimm­
+            ten Werte konfiguriert (wird automatisch bei jedem Systemstart durch­
+            geführt). 
+ 
+#ib#configuration manager#ie# 
+     PROC configuration manager 
+     Zweck: Durch Aufruf dieser Prozedur wird die Task zu einem Konfigurations­
+            manager. Man kann also die Task "configurator" löschen, neu als
+            Systemtask einrichten und mit diesem Kommando wieder etablieren. 
+     BEACHTE:  - Die Task muß 'configurator' heißen. 
+               - Alle Terminalanpassungen gehen beim Löschen verloren, d.h.
+                 man sollte sie vorher sichern! 
+ 
+ 
+#on("i")#Hinweis:  Es passieren, daß eine Task schon Ausgaben macht, bevor der Kanal
+          konfiguriert ist (z.B. wenn ein 'shutup' bei aktiver Netz-Kommunikation
+          durchgeführt wurde).#off("i")# 
+
diff --git a/doc/system/systemhandbuch.2 b/doc/system/systemhandbuch.2
new file mode 100644
index 0000000..c4772f0
--- /dev/null
+++ b/doc/system/systemhandbuch.2
@@ -0,0 +1,1351 @@
+#start(2.5,1.5)# 
+#pageblock# 
+#block# 
+#page (35)# 
+#headeven# 
+ 
+%#center#EUMEL-Systemhandbuch 
+ 
+ 
+#end# 
+#headodd# 
+ 
+#center#3. ELAN-Programme#right#% 
+ 
+ 
+#end# 
+ 
+ 
+#ib(9)#3. #ib#ELAN-Programme#ie##ie(9)# 
+ 
+ 
+ 
+ 
+#ib(9)#3.1. #ib#Wertebereich#ie#e und #ib#Speicherbedarf#ie##ie(9)# 
+ 
+ 
+#ib#INT-Objekte#ie# 
+ 
+ 
+Jedes #ib#Datenobjekt#ie# vom Typ INT belegt im Speicher 2 Bytes. Mögliche INT-Werte sind
+die ganzen Zahlen von -32768 bis +32767 einschließlich. 
+ 
+ 
+ 
+ 
+#ib#REAL-Objekte#ie# 
+ 
+ 
+Jedes Datenobjekt vom Typ REAL belegt im Speicher 8 Bytes. 
+ 
+REALs haben eine 13-stellige #ib#Mantisse#ie#, die im Rechner dezimal geführt wird. (Das
+heißt, bei Konversionen zwischen interner und TEXT-Darstellung treten keine Run­
+dungsfehler auf.) Der Wertebereich wird durch folgende Eckwerte abgelegt: 
+ 
+      9.999999999999e+126    größter REAL-Wert 
+      0.000000000001         kleinster positiver REAL-Wert mit x + 1.0 > 1.0 
+      9.999999999999e-126    kleinster positiver REAL-Wert > 0.0 
+     -9.999999999999e-126    größter negativer REAL-Wert 
+     -9.999999999999e+126    kleinster REAL-Wert 
+ 
+ 
+ 
+ 
+ 
+#ib#BOOL-Objekte#ie# 
+ 
+ 
+Jedes Datenobjekt vom Typ BOOL belegt im Speicher 2 Bytes. 
+ 
+ 
+ 
+ 
+ 
+#ib#TEXT-Objekte#ie# 
+ 
+ 
+Jedes Datenobjekt vom Typ TEXT besteht aus einem festen Teil von 16 Bytes und
+möglicherweise aus einem flexiblen Teil auf dem #on("i")##on("b")##ib#Heap#ie##off("i")##off("b")#. Im festen Teil werden #ib#Texte bis
+zur Länge von 13 Zeichen#ie# untergebracht. Wenn eine TEXT-Variable einen Wert mit
+mehr als 13 Zeichen Länge annimmt, werden alle Zeichen auf dem Heap unterge­
+bracht. Genauer ergibt sich folgendes Bild: 
+ 
+     kurzer Text (LENGTH <= 13): 
+ 
+          Heap-Link    2 Bytes 
+          Textlänge    1 Byte 
+          Text        13 Bytes 
+ 
+     langer Text (LENGTH > 13): 
+ 
+          Heap-Link    2 Bytes 
+          255          1 Byte 
+          Länge        2 Bytes 
+          ungenutzt   11 Bytes 
+ 
+Wenn eine Variable einmal Platz auf dem Heap bekommen hat, behält sie diesen
+vorbeugend auch dann, wenn sie wieder einen kurzen Text als Wert erhält. So muß
+wahrscheinlich kein neuer Platz auf dem Heap zugewiesen werden, wenn sie wieder
+länger wird. Das gilt allerdings nur bis zur nächsten #ib#Garbage Collection#ie# auf den
+TEXT-Heap, denn dabei werden alle Heap-Container minimal gemacht bzw. gelöscht,
+wenn sie nicht mehr benötigt werden. Der Platz auf dem Heap wird in Vielfachen von
+16 Bytes vergeben. In Fremddatenräumen wird in jedem #ib#Container#ie# neben dem eigent­
+lichen Text auch die Containerlänge untergebracht. 
+ 
+Beispiele:     TEXT-Länge    Speicherbedarf (Byte) 
+ 
+                   0                 16 
+                  13                 16 
+                  14                 32 
+                  15                 48 
+                  30                 48 
+                  31                 64 
+                  46                 64 
+                  47                 80 
+                  62                 80 
+ 
+ 
+Die Heapgröße eines Fremddatenraums berechnet sich als: 
+ 
+      1024 * 1024 - 520 = 1048056 - stat  Bytes 
+ 
+'stat' ist dabei die statistische Größe der Datenstruktur, die dem Datenraum aufgeprägt
+wurde. Bei einem BOUND ROW 1000 TEXT ergibt sich also eine Heapgröße von 
+ 
+      1048056 - (1000 * 16) = 1032056  Bytes. 
+ 
+ 
+ 
+ 
+ 
+ 
+#ib#ROW- und STRUCT-Objekte#ie# 
+ 
+ 
+Bei der Berechnung des Speicherbedarfs von #ib#STRUCT#ie#s und #ib#ROW#ie#s muß man beden­
+ken, daß längere Datenobjekte ausgerichtet werden. Und zwar werden alle Objekte, die
+mindestens die Länge eines REAL-Objektes haben, auf durch 8 teilbare Speichera­
+dressen ausgerichtet. Man bedenke, daß bei ROWs alle Elemente entsprechend ihres
+Elementtyps ausgerichtet sind. 
+ 
+Beispiele:                                 Länge (Byte) 
+ 
+   ROW 2 BOOL                                    4 
+   ROW 4 INT                                     8 
+   ROW 5 INT                                    16 
+   ROW 2 STRUCT (INT, BOOL)                      4 
+   ROW 100 STRUCT (INT,INT)                    400 
+   ROW 100 STRUCT (INT,REAL)                  1600 
+   ROW 100 STRUCT (INT,INT,INT,INT,REAL)      1600 
+   ROW 100 STRUCT (REAL, REAL)                1600 
+   ROW 100 STRUCT (INT,TEXT)                  2400 
+   ROW 100 STRUCT (INT,INT,INT,INT,TEXT)      2400 
+   ROW 100 STRUCT (INT,TEXT,INT,TEXT)         4800 
+   ROW 100 STRUCT (INT,INT,TEXT,TEXT)         4000 
+   ROW 100 ROW 3 INT                           600 
+   ROW 100 ROW 4 INT                           800 
+   ROW 100 ROW 5 INT                          1600 
+aber: 
+   ROW 500 INT                                1000 
+ 
+#on("i")#Anmerkung: Bei der #ib#Speichervergabe#ie# der einfachen Variablen und Konstanten eines
+           Programms spielen Verluste aufgrund von Ausrichtungen in der Regel
+           keine Rolle. Der ELAN-Compiler optimiert dabei soweit möglich.#off("i")# 
+#page# 
+#headeven# 
+ 
+%#center#EUMEL-Systemhandbuch 
+ 
+ 
+#end# 
+#headodd# 
+ 
+#center#4. Standardpakete für Systemprogrammierer#right#% 
+ 
+ 
+#end# 
+ 
+ 
+#ib(9)#4. #ib#Standardpakete für 
+   Systemprogrammierer#ie(9)##ie# 
+ 
+ 
+#ib(9)#4.1. #ib#Fehlerbehandlung#ie##ie(9)# 
+ 
+ 
+Übersicht 
+ 
+ 
+#on("italics")# 
+        Fehler treten auf, wenn ein Programm eine gewünschte Leistung
+        nicht erbringen kann. Solche Situationen müssen von System-
+        Programmen kontrolliert behandelt werden. Die folgenden Aus­
+        führungen sind somit nur für diejenigen interessant, die "Sy­
+        stem"-Programme schreiben wollen.#off("italics")# 
+ 
+#ib#Fehler#ie# treten in Operationen auf, wenn diese eine geforderte Leistung nicht erbringen
+können (z.B. das Drucken einer nicht vorhandenen Datei). Da folgende Anweisungen
+aber davon ausgehen, daß die gewünschten Leistungen erbracht wurden, ist es nicht
+sinnvoll, die Operation weiter auszuführen. Wir sprechen vom #ib#Abbruch einer Operation#ie#,
+wenn nach einem Fehler keine Anweisungen mehr ausgeführt werden, sondern die
+Operation verlassen wird. Im EUMEL-System kann durch folgende drei Maßnahmen
+ein Abbruch verursacht werden: 
+ 
+-  Aufruf der Prozedur '#ib#errorstop#ie#': 
+   Die Operation wird mit einer Fehlermeldung abgebrochen, die man dem Aufruf von
+   'errorstop' als Parameter beifügt werden kann. 
+ 
+-  Aufruf der Prozedur '#ib#stop#ie#': 
+   Die Operation wird abgebrochen. Wirkt wie 'errorstop' mit der Meldung "stop". 
+ 
+-  Umschalten in den Supervisor: 
+   Durch Betätigen der Taste SV und Eingabe des Kommandos '#ib#halt#ie#'. Die laufende
+   Operation wird abgebrochen. Wirkt wie ein 'errorstop', der von "außen" in das
+   Programm induziert wird. 
+ 
+Da alle drei Maßnahmen zum Abbruch führen können und somit eine anormale (vor­
+zeitige) Beendigung eines Programms bewirken, werden sie im folgenden zusammen­
+fassend als #ib#Fehler#ie# bezeichnet. 
+ 
+Für solche Fehler bietet das EUMEL-System die Möglichkeit, den Abbruch zu unter­
+drücken. Dies kann notwendig werden, wenn 
+ 
+a) bestimmte Fehlerfälle vom aufrufenden Programm selbst behandelt werden sollen.
+   Beispiel: 
+ 
+   Der EUMEL-Editor wird aufgerufen, um eine Datei zu bearbeiten. Er versucht als
+   erstes, die Datei zu assoziieren. Existiert die Datei nicht, wird die Prozedur
+   (z.B. 'old'), mit der die Datei angemeldet werden soll, normalerweise mit der Feh­
+   lermeldung ' "datei" gibt es nicht' abgebrochen. Diesen Fehlerzustand fängt der
+   Editor jedoch ab und versucht, eine neue Datei einzurichten (Anmerkung: In Wirk­
+   lichkeit fragt der Editor natürlich vor der Assoziierung mit 'exists' ab, ob die Datei
+   existiert). 
+ 
+b) eine Operation die Kontrolle auf jeden Fall behalten soll. 
+ 
+   Dies ist z.B. beim Monitor notwendig. Gleich welche Fehler vom Monitor gerufene
+   Programme produzieren, der Monitor muß in der Lage sein, die weitere Bearbei­
+   tung zu ermöglichen. 
+ 
+c) eine Operation nicht unterbrechbar sein darf. 
+ 
+   Beispielsweise dürfen Programm(teil)e, die Daten transportieren, nicht unterbro­
+   chen werden, da sonst ein Verlust dieser Daten eintreten könnte. 
+ 
+ 
+ 
+#ib(9)##ib#Fehlerbehandlung#ie# und #ib#Fängerebenen#ie##ie(9)# 
+ 
+ 
+Der Aufruf einer der Prozeduren 
+ 
+     #ib#errorstop#ie# 
+     #ib#stop#ie# 
+     #ib#halt#ie# 
+ 
+(wobei letztere vom Supervisor gegeben werden muß) werden zusammenfassend als
+#ib#Fehler#ie# bezeichnet. Bei einem Fehler wird ein #ib#Fehlerzustand#ie# gesetzt. Im Fehlerzustand
+merkt sich das EUMEL-System, daß ein Fehler vorliegt. Die Prozeduren 
+ 
+    #ib#enable stop#ie# 
+    #ib#disable stop#ie# 
+ 
+bestimmen, ob Operationen im Fehlerzustand weiter bearbeitet oder abgebrochen
+werden. Beispiel: 
+ 
+ 
+     INT VAR x; 
+     get (x); 
+     ... 
+     disable stop; 
+     x := x * x; 
+     ... 
+ 
+ 
+Hier wird mit 'disable stop' verhindert, daß ein Abbruch beispielsweise durch 'INT-
+Ueberlauf' auftreten kann. Die Anweisungen nach 'x * x' werden also weiter bearbei­
+tet. 
+ 
+Welchen Wert hat aber nun die Variable 'x', nachdem der Fehler auftrat? Offensicht­
+lich war die den Fehler auslösende Operation '*' nicht in der Lage, den richtigen Wert
+zu errechnen. #ib#Abgebrochene Operationen#ie# liefern in der Regel keinen Wert. Dadurch ist
+der Wert von 'x' in unserem Beispiel nach einem Fehler bei '*' undefiniert. Es ist nun
+ersichtlich, daß mit der Anwendung der 'disable stop'-Prozedur äußerst vorsichtig zu
+verfahren ist, weil u.U. Werte verloren gehen können bzw. mit unerwarteten Werten
+weitergerechnet wird. 
+ 
+Damit Programmierer erfahren können, ob ein Fehler aufgetreten ist, gibt es die Infor­
+mations-Prozedur 
+ 
+     #ib#is error#ie# 
+ 
+über den Fehlerzustand. Die Prozedur liefert den Wert TRUE, wenn ein Fehler vorliegt,
+andernfalls FALSE. Die Prozedur 
+ 
+     #ib#clear error#ie# 
+ 
+"löscht" den Fehlerzustand, d.h. anschließende Abfragen mit 'is error' liefern FALSE.
+(Die "richtige" Reaktion auf den Fehler muß ein Programmierer natürlich selbst be­
+stimmen). 
+ 
+Beispiel: 
+ 
+ 
+     INT VAR x; 
+     get (x); 
+     ... 
+     disable stop; 
+     x := x * x; 
+     IF is error 
+       THEN put ("'x'-Wert zu groß"); 
+            x := 0; 
+            clear error 
+     FI; 
+     ... 
+ 
+ 
+Leider würden jetzt aber auch alle folgenden Anweisungen bei eventuellen Fehlern
+nicht abgebrochen, also auch in Situationen, in denen ein Abbruch erwünscht ist, um
+#ib#Programmierfehler#ie# zu erkennen. Deshalb können durch 
+ 
+     #ib#enable stop#ie# 
+ 
+Abbrüche wieder zugelassen werden. Wenn wir jetzt also schreiben: 
+ 
+ 
+     INT VAR x; 
+     get (x); 
+     ... 
+     disable stop; 
+     x := x * x; 
+     IF is error 
+       THEN put ("'x'-wert zu gross"); 
+            x := 0; 
+            clear error 
+     FI; 
+     enable stop; 
+     ... 
+ 
+ 
+dann würden - wie gewünscht - eventuelle Fehler in den Anweisungen nach 'enable
+stop' zu einem Abbruch führen. 
+ 
+Nicht mit '#ib#clear error#ie#' gelöschte Fehler führen bei '#ib#enable stop#ie#' ebenfalls zu einem
+Abbruch. In dem Programmteil 
+ 
+ 
+     ... 
+     disable stop; 
+     x := x * x; 
+     enable stop; 
+     ... 
+ 
+ 
+würde der eventuell auftretender Fehler 'INT Ueberlauf' nicht abgefangen, sondern nur
+verzögert wirksam, weil er nicht mit 'clear error' gelöscht wurde. 
+ 
+Für die Behandlung von Fehlern durch Benutzer gibt es Prozeduren, die eine adäquate
+Reaktion auf den Fehler erlauben. Mit 
+ 
+     #ib#error message#ie# 
+ 
+können Sie auf die erste Fehlermeldung (eines 'error stop') nach dem letzen 'clear
+error' zugreifen (d.h. Folgefehler verändern nicht die Originalmeldung). Die Prozedur 
+ 
+     #ib#error code#ie# 
+ 
+liefert den #ib#Fehlercode#ie#, der bei der Prozedur 'errorstop' zusätzlich zum #ib#Fehlertext#ie#
+angegeben werden kann. 
+ 
+     #ib#error line#ie# 
+ 
+liefert die Zeilennummer des zuletzt aufgetretenen Fehlers. Mit 
+ 
+     #ib#put error#ie# 
+ 
+kann eine noch anstehende Fehlermeldung ausgegeben werden. Beispiel: 
+ 
+ 
+     INT VAR x; 
+     get (x); 
+     ... 
+     disable stop; 
+     x := x * x; 
+     IF is error 
+       THEN IF error message = "INT-Ueberlauf" 
+              THEN put ("'x'-wert zu gross"); 
+              ELSE put error 
+            FI; 
+            clear error 
+     FI; 
+     enable stop; 
+     ... 
+ 
+ 
+Tritt ein Fehler auf, so wird die den Fehler auslösende Operation entweder abgebro­
+chen oder "normal" weiter bearbeitet, je nachdem, ob 'enable stop' oder 'disable stop'
+gesetzt ist. Auf jeden Fall wird der #ib#Fehlerzustand#ie# an die aufrufende Operation weiter­
+gemeldet, die wiederum abgebrochen oder weiterbearbeitet werden kann usw. Die
+#ib#Weitermeldung#ie# eines Fehlers kann auch über mehrere Stufen erfolgen, solange bis der
+Fehler gelöscht wird. Andererseits gilt 'enable/ disable stop' nicht nur für die aktuelle
+Operation, sondern auch für gerufene Operationen ("Vererbung"). Die gerufenen Ope­
+rationen können allerdings 'enable/disable stop' neu festlegen. Beispiel: 
+ 
+ 
+        PROC a:             PROC b:          PROC c: 
+        ...                 ...              ROW 10 INT VAR x; 
+        disable stop;       enable stop;     ... 
+        b;                  ...              INT VAR i :: 4711; 
+        IF is error         c;               x [i] := ...; 
+          THEN ...          ...              ... 
+               clear error  END PROC b       END PROC c 
+        FI; 
+        enable stop 
+        END PROC a; 
+ 
+ 
+In der Prozedur 'a' wird die Prozedur 'b' aufgerufen. Diese ruft wiederum eine Prozedur
+'c' auf. Für die Prozedur 'c' gilt nun der Zustand 'enable stop' der Prozedur 'b' (#ib#Verer­
+bung von 'enable stop'#ie#). Tritt jetzt in 'c' der Subskriptions-Fehler auf, wird 'c' abgebro­
+chen. Die Wirkung der fehlerauslösenden Operation ist nicht definiert. 
+ 
+Da aber auch die Prozedur 'b' im 'enable stop' Zustand ist, wird auch die Prozedur 'b'
+abgebrochen. Der Fehler bleibt jedoch erhalten, wird also weitergemeldet. Dies wirkt
+sich so aus, daß die Anweisung 'c' nicht ausgeführt wird. Da die Prozedur 'a' 'disable
+stop' gesetzt hat, werden die auf den Aufruf von 'b' folgenden Anweisungen durchlau­
+fen und somit durch 'clear error' der Fehler gelöscht. In diesem Beispiel "fängt" die
+Prozedur 'a' Fehler auf, die in den Prozeduren 'b' und 'c' entstehen können. 
+ 
+Ein solcher #ib#Fänger#ie# wird durch zwei Prozeduren konstruiert. Der eigentliche Fänger
+(hier: Prozedur 'a') ruft eine ausführende Prozedur (hier: 'b') im 'disable stop'-Zustand
+auf. Die gerufene Prozedur setzt sofort 'enable stop' und führt dann die eigentlichen
+Aktionen aus. So wird die gerufene Prozedur abgebrochen (kann also im Fehlerfall
+nicht zuviel Schaden anrichten). Der Abbruch führt bis zur Fängerprozedur ('a') hinter
+den Aufruf der gerufenen Prozedur ('b'). Nach Löschung eventuell auftretender Fehler
+ist somit sichergestellt, daß der Fänger immer weiterarbeiten kann. 
+ 
+ 
+ 
+#ib(9)#Wichtiger Hinweis#ie(9)# 
+ 
+ 
+ 
+     1. #on("italics")##on("bold")#Da im 'disable stop'-Zustand kein Fehler zum Abbruch führt, kann
+        eine Operation in diesem Zustand auch nicht durch 'halt' abge­
+        brochen werden. Einerseits ist das für manche Systemteile wün­
+        schenswert, andererseits können Operationen, die auf Grund von
+        Programmierfehlern nicht terminieren (Endlosschleifen), nicht
+        unter Kontrolle gebracht werden. Also Vorsicht! (Letztes Mittel:
+        Task löschen)#off("italics")##off("bold")# 
+ 
+     2. #on("i")##on("b")#Es ist nicht (!) garantiert, daß im Fehlerzustand aufgerufene
+        Prozeduren ihre normale Wirkung haben. Garantiert ist dies je­
+        doch für alle Prozeduren und Operatoren, die in diesem Kapi­
+        tel aufgeführt werden.#off("i")##off("b")# 
+ 
+#on("italics")##on("bold")#Merke:  Fehler sind im EUMEL-System Aufrufe der Prozeduren 'errorstop',
+        'stop' oder das Betätigen der SV Taste und dem Supervisor-
+        Kommando 'halt'. Ein Fehler gilt solange, bis er mit Hilfe der
+        Prozedur 'clear error' gelöscht wurde. Die Prozeduren 'enable/
+        disable stop' steuern die Abarbeitung der Operationen im Fehler­
+        fall. Gilt für eine Operation 'enable stop', wird die Operation
+        abgebrochen, d.h. die restlichen Anweisungen der Operation
+        nach der Fehler auslösenden Anweisung werden nicht durchlau­
+        fen. Ist 'disable stop' gesetzt, werden die restlichen Operationen
+        weiterhin abgearbeitet. 'enable/disable stop' gilt für alle - auch
+        indirekt - aufgerufenen Operationen ("Vererbung"), es sei denn, in
+        den gerufenen Operationen wird ein erneutes 'enable/disable
+        stop' gesetzt. Über die Aufrufkette werden ggf. auch die Fehler
+        zurück gemeldet.#off("italics")##off("bold")# 
+ 
+ 
+        #on("italics")##on("bold")#Eine Fänger-Ebene ist eine Prozedur, die 'disable stop' setzt und
+        dann andere Operationen aufruft. Nach jedem dieser Aufrufe
+        kann eine Fehlerbehandlung mit 'clear error' durchgeführt wer­
+        den. Damit ist gewährleistet, daß Fehler immer von der Fänger-
+        Ebene "aufgefangen" und entsprechend behandelt werden.#off("italics")##off("bold")# 
+ 
+ 
+ 
+#ib(9)##ib#Prozeduren zur Fehlerbehandlung#ie##ie(9)# 
+ 
+ 
+#ib#clear error#ie# 
+     PROC clear error 
+     Zweck: Löscht den Fehlerzustand. 'is error' liefert anschließend wieder FALSE.
+            'error message', 'error code' und 'error line' werden nicht gelöscht. 
+ 
+#ib#disable stop#ie# 
+     PROC disable stop 
+     Zweck: Unterbindet den Abbruch in aufgerufenen Operationen. 'disable stop'
+            gilt für die Prozedur, in der sie aufgerufen wird und in allen folgenden
+            gerufenen Prozeduren, es sei denn, sie wird durch 'enable stop' außer
+            Kraft gesetzt. Wird die Operation verlassen, in der 'disable stop' aufge­
+            rufen wurde, wird der "alte" Zustand wiederhergestellt, der vor dem
+            Aufruf der Operation galt. 'disable stop' kann weiterhin in einer aufge­
+            rufenen Operation durch den Aufruf von 'enable stop' in dieser und den
+            folgenden Operationen außer Kraft gesetzt werden. 
+ 
+#ib#enable stop#ie# 
+     PROC enable stop 
+     Zweck: Setzt die Wirkung eines Aufrufs von 'disable stop' zurück. Fehler ('error­
+            stop', 'stop' oder 'halt') in der aktuellen Operation oder den folgenden
+            aufgerufenen Operationen führen zum Abbruch. Bisher nicht gelöschte
+            Fehler (siehe 'clear error') führen sofort zum Abbruch. 
+ 
+#ib#error code#ie##--goalpage ("fehlercodes")# 
+     INT PROC error code 
+     Zweck: Liefert den durch 'errorstop' gesetzten #ib#Fehlercode#ie#. Beispiel: 
+ 
+               PROC test: 
+                 enable stop; 
+                 error stop (110, "Dies ist mein Abbruch!"); 
+               END PROC test; 
+ 
+               ... 
+               disable stop; 
+               test; 
+               put (error code);   (* liefert 110 *) 
+               clear error; 
+               enable stop 
+ 
+ 
+#ib#error line#ie# 
+     INT PROC error line 
+     Zweck: Liefert die Zeilennummmer des Fehlers (Voraussetzung : Die Überset­
+            zung erfolgt im 'checkon-Modus). 
+ 
+#ib#error message#ie# 
+     TEXT PROC error message 
+     Zweck: Liefert die Fehlermeldung als Text. Anhand dieser Meldung kann ent­
+            schieden werden, welcher Fehler vorliegt. 
+     Hinweis: Eine Fehlermeldung "" (also: 'error stop ("")') führt zum Fehlerabbruch
+            mit der Bedeutung "Fehlermeldung wurde bereits ausgegeben". Dem­
+            entsprechend erfolgt bei der Fehlermeldung 'niltext' keine Reaktion bei
+            'put error'. 
+ 
+#ib#errorstop#ie# 
+     PROC error stop (TEXT CONST message) 
+     Zweck: Bricht ab und setzt die Zeilennummer (wenn man sich im 'checkon'-
+            Modus befindet), in der der Fehler aufgetreten ist, sowie den Text 'mes­
+            sage'. Der Abbruch kann mit 'disable stop' unterbunden werden. 'error­
+            stop' hat keine Wirkung, wenn ein noch nicht gelöschter Fehler vorliegt.
+            Zu einer Fehlermeldung "" siehe auch die Prozedur 'error message'. Als
+            'error-code' wird 0 gesetzt. 
+ 
+ 
+     PROC error stop (INT CONST code, TEXT CONST message) 
+     Zweck: Analog obiger 'errorstop'-Prozedur, aber mit Angabe des Fehlercodes,
+            der durch die Prozedur 'error code' in einer Fängerebene erfragt wer­
+            den kann. 
+ 
+#ib#is error#ie# 
+     BOOL PROC is error 
+     Zweck: Informationsprozedur auf das Vorhandensein eines Fehlers. 
+ 
+#ib#put error#ie# 
+     PROC put error 
+     Zweck: Gibt die durch 'errorstop' gesetzte Fehlermeldung aus, falls ein Fehler
+            noch nicht gelöscht ist (siehe auch: 'error message'). 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Fehlercode#ie#s#ie(9)# 
+ 
+ 
+Einige Fehlercodes sind bereits belegt: 
+ 
+               0       kein Fehlercode spezifiziert (Standardwert) 
+               1       'halt' vom Terminal 
+               2       Stack-Ueberlauf 
+               3       Heap-Ueberlauf 
+               4       INT-Ueberlauf 
+               5       DIV durch 0 
+               6       REAL-Ueberlauf 
+               7       TEXT-Ueberlauf 
+               8       zu viele DATASPACEs 
+               9       Ueberlauf bei Subskription 
+               10      Unterlauf bei Subskription 
+               11      falscher DATASPACE-Zugriff 
+               12      INT nicht initialisiert 
+               13      REAL nicht initialisiert 
+               14      TEXT nicht initialisiert 
+               15      nicht implementiert 
+               16      Block unlesbar 
+               17      Codefehler 
+               100     Syntax-Fehler beim Übersetzen 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#4.2. #ib#THESAURUS#ie##ie(9)# 
+ 
+ 
+ 
+Ein #ib#Thesaurus#ie# ist ein #ib#Namensverzeichnis#ie#, das bis zu 200 Namen beinhalten kann.
+Dabei muß jeder Namen mindestens ein Zeichen und darf höchstens 100 Zeichen lang
+sein. Steuerzeichen (code < 32) sind in Namen nicht erlaubt. 
+ 
+Ein Thesaurus ordnet jedem eingetragenen Namen einen Index zwischen 1 und 200
+(einschließlich) zu. Diese Indizes bieten dem Anwender die Möglichkeit, Thesauri zur
+Verwaltung benannter Objekte zu verwenden. (Der Zugriff erfolgt dann über den Index
+eines Namens in einem Thesaurus). So werden Thesauri u.a. von der Dateiverwaltung
+benutzt. Sie bilden die Grundlage der ALL- und SOME-Operatoren. 
+ 
+ 
+ 
+ 
+#ib(9)#Grundoperationen#ie(9)# 
+ 
+ 
+#ib#CONTAINS#ie# 
+     BOOL OP CONTAINS (THESAURUS CONST t, TEXT CONST name) 
+     Zweck: Liefert genau dann TRUE, wenn 't' den Namen 'name' enthält. Falls
+            'name=""' oder 'LENGTH name > 100', wird FALSE geliefert. 
+ 
+#ib#delete#ie# 
+     PROC delete (THESAURUS VAR t, TEXT CONST name, INT VAR index) 
+     Zweck: Falls der Name 'name' im Thesaurus 't' enthalten ist, wird er dort ge­
+            löscht. In 'index' wird dann sein alter Index geliefert, unter dem er im
+            Thesaurus eingetragen war. Ist der Name nicht im Thesaurus enthalten,
+            wird 0 als Index geliefert. 
+ 
+     PROC delete (THESAURUS VAR t, INT CONST index) 
+     Zweck: Der Eintrag mit dem angegebenen Index wird aus dem Thesaurus 't'
+            gelöscht. 
+ 
+#ib#empty thesaurus#ie# 
+     THESAURUS PROC empty thesaurus 
+     Zweck: Für Initialisierungszwecke wird ein leerer Thesaurus geliefert. 
+ 
+#ib#get#ie# 
+     PROC get (THESAURUS CONST t, TEXT VAR name, INT VAR index) 
+     Zweck: Liefert den "nächsten" Eintrag aus dem Thesaurus 't'. "Nächster" heißt
+            hier, der kleinste vorhandene mit einem Index größer als 'index'. Dabei
+            wird in 'name' der Name und in 'index' der Index des Eintrags geliefert.
+            D.h. 'index' wird automatisch weitergeschaltet. Den ersten Eintrag erhält
+            man entsprechend durch Aufruf mit 'index=0'. Nach dem letzten Ein­
+            trag wird 'name=""' und 'index=0' geliefert. Beispiel: 
+ 
+ 
+                         TEXT VAR name; 
+                         INT VAR index := 0 ; 
+                         get (thesaurus, name, index) ; 
+                         WHILE index > 0 REP 
+                           putline (name) ; 
+                           get (thesaurus, name, index) 
+                         PER 
+ 
+ 
+#ib#highest entry#ie# 
+     INT PROC highest entry (THESAURUS CONST t) 
+     Zweck: Liefert den höchsten belegten Index des Thesaurus 't'. 
+            Achtung: Das ist nicht die Anzahl der vorhandenen Namen, da durch
+                     Löschungen Lücken entstanden sein können. 
+ 
+#ib#insert#ie# 
+     PROC insert (THESAURUS VAR t, TEXT CONST name, INT VAR index) 
+     Zweck: Der Name 'name' wird als zusätzlicher Eintrag in den Thesaurus 't'
+            eingetragen und der dafür vergebene Index geliefert. Falls der Thesau­
+            rus schon voll ist und der Name nicht mehr eingetragen werden kann,
+            wird 0 als Index geliefert. 
+            Achtung: Mehrfacheintragungen sind möglich. Wenn man diese verhin­
+                     dern will, muß man entsprechend vermittels 
+ 
+ 
+                         IF NOT t CONTAINS name 
+                           THEN insert (t, name, index) 
+                         FI 
+ 
+ 
+                     eintragen. 
+     Fehlerfall: 
+           * Name unzulaessig 
+ 
+     PROC insert (THESAURUS VAR t, TEXT CONST name) 
+     Zweck: s.o. Allerdings wird der Index des Namens nicht geliefert. Ein Thesau­
+            rusüberlauf wird entsprechend als 'errorstop' gemeldet. 
+     Fehlerfälle: 
+          * Name unzulaessig 
+          * THESAURUS-Ueberlauf 
+ 
+#ib#link#ie# 
+     INT PROC link (THESAURUS CONST t, TEXT CONST name) 
+     Zweck: Liefert den Index des Namens 'name' im Thesaurus 't'. Falls der Name
+            nicht enthalten ist, wird 0 geliefert. Ist der Name mehrfach im Thesau­
+            rus enthalten, ist nicht definiert, welcher der möglichen Indizes geliefert
+            wird. 
+ 
+#ib#name#ie# 
+     TEXT PROC name (THESAURUS CONST t, INT CONST index) 
+     Zweck: Liefert den Namen des Eintrags mit dem Index 'index' aus dem The­
+            saurus 't'. Falls kein solcher Eintrag im Thesaurus enthalten ist, wird
+            Niltext geliefert. 
+ 
+#ib#rename#ie# 
+     PROC rename (THESAURUS VAR t, TEXT CONST old, new) 
+     Zweck: Ändert im Thesaurus 't' einen Eintrag mit dem alten Namen 'old' in 'new'
+            um. Falls 'old' nicht im Thesaurus enthalten ist, wird keine Leistung
+            erbracht. Falls 'old' mehrfach in 't' enthalten ist, ist nicht definiert, wel­
+            cher der möglichen Einträge geändert wird. 
+     Fehlerfall: 
+            * Name unzulaessig 
+ 
+     PROC rename (THESAURUS VAR t, INT CONST index, TEXT CONST new) 
+     Zweck: Ändert im Thesaurus 't' den Namen des durch 'index' identifizierten
+            Eintrags in 'new'. 
+     Fehlerfall: 
+            * Name unzulaessig 
+ 
+#ib#THESAURUS#ie# 
+     TYPE THESAURUS 
+     Zweck: Bezeichnet Thesaurus-Datenobjekte 
+ 
+:= 
+     OP := (THESAURUS VAR dest, THESAURUS CONST source) 
+     Zweck: Zuweisung 
+ 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#Verknüpfungsoperationen#ie(9)# 
+ 
+Das Paket '#ib#nameset#ie#' bietet die Möglichkeit, Operationen nicht nur auf einzelnen Datei­
+en, sondern auf (geordneten) Mengen ablaufen zu lassen: 
+ 
+#ib#ALL#ie# 
+     THESAURUS OP ALL (TASK CONST task) 
+     Zweck: Liefert einen Thesaurus, der alle Dateinamen der angegebenen Task
+            enthält. 
+ 
+     THESAURUS OP ALL (TEXT CONST file name) 
+     Zweck: Liefert einen Thesaurus, der die in der angegebenen Datei vorhande­
+            nen Namen (jede Zeile ein Name) enthält. 
+ 
+#ib#all#ie# 
+     THESAURUS PROC all 
+     Zweck: Liefert einen Thesaurus, der alle Dateinamen der eigenen Task enthält.
+            Entspricht 'ALL myself'. 
+ 
+#ib#LIKE#ie# 
+     THESAURUS OP LIKE (THESAURUS CONST thesaurus, TEXT CONST muster) 
+     Zweck: Alle im Thesaurus enthaltenen Dateien, die dem 'muster' entsprechen
+            sind im Ergebnisthesaurus enthalten. 
+            (Die Syntax von 'muster' findet man bei der Beschreibung des Pattern-
+            Matching) 
+ 
+#ib#SOME#ie# 
+     THESAURUS OP SOME (THESAURUS CONST thesaurus) 
+     Zweck: Bietet den angegebenen Thesaurus im EUMEL-Editor zum Ändern an.
+            Es können nicht erwünschte Namen gestrichen werden. 
+ 
+     THESAURUS OP SOME (TASK CONST task) 
+     Zweck: Aufruf von: SOME ALL task. 
+ 
+     THESAURUS OP SOME (TEXT CONST file name) 
+     Zweck: Aufruf von: SOME ALL filename. 
+ 
+#ib#FILLBY#ie# 
+     OP FILLBY (THESAURUS VAR thesaurus, FILE VAR file) 
+     Zweck: Schreibt 'file' in den Thesaurus. Dabei werden Zeilen, die schon im
+            Thesaurus sind, nicht mehr in den Thesaurus geschrieben. Jede Zeile
+            kommt im Thesaurus also nur einmal vor. 
+ 
+     OP FILLBY (FILE VAR file, THESAURUS CONST thesaurus) 
+     Zweck: Schreibt den Thesaurus in die Datei 'file'. 
+ 
+     OP FILLBY (TEXT CONST filename, 
+                          THESAURUS CONST thesaurus) 
+     Zweck: Richtet eine Datei mit dem Namen 'filename' ein und schreibt den The­
+            saurus in die Datei. 
+ 
++ 
+     THESAURUS OP + (THESAURUS CONST left, right) 
+     Zweck: Liefert die Vereinigungsmenge von 'left' und 'right'. 
+            Achtung: Die Vereinigungsmenge enthält keine Namen mehrfach. 
+ 
+     THESAURUS OP + (THESAURUS CONST left, TEXT CONST right) 
+     Zweck: Fügt dem Thesaurus 'right' zu, wenn 'right' noch nicht im Thesaurus
+            enthalten ist. 
+ 
+- 
+     THESAURUS OP - (THESAURUS CONST left, right) 
+     Zweck: Liefert die Differenzmenge. Achtung: Die Differenzmenge enthält keine
+            Namen mehrfach. 
+ 
+     THESAURUS OP - (THESAURUS CONST left, TEXT CONST right) 
+     Zweck: Nimmt den Namen 'right' aus dem Thesaurus. 
+ 
+/ 
+     THESAURUS OP / (THESAURUS CONST left, right) 
+     Zweck: Liefert die Schnittmenge 
+            Achtung: Die Schnittmenge enthält keine Namen mehrfach. 
+ 
+#ib#do#ie# 
+     PROC do (PROC (TEXT CONST) operate, THESAURUS CONST thesaurus) 
+     Zweck: Ruft 'operate' nacheinander mit allen im Thesaurus enthaltenen Namen
+            auf. 
+ 
+     PROC do (PROC (TEXT CONST, TASK CONST) operate, 
+              THESAURUS CONST thesaurus, TASK CONST task) 
+     Zweck: s.o. 
+ 
+#ib#erase#ie# 
+     PROC erase (THESAURUS CONST thesaurus) 
+     Zweck: Löscht alle aufgeführten Dateien in der Vater-Task. 
+ 
+     PROC erase (THESAURUS CONST thesaurus, TASK CONST manager) 
+     Zweck: Löscht alle aufgeführten Dateien in der Task 'manager'. 
+ 
+#ib#fetch#ie# 
+     PROC fetch (THESAURUS CONST thesaurus) 
+     Zweck: Holt alle aufgeführten Dateien vom Vater. 
+ 
+     PROC fetch (THESAURUS CONST thesaurus, TASK CONST manager) 
+     Zweck: Holt alle aufgeführten Dateien vom 'manager'. 
+ 
+#ib#fetch all#ie# 
+     PROC fetch all (TASK CONST manager) 
+     Zweck: Holt alle Dateien vom 'manager'. Diese Prozedur entspricht dem Aufruf
+            der Prozedur 'fetch (ALL manager, manager)'. 
+ 
+     PROC fetch all 
+     Zweck: Aufruf der Prozedur 'fetch all (father)'. 
+ 
+#ib#forget#ie# 
+     PROC forget (THESAURUS CONST thesaurus) 
+     Zweck: Löscht alle aufgeführten Dateien in der Benutzer-Task. 
+ 
+#ib#insert#ie# 
+     PROC insert (THESAURUS CONST thesaurus) 
+     Zweck: Insertiert alle aufgeführten Dateien in der Benutzer-Task. 
+ 
+#ib#remainder#ie# 
+     PROC remainder 
+     Zweck: Liefert nach einem 'errorstop' die noch nicht bearbeiteten Dateien. 
+            Beispiel: 
+              'save all (archive)' 
+                 kann dazu führen, daß nicht alle Dateien auf das Archiv geschrie­
+                 ben werden können. Fehlermeldung: 
+              '"....." kann nicht geschrieben werden (Archiv voll)' 
+                 Nachdem man eine neue Floppy ins Archivlaufwerk gelegt hat,
+                 kann man mit 
+              'save (remainder, archive)' 
+                 den Rest der Dateien auf der Floppy sichern. 
+ 
+#ib#save#ie# 
+     PROC save (THESAURUS CONST thesaurus) 
+     Zweck: Schickt alle aufgeführten Dateien zur Vater-Task. 
+ 
+     PROC save (THESAURUS CONST thesaurus, TASK CONST manager) 
+     Zweck: s.o. 
+ 
+#ib#save all#ie# 
+     PROC save all (TASK CONST manager) 
+     Zweck: Schickt alle eigenen Dateien zum 'manager'. Diese Prozedur entspricht
+            dem Aufruf der Prozedur 'save (ALL myself, manager)'. 
+ 
+     PROC save all 
+     Zweck: Aufruf der Prozedur 'save all (father)'. 
+ 
+ 
+Beispiele: 
+ 
+                    save (ALL myself) 
+                    forget (ALL myself) 
+                    forget (all) 
+                    fetch (SOME father) 
+                    fetch (ALL father - ALL myself) 
+                    insert (ALL "gen datei") 
+                    save (ALL myself - ALL archive, archive) 
+ 
+ 
+ 
+ 
+#ib(9)#4.3. #ib#Kommandos und Dialog#ie(9)##ie# 
+ 
+ 
+ 
+#ib##ib(9)#Kommandodialog#ie##ie(9)# 
+ 
+ 
+Das Paket "#ib#command dialogue#ie#" dient zur zentralen Steuerung und einfachen Durch­
+führung von #ib#Kommando-Dialog#ie#en wie 
+ 
+     "datei" loeschen (j/n)? 
+ 
+Er wird von allen Systemteilen verwandt, die einen Kommandodialog mit dem Benut­
+zer aufnehmen. Anwenderprozeduren mit ähnlichen Problemen sollten genauso damit
+arbeiten. 
+ 
+Der Kommandodialog kann zentral aus- und eingeschaltet werden. 
+ 
+ 
+ 
+#ib#command dialogue#ie# 
+     BOOL PROC command dialogue 
+     Zweck: Liefert den aktuellen Zustand des Kommandodialogs: 
+            TRUE   -  Dialog soll geführt werden! 
+            FALSE  -  Dialog soll nicht geführt werden! 
+ 
+     PROC command dialogue (BOOL CONST status) 
+     Zweck: Schaltet den Kommandodialog ein ('status' = TRUE) oder aus ('status'
+            = FALSE). Der alte Zustand wird überschrieben. Soll später wieder in
+            den alten Zustand zurückgeschaltet werden, muß er vorher erfragt und
+            gesichert werden. 
+ 
+#ib#yes#ie# 
+     BOOL PROC yes (TEXT CONST question) 
+     Zweck: a) Kommandodialog soll geführt werden (command dialogue = TRUE) 
+               Der übergebene Fragetext wird durch " (j/n)?" ergänzt auf dem Ter­
+               minal ausgegeben. Als Antwort wird eine der Tasten <j>, <J>,
+               <y>, <Y>, <n>, <N> akzeptiert; jede andere Eingabe führt zu
+               einem akustischen Signal und der Fragewiederholung. Das Resultat
+               der Prozedur ist 
+                      TRUE  bei  bejahender Antwort (j,J,y,Y) 
+                      FALSE bei  verneinender Antwort (n,N) 
+            b) Kommandodialog soll nicht geführt werden (command dialogue =
+               FALSE) 
+               Keine Aktion, das Resultat ist TRUE. 
+ 
+#ib#no#ie# 
+     BOOL PROC no (TEXT CONST question) 
+     Zweck: a) Kommandodialog soll geführt werden (command dialogue = TRUE) 
+               Frage und Antwort wie bei 'yes'. Das Resultat ist 
+                      TRUE  bei  verneinender Antwort (n,N) 
+                      FALSE bei  bejahender Antwort (j,J,y,Y) 
+            b) Kommandodialog soll nicht geführt werden (command dialogue =
+               FALSE) 
+               Keine Aktion, das Resultat ist FALSE. 
+ 
+#ib#say#ie# 
+     PROC say (TEXT CONST message) 
+     Zweck: IF command dialogue THEN out (text) FI 
+ 
+#ib#last param#ie# 
+     TEXT PROC last param 
+     Zweck: Liefert den zuletzt gesetzten Parameter-Text (siehe folgende Proze­
+            dur). Falls 'command dialogue' = TRUE und die 'param position' > 0
+            ist, wird der Parametertext als Standardparameter an der angegebenen
+            x-Position eine Zeile höher in der Form ("...") ausgegeben. Diese Proze­
+            dur wird von den parameterlosen Kommandos bzw. Prozeduren wie
+            'edit', 'run' usw. verwandt, um mit dem Standardparameter weiterzuar­
+            beiten. 
+ 
+     PROC last param (TEXT CONST new) 
+     Zweck: Setzt 'last param' auf 'new'. (Das Setzen muß explizit durchgeführt
+            werden und geschieht nicht implizit durch den 'command handler'. 'Last
+            param' wird beispielsweise von den einparametrigen Prozeduren 'edit'
+            und 'run' gesetzt. 
+ 
+#ib#param position#ie# 
+     PROC param position (INT CONST x) 
+     Zweck: Setzt die Echoposition für 'last param'. Bei x=0 wird ein Echo unter­
+            drückt. 
+ 
+#ib#std#ie# 
+     TEXT PROC std 
+     Zweck: Liefert wie 'last param' den zuletzt gesetzten Parameter. Im Gegensatz
+            dazu wird der Parameter aber nicht ausgegeben. 
+ 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Kommandoverarbeitung#ie##ie(9)# 
+ 
+ 
+Das Paket '#ib#command handler#ie#' stellt Prozeduren zur #ib#Kommandoanalyse#ie# und zum
+Führen des kompletten Kommandodialogs zur Verfügung. 
+ 
+ 
+#ib#get command#ie# 
+     PROC get command (TEXT CONST dialogue text, TEXT VAR command line) 
+     Zweck: Falls eine Fehlermeldung aussteht, ('is error' liefert TRUE), wird sie über
+            'put error' ausgegeben und der Fehlerzustand zurückgesetzt. Der 'dialo­
+            gue text' wird als Dialogaufforderung ausgegeben und der Benutzer
+            kann eine Kommandozeile eingeben. Die letzte Kommandozeile wird
+            ihm dabei automatisch (zum Ändern) angeboten, wenn vorher eine
+            Fehlermeldung anstand. Der Benutzer kann dies ebenfalls erreichen,
+            wenn er zu Beginn <ESC k> gibt. Die Kommandozeile wird dem Auf­
+            rufer in der Variablen 'command line' geliefert. 
+ 
+     PROC get command (TEXT CONST dialogue text) 
+     Zweck: s.o. Allerdings wird eine interne Kommandozeile des Pakets 'command
+            handler' als 'command line' verwandt. Dadurch wird es möglich, alle
+            Spuren einer Kommandoeingabe durch 'cover tracks' zu beseitigen. 
+ 
+#ib#analyze command#ie# 
+     PROC analyze command (TEXT CONST command list, command line, 
+                           INT CONST permitted type, 
+                           INT VAR command index, number of params, 
+                           TEXT VAR param 1, param 2) 
+     Zweck: Die übergebene Kommandozeile ('command line') wird anhand der
+            übergebenen 'command list' analysiert. Sie ist ein TEXT, der aus einer
+            Folge von Kommandospezifikationen besteht. Jede hat die Form 
+                          K:I.P 
+ 
+                  K    Kommandotext, Prozedurname nach ELAN-Syntax 
+                  I    Hauptindex, Form eines INT-Denoters 
+                  P    Parameterspezifikation, eine Folge der Ziffern 0, 1 und 2. 
+ 
+             Beispiele: 
+               -  'edit:15.012' 
+                  Das Kommando 'edit' wird in drei verschieden parametrisierten
+                  Formen spezifiziert: 
+                     edit mit 0 Parameter   erhält Index 15 
+                     edit mit 1 Parameter   erhält Index 16 
+                     edit mit 2 Parametern  erhält Index 17 
+ 
+               -  'fetch:18.1' 
+                  Das Kommando 'fetch' wird in einer Form spezifiert: 
+                     fetch mit 1 Parameter  erhält Index 18 
+ 
+            Die Analyse erfolgt gemäß ELAN-Syntaxregeln. Dabei sind als Para­
+            meter Denoter vom Typ TEXT und vom übergebenen ' permitted type'
+            zugelassen. Diese Typen werden wie beim Scanner (s. Benutzerhand­
+            buch Programmierung Kap. 5.6) angegeben: 
+ 
+                1    tag 
+                2    bold 
+                3    number 
+                4    text 
+                5    operator 
+                6    delimiter 
+ 
+            Falls das Kommando in der Kommandoliste gefunden wird (und die
+            Syntax in Ordnung ist), wird der entsprechende 'command index' zu­
+            rückgemeldet. Die Parameter werden (falls vorhanden) in 'param 1' und
+            'param 2' abgelegt. Undefinierte oder nicht vorhandene Parameter
+            werden als Niltext geliefert. Wenn ein  Kommando vorhanden ist, die
+            Anzahl der Parameter aber nicht stimmt, wird der negative Hauptindex
+            geliefert. Ist es vollkommen unbekannt oder ist die Eingabe zu komplex
+            (mehrere Kommandos, Ausdrücke oder komplexere ELAN-Statements),
+            wird 0 geliefert. Der Anwender kann in solchen Fällen die Analyse mit
+            einer anderen Kommandoliste fortsetzen, das Kommando dem ELAN-
+            Compiler übergeben oder eine Fehlermeldung auslösen (s. 'command
+            error'). 
+ 
+     PROC analyze command (TEXT CONST command list, 
+                           INT CONST permitted type, 
+                           INT VAR command index, number of params, 
+                           TEXT VAR param 1, param 2) 
+     Zweck: s.o. Allerdings wird die interne Kommandozeile des Pakets 'command
+            handler' als 'command line' verwandt. 
+ 
+#ib#command error#ie# 
+     PROC command error 
+     Zweck: Falls bei der Kommandoanalyse ein Fehler gefunden wurde, führt er
+            nicht zum 'errorstop', sondern wird nur hinterlegt. (Soll das Kommando
+            dem Compiler übergeben werden, liegt ja evt. überhaupt kein Fehler
+            vor.) Diese hinterlegte Meldung kann mit 'command error' als 'errorstop'
+            gegeben werden. Mögliche Meldungen: 
+                    "ungueltiger name" 
+                    ") fehlt" 
+                    "( fehlt" 
+                    "Parameter ist kein TEXT ("fehlt)" 
+                    "Kommando zu schwierig" 
+ 
+#ib#cover tracks#ie# 
+     PROC cover tracks 
+     Zweck: Die Spuren der letzten Kommandoanalyse werden gelöscht. Das dient
+            u.a. dazu, daß später eingerichtete Sohntasks keine Relikte des Kom­
+            mandos mehr auf dem Textheap vorfinden und evtl. mittels nicht initiali­
+            sierter TEXT VARs herausfinden können. Vollständig können die Spuren
+            aber nur dann gelöscht werden, wenn für die Kommandoanalyse die
+            'get command'- und 'analyze command'-Prozeduren benutzt wurden,
+            die auf der internen Kommandozeile des Pakets 'command handler'
+            arbeiten. 
+ 
+#ib#do command#ie# 
+     PROC do command 
+     Zweck: Die interne Kommandozeile des Pakets 'command handler' wird dem
+            ELAN-Compiler zur Ausführung übergeben. 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#Beispiele zur Kommandoverarbeitung#ie(9)# 
+ 
+ 
+#ib##ub#Kleiner Monitor#ue##ie# 
+ 
+ 
+LET command list = "otto:1.12emil:3.012hugo:6.0" ; 
+ 
+LET   number = 3 , 
+      text   = 4 ; 
+ 
+INT VAR command index, params ; 
+TEXT VAR param 1, param 2 ; 
+ 
+PROC monitor : 
+ 
+     disable stop ; 
+     command dialogue (TRUE) ; 
+     REP  get command ("gib kleines kommando:") ; 
+          analyze command (command list, text, 
+                           command index, params, 
+                           param 1, param 2) ; 
+          execute command 
+     PER 
+ 
+ENDPROC monitor ; 
+ 
+PROC execute command : 
+ 
+     enable stop ; 
+     SELECT command index OF 
+          CASE 1 : otto (param 1) 
+          CASE 2 : otto (param 1, param 2) 
+          CASE 3 : emil 
+          CASE 4 : emil (param 1) 
+          CASE 5 : emil (param 1, param 2) 
+          CASE 6 : hugo 
+       OTHERWISE do command line 
+     END SELECT 
+ 
+ENDPROC execute command ; 
+ 
+ 
+ 
+#ib(9)##ub#Steuerkommando-Analyse#ue##ie(9)# 
+ 
+ 
+PROC command (TEXT CONST command text) : 
+ 
+     disable stop ; 
+     command dialoge (FALSE) ; 
+     analyze command (command list, command text, number, 
+                      command index, params, param 1, param 2) ; 
+     execute command ; 
+     IF is error 
+       THEN put error ; 
+            clear error 
+     FI 
+ 
+ENDPROC command ; 
+ 
+PROC execute command : 
+ 
+     enable stop ; 
+     SELECT command index OF 
+          CASE .... 
+        OTHERWISE    IF command index = 0 
+                        THEN errorstop ("unbekanntes Kommando") ELSE command error 
+                     FI 
+     END SELECT 
+ 
+ENDPROC execute command ; 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#4.4. Verschiedenes#ie(9)# 
+ 
+ 
+#ib(9)##ib#SESSION#ie(9)##ie# 
+ 
+ 
+Mit Hilfe von 'session' kann man feststellen, ob das System neu gestartet wurde. Dabei
+spielt es keine Rolle, ob es korrekt ('shutup') abgeschaltet wurde, oder ob es sich um
+einen "RERUN" handelt. 
+ 
+#ib#session#ie# 
+     INT PROC session 
+     Zweck: Liefert eine "Sitzungsnummer". Diese wird automatisch bei jedem
+            Systemstart erhöht. 
+ 
+Beispiel: 
+ 
+ 
+     REP 
+       INT VAR old session := session ; 
+       WHILE session = old session REP pause (100) PER ; 
+       putline ("Neuer Systemstart") 
+     PER. 
+ 
+ 
+ 
+ 
+#ib(9)##ib#INITFLAG#ie##ie(9)# 
+ 
+ 
+Im Multi-User-System ist es oft notwendig, Pakete beim Einrichten einer neuen Task in
+dieser neu zu initialisieren. Das muß z.B. bei der Dateiverwaltung gemacht werden, da
+die neue Task ja nicht die Dateien des Vaters erbt. Mit Hilfe von INITFLAG-Objekten
+kann man zu diesem Zweck feststellen, ob ein Paket #on("b")##on("i")#in dieser Task#off("b")##off("i")# schon initialisiert
+wurde. 
+ 
+ 
+#ib#INITFLAG#ie# 
+     TYPE INITFLAG 
+     Zweck: Erlaubt die Deklaration entsprechender Flaggen. 
+ 
+:= 
+     OP := (INITFLAG VAR flag, BOOL CONST flagtrue) 
+     Zweck: Erlaubt die Initialisierung von INITFLAGs 
+ 
+#ib#initialized#ie# 
+     BOOL PROC initialized (INITFLAG VAR flag) 
+     Zweck: Wenn die Flagge in der Task A auf TRUE oder FALSE gesetzt wurde,
+            dann liefert sie beim ersten Aufruf den entsprechenden Wert, danach
+            immer TRUE (in der Task A!). 
+            Beim Einrichten von Söhnen wird die Flagge in den Sohntasks automa­
+            tisch auf FALSE gesetzt. So wird erreicht, daß diese Prozedur in den neu
+            eingerichteten Söhnen und Enkeltasks genau beim ersten Aufruf FALSE
+            liefert. 
+ 
+ 
+Beispiel: 
+ 
+          PACKET stack DEFINES push, pop: 
+ 
+          INITFLAG VAR in this task := FALSE ; 
+          INT VAR stack pointer ; 
+          ROW 1000 INT VAR stack ; 
+ 
+          PROC push (INT CONST value) : 
+ 
+            initialize stack if necessary ; 
+            .... 
+ 
+          ENDPROC push ; 
+ 
+          PROC pop (INT VAR value) : 
+ 
+            initialize stack if necessary ; 
+            .... 
+ 
+          ENDPROC pop ;. 
+ 
+          initialize stack if necessary : 
+            IF NOT initialized (in this task) 
+              THEN stack pointer := 1 
+            FI . 
+ 
+          ENDPACKET stack 
+ 
+ 
+ 
+ 
+ 
+#ib(9)##ib#Bit-Handling#ie##ie(9)# 
+ 
+ 
+Die #ib#Bit-Operationen#ie# arbeiten auf INT-Objekten. Sie können z.B. für die Systempro­
+grammierung benutzt werden, wenn es um Bitmasken u.ä. geht. 
+ 
+Ein INT besteht aus 16 Bits. Dabei hat das niederwertigste die Nummer 0, das höch­
+stwertige die Nummer 15. 
+ 
+ 
+#ib#AND#ie# 
+     INT OP AND (INT CONST left, right) 
+     Zweck: Bitweise UND-Verknüpfung von 'left' mit 'right'. 
+ 
+#ib#OR#ie# 
+     INT OP OR (INT CONST left, right) 
+     Zweck: Bitweise ODER-Verknüpfung von 'left' mit 'right'. 
+ 
+#ib#XOR#ie# 
+     INT OP XOR (INT CONST left, right) 
+     Zweck: Bitweise EXCLUSIV-ODER-Verknüpfung von 'left' mit 'right'. 
+ 
+#ib#bit#ie# 
+     BOOL PROC bit (INT CONST bits, bit no) 
+     Zweck: Liefert TRUE genau dann, wenn das Bit mit der Nummer 'bit no' in dem
+            INT 'bits' gesetzt ist. 
+ 
+#ib#set bit#ie# 
+     PROC set bit (INT VAR bits, INT CONST bit no) 
+     Zweck: Das Bit mit der Nummer 'bit no' wird in 'bits' auf 1 gesetzt. 
+ 
+#ib#reset bit#ie# 
+     PROC reset bit (INT VAR bits, INT CONST bit no) 
+     Zweck: Das Bit mit der Nummer 'bit no' wird in 'bits' auf 0 gesetzt. 
+ 
+#ib#rotate#ie# 
+     PROC rotate (INT VAR bits, INT CONST number of bits) 
+     Zweck: Bits können mit dieser Prozedur zyklisch geschiftet werden. 
+            Bsp.: rotate (1,1)      ---> 2 
+                  rotate (1,2)      ---> 4 
+                  rotate (1,-3)     ---> 16384 
+                  rotate (16384,3)  ---> 1 
+ 
+#ib#lowest set#ie# 
+     INT PROC lowest set (INT CONST bits) 
+     Zweck: Liefert die Nummer des niederwertigsten 1-Bits in 'bits'. Ist kein Bit auf 1
+            gesetzt, wird -1 geliefert. 
+ 
+#ib#lowest reset#ie# 
+     INT PROC lowest reset (INT CONST bits) 
+     Zweck: Liefert die Nummer des niederwertigsten 0-Bits in 'bits'. Ist kein Bit auf 0
+            gesetzt, wird -1 geliefert. 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#4.5. #ib#Blockorientierte Ein-/Ausgabe#ie##ie(9)# 
+ 
+ 
+ 
+Die blockorientierte Ein-/Ausgabe dient dazu, Datenraumseiten (#ib#Blöcke#ie#) oder Teile
+davon über die #ib#Kanäle#ie# zu transferieren. Sie wird vom System u.a. beim Archivzugriff
+und bei der Konfigurierung der Kanäle eingesetzt. 
+ 
+Die Wirkung der blockorientierten Ein-/Ausgabeoperationen kann dabei kanal- und
+rechnerspezifisch unterschiedlich sein. 
+Auf dem Archivkanal (31) und allen anderen Block-IO-Kanälen werden bei 
+'code 1 = 0' die normalen Blocklese- bzw. -schreiboperationen durchgeführt. 'code 2'
+gibt dabei die Blocknummer an. Andere (positive) Werte von 'code 1' sind zur Zeit
+nicht offiziell definiert. Negative Werte können vom SHard für Spezialaufgaben verge­
+ben werden. 
+ 
+ 
+ 
+#ib#blockin#ie# 
+     PROC blockin (DATASPACE VAR ds, INT CONST page nr, code1, code2, 
+                   INT VAR return code) 
+     Zweck: Die Seite 'page nr' des Datenraums 'ds' wird "eingelesen". Die Opera­
+            tion kann durch 'code1' und 'code2' näher gesteuert werden. 
+ 
+     PROC blockin (ROW 256 INT VAR block, INT CONST code1, code2, 
+                   INT VAR return code) 
+     Zweck: Wie oben, nur wird der Block direkt als Datenstruktur übergeben. 
+ 
+#ib#blockout#ie# 
+     PROC blockout (DATASPACE CONST ds, INT CONST page nr, 
+                    code1, code2, INT VAR return code) 
+     Zweck: Die Seite 'page nr' des Datenraums 'ds' wird "ausgegeben". Die Opera­
+            tion kann durch 'code1' und 'code2' näher gesteuert werden. 
+ 
+     PROC blockout (ROW 256 INT CONST block, INT CONST code1, code2, 
+                    INT VAR return code) 
+     Zweck: Wie oben, nur wird der Block als Datenstruktur übergeben. 
+ 
+#ib#control#ie# 
+     PROC control (INT CONST code1, code2, code3, INT VAR return code) 
+     Zweck: Diese Prozedur dient zur Kanalsteuerung. 
+ 
+#ib#ds pages#ie# 
+     INT PROC ds pages (DATASPACE CONST ds) 
+     Zweck: Liefert die Anzahl der belegten Seiten eines Datenraums. (Jede Seite ist
+            512 Byte groß.) 
+ 
+#ib#next ds page#ie# 
+     INT PROC next ds page (DATASPACE CONST ds, INT CONST page nr) 
+     Zweck: Liefert die Nummer der nächsten (von 'page nr' an gerechneten) Seite
+            des Datenraums. Die erste belegte Seite erhält man durch 
+ 
+                     next ds page (ds, -1) 
+ 
+            #on ("b")#Achtung: Die Seitennummern müssen nicht lückenlos sein.#off ("b")# 
+
diff --git a/doc/system/systemhandbuch.3 b/doc/system/systemhandbuch.3
new file mode 100644
index 0000000..3c0a482
--- /dev/null
+++ b/doc/system/systemhandbuch.3
@@ -0,0 +1,1366 @@
+#start(2.5,1.5)# 
+#pageblock# 
+#block# 
+#page (63)# 
+#headeven# 
+ 
+%#center#EUMEL-Systemhandbuch 
+ 
+ 
+#end# 
+#headodd# 
+ 
+#center#5. Supervisor, Tasks und Systemsteuerung#right#% 
+ 
+ 
+#end# 
+ 
+#ib(9)#5. #ib#Supervisor#ie#, #ib#Tasks#ie# und 
+   #ib#Systemsteuerung#ie##ie(9)# 
+ 
+ 
+ 
+#ib(9)#5.1. #ib#Tasks#ie##ie(9)# 
+ 
+ 
+ 
+#ib(9)#Der Datentyp #ib#TASK#ie##ie(9)# 
+ 
+ 
+Benannte Tasks werden innerhalb eines Rechners vollständig und eindeutig über ihren
+Namen identifiziert. Eine weitere Möglichkeit der Identifikation besteht in der Verwen­
+dung von Datenobjekten vom Typ TASK. Beispiel: 
+ 
+        TASK VAR plotter := task ("PLOTTER 1") 
+ 
+Die Taskvariable 'plotter' bezeichnet jetzt die Task im System, die augenblicklich den
+Namen "PLOTTER 1" hat. Nun sind #ib#Taskvariablen#ie# auch unter Berücksichtigung der Zeit
+und nicht nur im aktuellen Systemzustand eindeutig. Der Programmierer braucht sich
+also keine Sorgen darüber zu machen, daß seine Taskvariable irgendwann einmal eine
+"falsche" Task (nach Löschen von "PLOTTER 1" neu eingerichtete gleichen oder ande­
+ren Namens) identifiziert. Wenn die Task "PLOTTER 1" gelöscht worden ist, bezeichnet
+'plotter' keine gültige Task mehr. 
+ 
+#ib#Unbenannte Tasks#ie# haben alle den Pseudonamen "-". Sie können nur über Taskvari­
+ablen angesprochen werden. 
+ 
+Der #ib#Task-Katalog#ie# wird vom Supervisor geführt; andere Tasks können sich Kopien
+dieses Katalogs besorgen. Einige Prozeduren arbeiten auf dieser taskeigenen Kopie,
+ohne diese automatisch auf den neuesten Stand zu bringen (Effizienzgründe). Das
+muß bei Bedarf explizit geschehen. 
+ 
+ 
+#ib#TASK#ie# 
+     TYPE TASK 
+     Zweck: Interner Taskbezeichner 
+ 
+:= 
+     OP := (TASK VAR dest, TASK CONST source) 
+     Zweck: Zuweisung von internen Taskbezeichnern 
+ 
+= 
+     BOOL OP = (TASK CONST left, right) 
+     Zweck: Gleichheitsabfrage 
+ 
+< 
+     BOOL OP < (TASK CONST left, right) 
+     Zweck: Überprüft, ob die Task 'left' ein Sohn, Enkel, Urenkel, ... der Task 'right'
+            ist. 
+ 
+/ 
+     TASK OP / (TEXT CONST task name) 
+     Zweck: Liefert die Task des angegebenen Namens, falls sie existiert. Der eigene
+            Katalog wird automatisch aktualisiert (identisch mit der
+            PROC task (TEXT CONST task name). 
+     Fehlerfall: 
+          * ... gibt es nicht 
+ 
+     TASK OP / (INT CONST station number, TEXT CONST name) 
+     Zweck: Liefert die Task des angegebenen Namen von der Station mit der ange­
+            gebenen Nummer. 
+ 
+#ib#access#ie# 
+     PROC access (TASK CONST task) 
+     Zweck: Aktualisiert den eigenen Taskkatalog, falls 'task' nicht darin enthalten ist. 
+ 
+#ib#access catalogue#ie# 
+     PROC access catalogue 
+     Zweck: Aktualisiert den eigenen Taskkatalog, indem die neueste Fassung vom
+            Supervisor geholt wird. Die Prozeduren 'father', 'son', 'brother' arbeiten
+            dann auf dieser neuen Fassung. 
+ 
+#ib#archive#ie# 
+     TASK PROC archive 
+     Zweck: Liefert den internen Taskbezeichner der aktuellen Task mit Namen
+            "ARCHIVE". Diese Prozedur dient zum schnellen und bequemen An­
+            sprechen der Archivtask. 
+ 
+#ib#brother#ie# 
+     TASK PROC brother (TASK CONST task) 
+     Zweck: Liefert den nächsten Bruder von 'task'. Falls kein Bruder existiert, wird
+            'niltask' geliefert. Aktualisiert den eigenen Katalog nicht automatisch! 
+ 
+#ib#canal#ie# 
+     TASK PROC canal (INT CONST channel number) 
+     Zweck: Diese Prozedur zeigt an, welche Command-Analyser-Task an einem
+            bestimmten Kanal hängt. 
+ 
+#ib#exists#ie# 
+     BOOL PROC exists (TASK CONST task) 
+     Zweck: Falls 'task' auf der eigenen Station liegt, informiert diese Prozedur, ob
+            die angegebene 'task' noch existiert. Der eigene Taskkatalog wird dabei
+            aktualisiert. 
+            Wenn abgefragt werden soll, ob 'task' auf einer anderen Station liegt,
+            muß die Prozedur 'name (task) <> "" ' verwendet werden. 
+            Achtung: Diese Prozedur taugt nicht dazu, zu erfragen, ob eine Task
+                     mit bestimmtem Namen im System exisiert. 
+ 
+                            exists (task ("hugo")) 
+ 
+                     Falls die Task "hugo" nicht existiert, führt schon der Aufruf
+                     'task ("hugo")' zum 'errorstop (""hugo" gibt es nicht")'. 
+ 
+#ib#exists task#ie# 
+     BOOL PROC exists task (TEXT CONST name) 
+     Zweck: Wenn auf der eigenen Station eine Task mit dem Namen 'name' exi­
+            stiert, liefert diese Prozedur 'TRUE'. 
+ 
+#ib#father#ie# 
+     TASK PROC father 
+     Zweck: Liefert die eigene Vatertask. 
+ 
+     TASK PROC father (TASK CONST task) 
+     Zweck: Liefert den Vater von 'task'. Existiert kein Vater (z.B. bei UR), wird niltask
+            geliefert. Aktualisiert den eigenen Katalog nicht automatisch! 
+ 
+#ib#index#ie# 
+     INT PROC index (TASK CONST task) 
+     Zweck: Liefert einen INT-Wert von 1 bis 125, der 'task' unter allen gleichzeitig (!)
+            existierenden Tasks eindeutig identifiziert. 
+ 
+#ib#is niltask#ie# 
+     BOOL PROC is niltask (TASK CONST task) 
+     Zweck: task = niltask 
+ 
+#ib#myself#ie# 
+     TASK PROC myself 
+     Zweck: Liefert eigenen Task-Bezeichner. 
+ 
+#ib#name#ie# 
+     TEXT PROC name (TASK CONST task) 
+     Zweck: Liefert den Namen von 'task'. Die Task muß noch im System existieren,
+            sonst ist der Name nicht mehr bekannt. Falls die 'task' noch nicht im
+            eigenen Katalog enthalten ist, wird er aktualisiert. 
+ 
+#ib#niltask#ie# 
+     TASK CONST niltask 
+     Zweck: Bezeichner für "keine Task". So liefern die Prozeduren 'son', 'brother'
+            und 'father' als Resultat 'niltask', wenn keine Sohn-, Bruder- oder Vater­
+            task existiert. 
+ 
+#ib#printer#ie# 
+     TASK PROC printer 
+     Zweck: Liefert den internen Taskbezeichner der aktuellen Task mit Namen
+            #ib#PRINTER#ie#. Diese Prozedur dient zum schnellen und bequemen Anspre­
+            chen des Druckspoolers. 
+ 
+#ib#public#ie# 
+     TASK PROC public 
+     Zweck: Liefert den internen Taskbezeichner der Task #ib#PUBLIC#ie#. 
+ 
+#ib#reserve#ie# 
+     PROC reserve (TASK CONST task) 
+     Zweck: Reservieren einer Task für den ausschließlichen Dialog mit der Task, in
+            der das Kommando gegeben wurde. 
+     PROC reserve (TEXT CONST message, TASK CONST task) 
+     Zweck: Wie 'reserve (TASK CONST task)' mit Übergabe einer 'message'. 
+ 
+#ib#son#ie# 
+     TASK PROC son (TASK CONST task) 
+     Zweck: Liefert den ersten Sohn von 'task'. Falls keiner im Katalog vermerkt ist,
+            wird 'niltask' geliefert. Aktualisiert den eigenen Katalog nicht automa­
+            tisch! 
+ 
+#ib#supervisor#ie# 
+     TASK PROC supervisor 
+     Zweck: Liefert den internen Taskbezeichner des Supervisors. 
+ 
+#ib#task#ie# 
+     TASK PROC task (TEXT CONST task name) 
+     Zweck: Liefert die Task des angegebenen Namens, falls sie existiert. Der eigene
+            Katalog wird automatisch aktualisiert. 
+     Fehlerfall: 
+          * ... gibt es nicht 
+ 
+     TASK PROC task (INT CONST channel number) 
+     Zweck: Liefert den Namen der Task, die an dem angegebenen Kanal hängt. 
+ 
+ 
+ 
+#ib##ib(9)#Inter-Task-Kommunikation#ie##ie(9)# 
+ 
+ 
+Die #ib#Task-Kommunikation#ie# im EUMEL System ist strikt botschaftsorientiert. Eine #ib#Bot­
+schaft#ie# bzw. "#ib#Sendung#ie#" besteht immer aus einem #ib#Sendungscode#ie# (INT) und einem
+Datenraum (DATASPACE). Damit kann eine Botschaft bis zu 1 Mbyte umfassen! 
+ 
+Kommunikation zwischen zwei Tasks ist nur dann möglich, wenn #ib#Sender#ie# und #ib#Empfän­
+ger#ie# dazu bereit sind. Eine Sendung kann also nur dann korrekt transferiert werden,
+wenn der Empfänger existiert und empfangsbereit ist. Diese Art der Kommunikation
+wurde gewählt, um 
+ 
+    -  eine möglichst einfache und effiziente Implementation zu ermöglichen und 
+    -  mit den vorhandenen Primitiva möglichst flexibel bei der Implementation
+       "höherer" Kommunikationsmethoden (z.B. Warteschlangen) zu sein. 
+ 
+ 
+#ib#call#ie# 
+     PROC call (TASK CONST destination, INT CONST send code, 
+                DATASPACE VAR message ds, INT VAR reply code) 
+     Zweck: Die eigene Task wartet, bis die Zieltask 'destination' empfangsbereit ist.
+            Dann wird die Sendung ('send code' und 'message ds') transferiert.
+            Anschließend wartet die Sendertask auf eine Antwort von 'destination'.
+            Für Sendungen anderer Tasks ist sie dabei nicht (!) empfangsbereit, nur
+            die Zieltask kann eine Antwortsendung schicken. Nachdem eine solche
+            Antwort eingetroffen ist, wird sie in 'message ds' und 'reply code' gelie­
+            fert und die eigene Task fortgesetzt. Wenn die angesprochene Zieltask
+            nicht existiert, wird -1 als 'reply code' geliefert. 'message ds' ist in
+            diesem Fall unverändert. 
+            'call' hat Ähnlichkeiten mit einem Prozeduraufruf, nur ist es hier der
+            Aufruf einer anderen Task. Störungen können hierbei nicht auftreten, da
+            der Zustand der Zieltask keine Rolle spielt (es wird auf Empfangsbereit­
+            schaft gewartet) und beim Warten auf Antwort auch keine "Querschlä­
+            gersendungen" von anderen Tasks dazwischenfunken können. 
+ 
+#ib#pingpong#ie# 
+     PROC pingpong (TASK CONST destination, INT CONST send code, 
+                    DATASPACE VAR message ds, INT VAR reply code) 
+     Zweck: Diese Prozedur wirkt wie die entsprechende 'call'-Prozedur, wartet aber
+            nicht (!), bis die Zieltask empfangsbereit ist. Wenn die Zieltask existiert,
+            aber nicht empfangsbereit ist, wird -2 als 'reply code' geliefert. Der
+            'message ds' ist dann nicht verändert. 
+ 
+#ib#send#ie# 
+     PROC send (TASK VAR destination, INT CONST send code, 
+                DATASPACE VAR message ds, INT VAR receipt) 
+     Zweck: Wenn die Zieltask existiert und empfangsbereit ist, wird die Sendung
+            ('send code' und 'message ds') transferiert und die Zieltask aktiviert. Als
+            'receipt' wird 0 (=ack) gemeldet. Diese positive Quittung kommt nicht
+            von der Zieltask, sondern bestätigt nur, daß die Sendung ordnungsge­
+            mäß übertragen wurde. Der Datenraum gehört dann nicht mehr der
+            Sender-, sondern der Zieltask, d.h. die Variable 'message ds' bezeichnet
+            keinen gültigen Datenraum mehr. 
+            Im Gegensatz zu 'call' und 'pingpong' läuft die Sendertask ohne Halt
+            weiter und wartet nicht auf eine Antwort von der Zieltask. 
+            Falls die Zieltask nicht existiert, wird -1, falls sie nicht empfangsbereit ist,
+            -2 als 'receipt' geliefert. Bei diesen negativen Quittungen bleibt der
+            Datenraum Eigentum der Absendertask, d.h. die Variable 'message ds'
+            bezeichnet immer noch einen gültigen Datenraum. 
+ 
+     PROC send (TASK VAR destination, INT CONST send code, 
+                DATASPACE VAR message ds) 
+     Zweck: s.o. Negative Quittungen (-1 oder -2) werden jedoch ignoriert. Der Da­
+            tenraum wird entweder transferiert oder gelöscht ('forget'), steht also in
+            keinem Fall mehr zur Verfügung. Die Prozedur sollte nur verwendet
+            werden, wenn der Sender sicher ist, daß die Sendung transferiert wer­
+            den kann, bzw. daß sie im Fehlerfall nicht transferiert zu werden braucht. 
+ 
+#ib#wait#ie# 
+     PROC wait (DATASPACE VAR message ds, INT VAR message code, 
+                TASK VAR source task) 
+     Zweck: Die eigene Task geht in den #ub##ib#offenen Wartezustand#ie##ue# über. Sie ist jetzt
+            gegenüber allen anderen Tasks empfangsbereit. Sie wird erst fortge­
+            setzt, wenn eine Sendung eintrifft. Diese wird in 'message ds' und 'mes­
+            sage code', die Absendertask in 'source task' geliefert. 
+ 
+Der #ub##ib#Sendungscode#ue##ie# muß zwischen den Beteiligten abgesprochen sein und ist also frei
+wählbar. Allerdings sind negative Werte nicht erlaubt, sondern für bestimmte "Pseudo­
+antworten" vom Betriebssystem reserviert: 
+ 
+      -1      "Zieltask existiert nicht" 
+ 
+      -2      "Zieltask ist nicht empfangsbereit" 
+ 
+      -4      "Eingabe vom Kanal" Diese Meldung kann nur (!) beim offenen War­
+              ten ('wait') auftreten, und auch dann nur, wenn die Task gleichzeitig
+              an einen Kanal angekoppelt ist. Auf diese Weise wird mitgeteilt, daß
+              mindestens ein Zeichen vorliegt. Dieses kann im folgenden mit 'in­
+              char', 'incharety', 'blockin' oder darauf aufbauenden Prozeduren
+              gelesen werden. 
+ 
+Weitere Codes werden in Systemroutinen standardmäßig verwandt und sollten auch
+von Anwenderroutinen genauso interpretiert werden: 
+ 
+       0      "#ib#ack#ie#"        positive Quittung 
+ 
+       1      "#ib#nak#ie#"        negative Quittung 
+ 
+       2      "#ib#error nak#ie#"  negative Quittung mit Fehlermeldung. 
+                           Der gelieferte Datenraum sollte die Struktur eines
+                           BOUND TEXTs haben und die Fehlermeldung in
+                           diesem TEXT beinhalten. 
+ 
+ 
+Beispiel:      #ub#Kommunikation mit einem Manager#ue# 
+ 
+ 
+     Auftraggeber                  Manager 
+ 
+ 
+     call (....)                   REP 
+                                     wait (ds, order, order task) ; 
+                                     execute order ; 
+                                     send (order task, reply, ds) 
+                                   PER 
+ 
+Da der Auftraggeber 'call' verwendet, wartet er automatisch so lange, bis der Manager
+für ihn empfangsbereit wird. Dann schickt er die Sendung und geht gleichzeitig (!) in
+den geschlossenen "auf Antwort warten" - Zustand über. Der Manager kann daher
+unbesorgt mit dem "unsicheren" 'send' antworten, da die Empfangsbereitschaft des
+Auftraggebers nur durch Katastrophen wie Löschung der Task oder "halt from terminal"
+gestört werden kann. (In diesen Fällen kann die Antwort ruhig ins Leere gehen.) 
+ 
+Hier sieht man auch den Unterschied zwischen 
+ 
+       call (...)      und       send (....); wait (....) . 
+ 
+Bei der zweiten Alternative können drei Störfälle eintreten: 
+ 
+ 
+     a) Der Manager ist nicht empfangsbereit. 'send' versagt, 'wait' wartet ewig. 
+ 
+     b) Da über die zeitlichen Rahmenbedingungen nichts ausgesagt werden kann,
+        ist es möglich, daß der Manager die Antwort schickt, bevor die 'wait'-Opera­
+        tion beim Auftraggeber ausgeführt werden konnte. In unserem Beispiel
+        würde das den Verlust der Rückmeldung und ewiges Warten seitens des
+        Auftraggebers auslösen. 
+ 
+     c) Beim 'wait' kann eine Störsendung einer anderen Task eintreffen. 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#5.2. #ib#Supervisor#ie##ie(9)# 
+ 
+ 
+ 
+#ib(9)##ib#Verbindung zum Supervisor#ie##ie(9)# 
+ 
+ 
+#ib#begin#ie# 
+     PROC begin (PROC start, TASK VAR new task) 
+     Zweck: Es wird eine #ib#unbenannte Task#ie# (Pseudoname "-") als neuer Sohn der
+            aufrufenden eingerichtet und mit der Prozedur 'start' gestartet. Namens­
+            kollision ist nicht möglich, die erzeugte Task kann aber auch nicht na­
+            mensmäßig angesprochen werden. 'new task' identifiziert den neuen
+            Sohn, falls kein Fehler auftrat. 
+     Fehlerfälle : 
+          * zu viele Tasks 
+ 
+     PROC begin (TEXT CONST son name, PROC start, TASK VAR new task) 
+     Zweck: Es wird eine Task mit Namen 'son name' als Sohn der aufgerufenen
+            eingerichtet und mit der Prozedur 'start' gestartet. 'new task' identifi­
+            ziert den neuen Sohn, falls kein Fehler auftrat. 
+     Fehlerfälle : 
+          * zu viele Tasks 
+          * Name unzulaessig        (* "" oder LENGTH > 100 *) 
+          * ... existiert bereits 
+ 
+#ib#begin password#ie# 
+     PROC begin password (TEXT CONST password) 
+     Zweck: Bei normalen 'global manager'-Tasks kann man mit dieser Operation
+            das weitere Kreieren von Sohntasks unter Paßwortkontrolle stellen.
+            Wenn dieses Kommando in der Manager-Task gegeben worden ist, wird
+            bei folgenden SV-begin-Kommandos interaktiv das Paßwort verlangt.
+            Dabei gelten die üblichen Paßwort-Konventionen: 
+ 
+                 a) "" (Niltext) bedeutet #on("i")#kein Paßwort#off("i")#. Damit kann man durch
+                    'begin password ("")' das Paßwort wieder ausschalten. 
+                 b) "-" bedeutet #on("i")#jedes eingegebene Paßwort ist ungültig#off("i")#. Damit
+                    kann man durch 'begin password ("-")' das Einrichten von
+                    Sohntasks von außen (durch SV-Kommando) abschalten. 
+ 
+#ib#break#ie# 
+     PROC break 
+     Zweck: Die Task koppelt sich von einem evtl. angekoppelten Terminal ab. Bei
+            der Abkopplung wird auf dem Terminal die "Tapete" ("Terminal n...
+            EUMEL Version ..../M...") ausgegeben. 
+ 
+     PROC break (QUIET CONST quiet) 
+     Zweck: Die Task koppelt sich von einem evtl. angekoppelten Terminal ab. Dabei
+            wird aber keine "Tapete" ausgegeben. 
+ 
+#ib#channel#ie# 
+     INT PROC channel 
+     Zweck: Liefert die #ib#Kanalnummer#ie# der eigenen Task. Falls kein Kanal (Terminal)
+            zugeordnet ist, wird 0 geliefert. 
+ 
+     INT PROC channel (TASK CONST task) 
+     Zweck: Liefert die Kanalnummer der angegebenen Task. Ist kein Kanal zuge­
+            ordnet, wird 0 geliefert. 
+ 
+#ib#clock#ie# 
+     REAL PROC clock (INT CONST index) 
+     Zweck: Liefert die über Index spezifizierte #ib#Systemuhr#ie#. Die Zeiteinheit ist 1 sec,
+            die Meßgenauigkeit 0.1 sec. 
+                     clock (0)   :   CPU-Zeit der eigenen Task 
+                     clock (1)   :   Realzeit des Systems 
+ 
+     REAL PROC clock (TASK CONST task) 
+     Zweck: Liefert die CPU-Zeit der angegebenen Task. 
+ 
+     Hinweis: Die CPU-Zeit beginnt mit der Taskkreation zu laufen. Sie gibt also
+              jeweils die gesamte bisher verbrauchte CPU-Zeit an. Die Zeitdauer
+              bestimmter Operationen kann als Differenz zweier 'clock'-Aufrufe
+              gemessen werden. Beim Ende einer Task wird ihr CPU-Zeitverbrauch
+              dem Vater zugeschlagen, um Abrechnungen zu ermöglichen. 
+ 
+#ib#continue#ie# 
+     PROC continue (INT CONST channel nr) 
+     Zweck: Die Task versucht, sich an den vorgegebenen Kanal anzukoppeln. Falls
+            sie vorher schon an ein Terminal gekoppelt war, wird implizit 'break'
+            durchgeführt, falls die Aktion erfolgreich durchgeführt werden konnte.
+            Ein erfolgreiches 'continue' beinhaltet implizit 'reset autonom'. 
+            Anmerkung: Normale Tasks können auf die Kanäle 1-24 zugreifen,
+                       Systemtasks dürfen sich auch an die privilegierten Kanäle
+                       25-32 ankoppeln. 
+     Fehlerfälle: 
+          * ungueltiger Kanal 
+          * Kanal belegt 
+ 
+#ib#end#ie# 
+     PROC end 
+     Zweck: Löscht die eigene Task und alle Söhne. Wenn die Task an ein Terminal
+            angekoppelt ist, wird vorher angefragt, ob wirklich gelöscht werden soll.
+            Anschließend wird die Standard-"Tapete" auf dem Bildschirm ausge­
+            geben. 
+ 
+     PROC end (TASK CONST task) 
+     Zweck: Löscht die angegebene 'task'. 'task' muß allerdings die eigene oder eine
+            Sohn- bzw. Enkel-Task der eigenen sein (siehe auch: 'Privilegierte Ope­
+            rationen'). Im Unterschied zur oben aufgeführten parameterlosen Proze­
+            dur 'end' wird nicht angefragt und auch keine "Tapete" ausgegeben.
+            Wenn also die eigene Task ohne Reaktion auf dem Terminal beendet
+            werden soll, kann dies mit 'end (myself)' geschehen. 
+     Fehlerfall: 
+          * 'end' unzulaessig 
+ 
+#ib#family password#ie# 
+     PROC family password (TEXT CONST password) 
+     Zweck: Diese  Prozedur setzt oder ändert das Paßwort derjenigen Familien­
+            mitglieder, die kein Paßwort oder das gleiche Paßwort wie die aufrufen­
+            de Task haben. 
+            Zu einer Familie gehören die Task, in der man sich befindet, und die ihr
+            untergeordneten Tasks. 
+            Natürlich gelten auch hier die allgemeinen Paßwortbedingungen (siehe
+            dazu: 'task password'). 
+            Beispiel: Das Kommando 'family password ("EUMEL")' wird in SYSUR
+                      gegeben. Dadurch wird das SYSUR­Paßwort und die Paß­
+                      worte der entsprechenden Tasks unter SYSUR auf "EUMEL"
+                      gesetzt. 
+ 
+ 
+#ib#next active#ie# 
+     PROC next active (TASK VAR task) 
+     Zweck: 'task' wird auf die nächste aktive Task gesetzt. Aktiv sind alle Tasks, die
+            sich im Zustand 'busy' befinden oder auf Ein/Ausgabe warten (i/o) und
+            an einen Kanal angekoppelt sind. Beispiel: 
+ 
+ 
+                      TASK VAR actual task := myself; 
+                      REP 
+                        ... ; 
+                        next active (actual task) 
+                      UNTIL actual task = myself PER. 
+ 
+ 
+            Hier werden alle aktiven Tasks durchgemustert (z.B. für Scheduling-
+            Anwendungen). Dieses Verfahren ist sehr viel weniger aufwendig als
+            eine Durchmusterung des ganzen Taskbaumes, liefert aber nur die
+            gerade aktiven Tasks. 
+ 
+#ib#rename myself#ie# 
+     PROC rename myself (TEXT CONST new task name) 
+     Zweck: Die eigene Task erhält als neuen Tasknamen 'new task name'. Damit
+            kann auch aus einer benannten eine unbenannte Task mit dem Pseu­
+            donamen "-" werden. Umbenennung in die andere Richtung ist eben­
+            falls möglich. 
+            Achtung: Durch das Umbenennen der Task werden alle Taskvariablen,
+                     die sich auf diese Task beziehen, ungültig (als wäre die Task
+                     gelöscht und dann neu eingerichtet). 
+     Fehlerfälle: 
+          * ... existiert bereits 
+          * Name unzulaessig 
+ 
+#ib#reset autonom#ie# 
+     PROC reset autonom 
+     Zweck: Die eigene Task deklariert sich beim Supervisor als nicht autonom
+            (Normalzustand). Das bedeutet, 'continue'-Aufforderungen über ein
+            'Supervisor-Kommando' vom Terminal werden vom System ohne Be­
+            nachrichtigung der Task durchgeführt. 
+ 
+#ib#set autonom#ie# 
+     PROC set autonom 
+     Zweck: Die eigene Task deklariert sich beim Supervisor als #ib#autonom#ie# (üblich für
+            Manager-Tasks). Wenn jetzt ein 'continue'-Supervisor-Kommando auf
+            diese Task von einem Terminal aus gegeben wird, wird der Task über
+            'send' eine Nachricht zugestellt. 
+            Achtung: Im autonomen Zustand ist der Programmierer selbst für die
+                     Reaktion der Task verantwortlich. Man kann sie von außen auf
+                     keine Weise gewaltsam an ein Terminal koppeln (ermög­
+                     licht Paßalgorithmen / Datenschutz). 
+                     Um die Programmierung etwas zu entschärfen, wird eine
+                     Task automatisch aus dem autonomen in den Normalzustand
+                     überführt, wenn sie selbst ein 'continue' gibt. 
+ 
+#ib#status#ie# 
+     INT PROC status (TASK CONST task) 
+     Zweck: Liefert den Status der angegebenen Task: 
+ 
+            0    -busy-        Task ist aktiv. 
+            1    i/o           Task wartet auf Beendigung des Outputs oder
+                               auf Eingabe. 
+            2    wait          Task wartet auf Sendung von einer anderen Task. 
+            4    busy-blocked  Task ist rechenwillig, ist aber blockiert. 
+            5    i/o -blocked  Task wartet auf I/O, ist aber blockiert. 
+            6    wait-blocked  Task wartet auf Sendung, ist aber blockiert. 
+                               Achtung: Die Task wird beim Eintreffen einer
+                                        Sendung automatisch entblockiert. 
+ 
+#ib#storage#ie# 
+     PROC storage (INT VAR size, used) 
+     Zweck: Informiert über den physisch verfügbaren ('size') und belegten ('used')
+            Speicher des Gesamtsystems. Die Einheit ist KByte. 
+            Achtung: 'size' gibt den Speicher an, der benutzt werden kann, ohne in
+                     eine Engpaßsituation zu kommen. Tatsächlich wird auf dem
+                     Hintergrundmedium noch eine gewisse Reserve freigehalten.
+                     Wenn diese angebrochen wird, befindet sich das System im
+                     #ib#Speicherengpaß#ie#. Dieser Zustand kann mit 'used > size'
+                     abgefragt werden. 
+ 
+     INT PROC storage (TASK CONST task) 
+     Zweck: Liefert die Größe des Speicherbereichs in KByte, den die angegebene
+            Task augenblicklich belegt. 
+            Dabei werden durch Sharing mögliche Optimierungen nicht berücksich­
+            tigt. D.h. eine Task kann physisch erheblich weniger Speicher als logisch
+            belegen. Entsprechend kann die Speichersumme aller Tasks den phy­
+            sisch belegten Speicherbereich des Gesamtsystems beträchtlich über­
+            schreiten. 
+ 
+#ib#task password#ie# 
+     PROC task password (TEXT CONST password) 
+     Zweck: Das angegebene Paßwort wird beim Supervisor hinterlegt. Bei folgen­
+            den SV-Kommandos 'continue...' auf diese Task wird interaktiv das
+            Paßwort abgefragt. Dabei gelten die üblichen Paßwort-Konventionen: 
+ 
+                 a) "" (Niltext) bedeutet #on("i")#kein Paßwort#off("i")#. Damit kann man durch
+                    'task password ("")' das Paßwort wieder ausschalten. 
+ 
+                 b) "-" bedeutet #on("i")#jedes eingegebene Paßwort ist ungültig#off("i")#. Damit
+                    kann man durch 'task password ("-")' das Ankoppeln an ein
+                    Terminal von außen (durch SV-Kommando) unterbinden. 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Privilegierte Operationen#ie(9)##ie# 
+ 
+ 
+Die im folgenden aufgeführten privilegierten Operationen können #ub#nur#ue# von #ib#System­
+tasks#ie# - das sind direkte oder indirekte Söhne des Supervisors - ausgeführt werden. Um
+Mißbrauch unmöglich zu machen, sollte der Supervisor nach der Einrichtung der
+gewünschten Systemtasks bzgl. der Einrichtung neuer Söhne gesperrt und alle Sy­
+stemtasks durch Paßworte geschützt werden. 
+ 
+ 
+#ib#block#ie# 
+     PROC block (TASK CONST task) 
+     Zweck: Die angegebene #ib#Task wird blockiert#ie#, d.h. so lange von der Verarbeitung
+            suspendiert, bis die Blockade durch 'unblock' wieder aufgehoben wird.
+            Diese Operation wird vom Scheduler benutzt. Falls das Packet 'schedu­
+            ler' insertiert ist, sollten andere Tasks die Prozedur 'block' nicht anwen­
+            den, um dem Scheduling nicht entgegenzuwirken. 
+ 
+#ib#collect garbage blocks#ie# 
+     PROC collect garbage blocks 
+     Zweck: Es wird eine außerplanmäßige Gesamtmüllabfuhr durchgeführt. Plan­
+            mäßig (d.h. ohne Aufruf dieser Prozedur) wird sie alle 15 Minuten und in
+            Engpaßsituationen durchgeführt. Nach Aufruf dieser Prozedur wird der
+            automatische Fixpunkt/ Müllabfuhr-Rhythmus ca. 1 Stunde lang ge­
+            sperrt. Somit kann man z.B. in der Task "scheduler" einen eigenen
+            Fixpunkt/Müllabfuhr-Rhythmus implementieren. 
+            Achtung: Diese Operation erfordert starkes Paging und dauert dement­
+                     sprechend lange. 
+ 
+#ib#end#ie# 
+     PROC end (TASK CONST task) 
+     Zweck: Die angegebene Task und alle Söhne, Enkel etc. werden gelöscht.
+            Systemtasks (direkte und indirekte Nachkommen des SUPERVISORs)
+            können beliebige andere Tasks (nicht nur eigene Söhne) löschen. 
+ 
+#ib#fixpoint#ie# 
+     PROC fixpoint 
+     Zweck: Für das Gesamtsystem wird ein außerplanmäßiger #ib#Fixpunkt#ie# geschrie­
+            ben. Planmäßige Fixpunkte (d.h. ohne Aufruf dieser Prozedur) werden
+            alle 15 Minuten geschrieben. Nach Aufruf dieser Prozedur wird der
+            automatische Fixpunkt/Müllabfuhr-Rhythmus ca. 1 Stunde lang ge­
+            sperrt. Somit kann man z.B. in der Task "scheduler" einen eigenen
+            Fixpunkt/Müllabfuhr-Rhythmus implementieren. 
+            Achtung: Diese Operation verursacht starkes Paging (Rückschreiben
+                     aller veränderten Seiten auf das Hintergrundmedium) und
+                     dauert dementsprechend lange. 
+ 
+#ib#prio#ie# 
+     INT PROC prio (TASK CONST task) 
+     Zweck: Liefert die augenblickliche #ib#Priorität#ie# der angegebenen Task. 
+ 
+     PROC prio (TASK CONST task, INT CONST new prio) 
+     Zweck: Setzt die Priorität der Task. 
+ 
+     Hinweis: 0 ist die höchste, 15 die niedrigste Priorität. Die Prioritäten 0 bis 2
+              werden von EUMEL 0 (fine scheduling) verwaltet. Die restlichen Priori­
+              täten können für 'rough scheduling' (siehe auch im Kapitel Scheduler)
+              eingesetzt werden. 
+              Durch 'continue ("name")' wird die Priorität wieder auf 0 gesetzet. 
+ 
+#ib#set date#ie# 
+     PROC set date 
+     Zweck: #ib#Datum#ie# und #ib#Uhrzeit#ie# können im Dialog gesetzt werden (Form wie beim
+            Start des Systems). Dabei wird gegebenenfalls die Hardware­Uhr gele­
+            sen. 
+            Sollte der SHard ein falsches Datum liefern, so muß das Datum mit 
+                set clock (date("tt.mm.jj") + time ("hh:mm:ss")) 
+            gesetzt werden. 
+ 
+#ib#save system#ie# 
+     PROC save system 
+     Zweck: Der gesamte Systemhintergrund wird auf Archivdisketten gesichert. Zu
+            diesem Zweck wird das System wie bei 'shutup' heruntergefahren. 
+ 
+#ib#shutup#ie# 
+     PROC shutup 
+     Zweck: #ib#Kontrolliertes Herunterfahren des Systems#ie#. Beim nächsten Systemstart
+            wird automatisch Datum und Uhrzeit erfragt, wenn der Kommandodial­
+            og eingeschaltet ('command dialogue (TRUE)') und keine Hardwareuhr
+            vorhanden ist. Falls diese Prozedur nicht vor dem Abschalten aufgerufen
+            wurde, findet beim Neustart ein Aufsetzen auf dem letzten Fixpunkt statt
+            (RERUN). 
+ 
+#ib#unblock#ie# 
+     PROC unblock (TASK CONST task) 
+     Zweck: Eine vorherige Blockierung der Task wird aufgehoben. Ist die Task nicht
+            blockiert, bewirkt 'unblock' nichts. Diese Operation wird vom Scheduler
+            benutzt. Andere Tasks sollten sie normalerweise nicht anwenden, um
+            dem Scheduling nicht entgegenzuwirken. 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#5.3. #ib#ID ­ Konstanten#ie##ie(9)# 
+ 
+ 
+Die Informationsprozedur 
+ 
+     INT PROC id (INT CONST no) 
+ 
+liefert folgende Informationen über die Soft­ und Hardware des Rechners: 
+ 
+   Von EUMEL 0 werden geliefert: 
+     id (0) --> EUMEL­Version 
+     id (1) --> Prozessortyp  (1: Z80, 
+                               2: Z8001, 
+                               3: 8086 und kompatible, 
+                               4: 68000 
+                               5: 80286) 
+     id (2) --> Urlader­Version 
+     id (3) --> reserviert 
+ 
+   Vom SHard werden geliefert: 
+     id (4) --> Lizenznummer des SHards 
+     id (5) --> Installationsnummer des EUMEL­Anwenders 
+     id (6) --> SHard­spezifisch 
+     id (7) --> SHard­spezifisch 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#5.4. #ib#Systemverwaltung#ie##ie(9)# 
+ 
+ 
+#on("i")#Achtung#off("i")#: Dieser Teil des Systemhandbuchs ist nur für solche Multi-User-Installationen
+         von Bedeutung, die erweiterte Systemverwaltungsfunktionen generieren
+         bzw. modifizieren wollen. 
+ 
+         #on("i")#Das EUMEL-System ist in der ausgelieferten minimalen Standardform (ohne
+         die Features) ohne weiteres benutzbar#off("i")#. 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#Der Systemmanager #ib#SYSUR#ie##ie(9)# 
+ 
+ 
+Der Systemmanager verhält sich im wesentlichen wie ein normaler Manager, allerdings
+mit folgender Erweiterung: 
+ 
+    -  Die Operationen 'list' und 'fetch' können von allen Tasks des Systems und
+       nicht nur von Söhnen durchgeführt werden. Damit kann man Systemverwal­
+       tungsdateien (z.B. "#ib#logbuch#ie#") von allen Tasks aus lesen. 'erase' und 'save' sind
+       jedoch nur von Söhnen bzw. Enkeln - d.h. von privilegierten Systemtasks - aus
+       zulässig. 
+ 
+Das Paket stellt folgende Operationen zusätzlich zur Verfügung: 
+ 
+#ib#generate shutup manager#ie# 
+     PROC generate shutup manager 
+     Zweck: Es wird eine Sohntask mit Namen "shutup" kreiert. Diese Task ist nicht­
+             (!) paßwortgeschützt, läßt aber keine normalen Kommandos zu, son­
+            dern fragt nur 
+ 
+                     shutup (j/n) ? 
+ 
+            So kann jeder das System kontrolliert abschalten und die privilegierten
+            Operationen des OPERATORs wie 'end' sind dennoch geschützt. 
+ 
+#ib#put log#ie# 
+     PROC put log (TEXT CONST log record) 
+     Zweck: Der angegebene 'log record' wird mit vorangestelltem Tasknamen des
+            Absenders, Datums- und Uhrzeitangabe in die Logbuchdatei "logbuch"
+            in der Task "SYSUR" geschrieben. Der neue Satz wird an die Datei ange­
+            fügt. ("logbuch" wird z.B. vom EUMELmeter verwandt.) 
+ 
+     Hinweis: Bei Verwendung des Logbuchs darf die zwar große, aber doch end­
+              liche Dateikapazität nicht vergessen werden. Nachdem das Logbuch
+              mit 4073 Sätzen voll ist, werden weitere 'put log' Operationen igno­
+              riert. Die Datei "logbuch" sollte deshalb - wenn sie beispielsweise vom
+              EUMELmeter verwandt wird - von Zeit zu Zeit gelöscht werden ('erase'
+              bzw. 'forget')! 
+ 
+ 
+ 
+ 
+#ib(9)##ib#Scheduler#ie##ie(9)# 
+ 
+ 
+Der Scheduler dient zur Verwaltung der rechenwilligen #ib#Hintergrundtask#ie#s. Will man den
+Scheduler (eventuell abgeändert) insertieren, muß man die Task "scheduler" als Sohn
+von SYSUR einrichten. Dann holt man die Datei "scheduler" vom Archiv und insertiert
+sie. "scheduler" beinhaltet "#ib#eumelmeter#ie#". Es wird beim Start erfragt, ob die Meßrouti­
+nen aktiviert werden sollen oder nicht. 
+ 
+ 
+ 
+ 
+#ib##ib(9)#Funktionsweise des Schedulers#ie(9)##ie# 
+ 
+ 
+Der Scheduler sammelt in bestimmten Zeitintervallen alle aktiven (rechnenden) Tasks
+ab, die an kein Terminal angekoppelt sind und auch keine Manager sind. Diese Tasks
+werden blockiert und in die Warteschlange der #ib#Standardklasse#ie# eingefügt. 
+ 
+Die Klassen des Schedulers werden durch die #ib#Taskpriorität#ie#en 5 bis 9 definiert. Die
+Standardklasse entspricht der Priorität 7. Die Klassenzugehörigkeit einer Task kann von
+einer Systemtask aus (z.B. von "OPERATOR") mit der Prozedur '#ib#prio#ie#' verändert werden. 
+ 
+Der Scheduler geht nach folgender Strategie vor: 
+ 
+     Anhand der Vordergrund/Hintergrundlast des Systems wird entschieden, ob
+     überhaupt Hintergrundtasks aktiv sein dürfen, welche Klassen aktiv sein dürfen
+     und wieviel #ib#Hintergrundtask#ie#s gleichzeitig rechnen dürfen. 
+ 
+     Die wartenden #ib#Hintergrundtask#ie#s werden im #ib#Round-Robin-Verfahren#ie# aktiviert.
+     Dabei kommt die Klasse n+1 erst dann zum Zug, wenn die Warteschlange der
+     Klasse n leer ist oder weniger Tasks enthält, als gleichzeitig aktiviert werden
+     sollen. 
+ 
+Die implementierte Standardstrategie hat als oberste Maxime, den Vordergrund auf
+keinen Fall zu stören. Dementsprechend wird der Hintergrund nur aktiviert, wenn eine
+der folgenden Bedingungen erfüllt ist: 
+ 
+    -  Die Vordergrundlast des Systems liegt unter 3% . 
+ 
+    -  Es ist keine normale #ib#Vordergrundtask#ie# (Nachfahre von "UR") an einen Kanal
+       angekoppelt. Man beachte, daß Systemtasks hierbei nicht berücksichtigt
+       werden. Ein aktiver Drucker blockiert die Hintergrundtasks also nicht. 
+ 
+ 
+ 
+ 
+EUMELmeter (Systemstatistik) 
+ 
+ 
+Die #ib#Meßsoftware#ie# zum #ib#Protokollieren der Systembelastung#ie# befindet sich auf dem Archiv
+'std.zusatz'. 
+ 
+Falls das System keinen #ib#Scheduler#ie# benutzt, muß eine Meßtask als Sohn von "SYSUR"
+eingerichtet werden. In diese Task muß dann die Datei "#ib#eumelmeter#ie#" vom Archiv geholt
+und übersetzt werden. 
+ 
+Falls das System einen Scheduler beinhalten soll, muß bei der Generierung des Sche­
+dulers lediglich auf die Frage "mit eumelmeter (j/n) ?" mit "j" geantwortet werden. 
+ 
+ 
+ 
+#ib##ib(9)#EUMELmeter#ie(9)##ie# 
+ 
+ 
+Das EUMELmeter protokolliert die #ib#Systemlast#ie# in ca. 10 minütigen Abständen in der
+Datei "#ib#logbuch#ie#" in "SYSUR". Für jedes Meßintervall wird eine Zeile angefügt. Die Zeilen
+sind folgendermaßen aufgebaut: 
+ 
+tt.mm.jj hh:mm   hg  uf ub  pw pb  cpuf cpub cpus last nutz 
+ 
+ 
+tt.mm.jj hh:mm    Datum und Uhrzeit des Eintrags 
+ 
+hg                Größe des aktuell belegten Hintergrundspeichers 
+                  (in KB) 
+ 
+uf                Anzahl der aktiven Vordergrundtasks 
+ 
+ub                Anzahl der aktiven Hintergrundtasks 
+ 
+pw                #ib#Paginglast#ie# bei wartender CPU (#ib#Paging/Wait#ie#) 
+ 
+pb                Paginglast bei aktiver CPU (#ib#Paging/Busy#ie#) 
+ 
+cpuf              #ib#CPU-Auslastung#ie# durch Vordergrundtasks 
+ 
+cpub              CPU-Auslastung durch Hintergrundtasks 
+ 
+cpus              #ib#CPU-Systemlast#ie# 
+ 
+last              #ib#Gesamtlast des Systems#ie#: 
+                  pw + pb + cpuf + cpub+ cpus 
+                  (Achtung: kann 100% übersteigen, da Platte und CPU über­
+                  lappt arbeiten können.) 
+ 
+nutz              #ib#Nutzgüte#ie# im Meßintervall:  100% - pw - cpus 
+                  Die Nutzgüte gibt an, welcher Anteil der Systemarbeit für echte
+                  Nutzarbeit verfügbar war. Sie ist die Summe aus der echten
+                  Nutzlast 'cpuf+cpub' und der Leerzeit, die ja theoretisch auch
+                  für Nutzarbeit hätte verwandt werden können. Sie läßt sich, wie
+                  oben angegeben, auch berechnen, indem man den idealerweise
+                  überflüssigen Overhead 'cpus' und 'pw' von 100% abzieht. 
+#page# 
+ 
+#count per page# 
+#headeven# 
+%#center#EUMEL-Systemhandbuch 
+ 
+ 
+#end# 
+#headodd# 
+#center#6. Der EUMEL-Drucker#right#% 
+ 
+ 
+#end# 
+ 
+#ib(9)#6. Der #ib#EUMEL-Drucker#ie##ie(9)# 
+ 
+ 
+ 
+#ib(9)#6.1. Allgemeine Einführung#ie(9)# 
+ 
+ 
+Die Ansteuerung eines #ib#Druckers#ie# durch das EUMEL-System geschieht durch zwei
+aufeinanderbauende Komponenten. Die eine Komponete ist der hardwareunabhängi­
+ge #ib#EUMEL-Drucker#ie#, der die #ib#Textverarbeitungsanweisungen#ie# umsetzt und die Druck­
+seite entsprechend aufbereitet, so daß sie im Blocksatz, in Tabellenform oder in Spal­
+ten gedruckt werden kann. Die andere Komponente ist der hardwareabhängige #ib#Druk­
+kertreiber#ie#, der durch ein einfaches Interface zum EUMEL-Drucker, wie z.B. Textausge­
+ben, Positionieren oder Schrifttypen und Modifikationen an- und ausschalten, den
+eigentlichen Druck vornimmt. 
+Die hardwareunabhängige Komponente, der EUMEL-Drucker, befindet sich bei den
+ausgelieferten Systemen im priviligierten Ast des Taskbaums, so daß beim Anschluß
+eines Druckers nur noch der hardwareabhängige Druckertreiber insertiert werden muß.
+Auf dem PRINTER-Archiv befinden sich schon einige Druckeranpassungen für diverse
+Druckertypen. 
+ 
+-  Implementierung des Druckertreiber-Interface 
+       Das Paket mit dem Druckertreiber muß in einer Task "PRINTER" insertiert und
+       ein Spool eingerichtet werden. 
+ 
+-  Erstellen einer Fonttabelle für den anzuschießenden Drucker 
+       Eine vorhandene Fonttabelle wird dabei in die Task "configurator" gebracht
+       werden. Die Fonttabelle sollte in allen bestehenden Tasks - insbesondere in
+       der Task "PUBLIC" und der Task "PRINTER" - mit dem #on("i")##on("b")#fonttable#off("i")##off("b")#-Kommando
+       eingestellt werden. 
+ 
+ 
+ 
+ 
+#ib(9)#6.2. Das #ib#Druckertreiber-Interface#ie##ie(9)# 
+ 
+ 
+Da der EUMEL-Drucker vor dem Druckertreiber insertiert ist, aber auf dem Drucker­
+treiber aufbaut, müssen beim Aufruf der 'print'-Prozedur des EUMEL-Druckers die
+Prozeduren des Druckertreibers mit übergeben werden. Aus progammtechnischen
+Gründen sollte ihre Anzahl möglichst gering gehalten werden. Deshalb gibt es die
+folgende drei Prozeduren, die mit einem 'op code' parametrisiert werden. Die Bedeu­
+tung der weiteren Parameter der Interfaceprozeduren hängen von diesem 'op code' ab.
+Die folgende Beschreibung der Prozeduren gibt einen Programmrahmen vor, in dem
+die Parameter durch Refinements entsprechend ihrer Bedeutung umdefiniert sind. 
+ 
+ 
+ 
+PROC open (INT CONST op code, INT VAR param 1, param 2) : 
+ 
+  LET document code  =  1 , 
+      page code      =  2 ; 
+ 
+  SELECT op code OF 
+    CASE document code  :  open document 
+    CASE page code      :  open page 
+  END SELECT. 
+ 
+ 
+  x steps : param1 . 
+  y steps : param2 . 
+ 
+  #ib#open document#ie# : 
+ 
+      Zweck: Die Prozedur wird vom EUMEL-Drucker zur Einleitung jedes Ausdrucks
+             aufgerufen. Hier können notwendige Initialisierungen der Hardware
+             durchgeführt werden. In 'x steps' und 'y steps' muß die Breite bzw.
+             Höhe der bedruckbaren Fläche des Papieres in Mikroschritten des
+             Druckers angegeben werden.#u##count#)#e# 
+#foot# 
+ 
+#value#) Zur Definition der Mikroschritte siehe Bemerkung 2. 
+#end# 
+ 
+ 
+ 
+  x start : param1 . 
+  y start : param2 . 
+ 
+  #ib#open page#ie# : 
+ 
+      Zweck: Hiermit wird dem Hardware-Interface der Beginn einer neuen Seite
+             mitgeteilt. Die Parameter 'x start' und 'y start' liefern die gewünschte
+             Position der linken oberen Ecke des Schreibfeldes. Das Hardware-In­
+             terface muß in diesen Parametern seine augenblickliche Position auf
+             dem Papier zurückmelden, wobei die Position (0,0) die linke obere
+             Ecke des Papieres ist. 
+             Vor der Rückmeldung kann aber auch auf die angegebene Startpo­
+             sition positioniert und diese zurückgemeldet werden. Es ist jedoch
+             darauf zu achten, daß die zurückgemeldete Position den internen
+             Nullpunkt für die Absolutkoordinaten im EUMEL-Drucker definiert.
+             Deswegen muß das Hardware-Interface sicherstellen, daß bei einem
+             "Zeilenrücklauf" die zurückgemeldete Position 'x start' erreicht wird.
+             (Siehe 'carriage return' in der Prozedur 'execute'). Auch gibt es Fälle,
+             bei denen links von der gemeldeten 'x start'-Position positioniert wird. 
+             Bei #ib#Druckern mit Einzelblatteinzug#ie#, bei denen das Papier gleich auf die
+             zweite oder dritte Zeile positioniert wird, sollte, um ein korrektes Druck­
+             bild zu erreichen, diese Postion in 'y start' zurückgemeldet werden. 
+ 
+ 
+END PROC open; 
+ 
+ 
+PROC close (INT CONST op code, INT CONST param 1) : 
+ 
+  LET document code  =  1 , 
+      page code      =  2 ; 
+ 
+  SELECT op code OF 
+    CASE document code  :  close document 
+    CASE page code      :  close page 
+  END SELECT. 
+ 
+ 
+  #ib#close document#ie# : 
+ 
+      Zweck: Hiermit wird dem Hardware-Interface das Ende eines Druckvorgangs
+             mitgeteilt. 
+ 
+ 
+ 
+  remaining y steps : param 1 . 
+ 
+  #ib#close page#ie# : 
+ 
+      Zweck: Hiermit wird dem Hardware-Interface mitgeteilt, daß der Druck der
+             aktuellen Seite abgeschlossen ist. 
+             'remaining y steps' gibt an, wieviel Mikroschritte das vertikale Papier­
+             ende noch von der aktuellen Druckposition entfernt ist. Die x-Position
+             des Druckers ist bei Aufruf dieser Prozedur immer der linke Rand
+             'x start'. 
+ 
+ 
+END PROC close; 
+ 
+ 
+PROC execute (INT CONST op code, TEXT CONST string, 
+                                 INT  CONST param1, param2) : 
+ 
+  LET write text code       =  1 , 
+      write cmd code        =  2 , 
+      carriage return code  =  3 , 
+      move code             =  4 , 
+      draw code             =  5 , 
+      on code               =  6 , 
+      off code              =  7 , 
+      type code             =  8 ; 
+ 
+  SELECT op code OF 
+    CASE write text code       :  write text 
+    CASE write cmd code        :  write cmd 
+    CASE carriage return code  :  carriage return 
+    CASE move code             :  move 
+    CASE draw code             :  draw 
+    CASE on code               :  on 
+    CASE off code              :  off 
+    CASE type code             :  type 
+  END SELECT . 
+ 
+ 
+  from : param1 . 
+  to   : param2 . 
+ 
+  #ib#write text#ie# : 
+ 
+      Zweck: Der übergebene Text 'string' muß von der Zeichenposition 'from' bis
+             'to' (einschließlich) auf dem Drucker ausgegeben werden. Die Über­
+             schreitung der Papierbreite braucht nicht überprüft zu werden. 
+ 
+ 
+ 
+  #ib#write cmd#ie# : 
+ 
+      Zweck: Der übergebene Text 'string' enthält zwischen den Positionen 'from'
+             und 'to' ein direkt angegebenes #ib#Druckerkommando#ie# (\#"..."\#). Wenn
+             direkte Druckerkommandos erlaubt sein sollen, müssen sie ausgege­
+             ben werden. 
+ 
+ 
+ 
+  x steps to left margin : param 1 . 
+ 
+  #ib#carriage return#ie# : 
+ 
+      Zweck: Der Druckkopf muß (ohne Zeilenvorschub) an den linken Rand be­
+             wegt werden, d.h. an die bei 'open page' vom Druckertreiber gemel­
+             dete Position 'x start'. 'x steps to left margin' gibt an, wieviel Minimal­
+             schritte die augenblickliche Position vom linken Rand entfernt ist. 
+ 
+ 
+ 
+  x steps : param 1 . 
+  y steps : param 2 . 
+ 
+  #ib#move#ie# : 
+ 
+      Zweck: Die Schreibposition muß um 'x steps' Mikroschritte nach rechts und um
+             'y steps' Mikroschritte nach unten verschoben werden. Negative
+             Schrittwerte bedeuten dabei die jeweils andere Richtung. Das Über­
+             schreiten des Papiers braucht nicht überprüft zu werden. Bei einer
+             horizontalen Bewegung nach rechts ('x steps' > 0) müssen die einge­
+             schalteten Modifikationen beachtet werden. Wenn z.B. 'underline'
+             eingeschaltet ist, muß die Strecke unterstrichen werden. 
+             Kann eine Leistung (z.B. Bewegung nach links) nicht erbracht wer­
+             den, muß ein 'errorstop' ausgelöst werden. Im Fehlerfall bei einer
+             Horizontalbewegung versucht der EUMEL-Drucker nach einem Zei­
+             lenrücklauf nochmals die angestrebte x-Position zu erreichen. Somit
+             brauchen horizontale Bewegungen nach links ('x steps' < 0) nicht
+             unbedingt implementiert zu werden, sondern können mit einem 'error­
+             stop' beantwortet werden. Im Fehlerfall bei einer vertikalen Bewegung
+             wird an der alten Position weitergeschrieben. 
+ 
+ 
+ 
+  #ib#draw#ie# : 
+ Zweck: Von der aktuellen Schreibposition an (linke untere Ecke der Zeichenposition)
+             soll eine gerade Linie zum Zielpunkt ('x steps' weiter rechts, 'y steps' weiter
+             unten) gezogen werden. Kann eine Leistung (z.B. schräge Linie, Linie nach
+             oben o.ä.) nicht erbracht werden, muß ein 'errorstop' ausgelöst werden.
+             Dieser Fehlerfall wird vom EUMEL-Drucker ignoriert. Das Überschreiten
+             des Schreibfeldes braucht nicht überprüft zu werden. 
+ 
+ 
+ 
+  modification : param 1 . 
+ 
+  #ib#on#ie# : 
+ 
+      Zweck: Die #ib#Modifikation#ie# der Nummer 'modification' soll eingeschaltet wer­
+             den, sofern die Hardware es erlaubt. Augenblicklich gibt es folgende
+             Modifikationen: 
+ 
+                         1      underline 
+                         2      bold 
+                         4      italics 
+                         8      reverse 
+ 
+             Die in der Fonttabelle spezifizierte Befehlssequenz, um die entspre­
+             chende Modifikation anzuschalten, kann mit der Prozedur #on("i")#on string
+             (modification)#off("i")# abgefragt werden. 
+             Kann eine Leistung nicht erbracht werden, muß ein 'errorstop' aus­
+             gelöst werden. Im Fehlerfall der Modifikation 'underline' versucht der
+             neue EUMEL-Drucker die Zeile mit Hilfe von 'draw' zu unterstreichen.
+             Im Fehlerfall der Modifikation 'bold' wird die Zeile nochmals, um den in
+             der Fonttabelle spezifizierten 'bold offset' verschoben, ausgegeben.
+             Bei den restlichen beiden Modifkationen wird der Fehlerfall ignoriert. 
+ 
+ 
+ 
+  #ib#off#ie# : 
+ 
+      Zweck: Die angegebene #ib#Modifikation#ie# 'modification' soll ausgeschaltet wer­
+             den. Die in der Fonttabelle spezifizierte Befehlssequenz, um die ent­
+             sprechende Modifikation auszuschalten, kann mit der Prozedur #on("i")#off
+             string (modification)#off("i")# abgefragt werden. Ein Fehlerfall wird hier igno­
+             riert. 
+ 
+ 
+ 
+  font nr : param 1 . 
+ 
+  #ibie# : 
+ 
+      Zweck: Die Druckausgabe soll auf den #ib#Schrifttyp#ie# mit der angegebenen Font­
+             nummer 'font nr' umgeschaltet werden. Diese Nummer bezieht sich auf
+             die eingestellte Fonttabelle. Mit den Prozeduren des Fontspeichers
+             können anhand dieser Nummer die nötigen Informationen beschafft
+             werden. So liefert z.B. die Prozedur #on("i")#font string (font nr)#off("i")# die in der Font­
+             tabelle spezifizierte Befehlssequenz oder die Prozedur #on("i")#font (font nr)#off("i")#
+             den Namen des Fonts. Die Breite des Leerzeichens kann mit #on("i")#char pitch
+             (font nr, " ")#off("i")# bestimmt werden. 
+ 
+ 
+END PROC execute; 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#6.3. Prozedur-Schnittstelle des EUMEL- 
+     Druckers#ie(9)# 
+ 
+ 
+ 
+#ib#print#ie# 
+     PROC print  (PROC (TEXT VAR) next line, BOOL PROC eof, 
+                  PROC (INT CONST, INT VAR, INT VAR) open, 
+                  PROC (INT CONST, INT CONST) close, 
+                  PROC (INT CONST, TEXT CONST, 
+                                      INT CONST, INT CONST) execute, 
+                  BOOL CONST elan listing, TEXT CONST file name) 
+     Zweck:  Solange die Prozedur 'eof' FALSE liefert wird mit der Prozedur 'next
+             line' eine Zeile eingelesen. Dieser Eingabestrom wird für den Druck
+             aufbereitet. Ist die Konstante 'elan listing' auf FALSE gesetzt, so wird
+             der Eingabestrom als Textdatei mit Textkosmetik-Anweisungen aus­
+             gedruckt. Andernfalls wird der Eingabestrom wie ein ELAN-Listing
+             behandelt. In der Textkonstanten 'file name' muß dann der Dateiname
+             der Programmdatei enthalten sein. 
+ 
+ 
+      PROC print (FILE VAR 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) 
+      Zweck: Der Eingabestrom kommt aus der angegebenen Datei. Anhand vorge­
+             gebener Kriterien wird entschieden, ob diese Datei als Textdatei oder
+             als ELAN-Listing ausgedruckt wird. 
+ 
+#ib#with elan listings#ie# 
+      PROC with elan listings (BOOL CONST flag) 
+      Zweck: Mit dieser Prozedur kann bei der vorangegangenen 'print'-Prozedur
+             gesteuert werden, ob überhaupt irgendwelche Dateien als ELAN-Lis­
+             tings gedruckt werden sollen. Wird damit FALSE eingestellt, so wer­
+             den alle Dateien als Textdateien gedruckt. 
+ 
+     BOOL PROC with elan listings 
+     Zweck:  Liefert die aktuelle Einstellung. 
+ 
+ 
+#ib#is elan source#ie# 
+     PROC is elan source (FILE VAR file) 
+     Zweck:  Entscheidet nach vorgebenen Kriterien, ob die angegebene Datei ein
+             ELAN-Listing ist. 
+ 
+ 
+#ib#bottom label for elan listings#ie# 
+     PROC bottom label for elan listings (TEXT CONST label) 
+     Zweck:  Bei ELAN-Listings wird in der Fußzeile ein Text eingestellt, der durch
+             Schägstrich getrennt vor die Seitennummer geschrieben wird. (z.B. zur
+             Durchnumerierung der Pakete im Quellcode) 
+ 
+     TEXT PROC bottom label for elan listings 
+     Zweck:  Liefert die aktuelle Einstellung. 
+ 
+ 
+#ib#material#ie# 
+     TEXT PROC material 
+     Zweck:  Hier kann das Hardware-Interface jeder Zeit den aktuellen Material­
+             wert abfragen, der vom Benutzer mit der 'material'-Anweisung einge­
+             stellt ist. 
+ 
+ 
+#ib#x pos#ie# 
+     INT PROC x pos 
+     Zweck:  Wird in der Prozedur 'execute' die Funktion 'move' oder 'draw' ange­
+             steuert, so liefert diese Prozedur die absolute Zielposition in x-Rich­
+             tung, wo bei der Nullpunkt durch das zurückgelieferte 'x start' bei 'open
+             page' definiert ist. Diese Prozedur dient zur Unterstützung von Druk­
+             kern, die eine absolute Positionierung in horizontaler Richtung benöti­
+             gen. 
+ 
+ 
+#ib#y pos#ie# 
+     INT PROC y pos 
+     Zweck:  Wird in der Prozedur 'execute' die Funktion 'move' oder 'draw' an­
+             gesteuert, so liefert diese Prozedur die absolute Zielposition in y-Rich­
+             tung, wo bei der Nullpunkt durch das zurückgelieferte 'y start' bei 'open
+             page' definiert ist. Diese Prozedur dient zur Unterstützung von Druk­
+             kern, die eine absolute Positionierung in vertikaler Richtung benötigen. 
+ 
+ 
+#ibie# 
+     INT PROC linetype 
+     Zweck:  Wird in der Prozedur 'execute' die Funktion 'draw' angesteuert, so gibt
+             diese Prozedur den gewünschten Linientyp an. Bisher ist nur definiert: 
+                         1      underline 
+ 
+     Anmerkung:  Bis jetzt benutzt der EUMEL-Druckers die Funktion 'draw' lediglich
+                 zum Unterstreichen in Fehlerfall der Modifikation 'underline', d.h.
+                 zeichnen mit 'y steps = 0' und 'x steps >= 0' mit 'line type = 1'
+                 reicht aus. 
+ 
+ 
+#ib#y offset index#ie# 
+     INT PROC y offset index 
+     Zweck:  Wurde der Font mit 'y offsets' definiert, so kann hiermit in der bei der
+             Funktion 'write text' in der Prozedur 'execute' der jeweilige Offset-In­
+             dex für den auszugebenden Text abgefragt werden. Der Offset-Index
+             sagt aus, die wievielte Verschiebung nun ausgegeben wird. Dabei
+             werden die Verschiebungen in der Reihenfolge durchnummeriert, in
+             der sie in der Fonttabelle angegeben wurden. Anhand dieses Offset-In­
+             dex muß das Hardware-Interface entscheiden, welche Bitmuster aus­
+             gegeben werden müssen. 
+ 
+ 
+#ib#pages printed#ie# 
+     INT PROC pages printed 
+     Zweck:  Gibt nach dem Ausdruck an, wieviel Seiten gedruckt wurden. 
+ 
+ 
+ 
+ 
+#ib(9)#6.4. Bemerkungen und Ratschläge#ie(9)# 
+ 
+ 
+ 
+1) Für ein Paket, das dieses Interface implementiert, sind folgende Punkte wichtig: 
+ 
+    -  Man braucht sich keine Zustände (aktuelle Position o.ä.) zu merken. 
+ 
+    -  Rückmeldungen über die Leistungsfähigkeit eines Druckers bzw. seiner An­
+       passung erfolgen über 'errorstop'. Der #ib#EUMEL-Drucker#ie# stellt fest, ob bestimm­
+       te Leistungen (Einschalten der Attribute und Bewegungen des Druckers)
+       verfügbar sind, indem er sie versuchsweise ausführen läßt. Bei den Prozedu­
+       ren 'open', 'close' und den Funktionen 'write text', 'write cmd', 'carriage return'
+       und 'type' der Prozedur 'execute' führt ein 'errorstop' jedoch zum Abbruch des
+       Drucks. 
+ 
+2) Die #on("i")##on("b")##ib#Mikroschritte#ie##off("i")##off("b")# sollten die kleinsten durchführbaren horizontalen bzw. vertikalen
+   Bewegungen des Druckers sein. Oft gibt aber das Handbuch des Druckers keine
+   eindeutige Angabe über die Mikroschritte in horizontaler Richtung, sondern sagt
+   nur, daß es gewisse Schriften mit einer bestimmten Anzahl von Zeichen pro Zoll
+   gibt.#u##count#)#e# Dann ergibt sich die Anzahl von Mikroschritten pro Zoll aus dem kleinsten#foot#
+    
+#value#) 1 Zoll = 1 Inch = 2.54 cm 
+ 
+#end# 
+   gemeinsamen Vielfachen der Anzahl Zeichen pro Zoll aller Schriften. 
+ 
+   Beispiel: 
+      Der Olivetti Drucker PR1470 hat drei Schriften mit 10, 12, und 16.6 Zeichen pro
+      Zoll. Das kleinste gemeinsame Vielfache ist 300. Ein Mikroschritt bei dem Druk­
+      ker PR1470 entspricht also einem 300stel Zoll. Die Breite der einzelnen Schrif­
+      ten läßt sich nun aus der folgenden Tabelle ablesen. 
+ 
+       Anzahl Zeichen pro Zoll           Breite in 1/300 Zoll 
+                10                            30 
+                12                            25 
+               16.6                           18 
+ 
+   Wenn der Drucker in diesen theoretischen Mikroschritten nicht positionieren kann,
+   so muß er bei einem #on("i")#move#off("i")#-Befehl so genau wie möglich positionieren. Der Rest
+   sollte abgespeichert und beim nächsten #on("i")#move#off("i")#-Befehl hinzuaddiert werden. 
+ 
+3) Um ein optimales Druckbild zu bekommen, müssen alle Breiten und Höhenanga­
+   ben der Zeichen genau angegeben werden. 
+ 
+4) Die Fonttabelle bietet eine einfache Möglichkeit, Zeichen mit Hilfe der #ib#Ersatzdar­
+   stellung#ie#en umzucodieren. Deshalb sollte der Druckerkanal auch mit der Konfigu­
+   rationstabelle 'transparent' konfiguriert werden. 
+ 
+5) Um den Schrifttyp festzulegen, mit dem #ib#ELAN-Listing#ie#s gedruckt werden sollen,
+   kann in der Fonttabelle einem Font der Name #on("i")##on("b")#"#ib#elanlist#ie#"#off("i")##off("b")# zugeordnet werden, denn
+   der ELAN-Lister versucht auf einen Schrifttyp mit diesem Namen zuschalten. Wenn
+   kein Schrifttyp "elanlist" existiert, dann wird für ELAN-Listings der erste Schrifttyp
+   der Fonttabelle genommen. 
+ 
+6) Nach der Installation des #ib#Druckertreiber#ie#s ist darauf zu achten, daß in der Task
+   "PRINTER" eine Fonttabelle des Druckers eingestellt ist. 
+ 
+7) Der #ib#Druckertreiber#ie# sollte eventuell noch ein Prozedur bereitstellen, mit der die
+   Papierbreite bzw. -höhe eingestellt werden kann, die bei 'open document' dem
+   EUMEL-Drucker gemeldet wird. 
+ 
+ 
+ 
+ 
+#ib(9)#6.5. Arbeitsweise des EUMEL-Druckers#ie(9)# 
+ 
+ 
+ 
+Der EUMEL-Drucker arbeitet mit der folgenden Strategie: 
+ 
+Die Datei wird zeilenweise analysiert. Bei der Analyse werden einzelne #ib#Token#ie# be­
+stimmt. Ein Token ist ein Textteil, der zusammenhängend gedruckt werden kann, ohne
+daß es zu Typumschaltungen, Modifkationsänderungen oder Positionierungen in x-
+bzw. y-Richtung kommt. So ist bei einfachem Zeilendruck jede Zeile ein Token, wäh­
+rend im Blocksatz jedes Wort ein Token ist. Ein Token hat also immer 
+ 
+  -  einen Text, 
+  -  die Länge des Textes bei der Ausgabe, 
+  -  eine absolute x- und y- Position auf dem Papier, 
+  -  einen Schrifttyp, 
+  -  Modifikationen für den Text, 
+  -  Modifikationen für den Zwischenraum vom letzten Token zu diesem Token. 
+ 
+Sind alle Token einer Zeile bestimmt, so werden sie in eine Liste aller bisher erzeug­
+ten, aber noch nicht gedruckten Token der absoluten y-Position nach einsortiert. Diese
+Tokenliste wird erst dann ausgedruckt, wenn sichergestellt ist, daß im weiteren Verlauf
+der Datei kein Token vor das letzte Token der sortierten Liste kommt. Beim Zeilendruck
+ist dies nach jeder Zeile der Fall. Bei Spaltendruck kann jedoch erst dann ausgedruckt
+werden, wenn sich die Analyse in der letzten Spalte befindet. Spätestens bei einem
+Seitenwechsel muß die Tokenliste ausgegeben werden. 
+ 
+Durch diese Strategie lassen sich Spaltendruck oder Indizes und Exponenten sehr
+leicht für alle Drucker implementieren, ohne daß ein Drucker in vertikaler Richtung
+rückwärts positionieren muß. 
+ 
+Bei der Ausgabe der Tokenliste wird jeweils auf die nächst größere y-Position posi­
+tioniert und dort werden alle Token zu dieser y-Position ausgegeben. Die Ausgabe
+eines Tokens erfolgt in der folgenden Reihenfolge: 
+ 
+  -  der Schrifttyp wird eingeschaltet, 
+  -  die Modifikationen für den Zwischenraum werden eingeschaltet, 
+  -  der Positionsbefehl für horizontale Bewegungen wird gegeben, 
+  -  die Modifikationen für den Text werden eingeschaltet, 
+  -  der Text wird ausgegeben. 
+ 
+Die ersten vier Punkte werden nur dann ausgeführt, wenn sie notwendig sind. Über­
+schreitet der Text die Papierbreite, so zeigen Punkte am Ende der Zeile dies an.
+
diff --git a/doc/system/systemhandbuch.4 b/doc/system/systemhandbuch.4
new file mode 100644
index 0000000..e511eb5
--- /dev/null
+++ b/doc/system/systemhandbuch.4
@@ -0,0 +1,1185 @@
+#start(2.5,1.5)# 
+#pageblock# 
+#block# 
+#page (91)# 
+#headeven# 
+%#center#EUMEL-Systemhandbuch 
+ 
+ 
+#end# 
+#headodd# 
+#center#7. Der Fontspeicher#right#% 
+ 
+ 
+#end# 
+ 
+#ib(9)#7. Der #ib#Fontspeicher#ie##ie(9)# 
+ 
+ 
+ 
+#ib(9)#7.1. #ib#Fonttabellen#ie##ie(9)# 
+ 
+ 
+Damit die Textverarbeitung Dokumente formatieren kann, muß sie über Breiten und
+Höhen der einzelnen Schrifttypen (auch "#ib#Fonts#ie#" genannt) des Druckers, auf dem das
+Dokument gedruckt wird, Bescheid wissen. Auch bei dem Ausdruck des Dokuments
+wird diese Information benötigt. Im EUMEL-System stellt der #ib#Fontspeicher#ie# diese Infor­
+mation den #ib#Formatierprogramm#ie#en (#on("i")#lineform#off("i")# und #on("i")#pageform#off("i")#) und dem #ib#EUMEL-Drucker#ie#
+zur Verfügung. 
+ 
+Da nun der Drucker Angaben zur Positionierung in seinen #ib#Mikroschritten#ie# (kleinste
+Schrittweite in horizontaler oder vertikalter Richtung) benötigt, liefert die Fonttabelle
+die Breiten- und Höhenangaben in Mikroschritten und eine Umrechnungseinheit von
+Schritten in Zentimeter oder umgekehrt. So braucht der EUMEL-Drucker bei Positionie­
+rungen keine Umrechnung vorzunehmen. Allerdings müssen die Formatierprogramme
+auch in Mikroschritten des jeweiligen Druckers rechnen. Dadurch werden jedoch
+Unterschiede durch Rundungsfehler zwischen dem EUMEL-Drucker und den Forma­
+tierprogrammen vermieden. 
+ 
+Bei diesem Konzept können Fonts von verschiedenen Druckern nicht in einer Fontta­
+belle verwaltet werden, denn unterschiedliche Drucker haben meist verschiedene
+Mikroschritte. Somit muß es für jeden Drucker mindestens eine Fonttabelle geben. 
+ 
+Es gibt aber auch Fälle, in denen Fonts auf einem Drucker nicht mit anderen Fonts des
+Druckers zusammengedruckt werden können. Solche Fälle liegen z.B. bei Typenrad­
+druckern vor, die immer nur mit einem Typenrad drucken können und dessen Zei­
+chenbreite hardwaremäßig eingestellt werden muß (z.B. beim Olivetti PR320), bei
+Druckern, die verschiedene Fonts für Längs- und Querformat haben (z.B. beim Agfa
+P400), oder bei Druckern, deren Fonts geladen werden (z.B. beim HP 2686). Eine
+#on("b")##ib#Fonttabelle#ie##off("b")# enthält also alle die Fonts eines Druckers, #on("b")#die auf dem Drucker kompati­
+bel sind#off("b")#. Es kann mehrere Fonttabellen zu einem Drucker geben. 
+ 
+Die verschiedenen Fonttabellen werden von im Multi-User Betrieb von der Task "#ib#confi­
+gurator#ie#" verwaltet. Sie enthält alle Fonttabellen, die auf dem Rechner zur Verfügung
+stehen. Mit dem Kommando 
+ 
+ 
+  #ib#fonttable#ie# ("Name der Fonttabelle") 
+ 
+ 
+wird in einer Task die gewünschte Fonttabelle eingestellt. Danach stehen die Fonts
+dieser Tabelle in der Task zur Verfügung. Die Einstellung der Fonttabelle vererbt sich
+auf die Sohntasks, d.h. wird eine Sohntask begonnen, so ist dort die Fonttabelle des
+Vaters eingestellt. 
+ 
+Dazu das folgenden Beispiel: 
+ 
+    Für den Agfa-Drucker P400 gibt es die Fonttabellen "agfa" und "agfaquer", in
+    denen die Fonts für Längsdruck bzw. Querdruck enthalten sind. In der Task
+    #on("i")#PUBLIC#off("i")# wird mit dem Kommando #on("i")#fonttable ("agfa")#off("i")# die Fonttabelle "agfa" ein­
+    gestellt. Alle neuen Sohntasks können sofort ohne weitere Einstellung mit der
+    Textformatierung im Längsformat beginnen. Will nun jemand im Querformat
+    drucken, so muß er in seiner Task mit dem Kommando #on("i")#fonttable ("agfaquer")#off("i")# den
+    Fontspeicher auf die Fonts zum Querdruck umstellen. 
+ 
+Das Kommando 
+ 
+ 
+  #ib#list fonts#ie# 
+ 
+ 
+listet die Fonts der eingestellten Fontabelle ins #on("i")#notebook#off("i")# und das Kommando 
+ 
+ 
+  #ib#list fonttables#ie# 
+ 
+ 
+informiert über die verfügbaren Fonttabellen. 
+ 
+ 
+ 
+ 
+#ib(9)#7.2. Erstellen einer #ib#Fonttabelle#ie##ie(9)# 
+ 
+ 
+Die Fonttabelle ist ein Datenraum mit einer eigenen Struktur. Somit kann sie nicht
+mehr mit dem Editor, sondern nur mit einem entsprechenden Programm bearbeitet
+werden. Solch ein Programm befindet sich in der Datei "#ib#font convertor#ie#" auf dem Stan­
+dardarchiv 'std.zusatz'. Diese Datei sollte in einer Systemtask (Sohntask von "SYSUR")
+insertiert werden. Danach stehen entsprechende Kommandos zur Bearbeitung einer
+Fonttabelle zur Verfügung. 
+ 
+Um eine Fonttabelle zu bekommen, muß zuerst eine #on("b")##ib#Fontdatei#ie##off("b")# (d.h. eine editierbare
+Datei mit dem unten beschriebenen Aufbau) angelegt werden. Mit dem Kommando 
+ 
+ 
+  #ib#create fonttable#ie# ("Name der Fontdatei") 
+ 
+ 
+werden alle in der Fontdatei spezifizierten Fonttabellen erstellt. Sie liegen als benannte
+Datenräume in der Task vor und können mit dem Kommando #on("i")#save#off("i")# von einer System­
+task an die Task "configurator" gesendet werden. Danach sind diese Fonttabellen in
+allen Task auf dem Rechner verfügbar und können mit dem #on("i")#fonttable#off("i")# - Kommando
+eingestellt werden. 
+ 
+Soll dagegen eine bestehende Fonttabelle geändert werden, so erstellt das Komman­
+do 
+ 
+ 
+  #ib#create fontfile#ie# ("Name der Fonttabelle", "Name der Fontdatei") 
+ 
+ 
+aus der angegebenen Fonttabelle eine Fontdatei. Die Fonttabelle muß dazu in der Task
+als benannter Datenraum vorliegen (d.h. sie muß eventuell mit #on("i")#fetch#off("i")# von der Task
+"configurator" geholt werden). In der so erstellten Fontdatei können die Änderungen
+mit dem Editor vorgenommen, mit #on("i")#create fonttable#off("i")# die geänderte Fonttabelle erstellt
+und diese wiederum mit #on("i")#save#off("i")# an die Task "configurator" gesendet werden. Mit dem
+#on("i")#fonttable#off("i")#-Kommando kann dann in den bestehenden Tasks die geänderte Fonttabelle
+eingestellt werden. Alle neuen Tasks erhalten automatisch die geänderte Fonttabelle. 
+ 
+ 
+ 
+#ib(9)#Prozedurbeschreibung der Umwand­ 
+lungs­Kommandos#ie(9)# 
+ 
+ 
+Nach der Insertierung der Datei "font convertor" stehen die folgenden Kommandos zur
+Umwandlung einer Fontdatei in eine Fonttabelle oder umgekehrt zur Verfügung. 
+ 
+#ib#create fontfile#ie# 
+     PROC create fontfile (TEXT CONST fonttable name, fontfile name) 
+     Zweck:  Aus Fonttabelle 'fonttable name' wird eine Fontdatei mit dem ange­
+             gebenen Name erstellt. Die Fonttabelle muß dabei in der eigenen Task
+             als benannter Datenraum vorliegen. 
+ 
+#ib#create fonttable#ie# 
+     PROC create fonttable (TEXT CONST fontfile name) 
+     Zweck:  Es werden alle Fonttabellen erzeugt, die in der Fontdatei 'fontfile name'
+             angegeben sind. Die Fonttabellen liegen dann als benannte Datenräu­
+             me in der Task vor. 
+ 
+     PROC create fonttable 
+     Zweck:  Es werden alle Fonttabellen erzeugt, die in der zuletzt bearbeiteten
+             Datei angegeben sind. 
+ 
+ 
+ 
+ 
+#ib(9)#7.3. Aufbau der #ib#Fontdatei#ie##ie(9)# 
+ 
+ 
+In der Fontdatei können drei Strukturen stehen und zwar Kennungen, Identifkationen
+und Zeichenspezifikationen.#u##count#)#e# 
+#foot# 
+ 
+#value#) Beim formalen Aufbau bedeuten eckige Klammern, daß diese Angaben optional sind. 
+ 
+#end# 
+ 
+ 
+ 
+#ib(9)##ib#Kennungen#ie##ie(9)# 
+ 
+ 
+    Formaler Aufbau:  <#on("i")#Kennung#off("i")#>  :  Name 1  [,  Name 2]  [ ... ] ; 
+ 
+    Eine Kennung leitet eine Definition ein. Für die Namen der Namensliste gelten die
+    folgenden Konventionen: 
+ 
+     -  der Name muß als TEXT-Denoter angegeben werden, 
+     -  der Name muß ungleich #on("i")#niltext#off("i")# sein, 
+     -  Leerzeichen sind im Namen nicht signifikant (d.h. "agfa quer" wird zu "agfa­
+        quer"). 
+ 
+    Eine Kennung kann die folgenden Werte annehmen: 
+ 
+    <#on("i")#Kennung#off("i")#>       { FONTTABLE, FONT } 
+ 
+    - #on("b")##ib#FONTTABLE#ie##off("b")# 
+        Hiermit wird eine Definition einer Fonttabelle eingeleitet. Es wird nur der erste
+        Name der Namensliste ausgewertet, da die Fonttabelle eindeutig identifiziert
+        sein muß. Alle folgenden Angaben werden dieser Fonttabelle zugeordnet, bis
+        eine neue Kennung FONTTABLE folgt. 
+ 
+    - #on("b")##ib#FONT#ie##off("b")# 
+        Hiermit wird eine Definition eines Schrifttyps eingeleitet. Ein Schrifttyp kann
+        mehrere Namen haben. Jedoch darf in einer Fonttabelle jeder Fontname nur
+        einem Font zugeordnet werden. 
+ 
+ 
+ 
+#ib(9)##ib#Identifikation#ie#en#ie(9)# 
+ 
+ 
+    Formaler Aufbau: [ <#on("i")#Identifikation#off("i")#>  =  <Wert der Identifikation> ; ] 
+ 
+    Mit den Identifikationen werden bestimmte Angaben zu den Kennungen gemacht.
+    Sie müssen unmittelbar nach der entsprechenden Kennung folgen, brauchen aber
+    nur angegeben werden, wenn sie von den Standardwerten abweichen. 
+ 
+ 
+ 
+#ib(9)#Identifikationen nach der Kennung #ib#FONTTABLE#ie##ie(9)# 
+ 
+ 
+    <#on("i")#Identifikation#off("i")#>       { x unit, y unit, on string, off string } 
+ 
+    - #on("b")##ib#x unit#ie##off("b")# 
+        Hiermit wird die Anzahl der Mikroschritte des Druckers pro Zentimeter in
+        horizontaler (x-) Richtung spezifiziert. Die Einheit muß als REAL-Denoter
+        angegeben werden. Alle weiteren Breitenangaben zu den Fonts dieses Druk­
+        kers beziehen sich auf diese Einheit. 
+ 
+        STD-Wert:    10.0 / 2.54  =  3.937008 
+ 
+    - #on("b")##ib#y unit#ie##off("b")# 
+        Hiermit wird die Anzahl der Mikroschritte des Druckers pro Zentimeter in
+        vertikaler (y-) Richtung spezifiziert. Die Einheit muß als REAL-Denoter ange­
+        geben werden. Alle weiteren Höhenangaben zu den Fonts dieses Druckers
+        beziehen sich auf diese Einheit. 
+ 
+        STD-Wert:     6.0 / 2.54  =  2.362205 
+ 
+    - #on("b")##ib#on string#ie##off("b")# 
+        Hier müssen vier Textdenoter, durch Komma getrennt, angegeben werden.
+        Die Textdenoter enthalten die Befehlssequenzen, um beim Drucker die Mo­
+        difikationen anzuschalten. Dabei ist die Reihenfolge der Modifikationen 
+            underline,   bold,   italics,   reverse. 
+        Liegt für eine der Modifikationen keine Befehlssequenz vor, so muß #on("i")#niltext#off("i")#
+        angegeben werden. Die Befehlssequenzen können vom Druckertreiber ab­
+        gefragt werden. 
+ 
+        STD-Wert:    #on("i")#niltext#off("i")# für alle Modifikationen 
+ 
+    - #on("b")##ib#off string#ie##off("b")# 
+        Hier müssen vier Textdenoter, durch Komma getrennt, angegeben werden.
+        Die Textdenoter enthalten die Befehlssequenzen, um beim Drucker die Mo­
+        difikationen auszuschalten. Dabei ist die Reihenfolge der Modifikationen 
+            underline,   bold,   italics,   reverse. 
+        Liegt für eine der Modifikationen keine Befehlssequenz vor, so muß #on("i")#niltext#off("i")#
+        angegeben werden. Die Befehlssequenzen können vom Druckertreiber ab­
+        gefragt werden. 
+ 
+        STD-Wert:    #on("i")#niltext#off("i")# für alle Modifikationen 
+ 
+ 
+ 
+#ib(9)#Identifikationen nach der Kennung #ib#FONT#ie##ie(9)# 
+ 
+ 
+    <#on("i")#Identifikation#off("i")#>       {  font lead, font height, font depth, indentation pitch, 
+                               next larger font, next smaller font, 
+                               font string, y offsets, bold offset   } 
+ 
+    - #on("b")##ib#font lead#ie##off("b")##u##count#)#e# 
+        Der Durchschuß eines Fonts gibt den Zwischenraum in vertikaler Richtung
+        zwischen den Zeilen bei einfachem Zeilenvorschub an. Er muß in Mikroschrit­
+        ten der y-Richtung als INT-Denoter angegeben werden. 
+ 
+        STD-Wert:    0 
+#foot# 
+ 
+#value#) Für spätere Erweiterungen des EUMEL-Druckers wurde die bisherige Fonthöhe in Durchschuß, Fonthöhe
+   und Fonttiefe aufgespalten. Für alle bis jetzt definierten Leistungen braucht nur wie bisher die Fonthöhe
+   angegeben zu werden. Der Durchschuß und die Fonttiefe werden dann auf Null gesetzt. 
+#end# 
+ 
+    - #on("b")##ib#font height#ie##off("b")##u##value#)#e# 
+        Die Fonthöhe ist die Distanz von der Basislinie bis zur Oberkante des höch­
+        sten Zeichens. Sie muß in Mikroschritten der y-Richtung als INT-Denoter
+        angegeben werden. 
+ 
+        STD-Wert:    6 Zeilen pro Inch entsprechend der definierten #on("i")#y unit#off("i")# 
+ 
+    - #on("b")##ib#font depth#ie##off("b")##u##value#)#e# 
+        Die Fonttiefe ist die Distanz von der Basislinie bis zur Unterkante des tief­
+        sten Zeichens. Sie muß in Mikroschritten der y-Richtung als INT-Denoter
+        angegeben werden. 
+ 
+        STD-Wert:    0 
+ 
+    - #on("b")##ib#indentation pitch#ie##off("b")# 
+        Einrückungen oder Aufzählungen werden äquidistant berechnet, d.h. Anzahl
+        der Zeichen mal einer festen Breite. Diese Einrückbreite sollte ein Mittel al­
+        ler Zeichenbreiten sein und braucht nicht der Breite des Leerzeichens zu
+        entsprechen. Sie muß in Mikroschritten der x-Richtung als INT-Denoter an­
+        gegeben werden. 
+ 
+        STD-Wert:    10 Zeichen pro Inch entsprechend der definierten #on("i")#x unit#off("i")# 
+ 
+    - #on("b")##ib#next larger font#ie##off("b")# 
+        Hier muß der Name des nächst größeren Fonts als TEXT-Denoter aufgeführt
+        werden. Gibt es keinen nächst größeren Font, so ist #on("i")#niltext#off("i")# anzugeben. 
+ 
+        STD-Wert:    #on("i")#niltext#off("i")# 
+ 
+    - #on("b")##ib#next smaller font#ie##off("b")# 
+        Hier muß der Name des nächst kleineren Fonts als TEXT-Denoter aufge­
+        führt werden. Gibt es keinen nächst kleineren Font, so ist #on("i")#niltext#off("i")# anzugeben.
+        Bei Indizes oder Exponenten wird automatisch auf diesen nächst kleineren
+        Font umgeschaltet. 
+ 
+        STD-Wert:    #on("i")#niltext#off("i")# 
+ 
+ 
+    - #on("b")##ib#font string#ie##off("b")# 
+        Hier kann als TEXT-Denoter eine Befehlssequenz angegeben werden, die
+        den Drucker auf diesen Font umschaltet. Diese Befehlssequenz kann vom
+        Druckertreiber abgefragt werden. Dadurch ist es nicht nötig, daß er die Na­
+        men der Fonts kennt. 
+ 
+        STD-Wert:    #on("i")#niltext#off("i")# 
+ 
+    - #on("b")##ib#y offsets#ie##off("b")# 
+        Um bei Matrixdruckern Schriften zu erzeugen, die höher als eine Nadelreihe
+        sind, müssen entsprechende Bitmuster des Textes an verschiedenen y-Po­
+        sitionen ausgegeben werden. Um diese Anforderung durch den EUMEL-
+        Drucker zu unterstützen, kann hier eine Liste von Verschiebungen von der
+        Basislinie angegeben werden, an denen der Text ein weiteres Mal ausgege­
+        ben wird. Dabei bedeuten negative Werte eine Verschiebung oberhalb und
+        positive Werte eine Verschiebung unterhalb der Basislinie. Ist der Wert Null,
+        so wird der Text auf der Basislinie ausgegeben. Die Modifikation #on("i")#underline#off("i")#
+        wird bei der Ausgabe des Textes nur an der ersten Verschiebung angestellt.
+        Die Werte für die Verschiebungen müssen in Mikroschritten der y-Richtung
+        als INT-Denoter angegeben und durch Komma getrennt werden. 
+ 
+        STD-Wert:    0 
+ 
+    - #on("b")##ib#bold offset#ie##off("b")# 
+        Falls der Drucker die Modifikation #on("i")#bold#off("i")# nicht beherrscht, versucht der
+        EUMEL-Drucker sie durch Doppeldruck zu simulieren. Der 'bold offset' gibt
+        an, ob und wieviel der zweite Durchgang in x-Richtung verschoben werden
+        soll. Dies ergibt insbesondere bei Laserdruckern, die nicht für alle Schriftty­
+        pen einen Bold-Typ haben, einen recht guten Fettdruck. Der Wert muß in
+        Mikroschritten der x-Richtung als INT-Denoter angegeben werden. 
+ 
+        STD-Wert:    0 
+ 
+ 
+ 
+#ib(9)##ib#Zeichenspezifikationen#ie##ie(9)# 
+ 
+ 
+ 
+   Formaler Aufbau:   [ <Zeichen>  [,  <Breite des Zeichens>] 
+                                   [,  <Ersatzdarstellung des Zeichens>] ; ] 
+ 
+ 
+   Nachdem die Identifikationen zu einer Kennung angegeben wurden, können Zei­
+   chenspezifikationen folgen, d.h. zu einem Zeichen kann die Breite und/oder eine
+   Ersatzdarstellung spezifiziert werden. Dazu muß zuerst das Zeichen selber als
+   TEXT-Denoter angegeben werden. 
+ 
+   - #on("b")##ib#Breite des Zeichens#ie##off("b")# 
+       Die Zeichenbreite muß als INT-Denoter in Mikroschritten angegeben werden.
+       Alle Zeichenbreiten werden mit der Einrückbreite vorbesetzt, so daß nur sol­
+       che Zeichen angegeben werden müssen, deren Breite von der Einrückbreite
+       abweichen. Negative Zeichenbreiten sind nicht erlaubt. Die Angabe von Zei­
+       chenbreiten nach der Kennung FONTTABLE wird ignoriert. 
+ 
+   - #on("b")##ib#Ersatzdarstellung des Zeichens#ie##off("b")# 
+       Die Ersatzdarstellung wird statt des Zeichens ausgedruckt. Sie muß als
+       TEXT-Denoter angegeben werden. Werden Ersatzdarstellungen nach der
+       Kennung FONTTABLE angegeben, so gelten sie global für alle Fonts dieser
+       Fonttabelle. Sie können jedoch bei der Fontangabe lokal wieder überschrie­
+       ben werden. Eine Ersatzdarstellung darf höchsten 255 Zeichen lang sein. Alle
+       Ersatzdarstellungen eines Fonts dürfen 32767 Zeichen nicht überschreiten. 
+ 
+ 
+ 
+#ib(9)##ib#Kommentare in der Fontdatei#ie##ie(9)# 
+ 
+ 
+   In der Fontdatei dürfen Kommentare eingefügt werden. Sie müssen den Kommen­
+   taren der ELAN-Syntax entsprechen, d.h. mit '(*' beginnen und mit '*)' enden. 
+ 
+ 
+ 
+#ib(9)##ib#Deutsche Namen#ie##ie(9)# 
+ 
+ 
+   Kennungen und Identifikationen dürfen in der Fontdatei auch mit folgenden deut­
+   schen Namen angegeben werden. 
+ 
+       FONTABLE            :   FONTABELLE 
+       FONT                :   FONT 
+ 
+#free (0.15)# 
+       x unit              :   x einheit 
+       y unit              :   y einheit 
+       on string           :   on sequenz 
+       off string          :   off sequenz 
+       indentation pitch   :   einrueckbreite 
+       font lead           :   durchschuss 
+       font height         :   fonthoehe 
+       font depth          :   fonttiefe 
+       next larger font    :   groesserer font 
+       next smaller font   :   kleinerer font 
+       font string         :   font sequenz 
+       y offsets           :   y verschiebungen 
+       bold offset         :   bold verschiebung 
+ 
+ 
+ 
+ 
+#ib(9)#7.4. Beispiel für eine Fontdatei#ie(9)# 
+ 
+ 
+In diesem Beispiel einer Fonttdatei sind drei Fonttabellen enthalten, nämlich "agfa" und
+"agfaquer" für den Agfa-Drucker und "epson" für einen Epson-Drucker. 
+ 
+ 
+FONTTABLE  :  "agfa" ; 
+  x unit      =  160.0 ;                 #right#(* Anzahl der Mikroschritte pro cm *) 
+  y unit      =  160.0 ; 
+  on string   =  "\UL1;",  "\BO1;",  "\IT1;",  "\CFW;\CBB;" ; 
+  off string  =  "\UL0;",  "\BO0;",  "\IT0;",  "\CFT;\CBT;" ; 
+ 
+#right#(* globale Ersatzdarstellungen für alle Agfa-Fonts *) 
+ 
+  ""214"" ,   "\!298;" ;                       #right#(* AE *) 
+  ""215"" ,   "\!299;" ;                       #right#(* OE *) 
+  ""216"" ,   "\!300;" ;                       #right#(* UE *) 
+  ""217"" ,   "\!451;" ;                       #right#(* ae *) 
+  ""218"" ,   "\!452;" ;                       #right#(* oe *) 
+  ""219"" ,   "\!453;" ;                       #right#(* ue *) 
+  . 
+  . 
+  . 
+ 
+  FONT  :  "trium10" ; 
+    indentation pitch   =  30 ; 
+    font lead           =  7 ; 
+    font heigth         =  54 ; 
+    font depth          =  15 ; 
+    next larger font    =  "trium12" ; 
+    next smaller font   =  "helvetica8" ; 
+    font string         =  "\FO5;" ; 
+ 
+    " "     ,    20 ;           "!"  ,      16 ; 
+    """"    ,    22 ;           "\#"  ,      31 ; 
+    "$"     ,    31 ;           "%"  ,      55 ; 
+    . 
+    . 
+    . 
+    ""217"" ,    31 ;                          #right#(* ae          *) 
+ 
+#right#(* lokale Ersatzdarstellungen für Font "trium10" *) 
+ 
+    ""244"" ,    43 ,   "\FO23;\!725;\FO5;" ;  #right#(* ungleich    *) 
+    ""245"" ,    31 ,   "\FO23;\!405;\FO5;" ;  #right#(* mal-Zeichen *) 
+ 
+  FONT  :  "modern12",  "elanlist" ;    #right#(* Mehrere Namen für einen Font *) 
+    indentation pitch  =  33 ; 
+    font lead          =  14; 
+    font heigth        =  53; 
+    font depth         =  13; 
+    next larger font   =  "" ; 
+    next smaller font  =  "micro" ; 
+    font string        =  "\FO11;" 
+                                        #right#(* Alle Zeichen haben die gleiche Breite *) 
+ 
+  FONT . . . 
+ 
+ 
+FONTTABLE  :  "agfaquer" ; 
+  x unit      =  160.0 ; 
+  y unit      =  160.0 ; 
+  on string   =  "\UL1;",  "\BO1;",  "\IT1;",  "\CFW;\CBB;" ; 
+  off string  =  "\UL0;",  "\BO0;",  "\IT0;",  "\CFT;\CBT;" ; 
+  . 
+  . 
+  . 
+ 
+ 
+FONTTABLE  :  "epson" ; 
+  x unit      =  47.24409 ;                    #right#(* 120.0 / 2.54 *) 
+  y unit      =  85.03937 ;                    #right#(* 216.0 / 2.54 *) 
+  on string   =  ""27"-"1"",  "",  ""27"4",  ""; 
+  off string  =  ""27"-"0"",  "",  ""27"5",  ""; 
+ 
+  ""214"" ,   ""27"R"2""091""27"R"0"" ;        #right#(* AE                           *) 
+  ""215"" ,   ""27"R"2""092""27"R"0"" ;        #right#(* OE                           *) 
+  ""216"" ,   ""27"R"2""093""27"R"0"" ;        #right#(* UE                           *) 
+  ""217"" ,   ""27"R"2""123""27"R"0"" ;        #right#(* ae                           *) 
+  ""218"" ,   ""27"R"2""124""27"R"0"" ;        #right#(* oe                           *) 
+  ""219"" ,   ""27"R"2""125""27"R"0"" ;        #right#(* ue                           *) 
+  ""220"" ,   "k" ;                            #right#(* Trenn-k                      *) 
+  ""221"" ,   "-" ;                            #right#(* Trennstrich                  *) 
+  ""222"" ,   "\#" ;                            #right#(* geschütztes Nummernkreuz     *) 
+  ""223"" ,   " " ;                            #right#(* geschütztes Leerzeichen      *) 
+  ""251"" ,   ""27"R"2""126""27"R"0"" ;        #right#(* ss                           *) 
+  ""252"" ,   ""27"R"2""064""27"R"0"" ;        #right#(* Paragraph                    *) 
+ 
+  FONT  :  "12",  "elite",  "elite12" ;        #right#(* Mehrere Namen für einen Font *) 
+    font height        =  36 ; 
+    indentation pitch  =  10 ; 
+    next smaller font  =  "12.klein" ; 
+    font string        =  ""27"!"1""27"p"0""27"T" ; 
+    bold offset        =  2 ; 
+ 
+  FONT  :  "12.klein",  "elite.klein",  "elanlist" ; 
+    font height         =  20 ; 
+    indentation pitch   =  10 ; 
+    next smaller font   =  "12.klein" ; 
+    font string         =  ""27"!"1""27"p"0""27"S"1"" ; 
+    bold offset         =  1 ; 
+ 
+  FONT  :  "12.hoch" ; 
+    font height         =  96 ; 
+    indentation pitch   =  10 ; 
+    next smaller font   =  "12.klein" ; 
+    font string         =  "" ; 
+    bold offset         =  2 ; 
+    y offsets           =  12, -12 ;#right#(* der Text wird jeweils 12 Mikroschritte unter-    
+                                    #right#   und überhalb der Basislinie ausgegeben *) 
+ 
+  FONT  :  "prop10",  "prop" ; 
+    font height         =  12 ; 
+    indentation pitch   =  24 ; 
+    next smaller font   =  "" ; 
+    font string         =  ""27"!"0""27"p"1""27"T" ; 
+    bold offset         =  2 ; 
+ 
+    "!"   ,   10 ; 
+    """"  ,   16 ; 
+    "("   ,   12 ; 
+    . . . 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#7.5. Schnittstelle des #ib#Fontspeicher#ie#s#ie(9)# 
+ 
+ 
+ 
+Das Paket #on("i")#font store#off("i")# liefert die folgenden Prozeduren: 
+ 
+#ib#fonttable#ie# 
+     PROC fonttable (TEXT CONST fonttable name) 
+     Zweck:  Stellt die angegebene Fonttabelle in der Task ein. Dabei wird zuerst in
+             der eigenen Task nach der angegebenen Fonttabelle gesucht. Existiert
+             die Fonttabelle in der eigenen Task nicht, so wird die Fonttabelle von
+             der Task "configurator" geholt. 
+             Wenn die Fonttabelle eingestellt ist, sind in der Task nur noch die Fonts
+             dieser Fonttabelle bekannt. Die Einstellung vererbt sich auf die Sohn­
+             tasks. 
+ 
+     TEXT PROC fonttable 
+     Zweck:  Liefert den Name der eingestellten Fonttabelle. 
+ 
+#ib#list fonttables#ie# 
+     PROC list fonttables 
+     Zweck:  Zeigt die Liste der verfügbaren Fonttabellen im #on("i")#notebook#off("i")#. 
+ 
+#ib#list fonts#ie# 
+     PROC list fonts 
+     Zweck:  Listet die Fonts der eingestellten Tabelle ins #on("i")#notebook#off("i")#. 
+ 
+     PROC list fonts (TEXT CONST fonttable name) 
+     Zweck:  Listet die Fonts der angegebenen Fonttabelle ins #on("i")#notebook#off("i")#. Die vorher
+             eingestellte Fonttabelle bleibt jedoch weiter eingestellt. 
+ 
+#ib#x step conversion#ie# 
+     INT PROC x step conversion (REAL CONST cm) 
+     Zweck:  Rechnet die in Zentimeter angegebene Länge in Mikroschritte der
+             x-Richtung um. 
+ 
+     REAL PROC x step conversion (INT CONST steps) 
+     Zweck:  Rechnet die in Mikroschritten der x-Richtung angegebene Länge in
+             Zentimeter um. 
+ 
+#ib#y step conversion#ie# 
+     INT PROC y step conversion (REAL CONST cm) 
+     Zweck:  Rechnet die in Zentimeter angegebene Länge in Mikroschritte der
+             y-Richtung um. 
+ 
+     REAL PROC y step conversion (INT CONST steps) 
+     Zweck:  Rechnet die in Mikroschritten der y-Richtung angegebene Länge in
+             Zentimeter um. 
+ 
+#ib#on string#ie# 
+     TEXT PROC on string (INT CONST modification) 
+     Zweck:  Liefert die in der Fonttabelle spezifizierte Befehlssequenz, um eine
+             Modifikation anzuschalten. Es gibt die folgenden Modifikationen 
+                   1     underline 
+                   2     bold 
+                   4     italics 
+                   8     reverse 
+ 
+#ib#off string#ie# 
+     TEXT PROC off string (INT CONST modification) 
+     Zweck:  Liefert die in der Fonttabelle spezifizierte Befehlssequenz, um eine
+             Modifikation auszuschalten. Es gibt die folgenden Modifikationen 
+                   1     underline 
+                   2     bold 
+                   4     italics 
+                   8     reverse 
+ 
+#ib#font#ie# 
+     INT PROC font (TEXT CONST font name) 
+     Zweck:  Liefert die interne Fontnummer des Fonts. Mit dieser Fontnummer
+             können die weiteren Informationen über den Font angefordert werden.
+             Existiert kein Font mit diesem Namen, so wird Null geliefert. 
+ 
+     TEXT PROC font (TEXT CONST font nr) 
+     Zweck:  Liefert den Fontnamen des Fonts mit der angegeben Fontnummer. Hat
+             der Font mehrere Namen, so wird der erste Name der Namensliste aus
+             der Fontdatei geliefert. Existiert kein Font unter dieser Nummer, so wird
+             #on("i")#niltext#off("i")# geliefert. 
+ 
+#ib#font exists#ie# 
+     BOOL PROC font exists (TEXT CONST font name) 
+     Zweck:  Informationsprozedur zur Abfrage der Existenz eines Fonts. 
+ 
+#ib#next smaller font exists#ie# 
+     BOOL PROC next smaller font exists  (INT CONST font nr, 
+                                          INT VAR next smaller font) 
+     Zweck:  Informationsprozedur zur Abfrage der Existenz des nächst kleineren
+             Fonts. Wenn er existiert, wird die Fontnummer dieses Fonts zurück­
+             geliefert. 
+ 
+#ib#next larger font exists#ie# 
+     BOOL PROC next larger font exists  (INT CONST font nr, 
+                                         INT VAR next larger font) 
+     Zweck:  Informationsprozedur zur Abfrage der Existenz des nächst größeren
+             Fonts. Wenn er existiert, wird die Fontnummer dieses Fonts zurück­
+             geliefert. 
+ 
+#ib#indentation pitch#ie# 
+     INT PROC indentation pitch (INT CONST font nr) 
+     Zweck:  Liefert die Einrückbreite in Mikroschritten der x-Richtung. Sie sollte eine
+             mittlere Breite der Zeichen sein, denn mit ihr werden die Einrückungen
+             und Aufzählungen berechnet. 
+ 
+#ib#font lead#ie# 
+     INT PROC font lead (INT CONST font nr) 
+     Zweck:  Liefert den Durchschuss des Fonts in Mikroschritten der y-Richtung.
+             Der Druchschuß ist der Zwischenraum zwischen den einzelnen Zeilen
+             bei einfachem Zeilenvorschub. 
+ 
+#ib#font height#ie# 
+     INT PROC font height (INT CONST font nr) 
+     Zweck:  Liefert die Höhe des Fonts in Mikroschritten der y-Richtung. Die Fon­
+             thöhe ist die Distanz von der Basislinie bis zur Oberkante des höchsten
+             Zeichens. 
+ 
+#ib#font depth#ie# 
+     INT PROC font depth (INT CONST font nr) 
+     Zweck:  Liefert die Tiefe des Fonts in Mikroschritten der y-Richtung. Die Fonttie­
+             fe ist die Distanz von der Basislinie bis zur Unterkante des tiefsten
+             Zeichens. 
+ 
+#ib#font string#ie# 
+     TEXT PROC font string (INT CONST font nr) 
+     Zweck:  Liefert den Fontstring des Fonts. Der Fontstring enthält die Befehls­
+             sequenz, um den Drucker auf diesen Font umzuschalten. 
+ 
+#ib#y offsets#ie# 
+     TEXT PROC y offsets (INT CONST font nr) 
+     Zweck:  Liefert einen Text mit den y-Verschiebungen von der Basislinie. Die
+             einzelnen Verschiebungen können mit dem Operator 'ISUB' abgefragt
+             werden. 
+ 
+#ib#bold offsets#ie# 
+     INT PROC bold offsets (INT CONST font nr) 
+     Zweck:  Liefert die 'bold'-Verschiebung. 
+ 
+#ib#char pitch#ie# 
+     INT PROC char pitch (INT CONST font nr, TEXT CONST char) 
+     Zweck:  Liefert die Breite des Zeichens in Mikroschritten der x-Richtung. 
+ 
+#ib#replacement#ie# 
+     TEXT PROC replacement (INT CONST font nr, TEXT CONST char) 
+     Zweck:  Falls das Zeichen eine Ersatzdarstellung hat, so wird diese geliefert,
+             anderfalls das Zeichen selbst. 
+ 
+#ib#get font#ie# 
+     PROC get font  (INT CONST font nr, 
+                     INT VAR indentation pitch, font lead, font height, font depth, 
+                     ROW 256 INT VAR pitch table) 
+     Zweck:  Die Variablen liefern die entsprechenden Informantionen über den
+             Font. Der Eintrag des Codewerts eines Zeichens plus eins in der Brei­
+             tentabelle liefert die Breite dieses Zeichens. 
+ 
+#ib#get replacements#ie# 
+     PROC get replacements  (INT CONST font nr, 
+                             TEXT VAR replacements, 
+                             ROW 256 INT VAR replacement table) 
+     Zweck:  In der Fonttabelle kann für jedes Zeichen eine Ersatzdarstellung an­
+             gegeben werden. Diese Ersatzdarstellungen werden mit dieser Proze­
+             dur geliefert. Dabei stehen in der Textvariablen 'replacement' die ge­
+             samten Ersatzdarstellungen des Fonts. Die Ersatzdarstellungstabelle
+             enthält Zeiger auf den Text der Ersatzdarstellungen. Die Ersatzdarstel­
+             lung eines Zeichnes bestimmt sich wie folgt: 
+ 
+ 
+     ersatzdarstellung : 
+       INT CONST wert := replacement table (code( zeichen ) + 1); 
+       IF wert > 0 
+          THEN INT CONST ende := wert + code (replacements SUB wert); 
+               subtext (replacements, wert + 1, ende) 
+          ELSE zeichen 
+        FI. 
+ 
+ 
+Bei den Prozeduren des Packets #on("i")#font store#off("i")# können die folgenden Fehlerfälle auftreten: 
+ 
+     -  Fonttabelle noch nicht eingestellt 
+          Es wurde noch keine Fonttabelle in der Task eingestellt. 
+ 
+     -  Fonttabelle "fonttable name" gibt es nicht 
+          Die angegebene Fonttabelle wurde weder in der eigenen Task, noch in der
+          Task 'configurator' gefunden. 
+ 
+     -  Font 'font nr' gibt es nicht 
+          Unter der angegebenen Fontnummer gibt es in der eingestellten Font­
+          tabelle keinen Font. Speziell ist das für 'font nr' = 0 der Fall, falls ein Font­
+          name nicht gefunden wurde. 
+ 
+     -  unzulaessige Modifikation 
+          Die angegebene Modifikation ist ungleich 1, 2, 4 oder 8. 
+#page# 
+ 
+#headeven# 
+ 
+%#center#EUMEL-Systemhandbuch 
+ 
+ 
+#end# 
+#headodd# 
+ 
+#center#8. Verschiedenes#right#% 
+ 
+ 
+#end# 
+ 
+#ib(9)#8. Verschiedenes#ie(9)# 
+ 
+ 
+ 
+ 
+#ib(9)#8.1. Der Spoolmanager#ie(9)# 
+ 
+ 
+Der "#ib#Spoolmanager#ie#" verwaltet eine #ib#Warteschlange von Datenräumen#ie# (Dateien), die von
+einem "#ib#Server#ie#" abgearbeitet werden sollen. Dabei puffert der Spoolmanager Dateien,
+die von beliebigen Tasks geschickt werden können, in einer Warteschlange und gibt
+sie der Reihe nach dem Server zur eigentlichen Verarbeitung. Ein typischer Einsatzfall
+(aber nicht der einzige) für ein solches System ist der Druck von Dateien in Multi-
+User-Systemen. Unabhängig davon, ob der Drucker gerade aktiv ist und wieviele
+Dateien noch auf den Ausdruck warten, kann jeder seine Datei dem Druckerspool (in
+der Regel die Task "PRINTER") senden und sofort danach weiterarbeiten. 
+ 
+ 
+ 
+#ib(9)#Prozeduren des Spoolmanagers#ie(9)# 
+ 
+ 
+Im privilegierten Ast des Taskbaumes (Söhne von "SYSUR"), stehen die folgenden
+Prozeduren zur Einrichtung eines Spoolmanagers zur Verfügung. 
+ 
+#ib#spool manager#ie# 
+     PROC spool manager (PROC server, BOOL CONST with start) 
+     Zweck: Die Task, in der die Prozedur aufgerufen wird, wird zum Spoolmanager.
+            Wenn 'with start' auf TRUE  gesetzt ist, wird eine Server-Task als unbe­
+            nannter Sohn ("-") eingerichtet und mit der übergebenen 'PROC server'
+            gestartet. Anderfalls muß der Spool durch den Benutzer mit Hilfe der
+            Spoolkommandos (siehe dort) gestartet werden. 
+ 
+     PROC spool manager (PROC server) 
+     Zweck: Diese Prozedur ruft die Prozedur 'spool manager' mit 'with start' gleich
+            TRUE auf. 
+ 
+ 
+Mit Hilfe der folgenden Prozeduren kann der Spool eingestellt werden. 
+ 
+#ib#station only#ie# 
+     PROC station only (BOOL CONST flag) 
+     Zweck: Wenn flag auf TRUE gesetzt ist, nimmt der Spooler nur Aufträge von
+            Tasks der eigenen Station entgegen. 
+            Voreinstellung: 'station only (FALSE)'. 
+ 
+     BOOL PROC station only 
+     Zweck: liefert TRUE, wenn der Spooler nur von der eigenen Station benutzt
+            werden darf. 
+ 
+#ib#spool duty#ie# 
+     PROC spool duty (TEXT CONST duty) 
+     Zweck: Mit dieser Prozedur kann ein Text im Spooler eingestellt werden, der die
+            Aufgabe des Spoolers beschreibt. Dieser wird beim 'list' gemeldet. 
+ 
+     TEXT PROC spool duty 
+     Zweck: Liefert die eingestellte Text-Beschreibung der Aufgabe des Spools. 
+ 
+#ib#spool control task#ie# 
+     PROC spool control task (TASK CONST task) 
+     Zweck: Diese Prozedur gibt der Task 'task' und ihrer Söhne die Berechtigung
+            Spoolkommandos (z.B. 'stop' oder 'start') an den Spoolmanager zusen­
+            den. Dabei muß die Task auf derselben Station wie der Spool sein und
+            in der Task muß die Datei "spool cmd", die sich auf dem Standardar­
+            chiv befindet, insertiert werden. 
+            Wird "SUPERVISOR" als Spoolkontrolltask eingestellt, so können alle
+            Tasks der Station, in denen die Datei "spool cmd" insertiert ist, die
+            Spoolkommandos geben. 
+ 
+     TASK PROC spool control task 
+     Zweck: Liefert die Taskidentifikation der Spoolkontrolltask. 
+ 
+#ib#server channel#ie# 
+     PROC server channel (INT CONST channel) 
+     Zweck: Mit Hilfe dieser Prozedur wird im Spoolmanager eine Kanalnummer
+            eingestellt, die der Server mit der Prozedur 'server channel' abfragen
+            kann. 
+     Fehlerfall: 
+            *  falsche Kanalangabe 
+                 Der angegebene Kanal ist kleiner als 1 oder größerer als 32. 
+ 
+     INT PROC serverchannel 
+     Zweck: Liefert die Nummer des Kanals, der im Spool eingestellt ist. 
+ 
+#on("b")#Anmerkung:#off("b")#  Soll im nicht-privilegierten Ast des Taskbaums (Söhne von "PUBLIC") ein
+            Spool eingerichtet werden, so muß dort die Datei "spool manager", die
+            sich auf dem Standardarchiv "std.zusatz" befindet, insertiert werden. 
+ 
+ 
+ 
+ 
+#ib(9)##ib#Spoolkommandos#ie##ie(9)# 
+ 
+ 
+Ein Spool kann zur Verwaltung der Warteschlange wie jede andere Task ans Termi­
+nal gekoppelt werden. Danach stehen die folgenden Spoolkommandos zur Verfügung.
+Diese Kommandos sind keine Prozeduren, sondern werden nur interpretiert. Sie dürfen
+also nur alleine eingegeben werden. Nach Beendigung der Verwaltungsaufgaben muß
+der Spool mit dem Kommando 'break' verlassen werden, da sonst keine weiteren
+Aufträge an den Spool gesendet werden können und auch die Warteschlange nicht
+weiter abgearbeitet wird. 
+ 
+#ib#stop#ie# 
+     Zweck: Die Server-Task wird gelöscht und dadurch der Spool deaktiviert. Der
+            Spool empfängt zwar noch weitere Aufträge und sortiert diese in die
+            Warteschlange ein. Die Warteschlange wird aber nicht weiterabgearbei­
+            tet. Ein eventuell von der Server-Task belegter Kanal wird freigegeben. 
+            Ist bei einem 'stop' noch ein Auftrag in Bearbeitung, so wird dieser
+            Auftrag abrupt abgebrochen. Es wird jedoch angefragt, ob der Auftrag
+            nochmal neu an die erste Stelle in der Warteschlange eingetragen wer­
+            den soll. 
+            Ist ein Spool deaktiviert, so wird dies bei einem 'list' angezeigt, 
+ 
+#ib#halt#ie# 
+     Zweck: Der Spool deaktiviert sich nach Abarbeitung des Auftrags, der gerade
+            bearbeitet wird. Bei einem 'list' wird dies vermerkt. 
+ 
+#ib#start#ie# 
+     Zweck: Der Spool wird aktiviert, indem eine neue Server-Task begonnen wird. Ist
+            der Spool zuvor nicht gestoppt worden, so wird zuerst ein 'stop' durch­
+            geführt. 
+            Wurde mit der Prozedur 'server channel' kein Kanal eingestellt, so wird
+            die Warnung 
+                  WARNUNG : Serverkanal nicht eingestellt 
+            ausgeben. Der Spool wird trotzdem gestartet. 
+ 
+start (kanal nummer) 
+     Zweck: Vor dem Start des Spools wird zuerst mit der Prozedur 'server channel'
+            der angegebene Kanal eingestellt. 
+ 
+#ib#first#ie# 
+     Zweck: Im Dialog kann ein Auftrag in der Warteschlange auf den ersten Platz
+            vorgezogen werden. 
+ 
+#ib#killer#ie# 
+     Zweck: Im Dialog werden alle Aufträge der Warteschlange zum Löschen ange­
+            boten. 
+ 
+#ib#list spool#ie# 
+     Zweck: Der aktuelle Zustand des Spools und die Warteschlange werden geli­
+            stet. 
+ 
+Ist nun eine Spoolkontrolltask eingestellt worden (siehe 'spool control task'), so muß in
+ihr die Datei "spool cmd" insertiert werden. Danach stehen die folgenden Prozeduren
+zur Verfügung. 
+ 
+#ib#stop#ie# 
+     PROC stop (TASK CONST spool) 
+     Zweck: Dem Spool 'spool' wird ein 'stop' zugestellt, was den Spool deaktiviert.
+            Wird noch ein Auftrag bearbeitet, so wird angefragt, ob dieser neu
+            eingetragen werden soll. 
+ 
+#ib#halt#ie# 
+     PROC halt (TASK CONST spool) 
+     Zweck: Dem Spool 'spool' wird ein 'halt' zugestellt, d.h der Spool deaktiviert
+            sich nach Beendigung des aktuellen Auftrags. 
+ 
+#ib#wait for halt#ie# 
+     PROC wait for halt (TASK CONST spool) 
+     Zweck: Dem Spool 'spool' wird ein 'halt' zugestellt. Die Task wartet jedoch auf
+            eine Rückantwort, die ihr der Spool sendet, wenn er sich nach Been­
+            digung des aktuellen Auftrags deaktiviert hat. 
+     Fehlerfall: 
+            *  Task "task name" wartet schon auf halt 
+               Die angegebene Task wartet schon auf eine Rückantwort des Spools
+               'spool'. 
+ 
+#ib#start#ie# 
+     PROC start (TASK CONST spool) 
+     Zweck: Dem Spool 'spool' wird ein 'start' zugestellt, wodurch der Spool sich
+            aktiviert. War der Spool zuvor nicht deaktiviert, so wird er zuerst ge­
+            stoppt. 
+ 
+#ib#first#ie# 
+     PROC first (TASK CONST spool) 
+     Zweck: Im Dialog kann einer der Aufträge in der Warteschlange des Spools
+            'spool' auf den ersten Platz vorgezogen werden. 
+ 
+#ib#killer#ie# 
+     PROC killer (TASK CONST spool) 
+     Zweck: Im Dialog werden die Aufträge der Warteschlange des Spools 'spool'
+            zum Löschen angeboten. 
+ 
+ 
+ 
+#ib(9)#Arbeitsweise des #ib#Servers#ie##ie(9)# 
+ 
+ 
+Der Server wird vom Spoolmanager mit einer Prozedur gestartet, die die Abarbeitung
+der Warteschlange vornimmt. Dabei muß diese Prozedur zuerst den Datenraum mit
+dem 'fetch code' (= 11) holen. Danach kann der Server sich noch mit dem 'fetch
+param code' (= 21) die Dateiparameter (Dateiname, Schreib- und Lesepaßwort, Sen­
+dername und Senderstation) abholen und mit der Bearbeitung des Auftrags beginnen. 
+ 
+Beispiel: 
+ 
+ 
+LET fetch code       = 11, 
+    param fetch code = 21; 
+BOUND STRUCT (TEXT name, write pass, read pass, sendername, 
+              INT  senderstation ) VAR msg; 
+DATASPACE VAR ds, param ds; 
+INT VAR reply; 
+ 
+spool manager (PROC server); 
+ 
+PROC server : 
+     disable stop; 
+     continue (server channel); 
+     REP forget (ds); ds := nilspace; 
+         call (father, fetch code, ds, reply); 
+         forget (param ds); param ds := nilspace; 
+         call (father, param fetch code, param ds, reply); 
+         msg := param ds; 
+         execute spool; 
+         IF is error THEN error treatment FI; 
+    PER; 
+END PROC server; 
+ 
+PROC execute spool : 
+     enable stop; 
+     ... 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#Senden eines Auftrags an den Spool#ie(9)# 
+ 
+ 
+Jede Task kann jedem Spool durch Aufruf von '#ib#save#ie#' eine Datei senden. 
+ 
+Beispiel: 
+ 
+ 
+   save ("datei name", task ("spool name")) 
+ 
+ 
+Dieses 'save'-Kommando funktioniert zweiphasig. Dabei wird in der ersten Phase dem
+Spool die Dateiparameter zugesendet. In der zweiten Phase folgt dann der Datenraum
+selber. Bei Netzübertragung zu einem Spool ist dieses zweiphasige 'save' jedoch
+nachteilig. Deshalb können Dateien vom Typ 'FILE' auch mit einem einphasigen 'save'
+unter dem 'file save code' (= 22) an den Spool gesendet werden. Die #on("i")#'headline'#off("i")# dieser
+Dateien muß jedoch dann auf eine bestimmte Art und Weise aufbereitet werden, so
+daß sie die Dateiparameter enthält. Beim Aufbau der #on("i")#'headline'#off("i")# muß eine Information
+muß mit dem Code 0 beginnen und dem Code 1 enden. Die Dateiparamter müssen
+dann mit der folgenden Reihenfolge in die #on("i")#'headline'#off("i")# eingetragen werden. 
+ 
+   -  Dateiname 
+   -  Schreibepaßwort 
+   -  Lesepaßwort 
+   -  Name des Senders 
+   -  Station des Senders 
+ 
+Beispiel: 
+ 
+ 
+... 
+LET file save code = 22; 
+DATASPACE VAR ds := old (file name); 
+FILE VAR file := sequential file (input, ds); 
+INT VAR reply; 
+headline (file,    ""0"" + file name + 
+                ""1""0"" + write password + 
+                ""1""0"" + read password + 
+                ""1""0"" + name (myself) + 
+                ""1""0"" + text (station (myself)) + ""1""); 
+call (spool task, file save code, ds, reply); 
+... 
+ 
+ 
+Der Spoolmanager setzt bei Dateien, die mit dem 'file save code' angeliefert werden
+die #on("i")#'headline'#off("i")# wieder auf den Dateinamen. 
+ 
+Den Benutzer stehen neben dem '#ib#save#ie#'-Kommando zur Übertragung einer Datei zum
+Spool noch die folgenden Kommandos zur Verfügung. 
+ 
+ 
+   save (ALL myself, task ("spool name")) 
+   save (SOME myself, task ("spool name")) 
+ 
+       übertragung aller bzw. einiger Dateien der eigenen Task zum Spool. 
+ 
+ 
+   #ib#erase#ie# ("datei name", task ("spool name")) 
+   erase (ALL task ("spool name"), task ("spool name")) 
+ 
+       Löschen eines bzw. aller eigenen Aufträge in der Warteschlange des Spools 
+ 
+ 
+   #ib#list#ie# (task ("spool name")) 
+ 
+       Liste des Spools über den aktuellen Zustand und die Warteschlange. 
+ 
+Existiert ein Spool "PRINTER", so gibt es noch die folgenden Befehle. 
+ 
+ 
+   #ib#print#ie# 
+   print ("datei name") 
+   print (ALL myself) 
+   print (SOME myself) 
+ 
+       Sie entsprechen einem 'save' an die Task "PRINTER" 
+ 
+ 
+   #ib#printer#ie# 
+ 
+       Liefert den internen Taskbezeichner der Task "PRINTER", d.h. diese Proze­
+       dur entspricht dem Aufruf von 'task ("PRINTER")'. 
+ 
+ 
+ 
+ 
+ 
+#ib(9)#8.2. #ib#Freie Kanäle#ie(9)##ie# 
+ 
+ 
+Das Paket '#ib#free channel#ie#' ermöglicht in Multi-User-Systemen die Einrichtung freier
+Kanäle. Freie Kanäle kann man zusätzlich zu dem Terminalkanal, der einem vom
+Supervisor zugeordnet wurde, benutzen. Jeder freie Kanal wird durch eine (benannte)
+Task - dem #ib#Kanalmanager#ie# - implementiert. Er wird danach mit dem Tasknamen ange­
+sprochen und kann von jeder Task belegt und wieder freigegeben werden. Während
+einer Belegung können andere Tasks den Kanal nicht benutzen. Der Kanalmanager
+koppelt sich für jede Belegung an den physikalischen Kanal an und gibt ihn danach
+auch wieder frei. Ein physischer Kanal kann also im Wechsel von mehreren Kanalma­
+nagern oder einem Kanalmanager und "normalen" Tasks belegt werden. 
+ 
+Das Paket 'free channel' muß beim Kanalmanager und allen Benutzern des Kanals
+bzw. bei einem gemeinsamen Vater insertiert sein. 
+ 
+ 
+#ib#FCHANNEL#ie# 
+     Zweck: Der Datentyp FCHANNEL spezifiziert einen freien Kanal. Die Assoziie­
+            rung mit einem realen freien Kanal erfolgt mit der Prozedur 'free chan­
+            nel' und der Zuweisung ':=' (ähnlich wie beim Datentyp FILE). 
+ 
+:= 
+     OP := (FCHANNEL VAR dest, FCHANNEL CONST source) 
+     Zweck: Zuweisung. Wird insbesondere bei der Assoziation (Assoziation: Verbin­
+            dung zwischen FCHANNEL VAR und Kanal) benötigt. 
+ 
+#ib#close#ie# 
+     PROC close (FCHANNEL VAR f) 
+     Zweck: Der belegte FCHANNEL wird freigeben. 
+ 
+     PROC close (TEXT CONST channel name) 
+     Zweck: Der namentlich spezifizierte Kanal wird freigegeben. 
+ 
+#ib#dialogue#ie# 
+     PROC dialogue (FCHANNEL CONST f, TEXT CONST end of dialogue char) 
+     Zweck: Der Terminalkanal wird direkt mit dem angegebenen freien Kanal ge­
+            koppelt. (Das Benutzerterminal wird "durchgeschaltet".) Eingaben am
+            Terminal werden auf 'f' ausgegeben, auf 'f' ankommende Daten werden
+            auf dem Benutzerterminal ausgegeben. Der Datenverkehr erfolgt im
+            #ib#Vollduplexmodus#ie#, d.h. der Datenverkehr beider Richtungen läuft unab­
+            hängig voneinander parallel. Hiermit können Terminals dynamisch an
+            andere Rechner gekoppelt werden. Der Dialogzustand wird durch Ein­
+            gabe des 'end of dialogue char' am Benutzerterminal beendet. 
+ 
+#ib#fetch#ie# 
+     PROC fetch (FCHANNEL VAR channel, TEXT CONST filename, controlchars) 
+     Zweck: Die angegebene datei wird über den Kanal 'channel' eingelesen. Dabei
+            besteht 'control chars' aus zwei bis vier Zeichen 
+               (eof + eol + handshake + handshake prompt) 
+            eof: 
+                Dieses Zeichen wird als Dateiabschluß erwartet. 
+            eol: 
+                Dieses Zeichen wird als Zeilenende erwartet. 
+            handshake, handshake prompt: 
+                Falls 'handshake prompt <> "" ' ist, wird bei dem Empfang eines
+                Prompt­Zeichen eine Quittung (Handshake­Zeichen) ausgegeben. 
+ 
+#ib#free channel#ie# 
+     FCHANNEL PROC free channel (TEXT CONST channel name) 
+     Zweck: Der namentlich spezifizierte Kanal wird belegt und als FCHANNEL
+            geliefert. 
+     Fehlerfälle: 
+          * task not existing 
+          * channel not free 
+ 
+     PROC free channel (INT CONST physical channel number) 
+     Zweck: Installiert die eigene Task als Kanalmanager für den angegebenen
+            physikalischen Kanal. 
+ 
+#ib#in#ie# 
+     PROC in (FCHANNEL CONST f, TEXT VAR response) 
+     Zweck: Es werden die Daten geliefert, die seit dem letzten 'in'­Aufruf bzw. seit
+            der Assoziierung eingetroffenen Daten geliefert. Bei 'niltext' liegen keine
+            Eingabedaten vor. 
+ 
+#ib#open#ie# 
+     PROC open (FCHANNEL VAR f) 
+     Zweck: Der Kanal wird neu belegt. Die Assoziation erfolgt mit dem gleichen
+            Kanal wie bei der letzten Assoziation. 
+     Fehlerfälle: 
+          * "task" gibt es nicht 
+          * Kanal ist nicht frei 
+ 
+#ib#out#ie# 
+     PROC out (FCHANNEL VAR f, TEXT CONST message) 
+     Zweck: Der übergebene Text wird auf dem Kanal 'f' ausgegeben. 
+ 
+#ib#save#ie# 
+     PROC save (FCHANNEL VAR f, TEXT CONST name, control chars) 
+     Zweck: Die übergebene Datei muß eine Textdatei sein (Struktur eines FILEs
+            haben). Sie wird komplett auf dem Kanal 'f' ausgegeben. 
+            Dabei bestehen 'control chars' aus bis zu drei Zeichen: 
+               (eof char + eol char + handshake option) 
+            eof char: 
+                Dieses Zeichen wird als Dateiabschluß geschickt. 
+            eol char: 
+                Dieses zeichen wird als Zeilenabschluß geschickt. 
+            handshake option: 
+                Falls die 'control chars' drei Zeichen umfassen, wird nach jeder
+                Zeile auf das als drittes definierte Handshake­Zeichen gewartet. 
+ 
+Beispiele: 
+ 
+ 
+  a) FCHANNEL VAR f := free channel ("otto") ; 
+     TEXT VAR antwort ; 
+     out (f, "hallo") ; 
+     in (f, antwort) ; 
+     put (antwort) ; 
+     close (f) ; 
+ 
+  b) open (f) ; 
+     REP 
+       out (f, "hallo ") ; 
+       in (f, antwort) 
+     UNTIL antwort <> "" PER ; 
+     put (antwort) ; 
+     close (f) ; 
+ 
+  c) open (f) ; 
+     dialogue (f, "§") ; 
+     close (f) 
+
diff --git a/doc/user/benutzerhandbuch.1 b/doc/user/benutzerhandbuch.1
new file mode 100644
index 0000000..7c8fec7
--- /dev/null
+++ b/doc/user/benutzerhandbuch.1
@@ -0,0 +1,580 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#Benutzerhandbuch 
+ 
+ 
+ 
+ 
+#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# 
+ 
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Teil 1: Einleitung    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+1 - %            GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        1 - % 
+#tableend##clearpos# 
+#end# 
+TEIL 1: Einleitung 
+#free(1.0)# 
+ 
+1.1. Vorwort 
+#free(1.0)# 
+ 
+Dieses Buch bietet Ihnen eine Anleitung zur Handhabung des Betriebssystems
+EUMEL in Hinblick auf die Textverarbeitung. Das Buch wendet sich somit an alle, die
+das leicht erlernbare EUMEL-System zur Erstellung von Texten jeglicher Art und
+jeden Umfangs nutzen wollen. 
+ 
+Die Anleitung erfordert keinerlei Vorkenntnisse, weder von Computern im allgemei­
+nen noch von EUMEL im besonderen. Neulingen auf dem Gebiet der Benutzung eines
+Computers sei empfohlen, dieses erste Kapitel, das sich kurz mit der 'grauen Theorie'
+beschäftigt, mindestens zweimal zu lesen: 
+ 
+-  Der erste Durchgang sollte nur einer groben Orientierung dienen. Die Begriffe, die
+   teilweise erst im routinierteren Umgang Sinn gewinnen, sollten Sie 'mal gehört'
+   haben, um die folgenden Kapitel leichter lesen zu können. 
+ 
+-  Der zweite Durchgang erscheint uns sinnvoll, wenn Sie sich 'freigeschwommen'
+   haben. Wenn der Umgang mit dem EUMEL-System Ihnen nach einigen Tagen
+   schon vertrauter erscheint, ist es zweckmäßig, sich auf dem Hintergrund der
+   gemachten Erfahrungen die Erklärungen noch einmal durchzulesen. Einige der
+   Begriffe werden erst dann wirklich verständlich und manche Unsicherheit wird
+   beseitigt werden. 
+ 
+Die weiteren Teile des Buches geben dann Anleitung vom ersten Einstieg ins
+EUMEL-System bis hin zur detaillierten Beschreibung der Textverarbeitung. Alle in
+Teil 3 und 4 enthaltenen Beispiele sollten Sie sorgfältig durchgehen und am Bild­
+schirm nachvollziehen. Aus dem Teil 5 können Sie nach eigener Einschätzung zu­
+nächst die Bereiche auswählen, die Sie selbst für besonders wichtig halten. Sie wer­
+den feststellen, daß Sie durch den Umgang mit der EUMEL-Textverarbeitung mit
+fortschreitender Routine immer mehr der gebotenen Möglichkeiten hinzunehmen
+werden. 
+#free(1.0)# 
+Was ist ein Betriebssystem ? 
+ 
+Ein #ib#Betriebssystem#ie# ist eine Sammlung von Programmen, die dem Benutzer eines
+Computers die Arbeit mit diesem Gerät erst ermöglichen. Die Programme des Be­
+triebssystems stellen die Verbindung zwischen den Bausteinen eines Computers, der
+Hardware, und den Anwendungsprogrammen eines Benutzers her. 
+ 
+Alle Programme, die diese riesige Lücke schließen und z.B. dafür sorgen, daß der
+Befehl: #on("i")#drucke ("diesen brief")#off("i")# tatsächlich dazu führt, daß der eben noch am Bild­
+schirm verfaßte Brief zum Drucker gesendet und dort ausgedruckt wird, sind soge­
+nannte Systemprogramme, Teile des Betriebssystems. 
+ 
+Dieses Benutzerhandbuch zum Betriebssystem EUMEL wird Ihnen schrittweise die
+Befehle erklären, die Sie zur Nutzung aller Möglichkeiten der Textverarbeitung mit
+EUMEL verwenden können, und Ihnen somit einen Teil des Betriebssystems vorstel­
+len. 
+#free(1.0)# 
+Ist EUMEL anders als andere ?
+ 
+#on("b")#Ja.#off("b")# Das Betriebssystem EUMEL (#on("b")#E#off("b")#xtendable multi #on("b")#U#off("b")#ser #on("b")#M#off("b")#icroprocessor #on("b")#EL#off("b")#an Sy­
+stem) erklärt durch seinen voll ausgeschriebenen Namen einen wesentlichen Unter­
+schied zu anderen Systemen: "Erweiterbares Mehrbenutzer Mikroprozessor ELAN-
+System." 
+ 
+Während andere auf Mikroprozessoren (und damit auf sogenannte Personal Compu­
+ter) abgestimmte Betriebssysteme #on("u")#einen#off("u")# Benutzer bei seiner Arbeit unterstützen, ist
+EUMEL fähig, #on("u")#mehreren#off("u")# Anwendern gleichzeitig die Benutzung eines Computers zu
+ermöglichen. Natürlich funktioniert EUMEL ebensogut für einen einzigen Benutzer. Es
+gibt aber bei EUMEL die Möglichkeit, durch Ankoppeln weiterer Bildschirme an den
+Rechner und #on("b")#ohne#off("b")# Kosten für zusätzliche Software mehreren Benutzern gleichzeitig
+die Arbeit an diesem Rechner zu ermöglichen. 
+ 
+Zweitens ist EUMEL hardwareunabhängig, das heißt, gleichgültig von welchem Her­
+steller Ihr Computer stammt, die Bedienung und die Kommandosprache ist immer
+gleich. Auch können Disketten, die mit einem XY-Rechner beschrieben wurden, von
+einem ABC-Computer gelesen werden; durchaus keine Selbstverständlichkeit. 
+ 
+Eine weitere Besonderheit des EUMEL-Systems macht alle froh, die damit arbeiten:
+EUMEL ist durchgängig in der Programmiersprache ELAN gehalten. Auch wenn Sie
+(noch) nicht programmieren möchten, erleichtert Ihnen ELAN das Leben dadurch, daß
+Sie schreiben können, was Sie meinen: eine Datei, die einen Geschäftsbrief fix und
+fertig und druckbereit enthält, heißt nicht etwa: 
+ 
+               $TXT.PRT 
+ 
+sondern: 
+ 
+               Angebot an Fa.Müller 1.7.86 
+ 
+ 
+Ein weiterer wichtiger Unterschied wird Ihnen bewußt werden, wenn Sie ein anderes
+Betriebssystem kennen: Die EUMEL-Textverarbeitung ist kein zusätzliches Programm
+mit eigener Kommandosprache, welches bei Bedarf geladen werden muß, sondern
+steht jederzeit, im wahrsten Sinne des Wortes auf Knopfdruck, zu Ihrer Verfügung. 
+#free(1.5)# 
+1.2. Wichtige Begriffe 
+#free(1.0)# 
+-  #on("b")#TASK#off("b")#. Eine #ib#Task#ie# ist ein eigenständiger Prozeß innerhalb eines EUMEL-Systems,
+   der entweder zur Verwaltung des EUMEL-Systems oder zu einem Benutzer
+   gehört. Indem jedem Benutzer ein eigener Arbeitsbereich zugewiesen ist, wird
+   verhindert, daß unkontrolliert auf fremde Daten zugegriffen wird. Eine Task hat
+   einen Namen, mit dem sie angesprochen werden kann. Ein EUMEL-System
+   besteht aus mehreren Tasks. 
+ 
+   Ein brauchbarer Vergleich mit einem EUMEL-Tasksystem ist ein Firmengebäude:
+   Es besteht aus vielen Räumen und jeder Raum ( = Task ) ist entweder ein nor­
+   males Arbeitszimmer oder ein Chefzimmer oder eine Werkstatt, in der Dienst­
+   leistungen für andere erledigt werden. 
+ 
+   Eine solche Ordnung zeigt folgendes Tasksystem; der #on("i")#kursiv#off("i")# gesetzte Kommentar
+   zeigt die Benennung der 'Dienstposten' eines vergleichbaren Büros: 
+ 
+ 
+         SUPERVISOR #on("i")#(* Zimmerverwalter *)#off("i")# - 
+             - 
+ 
+           SYSUR   #on("i")#(* Werkstattmeister *)#off("i")# 
+ 
+ 
+               ARCHIVE   #on("i")#(* Archivar *)#off("i")# 
+ 
+               configurator    #on("i")#(* Elektriker *)#off("i")# 
+ 
+               OPERATOR   #on("i")#(* Hausmeister *)#off("i")# 
+ 
+                   shutup   #on("i")#(* Nachtwächter *)#off("i")# 
+ 
+       UR   #on("i")#(* Aufsichtsrat *)#off("i")# 
+ 
+           PUBLIC    #on("i")#(* Abteilungsleiter *)#off("i")# 
+ 
+               Meier     #on("i")#(*  Angestellter *)#off("i")# 
+               Müller    #on("i")#(*     "         *)#off("i")# 
+               Schulze   #on("i")#(*     "         *)#off("i")# 
+ 
+ 
+   Bildlich gesprochen stellt eine Task also ein 'Arbeitszimmer' für einen EUMEL-
+   Benutzer dar. Als EUMEL Anwender richten Sie sich Ihre Task selbst ein, indem
+   Sie das Kommando 'begin ("taskname")' geben. 
+ 
+   Nachdem Sie dieses Kommando einmal gegeben haben, existiert diese Task unter
+   dem von Ihnen gewählten Namen. 
+ 
+   In der Task (also sinngemäß im Arbeitszimmer) arbeiten Sie - insbesondere legen
+   Sie Dateien (= Akten) an. Dateien existieren nur innerhalb einer Task. 
+ 
+   Tasks werden durch den SUPERVISOR verwaltet, er regelt den Zugriff auf Tasks.
+   Um Ihre Task zu verlassen, geben Sie das Kommando 'break' an den
+   SUPERVISOR, um sie wieder zu betreten, das Kommando 'continue ("taskna­
+   me")'. 
+ 
+ 
+-  #on("b")#DATEI#off("b")#. Eine #ib#Datei#ie# ist eine Menge von zusammengehörigen Daten. Eine Datei in
+   einer Task entspricht einer Akte in einem Arbeitszimmer. Eine Task kann bis zu
+   200 Dateien enthalten. Jede Datei in einer Task hat einen eigenen Namen, in ver­
+   schiedenen Tasks dürfen gleichnamige Dateien existieren. Eine Datei ist in Zeilen
+   unterteilt. 
+ 
+   Für die Arbeit in einer Datei am Bildschirm muß auf die Datei mit dem Editor
+   zugegriffen werden: 'edit ("dateiname")', danach kann der Inhalt der Datei am
+   Terminal bearbeitet werden (siehe Kapitel 4 und 5). 
+ 
+ 
+-  #on("b")#KOMMANDO#off("b")#. Ein #ib#Kommando#ie# ist ein Befehl an den Rechner, eine Arbeit zu tun.
+   Welche Kommandos Sie dem Rechner zum jeweiligen Zeitpunkt geben können,
+   hängt davon ab, auf welcher 'Kommandoebene' Sie sich befinden. Als Anhalt gilt: 
+ 
+   -  Kommandos auf Supervisor-Ebene betreffen das Tasksystem. 
+ 
+   -  Kommandos auf Monitor-Ebene betreffen die eigene Task oder Dateien. 
+ 
+   -  Kommandos auf Editor- Ebene betreffen Zeilen, Worte oder einzelne Zeichen
+      der aktuellen Datei. 
+ 
+   Auf welcher Ebene Sie sich befinden, werden Sie nach kurzer Gewöhnung leicht
+   am Bildschirm erkennen (siehe Teil 3). 
+ 
+   Bei manchen Kommandos muß nicht nur gesagt werden, was getan werden soll,
+   sondern auch, womit es getan werden soll. Eine solche Angabe zum Kommando
+   heißt #ib#Parameter#ie#. 
+                                        Kommando    Parameter 
+                                           |            | 
+     Beispiel: Lege neue Task an     =    begin    ("taskname") 
+               Drucke Datei          =    print    ("dateiname"). 
+               Suche das Wort ENDE   =    down     ("ENDE") 
+ 
+   Parameter werden in runde Klammern gesetzt und ggf. durch Kommata voneinan­
+   der getrennt. Textparameter werden zusätzlich in Anführungsstriche gesetzt. 
+ 
+   Ein Kommando kann keinen, einen oder viele Parameter benötigen; die
+   Beschreibung der Kommandos in diesem Buch zeigt jeweils alle Möglichkeiten. 
+ 
+ 
+-  #on("b")#SUPERVISOR#off("b")#.  Spezielle Task zur Überwachung eines EUMEL-Systems. Ein
+   Benutzer kann durch die #ib#Supervisor#ie#-Kommandos Leistungen von dieser Task
+   fordern: neue Task einrichten, Task wiederaufnehmen und diverse Informationen. 
+ 
+ 
+-  #on("b")#MONITOR#off("b")#.  Befehlsempfänger in einer Task. Jede Arbeit im EUMEL-System
+   findet in einer Task statt. Die Arbeit mit einem Computer besteht in wesentlichen
+   Teilen im Aufruf von Programmen durch Kommandos. Der Empfänger dieser
+   Kommandos in einer Task ist der #ib#Monitor#ie#. Der Monitor ist sichtbar durch eine
+   Zeile, in der 'gib kommando' steht. In diese Zeile werden #ib#Kommando#ie#s und erfor­
+   derliche Parameter eingegeben. 
+ 
+ 
+-  #on("b")#ARCHIVE#off("b")#.  Spezielle Task zur Verwaltung des Diskettenlaufwerks. Da für die
+   längerfristige Datenhaltung und zur zusätzlichen Datensicherung Dateien auf
+   Disketten geschrieben werden, besitzt das EUMEL-System für diese Aufgabe
+   eine besondere Task, die die Bedienung vereinfacht und exklusiven Zugriff auf das
+   Laufwerk garantiert. 
+ 
+ 
+-  #on("b")#EDITOR#off("b")#.  Programm zur Dateibearbeitung am Bildschirm. Das Programm wird
+   durch das ( Monitor- ) Kommando 'edit' und die Eingabe des Namens der ge­
+   wünschten Datei als Parameter gestartet. 
+ 
+   Da ein Bildschirm normelerweise auf 80 Zeichen Zeilenbreite und 24 Zeilen be­
+   schränkt ist, kann der Editor als Fenster betrachtet werden, das über die mögli­
+   cherweise weitaus größere Datei bewegt wird und durch das der betrachtete Aus­
+   schnitt der Datei bearbeitet werden kann. 
+ 
+    
+   +-------------------------------------------------------------------+ 
+   i                                                                   i 
+   i                                                                   i 
+   +------------------------------------+                              i 
+   i                                    i                              i 
+   i      Der Editor, Fenster zur       i                              i 
+   i      Dateibearbeitung              i                              i 
+   i                                    i                              i 
+   +------------------------------------+                              i 
+   i                                                                   i 
+   +-------------------------------------------------------------------+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+1.3. Die Notation in diesem Buch 
+#free(1.0)# 
+Im weiteren Text werden Sie schrittweise in die Bedienung des Systems eingeführt.
+Für alle Kommandos und Arbeiten haben wir Beispiele in dieses Buch aufgenommen,
+die Sie direkt am Rechner nachvollziehen sollten. 
+ 
+Beachten Sie dabei bitte folgende Regeln der Aufschreibung: 
+ 
+-  Es gibt eine Reihe von Tasten auf einer Computertastatur, die eine besondere
+   Bedeutung haben. Diese sogenannten Funktionstasten werden ebenso wie beson­
+   dere Tastenkombinationen explizit als Tasten dargestellt: 
+ 
+ 
+      <SV> 
+ 
+      <ESC> <e> 
+ 
+      <CR>
+ 
+ 
+-  Alles, was Sie am Bildschirm Ihres Rechners schreiben oder lesen sollen, ist in
+   Textbereiche, die einen Bildschirm darstellen, eingefaßt. 
+ 
+  Beispiel: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+edit ("meine datei") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+-  Innerhalb des Handbuchs sind in der Aufschreibung die Konventionen der
+   Programmiersprache ELAN, in der alle Programme des Betriebssystems geschrie­
+   ben sind, berücksichtigt. Dabei sind folgende Besonderheiten zu beachten: 
+ 
+   1) Kommandos werden grundsätzlich klein geschrieben. 
+ 
+   2) Dateinamen u.ä. werden in Klammern und Anführungsstriche gesetzt. In
+      diesem Buch steht an den Stellen, wo ein Dateiname auftaucht #on("i")# 'dateiname' #off("i")#;
+      den Namen, den Sie tatsächlich verwenden, können Sie frei wählen. 
+ 
+   3) Falls besondere Begriffe oder Beispiele innerhalb eines normalen Textes
+      auftreten, werden sie in einfache Anführungsstriche gesetzt. 
+ 
+ 
+Also: Das Kommando 'edit' benötigt als Parameter einen Dateinamen. Wählen Sie
+      einen Namen und geben Sie 'edit ("dateiname")' ein.  Falls Sie den Namen #on("i")#
+      "Geschäftsbrief" #off("i")# gewählt haben, müssen Sie am Bildschirm: 
+ 
+ 
+edit ("Geschäftsbrief") 
+ 
+ 
+tippen und das Kommando mit der <CR> Taste dem Monitor zur Bearbeitung überge­
+ben: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+edit ("Geschäftsbrief") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+#on("b")##on("i")#Die Eingabe von <CR> als 'Auslöser' für die Ausführung von
+Kommandos wird im weiteren nicht besonders hervorgehoben.#off("b")##off("i")# 
+#page# 
+1.4. Voraussetzungen 
+ 
+#free(1.0)# 
+Neben dem Computer an sich ist die vollständige Installation eines EUMEL-Systems
+auf diesem Computer Voraussetzung für alle im folgenden beschriebenen Aktivitäten. 
+ 
+Die Beschreibung einer Systeminstallation finden Sie im Anhang I. Im weiteren gehen
+wir davon aus, daß Ihr Rechner sich in einem Zustand befindet, der durch Eingabe
+von <SV> oder <CNTL> <b> (gleichzeitig) die sogenannte EUMEL-Tapete zeigt und
+Supervisor-Kommandos annimmt. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+                                           Terminal 2  
+ 
+ 
+                      EUMEL Version 1.8/M 
+ 
+ 
+        gib supervisor kommando: 
+        begin("meine erste task") 
+ 
+ 
+ 
+   ESC ? --> help 
+   ESC b --> begin("")            ESC h --> halt 
+   ESC c --> continue("")         ESC s --> storage info 
+   ESC q --> break                ESC t --> task info 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Weiterführende Information zum Aufbau eines EUMEL-Systems finden Sie im An­
+hang I. 
+ 
+#page# 
+Die Funktionstasten des EUMEL-Systems 
+ 
+ 
+ 
+Die Lage der EUMEL-Funktionstasten entnehmen Sie bitte der speziellen Installa­
+tionsanleitung zu dem von Ihnen benutzten Gerät. #l pos (0.0)##l pos(4.0)# 
+
+ 
+<,>,v,^           Positionierungstasten 
+#table# 
+#free(0.5)# 
+<SHIFT>           Umschalttaste 
+#free(0.5)# 
+<CR>              Eingabe-/ Absatztaste 
+#free(0.5)# 
+<HOP>             Verstärkertaste 
+#free(0.5)# 
+<RUBOUT>          Löschtaste 
+#free(0.5)# 
+<RUBIN>           Einfügetaste 
+#free(0.5)# 
+<TAB>             Tabulatortaste 
+#free(0.5)# 
+<MARK>            Markiertaste 
+#free(0.5)# 
+<ESC>             Kommandotaste 
+#free(0.5)# 
+<SV>              Supervisortaste 
+#free(0.5)# 
+<STOP>            Stoptaste 
+#free(0.5)# 
+<WEITER>          Weitertaste 
+#tableend##clear pos# 
+ 
+Task-Organisation 
+#free(1.0)# 
+ 
+Zum Verständnis der Handhabung des Systems sollten Sie versuchen, eine Vorstel­
+lung von der Organisation der Teile zu bekommen. 
+ 
+Die einzelnen #ib#Task#ie#s eines EUMEL-Systems 'stehen nicht frei im Raum', sondern
+sind in einer baumartigen Beziehung organisiert: 
+ 
+ 
+ 
+SUPERVISOR 
+    - 
+    SYSUR 
+        configurator 
+        OPERATOR 
+ 
+        ARCHIVE 
+UR 
+    PUBLIC 
+        Meyer 
+        Müller 
+        Schulze 
+ 
+ 
+ 
+Das System besteht aus zwei Zweigen, die nebeneinander liegen: 
+ 
+Dem Systemzweig mit der Wurzel SUPERVISOR 
+ 
+                 und 
+ 
+dem Benutzerzweig mit der Wurzel UR. 
+ 
+Der Systemzweig stellt Ihnen privilegierte Dienstleistungen zur Verfügung, der Benut­
+zerzweig stellt die normale Arbeitsumgebung dar. 
+ 
+Alle unter diesen Wurzeln liegenden Tasks des EUMEL-Systems haben mindestens
+einen Vorgänger, es besteht also eine 'Vater-Sohn Beziehung' zwischen allen Tasks
+des Systems. 
+ 
+Grundsätzlich können Dateien ohne besondere Kommandos zur Vater-Task geschickt
+und von der Vater-Task geholt werden, aber nicht zu beliebigen anderen Tasks. 
+ 
+'Müller' kann eine Datei an '#ib#PUBLIC#ie#' schicken und 'Schulze' kann sie dann dort
+abholen, aber eine direkte Sendung von 'Müller' nach 'Schulze' ist in der Regel nicht
+möglich. 
+ 
+Zur Sprechweise: jede Task, über die diese Art von 'Dateivermittlung' abgewickelt
+werden kann, heißt 'Manager-Task'. Jede Task kann zum '#ib#Manager#ie#' erklärt werden. 
+1.5. Eine Beispielsitzung 
+#free(1.0)# 
+Der Ablauf zur Erstellung eines Schreibens stellt sich im EUMEL-System wie folgt
+dar: 
+ 
+  <SV>       SUPERVISOR aufrufen 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+                                           Terminal 2  
+ 
+ 
+                      EUMEL Version 1.8/M 
+ 
+ 
+        gib supervisor kommando: 
+        begin("meine erste task") 
+ 
+ 
+ 
+   ESC ? --> help 
+   ESC b --> begin("")            ESC h --> halt 
+   ESC c --> continue("")         ESC s --> storage info 
+   ESC q --> break                ESC t --> task info 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Durch das Kommando 'begin ("meine erste task")', welches durch <CR> abgeschlos­
+sen werden muß, wird eine Task mit dem Namen 'meine erste task' im Benutzer­
+zweig, also unterhalb von 'PUBLIC' angelegt. Würde diese Task bereits existieren, so
+könnten Sie sie mit 'continue ("meine erste task")' an das Terminal holen. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+edit ("Rechnung zum 31.12.86") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+In der Task eröffnen Sie eine Datei mit dem Kommando 'edit ("dateiname")'. Falls
+diese Datei neu ist, erfolgt eine Kontrollfrage (zur Kontrolle der gewünschten Schreib­
+weise des Dateinamens), die Sie durch <j> bejahen. 
+ 
+Die Datei ist in diesem Beispiel bereits mit etwas Text gefüllt. Tippen Sie einen belie­
+bigen Text ein und beenden Sie die Bearbeitung dieser ersten Datei durch Drücken
+der Tasten <ESC> <q> (nacheinander!). 
+ 
+ 
+____________________________________________________________________________ 
+.................... Rechnung zum 31.12.86 ...................... Zeile 1      
+                                            G M D 
+                                            Sankt Augustin 
+                                            Schloß Birlinghoven 
+ 
+Sehr geehrte Damen und Herren, 
+> 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+Um die Arbeit in der Task zu beenden, geben Sie auch an dieser Stelle <ESC> <q> 
+(nacheinander!) ein. 
+ 
+Nach Verlassen der Task ist wiederum die EUMEL-Tapete auf dem Bildschirm. Jede
+weitere Aktion wird wiederum von hier aus durch <SV> begonnen. Insbesondere zum
+#ib#Ausschalten des Geräts#ie# muß nach <SV> die Task '#ib#shutup#ie#' angestoßen werden (siehe
+auch Anhang I). 
+
diff --git a/doc/user/benutzerhandbuch.2 b/doc/user/benutzerhandbuch.2
new file mode 100644
index 0000000..0153fae
--- /dev/null
+++ b/doc/user/benutzerhandbuch.2
@@ -0,0 +1,443 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Teil 2: Der Supervisor    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+2 - %            GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        2 - % 
+#tableend##clearpos# 
+#end# 
+ 
+TEIL 2: Der Supervisor
+#free(1.0)# 
+ 
+#ib(9)#2.1. Steuerkommandos#ie(9)# 
+#free(1.0)# 
+ 
+Jegliche Aktivität im EUMEL-System beginnt mit dem Aufruf des SUPERVISOR
+durch Drücken der Taste 
+ 
+                         <SV> 
+ 
+ 
+Dieser Tastendruck koppelt Ihr Terminal an den Rechner an. Dieser Vorgang ist auch
+dann nötig, wenn diese Geräte praktisch eine Einheit bilden. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+                                                         Terminal 2  
+ 
+ 
+                      EUMEL Version 1.8/M 
+ 
+ 
+            gib supervisor kommando: 
+ 
+ 
+ 
+ 
+   ESC ? --> help 
+   ESC b --> begin("")            ESC h --> halt 
+   ESC c --> continue("")         ESC s --> storage info 
+   ESC q --> break                ESC t --> task info 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die auf den unteren Informationszeilen angezeigten Kommandos stehen nun zur
+Auswahl. Für alle diese Kommandos gilt, daß sie entweder durch zwei aufeinander­
+folgende Tastendrücke <ESC> und Kennzeichen oder auch durch vollständiges Eintip­
+pen eingegeben werden können und mit <CR> ausgelöst werden. 
+ 
+Die Eingabe eines falschen Zeichens nach <ESC> oder eines falschen Kommandos
+wird abgewiesen. Die Eingabe ist dann zu wiederholen. 
+ 
+ 
+Bedeutung der Kommandos: 
+ 
+#on("b")# 
+1) Steuerkommandos #off("b")# 
+ 
+   #ib#ESC b#ie#   #ib#begin#ie# ("taskname")        Task einrichten. 
+   #ib#ESC c#ie#   #ib#continue#ie# ("taskname")     Task wieder ankoppeln. 
+   #ib#ESC q#ie#   #ib#break#ie#                     Terminal abkoppeln. 
+   #ib#ESC h#ie#   #ib#halt#ie#                      Programmlauf abbrechen. 
+ 
+ 
+ 
+#on("b")# 
+2) Informationskommandos#off("b")#  (nur Supervisor) 
+ 
+   #ib#ESC ?#ie#   #ib#help#ie#                      Information. 
+   #ib#ESC s#ie#   #ib#storage info#ie#              Belegten Speicherplatz anzeigen. 
+   #ib#ESC t#ie#   #ib#task info#ie#                 Im System befindliche Tasks anzeigen. 
+ 
+#page# 
+2.2. Eine Task einrichten 
+#free(1.0)# 
+ 
+    
+   Mit dem Kommando 'begin' wird eine neue Task eingerichtet. 
+ 
+                                              
+#free(1.0)# 
+ 
+Zunächst koppeln Sie Terminal und Rechner, dann legen Sie eine neue Task an. 
+ 
+    Terminal ankoppeln:  <SV> 
+ 
+                         <ESC> <b> 
+ 
+Die Tastenkombination 'ESC b' schaltet den Einfügemodus ein und positioniert
+den Cursor passend für die Eingabe des Tasknamens. 
+ 
+____________________________________________________________________________ 
+ 
+gib supervisor kommando : 
+begin ("") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Dateinamen eintippen: 
+ 
+____________________________________________________________________________ 
+ 
+           gib supervisor kommando: 
+           begin ("taskname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nachdem Sie den Namen eingegeben haben, betätigen Sie die <CR> Taste. Daraufhin
+meldet sich der Monitor der neuen Task und Sie können beliebige Monitor-
+Kommandos (siehe Teil 3) eingeben. 
+ 
+Wird eine Task in dieser geschilderten Weise neu eingerichtet, so wird sie automa­
+tisch (von der Task SUPERVISOR) als Sohn der Task PUBLIC angelegt. 
+ 
+ 
+Soll eine Task nicht als Sohn von PUBLIC, sondern als Sohn einer anderen Task
+angelegt werden, so ist das Kommando 'begin' mit zwei Parametern zu geben. Die
+neue Task wird dann als Sohn einer anderen Manager-Task angelegt (siehe Teil 3). 
+ 
+ 
+____________________________________________________________________________ 
+ 
+           gib supervisor kommando: 
+           begin ("taskname","name der vatertask") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ACHTUNG:   Die Task, die als Vater-Task angegeben wird, muß
+          eine Manager-Task sein, sonst passiert überhaupt nichts!
+          (s. Kap. 3.1.2.) 
+ 
+#page# 
+Task wiederankoppeln 
+#free(1.0)# 
+ 
+    
+   Mit dem Kommando 'continue' wird eine existierende Task an das
+   Terminal angekoppelt. 
+ 
+                               
+#free(1.0)# 
+ 
+Wenn Sie die Arbeit in einer Task wiederaufnehmen wollen, holen Sie die Task mit
+dem Kommando 'continue' an das Terminal. Dieser Vorgang ähnelt dem Einrichten
+einer neuen Task: 
+ 
+   Terminal ankoppeln:  <SV> 
+ 
+                        <ESC> <c> 
+ 
+Die Tastenkombination 'ESC c' schaltet den den Einfügemodus ein und positioniert
+den Cursor passend für die Eingabe des Tasknamens. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+           gib supervisor kommando: 
+           continue ("taskname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nach dieser Eingabe finden Sie die wiederaufgenommene Task so vor, wie Sie sie
+verlassen haben. 
+ 
+#page# 
+Terminal abkoppeln 
+#free(1.0)# 
+ 
+   
+  Mit dem Kommando 'break' wird das Terminal vom Rechner abgekoppelt. 
+ 
+       
+#free(1.0)# 
+ 
+Wenn Sie beispielsweise nach einem Informationskommando (siehe Teil 2.3.ff) das
+Terminal sofort vom Rechner abkoppeln möchten, geben Sie das 'break'-Kommando.
+Nach 'storage info' geht es jedoch nur mit <SV> weiter. 
+ 
+____________________________________________________________________________ 
+ 
+           gib supervisor kommando: 
+           break 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nach dieser Eingabe ist das Terminal abgekoppelt. Jede neue Aktivität ist wiederum
+mit <SV> einzuleiten. 
+#page# 
+Laufendes Programm stoppen 
+#free(1.0)# 
+ 
+   
+  Mit dem Kommando 'halt' wird ein Programm gestoppt, das am betreffenden Termi­
+  nal läuft. 
+ 
+       
+#free(1.0)# 
+ 
+Dieses Kommando ist in besonderen Fehlersituationen von Wichtigkeit. Falls Sie ein
+Programm abbrechen wollen, aber keine regulären Eingaben am Bildschirm mehr
+möglich sind, so geben Sie zunächst <SV> ein. 
+ 
+Sobald der Supervisor-Bildschirm erscheint, drücken Sie die Tasten 
+ 
+#center# <ESC> <h> (oder tippen 'halt' und drücken 'CR'). 
+ 
+____________________________________________________________________________ 
+ 
+           gib supervisor kommando: 
+           halt 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nach dieser Eingabe wird das an diesem Terminal laufende Programm unterbrochen.
+Nach dem Abbruch kommen Sie wieder auf die Monitor-Ebene (s. Teil 3). 
+#page# 
+2.3. Informationskommandos
+#free(1.0)# 
+ 
+   
+  Mit den Informationskommandos können Informationen zum System abgerufen
+  werden. 
+                                        
+#free(1.0)# 
+ 
+Die folgenden Informationskommandos können direkt an den SUPERVISOR gegeben
+werden. 
+ 
+   Terminal ankoppeln:  <SV> 
+ 
+                        <ESC> <s> 
+ 
+ 
+beziehungsweise 
+ 
+____________________________________________________________________________ 
+ 
+            gib supervisor kommando : 
+            storage info 
+ 
+____________________________________________________________________________ 
+ 
+ 
+gibt Auskunft über den belegten Speicherplatz auf dem EUMEL-Hintergrundspeicher. 
+ 
+Das Kommando: 
+ 
+ 
+____________________________________________________________________________ 
+ 
+            gib supervisor kommando : 
+            task info 
+ 
+____________________________________________________________________________ 
+ 
+ 
+gibt Auskunft über die Namen der im EUMEL-System befindlichen Tasks und die
+Struktur des Taskbaums. Verzweigungen im Taskbaum sind durch Einrückungen in
+den Ebenen des Taskbaums dargestellt. 
+ 
+ 
+Alle in dem Schema der Task-Organisation (siehe Teil 1) fettgedruckten Tasks sind
+auch auf jedem Multi-User-Sysrtem zu finden, da sie zum Betrieb nötig sind. 
+ 
+Die unterhalb von PUBLIC gelegenen Tasks werden, falls überhaupt schon vorhan­
+den, häufig nach ihrem 'Besitzer' oder der in ihnen erledigten Arbeit benannt sein. 
+ 
+#page# 
+2.4. Übersicht über Supervisor-Kommandos 
+#free(1.0)# 
+ 
+   
+  In diesem Abschnitt werden alle Supervisor- und Task-Kommandos in der
+  ELAN-Notation dargestellt. 
+                         
+#free(1.0)# 
+ 
+Die Supervisor-Kommandos entsprechen - wie alle anderen Kommandos im
+EUMEL-System - der ELAN-Syntax (Kommando-Namen werden klein geschrie­
+ben, Parameter in Klammern, mehrere Parameter durch Kommata getrennt, TEXT-
+Parameter in Anführungsstrichen usw.). 
+#free(1.0)# 
+Die ELAN-Notation 
+#free(1.0)# 
+ 
+Diese Notation dient der präzisen Beschreibung von Konstrukten der Programmier­
+sprache ELAN. Im Anschluß an die teilweise eher informelle Formulierung innerhalb
+des Kapitels folgt jedem Teil eine Kurzbeschreibung der zu diesem Themenkreis
+gehörigen Konstrukte. 
+ 
+Eine solche Beschreibung hat z.B. die Form: 
+ 
+   PROC edit (TEXT CONST dateiname) 
+ 
+Die klein geschriebenen Benennungen von Prozeduren, Parametern etc. sind hoffent­
+lich selbsterklärend, die groß geschriebenen Begriffe sind sogenannte Schlüsselworte
+und haben folgende Bedeutung: 
+ 
+OP     Operator 
+       Ein Operator bewirkt eine elementare Operation. Operatoren werden stets
+       durch Großbuchstaben oder Sonderzeichen dargestellt. 
+ 
+       Beispiel:   + ( Addition zweier Zahlen) 
+ 
+ 
+PROC   Prozedur 
+       Programm, welches unter seinem Namen aufrufbar ist, ggf. unter Anfügung
+       von Parametern. <CR> beendet die Eingabe und läßt das Programm ablaufen. 
+ 
+       Beispiel:   'edit ("dateiname")' 
+ 
+ 
+CONST  Konstante 
+       Unveränderbarer Wert. 
+ 
+ 
+VAR    Variable 
+       Veränderbarer Wert. 
+ 
+ 
+BOOL   Wahrheitswert 
+       Typ, der nur die Werte TRUE oder FALSE annnehmen kann. 
+ 
+ 
+TEXT   Text 
+       Typ, der alle Buchstaben, Sonderzeichen, aber auch Ziffern umfaßt. Eine
+       TEXT CONST ist somit eine sogenannte Zeichenkette: 
+ 
+                    "meine datei" 
+                    "$abc123(XYZ)" 
+                    "abrechnung vom 30.09.86" 
+ 
+ 
+       Eine im Editor erstellte Datei besteht ausschließlich aus TEXTen. Ein Text
+       wird in Anführungszeichen " " eingeschlossen. 
+ 
+ 
+INT    Integer 
+       Ganze Zahl. Ein INT CONST ist also irgendeine ganze Zahl. Falls beschrie­
+       ben ist: 'INT CONST zeilennr', so ist gemeint, daß an dieser Stelle die Zeilen­
+       nummer der gewünschten Zeile der Datei anzugeben ist, also '25' oder '999'. 
+ 
+ 
+REAL   Real 
+       Reelle Zahl. Eine REAL CONST bezeichnet eine Zahl mit Dezimalpunkt. 
+ 
+       PROC sin (REAL CONST x)  => sin (0.5) 
+ 
+ 
+ 
+TASK   Task 
+       Eine TASK CONST bezeichnet eine existierende Task durch einen internen
+       Task-Bezeichner. 
+ 
+ 
+ 
+THESAURUS 
+       Ein THESAURUS ist eine Liste von Namen, z.B. eine Liste von Dateinamen. 
+ 
+ 
+ 
+#page# 
+Folgende Supervisor-Kommandos stehen zur Verfügung: 
+ 
+ 
+#sy("begin 
+   PROC begin (TEXT CONST task name) 
+   Richtet eine neue Task als Sohn von PUBLIC ein. 
+ 
+   PROC begin (TEXT CONST task name, father task name) 
+   Richtet eine neue Task als Sohn der 'fathertaskname'-Task ein. 
+ 
+ 
+break 
+   PROC break 
+   Das Terminal wird vom Rechner abgekoppelt. 
+ 
+ 
+continue 
+   PROC continue (TEXT CONST task name) 
+   Eine existierende Task wird an das Terminal des Benutzers angekoppelt. 
+ 
+halt 
+   PROC halt 
+   Das laufende Programm der dem Terminal aktuell zugeordneten Task wird
+   abgebrochen. Natürlich wird die Task nicht gelöscht. 
+ 
+   Genauer: 
+   Es wird der Fehler 'halt from terminal' induziert. Normalerweise wird das
+   Programm dadurch wie durch jeden anderen Fehler abgebrochen. Genaueres
+   findet man im Systemhandbuch unter Fehlerbehandlung. 
+ 
+storage info 
+   PROC storage info 
+   Informationsprozedur über den Hintergrund-Speicher. 
+ 
+task info 
+   PROC task info 
+   Informiert über alle Tasknamen im System unter gleichzeitiger Angabe der
+   Vater/Sohn-Beziehungen durch Einrückungen. 
+
diff --git a/doc/user/benutzerhandbuch.3 b/doc/user/benutzerhandbuch.3
new file mode 100644
index 0000000..eb1c762
--- /dev/null
+++ b/doc/user/benutzerhandbuch.3
@@ -0,0 +1,2019 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Teil 3: Der Monitor    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+3 - %         GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        3 - % 
+#tableend##clearpos# 
+#end# 
+ 
+TEIL 3: Der Monitor 
+#free(1.0)# 
+#ib(9)#3.1. Der Monitor#ie(9)# 
+#free(1.0)# 
+ 
+   
+  Der Monitor nimmt die Kommandos des Benutzers entgegen, die dieser innerhalb
+  seiner Task gibt. In diesem Kapitel sind die gebräuchlichen Kommandos zur Text­
+  verarbeitung beschrieben. 
+ 
+                     
+#free(1.0)# 
+ 
+Der #ib#Monitor#ie# ist der Empfänger der Kommandos in einer EUMEL-Task. Jede Task
+und somit jeder aktive Benutzer eines EUMEL-Systems verfügt über einen eigenen
+Monitor. Halten Sie sich an dieser Stelle vor Augen:  
+#on("i")##on("b")# 
+ 
+ 
+Der SUPERVISOR ist die Task, die die Aufsicht über
+alle weiteren Tasks des EUMEL-Systems hat. 
+ 
+Der Monitor ist der Befehlsempfänger in Ihrer Task.
+Jede Task hat einen Monitor. 
+ 
+#goalpage("Mon-kdo")# 
+Der Monitor in Ihrer Task macht sich direkt bemerkbar durch die Zeile: 
+ 
+____________________________________________________________________________ 
+ 
+#ib#gib kommando#ie# : 
+____________________________________________________________________________ 
+ 
+ 
+Die Kommandos der Monitor-Ebene, die Sie an dieser Stelle eingeben können,
+lassen sich in Gruppen ordnen: 
+#on("b")# 
+ 
+ 
+Informationskommandos #off("b")# 
+ 
+     #ib#storage info#ie#                 Belegten Speicherplatz anzeigen. 
+     #ib#task info#ie#                    Im System befindliche Tasks anzeigen. 
+     #ib#task status#ie#                  Zustand der Task anzeigen. 
+ 
+ 
+#on("b")# 
+Kommandos zur Tasksteuerung #off("b")# 
+ 
+     #ib#break#ie#                        Task abkoppeln. 
+     #ib#end#ie#                          Task löschen. 
+     #ib#global manager#ie#               Task zum Manager machen, d.h. 
+                                  Sohn-Tasks können eingerichtet 
+                                  werden. 
+ 
+ 
+#on("b")# 
+Kommandos zur Dateibearbeitung #off("b")# 
+ 
+     #ib#copy#ie# ("dateiname","kopie")   Datei kopieren. 
+     #ib#edit#ie# ("dateiname")           Editor aufrufen. 
+     #ib#forget#ie# ("dateiname")         Datei löschen. 
+     #ib#list#ie#                         Dateien auflisten. 
+     #ib#rename#ie# ("dateiname","neu")   Datei umbenennen. 
+ 
+#on("b")# 
+Transport von Dateien#off("b")# 
+ 
+     #ib#fetch#ie# ("dateiname")          Datei von Vater-Task holen. 
+     #ib#erase#ie# ("dateiname")          Datei in Vater-Task löschen. 
+     #ib#save#ie# ("dateiname")           Datei zu Vater-Task senden. 
+ 
+ 
+#on("b")# 
+Archiv-Kommandos#off("b")# 
+ 
+     #ib#archive#ie# ("name")             Archivlaufwerk reservieren. 
+     #ib#fetch#ie# ("dateiname",archive)  Datei von Archiv holen. 
+     #ib#save#ie# ("dateiname",archive)   Datei auf Archiv schreiben. 
+     #ib#list (archive)#ie#               Inhalt des Archivs listen. 
+     #ib#check#ie# ("dateiname",archive)  Datei auf Lesbarkeit prüfen. 
+     #ib#clear#ie# (archive)              Archiv löschen/umbenennen. 
+     #ib#format (archive)#ie#             Archivdiskette für Benutzung 
+                                  vorbereiten. 
+ 
+#on("b")# 
+Textverarbeitung                     #off("b")# 
+ 
+     #ib#list fonts#ie#                   Nennt die eingestellten
+                                  Schrifttypen. 
+     #ib#fonttable#ie#                    Stellt die gewünschte Fonttabelle ein. 
+     #ib#lineform#ie# ("dateiname")       Zeilenweise formatieren. 
+     #ib#autoform#ie# ("dateiname")       Automatische Zeilenformatierung. 
+     #ib#pageform#ie# ("dateiname")       Seitenweise formatieren. 
+     #ib#autopageform#ie# ("dateiname")   Automatische Seitenformatierung. 
+     #ib#index#ie# ("dateiname.p")        Stichwortverzeichnis erzeugen. 
+     #ib#outline#ie# ("dateiname")        Übersicht bzw. Kurzfassung eines
+                                  Textes erstellen. 
+     #ib#print#ie# ("dateiname")          Datei drucken. 
+ 
+ 
+ 
+#on("b")# 
+Passwortschutz                     #off("b")# 
+ 
+     #ib#task password#ie# ("geheim")     Passwort für existierende Task festlegen. 
+     #ib#begin password#ie# ("geheim")    Passwort für neue Task festlegen. 
+     #ib#family password#ie# ("geheim")   Passwort für mehrere Tasks 
+                                  festlegen. 
+     #ib#enter password#ie# ("geheim")    Passwort für Datei festlegen. 
+ 
+#page# 
+3.1.1. Informationskommandos 
+#free(1.0)# 
+ 
+   
+  Mit den Informationskommandos können Informationen zur eigenen Task bzw. zum
+  gesamten System abgerufen werden. 
+                                         
+#free(0.5)# 
+ 
+Bereits von Teil 2 bekannt sind die Informationskommandos 'ESC s' und 'ESC t'. Auf
+der Monitor-Ebene ist die abkürzende Schreibweise nicht voreingestellt. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+storage info 
+ 
+____________________________________________________________________________ 
+ 
+ 
+gibt Auskunft über den belegten Speicherplatz auf dem EUMEL-Hintergrundspeicher. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+task info 
+ 
+____________________________________________________________________________ 
+ 
+ 
+gibt Auskunft über die Namen der im EUMEL-System befindlichen Tasks und die
+Struktur des Taskbaums. 
+#page# 
+Auf Monitor-Ebene kann durch zusätzliche Angabe einer Zahl zwischen 1 und 3
+Zusatzinformation angefordert werden. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+task info (2) 
+ 
+____________________________________________________________________________ 
+ 
+liefert: 
+ 
+____________________________________________________________________________ 
+26.11.86   10:10                          CPU    PRIO CHAN STATUS 
+SUPERVISOR........................... 0001:08:50   0   -   wait 
+    -................................ 0000:00:08   0   2   i/o 
+    -................................ 0000:01:45   0   -   wait 
+    SYSUR............................ 0000:01:48   0   -   wait 
+        configurator................. 0000:00:43   0   -   wait 
+        OPERATOR..................... 0000:00:03   0   -   i/o 
+            shutup dialog............ 0000:03:08   0   -   i/o 
+        ARCHIVE...................... 0000:03:03   0  31   wait 
+UR................................... 0000:00:43   0   -   wait 
+    PUBLIC........................... 0000:01:26   0   -   i/o 
+        agfa......................... 0000:00:11   0   -   i/o 
+        werner....................... 0000:06:00   0   -   -busy- 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+'task info (1)' entspricht dabei dem Kommando ohne Parameterangabe, '(2)' liefert
+zusätzlich die verbrauchte CPU-Zeit (=reine Rechenzeit), die Priorität, den Kanal
+(siehe S.#topage("Kanal")#) und den Taskstatus für jede Task des Systems. '(3)' liefert neben diesen
+Angaben auch noch den belegten Speicherplatz jeder Task. Die Ausführung von task
+info (3) ist sehr zeitaufwendig! 
+ 
+Um insbesondere den belegten Speicherplatz der eigenen Task anzusehen, aber auch
+die übrigen der oben erwähnten Angaben, benutzt man das Kommando: 
+ 
+____________________________________________________________________________ 
+ 
+      gib kommando : 
+      task status 
+ 
+24.12.86 18:30   TASK: wenni 
+ 
+Speicher: 1000K 
+CPU-Zeit: 0000.01:11 
+Zustand : -busy-, (Prio 1), Kanal 1 
+ 
+      gib kommando : 
+ 
+____________________________________________________________________________ 
+#page# 
+3.2. Tasksteuerung 
+#free(1.0)# 
+Task abkoppeln 
+#free(1.0)# 
+ 
+   
+  Mit dem Kommando 'break' wird eine Task vom Terminal abgekoppelt. 
+ 
+                                   
+#free(1.0)# 
+ 
+Durch die Eingabe des Kommandos 'break' auf Monitor-Ebene wird die Task vom
+Terminal abgekoppelt. Dieses Kommando bewirkt ansonsten keine Veränderungen. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+break 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Statt 'break' einzutippen, können Sie auch die Tastenkombination 
+ 
+#center#<ESC> <q> 
+ 
+benutzen. 
+ 
+#page# 
+ 
+Eine Manager-Task erzeugen 
+#free(1.0)# 
+ 
+   
+  Eine Task kann zum #ib#Manager#ie#, d.h. zum Kommunikationspartner anderer Tasks,
+  erklärt werden. Insbesondere zwischen Manager-Tasks und anderen, die
+  zueinander in Vater-Sohn-Beziehung stehen, ist ein einfacher Dateitransfer
+  möglich (siehe S.#topage("Dateitrans")#). 
+                           
+#free(1.0)# 
+ 
+Normalerweise werden Benutzertasks als Sohn der Task PUBLIC eingerichtet. Es
+kann jedoch wünschenswert sein, selbst eine Task-Hierarchie aufzubauen und eine
+vorhandene Task zum Vater einer oder mehrerer in Zukunft einzurichtender Tasks zu
+machen, um somit auch eine Dateihierarchie mit den benötigten Operationen zu
+erhalten. Dazu wird diese Task zum 'Manager' erklärt:#goalpage("globalmanager")# 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+global manager 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Durch das '#ib#global manager#ie#'-Kommando wird implizit ein 'break'-Kommando gege­
+ben, so daß Sie nach Eingabe dieses Kommandos wieder ein Supervisor-Kommando
+geben können. Wenn Sie nun zu irgendeinem Zeitpunkt diese (zunächst potentielle)
+Vater-Task wieder ankoppeln ('continue'-Kommando), meldet sich die Task nicht
+wie gewohnt mit 'gib kommando :', sondern mit: 
+ 
+____________________________________________________________________________ 
+ 
+maintenance : 
+ 
+____________________________________________________________________________ 
+ 
+ 
+um anzudeuten, daß es sich um eine Manager-Task handelt. 
+ 
+Um eine Sohn-Task unterhalb einer Manager-Task einzurichten, wird zur Erzeu­
+gung dieser neuen Task nicht nur der gewünschte Name, sondern auch der Name der
+Vater-Task angegeben.#u#1)#e# 
+#foot# 
+#u#1)#e# Falls keine Vater-Task angegeben wird, so ist die neue Task Sohn der
+Manager-Task 'PUBLIC'. 
+#end# 
+ 
+____________________________________________________________________________ 
+ 
+                                           Terminal 2  
+ 
+ 
+                      EUMEL Version 1.8/M 
+ 
+ 
+        gib supervisor kommando: 
+        begin("sohntask","vatertask") 
+ 
+ 
+ 
+   ESC ? --> help 
+   ESC b --> begin("")            ESC h --> halt 
+   ESC c --> continue("")         ESC s --> storage info 
+   ESC q --> break                ESC t --> task info 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+In dieser Sohn-Task können dann mit einfachen Kommandos Dateien von der
+Vater-Task geholt und zur Vater-Task geschickt werden. 
+ 
+Soll eine Task für alle anderen Tasks, nicht nur für Sohn-Tasks, des Gesamtsystems
+als Kommunikationspartner erreichbar sein, so muß diese Task als freier Manager
+deklariert werden: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+#ib#free global manager#ie# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Auf eine solche Task kann von #on("u")#jeder#off("u")# anderen Task aus zugegriffen werden, ansonsten
+gilt das für gewöhnliche Manager-Tasks gesagte. 
+#page# 
+Task löschen 
+#free(1.0)# 
+ 
+   
+  Eine Task kann mit dem '#ib#end#ie#' Kommando gelöscht werden (und mit ihr alle Daten). 
+   
+  #free(0.5)# 
+Normale Benutzertasks werden meistens zweck- oder themengebunden eingerichtet.
+Sind die Aufgaben im Zusammenhang mit einer solchen Task erledigt, so sollte die
+Task gelöscht werden, nachdem alle Daten von Bedeutung auf Diskette gesichert
+wurden. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+end 
+ 
+____________________________________________________________________________ 
+ 
+Wie bei allen Löschungen im EUMEL-System folgt eine Kontrollfrage durch den
+Monitor: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+end 
+task "taskname" löschen (j/n) ? 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nur bei der positiven Antwort wird gelöscht, alle Dateien sind unwiderruflich verlo­
+ren. Als positive Antwort auf derartige Abfragen wirken: 
+ 
+#center#<j> <J> <y> <Y> 
+ 
+<n> bzw. <N> unterdrücken die angebotene Aktion, andere Eingaben werden abgewie­
+sen. 
+ 
+#on("b")# 
+ACHTUNG:   Wird eine Manager-Task gelöscht, so werden alle Sohn- Enkel- etc.
+           Tasks ohne zusätzliche Nachfrage gelöscht, falls die Sicherheitsabfrage
+           mit 'j' beantwortet wurde.  #off("b")# 
+#page# 
+3.3. Dateibearbeitung 
+#free(1.0)# 
+Datei einrichten 
+#free(1.0)# 
+ 
+   
+  Mit dem Editoraufruf 'edit' wird eine neue Datei eingerichtet, bzw. eine existierende
+  Datei zur Bearbeitung am Bildschirm gezeigt. 
+ 
+ 
+ 
+#free(0.5)# 
+ 
+Eine Datei enthält Texte, die logisch zusammengehören und sie wird über ihren
+Namen eindeutig gekennzeichnet. 
+ 
+Das EUMEL-System speichert einmal geschriebene Texte, bis sie vom Benutzer
+gelöscht werden. In der Regel wird nicht nur ein (langer) Text oder ein Programm­
+text geschrieben, sondern mehrere und unterschiedliche. Um diese auseinanderhalten
+zu können, versehen wir sie jeweils mit einem Namen, der frei gewählt werden kann.
+Beispiele für Namen: 
+ 
+ 
+   "Brief vom 1.12.86" 
+   "1. Kapitel meines Buches" 
+ 
+ 
+Eine Sammlung von Zeichen (also im Normalfall unsere geschriebenen Texte), die mit
+einem Namen versehen worden ist, nennt man eine #ib##on("b")#Datei#ie##off("b")#. Der Editor erstellt also eine
+Datei, wenn wir einen Text schreiben. Eine Datei kann bis zu 4 000 Zeilen fassen,
+wobei jede bis zu 32 000 Zeichen lang sein darf. 
+ 
+ 
+Einrichten der ersten #ib#Datei#ie# in Ihrer Task: 
+ 
+Der erste Schritt sollte darin bestehen, daß Sie sich einen vernünftigen Dateinamen
+ausdenken. Das EUMEL-System legt Ihnen praktisch keine Beschränkungen über
+Länge oder Form des Dateinamens auf, deshalb sollten Sie sich angewöhnen, Ihre
+Dateien so zu benennen, daß Sie anhand des Namens auch nach einer Woche oder
+länger noch erahnen können, was diese Datei enthält. 
+ 
+Ein guter Name für die erste Datei wäre zum Beispiel: "meine erste Datei" oder
+"werners test vom 1.12.86". Im weiteren Text steht nur "dateiname" o. ä.. Setzen Sie
+dafür den von Ihnen gewählten Namen ein. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+edit ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+edit ("dateiname") 
+ 
+"dateiname" neu einrichten (j/n)? 
+ 
+____________________________________________________________________________ 
+ 
+Drücken Sie 'j', so wird eine neue Datei unter dem von Ihnen eingegebenen Namen
+eingerichtet. Die Datei ist zunächst leer: 
+ 
+____________________________________________________________________________ 
+ ................... dateiname .................... Zeile 1 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Welche Möglichkeiten Sie bei der Bedienung des Editors haben, können Sie in Teil 4
+nachschlagen. Schreiben Sie an dieser Stelle nur einige Worte in die Datei, anhand
+derer der Dateiinhalt wiederzuerkennen ist. Sie können die Tastatur genauso benutzen
+wie die einer Schreibmaschine. 
+ 
+____________________________________________________________________________ 
+ ................... dateiname .................... Zeile 1 
+Inhalt der ersten Datei. 1234567890 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Datei sollte an dieser Stelle wieder geschlossen werden. 
+ 
+Drücken Sie dazu <ESC> <q>. 
+ 
+Dabei ist gleichgültig, wo der Cursor steht. 
+ 
+Wiederholen Sie das Neuanlegen einer Datei mit einer zweiten Datei "anderer datein­
+ame". Bitte schreiben Sie wiederum einige Zeichen in die Datei. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+edit ("anderer dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Vorschlag zur Eingabe: 
+ 
+____________________________________________________________________________ 
+ 
+ .............. anderer dateiname ................. Zeile 1 
+Halten Sie irgendeine Taste gedrücktttttttttttttttt 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Beenden Sie die Arbeit ebenfalls mit <ESC> <q> . 
+ 
+ 
+#page# 
+Dateinamen auflisten 
+#free(1.0)# 
+ 
+   
+  Mit dem Kommando 'list' werden die Dateinamen der Dateien in der Task aus­
+  gegeben. 
+ 
+                                   
+#free(1.0)# 
+ 
+Vor jedem Dateinamen wird das Datum der letzten Bearbeitung der Datei angezeigt. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+list 
+ 
+____________________________________________________________________________ 
+ 
+bewirkt: 
+____________________________________________________________________________ 
+ 
+ ..................... list ....................... Zeile 1     
+ 
+01.08.86       "dateiname" 
+01.08.86       "anderer dateiname" 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Auch bei dieser Auflistung der Dateinamen handelt es sich um eine EUMEL-Datei
+ (allerdings um eine schreibgeschützte), die Ausgabe wird also wie gewohnt durch
+ das Kommando  <ESC> <q> beendet. 
+#page# 
+Datei duplizieren 
+#free(1.0)# 
+ 
+   
+  Mit dem Kommando 'copy' wird eine existierende Datei dupliziert. 
+ 
+                                   
+#free(1.0)# 
+ 
+Eine existierende Datei kann dupliziert werden durch das Kommando : 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+copy ("dateiname","kopiename") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Durch dieses Kommando wird eine Kopie der Datei "dateiname" unter dem Namen
+"kopiename" angelegt, der Inhalt der beiden Dateien ist zunächst identisch. Kontrol­
+lieren Sie die Richtigkeit dieser Behauptung, indem Sie nachsehen, ob der Inhalt der
+kopierten Datei gleich dem Inhalt der Ursprungsdateiname ist: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+edit ("kopiename") 
+ 
+____________________________________________________________________________ 
+#page# 
+Dateinamen ändern 
+#free(1.0)# 
+ 
+   
+  Mit dem Kommando 'rename' wird der Name einer Datei geändert. 
+ 
+                                   
+#free(1.0)# 
+ 
+Sollte Ihnen der Name einer Datei nicht gefallen, so besteht die Möglichkeit, den
+Namen zu ändern: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+rename ("dateiname","neuer dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+#page# 
+Datei löschen 
+#free(1.0)# 
+ 
+   
+  Mit dem Kommando 'forget' wird eine Datei gelöscht. 
+ 
+                                   
+#free(1.0)# 
+ 
+Das Löschen einer Datei wird durch das Kommando: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+forget ("neuer dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+eingeleitet. Aus Gründen der Sicherheit erfolgt vor der Ausführung des Kommandos
+jedoch die Abfrage: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+forget ("neuer dateiname") 
+ 
+"dateiname" löschen ? (j/n) 
+ 
+____________________________________________________________________________ 
+ 
+Als positive Antwort auf derartige Abfragen wirken: <j> <J> <y> <Y> 
+ 
+<n> bzw. <N> unterdrücken die angebotene Aktion, andere Eingaben werden abgewie­
+sen. 
+ 
+#page# 
+Dateien verschicken 
+#free(1.0)# 
+#goalpage("Dateitrans")# 
+ 
+   
+  Dateien können zur Vater-Task geschickt und von der Vater-Task geholt werden. 
+              
+#free(1.0)# 
+ 
+Die Vereinbarung, daß Dateien in einer Task lokal sind, d.h. daß nur in dieser Task
+Zugriff auf die Daten möglich ist, ist häufig zu einschränkend. So kann es zweck­
+mäßig sein, von mehreren Arbeitsplätzen (= Tasks) aus die wesentlichen Ergebnisse
+an einer zentralen Stelle zu sammeln oder Ergebnisse aus Tasks, die nur kurzzeitig
+für eine spezielle Aufgabe eingerichtet wurden, länger aufzubewahren. 
+ 
+Zu diesem Zweck wird eine Benutzertask zum Manager erklärt (siehe S.#topage("globalmanager")#) und es
+werden Söhne dieser Task eingerichtet. 
+#page# 
+Datei zur Vater-Task schicken 
+#free(1.0)# 
+ 
+   
+  Mit dem Kommando 'save' wird die Kopie einer Datei zur Vater-Task geschickt. 
+ 
+                                   
+#free(1.0)# 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+save ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+Wird eine Datei an die Vater-Task gesendet, wird eine Kopie der Ursprungsdateina­
+me unter dem Namen 'dateiname' in der Vater-Task eingerichtet. Danach sind diese
+beiden, zunächst gleichen Dateien unabhängig voneinander. Änderungen, welcher Art
+auch immer, haben keinen Einfluß auf die namensgleiche Kopie in der anderen Task. 
+ 
+Falls in der Vater-Task bereits eine Datei mit dem Namen 'dateiname' existiert, sei
+es durch Zufall oder weil bereits einmal eine 'save'-Operation durchgeführt worden
+ist, erfolgt eine Abfrage: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+save ("dateiname") 
+ 
+"dateiname" überschreiben ? (j/n) 
+ 
+____________________________________________________________________________ 
+ 
+Nur wenn die positive Eingabe 'j' erfolgt, wird die Datei in der Vater-Task durch die
+eigene Datei überschrieben. 
+#page# 
+Datei von der Vater-Task holen 
+#free(1.0)# 
+ 
+   
+  Mit dem Kommando 'fetch' wird die Kopie einer Datei von der Vater-Task geholt. 
+ 
+                                   
+#free(1.0)# 
+ 
+Entsprechend dem Versenden einer Dateikopie können Sie eine Kopie von der Vater­
+Task holen und ggf., natürlich nach Abfrage, Ihre Datei dieses Namens überschrei­
+ben. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+fetch ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+Datei in der Vater-Task löschen 
+#free(1.0)# 
+ 
+   
+  Mit dem Kommando 'erase' wird eine Datei in der Vater-Task gelöscht. 
+ 
+                                   
+#free(1.0)# 
+ 
+Soll eine Datei in der Vater-Task gelöscht werden, so kann dieses, dem 'forget'-
+Kommando analoge Kommando, in der Sohn-Task gegeben werden: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+erase ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+Falls die Datei in der Vater-Task existiert, wird sie nach Kontrollfrage gelöscht. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+erase ("dateiname") 
+"dateiname" loeschen (j/n)  j 
+ 
+gib kommando : 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+      Anm:  Die Task 'PUBLIC' ist grundsätzlich eine Manager-Task. Da Benut­
+      zer-Tasks als Sohn von '#ib#PUBLIC#ie#' eingerichtet werden, falls Sie nicht als
+      Sohn einer besonderen Manager-Task eingerichtet wurden, beziehen sich
+      'fetch'-, 'save'- und 'erase'-Kommandos auf 'PUBLIC'. 
+#page# 
+3.4. Das Archiv 
+#free(1.0)# 
+ 
+   
+  Das Archiv dient der Speicherung von Dateien auf Disketten (Sicherung). 
+                      
+#free(1.0)# 
+ 
+Das #ib#Archiv#ie# übernimmt im EUMEL-System die Verwaltung der langfristigen Daten­
+haltung. Das Archiv sollen Sie benutzen, um: 
+ 
+-  Sicherungskopien wichtiger Dateien außerhalb des Rechners zu besitzen; 
+ 
+-  nicht benötigte Dateien außerhalb einer Task zu halten (Speicherplatzersparnis!); 
+ 
+-  Dateien auf andere Rechner zu übertragen. 
+ 
+Das Archiv wird im EUMEL-System durch die Task 'ARCHIVE', die das Disketten­
+laufwerk des Rechners verwaltet, realisiert. Die Steuerung durch eine Task hat für Sie
+die erfreuliche Folge, daß die Handhabung des Archivs sich kaum von den schon
+bekannten Dateioperationen unterscheidet. In den Kommandos wird zusätzlich ange­
+geben, daß das Archiv angesprochen werden soll. 
+ 
+#page# 
+Archiv-Kommandos 
+#free(1.0)# 
+ 
+   
+  Der Arbeitsablauf bei Benutzung des Archivs besteht immer aus der Reservierung,
+  dem Lese- oder Schreibzugriff und der Freigabe des Archivs nach Ende der
+  Arbeit. Jede Arbeit mit dem Archiv beginnt mit dem Reservierungskommando. 
+ 
+   
+#free(1.0)# 
+ 
+Als ersten Schritt der Archivbenutzung müssen Sie das Archiv reservieren, das heißt
+der Verwaltung Ihres EUMEL-Systems mitteilen, daß Sie die Task 'ARCHIVE', die
+der Steuerung des Diskettenlaufwerks dient, für Ihre Task arbeiten lassen. Solange für
+Ihre Task das Archiv reserviert ist, kann keine andere Task das Archivlaufwerk benut­
+zen. 
+ 
+Für die Reservierung müssen Sie bei Benutzung einer schon vorbereiteten oder sogar
+beschriebenen Diskette den Namen dieser Archivdiskette kennen (er sollte auf dem
+Diskettenaufkleber stehen) oder vor Benutzung einer neuen Diskette einen Namen
+festlegen (und auf dem Aufkleber vermerken). Wie gewohnt gibt es keine Vorschrif­
+ten für die Namensgebung. 
+ 
+Erst nachdem Sie das Reservierungskommando gegeben haben: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+archive ("diskettenname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+sollten Sie die Diskette in das Laufwerk einschieben, um zu verhindern, daß ein
+anderer Benutzer, der das Archiv bereits für sich reserviert hat, auf Ihrer zufällig
+gleichnamigen Datei arbeitet. 
+ 
+ 
+Eine Datei wird mit dem Kommando: 
+ 
+____________________________________________________________________________ 
+ 
+save ("dateiname",archive) 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+auf eine Diskette geschrieben und mit dem Kommando: 
+ 
+____________________________________________________________________________ 
+ 
+fetch ("dateiname",archive) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+von einer Diskette geholt. 
+ 
+Das Inhaltsverzeichnis einer Diskette erhalten Sie durch: 
+ 
+____________________________________________________________________________ 
+ 
+list (archive) 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+Benutzung einer neuen Archivdiskette 
+#free(1.0)# 
+ 
+   
+  Eine neue Diskette muß für die Benutzung vorbereitet (formatiert) werden. 
+ 
+   
+ 
+#free(1.0)# 
+Vor der erstmaligen Benutzung einer Archivdiskette muß diese formatiert, d.h. in
+Spuren und Sektoren für die Positionierung des Schreib-/Lesekopfes des Disketten­
+laufwerks eingeteilt werden, um überhaupt ein Beschreiben der Diskette zu ermög­
+lichen. Die Einteilung ist geräteabhängig, häufige Formate sind: 
+ 
+              40 Spuren zu je 9 Sektoren (360 K) 
+              80 Spuren zu je 9 Sektoren (720 K). 
+ 
+Die #on("b")#Erst#off("b")#benutzung einer #ib#Archivdiskette#ie# erfordert nach der Reservierung des Archivs
+das Kommando: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+format (archive) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Erst nach einer Kontrollabfrage: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+format (archive) 
+ 
+Archiv "diskettenname" formatieren ? (j/n) 
+ 
+____________________________________________________________________________ 
+ 
+wird tatsächlich formatiert und die Diskette steht mit dem Namen "diskettenname" für
+Archivoperationen zur Verfügung. 
+ 
+#on("b")# 
+ACHTUNG:   Wird eine bereits beschriebene Diskette noch einmal formatiert, so sind
+           alle Daten, die auf der Diskette waren, verloren.#off("b")# 
+ 
+ 
+Bei einigen Rechnern ist es möglich, die Formatierung zu variieren. Falls beim Forma­
+tieren auf einem solchen Rechner ein anderes als das Standardformat erzeugt werden
+soll, so ist die Codierung des gewünschten Formats mitanzugeben. 
+ 
+ 
+Beispiel:    Für ein Gerät mit 5μ Zoll Disketten wäre z.B. einstellbar: 
+             code 0 : Standardformat 
+             code 1 : 40 Spuren 
+             code 2 : 80 Spuren 
+             code 3 : High Density 
+ 
+            'format (archive)' erzeugt ebenso wie 'format (0,archive)' eine standard­
+             formatierte Diskette, 'format (3,archive)' erzeugt eine High Density
+             Formatierung. 
+#page# 
+Diskette löschen / umbenennen 
+#free(1.0)# 
+ 
+   
+  Bereits benutzte Disketten können wieder gelöscht und auch umbenannt werden. 
+ 
+   
+#free(1.0)# 
+ 
+Falls Sie den Inhalt einer beschriebenen Archivdiskette löschen oder den Namen einer
+Diskette ändern wollen, müssen Sie das Archiv unter dem gewünschten Namen reser­
+vieren: Falls Sie den Inhalt löschen möchten, tun Sie das unter dem bisherigen und
+bestehenden Namen. Falls Sie die Diskette umbenennen wollen, reservieren Sie das
+Archiv unter dem neuen gewünschten Namen. Beachten Sie, daß durch das Umbe­
+nennen eines Archivs alle darauf befindlichen Dateien gelöscht werden. Anschließend
+geben Sie das Kommando: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+#ib#clear#ie# (archive) 
+ 
+____________________________________________________________________________ 
+ 
+Durch die Ausführung des Kommandos erhält die eingelegte Diskette den in der
+Reservierung angegebenen Namen. Das Inhaltsverzeichnis, das sich auf der Diskette
+befindet, wird gelöscht. Damit sind die Daten, die sich eventuell auf dieser Diskette
+befanden, nicht mehr auffindbar. Die Diskette entspricht einer neu formatierten Disket­
+te#u#1)#e#. #foot# 
+#u#1)#e# Das Kommando 'format' enthält implizit 'clear'. 
+#end# 
+Eine Neuformatierung ist demnach bei Wiederverwendung der Diskette nicht notwen­
+dig. 
+ 
+#page# 
+Inhaltsverzeichnis der Diskette 
+#free(1.0)# 
+ 
+   
+  Mit 'list (archive)' werden die Dateien auf der Diskette angezeigt. 
+ 
+   
+#free(1.0)# 
+ 
+Eine formatierte Diskette kann nach der Archivanmeldung gelesen oder beschrieben
+werden. Um zu sehen, welche Dateien auf der Diskette zu holen (= lesen) sind bzw.
+wieviel Platz zum Beschreiben vorhanden ist, ist es zweckmäßig, zunächst das In­
+haltsverzeichnis der Diskette zu betrachten. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+list (archive) 
+ 
+____________________________________________________________________________ 
+ 
+Beispiel: 
+ 
+____________________________________________________________________________ 
+ 
+ ............diskettenname (100 K belegt von 720 K)..............  
+ 
+01.05.86   25 K  "rechnungen april" 
+01.06.86   23 K  "rechnungen mai" 
+01.07.86   20 K  "rechnungen juni" 
+01.08.86   32 K  "rechnungen juli" 
+ 
+____________________________________________________________________________ 
+#page# 
+Lesen und Schreiben auf Diskette 
+#free(1.0)# 
+ 
+   
+  Lesen und Schreiben auf der Diskette entspricht den bekannten Operationen zum
+  Senden und Holen von Dateien. 
+ 
+   
+ 
+#free(1.0)# 
+Das Schreiben einer Datei auf Diskette entspricht dem Übersenden einer Datei an die
+Vater-Task. Einziger Unterschied ist, daß Sie das Ziel explizit angeben müssen: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+#ib#save#ie# ("dateiname",archive) 
+ 
+____________________________________________________________________________ 
+ 
+Entsprechend funktioniert auch das Lesen einer Datei von der Diskette: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+fetch ("dateiname",archive) 
+ 
+____________________________________________________________________________ 
+ 
+Wie auch bei der Kommunikation zwischen Sohn- und Vater-Task werden nur
+Kopien der Dateien geholt bzw. geschrieben. 
+#page# 
+Wechsel der Archivdiskette 
+#free(1.0)# 
+Bei Einlegen einer anderen Archivdiskette müssen Sie erneut das Kommando 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+archive ("diskettenname") 
+ 
+____________________________________________________________________________ 
+ 
+geben, da mit der Archivreservierung zugleich die Prüfung von Diskettenname und
+-Inhaltsverzeichnis vorbereitet wird. 
+#page# 
+Beenden der Archivreservierung 
+#free(1.0)# 
+ 
+   
+  Nach Benutzung Archiv freigeben! 
+ 
+   
+#free(1.0)# 
+ 
+Wenn Sie alle gewünschten Arbeiten mit dem Archiv fertiggestellt haben, geben Sie
+das Archiv wieder frei. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+#ib#release#ie# (archive) 
+ 
+____________________________________________________________________________ 
+ 
+Durch dieses Kommando kann die Task 'ARCHIVE' mit ihren Leistungen von einer
+anderen Task in Anspruch genommen werden. Falls Sie dieses Kommando nicht
+gegeben haben aber seit 5 Minuten keine Archivoperation ausgelöst haben, kann eine
+andere Task durch die Anforderung 'archive("diskettenname")' das Archiv reservieren.
+Durch diese Maßnahme wird verhindert, daß ein vergeßlicher Benutzer bei einem
+System mit mehreren Benutzern das Archiv blockiert. 
+#page# 
+Fehlermeldungen des Archivs 
+#free(1.0)# 
+ 
+   
+  Bei Archiv-Operationen kann es zu Fehlersituationen kommen. 
+   
+#free(1.0)# 
+ 
+Versucht man, eine Datei vom Archiv zu holen, kann es vorkommen, daß das Ar­
+chiv-System 
+ 
+____________________________________________________________________________ 
+ 
+#ib#Lese-Fehler (Archiv)#ie# 
+ 
+____________________________________________________________________________ 
+ 
+meldet und den Lese-Vorgang abbricht. Dies kann auftreten, wenn die Floppy
+beschädigt oder aus anderen Gründen nicht lesbar ist (z.B. nicht justierte Disket­
+ten-Geräte). In einem solchen Fall vermerkt das Archiv-System intern, daß die Datei
+nicht korrekt gelesen werden kann. Das sieht man z.B. bei 'list (archive)'. Dort ist der
+betreffende Datei-Name mit dem Zusatz 'mit Lese-Fehler' gekennzeichnet. Um
+diese Datei trotzdem zu lesen, muß man sie unter ihrem Dateinamen mit dem Zusatz
+'mit Lese-Fehler' lesen. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+fetch ("dateiname mit Lese-Fehler") 
+ 
+____________________________________________________________________________ 
+ 
+Die Datei wird in diesem Fall trotz Lese-Fehler (Informationsverlust!) vom Archiv
+gelesen. 
+ 
+Um solche Fälle möglichst zu vermeiden, sieht das EUMEL-System die Möglichkeit
+vor, Archive bzw. Archiv-Dateien nach Beschreiben zu prüfen. Das erfolgt mit dem
+Kommando 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+#ib#check#ie# ("dateiname", archive) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Durch dieses Kommando werden eventuelle Lese-Fehler gemeldet. 
+ 
+Weitere Fehlermeldungen des Archivs: 
+ 
+* Lesen unmöglich (Archiv) 
+  Die Archiv-Diskette ist nicht eingelegt oder die Tür des Laufwerks ist nicht ge­
+  schlossen. 
+=> Diskette einlegen bzw. Tür schließen. 
+ 
+* Schreiben unmöglich (Archiv) 
+  Die Diskette ist schreibgeschützt. 
+=> falls wirklich gewünscht, Schreibschutz entfernen. 
+ 
+* Archiv nicht angemeldet 
+  Das Archiv wurde nicht angemeldet 
+=> 'archive ("name")' geben. 
+ 
+* Lese-Fehler (Archiv) 
+  Siehe Lesen unmöglich 
+ 
+* Schreibfehler (Archiv) 
+  Die Diskette kann nicht (mehr) beschrieben werden. 
+=> Andere Diskette verwenden. 
+ 
+* Speicherengpass 
+  Im System ist nicht mehr genügend Platz, um eine Datei vom Archiv zu laden, ggf.
+=> ggf. Dateien löschen. 
+ 
+* RERUN bei Archiv-Zugriff Das System wurde bei einer Archiv-Operation durch
+  Ausschalten bzw. Reset unterbrochen. 
+ 
+* "dateiname" gibt es nicht 
+  Die Datei "dateiname" gibt es nicht auf dem Archiv. 
+=> mit 'list(archive)' Archiv prüfen. 
+ 
+* Archiv heißt ... 
+  Die eingelegte Diskette hat einen anderen als den eingegebenen Archivnamen. 
+=> Kommando 'archive' mit korrektem Namen geben. 
+ 
+* Archiv wird von Task ... benutzt 
+  Das Archiv wurde von einem anderen Benutzer reserviert. 
+=> Abwarten. 
+ 
+* "dateiname" kann nicht geschrieben werden (Archiv voll) 
+  Die Datei ist zu groß für die eingelegte Diskette. 
+=> Andere Diskette für diese Datei nehmen. 
+ 
+* Archiv inkonsistent 
+  Die eingelegte Diskette hat nicht die Struktur einer Archiv-Diskette. 
+=> 'format (archive)' vergessen. 
+ 
+* save/erase wegen Lese-Fehler verboten 
+  Bei Archiven mit Lese-Fehler sind Schreiboperationen verboten, weil ein Erfolg
+  nicht garantiert werden kann. 
+ 
+ 
+ 
+3.5. Kommandos für mehrere Dateien 
+#free(1.0)# 
+ 
+   
+  Durch Anwendung der besonderen Operatoren 'ALL' und 'SOME' können Sie
+  mehrere Dateien mit einem Kommando behandeln. 
+   
+ 
+#free(1.0)# 
+Oft ist es sehr zweckmäßig und erleichternd, einen Befehl für eine ganze Reihe von
+Dateien wirken zu lassen, wie z.B. beim Archivieren, wenn Sie etwa alle während des
+Tages veränderten Dateien mit deren neuen Stand auf Diskette schreiben möchten. 
+ 
+Da Tasks einen Namen haben und jede Task ein Inhaltsverzeichnis ihrer Dateien
+führt, ist es möglich, Listen von Dateien zu benennen. 
+#page# 
+Interne Tasknamen 
+#free(1.0)# 
+Wenn Sie eine andere als die eigene oder die Vater-Task ansprechen wollen, ist es
+notwendig, den 'internen Tasknamen' anzugeben. Diese auf den ersten Blick etwas
+undurchsichtige Forderung hat folgenden Hintergrund: 
+ 
+Durch die in der Einleitung vorgestellte Baumstruktur des EUMEL-Systems ist es
+ohne besondere Angaben nur möglich, Kommandos zu geben, die die eigene Task
+('edit'..) oder die Vater-Task ('save'..) betreffen. Beim Archivieren zum Beispiel wäre
+es demzufolge erforderlich, eine Datei über den Vater vom Vater vom Vater... an den
+Sohn des Sohnes... zu schicken, damit die Datei endlich in der Task 'ARCHIVE'
+landet. Statt dessen verwenden Sie eine Prozedur 'archive', die den internen Task­
+bezeichner liefert. Damit wird die gewünschte Task intern identifiziert, ohne daß Sie
+sich darum kümmern müssen. 
+ 
+Wichtige Prozeduren, die interne Taskbezeichner liefern, sind: 
+ 
+            myself           Bezeichner der eigenen Task 
+            public           Bezeichner von PUBLIC 
+            father           Bezeichner der Vater-Task#u##count##e# 
+            archive          Bezeichner von ARCHIVE 
+            printer          Bezeichner von PRINTER #foot# 
+#u##value##e# Falls kein besonderer Manager eingerichtet wurde, liefern 'father' und 'public'
+  natürlich dieselbe Task: PUBLIC. #end# 
+#page# 
+Dateiverzeichnisse 
+#free(1.0)# 
+Jede Task verfügt über ein Verzeichnis der in ihr befindlichen Dateien. Das Verzeich­
+nis Ihrer eigenen Task können Sie mit dem 'list'-Kommando betrachten. Das Ver­
+zeichnis einer anderen Task sehen Sie beispielsweise durch das Kommando 'list
+(archive)'. In diesem Fall müssen Sie dem eigentlichen Kommando den internen
+Taskbezeichner der gewünschten Task hinzugeben, um das Verzeichnis zu sehen. 
+ 
+Um ein Verzeichnis in Verbindung mit anderen Kommandos benutzen zu können, gibt
+es besondere Operatoren: 
+ 
+      #ib#ALL#ie#         liefert das gesamte Verzeichnis 
+      #ib#SOME#ie#        bietet das Verzeichnis zur Auswahl von Einträgen an. 
+ 
+ 
+In Verbindung mit einem internen Taskbezeichner wird einer der beiden Operatoren
+einem Monitor-Kommando als Parameter nachgestellt. Das Kommando wirkt dann
+nacheinander auf alle im Verzeichnis enthaltenen Dateien. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+fetch (ALL father) 
+ 
+____________________________________________________________________________ 
+ 
+Alle Dateien der Vater-Task werden nacheinander geholt, bei Namensgleichheit
+erfolgt die bekannte Kontrollfrage, ob die gleichnamige Datei in der eigenen Task
+überschrieben werden soll. 
+ 
+Falls nur einige Dateien des Verzeichnisses bearbeitet werden sollen, wird der Opera­
+tor 'SOME' dem Taskbezeichner vorangestellt: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+fetch (SOME father) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Hier wird zunächst das Dateiverzeichnis der Task angeboten. Streichen Sie alle
+Dateien, die auf der Diskette sind, aber nicht in Ihre Task geholt werden sollen, aus
+dem Verzeichnis, indem Sie 
+ 
+-  den Dateinamen mit Blanks überschreiben 
+ 
+                 oder: 
+ 
+-  die Zeile mit <HOP> <RUBOUT> löschen 
+ 
+                 oder: 
+ 
+-  mehrere Zeilen markieren, indem Sie zu Beginn des zu markierenden Bereichs
+   'mark' betätigen und mit Hilfe der Cursor-Tasten den Beereich so weit wie benö­
+   tigt ausdehnen. Im Anschluß daran können Sie diese Zeilen durch 
+ 
+                <ESC> <RUBOUT> oder 
+ 
+                <ESC> <p> 
+ 
+    löschen. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ ..............................    .......................... #markoff# 
+rechnungen april 
+rechnungen mai 
+rechnungen juni 
+rechnungen juli 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+In obigem Beispiel werden nach dem Kommando 'ESC RUBOUT' (=Löschen der
+markierten Zeilen) und dem Kommando 'ESC q' (=editieren beenden) die Dateien
+'rechnungen juni' und 'rechnungen juli' vom Archiv geholt. 
+ 
+Als weitere Vereinfachung gibt es die Prozedur 'all' als Abkürzung für 'ALL myself'. 
+ 
+Beispiel: alle Dateien auf Archivdiskette schreiben. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+save (all,archive) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Für Fortgeschrittene: 
+ 
+Sie können auch aus den Verzeichnissen mehrerer Tasks ein neues Verzeichnis
+bilden. Zu diesem Zweck sind folgende Mengenoperationen auf Verzeichnisse mög­
+lich: 
+ 
+     #ib#-#ie#  Differenzmenge 
+     #ib#+#ie#  Vereinigungsmenge 
+     #ib#/#ie#  Schnittmenge 
+ 
+Beispiel: 
+ 
+   fetch (ALL father - ALL myself) 
+ 
+Alle Dateien der Vater-Task, die noch nicht in der eigenen Task sind, werden geholt. 
+ 
+3.7. Passwortschutz 
+#free(1.0)# 
+ 
+   
+  Das EUMEL- System ermöglicht Passwortschutz für Dateien, einzelne Tasks und
+  ganze Zweige des Taskbaumes. 
+   
+#free(1.0)# 
+ 
+Falls Sie sicherstellen wollen (oder müssen), daß Teile Ihres EUMEL-Systems vor
+unberechtigter Benutzung geschützt sind, können Sie den Zugriff mit einem Passwort
+regeln. 
+ 
+Als Passwort können Sie jeden beliebigen Text nehmen. Bedenken Sie jedoch, daß
+ein wirklich wirksamer Schutz nur dann gewährleistet ist, wenn Sie weder ein triviales
+Passwort (etwa den eigenen Vornamen) auswählen, noch eines, das Sie selbst nicht
+behalten. #u##count("1")#)#e# #foot# 
+#u##value("1")#)#e# Man darf Passwörter nicht vergessen! Durch Passwörter geschützte Tasks kann
+niemand - außer durch die Angabe des korrekten Passworts - wieder ankoppeln.
+Hat man das Passwort vergessen, kann man nur noch die Task löschen. 
+#end# 
+ 
+ACHTUNG:   Es gibt ein besonderes Passwort im EUMEL-System: "-". Dieses
+           Passwort verhindert, daß die Task in der es gegeben wurde (z.B. UR), an
+           ein Terminal geholt wird, es darf folglich nicht für normale
+           Manager-Tasks gegeben werden. 
+#page# 
+Eine Task mit Passwort schützen 
+#free(1.0)# 
+Das Monitor-Kommando '#ib#task password#ie#' sorgt dafür, daß eine Task fortan nur wieder
+mit einem 'continue'-Kommando 'betreten' werden kann, wenn man vorher das
+richtige Passwort angibt. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+task password ("rosebud") 
+ 
+____________________________________________________________________________ 
+ 
+Versucht nun ein Benutzer, die mit dem Passwort geschützte Task mit dem 'conti­
+nue'-Kommando an sein Terminal anzukoppeln, wird er zunächst nach dem #ib#Pass­
+wort#ie# gefragt. Nur unter Angabe des Passworts wird die Task angekoppelt. 
+ 
+Bei der Beantwortung des Passworts werden statt der eingegebenen Zeichen Punkte
+auf den Bildschirm geschrieben. Durch Betätigen von ESC können die getippten
+Zeichen lesbar gemacht werden. 
+ 
+____________________________________________________________________________ 
+ 
+            gib supervisor kommando: 
+            continue("taskname") 
+                  Passwort: ....... 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Der Passwortschutz gewährleistet, daß kein unberechtigter Benutzer direkt an die
+Dateien und Programme der Task gelangen kann. Es gibt jedoch noch zwei Situatio­
+nen, die einen unberechtigten Zugang zu Dateien erlauben: 
+ 
+a) Dateien in die Vater-Task schicken: 
+   Transportiert man Dateien in die Vater-Task ('save'-Kommando) können Benut­
+   zer auf diese Dateien zugreifen (sofern sie Zugang zu dieser Task haben). Dies
+   kann man verhindern, indem man ein Datei-Passwort angibt. Man beachte, daß
+   das Passwort für Dateien und das oben beschriebene Passwort für Tasks nichts
+   miteinander zu tun haben. 
+ 
+b) Dateien werden in eine Sohn-Task geholt: 
+   Ist die Task als Vater-Task eingerichtet ('global manager'-Kommando), dann ist
+   es möglich, von der Sohn-Task Dateien ('fetch'-Kommando) aus der Vater-
+   Task zu holen, die mit einem Passwort geschützt ist. Darum muß man verhindern,
+   daß unberechtigte Benutzer Söhne einer mit Passwort geschützten Task einrich­
+   ten können. Das kann man mit dem Kommando 
+ 
+____________________________________________________________________________ 
+ 
+maintenance : 
+#ib#begin password#ie# ("geheim") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   Wird dieses Kommando gegeben, wird man bei dem Versuch, eine Sohn-Task
+   einzurichten, nach einem Passwort gefragt. Beachten Sie, daß das 'begin pass­
+   word' nichts mit dem Task-Passwort und Datei-Passwort zu tun hat. 
+ 
+ 
+Man kann einen ganzen Zweig eines EUMEL-Systems durch das Kommando 'family
+password' vor unberechtigtem Zugriff schützen. Das Kommando: 
+ 
+____________________________________________________________________________ 
+ 
+maintenance: 
+family password ("geheim") 
+ 
+____________________________________________________________________________ 
+ 
+wird dazu (wie gewohnt als Monitor-Kommando) in der Vater-Task des zu schüt­
+zenden Zweigs des Taskbaumes gegeben. Damit ist das Passwort aller Söhne, Enkel
+usw. dieser Task auf 'geheim' gesetzt, falls sie vorher kein Passwort oder das gleiche
+Passwort wie die aufrufende Task haben. Eine Task in diesem Zweig, die bereits ein
+eigenes, vom 'family password' verschiedenes Passwort besitzt, behält dieses eigene
+Passwort. 
+ 
+Bsp: Für 'PUBLIC' wird das Kommando '#ib#family password#ie# ("geheim")' gege­
+     ben. Dann ist das Passwort von 'PUBLIC' und aller Tasks des Benutzerzweiges
+     auf 'geheim' gesetzt. 
+ 
+ 
+Es ist zu beachten, daß bei der Vergabe des 'family password' nur die aktuellen
+Söhne der Task berücksichtigt werden. Söhne, die nach der Vergabe des 'family
+password' eingerichtet werden, sind nicht durch dieses Passwort geschützt. 
+ 
+Passwort löschen 
+ 
+ 
+Um ein Passwort zu löschen, geben Sie das Passwort-Kommando mit "" als Para­
+meter: 
+ 
+____________________________________________________________________________ 
+ 
+maintenance: 
+begin password("") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Durch diese Angabe haben Sie den Passwort einen leeren Text als Parameter gege­
+ben, der das bisherige Passwort 'überschreibt'. 
+ 
+#page# 
+Dateipasswort 
+ 
+ 
+Etwas komplizierter gestaltet sich der Passwortschutz für einzelne Dateien einer
+Manager-Task, da in dieser Anwendung eine Unterscheidung nach Schreib- und
+Leseschutz vorgenommen wird. 
+ 
+Da in dieser Anwendung nur einige Dateien der Vater-Task vor Lesen ('fetch'),
+Schreiben ('save','erase') oder beidem geschützt werden sollen, benötigt diese Proze­
+dur Angaben über Dateinamen, Schreibpasswort und Lesepasswort. 
+ 
+____________________________________________________________________________ 
+ 
+maintenance : 
+enter password ("dateiname","schreibschutz","leseschutz") 
+ 
+____________________________________________________________________________ 
+ 
+Falls die Datei nicht gegen Lesen geschützt werden soll, wird (wie beim Löschen
+eines Passworts) '""' als Lesepasswort angegeben. 
+ 
+Falls Schreiben und/oder Lesen für eine Datei gänzlich verboten#u#1)#e# sein soll, so ist
+"-" als entsprechendes Passwort anzugeben. 
+#foot# 
+1) Natürlich kann die Datei in der Manager-Task, der sie gehört, normal editiert
+   werden. 
+#end# 
+ 
+Um von einer Sohn-Task eine Datei mit Passwortschutz in der Vater-Task zu lesen
+oder zu schreiben muß vor dem 'fetch', 'save' oder 'erase' Kommando das 'enter
+password' Kommando eineggeben werden: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+enter password ("schreibpasswort/lesepasswort") 
+ 
+____________________________________________________________________________ 
+ 
+In der Sohn-Task wird also nur ein Passwort eingegeben. Falls wie oben ein '/' in
+diesem Passwort enthalten ist, wird der erste Teil vor dem '/' als Schreibpasswort und
+der zweite Teil als Lesepasswort geprüft. Falls kein '/' in dem Passwort enthalten ist,
+wird das Wort sowohl als Schreib- als auch als Lesepasswort interpretiert. 
+ 
+Beispiel: 
+In einer Manager-Task wird eine Datei "texte" eingerichtet, die Textvorlagen enthält.
+In einigen Sohn-Tasks soll diese Datei geholt (= gelesen) werden können. Die
+bearbeitete, somit veränderte Datei darf aber nicht zurück in die Vater-Task ge­
+schrieben werden. 
+ 
+In der Vater-Task:  enter password ("texte","-","psw") 
+ 
+ 
+In der Sohn-Task :  enter password ("psw") 
+ 
+ 
+Falls das Passwort in einer Sohn-Task fehlerhaft oder gar nicht eingegeben wurde,
+erscheint die Meldung : 
+ 
+____________________________________________________________________________ 
+ 
+      gib kommando : 
+      fetch ("geschützte datei") 
+FEHLER : Passwort falsch 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Somit kann diese Datei nur von Benutzern, die das Lesepasswort kennen, geholt
+werden. Ein Überschreiben der Datei ist nicht möglich, da das Schreibpasswort nicht 
+gegeben werden kann ("-" !). 
+#page# 
+3.8.  Monitor-Kommandos 
+#free(1.0)# 
+ALL 
+   THESAURUS OP ALL (TASK CONST task) 
+   Liefert einen Thesaurus#u#1)#e#, der alle Dateinamen der angegebenen Task enthält
+   (auch der Benutzer-Task 'myself'). 
+#foot# 
+1) Ein Thesaurus ist eine Liste, in diesem Zusammenhang eine Liste von Dateien.
+   (Siehe auch 2.4. Die ELAN-Notation 
+#end# 
+   fetch (ALL father) 
+ 
+   THESAURUS OP ALL (TEXT CONST datei) 
+   Liefert einen Thesaurus, der die in 'datei' vorhandenen Dateinamen (jede Zeile ein
+   Name) enthält. 
+ 
+   fetch (ALL "dateiliste") 
+ 
+archive 
+   PROC archive (TEXT CONST archivname) 
+   Anmeldung von Archiv-Operationen. 'archivname' wird zur Überprüfung für alle
+   folgenden Archiv-Operationen verwandt, um die unberechtigte Benutzung eines
+   Archivs zu verhindern. Die Anmeldung wird abgelehnt, wenn ein anderer Nutzer
+   das Archiv belegt hat. 
+ 
+ 
+   archive ("textdiskette") 
+ 
+ 
+   TASK PROC archive 
+   Liefert den internen Task-Bezeichner für die Verwendung in Dateikommandos. 
+ 
+ 
+   save ("dateiname", archive) 
+ 
+ 
+ 
+begin password 
+   PROC begin password (TEXT CONST geheim) 
+   Verhindert das unberechtigte Einrichten einer Sohn-Task. 
+ 
+ 
+   begin password("gmd") 
+ 
+ 
+break 
+   PROC break 
+   Die zum Terminal aktuell zugeordnete Task wird abgekoppelt. Sie wird damit zu
+   einer Hintergrund-Task. 
+ 
+ 
+brother 
+   TASK PROC brother (TASK CONST task) 
+   Liefert den internen Task-Bezeichner der angegebenen "Bruder"-Task. 
+ 
+ 
+   list(brother) 
+ 
+ 
+check 
+   PROC check (TEXT CONST dateiname, TASK CONST task) 
+   Überprüft, ob die Datei 'dateiname' auf dem Archiv lesbar ist. 
+ 
+ 
+   check ("meine datei", archive) 
+ 
+ 
+   PROC check (THESAURUS CONST t, TASK CONST task) 
+   Überprüft, ob die in dem Thesaurus 't' enthaltenen Dateien auf dem Archiv lesbar
+   sind. 
+ 
+ 
+   check (ALL archive, archive) 
+ 
+ 
+ 
+clear 
+   PROC clear (TASK CONST task) 
+   Löscht alle Dateien der Task 'ARCHIVE'und benennt die Diskette um, falls ein
+   anderer als der bisherige Diskettenname bei der Reservierung angegeben wurde. 
+ 
+ 
+   archive("disk1"); clear(archive) 
+ 
+ 
+copy 
+   PROC copy (TEXT CONST quelle, ziel) 
+   Kopiert die Datei 'quelle' in eine neue Datei mit dem Namen 'ziel' in der
+   Benutzer-Task. 
+ 
+ 
+   copy("datei","neue datei") 
+ 
+   Fehlerfälle: "ziel" existiert bereits 
+                "quelle" gibt es nicht 
+                 zu viele Dateien 
+ 
+ 
+edit 
+   PROC edit 
+   a) Im Monitor: 
+      Ruft den Editor mit den zuletzt verwandten Dateinamen auf. 
+   b) Im Editor: 
+      Der Dateiname wird erfragt. 
+   Für jedes 'edit' gilt: 
+   Wurde 'edit' zum ersten Mal aufgerufen, nimmt das Fenster den gesamten
+   Bildschirm ein. Bei erneutem 'edit'-Aufruf wird ein Fenster nach rechts unten ab
+   der aktuellen Cursor-Position eröffnet. 
+ 
+   PROC edit (TEXT CONST dateiname) 
+   Ruft den Editor mit 'dateiname' auf. 
+ 
+ 
+   edit("handbuch teil3") 
+ 
+ 
+ 
+   PROC edit (TEXT CONST dateiname, x, y, xbreite, yhöhe) 
+   Wie obiger 'edit'-Aufruf, jedoch kann das Fenster, in dem 'dateiname' editierbar
+   ist, gesetzt werden. Die Parameter definieren ein Editor-Fenster mit der linken
+   oberen Ecke auf den Bildschirmkoordinaten 'x' und 'y' und einer Zeilenbreite
+   'xbreite' und 'yhöhe' Zeilen. Wird der Editor mit 'edit ("dateiname")' aufgerufen,
+   wird implizit 'edit ("dateiname", 1, 1, 79, 24)' aufgerufen. 
+ 
+ 
+   edit("notiz",5,5,44,12) 
+ 
+ 
+   PROC edit (THESAURUS CONST t) 
+   Editieren aller in dem Thesaurus 't' enthaltenen Dateien nacheinander. 
+ 
+ 
+   edit (ALL father) 
+ 
+ 
+ 
+end 
+   PROC end 
+   Die zum Terminal aktuell gehörende Task wird abgebrochen und gelöscht. 
+ 
+enter password 
+   PROC enter password (TEXT CONST datei, schreibpass, lesepass) 
+   Die angegebene Datei wird mit Schreib- und Lesepassword versehen. Die
+   Passwörter werden in der eigenen Task nicht berücksichtigt. 
+   Falls der Schutz total sein soll, so ist für die verbotene Operation "-" als
+   Passwort anzugeben. 
+ 
+ 
+   enter password ("daten","sicher","heit") 
+ 
+ 
+   PROC enter password (TEXT CONST password) 
+   Gibt Schreib- und Lesepasswort für den Austausch mit Manager-Task an. Falls
+   zwei verschiedene Passwörter für Lesen und Schreiben vereinbart sind, so sind
+   sie als ein Text durch "/" getrennt einzugeben. 
+ 
+ 
+   enter password ("lese/schreibpasswort")  
+ 
+ 
+erase 
+   PROC erase (TEXT CONST datei) 
+   Löscht eine Datei mit dem Namen 'name' in der unmittelbaren Vater-Task. 
+ 
+ 
+   erase("alte datei") 
+ 
+ 
+   Fehlerfälle: 
+                "datei" gibt es nicht 
+                 Passwort falsch 
+ 
+   PROC erase (TEXT CONST name, TASK CONST manager) 
+   Löscht eine Datei mit dem Namen 'name' in der Task 'manager'. 
+ 
+ 
+   erase ("dateiname", father) 
+ 
+ 
+   PROC erase (THESAURUS CONST thesaurus) 
+   Löscht die im 'thesaurus' angegebenen Dateien in der Vater-Task. 
+ 
+ 
+   erase (ALL myself) 
+   (* löscht alle Dateien in der Vater-Task, die in der 
+    Benutzer-Task vorhanden sind *) 
+ 
+ 
+   PROC erase (THESAURUS CONST thesaurus, TASK CONST manager) 
+ 
+ 
+   erase (all,father) 
+   (* löscht alle Dateien in der Vater-Task, die in der 
+    Benutzer-Task vorhanden sind *) 
+ 
+ 
+ 
+father 
+   TASK PROC father 
+   Liefert den internen Task-Bezeichner der Vater-Task der Benutzer-Task. 
+ 
+ 
+   list(father) 
+ 
+ 
+   TASK PROC father (TASK CONST task) 
+   Liefert den internen Task-Bezeichner von 'task'. 
+ 
+ 
+   save ("dateiname", father (father)) 
+   (* Kopiert 'dateiname' zum "Großvater" *) 
+ 
+ 
+ 
+fetch 
+   PROC fetch (TEXT CONST name) 
+   Kopieren einer Datei von der Vater-Task in die Benutzer-Task 
+ 
+ 
+   fetch("sicherungskopie") 
+ 
+   Fehlerfälle: 
+               "datei" gibt es nicht 
+                Passwort falsch 
+                zu viele Dateien 
+ 
+ 
+   PROC fetch (TEXT CONST name, TASK CONST manager) 
+   Kopieren einer Datei in die Benutzer-Task von 'manager'. 
+ 
+ 
+   fetch ("dateiname", /"global") 
+ 
+ 
+   PROC fetch (THESAURUS CONST thesaurus) 
+   Holt alle im 'thesaurus' enthaltenen Dateien von der Vater-Task. 
+ 
+ 
+   fetch (ALL) 
+ 
+ 
+   PROC fetch (THESAURUS CONST thesaurus, TASK CONST manager) 
+   Zweck: Holt alle im 'thesaurus' enthaltenen Dateien von der 'manager'-Task. 
+ 
+ 
+   fetch (ALL /"global", /"global") 
+ 
+ 
+forget 
+   PROC forget (TEXT CONST datei) 
+   Löschen einer Datei mit dem Namen 'name' in der Benutzer-Task. 
+ 
+ 
+   forget ("alte datei") 
+ 
+   Fehlerfälle: 
+               "datei" gibt es nicht 
+ 
+   PROC forget (THESAURUS CONST thesaurus) 
+   Löscht die im 'thesaurus' enthaltenen Dateien in der Benutzer-Task. 
+ 
+ 
+   forget (SOME myself) 
+ 
+ 
+format 
+   PROC format (THESAURUS CONST thes) 
+   Formatieren von Disketten und Einstellen des Namens. 
+ 
+ 
+   format(archive) 
+ 
+ 
+   PROC format (INT CONST art, THESAURUS CONST thes) 
+   Formatieren von Disketten im Nichtstandardformat des benutzten Geräts 
+ 
+ 
+   format(2,archive) 
+ 
+ 
+global manager 
+   PROC global manager 
+   Durch den Aufruf der Prozedur wird die Benutzer-Task zu einem Datei-
+   Manager. Danach können Söhne dieser Task eingerichtet werden. 
+ 
+ 
+list 
+   PROC list 
+   Listet alle Dateien der Benutzer-Task mit Namen und Datum des letzten Zugriffs
+   auf dem Terminal auf. 
+ 
+   PROC list (TASK CONST task) 
+   Listet alle Dateien der angegebenen 'task' mit Namen und Datum der letzten
+   Änderung auf dem Terminal auf. 
+ 
+ 
+   list (father) 
+ 
+ 
+ 
+myself 
+   TASK PROC myself 
+   Liefert den internen Task-Bezeichner der Benutzer-Task. 
+ 
+ 
+   save (ALL myself, father) 
+ 
+ 
+ 
+public 
+   TASK PROC public 
+   Liefert den internen Task-Bezeichner von "PUBLIC". 
+ 
+ 
+   fetch ("dateiname", public) 
+ 
+ 
+ 
+rename 
+   PROC rename (TEXT CONST altername,neuername) 
+   Umbenennen einer Datei von 'altername' in 'neuername'. 
+ 
+ 
+   rename("altes handbuch","neues handbuch") 
+ 
+ 
+save 
+   PROC save (TEXT CONST dateiname) 
+   Datei 'dateiname' wird an die unmittelbare Vater-Task übertragen. 
+ 
+ 
+   save("neues handbuch") 
+ 
+ 
+   Fehlerfälle: 
+               "neues handbuch" gibt es nicht 
+                zu viele Dateien 
+                Passwort falsch 
+ 
+   PROC save (TEXT CONST name, TASK CONST task) 
+   Datei mit dem Namen 'name' in Task 'task' kopieren 
+ 
+ 
+   save ("dateiname", /"global") 
+ 
+ 
+   Fehlerfälle: 
+               "dateiname" gibt es nicht 
+                zu viele Dateien 
+                Passwort falsch 
+ 
+   PROC save (THESAURUS CONST thesaurus) 
+   Kopiert die Dateien, die in 'thesaurus' enthalten sind, in die Vater-Task. 
+ 
+ 
+   save (SOME myself) 
+ 
+ 
+   PROC save (THESAURUS CONST thesaurus, TASK CONST manager) 
+   Kopiert die Dateien, die in 'thesaurus' enthalten sind, in Task 'manager'. 
+ 
+ 
+   save(SOME myself, /"global") 
+ 
+ 
+SOME 
+   THESAURUS OP SOME (THESAURUS CONST thesaurus) 
+   Bietet den angegebenen 'thesaurus' zum Editieren an. Dabei können nicht
+   erwünschte Namen gestrichen werden. 
+ 
+   THESAURUS OP SOME (TASK CONST task) 
+   Bietet einen THESAURUS von 'task' zum Editieren an. 
+ 
+   THESAURUS OP SOME (TEXT CONST dateiname) 
+   Bietet einen 'thesaurus', der aus 'dateiname' gebildet wird, zum Editieren an. 
+ 
+ 
+task 
+   TASK PROC task (TEXT CONST task name) 
+   Liefert den internen Task-Bezeichner von 'task name'. 
+ 
+ 
+   save ("dateiname", task ("PUBLIC")) 
+                =     save ("dateiname", public) 
+ 
+ 
+ 
+storage info 
+   PROC storage info 
+   Informationsprozedur über den belegten Hintergrund-Speicher. 
+ 
+ 
+task info 
+    PROC task info 
+    Informiert über alle Tasknamen im System unter gleichzeitiger Angabe der
+    Vater/Sohn-Beziehungen (Angabe durch Einrückungen). 
+ 
+   PROC task info (INT CONST art) 
+   Informiert über alle Tasks im System. Mit 'art' kann man die Art der Zusatz-
+   Information auswählen. Für 'art' sind zur Zeit folgende Werte zugelassen: 
+ 
+   art=1: entspricht 'task info' ohne Parameter, d.h. es gibt nur die Tasknamen
+          unter Angabe der Vater/Sohn-Beziehungen aus. 
+ 
+   art=2: gibt die Tasknamen aus. Zusätzlich erhalten Sie Informationen über die
+          verbrauchte CPU-Zeit der Task, die Priorität, den Kanal, an dem die
+          Task angekoppelt ist, und den eigentlichen Taskstatus. Hierbei bedeuten: 
+ 
+          0    -busy-        Task ist aktiv. 
+          1    i/o           Task wartet auf Beendigung des Outputs oder auf
+                             Eingabe. 
+          2    wait          Task wartet auf Sendung von einer anderen Task. 
+          4    busy-blocked  Task ist rechenwillig, aber blockiert. 
+          5    i/o -blocked  Task wartet auf I/O, ist aber blockiert. 
+          6    wait-blocked  Task wartet auf Sendung, ist aber blockiert.
+                             Achtung: Die Task wird beim Eintreffen einer
+                             Sendung automatisch entblockiert. 
+ 
+    art=3: wie 2, aber zusätzlich wird der belegte Speicher angezeigt. (Achtung:
+           Prozedur ist zeitaufwendig!). 
+ 
+ 
+   task info(2) 
+ 
+ 
+task status 
+   PROC task status 
+   Informationsprozedur über den Zustand der eigenen Task. Informiert u.a. über 
+   -  Name der Task, Datum und Uhrzeit; 
+   -  verbrauchte CPU-Zeit; 
+   -  belegten Speicherplatz; 
+   -  Kanal, an den die Task angekoppelt ist; 
+   -  Zustand der Task (rechnend u.a.m.); 
+   -  Priorität. 
+ 
+   PROC task status (TASK CONST t) 
+   Wie obige Prozedur, aber über die Task mit dem internen Tasknamen 't'. 
+ 
+ 
+   task status (father) 
+ 
+ 
+ 
+task password 
+   PROC task password (TEXT CONST geheim) 
+   Einstellen eines Passworts für Benutzertask. Das Kommando 'task password' ist
+   ein Monitor-Kommando. Ist eine Task mit einem Paßwort geschützt, so wird
+   durch den Supervisor nach dem 'continue'-Kommando das Passwort angefragt.
+   Nur nach Eingabe des richtigen Passworts gelangt man in die gewünschte Task.
+   Das Passwort kann durch nochmaligen Aufruf von 'task password' geändert
+   werden, z.B. wenn es in regelmäßigen Abständen geändert werden muß, um
+   personenbezogene Daten zu schützen. 
+ 
+   Es gibt keine Möglichkeit, ein einmal eingestelltes Passwort in Erfahrung zu
+   bringen. Sollte das Passwort vergessen werden, kann somit die Task nur noch
+   gelöscht werden. 
+ 
+   Wird als Passwort ein '-'-Zeichen eingegeben, so wird verhindert, daß die
+   betreffende Task jemals wieder mit dem 'continue'-Kommando angekoppelt
+   werden kann. Dies ist z.B. für Manager-Tasks sinnvoll. 
+ 
+ 
+   task password("mein geheimnis") 
+ 
+ 
++ 
+   THESAURUS OP + (THESAURUS CONST links, rechts) 
+   Vereinigungsmenge von 'links' und 'rechts'. 
+ 
+   THESAURUS OP + (THESAURUS VAR thes, TEXT CONST name) 
+   Nimmt den TEXT 'name' in den Thesaurus 'thes' auf. 
+ 
+ 
+   save (SOME father + "rechnung", archive) 
+ 
+ 
+ 
+- 
+   THESAURUS OP - (THESAURUS CONST links, rechts) 
+   Differenzmenge von 'links' und 'rechts'. 
+ 
+   THESAURUS OP - (THESAURUS VAR thes, TEXT CONST name) 
+   Liefert einen Thesaurus aus 'thes', aber ohne den Eintrag 'name'. 
+ 
+ 
+   save (ALL myself - "rechnung", archive) 
+ 
+ 
+ 
+/ 
+   THESAURUS OP / (THESAURUS CONST links, rechts) 
+   Zweck: Schnittmenge von 'links' und 'rechts'. 
+ 
+ 
+   save(ALL myself / ALL father, archive) 
+ 
+ 
+   TASK OP / (TEXT CONST task name) 
+   Liefert aus einem Tasknamen den internen Tasknamen. '/' kann überall dort
+   eingesetzt werden, wo ein interner Taskname verlangt wird. 
+ 
+ 
+   fetch ("dateiname", /"global") 
+
diff --git a/doc/user/benutzerhandbuch.4 b/doc/user/benutzerhandbuch.4
new file mode 100644
index 0000000..c13a091
--- /dev/null
+++ b/doc/user/benutzerhandbuch.4
@@ -0,0 +1,2242 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Teil 4: Der Editor    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+4 - %     GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        4 - % 
+#tableend##clearpos# 
+#end# 
+TEIL 4: Der Editor 
+#free(1.0)# 
+ 
+4.0. Vorwort 
+ 
+#free(1.0)# 
+Mit dem #ib#EUMEL-Editor#ie# schreiben Sie alle Ihre Texte und Daten. Er bietet vielfäl­
+tige Möglichkeiten, um Autoren oder Programmierer bei dem Erstellen, Korrigieren und
+Gestalten von Manuskripten oder Programmen zu unterstützen. Die größte Hilfe beim
+Schreiben besteht (durch die Speicherfähigkeit von Computern) im beliebig häufigen
+Zugriff auf einmal geschriebene Informationen. Im Gegensatz zu einer Schreibmaschi­
+ne können Sie mit dem EUMEL-Editor (beliebig oft) Einfügungen vornehmen, Texte
+korrigieren, löschen und neu gestalten. 
+ 
+Somit ist das Schreiben von Texten mittels des EUMEL-Systems besonders dann
+vorteilhaft und zeitsparend, wenn Texte häufig geändert werden oder wenn sie in
+einer besonders schönen Form gedruckt werden sollen. Weiterhin bietet der Editor
+Hilfen zum Schreiben an, wie z.B. automatischen Wortumbruch am Zeilenende, eine
+Einrückungsautomatik, "Lernen" von Texten u.a.m. Zusätzlich kann der Editor in
+seinen Fähigkeiten erweitert und somit für spezielle Schreibarbeiten angepaßt werden.
+Aber das soll in einem späteren Kapitel beschrieben werden. 
+ 
+Bei der Entwicklung des Editors wurde besonderer Wert auf einfache Bedienung
+gelegt: innerhalb von wenigen Minuten können Sie schon Texte schreiben und Daten
+erfassen und sehen stets auf dem Bildschirm, was mit Ihrem Text passiert. Das
+Schreiben und Korrigieren werden durch einige wenige, aber leistungsstarke Funk­
+tionstasten unterstützt. 
+ 
+Einige Gestaltungsmöglichkeiten für Texte kann man nicht direkt auf dem Terminal
+"sehen", wie z.B. Proportionalschriften, Fettdruck usw. Solche Leistungen können
+durch Anweisungen an die Textkosmetik-Programme und den EUMEL-Drucker
+angefordert werden. Diese Anweisungen müssen in den Text eingefügt werden. Lesen
+Sie hierzu Teil 5 ("Textkosmetik"). 
+#free(1.0)# 
+ 
+#ib(9)#4.1.    #ib#Ein- und Ausschalten des Editors#ie##ie(9)# 
+ 
+#free("1.0")# 
+   #on("i")# 
+   Hier beschreiben wir, wie der Editor ein- und ausgeschaltet wird und wie der
+   Editor eine Datei einrichtet. 
+    
+ #off("i")##free(1.0)# 
+Wenn in Ihrer Task auf dem Bildschirm die Aufforderung 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+ 
+____________________________________________________________________________ 
+ 
+ 
+erscheint, tippen Sie 
+ 
+____________________________________________________________________________ 
+ 
+#ib#edit#ie# ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+und der EUMEL-Editor wird eingeschaltet. Ist die Datei noch nicht vorhanden, d.h.
+kein Text unter dem angegebenen Namen im System gespeichert, folgt eine Anfrage,
+ob eine Datei unter dem eingegebenen Namen neu eingerichtet werden soll: 
+ 
+____________________________________________________________________________ 
+ 
+"dateiname" neu einrichten (j/n) ? 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Dies dient zur Kontrolle von Schreibfehlern, die besonders bei ähnlichen Dateina­
+men auftreten. Man kann dann das Einrichten der Datei ablehnen, den Dateinamen
+verbessern und das Kommando erneut geben. 
+ 
+Falls Sie die Datei neu anlegen wollen, bejahen Sie diese Frage mit 
+ 
+#center##taste1(" j ")# #taste1(" J ")# #taste1(" y ")# oder #taste1(" Y ")# 
+ 
+ 
+Es erscheint ein leerer Editorbildschirm. Die oberste Zeile des Bildschirms ist die
+#ib#Titelzeile#ie#. In ihr kann nicht geschrieben werden. Sie zeigt jedoch verschiedene
+nützliche Dinge an: den Namen der Datei, die Nummer der aktuellen Zeile, in der
+gerade geschrieben wird, Tabulatormarken, Einfügemodus, Lernmodus, Auftrennung
+usw. 
+ 
+____________________________________________________________________________ 
+ 
+ ................. dateiname ...................... Zeile 1     
+_ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+In unserem Fall haben Sie eine neue Datei angelegt. Sie enthält noch keinen Text. In
+der Titelzeile sind jedoch schon der Name der Datei und die aktuelle Zeilennummer
+eingetragen. Bei einer neuen Datei ist der Bildschirm unterhalb der Titelzeile leer.
+Dieser Teil dient als "Schreibfläche". Der #ib#Cursor#ie# steht dann direkt unter der Titelzei­
+le. Er zeigt immer die aktuelle #ib# Schreibposition#ie# an. Jetzt kann sofort mit dem Schrei­
+ben begonnen werden, ganz wie mit einer normalen Schreibmaschine. 
+ 
+Rufen Sie eine Datei auf, in die Sie schon Text geschrieben haben, zeigt Ihnen der
+Editor das zuletzt bearbeitete Textstück und Sie können normal weiter schreiben. 
+ 
+Wollen Sie die #ib#Schreibarbeit beenden#ie# und den #ib#Editor ausschalten#ie#, so drücken Sie die
+beiden Tasten 
+ 
+<ESC> <q> 
+ 
+nacheinander. Es erscheint 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+ 
+____________________________________________________________________________ 
+ 
+ 
+und Sie haben damit den #ib#Editor verlassen#ie# und befinden sich wieder im Monitor. #page# 
+ 
+#ib(9)#4.2.    Die wichtigsten Tasten des Editors#ie(9)# 
+#free(1.0)# 
+#ib(9)#4.2.1.   Das #ib#Tastenfeld#ie##ie(9)# 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Auf dem Tastenfeld gibt es einige Tasten, die auf einer Schreibmaschine nicht vor­
+   handen sind. 
+    
+ #off("i")# 
+#free(1.0)# 
+Das Tastenfeld eines EUMEL-Terminals entspricht weitgehend dem einer Schreib­
+maschine. Sie finden also die Buchstaben a-z und die Ziffern 0-9 auf Tasten. Mit
+der #ib#SHIFT-Taste#ie# (Umschalttaste) und gleichzeitigem Drücken einer anderen Taste
+können Sie die großen Buchstaben und eine Reihe von speziellen anderen Zeichen,
+die #ib#Sonderzeichen#ie# genannt werden, schreiben. Die "Zwischenraumtaste" oder Leer­
+taste erzeugt immer ein Leerzeichen. 
+ 
+Nun gibt es in der Praxis zwei unterschiedliche Tastaturen. Zum einen existiert die
+#ib#EDV-Tastatur#ie#, die zum Schreiben von Programmen benutzt wird. Sie erkennt man
+daran, daß keine #ib#Umlaute#ie# (ä, ö, ü) und kein ß auf den Tasten abgebildet sind. Dafür
+gibt es Tasten für eckige und geschweifte Klammern. Sollen auf einer solchen Tasta­
+tur die Umlaute geschrieben werden, muß man sich eines Tricks bedienen: mit der
+Taste ESC und nachfolgendem Betätigen einer anderen Taste (z.B. a, o, u) erhalten
+wir den entsprechenden Umlaut. 
+ 
+In der Regel kann man die Umlaute auf dem Bildschirm eines solchen EDV-Ter­
+minals nicht sehen, sondern sie erscheinen als "a", "u", usw. Beim Druck eines
+Textes werden sie aber richtig dargestellt. 
+ 
+Die andere Tastatur entspricht in der #ib#Tastenbelegung#ie# weitgehend einer deutschen
+Schreibmaschine und besitzt Tasten für die Umlaute und ß. Sollen vorwiegend deut­
+sche Texte geschrieben werden, empfiehlt es sich, solch ein Terminal zu verwenden. 
+ 
+ 
+ 
+      Tastatur 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+                                                               
+ 
+ 
+ 
+Neben diesen "einfachen" Tasten gibt es die Funktionstasten, die zur Bedienung des
+Editors (aber auch anderer Programme) notwendig sind. Wo die Tasten auf Ihrem
+Gerät liegen, hängt von dem jeweiligen Gerätetyp ab. Die Wirkung der Tasten
+erklären wir in den anschließenden Abschnitten. #count("1")#) #foot# 
+#value("1")#) Es kann sein, daß die Tasten nicht richtig beschriftet sind. Die Installations­
+   anleitung muß dann die Entsprechungen beschreiben. Zusätzlich zu den im
+   folgenden beschriebenen können sich noch weitere Tasten auf Ihrem Terminal
+   befinden, die aber standardmäßig keine besondere Bedeutung für den Editor
+   haben. 
+#end# 
+#page# 
+Die Funktionstasten des EUMEL-Systems 
+#l pos (0.0)##l pos(4.0)# 
+ 
+ 
+<,>,v,^                       Positionierungstasten 
+#table# 
+#free(0.5)# 
+<SHIFT>           Umschalttaste 
+#free(0.5)# 
+<CR>              Eingabe-/ Absatztaste 
+#free(0.5)# 
+<HOP>             Verstärkertaste 
+#free(0.5)# 
+<RUBOUT>          Löschtaste 
+#free(0.5)# 
+<RUBIN>           Einfügetaste 
+#free(0.5)# 
+<TAB>             Tabulatortaste 
+#free(0.5)# 
+<MARK>            Markiertaste 
+#free(0.5)# 
+<ESC>             Kommandotaste 
+#free(0.5)# 
+<SV>              Supervisortaste 
+#free(0.5)# 
+<STOP>            Stoptaste 
+#free(0.5)# 
+<WEITER>          Weitertaste 
+#tableend##clear pos# 
+ 
+ 
+#page# 
+Die Wirkung der Funktionstasten 
+#free(0.5)# 
+<SHIFT> 
+ 
+#ib#Umschalttaste#ie# 
+ 
+Wird diese Taste gleichzeitig mit einer anderen betätigt, so wird ein Buchstabe in
+Großschreibung, bei den übrigen Tasten das obere Zeichen, ausgegeben. So wird z.B.
+anstelle der "9" das Zeichen ")" ausgegeben. 
+#free(1.5)# 
+<CNTL> 
+ 
+#ib#Kontroll-/Steuertaste#ie# 
+ 
+Mit dieser Taste in Kombination mit Zusatztasten können Sonderfunktionen des
+Systems angewählt werden. Für EUMEL sind folgende drei Tastenkombinationen
+(wobei die Tasten gleichzeitig betätigt werden müssen) wichtig: 
+ 
+<CTRL> <a>    Anhalten der Bildschirmausgabe 
+ 
+<CTRL> <b>    Wirkung der SV-Taste (bei jedem Rechner) 
+ 
+<CTRL> <c>    Bildschirmausgabe fortführen 
+#l pos (0.0)##l pos(4.0)# 
+ 
+ 
+#free(1.5)# 
+<CR> 
+ 
+#ib#Eingabetaste / Absatztaste#ie#, Carriage Return, kurz: 'CR' 
+ 
+Diese Taste wird im Editor betätigt, um das Ende eines Absatzes zu kennzeichnen.
+Die kontinuierliche Fließtexteingabe wird durch sie unterbrochen und es wird an den
+Beginn der nächsten Zeile positioniert. Einrückungen werden beibehalten. Eine Ab­
+satzmarke ist im Editor an der Inversmarkierung am rechten Bildschirmrand zu erken­
+nen. 
+ 
+Die 'CR'-Taste ist oft mit einem geknicktem Pfeil nach links gekennzeichnet. Im
+Kommandomodus (also bei "gib kommando :") wird durch Betätigung dieser Taste ein
+gegebenes Kommando ausgeführt. 
+ 
+Die sonstige Benutzung dieser Taste außerhalb des Editors wird in der jeweiligen
+Anwendung beschrieben, z.B. Bestätigung eines Trennvorschlags bei der Silbentren­
+nung. 
+ 
+<, >, v, ^ 
+ 
+Tasten für die Positionierung 
+ 
+#ib#Positionierung des Cursors#ie# um eine Spalten-/Zeilenposition in die jeweilige Richtung. 
+#free(1.5)# 
+<HOP> 
+ 
+"#ib#Verstärkertaste#ie#"; wird als Vorschalttaste bedient. 
+ 
+In Kombination mit anderen Funktionstasten wird deren Wirkung verstärkt. (vgl.
+4-#topage("HOP")#) 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+ 
+<HOP> <v> 
+ 
+Steht der Cursor nicht am unteren Bildrand, so wird er dorthin positioniert. Steht er
+am unteren Bildrand, so wird um einen Bildschirminhalt "weitergeblättert". 
+ 
+Auch die Funktionen 'RUBIN'/'RUBOUT' werden in Kombination mit der HOP-Taste
+verstärkt.(vgl. 4-#topage("verstärkt")#ff) #free(1.5)# 
+<RUBOUT> 
+ 
+#ib#Löschtaste#ie# 
+ 
+Das Zeichen, auf dem der Cursor steht, wird gelöscht. Wenn der Cursor hinter dem
+letzten Zeichen einer Zeile steht, wie bei fortlaufender Eingabe üblich, wird das letzte
+Zeichen gelöscht. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ...................... Zeile 4     
+ 
+Mit der RUBOUT-Taste ist es möglich, ein 
+Zeichen nach dem anderen auf dem Bildschirm 
+zu löschen. Steht der Cursor auf einem 
+Zeichen, das irrtümlicherweise eingetipp?t 
+wurde, kann dieses durch einmaliges 
+Betätigen der RUBOUT-Taste aus der Datei 
+gelöscht werden. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nach Betätigen der  <RUBOUT> - Taste: 
+ 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ...................... Zeile 4     
+ 
+Mit der RUBOUT-Taste ist es möglich, ein 
+Zeichen nach dem anderen auf dem Bildschirm 
+zu löschen. Steht der Cursor auf einem 
+Zeichen, das irrtümlicherweise eingetippt 
+wurde, kann dieses durch einmaliges 
+Betätigen der RUBOUT-Taste aus der Datei 
+gelöscht werden. 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+ 
+ 
+<RUBIN> 
+ 
+#ib#Ein- bzw. Ausschalten des Einfügemodus.#ie# 
+ 
+Das Betätigen der Taste schaltet in den Einfügemodus.Der Zustand wird durch das
+Wort "RUBIN" im linken Drittel der Titelzeile der Datei angezeigt. Vor dem Zeichen,
+auf dem der Cursor steht, wird eingefügt. Nochmaliges Betätigen der Taste schaltet
+den Einfügemodus aus. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ...................... Zeile 5     
+ 
+Das Betätigen der Taste schaltet in den 
+Einfügemodus. Der Zustand wird durch das 
+Wort "RUBIN" im linken Drittel der Titelzeile 
+angezeigt. Vor dem Zeichen, auf dem der 
+Cursor steht, wird ' ' eingefügt. 
+Nochmaliges Betätigen der Taste schaltet den 
+Einfügemodus aus. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Nach Betätigen der  <RUBIN> - Taste und Einfügen des Wortes " jetzt":  
+ 
+____________________________________________________________________________ 
+ .......RUBIN...... dateiname .....................
+Zeile 5     
+Das Betätigen der Taste schaltet in den 
+Einfügemodus. Der Zustand wird durch das 
+Wort "RUBIN" im linken Drittel der Titelzeile 
+angezeigt. Vor dem Zeichen, auf dem der 
+Cursor steht, wird jetzt ' ' eingefügt. 
+Nochmaliges Betätigen der Taste schaltet den 
+Einfügemodus aus. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+<TAB> 
+ 
+#ib#Tabulatortaste#ie# 
+ 
+Betätigen Sie die 'TAB'-Taste, um vom linken Bildschirmrand auf den Textbeginn in
+der Zeile bzw. eine Tabellenspalte zu positionieren. Erneutes Betätigen der 'TAB'-
+Taste positioniert den Cursor auf die nächste eingestellte Tabulator-Position. Die
+eingestellten Tabulatorpositionen erkennen Sie an den Tabulatorzeichen (Dachzei­
+chen) in der obersten Bildschirmzeile. 
+ 
+Wenn keine TABs gesetzt sind, werden die beiden Schreibgrenzen, linker Bildschirm­
+rand und Ende der Zeile, als #on("i")#voreingestellte# #off("i")# TABs angesehen. 
+#free(1.5)# 
+<MARK> 
+ 
+#ib#Ein- bzw. Ausschalten der Markierung#ie#. 
+ 
+Bei Betätigung dieser Taste wird in einen speziellen #ib#Markierzustand#ie# geschaltet. Alles,
+was Sie jetzt schreiben bzw. durch Bewegen des Cursors in Richtung Dateiende
+kennzeichnen, steht als #on("i")#markierter# #off("i")# Bereich für die Bearbeitung zur Verfügung. Zur
+besseren Sichtbarkeit wird der markierte Bereich invers zum übrigen Text dargestellt. 
+ 
+Wird der Cursor in eine Richtung bewegt, wird das gesamte Textstück zwischen
+Einschaltpunkt der Markierung und aktueller Cursorposition markiert. Rückwärtsbewe­
+gungen des Cursors verkürzen den markierten Bereich wieder. 
+ 
+Einen derart markierten Bereich können Sie nun z.B. duplizieren, verschieben, lö­
+schen, durchsuchen oder weiterverarbeiten. (vgl. 4- #topage("mark")# ff). 
+ 
+Durch erneutes Betätigen der MARK-Taste schalten Sie den Markier-Zustand auch
+wieder aus. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+Sie wollen einen Textteil markieren, um ihn an eine andere Stelle zu verschieben
+(evtl. um ihn an dieser Stelle später zu löschen): 
+ 
+Sie positionieren den Cursor auf den Beginn des Textteils, gehen in den Markierzu­
+stand durch Betätigen der MARK-Taste und führen nun den Cursor mit Hilfe der
+Positioniertasten bis zum Ende des zu markierenden Bereichs. 
+ 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ...................... Zeile 5     
+ 
+Mit dem Cursor positionieren Sie an die 
+Stelle, ab der markiert werden soll und 
+betätigen die MARK-Taste. Nun führen Sie den 
+Cursor bis zu der Stelle, bis zu der 
+markiert werden soll. Der markierte Text wird 
+normalerweise "schwarz auf weiss" 
+dargestellt.  
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Mit weiteren Kommandos (vgl. ESC-Taste und Kommando-Verarbeitung, 4- #topage("ESC")#)
+kann der Bereich nun bearbeitet werden. 
+#free(1.5)# 
+<ESC> 
+ 
+#ib#Kommandotaste#ie# 
+ 
+Mit der ESC-Taste in Kombination mit einer Folgetaste können Sie vordefinierte
+Aktionen anwählen. Es gibt Aktionen, die vorprogrammiert zur Verfügung stehen, und
+Sie selbst können weitere hinzufügen. (vgl. 4-#topage("ESC")# ) #free(1.5)# 
+<SV> 
+ 
+#ib#SUPERVISOR-Taste im Mehrbenutzer-Betrieb#ie# 
+ 
+Betätigen Sie diese Taste im Editor, dann unterbrechen Sie Ihre Editierarbeit und
+erhalten die Meldung 
+ 
+____________________________________________________________________________ 
+ 
+                                           Terminal 2  
+ 
+ 
+                      EUMEL Version 1.8/M 
+ 
+ 
+            gib supervisor kommando: 
+ 
+ 
+ 
+ 
+   ESC ? --> help 
+   ESC b --> begin("")            ESC h --> halt 
+   ESC c --> continue("")         ESC s --> storage info 
+   ESC q --> break                ESC t --> task info 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Wollen Sie nun im Editor fortfahren bzw. haben Sie irrtümlich die SV-Taste betätigt,
+dann geben Sie das Kommando 
+ 
+____________________________________________________________________________ 
+ 
+          gib supervisor kommmando : 
+          continue ("Sekretariat") 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+(falls Ihre Task, in der Sie arbeiteten, wirklich "Sekretariat" hieß!) 
+ 
+Um Ihren in Bearbeitung befindlichen Text wieder vollständig auf dem Bildschirm zu
+sehen, betätigen die die Tasten 
+ 
+<ESC> <b> 
+ 
+Sie sind wieder an der Stelle, an der Sie den Text mit der SV-Taste verlassen ha­
+ben, und können normal weiterarbeiten. 
+ 
+#on("u")#Achtung:#off("u")# Die SV-Taste kann, je nach Terminal, durch das Betätigen von zwei
+Tasten gleichzeitig realisiert sein (oft 'CTRL b'). Beachten Sie die Beschreibung Ihrer
+Tastatur! 
+#free(1.5)# 
+<STOP> 
+ 
+#ib#Unterbrechen einer Ausgabe#ie# (oft auch als CTRL a realisiert). 
+ 
+Haben Sie diese Taste aus Versehen betätigt, erkennen Sie dies daran, daß der
+Editor nicht "reagiert". Betätigen Sie die WEITER-Taste (oft auch CTRL c). 
+#free(1.5)# 
+<WEITER> 
+ 
+Unterbrochene Ausgabe fortsetzen. 
+ 
+Ein mit der STOP-Taste angehaltene Ausgabe können Sie durch Betätigen der
+#ib#WEITER-Taste#ie# fortsetzen. 
+ 
+ 
+#on("u")#VORSICHT:#off("u")# Die STOP-Taste unterbricht nur die Ausgabe auf den Bildschirm.
+Zeichen, die während des STOP eingegeben werden, werden gespeichert und nach
+'WEITER' ausgegeben! 
+ 
+ 
+#page# 
+4.2.2   Speicherung von Texten
+#free(1.0)# 
+   #on("i")# 
+   In diesem Abschnitt wird der Begriff "Datei" erklärt und es wird erläutert, wie
+   unterschiedliche Texte auseinandergehalten werden können. 
+   ## #off("i")# 
+ 
+ 
+ 
+Das EUMEL-System speichert einmal geschriebene Texte, bis sie vom Benutzer
+gelöscht werden. In der Regel wird nicht nur ein (langer) Text oder ein Programm
+geschrieben, sondern mehrere und unterschiedliche. Um diese auseinanderhalten zu
+können, versehen wir sie jeweils mit einem Namen, der frei gewählt werden kann.
+Beispiele für Namen: 
+ 
+ 
+   "Brief vom 1.12.86" 
+   "1. Kapitel meines Buches" 
+ 
+ 
+Eine Sammlung von Zeichen (also im Normalfall unsere geschriebenen Texte), die mit
+einem Namen versehen worden ist, nennt man eine #ib##on("bold")#Datei#ie##off("bold")#. Der Editor erstellt also eine
+Datei, wenn wir einen Text schreiben. Eine Datei kann bis zu 4 000 Zeilen fassen,
+wobei jede Zeile bis zu 32 000 Zeichen lang sein darf. Das Produkt aus der Anzahl
+der Zeilen und den Zeichen pro Zeile kann z.Zt. jedoch 1 000 000 Zeichen (=1MB)
+nicht übersteigen. #page# 
+ 
+#ib(9)#4.2.3.   #ib#Schreiben von Texten#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Texte werden fortlaufend geschrieben. Absätze werden durch die CR-Taste
+   markiert. 
+   # #off("i")# 
+ 
+#free(0.8)# 
+ 
+Nach dieser etwas langen Vorrede können wir endlich losschreiben. Wird ein Zeichen
+geschrieben, rückt der #ib#Cursor#ie# automatisch nach rechts auf die nächste Schreibstelle.
+Durch den automatischen #ib#Wortumbruch#ie# werden angefangene Worte, die über ein
+Zeilenende hinausgehen würden, ohne Silbentrennung in die nächste Zeile gebracht.
+#u##count("6")#)#e# 
+#foot# 
+#u##value("6")#)#e# Nehmen Sie bitte keine Silbentrennung "per Hand" vor. Eingebrachte Trenn­
+   striche gelten als Bindestrich und bleiben somit auch bei Umformatierungen
+   erhalten, was unerwünscht ist. Für diese mühevolle Aufgabe gibt es in der Text­
+   verarbeitung ein Programm! 
+#end# 
+ 
+Die 'CR'-Taste (bei einer Schreibmaschine bedeutet sie "Wagenrücklauf") braucht
+also nur noch betätigt zu werden, wenn eine Zeile vorzeitig beendet werden soll, d.h.
+bei einem #ib#Absatz#ie# oder einer #ib#Leerzeile#ie#. Der Cursor wird dabei an den Anfang der
+nächsten Zeile positioniert. Gleichzeitig erscheint in der vorherigen Zeile am rechten
+Rand des Bildschirms eine Markierung, die anzeigt, daß hier ein Absatz gemacht
+wurde. 
+ 
+Darum ist das Betätigen der 'CR'-Taste bei Tabellenzeilen und Programmtexten
+besonders wichtig, denn hier soll ja jede Zeile separat bleiben. Sie wirkt nur hinter
+dem letzten Zeichen. 
+ 
+Der Editor ist auf das Schreiben von "normalen" Texten eingestellt. Bei normalen
+Texten soll ein Wort, welches über das Ende einer Zeile gehen würde, automatisch in
+die nächste Zeile gebracht werden. Diese Funktion wird "Wortumbruch" genannt. 
+ 
+Ist kein Wortumbruch erwünscht, zum Beispiel bei der Beschreibung von Program­
+men, so geben Sie, bevor Sie den Editor aufrufen, im Monitor das Kommando 
+ 
+____________________________________________________________________________ 
+gib kommando : 
+#ib#word wrap (false)#ie# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Der Wortumbruch kann durch das Kommando 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando : 
+#ib#word wrap (true)#ie# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+wieder eingeschaltet werden. Der Editor ist standardmäßig auf "Wortumbruch" einge­
+stellt und Sie sollten nur in Ausnahmefällen diese Benutzungsart ausschalten. 
+ 
+Ein Bildschirm faßt (neben der Titelzeile) üblicherweise 23 Zeilen, die mit Text be­
+schrieben werden können. Ist die letzte Zeile voll und muß eine neue Zeile begonnen
+werden, "rutscht" der Bildschirminhalt automatisch um eine Zeile nach oben. Damit
+ist Platz für eine Leerzeile, die nun ebenfalls beschrieben werden kann, usw. Keine
+Angst: die so verschwundenen Zeilen sind natürlich nicht "weg". Da ein Bildschirm
+immer nur eine beschränkte Anzahl von Zeilen hat, kann der Editor nur einen Aus­
+schnitt aus der Datei zeigen. 
+#page# 
+Einrückungen 
+#free(1.0)# 
+   #on("i")# 
+   Die #ib#Einrückungautomatik#ie# erlaubt bei fortlaufendem Schreiben, die Einrückung zu
+   erhalten. 
+   # #off("i")# 
+#free(0.5)# 
+Soll ein Text eingerückt werden, so betätigt man entsprechend oft die Leertaste. Die
+in dieser Zeile geschriebene Einrückung wird automatisch in den folgenden Zeilen
+beibehalten, bis sie durch die Cursor-Positionierungstasten wieder aufgehoben wird. 
+ 
+#on("u")#Beispiele für Aufzählungen:#off("u")# Einrückung funktioniert automatisch ohne aktive Eingabe
+von Leerschritten. 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ...................... Zeile 1     
+                            -  Der erste Typ der Aufzählungsform
+                               ist die #ib#Aufzählung#ie# durch Voran­
+                               stellen eines Sondersymbols. 
+                               Als Sondersymbole sind die beiden
+                               Zeichen "-" und "*" zugelassen. An
+                               ihnen erkennt der Editor eine
+                               Aufzählung. 
+ 
+                             12. Weiterhin können Aufzählungen
+                                 durch Begriffe, gefolgt von
+                                 einem Punkt oder einer ")", als
+                                 #ib#Aufzählungskriterium#ie# verwendet
+                                 werden. 
+ 
+ 
+                             Aufzählung: Auch diese Möglichkeit
+                                         steht Ihnen zur Verfü­
+                                         gung. Der Editor er­
+                                         kennt, daß Sie hier
+                                         einen Begriff erläutern
+                                         wollen. 
+ 
+____________________________________________________________________________ 
+ 
+#page# 
+Wann werden nun Aufzählungen vom Editor erkannt? 
+ 
+Die hier aufgeführten Einzelheiten sollte nur der hieran interessierte Anfänger lesen! 
+ 
+Wenn die Einrückung nicht funktionieren sollte, prüfen Sie die folgenden Punkte, die
+für das Einrücken erfüllt sein müssen: 
+ 
+1) Die Vorgängerzeile hat eine Absatzmarke. 
+ 
+   Wichtig: Innerhalb eines Aufzählungspunktes schaltet die Absatztaste die Aufzäh­
+            lungseinrückung aus! 
+ 
+2) "*" bzw. "-" und mindestes ein Leerzeichen sind die ersten Zeichen in der
+   Zeile. 
+ 
+3) "." bzw. ")" und mindestens ein Leerzeichen nach höchstens sieben Zeichen sind
+   die ersten Zeichen in der Zeile. 
+ 
+4) ":" und mindestens ein Leerzeichen nach höchstens 19 Zeichen sind die ersten
+   Zeichen in der Zeile. 
+#page# 
+ 
+#ib(9)#4.2.4.   #ib#Positionieren#ie# im Text#ie(9)# 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Um Korrekturen (Überschreiben, Löschen oder Einfügen) vorzunehmen, muß der
+   #ib#Cursor#ie#, der die aktuelle Schreibposition anzeigt, bewegt werden können. Bei
+   längeren Texten ist es möglich, den Cursor auch auf Zeilen zu positionieren, die
+   (noch nicht) auf dem Bildschirm angezeigt werden. Somit zeigt der Editor nicht nur
+   immer das Ende einer Datei, sondern einen beliebigen Ausschnitt, der auf dem
+   Bildschirm im sogenannten '#ib#Fenster#ie#' sichtbar ist. 
+    #off("i")# 
+#free(1.0)# 
+Ist eine Korrektur notwendig, positionieren Sie den Cursor auf die Stelle, an der die
+Korrektur vorgenommen werden soll. Dazu verwenden Sie die #ib#Positionierungstasten#ie#
+LINKS, RECHTS, OBEN und UNTEN. LINKS und RECHTS bewegen den Cursor
+innerhalb einer Zeile. Stößt man mit RECHTS an das Ende einer Zeile, wird der
+Cursor an den Anfang der nachfolgenden Zeile bewegt. 
+ 
+             v              ^ 
+ 
+Ein #ib#Zeilenwechsel#ie# kann einfacher mit den Tasten OBEN und UNTEN vorgenommen
+werden. Die Taste OBEN bewegt den Cursor eine Zeile nach oben, die Taste UNTEN
+entsprechend eine Zeile tiefer. 
+ 
+Was passiert nun, wenn Sie den unteren oder den oberen Rand des Bildschirms
+erreicht haben, und Sie positionieren darüber hinaus? In diesem Fall wird der Text
+zeilenweise nach oben oder nach unten verschoben und es erscheint die gewünschte
+Zeile, wobei am anderen Rand einige verschwinden". Wir sehen also, daß wir mit den
+Positionierungstasten den Bildschirm als Fenster über die Datei hinweggleiten lassen
+können. Den Text selbst können wir uns auf einem langen Band geschrieben vorstel­
+len. Die #ib#Zeilennummer#ie#, die die Position des Cursors angibt, wird stets in der Titel­
+zeile angezeigt. 
+ 
+Vermeiden Sie es, den Cursor über das Textende hinaus nach unten laufen zu las­
+sen. Sie verlängern dadurch Ihren Text um Leerzeilen, die Sie beim Weiterschrei­
+ben nicht auffüllen, sondern vor sich herschieben. 
+ 
+Innerhalb einer Zeile ist es etwas anders: Positionieren wir bei einer Zeile, die breiter
+als der Bildschirm ist, nach rechts, wird nicht das Fenster verschoben, sondern die
+Zeile 'gerollt'.(vgl. Sie hierzu das Verschieben des Gesamtfensters mit dem 'mar­
+gin'-Kommando 4-#topage("margin")#) 
+4.2.5.   Korrigieren im Text 
+#free(1.0)# 
+ 
+   #on("i")# 
+   Einfache Korrekturen können durch #ib#Überschreiben von Zeichen#ie#, #ib#Löschen von
+   Zeichen#ie# und #ib#Einfügen von Zeichen#ie# vorgenommen werden. 
+    
+   #off("i")# 
+#free(1.0)# 
+<RUBOUT> 
+ 
+Die einfachste Möglichkeit der Korrektur ist das #ib#Überschreiben#ie#. Soll z.B. ein Zeichen
+durch ein anderes ersetzt werden, so positioniert man der Cursor genau über dieses
+und tippt das richtige Zeichen ein. Das kann natürlich auch mit mehreren Zeichen
+nacheinander erfolgen. 
+ 
+Korrekturen können Sie gleich beim Schreiben vornehmen, indem Sie die zuletzt
+geschriebenen Zeichen mit der #ib#RUBOUT-Taste#ie# löschen. Häufig bemerkt man aber
+#ib#Schreibfehler#ie# erst etwas später, so daß man diese Fehler nicht so leicht korrigieren
+kann. Für solche Zwecke müssen Sie den Cursor an die Textstelle bewegen, an der
+korrigiert werden soll. 
+ 
+Wollen Sie ein #ib#Zeichen löschen#ie#, so positionieren Sie den Cursor auf dieses Zeichen
+und betätigen die Taste #ib#RUBOUT#ie#. Das Zeichen verschwindet und die Restzeile rückt
+heran. Sollen mehrere Zeichen gelöscht werden, muß die RUBOUT-Taste entspre­
+chend oft gedrückt werden. 
+ 
+Steht der Cursor hinter dem letzten Zeichen der Zeile, wird immer das letzte Zeichen
+der Zeile gelöscht. Man kann also mit dieser Eigenschaft eine Zeile "von hinten
+wegradieren".(vgl. hierzu auch 4- #topage("ESC RUBOUT")#) 
+ 
+ 
+ 
+<RUBIN> 
+ 
+Fehlende Zeichen können Sie genauso einfach einfügen. Sie bringen den Cursor auf
+das Zeichen, vor das eingefügt werden soll. Dann drücken Sie die Taste #ib#RUBIN#ie#. Der
+Editor gelangt in den #ib#Einfügemodus#ie#, was in der Titelzeile durch RUBIN angezeigt
+wird. Er fügt alle Zeichen ein, die jetzt getippt werden (anstatt zu überschreiben). Der
+Teil der Zeile rechts vom Cursor rückt jeweils um entsprechend viele Stellen nach
+rechts. 
+ 
+Wichtig ist, daß im RUBIN-Modus der Editor genauso funktioniert wie im Normalzu­
+stand (natürlich mit der Ausnahme, daß eingefügt statt überschrieben wird). 
+ 
+Im eingeschalteten RUBIN-Modus können keine Zeichen verloren gehen. Viele
+Benutzer lassen darum den RUBIN-Modus immer eingeschaltet, um sich vor einem
+unbeabsichtigten Überschreiben von Texten zu schützen. Sie korrigieren, indem Sie
+die Verbesserung einfügen und den alten Text löschen. 
+ 
+Durch erneutes Betätigen der RUBIN-Taste beenden Sie den Einfügemodus. Die
+RUBIN-Taste wirkt wie ein Schalter, der den Einfügemodus ein- und ausschaltet.
+Allerdings können Sie nur so viele Zeichen in eine Zeile einfügen, bis das letzte Wort
+der Zeile an das Zeilenende stößt. Das letzte Wort wird am Anfang der folgenden
+Zeile eingefügt, sofern dort noch Platz ist und es sich nicht offensichtlich um die
+letzte Zeile eines Absatzes handelt. Andernfalls wird automatisch eine neue Zeile für
+das angefangene Wort eingefügt.(vgl. Sie hierzu auch 4- #topage("ESC RUBIN")#) #free(1.5)# 
+#page# 
+Springen und Zeilen einfügen/löschen 
+#free(1.0)# 
+   #on("i")# 
+   Bewegungen des Cursors sind mit den Positionierungstasten bei größeren "Ab­
+   ständen" etwas mühsam, ebenso bei umfangreichen Löschungen und Einfügun­
+   gen. Die "#ib#Verstärkertaste#ie#" HOP ermöglicht es, diese Operationen auf einfache
+   Weise zu beschleunigen. Mit der #ib#HOP-Taste#ie# kann man das Fenster über der
+   Datei nicht nur zeilenweise, sondern auch um jeweils eine Fensterlänge verschie­
+   ben. Das nennt man #ib#Blättern#ie#. 
+    
+   #off("i")# 
+#free(1.0)# 
+#goalpage("HOP")# 
+Wird die HOP-Taste vor einer anderen der schon erklärten Funktionstasten gedrückt,
+verstärkt sie deren Wirkung. Die HOP-Taste ist eine "Präfix"-Taste: sie wird vor
+(und nicht gleichzeitig mit, wie z.B. die Umschalttaste SHIFT) einer anderen Taste ge­
+drückt. Zuerst das springende Positionieren: 
+#free(1.0)# 
+<HOP> <>> 
+ 
+#ib#Sprung an das rechte Bildschirmende#ie#. 
+ 
+Falls die Zeile länger als das Fenster breit ist, wird die Zeile um eine Fensterbreite
+nach links verschoben. 
+#free(1.0)# 
+<HOP> <<> 
+ 
+#ib#Sprung an den Bildschirmrand links#ie# (ggf. seitlich blätternd). 
+#free(1.0)# 
+<HOP> <^> 
+ 
+#ib#Sprung auf die erste Zeile des Bildschirms#ie#. 
+ 
+Nochmaliges Betätigen dieser Tastenkombination positioniert den Cursor (und damit
+das Fenster in der Datei) um ein Fenster zurück. ("Blättern") 
+#free(1.0)# 
+<HOP> <v> 
+ 
+#ib#Sprung auf die letzte Zeile des Bildschirms#ie#. 
+ 
+Das Blättern erfolgt analog HOP OBEN. 
+#free(1.0)# 
+<HOP> <CR> 
+ 
+Positioniert das Fenster so, daß die aktuelle Zeile zur ersten des Fensters wird. 
+#free(1.0)# 
+<HOP> <RUBIN> 
+ 
+#ib#Einfügen von Textpassagen#ie#. #goalpage("verstärkt")# Die HOP-Taste in Verbindung mit RUBIN und
+RUBOUT wird zum "verstärkten" Löschen und Einfügen verwendet. 
+ 
+Ab der aktuellen Position des Cursors "verschwindet" der restliche Text. Es kann wie
+bei der anfänglichen Texteingabe fortgefahren werden. Die Anzeige '#ib#REST#ie#' in der
+Titelzeile erinnert daran, daß noch ein Resttext existiert. Dieser erscheint nach einem
+neuerlichen Betätigen der beiden Tasten HOP RUBIN wieder auf dem Bildschirm (die
+Anzeige 'REST' verschwindet dann wieder). 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ...................... Zeile 4     
+ 
+In diesem Text soll vor dem zweiten Satz  
+etwas eingefügt werden. #cursor("H")#ierzu wird der 
+Cursor an die Position geführt, an der  
+ein beliebiger Text eingefügt werden soll. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nach Betätigen der Tasten   <HOP>   und   <RUBIN>   sieht der Bildschirm wie folgt
+aus: 
+ 
+____________________________________________________________________________ 
+ ............... dateiname .........REST.......... Zeile 4     
+ 
+In diesem Text soll vor dem zweiten Satz  
+etwas eingefügt werden. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Nun kann beliebig viel Text eingefügt werden. Nochmaliges Betätigen von HOP und
+RUBIN führt den Text-Rest wieder bündig heran. 
+ 
+ 
+<HOP>  <RUBOUT> 
+ 
+Löscht die Zeile ab Cursor-Position bis Zeilenende. 
+ 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ...................... Zeile 4     
+ 
+Soll eine ganze Zeile oder ein Textrest  
+gelöscht werden, so positioniert man an die  
+Stelle, ab der gelöscht werden soll. 'R'est löschen.... 
+Nach HOP RUBOUT ist der Zeilenrest gelöscht. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nach Betätigen der Tasten   <HOP>   und   <RUBOUT>   sieht der Bildschirm wie
+folgt aus: 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ...................... Zeile 4     
+ 
+Soll eine ganze Zeile oder ein Textrest  
+gelöscht werden, so positioniert man an die  
+Stelle, ab der gelöscht werden soll. 
+Nach HOP RUBOUT ist der Zeilenrest gelöscht. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Steht der Cursor am Zeilenanfang, wird nach HOP RUBOUT dementsprechend die
+ganze Zeile gelöscht und die Lücke durch Nachrücken der Folgezeilen geschlossen
+(HOP RUBOUT betätigen). 
+#page# 
+Zeilen aufbrechen und Rückumbruch 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Um grössere Textpassagen einzufügen, betätigt man #ib#HOP RUBIN#ie# nacheinander.
+   Diese Tastenfolge kann benutzt werden, um eine Zeile bzw. eine längere Textpas­
+   sage aufzubrechen). #ib#HOP RUBOUT#ie# am Ende einer Zeile macht einen #ib#Rückum­
+   bruch#ie#. 
+                          
+ #off("i")# 
+#free(1.0)# 
+<HOP>  <RUBIN> 
+ 
+Wie bereits beschrieben, bewirkt #ib#HOP RUBIN#ie# in einer Zeile, daß der Zeilenrest rechts
+des Cursors und alle Zeilen unterhalb der aktuellen Zeile scheinbar verschwinden.
+#ib#REST#ie# in der Titelzeile erinnert daran, daß ein Teil der Datei nicht sichtbar ist. 
+ 
+Wird unmittelbar nach HOP RUBIN wiederum HOP RUBIN betätigt, wird der vorherige
+Zeilenrest als eigenständige Zeile dargestellt. Es ist damit eine Aufspaltung einer Zeile
+in zwei Zeilen vollzogen. 
+ 
+ 
+<HOP>  <RUBOUT> 
+ 
+Der umgekehrte Fall, nämlich zwei Zeilen zu einer zusammenzufassen (sog. #ib# Rück­
+umbruch#ie#), ist durch #ib#HOP RUBOUT#ie# hinter dem letzten Zeichen einer Zeile möglich.
+Hinter das letzte Zeichen einer Zeile kann einfach mit dem Tabulator positioniert
+werden. 
+ 
+Das Aufbrechen einer Zeile und der Rückumbruch zusammen angewandt stellen den
+ursprünglichen Zustand wieder her. Beispiel: Mit HOP RUBIN bricht man eine Zeile
+auf, der Rest der Zeile und nachfolgende Zeilen verschwinden vom Bildschirm. Erneu­
+tes HOP RUBIN stellt den rechten Zeilenteil auf der nächsten Zeile und die nachfol­
+genden Zeilen auf dem Bildschirm wieder dar. Da der Cursor sich noch immer am
+rechten Rand der aufgebrochenen Zeile befindet, kann man mit HOP RUBOUT den
+ursprünglichen rechten Zeilenteil wieder rekombinieren. 
+#page# 
+ 
+ 
+#ib(9)#4.2.6.   Der #ib#Tabulator#ie##ie(9)# 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Eine weitere wichtige #ib#Positionierungshilfe#ie# innerhalb einer Zeile ist die #ib#TAB#ie#-Taste.
+   Sie wird u.a. zum Schreiben von Tabellen benötigt. Wie bei einer Schreibmaschine
+   können #ib#Tabulatormarken#ie# gesetzt bzw. gelöscht werden. 
+                
+ #off("i")# 
+#free(1.0)# 
+<TAB> 
+ 
+Der Tabulator hat eine wichtige Funktion für das schnelle Positionieren, auch wenn
+keine Marken eingestellt wurden. #ib#Voreingestellte Tabulatormarken#ie# sind nämlich der
+Textanfang einer Zeile (Einrückung, falls vorhanden) und die Stelle direkt hinter dem
+letzten Zeichen der Zeile. Betätigt man also die Taste TAB, dann springt die Schreib­
+marke an die nächste dieser voreingestellten Positionen. So kann man schnell mit
+dem Cursor an den Anfang oder das Ende einer Zeile gelangen (und z.B. am Zeilen­
+ende Zeichen "von hinten" löschen oder dort weiterschreiben). 
+ 
+<HOP>  <TAB> 
+ 
+Nun zum #ib#Setzen des Tabulators#ie#: Sie setzen ihn, indem Sie den Cursor auf die Zei­
+lenposition bringen, in der die Marke plaziert werden soll. Hier betätigen Sie nun #ib#HOP
+TAB#ie#. Die Tabulatorsetzung kann man in der Titelzeile an einer Markierung ("Dach­
+"-Zeichen) sehen, falls sie im Fensterbereich ist und die aktuelle Zeile nicht seitlich
+verschoben ist. Betätigt man nun an irgendeiner Position innerhalb einer Zeile die
+TAB-Taste, wird der Cursor auf die Position der nächsten Tabulatormarkierung (die
+sich rechts von dem Cursor befindet) oder eine der voreingestellten Positionen be­
+wegt. 
+ 
+#ib#Gesetzte Tabulatormarken#ie# können gelöscht werden, indem man mit der TAB-Taste
+die Position der Tabulatormarke einstellt und dann HOP TAB betätigt. Die Marke ist
+dann gelöscht, das Dach verschwindet in der Titelzeile. 
+ 
+Tabulatormarkierungen hinterlassen keine Spuren in der Datei, sondern dienen nur als
+Positionierungshilfen. mit 'HOP TAB' gesetzte Markierungen, die mit 'TAB' ange­
+sprungen werden, wirken beim Schreiben von Zahlen wie Dezimaltabulatoren, vgl. Sie
+dazu 4- #topage("zahlen")#. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+Es soll für den Textbeginn eine Tabulatorposition auf die 12. Spalte gesetzt werden.
+Hierzu wird der Cursor auf die 12. Spalte positioniert und die HOP- und die TAB-
+Taste nacheinander betätigt. Das "Dach"-Zeichen erscheint in der 12. Spalte in der
+Titelzeile und von nun an kann durch Betätigen der TAB-Taste diese Position direkt
+angesteuert werden. 
+ 
+____________________________________________________________________________ 
+ ..........^....... dateiname ...................... Zeile 4     
+ 
+HOP TAB wurde in der 12. Spalte betätigt.  
+           Mit TAB stehen Sie auf der 12.  
+           Spalte. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Werden #ib#Tabulatormarken#ie# gesetzt (HOP TAB), gelten die voreingestellten Tabulator­
+marken (Anfang und Ende einer Zeile) nicht mehr. Dies ist z.B. bei dem Schreiben
+von Tabellen notwendig. Andererseits möchte man beim Schreiben von "normalem"
+Text wieder die voreingestellten Tabulatormarken bedienen können. Mit den Tasten 
+ 
+<ESC> <TAB> 
+ 
+kann man die gesetzten Tabulatormarken (erkenntlich an dem "Dach"-Zeichen in
+der Kopfzeile) vorübergehend verschwinden lassen. Dann gelten wieder die voreinge­
+stellten Marken. Erneutes #ib#ESC TAB#ie# stellt die gesetzten Tabulatormarken wieder her
+usw.. 
+#free(1.5)# 
+Zahlentabellen schreiben: Dezimaltabulator 
+#goalpage("zahlen")# 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Beim Schreiben von #ib#Zahlentabellen#ie# sollen die Zahlen oft rechtsbündig im Text
+   erscheinen. Dazu bietet der Editor den #ib#Dezimaltabulator#ie# an. 
+               
+ #off("i")# 
+#free(1.0)# 
+Für jede Zahlenkolonne wird die gewünschte Position der Einerstelle (also der letzten
+Stelle) mit Hilfe eines Tabulators eingestellt. Mit #ib#TAB#ie# wird der Cursor zur jeweils
+nächsten Tabulatormarke vorgerückt. Werden nun Ziffern geschrieben, so schreibt
+man nicht - wie gewohnt - nach rechts, sondern die Ziffern werden nach links
+eingerückt. Etwas genauer: Beim Drücken einer Zifferntaste wird, solange links vor
+der Zahl noch ein Blank, eine Zahl, "+", "-" oder ein Punkt sichtbar ist, diese
+gelöscht und die hierdurch neu entstandene Ziffernfolge rechtsbündig an der Tabula­
+torposition geschrieben. Das Schreiben von rechtsbündigen Zahlenkolonnen ist so
+leicht möglich #count("11")#): 
+#foot# 
+#value("11")#) Wird eine #ib#Proportionalschrift#ie# (Schrift, bei der die Zeichen unterschiedliche
+   Breiten haben) verwendet, sollte man zwischen den einzelnen Zahlenkolonnen
+   mindestens zwei Leerzeichen schreiben. Andernfalls bekommt man - auf Grund
+   der unterschiedlicher Zeichenbreiten - keine rechtsbündigen Kolonnen gedruckt. 
+#end# 
+ 
+ 
+         12           12345,78 
+          1               0,23 
+      12345            1234,00 
+ 
+ 
+ 
+Es gibt somit vier nützliche Automatiken: neben dem automatischen Dezimaltabulator
+den Wortumbruch, die Einrückautomatik und die Zeileneinfügeautomatik beim ein­
+fügenden Schreiben. 
+4.2.7.   Lernen im Editor
+ 
+#free(1.0)# 
+    
+   Beliebige Folgen von Tastenbetätigungen können gelernt und Tasten zugeordnet
+   werden. Das ist sinnvoll, wenn Sie wiederholt immer die gleichen Tastenbetä­
+   tigungen ausführen müssen, wie z.B. in Tabellenzeilen etwas einfügen oder wenn
+   des öfteren gleiche Texte geschrieben werden müssen, wie z.B. ein Absender,
+   Grußformeln usw. 
+            #goalpage("ESC")# 
+           #free(1.0)# 
+< ESC>  <HOP> 
+ 
+Der #ib#Lernmodus#ie# wird durch Betätigen der Tasten #ib#ESC HOP#ie# eingeschaltet, es erscheint
+#ib#LEARN#ie# als Kontrolle rechts in der Titelzeile). Alle Tastenanschläge werden jetzt bis
+zum Ausschalten des Lernmodus gelernt. Auch Tastenanschläge wie 'CR'), so daß
+man kann demnach auch mehrere Zeilen lernen lassen kann. 
+ 
+<ESC>  <HOP>  <'taste'>     z.B. ESC HOP j 
+ 
+Das Beenden oder Ausschalten des Lernmodus erfolgt durch Drücken der drei Tasten
+#ib#ESC HOP 'taste'#ie#. Dabei wird die gelernte Tastenanschlagsfolge, auch #ib#Lernsequenz#ie#
+genannt, der Taste 'taste' zugeordnet. 
+ 
+<ESC>  <'taste'>     z.B. ESC j 
+ 
+Durch späteres Betätigen der Tastenfolge ESC 'taste' kann der gelernte Text an jeder
+Stelle der Datei geschrieben werden. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+Ein Sachbearbeiter hat jeden Tag 50 mal die Worte 'Gesellschaft für Datenverarbei­
+tung' zu tippen. Er läßt den Editor diese Worte lernen mit 
+ 
+ 
+ESC HOP Gesellschaft für Datenverarbeitung ESC HOP m  
+ 
+Die Worte liegen jetzt auf der Taste 'm'. Wird 'm' gedrückt, erscheint ein 'm' auf dem
+Bildschirm. Mit ESC 'm' erscheinen die obigen Worte. ESC ist also notwendig, um
+das normale 'm' von der Lernsequenz zu unterscheiden. 
+ 
+Welche Tasten dürfen zum #ib#Lernen#ie# belegt werden? Alle Tasten, außer 
+ 
+-  vom System benutzte Tasten, wie SV, CTRL; 
+-  vom Editor (je nach Anwendung) vorbelegte Tasten, wie die Tasten q oder ESC
+   und HOP; 
+-  durch Programmierung (siehe dieses Kapitel) fest belegte Tasten. 
+ 
+Praktische Tips: Man sollte die Tastatur nicht mit Lernsequenzen überlasten, weil man
+sich zu viele Tasten nicht merken kann. Besser ist es, einige wenige Tasten fest zu
+belegen und andere für momentane Aufgaben einzusetzen. 
+ 
+Der Einsatz von #ib#Lernsequenz#ie#en ist besonders sinnvoll für das Schreiben von Text­
+kosmetikanweisungen. Anweisungen wie z.B. 'Unterstreichen einschalten', Schrift­
+typ-Anweisungen usw. werden zweckmäßigerweise auf Tasten gelegt. 
+ 
+Hat man sich einmal beim '#ib#Lernen#ie#' verschrieben, so ist das nicht weiter schlimm: es
+kann ohne Bedenken korrigiert werden (z.B. mit der Taste RUBOUT). Solche Tasten­
+anschläge werden dann allerdings auch gelernt, was aber bei der Benutzung der
+Lernsequenzen keine Bedeutung hat. 
+4.2.8.   Textabschnitte durch Markieren bearbeiten 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Oft ergibt sich die Notwendigkeit, mehrere Zeilen oder ganze Textpassagen zu
+   löschen oder zu verschieben. Hierbei hilft die Taste #ib#MARK#ie#, mit der man #ib#Texte
+   markieren#ie# (also kennzeichnen) kann. Die so markierten Texte können dann auf
+   verschiedene Weisen als Ganzes verarbeitet werden. 
+               #goalpage("ESC")# 
+  
+  #free(1.0)# 
+<MARK> 
+ 
+Durch Drücken der Taste MARK wird die #ib#Markierung#ie# eingeschaltet und - bei erneu­
+ter Betätigung - wieder ausgeschaltet. Der Anfang der Markierung wird "festgehal­
+ten" und man kann nun das Markierende durch die Positionierungstasten und die
+HOP-Taste in Richtung auf das Dateiende verschieben, wobei die dazwischen lie­
+genden Zeichen markiert (in der Regel "schwarz auf weißem Grund" dargestellt)
+werden. 
+ 
+ 
+<ESC>  <RUBOUT> 
+ 
+Ein so markierter Text kann mit #ib#ESC RUBOUT#ie# gelöscht werden. #ib#Markieren und
+löschen#ie# mit ESC RUBOUT ist eine bequeme und sichere Löschmethode, da man
+genau sieht, was gelöscht wird.#goalpage("ESC RUBOUT")# 
+ 
+ 
+<ESC>  <RUBIN> 
+#goalpage("ESC RUBIN")# 
+ 
+Der gelöschte Abschnitt ist aber nicht vollständig gelöscht, sondern er kann an ande­
+rer (oder an der gleichen) Stelle im Text durch #ib#ESC RUBIN#ie# wieder eingefügt werden.
+Der vorsichtig gelöschte Text landet in einem #ib#Zwischenspeicher#ie# und kann bei Bedarf
+mit #ib#ESC RUBIN#ie# wieder aufgerufen werden. Wird erneut vorsichtig gelöscht, so wird
+der letzte Text des Zwischenspeichers überschrieben. Im Zwischenspeicher ist nur für
+einen #on("u")#Text#off("u")# Platz. Auf diese Art kann ein Textabschnitt beliebiger Länge an eine
+andere Stelle des Textes sicher, schnell und bequem verschoben werden. Zusätzlich
+ist die nachträgliche Korrektur von fehlerhaften Löschungen möglich, weil der Text
+wieder mit ESC RUBIN reproduziert werden kann. 
+ 
+Mit eingeschalteter Markierung kann auch geschrieben werden. Das #ib#markierende
+Schreiben#ie# ist eine besonders vorsichtige Art der Texterstellung, denn der Textein­
+schub bleibt erst durch Ausschalten der Markierung (MARK) wirklich bestehen. Er
+kann wieder gelöscht (ESC RUBOUT) und an eine andere Stelle gebracht werden
+(ESC RUBIN). Beim markierenden Schreiben wirkt RUBOUT immer auf das Zeichen
+vor der Cursorposition. 
+ 
+Hinweis: Positionierungen sind nur innerhalb der Markierung möglich. 
+#page# 
+4.2.9.   Der Fenstereditor 
+#free(1.0)# 
+ 
+   #on("i")# 
+   Oft ist es notwendig, mit mehreren Dateien gleichzeitig zu arbeiten, z.B. wenn aus
+   einer Datei etwas in eine andere kopiert werden muß, wenn Fehler durch die
+   Textkosmetik-Programme oder einen Compiler gefunden werden oder wenn man
+   kurz etwas in einer anderen Datei nachschauen will. Zu diesem Zweck bietet der
+   Editor die Möglichkeit, zwei (oder mehr) Dateien zur gleichen Zeit zu bearbeiten. #off("i")# 
+               
+ 
+#free(1.0)# 
+Der Editor ermöglicht dem Benutzer wie durch ein Fenster auf den zu bearbeitenden
+Text zu schauen. Es ist in diesem Zusammenhang nur natürlich, daß man bei der
+Bearbeitung eines Textes sich die Möglichkeit wünscht, weitere Texte gleichzeitig
+ansehen zu können. Dies kann notwendig sein, um zu vergleichen, Fehler zu entdek­
+ken oder Textteile aus einem Fenster in ein anderes zu übertragen. 
+ 
+Um ein neues Editor-Fenster zu "öffnen", betätigt man im Editor 
+ 
+<ESC>  <e> 
+ 
+Betätigt man ESC e ungefähr in der Mitte des Bildschirms, hat man das Fenster auf
+die neue Datei in der unteren Hälfte des Bildschirms und die "alte" Datei in der
+oberen Bildschirmhälfte. Zunächst wird der Dateiname erfragt. Nach dessen Eingabe
+und dem Betätigen der 'CR' Taste wird ein Fenster auf eine andere Datei eröffnet.
+Die obere linke Ecke des Fensters befindet sich an der aktuellen Cursor-Position.
+Dabei darf sich der Cursor nicht zu sehr am rechten oder unteren Rand befinden, weil
+das Fenster sonst zu klein würde. In diesem "Fenster" kann man dann genauso
+arbeiten wie im "normalen" Editor. 
+ 
+ 
+Mit der Tastenfolge 
+ 
+<ESC>  <w> 
+ 
+wechselt man von einem Fenster (zyklisch) in das benachbarte. Es gibt eine Hier­
+archie zwischen den Fenstern in der Reihenfolge, in der eines im anderen einge­
+richtet worden ist. Gibt man 
+ 
+<ESC>  <q> 
+ 
+in einem Fenster, so verschwindet dieses und alle darin eingeschachtelten Fenster,
+und man befindet sich im übergeordneten Fenster. 
+ 
+Wir schilderten zuvor, daß man mit ESC RUBOUT und ESC RUBIN Texte verschie­
+ben und löschen kann. Zwischen Dateien im Fenstereditor geht dies folgendermaßen: 
+ 
+Durch 
+ 
+<ESC>  <p>    oder     <ESC>  <d> 
+ 
+schreibt man einen markierten Teil in eine temporäre Datei (einen Zwischenspeicher);
+durch ESC p wird ein markierter Text aus der Ursprungsdatei entfernt und in einen
+Zwischenspeicher geschrieben. Im Gegensatz dazu wird er durch ESC d kopiert.
+Durch 
+ 
+<ESC>  <g> 
+ 
+fügt man ihn in eine andere (oder dieselbe) Datei ein. Im Unterschied zu ESC RUBIN
+wird die temporäre Datei dadurch nicht entleert. 
+ 
+Die Funktionen ESC d und ESC g leisten auf schnellere Weise dasselbe wie die
+Kommandos 'PUT ""' und 'GET ""'. 
+#page# 
+4.2.10.  Die wichtigsten vorbelegten Tasten 
+#free(1.0)# 
+ 
+      #on ("i")#
+   Lernsequenzen und Kommandos (d.h. ELAN-Programme) können Tasten zuge­
+   ordnet werden. Da einige Funktionen häufig benötigt werden, sind diese stan­
+   dardmäßig bestimmten Tasten zugeordnet. #off("i")# 
+            
+ 
+ 
+#free(1.0)# 
+#ib#ESC q#ie#          Verlassen des Editors bzw. der eingeschachtelten Fenster. 
+ 
+#ib#ESC e#ie#          Weiteres Editorfenster einschalten. 
+ 
+#ib#ESC n#ie#          Notizbuch "aufschlagen". 
+ 
+#ib#ESC v#ie#          Dateifenster auf ganzen Bildschirm vergrößern 
+               bzw. Bildschirm rekonstruieren (eingeschachteltes Fenster verlas­
+               sen). 
+ 
+#ib#ESC w#ie#          Dateiwechsel beim Fenstereditor. 
+ 
+#ib#ESC f#ie#          Nochmalige Ausführung des letzten Kommandos. 
+ 
+#ib#ESC b#ie#          Das Fenster wird auf den linken Rand der aktuellen (ggf. verscho­
+               benen) Zeile gesetzt. 
+ 
+ESC  >         Zum nächsten Wortanfang. 
+ 
+ESC  <         Zum vorherigen Wortanfang. 
+ 
+#ib#ESC 1#ie#          Zum Anfang der Datei. 
+ 
+#ib#ESC 9#ie#          Zum Ende der Datei. 
+#page# 
+Lernen 
+ 
+ 
+#ib#ESC HOP#ie#        Lernen einschalten. 
+ 
+#ib#ESC HOP taste#ie#  Lernen ausschalten und Lernsequenz auf 'taste' legen. 
+ 
+#ib#ESC HOP HOP#ie#    Gelerntes vergessen. Bedingung ist, daß man die Lernsequenz in
+               der Task löscht, in der man sie hat lernen lassen. 
+#free(1.0)# 
+Operationen auf Markierungen 
+ 
+#free(1.0)# 
+#ib#ESC RUBOUT#ie#     Markiertes "vorsichtig" löschen. 
+ 
+#ib#ESC RUBIN#ie#      Vorsichtig mit ESC RUBOUT Gelöschtes einfügen. 
+ 
+#ib#ESC p#ie#          Markiertes löschen und in die Notiz-Datei schreiben. Kann mit ESC
+               g an anderer Stelle reproduziert werden. 
+ 
+#ib#ESC d#ie#          Duplizieren: 
+               Markiertes in die Notiz-Datei kopieren (PUT ""), anschließend die
+               Markierung abschalten. Kann mit ESC g beliebig oft reproduziert
+               werden. 
+ 
+#ib#ESC g#ie#          MIT ESC p gelöschten oder mit ESC d duplizierten Text an aktuelle
+               Cursor-Stelle schreiben, d.h. Notiz-Datei an aktueller Stelle einfü­
+               gen (GET ""). 
+#free(1.0)# 
+#on("b")#Zeichen schreiben#u#1#e# 
+#off("b")# 
+#foot# 
+1) Diese Tasten sind standardmäßig so vorbelegt wie hier aufgeführt, sie könne aber
+von Benutzern und in Anwenderprogrammen geändert werden. 
+#end# 
+#free(0.5)# 
+#ib#ESC a#ie#          Schreibt ein ä. 
+#ib#ESC A#ie#          Schreibt ein Ä. 
+#ib#ESC o#ie#          Schreibt ein ö. 
+#ib#ESC O#ie#          Schreibt ein Ö. 
+#ib#ESC u#ie#          Schreibt ein ü. 
+#ib#ESC U#ie#          Schreibt ein Ü. 
+#ib#ESC s#ie#          Schreibt ein ß. 
+#ib#ESC (#ie#          Schreibt eine [. 
+#ib#ESC )#ie#          Schreibt eine ]. 
+#ib#ESC <#ie#          Schreibt eine {. 
+#ib#ESC >#ie#          Schreibt eine }. 
+#ib#ESC \##ie#          Schreibt ein \#, das auch gedruckt werden kann. 
+#ib#ESC ­#ie#          Schreibt einen (geschützten) Trennstrich, siehe Textverarbeitung. 
+#ib#ESC k#ie#          Schreibt ein (geschütztes) "k", siehe Textverarbeitung. 
+#ib#ESC blank#ie#      Schreibt ein (geschütztes) Leerzeichen, siehe Textverarbeitung. 
+#free(1.0)# 
+Kommando auf Taste legen 
+ 
+#free(1.0)# 
+#ib#ESC ESC#ie#        Kommandodialog einschalten 
+ 
+#ib#ESC ! taste#ie#    Im Kommandodialog: 
+               Geschriebenes Kommando auf Taste legen. 
+ 
+#ib#ESC ? taste#ie#    Im Kommandodialog: 
+               Auf 'taste' gelegtes Kommando zum Editieren anzeigen. 
+ 
+#ib#ESC k#ie#          Im Kommandodialog: 
+               Das zuletzt editierte Kommando (einzeilige ELAN-Programm)
+               anzeigen. 
+ 
+Eine ausführliche Beschreibung des Kommandodialogs finden Sie im folgenden Kapi­
+tel. 
+4.3.     Die wichtigsten Editor-Kommandos 
+#goalpage("ESC")# 
+#free(0.5)# 
+ 
+#ib(9)#4.3.1.   Der #ib#Kommandodialog#ie##ie(9)# 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Einige Operationen kann man nur mühselig mit den bis jetzt beschriebenen Tasten
+   durchführen. Z.B. ist es sehr zeitaufwendig, eine bestimmte Textstelle zu finden.
+   Andere Operationen sind mit den im vorigen Kapitel beschriebenen Tasten über­
+   haupt nicht möglich, wie etwa die Zeilenbreite einzustellen oder Programme aufzu­
+   rufen, die die zu editierende Datei verarbeiten. Solche Operationen werden durch
+   Kommandos ermöglicht, die man auf Editorebene geben kann. #off("i")# 
+             
+ 
+#free(1.0)# 
+Um Kommandos an den Editor geben zu können, schalten wir in den #ib#Kommando­
+zustand#ie#. 
+ 
+<ESC>  <ESC> 
+ 
+Durch zweimaliges Betätigen von ESC erfolgt #on("u")#im Editor#off("u")# die Aufforderung 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ...................... Zeile 4     
+ 
+Mit der ESC-Taste ist es möglich, den Kommandodialog 
+gib kommando :                                           
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Auf dem Bildschirm erscheint eine #ib#Kommandozeile#ie#, in der der Benutzer
+Kommandos schreiben kann. Durch Betätigen der Taste 'CR' wird das
+Kommando ausgeführt. 
+#page# 
+ 
+ 
+#ib(9)#4.3.2.   Zeile und #ib#Textstelle anwählen#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Auf der Kommandoebene des Editors können Sie Kommandos erteilen, um an eine
+   beliebige Stelle in der Datei zu positionieren.#off ("i")#   
+             
+#free(1.0)# 
+Sie haben einen (größeren) Text erstellt und stehen nun vor dem Problem, für die
+Korrektur die entsprechenden Textstellen aufzufinden. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+Bei der Durchsicht eines Ausdrucks Ihres Textes stellen Sie fest, daß Sie sich ver­
+schrieben haben. Anstelle von "diese Zeichen" haben Sie "diese Ziichen" geschrie­
+ben. Um diese Textstelle anzuwählen, gehen Sie wie folgt vor: Sie positionieren an
+den Beginn der Datei und betätigen die Tastenfolge 
+ 
+ 
+<ESC>  <ESC> 
+ 
+ 
+Auf dem Bildschirm ersceint: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando:                                             
+ 
+____________________________________________________________________________ 
+ 
+ 
+Sie schreiben nun die zu suchende Textstelle auf: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: "diese Ziichen"                             
+ 
+____________________________________________________________________________ 
+ 
+ 
+Durch die Angabe eines TEXTes in Anführungsstrichen wird nach dem eingeschlosse­
+nen TEXT 'diese Ziichen' ab der aktuellen Cursor-Position gesucht. Wird 'diese
+Ziichen' gefunden, bleibt der Cursor auf dem gesuchten Text stehen. Andernfalls steht
+der Cursor am Ende der letzten Zeile der Datei. 
+ 
+Eine andere Möglichkeit, an eine entferntere Stelle im Text zu kommen, ist die fol­
+gende: 
+ 
+<ESC>  <ESC> 
+ 
+ 
+Es erscheint auf dem Bildschirm: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando:                                             
+ 
+____________________________________________________________________________ 
+ 
+ 
+Sie geben nun die Textzeile an, die Sie suchen: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 134                                         
+ 
+____________________________________________________________________________ 
+ 
+ 
+Durch dieses Kommando wird auf die 134. Zeile positioniert. 
+#page# 
+ 
+#ib(9)#4.3.3.   #ib#Suchen und Ersetzen#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Auf der Kommandoebene des Editors können Sie wie auf der Monitor-Ebene
+   beliebige Kommandos geben. Diese können Sie zu (ELAN-) Programmen ver­
+   knüpfen. Zur Erstellung dieser Programme editieren Sie wie gewohnt in der Kom­
+   mandozeile. Für das Positionieren, Suchen und Ersetzen innerhalb Ihres ELAN-
+   Programms stehen Ihnen Kommandos zur Verfügung. Beliebige ELAN-Prog­
+   ramme sind zulässig.#off ("i")#   
+            
+#free(1.0)# 
+Die #ib#Kommandozeile#ie# kann wie eine "normale" Textzeile editiert werden (Positionieren,
+Überschreiben, Einfügen, Löschen und Markieren). Bevor ein Programm eine Aus­
+gabe erzeugt oder fehlerhafte Kommandos Fehlermeldungen hervorrufen, wird der
+Cursor in die linke obere Ecke positioniert. Um die Meldungen festzuhalten, sollte das
+#ib#Kommando 'pause'#ie# folgen. Diese Meldungen werden dann in der ersten Zeile des
+Bildschirms angezeigt. Danach ist man wieder im Editor und kann wie gewohnt
+arbeiten. 
+ 
+Kommandos werden durch ein Semikolon voneinander getrennt. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: T1; "Geschäftsführung";fetch("Lieferanten",archive) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Ihr ELAN-Programm besteht aus zwei Kommandos: zunächst positionieren Sie in die
+erste Zeile und suchen ab dort nach dem Wort "Geschäftsführung". dann lesen Sie
+die Datei "Lieferanten" von der Diskette in den Arbeitsspeicher. 
+ 
+Die beiden beschriebenen Kommandos (Text bzw. eine Zeile anwählen) sind Spezial­
+kommandos und können in dieser Form nicht durch ein Semikolon mit anderen Kom­
+mandos kombiniert werden. Deshalb gibt es für sie eine ELAN-Form, die es erlaubt,
+sie mit anderen Kommandos zusammen zu verwenden: 
+ 
+a) Einen Text ab der aktuellen Cursor-Position suchen (D ist eine Abkürzung für
+   '#ib#DOWN#ie#'): 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: "diese Zeichen"                                    
+ 
+____________________________________________________________________________ 
+ 
+(* Kurzform *) 
+ 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: #ib#D#ie# "diese Zeichen"                               
+ 
+____________________________________________________________________________ 
+ 
+(* Allgemeine Version *) 
+ 
+ 
+ 
+b) Auf eine Zeile positionieren (#ib#T#ie# ist eine Abkürzung für '#ib#TO LINE#ie#'): 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 127                                             
+ 
+____________________________________________________________________________ 
+ 
+ 
+(* Kurzform *) 
+ 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: T 127                                               
+ 
+____________________________________________________________________________ 
+ 
+ 
+(* Allgemeine Version *) 
+ 
+ 
+Mehrere Kommandos können in der Kommandozeile angegeben werden. Die einzel­
+nen Kommandos müssen in diesem Fall mit ';' voneinander getrennt werden. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+<ESC>  <ESC> 
+ 
+schaltet in den Kommandomodus 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: T 1; D "noch Zeichen"                               
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Diese zwei Kommandos werden nacheinander ausgeführt. Zuerst wird auf die erste
+Zeile positioniert und dann (von der ersten Zeile ab) nach 'noch Zeichen' gesucht.
+Damit ist es möglich, die Datei nicht nur ab der aktuellen Zeile zu durchsuchen,
+sondern die gesamte Datei. Soll nicht in Richtung auf das Dateiende, sondern in
+Richtung auf den Dateianfang (also nach "oben") gesucht werden, kann man das
+#ib#U-Kommando#ie# (Abkürzung für #ib#UP#ie#) verwenden: 
+ 
+<ESC>  <ESC> 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: U "noch ein Text"                                   
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Ein weiteres Kommando ist das #ib#C-Kommando#ie# (Abkürzung für '#ib#CHANGE#ie#'), mit
+welchem man einen TEXT sucht und diesen dann ersetzt. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+<ESC>  <ESC> 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: "alte Zeichen" C "neue Zeichen"                     
+ 
+____________________________________________________________________________ 
+ 
+ 
+Ab der aktuellen Cursor-Position wird nach 'alte Zeichen' gesucht. Wird der TEXT
+gefunden, wird er durch 'neue Zeichen' ersetzt. Der Cursor befindet sich in diesem
+Fall hinter dem ersetzten TEXT. Wird 'alte Zeichen' dagegen nicht in der Datei gefun­
+den, befindet sich der Cursor (wie beim erfolglosen Suchen mit D) am Ende der
+letzten Zeile der Datei. 
+ 
+Wie alle anderen Kommandos kann auch das C-Kommando mit anderen Komman­
+dos verbunden werden. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+<ESC>  <ESC> 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: #ib#T#ie# 500; "Schreibfelher" #ib#C#ie# "Schreibfehler"           
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Hier wird ab der 500. Zeile der Datei nach 'Schreibfelher' gesucht und ggf. ersetzt.
+Soll ein TEXT nicht nur einmal, sondern bei jedem Auftreten ersetzt werden, benutzt
+man das #ib#CA-Kommando#ie# (Abkürzung für #ib#CHANGE ALL#ie#): 
+ 
+<ESC>  <ESC> 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: "dieser alte Text" CA "dieser neue Text"             
+ 
+____________________________________________________________________________ 
+ 
+ 
+Dadurch wird 'dieser alte Text' bei jedem Auftreten ab der aktuellen Cursor-Position
+durch 'dieser neue Text' ersetzt. 
+Pattern Matcher 
+#free(1.0)# 
+ 
+    
+   Der #ib#Pattern Matcher#ie# ist ein Werkzeug zur #ib#Mustererkennung#ie#. Er dient zur
+   Beschreibung von Texten, die in verschiedenen Ausprägungen auftreten können.
+   Zum Suchen oder Ersetzen wird nicht ein Text fester Gestalt vorgegeben, sondern
+   eine  Beschreibung der gesuchten Struktur. 
+ 
+    
+#free(1.0)# 
+ 
+Häufig werden Sie #ib#Texte suchen#ie# oder ersetzen wollen, die in einigen Varianten inner­
+halb eines umfangreicheren Textes auftauchen können. 
+ 
+Beispiel: Gesucht wird 'unser' in verschiedenen Zusammenstellungen, also auch
+          'unsere' oder 'unserem'. Alle Textstellen, die diesem Muster entsprechen,
+          können in #on("u")#einem#off("u")# Suchverfahren gefunden werden, indem das Muster,
+          welches diese Texte beschreibt, für die Suche benutzt wird: 
+ 
+____________________________________________________________________________ 
+Suchen nach Begriffen deren genaue Ausprägung unbekannt ist. 
+gib kommando:D(" unser" + any + " ")                             
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+          Leseweise: 
+ 
+          Suche 'unser', gefolgt beliebigen Zeichen plus einem Leerzeichen, oder
+          auch nur einem Leerzeichen. 
+ 
+ 
+          Dieses Suchkommando liefert Treffer bei 'unser', 'unsere', 'unseres' usw.. 
+ 
+#free(1.0)# 
+Wie baut man ein Pattern ? 
+ 
+#free(1.0)# 
+ 
+    
+       Texte werden durch ihr Konstruktionsmuster aus bekannten und unbekannten
+       Teilen beschrieben 
+        
+#free(1.0)# 
+ 
+Ein Text, der in seiner konkreten Form nicht bekannt ist, dessen Aufbau jedoch durch
+ein Muster beschrieben werden kann, besteht aus Teilen, die als: 
+ 
+            -  bekannte Texte 
+            -  unbekannte Texte 
+ 
+bezeichnet werden und die mit dem Operatoren: 
+ 
+            '+'     Zusammensetzen 
+            'OR'    Alternative 
+ 
+kombiniert werden können. 
+ 
+ 
+Ein bekannter Text ist z.B. ein Stück eines gesuchten Textes, das als fest vorgegeben
+betrachtet werden kann, wie etwa der Wortstamm 'unser' in dem obigen Beispiel. Wie
+gewohnt wird ein solcher bekannter Text, in Anführungsstriche gesetzt, als TEXT
+CONST "text" notiert. 
+ 
+Demgegenüber ist ein unbekannter Text von nicht näher zu beschreibender Gestalt.
+Das Muster, welches einen unbekannten Text beschreibt, steht für irgendeinen einer
+Vielzahl von Texten, die diesem Muster entsprechen. 
+ 
+Mit der Prozedur: 
+ 
+             any 
+ 
+wird das Muster für einen beliebigen Text geliefert. 
+ 
+Im einleitenden Beispiel ist der Wortstamm bekannt, das Teilwort 'unser' kann also im
+'Klartext' angegeben werden. Die Endungen sind je nach dem Zusammenhang in dem
+das gesuchte Wort auftritt verschieden, also zunächst unbekannt. 
+Ein solcher unbekannter Text kann entweder durch Aufzählung der möglichen
+Alternativen seiner Erscheinung beschrieben werden oder durch die Prozedur 'any'. 
+ 
+ 
+          (text + ("er" OR "es" OR "em" OR ..... ) 
+ 
+    alternative Verknüpfung durch OR 
+ 
+ 
+          ("text" + any + ....           ) 
+ 
+    additive Verknüpfung durch + 
+ 
+Grundsätzlich ist zu beachten, daß der Suchvorgang des Pattern Matcher Zeichenket­
+ten untersucht und nicht etwa einzelne Worte und stets nach dem längstmöglichen
+Muster gesucht wird! 
+ 
+Ein schlecht beschriebener Suchtext kostet somit nicht nur viel Rechenzeit, sondern
+liefert auch unerwünschte Ergebnisse: z.B. sollte der Artikel 'der' mit einem führenden
+Leerzeichen als " der" gesucht werden, da andernfalls jedes Wort, das die Silbe 'der'
+enthält, einen Treffer in der Suche ergibt. 
+ 
+Da die Suche nach unbekannten Texten viele unerwünschte Ergebnisse liefern
+könnte, kann die Prozedur any in zweifacher Weise eingeschränkt werden: 
+ 
+ 
+D(" d" + any (2) ) 
+ 
+          Die Länge der unbekannten Textes wird vorgegeben, indem die Anzahl
+          der Zeichen aus denen der Text besteht, angegeben wird. Die Angabe
+          steht in Klammern hinter 'any'. (In diesem Beispiel genau 2 Zeichen). 
+ 
+ 
+D(" d" + any ("aeirs")) 
+ 
+ 
+          Das Alphabet, aus dem der unbekannte Text bestehen darf, wird angege­
+          ben.  (In diesem Beispiel darf der Text der einen Treffer ergibt nur aus
+          den Zeichen 'a', 'e', 'i', 'r', 's' bestehen, z.B: der, die, das oder auch
+          dies.) 
+ 
+ 
+D(" d" + any (2,"aeirs") 
+ 
+ 
+          Auch die Kombination der Beschränkungen ist möglich. (Jetzt liefern nur
+          noch 'der', 'die','das' etc. Treffer). 
+ 
+ 
+#on("b")# 
+ACHTUNG:   Das Zeichen '*' nimmt eine Sonderstellung ein, da es als Abkürzung für
+           'any' verwandt werden kann. Soll dieses Zeichen im Text gesucht oder
+           ersetzt werden, müssen Sie statt  "*"  'any(1,"*")' schreiben. 
+ 
+           Weitere Informationen zum Pattern Matcher finden Sie im EUMEL-
+           Handbuch zur Programmierung. 
+#off("b")# 
+#free(1.0)# 
+4.3.4.   Kommandos auf Tasten legen 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Oft benutzte Kommandos können auf Tasten gelegt werden. Damit ist es möglich,
+   den Editor auf Ihre speziellen Bedürfnisse einzurichten.#off ("i")#   
+    
+#free(1.0)# 
+ 
+Oft benutzte Kommandos können mit der Drei-Tastenfolge 
+ 
+<ESC>  <!>  <'taste'>    auf eine Taste gelegt werden. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+ 
+<ESC>  <ESC>          (* die Kommandozeile erscheint *) 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: save (SOME myself)                         
+ 
+____________________________________________________________________________ 
+ 
+ 
+<ESC>  <!>  <s>       (* das Kommando 'save (SOME myself)' ist
+                          nun auf die Taste 's' gelegt *) 
+ 
+ 
+Wird nun die Taste 's' gedrückt, erscheint das Zeichen 's' auf dem Bildschirm. Mit
+#ib#ESC s#ie# wird das 'save'-Kommando ausgeführt. Natürlich können auch kompliziertere
+Kommandos auf Tasten gelegt werden. 
+ 
+Möchten Sie ein Kommando, das auf eine Taste gelegt wurde, verändern, drücken Sie
+im Kommandodialog (!) die Drei-Tastenfolge 
+ 
+<ESC>  <?>  <'taste'> 
+ 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+<ESC>  <ESC>       (* in den Kommandodialog gehen *) 
+ 
+ 
+<ESC>  <?>  <s>    (* es erscheint nun: 'save (SOME myself)' *) 
+ 
+Dieses Kommando kann nun z.B. verändert und ausgeführt (durch 'CR') oder
+wiederum auf die gleiche oder eine andere Taste gelegt werden (durch #ib#ESC ! 'taste'#ie#). 
+ 
+Im Editor kann das letzte im Kommandodialog eingegebene Kommando durch '#ib#ESC f#ie#'
+wiederholt werden. 
+#page# 
+ 
+#ib(9)#4.3.5.   Texte aus anderen Dateien benutzen#ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Manchmal ist es notwendig, einen Text in eine andere Datei zu schreiben (z.B.
+   wenn man diesen Text noch einmal verwenden will) oder einen Text einer anderen
+   Datei in den zu bearbeitenden Text einzufügen. Die '#ib#GET#ie#'- und '#ib#PUT#ie#'-Kom­
+   mandos bieten die Möglichkeit, Texte zwischen Dateien auszutauschen (vergl.
+   auch den Abschnitt über paralleles Editieren).#off ("i")#   
+               
+#free(1.0)# 
+Mit dem #ib#'GET'-Kommando#ie# können wir Texte aus einer anderen Datei an die aktuelle
+Schreibposition kopieren. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: GET "absender"                              
+ 
+____________________________________________________________________________ 
+ 
+holt den Text 'absender'. Wenn also des öfteren Briefe geschrieben werden, braucht
+man sich den Absender nur einmalig in die Datei 'absender' zu schreiben und kann
+diesen mit dem Kommando 'GET' (was man auf eine Taste legen kann) u.U. mehr­
+mals an verschiedenen Stellen in die Datei einfügen. 
+ 
+Mit dem #ib#'PUT'-Kommando#ie# können wir zuvor markierte Textteile in eine Datei schrei­
+ben. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: PUT "adressen"                              
+ 
+____________________________________________________________________________ 
+ 
+ 
+schreibt einen markierten Text in die Datei 'adressen'. 'adressen' wird ggf. eingerich­
+tet. Ist die Datei 'adressen' bereits vorhanden, so wird erfragt, ob die Datei gelöscht
+werden kann, um den markierten Text aufzunehmen (überschreiben). Andernfalls wird
+der markierte Text an den bereits vorhandenen Text in 'adressen' angefügt. Es ist
+somit durch mehrmaliges Markieren und das 'PUT'-Kommando möglich, Texte aus
+einer Datei zu sammeln und in eine neue Datei zu geben. 
+#page# 
+ 
+#ib(9)#4.3.6.   #ib#Breitere Zeilen#ie# bearbeiten#ie(9)##goalpage("margin")# 
+#free(1.0)# 
+   #on("i")# 
+   Der Editor ist auf eine Zeilenbreite von 77 Zeichen eingestellt. Oft ist es notwen­
+   dig, mit einer anderen Zeilenbreite zu schreiben, welche man mit dem #ib#'limit'-
+   Kommando#ie# einstellen kann. Aber auch die Positionierung innerhalb einer Zeile
+   wird dadurch anders, weil breitere Zeilen nicht als Ganzes auf den Bildschirm
+   passen. In diesem Fall wird "#ib#gerollt#ie#".#off ("i")#   
+                          
+#free(1.0)# 
+Eine andere Zeilenbreite stellt man durch 'limit' ein. Beachten Sie, daß die eingestell­
+te Zeilenbreite für die gesamte Datei gilt. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: limit (180)                                       
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nun können Sie wie gewohnt schreiben. Allerdings wird die aktuelle Zeile, in der man
+sich befindet, nicht wie gewohnt am Bildschirmende umgebrochen, sondern erst an
+der Spalte 180, sofern sie nicht vorher durch die 'CR'-Taste beendet wird. Wird über
+das rechte Bildschirmende hinaus geschrieben, bleibt die Cursor-Position am Ende
+des Bildschirms erhalten, aber die Zeile wird beim weiteren Schreiben nach links
+verschoben, "rollt" also nach links (der Anfang der Zeile verschwindet scheinbar nach
+links). 
+ 
+Mit der Positionierung verhält es sich ähnlich. Wird mit RECHTS über den rechten
+Bildschirmrand positioniert, wird die Zeile ebenfalls gerollt. #ib#HOP RECHTS#ie# bewirkt ein
+#ib#Blättern#ie# innerhalb einer einzelnen Zeile nach rechts. Analog verläuft es bei verscho­
+bener Zeile, wenn nach links (LINKS bzw. #ib#HOP LINKS#ie#) positioniert wird. 
+ 
+Beim Schreiben von Tabellen kann es sinnvoll sein, das Fenster vorübergehend auf
+eine andere Anfangsposition (als 1) einzustellen. Das kann mit dem
+#ib#'margin'-Kommando#ie# erfolgen. 
+ 
+#on("u")#Beispiel:#off("u")# 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando:#ib#margin#ie# (50)                                       
+ 
+____________________________________________________________________________ 
+ 
+ 
+Das Editorfenster zeigt nun einen Ausschnitt aus der Datei, beginnend ab der Spalte
+50. In der Titelzeile wird "M50" angezeigt. 
+#page# 
+ 
+#ib(9)#4.3.7.   Die wichtigsten Kommandos#ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Einige Kommandos sind speziell für die Textverarbeitung im Editor programmiert.
+   Die wichtigsten werden hier vorgestellt.#off ("i")#   
+           
+#free(1.0)# 
+any 
+   TEXT PROC any 
+   liefert ein Muster beliebiger Gestalt und Länge (also auch der Länge 0) für
+   Suchoperationen. 
+ 
+ 
+   " ir" + any + "was" 
+ 
+ 
+any 
+   TEXT PROC any (TEXT CONST alphabet) 
+   liefert den längstmöglichen Text, der aus den in 'alphabet' angegebenen Zeichen
+   besteht. 
+ 
+ 
+   any ("1234567890")    (* suche Zahlen *) 
+ 
+ 
+any 
+   TEXT PROC any (INT CONST laenge) 
+   liefert ein Muster beliebiger Gestalt und der Länge 'laenge'. 
+ 
+ 
+   " d" + any (2) 
+ 
+ 
+any 
+   TEXT PROC any (INT CONST laenge, TEXT CONST alphabet) 
+   liefert ein Muster der Länge 'laenge', das nur aus Zeichen aus
+   'alphabet' besteht. 
+ 
+ 
+   " d" + any (2,"erias") 
+ 
+ 
+ 
+C 
+   OP C (TEXT CONST muster, ersatz) 
+   Ab der aktuellen Positon wird 'muster' in Richtung Dateiende gesucht und durch
+   'ersatz' ersetzt. Der Cursor steht danach hinter 'ersatz'. 
+ 
+ 
+   "alt" C "neu" 
+ 
+ 
+ 
+CA 
+   OP CA (TEXT CONST muster, ersatz) 
+   Arbeitet ab der aktuellen Position wie C. Die Aktion wird jedoch bis zum Erreichen
+   des Dateiendes wiederholt. Nach Ausführung ist somit jedes 'muster' durch
+   'ersatz' ersetzt. Der Cursor steht danach hinter dem letzten Zeichen der Datei. 
+ 
+ 
+   "alt" CA "neu" 
+ 
+ 
+ 
+ 
+D 
+   OP D (INT CONST n) 
+   Positioniert das Fenster n Zeilen vorwärts in Richtung auf das Dateiende. 
+ 
+ 
+   D 50 
+ 
+ 
+   OP D (TEXT CONST muster) 
+   Sucht 'muster' vorwärts in Richtung auf das Dateiende. Die Suche beginnt direkt
+   hinter der aktuellen Cursor-Position. Wird 'muster' nicht gefunden, steht der
+   Cursor hinter dem letzten Zeichen der Datei. Wird 'muster' gefunden, steht der
+   Cursor direkt auf dem ersten Zeichen von 'muster'. 
+ 
+ 
+   D "muster" 
+ 
+ 
+ 
+GET 
+   OP GET (TEXT CONST dateiname) 
+   Kopiert den Inhalt der Datei mit dem angegebenen Namen vor die aktuelle
+   Cursor-Position. Ist ein Teil der Quelldatei markiert, wird nur der markierte Teil
+   kopiert. 
+ 
+ 
+   GET "quelldatei" 
+ 
+ 
+   OP G (TEXT CONST dateiname) 
+   Wie GET. 
+ 
+ 
+limit 
+   OP limit (INT CONST limit) 
+   Setzt die rechte Schreibgrenze auf 'limit'. 
+ 
+ 
+   limit (50) 
+ 
+ 
+ 
+margin 
+   PROC margin (INT CONST anfang) 
+   Alle Zeilen erscheinen erst ab Spalte 'anfang' im Sichtfenster. 
+ 
+ 
+   margin (50) 
+ 
+ 
+ 
+OR 
+   TEXT OP OR (TEXT CONST texteins,textzwei) 
+   Liefert ein Muster, wenn texteins oder textzwei gefunden wird. Die Reihenfolge
+   spielt keine Rolle. 
+ 
+ 
+   D ("Geschäfts" + ("führung" OR "leitung")) 
+ 
+ 
+ 
+PUT 
+   OP PUT (TEXT CONST dateiname) 
+   Richtet eine Datei mit dem angegebenen Namen ein und kopiert den markierten
+   Textabschnitt in diese. 
+ 
+ 
+   PUT ("meine hilfsdatei") 
+ 
+ 
+   OP P (TEXT CONST dateiname) 
+   Zweck: Wie PUT. 
+ 
+ 
+T 
+   OP T (INT CONST n) 
+   Positioniert auf die Zeile 'n'. 
+ 
+ 
+   T 999 
+ 
+ 
+ 
+type 
+   PROC type (TEXT CONST zeichenkette) 
+ 
+   Fügt 'zeichenkette' in die aktuelle Position der editierten Datei ein. Besonders
+   nützlich in Verbindung mit der Prozedur 'code', um nicht auf der Tastatur enthal­
+   tene Zeichen in den Text zu bringen. 
+ 
+ 
+   type(code(200)) 
+ 
+ 
+ 
+U 
+   OP U (INT CONST n) 
+   Positioniert das Fenster n Zeilen rückwärts in Richtung auf den Dateianfang. 
+ 
+ 
+   U 100 
+ 
+ 
+   OP U (TEXT CONST muster) 
+   Sucht 'muster' rückwärts in Richtung auf den Dateianfang. Die Suche beginnt
+   links neben der aktuellen Cursor-Position. Vergl. D 
+ 
+ 
+   U "muster" 
+ 
+ 
+word wrap 
+   PROC word wrap (BOOL CONST an) 
+   Schaltet den automatischen Wortumbruch an (voreingestellt) bzw. aus. 
+ 
+ 
+             word wrap (true)         (* angeschaltet  *) 
+             word wrap (false)        (* ausgeschaltet *) 
+ 
+4.4.     Fehlersituationen und Abhilfe 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Von Zeit zu Zeit werden Sie als Anfänger in Arbeitssituationen geraten, wo Sie
+   nicht weiterwissen. Hier sind einige Tips, wie Sie sich behelfen können.#off ("i")#   
+             
+#free(1.0)# 
+ 
+Wie helfe ich mir, wenn... 
+ 
+ 
+...  nach 
+            continue("taskname") 
+ 
+     der Monitor #on("u")#nicht#off("u")# 
+ 
+            gib kommando: 
+ 
+     sagt, sondern "schweigt"? 
+ 
+=>   Sie haben die Task bei der letzten Benutzung nicht mit dem Kommando
+     'break' verlassen (evtl. haben Sie SV betätigt?). Sie sind jetzt im Editor, sehen
+     aber den zuletzt bearbeiteten Textausschnitt nicht. Betätigen Sie die Tasten 
+ 
+           ESC b 
+ 
+     und der Text wird neu auf dem Bildschirm ausgegeben. 
+#free(1.0)# 
+...  im Editor kein Tastendruck mehr akzeptiert wird? 
+ 
+=>   Sie haben irrtümlich die STOP-Taste (auch oft als CTRL a realisiert, abhängig
+     vom Terminal), d.h. Anhalten der Bildschirmausgabe betätigt. 
+ 
+     Drücken Sie die WEITER-Taste (= CTRL c, d.h. Bildschirmausgabe fortfüh­
+     ren). Alle Tastenanschläge, die zwischenzeitlich zu keiner Reaktion führten,
+     werden jetzt ausgegeben. 
+ 
+     Je nach Tastatur können STOP und WEITER auch auf anderen Tasten liegen. #free(1.0)# 
+...  der Lernmodus über lange Zeit (ungewollt) eingeschaltet war? 
+ 
+=>   a) Sie merken plötzlich, daß über einen unbestimmt langen Zeitraum alle Ihre
+        Tastenanschläge gelernt wurden (zu erkennen an der "LEARN"-Anzeige in
+        der Überschriftzeile). 
+ 
+        #on("u")#Was ist zu tun?#off("u")# 
+ 
+        Mit dem Kommando 
+ 
+                   ESC HOP HOP 
+ 
+        vergessen Sie alles Gelernte und schalten den Lernmodus aus. 
+ 
+=>   b) Sie beenden den Editor mit ESC q und die Meldung 
+ 
+____________________________________________________________________________ 
+ 
+        WARNUNG: Lernmodus nicht ausgeschaltet        
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+        erscheint auf dem Bildschirm. 
+ 
+        #on("u")#Was ist zu tun?#off("u")# 
+ 
+        Sie können mit 
+ 
+             ESC HOP HOP 
+ 
+        das Gelernte sofort vergessen. 
+#free(1.0)# 
+...  Sie zu viele Absatzzeichen in Ihrem Text gesetzt haben und diese entfernen
+     müssen? 
+ 
+=>   Sie positionieren in die Zeile, in der die Absatzmarke gelöscht werden soll. Sie
+     betätigen dann die TAB-Taste, um hinter den Text zu positionieren, dann die
+     RUBOUT-Taste. Wenn Sie jetzt die Zeile mit den Cursor-Tasten nach oben
+     oder unter verlassen, verschwindet die Absatzmarkierung. 
+#free(1.0)# 
+...  nach 
+ 
+         save("dateiname","vatertask") 
+ 
+     das Betriebssystem nicht mehr reagiert? 
+ 
+=>   Sie haben die Vater-Task nicht mit dem Kommando 'global manager' in
+     jenem Prozeß zum Empfang von Daten aus anderen Prozessen vorbereitet. 
+#free(1.0)# 
+...  Sie in Ihrer Task das Archive mit dem Kommando 
+ 
+     archive("archivname") 
+ 
+     anmelden wollen und das System Ihnen die Meldung 
+ 
+     "Fehler: Archive wird von Task "bib" benutzt" 
+ 
+     zustellt? 
+ 
+=>   Es gibt zwei Möglichkeiten: 
+     a) Ein anderer Benutzer benötigt das Archiv-Laufwerk in diesem Moment. Sie
+        müssen warten, bis er seine Arbeit beendet hat. 
+ 
+     b) Ein anderer Benutzer (oder Sie selbst) hat vergessen, mit dem Kommando 
+ 
+        release(archive) 
+ 
+        das Archiv in jener Task freizugeben. Falls Sie es selbst waren, holen Sie
+        das nach. Ansonsten kann das Archiv-Kommando wieder erfolgreich gege­
+        ben werden, wenn fünf Minuten nicht auf das Archiv 
+        zugegriffen wurde. #free(1.0)# 
+...  Sie eine (scheinbare oder echte) Endlosschleife auf einer Taste (z.B. Taste "x")
+     gelernt haben und diese (versehentlich oder bewußt) durch 'ESC x' aktivieren? 
+ 
+=>   Wie immer, wenn Sie eine endlos laufende Task beenden wollen, gelangen Sie
+     mit der SV-Taste in den Supervisor-Modus und mit dem Kommando 
+ 
+     'halt' 
+ 
+     beenden Sie die Endlosschleife. 
+ 
+     Mit 
+ 
+     ESC HOP HOP x 
+ 
+     wird danach das Gelernte 'vergessen'! 
+#free(1.0)# 
+...  Sie Ihre Datei verlassen wollen und 
+ 
+     'ESC q' 
+ 
+     (scheinbar) nicht funktioniert? 
+ 
+=>   Sie haben versehentlich den Feststeller für Großbuchstaben (SHIFT LOCK /
+     CAPS LOCK) betätigt und ESC q zeigt keine Wirkung (wie auch andere Tasten­
+     kombinationen mit Großbuchstaben evtl. keine Wirkung zeigen).  
+
diff --git a/doc/user/benutzerhandbuch.5a b/doc/user/benutzerhandbuch.5a
new file mode 100644
index 0000000..1e907f0
--- /dev/null
+++ b/doc/user/benutzerhandbuch.5a
@@ -0,0 +1,1446 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Teil 5: Textkosmetik und Druck     
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+5 - %      GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        5 - % 
+#tableend##clearpos# 
+#end# 
+ 
+#ib(9)#TEIL 5: Textkosmetik und Druck#ie(9)# 
+#free(1.0)# 
+#ib(9)#5.0. Vorwort#ie(9)# 
+ 
+#free(1.0)# 
+Die #ib#Textkosmetik-Programme#ie# des EUMEL-Systems bieten Ihnen eine einfach zu
+erlernende und zu bedienende Möglichkeit, Texte für den Druck zu gestalten (pro­
+grammtechnisch: #ib#formatieren#ie#) und zu manipulieren. 
+ 
+Die Textkosmetik-Programme bearbeiten Ihre Dateien, die durch den EUMEL-Editor
+erstellt wurden. Darum sollten Sie sich zuerst mit dem EUMEL-Editor vertraut
+machen. 
+ 
+Die Programme sind so konstruiert, daß die meisten Aufgaben durch in den Text
+eingefügte Anweisungen gesteuert werden. Solche Angaben für die Textkosmetik und
+den EUMEL-Drucker nennen wir im folgenden kurz #on("b")##on("i")#'Anweisung' #off("b")##off("i")#. Die Form der
+#ib#Anweisung#ie# ist für die Textkosmetik und den EUMEL-Drucker gleich und entspricht
+der ELAN-Syntax. Beachten Sie den #ib#Unterschied zwischen einem Kommando und
+einer Text-Anweisung#ie#: während ein Kommando direkt ausgeführt wird, wird eine in
+den Text eingebettete Anweisung erst nach dem Aufruf von Textkosmetik- und
+Drucker-Programmen wirksam. 
+ 
+Die Wirkungsweise der Textkosmetik-Anweisungen ist leicht zu erlernen und kann
+vor allen Dingen stufenweise erfolgen. Deshalb ein guter Rat für Anfänger: Lesen Sie
+diesen Teil des Benutzer-Handbuchs erst oberflächlich, so daß Sie ungefähr
+Bescheid wissen, welche Möglichkeiten die Textkosmetik-Programme bieten. Dann
+können Sie diejenigen Teile der Textkosmetik auswählen und bei Bedarf anwenden,
+die Sie für Ihre spezielle Anwendung benötigen. 
+#page# 
+ 
+#ib(9)#5.1. Einführung in die Benutzung der 
+     #ib#Textkosmetik#ie##ie(9)# 
+ 
+#free(1.0)# 
+   #on("i")# 
+   In diesem Kapitel erhalten Sie eine Übersicht über die verfügbaren Programme der
+   Textkosmetik. 
+                         
+#off("i")# 
+#free(1.3)# 
+Schreiben, Gestalten und Drucken von Texten 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Im EUMEL-System unterscheiden wir zwischen drei Stufen einer Textbehand­
+   lung:#on("b")# Erstellung, Gestaltung#off("b")# und #on("b")#Druck#off("b")#. Die Trennung in verschiedene Arbeits­
+   stufen hat den Vorteil, daß Sie sich zu einem Zeitpunkt nur auf einen Arbeitsschritt
+   konzentrieren müssen. 
+              #off("i")# 
+#free(1.3)# 
+Texterstellung bzw. Textbearbeitung 
+ 
+#free(1.0)# 
+Das Schreiben von Texten wird mit Hilfe des Editors erledigt. In dieser Stufe der
+Texterstellung können Sie sich ausschließlich auf das Schreiben und die inhaltliche
+Korrektheit Ihres Textes konzentrieren. Wird ein Text ohne Anweisungen gedruckt,
+dann erscheint er so, wie er mit dem Editor geschrieben wurde. Bei der Erstellung
+des Textes können Sie aber auch bereits Textkosmetik-Anweisungen in den Text
+einfügen. 
+ 
+____________________________________________________________________________ 
+ 
+   Es ist wichtig, daß Sie das Kapitel 'Editor' 
+   \#on("b")\#sehr\#off("b")\# gründlich lesen.     
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+Es ist wichtig, daß Sie das Kapitel 'Editor' 
+#on("b")#sehr#off("b")# gründlich lesen. 
+ 
+ 
+Sie sollten Texte im 'Fließtext'-Modus erstellen, d.h., dann werden Worte, die über
+Zeilengrenzen gehen, ohne Silbentrennung vom Editor in die nächste Zeile gebracht. 
+#free(1.5)# 
+Textkosmetik bzw. Textgestaltung 
+ 
+#free(1.0)# 
+Nachdem Sie einen Text geschrieben haben, können Sie ihn mit #ib#Textkosmetik-
+Programme#ie#n gestalten, ohne ihn inhaltlich zu verändern. Dies kann auch vor oder
+nach eventuellen Korrekturen erfolgen. Die Textkosmetik bietet zur Zeit vier Pro­
+gramme an, die je nach Bedarf eingesetzt werden können: 
+ 
+---    #on("b")#'#ib#lineform'/'autoform#ie#'#off("b")# formatiert einen Text zeilenweise und vollzieht eine
+       Silbentrennung. Weiterhin erlaubt 'lineform'/'autoform' die Verwendung unter­
+       schiedlicher Schrifttypen und Schrifthöhen. 
+ 
+---    #on("b")#'#ib#pageform#ie#'/'#ib#autopageform#ie#'#off("b")# gestattet die Formatierung eines Textes in Seiten
+       (drucktechnisch: "Seitenumbruch"). Dabei berücksichtigt 'pageform'/'auto­
+       pageform' unterschiedliche Schrifthöhen. Es ist mit 'pageform'/ 'autopage­
+       form' u.a. möglich, die Seiteneinteilung zu bestimmen, eine Seite in Spalten
+       zu formatieren ("Zeitungsformat"), Zeilen am Anfang bzw. Ende jeder Seite
+       einfügen zu lassen, eine Seitennumerierung (drucktechnisch: "Paginierung")
+       zu erhalten und Fußnoten zu gestalten. 
+ 
+---    #on("b")#'#ib#index#ie#'#off("b")# erlaubt die Erstellung von Stichwort- und Inhaltsverzeichnissen aus
+       einer mit 'pageform'/'autopageform' bearbeiteten Datei. 
+ 
+---    #on("b")#'#ib#outline#ie#'#off("b")# holt aus einer Datei alle mit Index-Anweisung gekennzeichneten
+       Überschriften und Stichworte. Es erstellt somit eine Übersicht bzw. Kurz­
+       fassung eines Textes. 
+#free(1.5)# 
+Drucken 
+#free(1.0)# 
+Zu jedem Zeitpunkt der Texterstellung kann gedruckt werden. Der EUMEL-Drucker
+beachtet die gleichen Anweisungen wie die Textkosmetik-Programme und noch
+einige zusätzliche, die nur für die Druckaufbereitung notwendig sind. Spezielle Druck­
+leistungen, wie z.B. verschiedenartige Schrifttypen, können nur auf besonderen
+Druckern erzeugt werden. Verfügt ein Drucker nicht über eine bestimmte Hardware-
+Eigenschaft, wird die von ihm geforderte Leistung ignoriert. Somit ist es möglich,
+Probedrucke für Korrekturen etc. auch auf preiswerten Druckern herzustellen. (siehe
+hierzu 5.6.1.) 
+#page# 
+ 
+     +-------------------------+ 
+     l   Text-Eingabe          l 
+     l                         l 
+ +->-+   Editor                +->-+ 
+ l   l                         l   l 
+ l   l   erstellt Datei        l   l 
+ l   +------------+------------+   l 
+ l                l                l 
+ l                V                l 
+ l   +------------+------------+   l 
+ l   l   lineform              l   l 
+ +-<-+                         +->-+ 
+ l   l   formatiert Zeilen     l   l 
+ l   +------------+------------+   l 
+ l                l                l 
+ l                V                l 
+ l   +------------+------------+   l 
+ l   l   outline               l   l     +--------------------------+ 
+ l   l                         l   l     l     E U M E L - Drucker  l 
+ +-<-+ gibt Übersicht bzw.     +->-+ ->--+                          l 
+ l   l Kurzfassung eines Textesl   l     l     Probe- bzw.          l 
+ l   l                         l   l     l     endgültiger Druck    l 
+ l   l  Dateiname + '.outline' l   l     +--------------------------+ 
+ l   +------------+------------+   l 
+ l                l                l 
+ l                V                l 
+ l   +------------+------------+   l 
+ l   l   pageform              l   l 
+ l   l                         l   l 
+ +-<-+   formatiert Seiten     +->-+ 
+ l   l                         l   l 
+ l   l   Druckdatei            l   l 
+ l   l   Dateiname + ".p"      l   l 
+ l   +------------+------------+   l 
+ l                l                l 
+ l                V                l 
+ l   +------------+------------+   l 
+ l   l   index                 l   l 
+ l   l                         l   l 
+ l   l erstellt Stichwort- und l   l 
+ +-<-+  Inhaltsverzeichnisse   +->-+ 
+     l                         l 
+     l  Indexdatei(en)         l 
+     l Dateiname + "i<nummer>" l 
+     +-------------------------+ 
+ #page# 
+ 
+#ib(9)#5.1.1. Anweisungen für die Textkosmetik 
+       und den Drucker#ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   In diesem Abschnitt wird beschrieben, wie Sie #ib#Anweisungen#ie# für die Textkosme­
+   tik- und Druckprogramme in einen Text einfügen können. Beachten Sie, daß jede
+   Anweisung von '\#'-Zeichen eingeschlossen werden muß. Benötigen Sie das
+   '\#'-Zeichen in Ihrem Text, müssen Sie es mit 'ESC' schreiben. 
+    #off("i")# 
+#free(1.0)# 
+Es gibt zwei Arten von Anweisungen: 
+ 
+a) Anweisungen, die das gesamte Aussehen eines Manuskripts verändern (#on("i")##ib#"layout-
+   Anweisungen"#ie##off("i")#). Zu diesen Anweisungen gehören die Anweisungen \#limit (...)\#­
+   (Einstellen der Zeilenbreite), \#linefeed (...)\# (Zeilenabstand), \#page\# (neue Seite)
+   usw. Diese Anweisungen gelten erst ab der nächsten Zeile und Sie sollten sie
+   daher in eine extra Zeile zwischen den Text stellen. 
+ 
+____________________________________________________________________________ 
+ 
+\#type ("trium8")\#\#limit (11.0)\# 
+\#start(5.0,1.5)\# 
+\#pagelength(17.4)\#\#pagenr("%",148)\#\#setcount(1)\# 
+\#block\#\#pageblock\# 
+\#count per page\# 
+\#headeven\# 
+\#lpos(0.0)\#\#cpos(5.5)\#\#rpos(11.0)\# 
+\#table\# 
+                     EUMEL-Benutzerhandbuch    
+\#fillchar(" ")\# 
+\#on("u")\#       \#off("u")\# 
+\#table end\#\#clear pos\# 
+ 
+\#end\# 
+\#headodd\# 
+\#lpos(0.0)\#\#cpos(5.5)\#\#rpos(11.0)\#\#fillchar(" ")\# 
+\#table\# 
+     Teil 5: Textkosmetik und Druck     
+\#fillchar(" ")\# 
+\#on("u")\#       \#off("u")\# 
+\#table end\#\#clear pos\# 
+ 
+\#end\# 
+ 
+____________________________________________________________________________ 
+ 
+    
+   Das Druckbild (das Ergebnis der Anweisungen) sehen Sie im vorliegenden
+   Benutzerhandbuch. 
+ 
+   Anweisungen, die für den Gesamttext gelten sollen, müssen Sie an den Anfang
+   der Datei stellen (noch vor \#head\#). 
+ 
+b) Anweisungen, die unmittelbar auf den nachfolgenden Text wirken sollen, wie z.B.
+   \#type\# (Schrifttyp), \#on\#/\#off\# (Modifikationen wie unterstreichen oder fett druk­
+   ken), \#ib\#/\#ie\# (Markierung von Stichworten) usw. Solche Anweisungen werden
+   unmittelbar beachtet und können überall auf einer Zeile stehen (wie in dem fol­
+   genden Beispiel). 
+ 
+____________________________________________________________________________ 
+ 
+   \#on("underline")\#Ausnahmen\#off("underline")\# werden bei der 
+   Beschreibung der Anweisungen speziell erwähnt.  
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+   #on("u")#Ausnahmen#off("u")# werden bei der 
+   Beschreibung der Anweisungen speziell erwähnt. 
+ 
+____________________________________________________________________________ 
+ 
+Weitere Beispiele für Textkosmetik-Anweisungen: 
+ 
+____________________________________________________________________________ 
+ 
+\#page\# 
+\#free(3.0)\# 
+\#type("quadrato")\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Diese Anweisungen entsprechen - wie alle Kommandos im EUMEL-System - der
+ELAN-Syntax (u.a. müssen sie klein geschrieben werden; Parameter in runden
+Klammern; mehrere Parameter werden durch Kommata getrennt; #ib#TEXT-Parameter#ie# in
+Anführungsstrichen; #ib#REAL-Parameter#ie# mit Dezimalpunkt usw.). Leerzeichen spielen
+(außer in TEXT-Parametern) keine Rolle und können zur besseren Lesbarkeit belie­
+big verwendet werden. 
+ 
+Die Zeichen, aus denen eine Anweisung besteht, werden bei der Formatierung einer
+Zeile oder Seite nicht mitgezählt und vom EUMEL-Drucker nicht gedruckt. Eine
+Zeile, die nur aus Anweisungen besteht, wird ebenso behandelt, auch wenn sie mit 
+<CR> abgeschlossen wird. 
+#page# 
+#on("b")#
+ 
+#ib(9)#5.1.2. #ib#Aufruf der Textkosmetik-Programme#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   In diesem Abschnitt wird beschrieben, wie Sie die #ib#Textkosmetik-Programme
+   aktivieren#ie# können. 
+   #off("i")# 
+#free(1.0)# 
+Sie rufen die Textkosmetik-Programme durch Kommandos auf (d.h. in der 'gib
+kommando'-Ebene). Sie geben ebenso wie zum Editieren den Namen des Pro­
+gramms und der Datei an.#goalpage("lineform")# 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   lineform ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   oder: 
+   autoform     ("dateiname") 
+   pageform     ("dateiname") 
+   autopageform ("dateiname") 
+   outline      ("dateiname") 
+#mark ("", "")# 
+   index        ("dateiname") 
+ 
+ 
+ 
+ 
+'lineform'/'autoform' können Sie auch vom EUMEL-Editor aus aufrufen. Zu diesem
+Zweck markieren Sie den zu formatierenden Abschnitt der Datei und geben im
+Kommando-Zustand ( <ESC> <ESC> drücken) 'lineform' bzw. 'autoform' (ohne Para­
+meter). 
+#mark ("", "")# 
+ 
+Das Programm 'pageform'/'autopageform' erzeugt aus der Eingabedatei eine #ib#Druck­
+datei#ie#, die den Namen der angegebenen Eingabedatei mit dem Zusatz '.p' bekommt. 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   pageform ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Als Ergebnis erhalten Sie: "dateiname.p" 
+ 
+ 
+ 
+ 
+Das Programm 'index' kann nur eine Druckdatei bearbeiten: 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   index ("dateiname.p") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+und erstellt die angeforderten Verzeichnisse in Dateien, die mit dem Zusatz
+'.i<nummer>' gekennzeichnet werden. 
+ 
+Beispiele: "dateiname.i1", "dateiname.i2" etc. 
+ 
+ 
+ 
+ 
+'#ib#outline#ie#' erstellt ebenfalls eine neue Datei. 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   outline ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+führt zu dem Ergebnis: "dateiname.outline" #mark ("", "")# 
+#page# 
+ 
+#ib(9)#5.1.3. Vorzeitiger #ib#Abbruch#ie# und 
+       #ib#Fehlermeldungen#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Sie können alle Textkosmetik-Programme vorzeitig abbrechen. Eventuelle
+   Fehlermeldungen werden Ihnen in einem Fenster angezeigt. 
+      #off("i")# 
+#free(1.0)# 
+Durch die #ib#<ESC>#ie(1,"-Abbruch")##ib##ie(1,"Abbruch mit ESC")#-Taste oder die #ib#<SV> #ie#-Taste und das Supervisor-Kommando 'halt'
+können Sie die Textkosmetik-Programme jederzeit vorzeitig abbrechen. Die Eingabe­
+datei steht Ihnen dann unverändert zur Verfügung. Ein #ib#vorzeitiger Abbruch#ie# kann
+notwendig sein, wenn Sie ein Programm mit einer falschen Datei aufgerufen haben
+oder zu viele Fehler gemeldet wurden. 
+#mark ("", "")# 
+ 
+Alle Textkosmetik-Programme melden Fehler, wenn Sie Anweisungen falsch be­
+nutzen. Die Fehlermeldungen werden auf dem Bildschirm angezeigt. Bei Beendigung
+eines Programms wird - falls Fehler entdeckt wurden - automatisch der #ib#Fenster-
+Editor#ie# aufgerufen, wobei die Fehlermeldungen im unteren #ib#Fenster#ie# (das ist das #ib#Notiz­
+buch#ie#) angezeigt werden, während Ihnen im oberen Fenster die Eingabedatei zur
+Korrektur angeboten wird. 
+ 
+____________________________________________________________________________ 
+ 
+.......................dateiname.................Zeile 1     
+ 
+   \#corner1("-5.0")\#\#on("i")\# 
+   Sie können alle Textkosmetik-Programme vorzeitig abbrechen.
+   Eventuelle Fehlermeldungen werden Ihnen in einem Fenster ange­
+   zeigt. 
+   \#box3("T","2","115.0")\#\#off("i")\# 
+   #cursor(" ")# 
+ 
+.......................notebook..................Zeile 1     
+FEHLER Zeile 1: Unbekannte Anweisung (ignoriert): corner1("-5.0") 
+   >>> Bitte Korrigieren 
+FEHLER Zeile 5: Unbekannte Anweisung (ignoriert): 
+   box3("T","2","115.0") 
+   >>> Bitte Korrigieren 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+ 
+Um von der Eingabedatei zum Notizbuch - und umgekehrt - zu wechseln, betätigen
+Sie <ESC> <w>. 
+#page# 
+ 
+#ib(9)#5.2. #ib#Lineform/Autoform#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Die Programme '#ib(1, "ff")#lineform#ie#' oder '#ib(1, "ff")#autoform#ie#' formatieren einen Text zeilenweise (ggf.
+   mit Silbentrennung) unter Berücksichtigung von Schrifttyp und Zeilenbreite. 
+   #off("i")# 
+#free(1.0)# 
+Zur #ib#Zeilenformatierung#ie# werden Ihnen zwei Programme (Kommandos) angeboten, die
+sich nur in ihrem interaktiven Charakter unterscheiden (Behandlung von Silben­
+trennungen): 
+ 
+---- #on("b")##ib#autoform#ie##off("b")#: 
+        Zeilenformatierung mit automatischer #ib#Silbentrennung#ie#. Sie sollten 'autoform'
+        nur bei Texten einsetzen, in denen einige wenige Trennfehler nicht von
+        großer Bedeutung sind, z.B. bei Probedrucken. 
+ 
+---- #on("b")##ib#lineform#ie##off("b")#: 
+        Zeilenformatierung mit Silbentrennung "per Hand", wobei (nach deutschen
+        Trennregeln) ein sinnvoller Trennvorschlag gemacht wird. Die Trennstelle
+        kann interaktiv soweit verschoben werden, wie das zu trennende Wort noch
+        auf die Zeile paßt. 
+ 
+ 
+'lineform'/'autoform' hat im wesentlichen vier Aufgaben: 
+ 
+---- #ib#Auffüllen von Zeilen#ie#: 
+        'lineform'/'autoform' kann besonders gut nach Korrekturen eingesetzt wer­
+        den, bei denen - nach Einfügungen oder Löschungen - nicht vollständige
+        oder zu lange Zeilen in der Datei stehenbleiben können. 
+ 
+---- Erstellen von Zeilen mit unterschiedlichen Schrifttypen: 
+        Werden in einer Datei mehrere Schriftarten (\#type\#-Anweisung) verwendet,
+        berechnet 'lineform'/'autoform' nach der eingestellten Zeilenbreite die Anzahl
+        der Zeichen, die auf eine Zeile passen. 
+ 
+---- Bearbeitung unterschiedlicher Zeilenbreiten: 
+        Manchmal ist es notwendig, die Zeilenbreite zu verändern (\#limit\#-
+        Anweisung). Dies wird von 'autoform'/'lineform' berücksichtigt. 
+ 
+---- Silbentrennung: 
+        Automatische ('autoform') und interaktive Silbentrennung ('lineform'). 
+ 
+ 
+'lineform'/'autoform' akzeptiert als Eingabe eine Datei und verändert diese. Dafür wird
+eine (interne) Zwischendatei benötigt. Deshalb müssen Sie darauf achten, daß noch
+ausreichend Platz auf dem System ist, der jedoch nur zwischenzeitlich für den Forma­
+tierungsschritt benötigt wird. 
+ 
+'lineform' und auch 'pageform' sind auf den ersten Schrifttyp der Fonttabelle, auf eine
+Zeilenbreite von 16.0 und eine Seitenhöhe von 25.0 initialisiert. Sind die ersten An­
+weisungen, die das verändern könnten, fehlerhaft, so bleiben diese Werte (wie auch
+sonst bei ignorierten Anweisungen) erhalten. 
+ 
+'lineform'/'autoform'fragt nach dem Kommando an, mit welchem #ib#Schrifttyp#ie# und mit
+welcher #ib#Zeilenbreite#ie# die Datei formatiert werden soll. Dabei erscheinen zuerst die
+voreingestellten Anweisungen. Beispiel: 
+ 
+____________________________________________________________________________ 
+ 
+LINEFORM (für ... Zeilen): dateiname 
+ 
+Bitte Schrifttyp: micro 
+Zeilenbreite (in cm): 16.0 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Diese Anweisungen können Sie jetzt durch Ihre gewünschten Anweisungen ersetzen.
+Diese Informationen werden von 'autoform'/'lineform' in Form von \#limit\#- und
+\#type\#-Anweisungen in der Datei vermerkt, so daß die Anfragen bei weiteren
+Datei-Bearbeitungen entfallen. 
+ 
+Bei Zeilen, die länger als die angegebene Zeilenbreite sind, werden diejenigen Worte,
+die über die Zeilenbreite hinausgehen, in die nächste Zeile umgebrochen. Kürzere
+Zeilen werden aus der nachfolgenden Zeile bis zur Zeilenbreite aufgefüllt. Worte
+werden jedoch nicht über Absatzgrenzen hinweg verschoben. Deshalb sollten Sie vor
+Anwendung von 'lineform'/'autoform'  darauf achten, daß Absätze richtig markiert
+wurden. Fehlende Markierungen sollten Sie nachträglich einfügen ( <CR> am Ende
+einer Zeile), andernfalls werden Zeilen über Absatzgrenzen zusammengezogen. Dies
+ist besonders bei Tabellenzeilen unangenehm. 
+ 
+#ib#Einrückungen#ie# (Leerzeichen am Anfang einer Zeile) werden von 'lineform'/'autoform'
+ebenfalls bei der Formatierung von Zeilen eingehalten. 
+#page# 
+ 
+#ib(9)#5.2.1. #ib#Zeilenweise formatieren#ie##ie(9)# 
+#free(1.0)# 
+#ib(9)#5.2.1.1. #ib#Interaktive Silbentrennung#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   'lineform' trennt Silben interaktiv, d.h., es werden Ihnen von 'lineform' #ib#Trennungs­
+   vorschläge#ie# gemacht, die Sie bestätigen oder ablehnen können. 
+    #off("i")# 
+#free(1.0)# 
+Paßt ein Wort nicht mehr ganz auf eine Zeile, dann wird es zur interaktiven Tren­
+nung angeboten. Bei der Trennung werden Anweisungen innerhalb des Wortes ent­
+sprechend berücksichtigt. Die Umgebung dieses Wortes wird zur Erleichterung des
+Trennvorgangs mit angezeigt. Das Trennzeichen erscheint an einer sinnvollen Stelle
+im zu trennenden Wort. 
+ 
+____________________________________________________________________________ 
+ 
+   Text vor dem Trennwort; das 
+   Trenn-wort steht mit diesem Text in dieser Zeile 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Der Teil des zu trennenden Wortes, der noch auf die Zeile passen würde, wird mar­
+kiert angezeigt. Sie können das Trennzeichen mit Hilfe der Positionierungstasten
+innerhalb des Trennbereichs verschieben. An der gewünschten Trennposition (der
+Wortteil, der noch auf die Zeile kommen soll, steht links vom Trennstrich) kann die
+<CR>-Taste betätigt werden. <CR> zeigt dem Programm 'lineform' an, daß an dieser
+Stelle die Trennung erfolgen soll. 'lineform' fügt an den ersten Teil des Wortes das
+"-"-Zeichen an und schreibt den abgetrennten Wortteil in die nächste Zeile. 
+#page# 
+Es stehen folgende #ib(1)#Operationen bei der interaktiven Trennung#ie# zur Verfügung: 
+#lpos(0.0)# #bpos(4.0, 11.0)# #table# 
+ 
+#on("b")#Taste             Bedeutung#off("b")#  
+ 
+<CR>            Trennen.  
+ 
+ 
+<<>             Trennzeichen um ein Zeichen nach links verschieben.  
+ 
+ 
+<>>             Trennstelle um ein Zeichen nach rechts verschieben.  
+ 
+ 
+<HOP> <<>  Trennstelle vor das Wort setzen (das Wort wird an
+   dieser Position nicht getrennt).  
+ 
+ 
+<HOP> <>>   Trennstelle an das Ende der Markierung setzen.  
+ 
+ 
+<BLANK>      Trennzeichen wird von "-" auf " " umgeschaltet. 
+   Dies kann verwendet werden, um Worte, die nicht
+   zusammengeschrieben werden sollen, beim Trenn­
+   vorgang in zwei Worte aufzuspalten.  
+ 
+ 
+<->           Schaltet das Trennzeichen von Leerzeichen (" ") 
+   wieder auf den Trennstrich ("-") um.  
+ 
+ 
+<ESC>          Abbruch von 'lineform'/'autoform'. Die zu bearbeitende
+   Datei steht unverändert zur Verfügung.  
+ 
+#tableend##clearpos# 
+#page# 
+Zwei Besonderheiten sind bei der interaktiven Trennung noch zu beachten: 
+ 
+ -  Bei Worten mit Bindestrich wird die Trennstelle hinter dem Bindestrich als Leer­
+    zeichen angezeigt. 
+ 
+ -  Bei einer Trennposition zwischen den Zeichen "ck" wird das Zeichen "c" in ein
+    "k" umgewandelt. 
+ 
+    Beispiel:      Druk-ker 
+ 
+Sofern es für die Zeilenformatierung notwendig ist, macht die Prozedur 'lineform'
+bereits erfolgte Trennungen rückgängig (das Trennzeichen wird entfernt und die
+Wortteile werden wieder zusammengefügt), wenn sich das getrennte Wort (etwa durch
+Korrekturen oder Veränderungen der Zeilenbreite) nicht mehr am Zeilenende befinden
+sollte. 
+ 
+Wenn Sie nicht Ihren Gesamttext mit 'lineform' bearbeiten möchten, haben Sie die
+Möglichkeit, #ib#'lineform' auf einen Textausschnitt#ie# anzuwenden. Hierfür markieren Sie
+den gewünschten Bereich, drücken <ESC> <ESC> und geben im Editor das Kommando
+'lineform'. (siehe S. #topage("lineform")#) 
+ 
+____________________________________________________________________________ 
+ 
+...................dateiname................... Zeile 30     
+ 
+ 
+Wenn Sie nicht Ihren Gesamttext mit 'lineform' bearbeiten 
+möchten/brauchen, haben Sie die Möglichkeit, 
+'lineform' für einen 
+Textausschnitt anzuwenden. Hierfür markieren Sie den gewünschten 
+Bereich, drücken 'ESC' 'ESC'  und 
+geben das Kommando 'lineform'. 
+ 
+ 
+gib kommando:lineform                                     
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+#page# 
+ 
+#ib(9)#5.2.1.2. #ib#Automatische Silbentrennung#ie# mit 
+       '#ib#autoform#ie#'#ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   'autoform' arbeitet wie 'lineform', nur werden die Silbentrennungen automatisch
+   vorgenommen. 
+   #off("i")# 
+#free(1.0)# 
+Ist eine Silbentrennung bei der Formatierung notwendig, übernimmt 'autoform' diese
+automatisch. Die Trennungen werden in das #ib#Notizbuch#ie# eingetragen. Nach Beendigung
+der Formatierung wird die bearbeitete Datei und das Notizbuch zur Kontrolle der
+Silbentrennungen angezeigt. Die automatische Silbentrennung arbeitet mit einer hohen
+#ib#Trenngüte#ie#; allerdings nur für deutsche Texte. Trotzdem kann es vorkommen, daß
+einige Trennungen, insbesondere bei zusammengesetzten Worten, falsch vorgenom­
+men werden. In einem solchen Fall müssen Sie diese nachträglich mit dem Editor
+korrigieren. (vgl. Sie dazu auch 5.8.4.) 
+#page# 
+ 
+#ib(9)#5.2.2. #ib#Unterschiedliche Schriften#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   #ib#Unterschiedliche Schrifttypen#ie# (Schriftarten) können Sie mit der \#type ("schrift­
+   name")\#-Anweisung anfordern. 
+   #off("i")# 
+#free(1.0)# 
+Sie haben die Möglichkeit, mit 'lineform' verschiedenartige #ib#Schrifttypen#ie(1, ", unterschiedliche")# (kurz Typen
+genannt) verarbeiten zu lassen. Jede Type hat eine bestimmte Höhe und jedes Zei­
+chen hat eine bestimmte Breite. Alle Typen werden auf einer Grundlinie gedruckt. 
+ 
+Es gibt zwei Arten von Schriften: 
+bei#on("b")# #ib#äquidistanten Schriften#ie##off("b")# sind alle Zeichen gleich breit (wie bei einer Schreib­
+maschine).#on("b")# #ib#Proportionalschrift#ie##off("b")# findet man in gedruckten Büchern. Hier haben unter­
+schiedliche Zeichen auch unterschiedliche Breiten. Die Zeichen ".", "i", "!" sind z.B.
+schmaler als die Zeichen "w", "o", "m" usw. 
+ 
+Mit der Anweisung: 
+ 
+____________________________________________________________________________ 
+ 
+   \#type ("schriftname")\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+kann auf einen anderen Schrifttyp umgeschaltet werden (auch mehrmals innerhalb
+einer Zeile). Diese Type gilt solange, bis wieder eine neue \#type ("schriftname")\#-
+Anweisung gegeben wird. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+        \#type ("micro")\#Jetzt schreiben wir mit einem
+        Schrifttyp, der 'micro' heißt. Und jetzt
+        \#type ("modern15")\#schalten wir auf eine an­
+        dere Schriftart um. Nun \#type ("modern12")\#
+        möchten wir mit einer größeren Type schrei­
+        ben. Um wieder zu unserem gewohnten Schrift­
+        typ zu gelangen, schalten wir auf \#type
+        ("trium8")\# zurück.  
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild (ohne 'lineform'): 
+ 
+ 
+Jetzt schreiben wir mit einem 
+Schrifttyp, der 'micro' heißt. Und jetzt 
+schalten wir auf eine an­ 
+dere Schriftart um. Nun  
+möchten wir mit einer größeren Type schrei­ 
+ben. Um wieder zu unserem gewohnten Schrift­ 
+typ zu gelangen, schalten wir auf 
+\#type ("trium8")\# zurück. 
+ 
+ 
+ 
+Welche Schriftarten Ihnen zur Verfügung stehen, hängt natürlich von dem verfügbaren
+Drucker ab. Sie können die vorhandenen Schrifttypen mit dem Kommando 'list fonts'
+erfragen. 
+ 
+Schrifttypen können modifiziert, d.h. verändert, gedruckt werden (vergl. Sie dazu den
+nächsten Abschnitt). Durch die Angabe einer \#type ("schriftname")\#-Anweisung
+werden alle Modifikationen ausgeschaltet. 
+#page# 
+#goalpage("on")##goalpage("off")# 
+ 
+#ib(9)#5.2.3. #ib#Veränderung des Schrifttyps#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der #ib#\#on ("..."\#-#ie(1,"Anweisung")# und #ib#\#off ("...")\#-Anweisung#ie# können Sie einen Schrifttyp in
+   seinem Aussehen verändern. Die Schrift wird zwar nicht gewechselt, aber ver­
+   ändert gedruckt. Zur Zeit ist #ib##ie(1,"Unterstreichung")##ib# unterstrichen#ie#, #ib#fett#ie#, #ib#kursiv#ie# und der Druck von#ib# weiß auf
+   schwarz #ie#möglich (abhängig vom eingesetzten Drucker). 
+   #off("i")#  
+#free(0.7)# 
+Die \#on\#/\#off\#-Anweisung wirkt wie ein Schalter, der die gewünschte #ib#Schrifttyp-
+Modifikation#ie# ein- bzw. ausschaltet. Die Anweisung \#on\# schaltet die Modifikation ein,
+\#off\# schaltet sie aus. 
+ 
+____________________________________________________________________________ 
+ 
+  Das EUMEL-System ermöglicht es Ihnen, 
+ 
+  \#on ("italic")\#kursiv\#off ("italic")\# 
+  \#on ("i")\#           \#off ("i")\# 
+ 
+  und 
+ 
+  \#on ("underline")\#unterstrichen\#off ("underline")\# 
+  \#on ("u")\#                     \#off ("u")\# 
+ 
+  und 
+ 
+  \#on ("bold")\#fett\#off ("bold")\# 
+  \#on ("b")\#       \#off ("b")\# 
+ 
+  und 
+ 
+  \#on ("reverse")\#invers (weiß auf schwarz)\#off ("reverse")\# 
+  \#on ("r")\#                               \#off ("r")\# 
+ 
+  zu schreiben 
+ 
+____________________________________________________________________________ 
+#page# 
+Druckbild: 
+ 
+ 
+  Das EUMEL-System ermöglicht es Ihnen, 
+ 
+  #on("i")#kursiv#off("i")# 
+ 
+  und 
+ 
+  #on("underline")#unterstrichen#off("underline")# 
+ 
+  und 
+ 
+  #on("b")#fett#off("b")# 
+ 
+  und 
+ 
+  #on("reverse")#invers (weiß auf schwarz)#off("reverse")# 
+ 
+  zu schreiben. 
+ 
+ 
+ 
+Dabei sollten Sie folgendes beachten: 
+ 
+a) Ein \#type\#-Anweisung schaltet immer eine vorausgehende Modifikation aus, d.h.
+   ein Schrifttypwechsel macht eventuelle \#off ("b")\#-, \#off ("u")\#-, \#off ("i")\#-
+   und \#off ("r")\#-Anweisungen überflüssig. 
+ 
+b) 'lineform'/'autoform' erzeugt eine Warnung, falls Sie vergessen haben, eine Modi­
+   fikation auszuschalten. 
+ 
+c) Nicht alle Drucker können die hier angegebenen Modifikationen auch drucken.
+   Welche Modifikationen gleichzeitig eingeschaltet werden können, ist ebenfalls
+   druckerabhängig. 
+#page# 
+ 
+#ib(9)#5.2.4. #ib#Gesperrt schreiben#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Die Silbentrennung an einem Leerzeichen verhindert man durch Verwendung des
+   geschützten Leerzeichens 'ESC' und 'Leertaste'. 
+   #off("i")# 
+#free(1.0)# 
+Möchten Sie ein Wort g e s p e r r t schreiben, muß natürlich verhindert werden, daß
+dieses Wort beim Formatieren getrennt wird. Andere Worte, wie z.B. in Formeln,
+sollten ebenfalls zusammen auf eine Zeile geschrieben werden (z.B. 'sin (x)'). Dies
+können Sie erreichen, indem Sie nicht das Leerzeichen zwischen die Zeichen schrei­
+ben, denn das Leerzeichen bedeutet für 'autoform'/'lineform' immer das Ende eines
+Wortes. Stattdessen verwenden Sie <ESC> <Leertaste>. Das geschützte Leerzeichen
+erscheint auf dem Bildschirm zur besseren Identifizierung invers dargestellt bzw. als
+ein anderes Zeichen (abhängig von Ihrem Gerät). Beim Drucken wird jedoch wieder
+ein Leerzeichen produziert. 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+     g e s p e r r t 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+     g e s p e r r t 
+ 
+ 
+ 
+#page# 
+#goalpage("limit")# 
+ 
+#ib(9)#5.2.5. #ib#Zeilenbreite einstellen#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der #ib#\#limit\#-Anweisung#ie# können Sie die Zeilenbreite einstellen. 
+   #off("i")# 
+#free(1.0)# 
+Die \#limit\#-Anweisung gibt in cm an, wie breit die Zeile sein soll. Beachten Sie, daß
+diese Anweisung nichts mit dem Editor-Kommando 'limit' zu tun hat. Dieses gibt an,
+wie viele Zeichen eine Bildschirmzeile lang sein soll. 
+ 
+Die Zeilenbreite wird zusammen mit dem Schrifttyp beim erstmaligen Aufruf von
+'autoform'/'lineform' interaktiv erfragt und als \#limit\#-Anweisung (zusammen mit der
+\#type\#-Anweisung) in die erste Zeile der Datei eingetragen. Sie kann in einer Datei
+mehrmals verändert werden. 
+ 
+Die neue Zeilenbreite gilt immer ab der #on("b")#nächsten#off("b")# Zeile, die der \#limit\#-Anweisung
+folgt. Beachten Sie, daß Sie als Parameter in der \#limit\#-Anweisung eine Zahl mit
+Dezimalpunkt und Nachkommastelle angeben müssen. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+\#limit(9.0)\# 
+       Mit der \#limit\#-Anweisung können Sie Para­
+       graphen in einem anderen Format leicht gestal­
+       ten. Die rechte Schreibgrenze wird durch die
+       \#limit\#-Anweisung eingestellt, wobei Sie den
+       linken Rand durch eine entsprechende Ein­
+       rückung gestalten können. 
+\#limit(11.0)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild (mit 'lineform' bearbeitet): 
+ 
+ 
+       Mit der \#limit\#-Anweisung können Sie Paragraphen in einem
+       anderen Format leicht gestalten. Die rechte Schreibgrenze
+       wird durch die \#limit\#-Anweisung eingestellt, wobei Sie den
+       linken Rand durch eine entsprechende Einrückung gestalten
+       können. 
+ 
+ 
+ 
+Die folgende Tabelle gibt sinnvolle #ib#'limit'-Einstellungen#ie# für die am häufigsten ver­
+wendeten Papiergrößen an: 
+ 
+ 
+      #on("b")#Format          'limit'          Verbleibender 
+                      (Zeilenbreite)   Rand#off("b")# 
+ 
+      DIN A4          16.0 cm          je 2.50 cm 
+ 
+      DIN A5          12.0 cm          je 1.42 cm 
+ 
+      DIN A4 quer     25.0 cm          je 2.35 cm 
+#page# 
+#goalpage("einfache Tabellen")# 
+ 
+#ib(9)#5.2.6. Einfache #ib#Tabellen#ie(1,", einfache")# und #ib#Aufzählungen#ie# 
+       schreiben#ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Aufzählungen und einfache #ib#Tabellen#ie(1, ", einfache")# werden automatisch richtig formatiert und
+   gedruckt, wenn Sie sich an einige einfache Regeln halten. 
+   #off("i")# 
+#free(1.0)# 
+Verwenden Sie eine #ib#Proportionalschrift#ie# beim Tabellenschreiben, so sind die Spalten in
+der Regel unterschiedlich breit, selbst wenn Sie eine gleiche Anzahl Zeichen in jeder
+Spalte schreiben. Dies können Sie durch das Schreiben von einem "#ib#Doppelblank#ie#"
+("#ib#Mehrfachblank#ie#") vermeiden; für kompliziertere Tabellen gibt es spezielle Tabellen­
+anweisungen. (siehe auch S. #topage("tabellenanw")#) 
+ 
+____________________________________________________________________________ 
+ 
+   iiii ooooo              
+   mmmm lllll              
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Druckbild: 
+ 
+ 
+   iiii ooooo 
+   mmmm lllll 
+ 
+Erste und zweite Spalte stehen nicht untereinander. 
+ 
+ 
+Aber mit Doppelblanks: 
+ 
+____________________________________________________________________________ 
+ 
+   iiii    ooooo        
+   mmmm    lllll        
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+     
+    iiii    ooooo 
+    mmmm    lllll 
+ 
+Erste und zweite Spalte stehen jetzt untereinander. 
+ 
+Das Doppelblank dient 'lineform'/'autoform' und dem Drucker als Zeichen, daß die
+Positionen speziell berechnet und beim Druck berücksichtigt werden müssen. Das gilt
+nur nach einer Absatzzeile. In seltenen Fällen (insbesondere beim Einsatz von Schrift­
+typen, die in der Größe stark voneinander abweichen) kann es vorkommen, daß diese
+Tabellenautomatik nicht funktioniert und Spalten übereinander gedruckt werden. In
+solchen Fällen müssen Sie die Anzahl der trennenden Doppelblanks erhöhen. 
+ 
+#on("b")##on("is")#Praktischer Tip:#off("is")##off("b")# 
+Beachten Sie, daß es für das Funktionieren der "#ib#Tabellenautomatik#ie#" erforderlich ist,
+daß jede Tabellenzeile eine Absatzzeile ist. Man sollte diese Zeilen vor dem Druck
+daraufhin überprüfen oder durch 'lineform'/'autoform' die Datei bearbeiten lassen.
+Sollten durch die zeilenweise Formatierung einmal wegen fehlender Absatzkennzeich­
+nung zwei Zeilen zusammengezogen sein, können Sie diese leicht mit dem Editor
+wieder "auseinanderbrechen" ( <HOP> <RUBIN> ,  <CR> und <HOP> <RUBIN> ). 
+ 
+ 
+Ähnliches gilt bei Aufzählungen. 
+ 
+____________________________________________________________________________ 
+ 
+   1)  Das ist die erste Aufzählung.                              
+       Dieser Satz wird bündig gedruckt.                          
+   2)  Hier auch.                                                 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+ 
+   1)  Das ist die erste Aufzählung. 
+       Dieser Satz wird bündig gedruckt. 
+   2)  Hier auch. 
+ 
+ 
+Auch in solchen Fällen wird der gedruckte Text in der Regel richtig eingerückt. Die
+#ib#Tabellenautomatik#ie# wirkt nur nach einem Absatz. Hier aber ein Beispiel für eine
+typische Fehlersituation: 
+ 
+____________________________________________________________________________ 
+ 
+   \#type("normal")\#                                 
+   1. Aufzählung                                    
+   2. Aufzählung                                    
+   3. Aufzählung                                    
+                                                    
+   \#type("fett")\#M1. Aufzählung                     
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Einrückbreite wird durch den Schrifttyp bestimmt, der vor der Zeile herrscht, und
+den ganzen Absatz über beibehalten. 
+ 
+ 
+Druckbild: 
+ 
+ 
+   1. Aufzählung 
+   2. Aufzählung 
+   3. Aufzählung 
+ 
+   M1. Aufzählung 
+ 
+ 
+Das Blank zwischen 'M1.' und 'Aufzählung' reicht nicht aus, um eine Überschreibung
+zu verhindern. Diesen Fehler können Sie umgehen, indem Sie die \#type\#-Anweisung
+in eine gesonderte Zeile stellen. Richtig wäre folgendes (gewünschter Schrifttyp vor
+die Zeile!): 
+ 
+____________________________________________________________________________ 
+ 
+   \#type("trium8")\#                                 
+   1. Aufzählung                                    
+   2. Aufzählung                                    
+   3. Aufzählung                                    
+                                                    
+   \#type("triumb14")\#                               
+   M1. Aufzählung                                   
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Druckbild: 
+ 
+ 
+   1. Aufzählung 
+   2. Aufzählung 
+   3. Aufzählung 
+ 
+    
+  M1. Aufzählung 
+ 
+      
+Die genauen Regeln sind etwas kompliziert, so daß sie hier nicht einzeln aufgeführt
+werden (siehe S. 5-89#topage("block")# unter der Anweisung \#block\#). Treffen Sie auf einen der
+seltenen Fälle, wo die Tabellenautomatik nicht funktioniert, können Sie immer noch
+Tabellen-Anweisungen verwenden. 
+#mark ("", "")# 
+#page# 
+ 
+#goalpage("tabellenanw")# 
+#ib(9)#5.2.6.1. #ib#Tabellenanweisungen#ie##ie(9)# 
+#free(1.0)# 
+   Mit den Tabellenanweisungen der Textkosmetik können Sie auf einfache Art Tabel­
+   len auch mit Porportionalschriften gestalten. 
+#free(1.0)# 
+Es ist sehr einfach, eine Tabelle in einer äquidistanten Schrift zu schreiben, denn
+hierbei stimmt das Schriftbild auf dem Terminal weitgehend mit dem späteren Druck
+überein. Bei einer äquidistanten Schrift ist jedes Zeichen gleich breit - Sie können
+also "sehen", an welcher Zeilenposition eine neue Spalte beginnt. 
+ 
+Etwas schwieriger sind Tabellen mit Proportionalschriften, da hier jedes Zeichen eine
+unterschiedliche Breite hat. Sie können somit einer Spaltenbreite nicht direkt "an­
+sehen", wie breit sie beim Druck wirklich wird. "Einfache" Tabellen können Sie mit
+dem Mehrfachblank gestalten (siehe S. 5-27). Bei komplizierteren Tabellen müssen
+Sie die folgenden Tabellenanweisungen benutzen. 
+ 
+Um eine Tabelle zu gestalten, gehen Sie folgendermaßen vor: 
+ 
+-  Definieren Sie die Spaltenpositionen der Tabelle mit den folgenden Anweisungen.
+   Für die Punkte bei den Anweisungen müssen Sie entsprechende Parameter
+   einsetzen. 
+ 
+#goalpage("lpos")##goalpage("rpos")##goalpage("cpos")##goalpage("dpos")##goalpage("bpos")# 
+#goalpage("fillchar")# 
+____________________________________________________________________________ 
+ 
+   #ib#\#l pos#ie(1,"-Anweisung")# (...)\#          (* linksbündig *) 
+   #ib#\#r pos#ie(1,"-Anweisung")# (...)\#          (* rechtsbündig *) 
+   #ib#\#c pos#ie(1,"-Anweisung")# (...)\#          (* zentrierend *) 
+   #ib#\#d pos#ie(1,"-Anweisung")# (..., ...)\#     (* zentrierend um eine Zeichenkette *)
+   #ib#\#b pos#ie(1,"-Anweisung")# (..., ...)\#     (* Blocksatz in einer Spalte *) 
+   #ib#\#fillchar#ie(1,"-Anweisung")# (...)\#       (* Füllzeichen zwischen Spalten *) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   Die Zentrierung um eine Zeichenkette ist wie folgt zu verstehen: Die Spalte wird
+   bis zum Anfang der angegebenen Zeichenkette rechtsbündig und ab der Zeichen­
+   kette linksbündig geschrieben. 
+ 
+#goalpage("table")# 
+-  Schreiben Sie dann die Tabelle. Sie muß von den Anweisungen 
+ 
+____________________________________________________________________________ 
+ 
+   #ib#\#table\##ie(1,"-Anweisung")# 
+ 
+ 
+   #ib#\#table end\##ie(1,"-Anweisung")# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+   eingefaßt werden. Die Spalten in der Tabelle müssen Sie durch mindestens zwei
+   Leerzeichen voneinander trennen. Es müssen alle Spalten in einer Tabelle vor­
+   handen sein. Soll einmal eine Spalte leer bleiben, müssen Sie für diese Spalte ein
+   #ib#geschütztes Leerzeichen#ie# verwenden. 
+ 
+-  Da die Spaltenpositionen erhalten bleiben (auch über die Anweisung \#table end\#
+   hinweg), sollten Sie direkt hinter dem Tabellenende die #ib#\#clear pos\#-Anweisung#ie#
+   geben. 
+ 
+-  Dann können Sie 'lineform'/'autoform' vornehmen. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+     \#r pos (2.2)\#\#c pos (3.8)\#\#l pos (5.8)\#\#d pos (8.8, ".")\#    
+     \#table\#                                                      
+     erste Spalte  zweite Spalte  dritte Spalte   vierte Spalte   
+     rechtsbündig  zentriert      linksbündig     dezi.mal        
+     1234          1234           1234            12.34           
+     12345         12345          12345           123.45          
+     123456        123456         123456          1234.56         
+     \#table end\# \#clear pos\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+ 
+     #r pos (2.2)##c pos (3.8)##l pos (5.8)##d pos (8.8, ".")# 
+     #table# 
+     erste Spalte  zweite Spalte  dritte Spalte   vierte. Spalte 
+     rechtsbündig  zentriert      linksbündig     dezi.mal 
+     1234          1234           1234            12.34 
+     12345         12345          12345           123.45 
+     123456        123456         123456          1234.56 
+     #table end##clear pos# 
+ 
+ 
+ 
+Solche Tabellen können Sie in \#head\#, \#bottom\# oder innerhalb von Fußnoten schrei­
+ben. Es ist jedoch nicht möglich, eine Fußnote innerhalb dieser Tabelle zu definieren. 
+Ausweg: Tabelle um die Fußnote aufspalten. 
+#page# 
+ 
+#ib(9)#5.2.6.2. Einstellen der #ib#Tabellenpositionen#ie (1, ", Einstellen von")##ie(9)# 
+#free(0.7)# 
+   #on("i")# 
+   Mit den \#pos\#-Anweisungen können Sie eine bestimmte Position innerhalb der
+   Tabelle einstellen, zugleich aber auch bestimmen, wie die Spalte gedruckt werden
+   soll. #off("i")# 
+    
+#free(0.7)# 
+____________________________________________________________________________ 
+ 
+   \#l pos (5.0)\#\#r pos (10.0)\#\#d pos (15.0, ".")\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Anweisung oben stellt die erste Spalte der Tabelle auf 5 cm vom Rand ein (links­
+bündig). Die zweite Spalte endet 10 cm vom Rand, wobei diese Spalte rechtsbündig
+geschrieben werden soll. Die dritte wird an die Position 15, zentriert um den Dezimal­
+punkt, gedruckt#u##count#)#e#.#foot# 
+#u##value#)#e# Spaltenposition < 0.0 und Spaltenposition > 'eingestelltes limit' sind nicht
+    erlaubt. 
+#end# 
+ 
+Beachten Sie, daß ein "Überlappen" von Spalten erfolgen kann (in unserem Beispiel
+kann die erste Spalte in die zweite hineinschreiben). 'lineform' bzw. 'autoform' meldet
+bei Spalten-Überschreibungen einen entsprechenden Fehler. 
+ 
+Für jede Spaltenposition nehmen Sie ein Element einer Zeile. Die Elemente müssen
+Sie beim Schreiben im Editor durch mindestens zwei Leerzeichen voneinander tren­
+nen. Auf die erste Spaltenposition wird das erste Element gedruckt, auf die zweite
+Position das zweite Element usw. Für das Drucken der Spalten wird der eingeschal­
+tete Schrifttyp mit möglicherweise einer Modifikation genommen. Der Schrifttyp und
+die Modifikation können innerhalb der Tabelle geändert werden#u##count#)#e#.#foot# 
+#u##value#)#e# Die Zwischenräume zwischen den Spalten werden nicht modifiziert (also z.B.
+   nicht unterstrichen). 
+#end# 
+ 
+Beachten Sie, daß die Tabellenpositionen so lange erhalten bleiben, bis sie explizit
+gelöscht werden (\#clear pos\#-Anweisung, siehe S. 5-38). 
+#page# 
+ 
+#ib(9)#5.2.6.3. #ib#Blocksatz innerhalb einer Spalte#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Für Blocksatz innerhalb einer Spalte verwenden Sie die \#b pos (...)\#-Anweisung. 
+   #off("i")# 
+#free(1.0)# 
+____________________________________________________________________________ 
+ 
+\#l pos (0.0)\#\#b pos (2.2, 8.0)\#\#l pos (9.0)\#                      
+\#table\#                                                           
+1. Spalte  Die mittlere Spalte wird bis zur Druck­    3. Spalte   
+1. Spalte  position '8.0' in Blocksatz gedruckt. Um   3. Spalte   
+1. Spalte  in dieser Spalte einen Absatz zu bekom­    3. Spalte   
+1. Spalte  men, muß ein geschütztes Leerzeichen am    3. Spalte   
+1. Spalte  Ende der Spalte stehen. #cursor(" ")#                  3. Spalte   
+\#table end\# \#clear pos\#                                           
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Druckbild: 
+ 
+#l pos (0.0)##b pos (2.2, 8.0)##l pos (9.0)# 
+#table# 
+1. Spalte  Die mittlere Spalte wird bis zur Druck­    3. Spalte 
+1. Spalte  position '8.0' in Blocksatz gedruckt. Um   3. Spalte 
+1. Spalte  in dieser Spalte einen Absatz zu bekom­    3. Spalte 
+1. Spalte  men, muß ein geschütztes Leerzeichen am    3. Spalte 
+1. Spalte  Ende der Spalte stehen.                    3. Spalte 
+#table end##clear pos# 
+#page# 
+ 
+#ib(9)#5.2.6.4. #ib#Tabellenspalten auffüllen#ie# (#ib#Füllzeichen#ie#)#ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der \#fillchar\#-Anweisung können Sie Spaltenzwischenräume füllen. 
+   #off("i")# 
+#free(1.0)# 
+Angenommen, Sie möchten eine Rechnung erstellen. Die Warenposten sollen links­
+bündig an der Druckposition '0.0' und die Beträge rechtsbündig an der Position '9.0'
+gedruckt werden. Zwischen einem Warenposten und dem dazugehörigen Betrag sollen
+entsprechend viele Punkte ('.') gedruckt werden. Das folgende Druckbild: 
+ 
+#l pos (0.0)##r pos (9.0)##fillchar(".")# 
+#table# 
+30 Benutzerhandbücher                 450,-DM 
+10 Systemhandbücher                   150,-DM 
+ 
+#table end##clear pos# 
+ 
+wird mit 
+ 
+____________________________________________________________________________ 
+ 
+   \#l pos (0.0)\#\#r pos (9.0)\#\#fillchar(".")\# 
+   \#table\# 
+   30 Benutzerhandbücher              450,-DM 
+   10 Systemhandbücher                150,-DM 
+ 
+   \#table end\#\#clear pos\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+erreicht. Mit der Anweisung \##ib#fillchar#ie#\# stellen Sie das/die #ib#Füllzeichen#ie# ein. Somit wer­
+den entsprechend viele Füllzeichen (anstatt der Leerzeichen) von dem Textende einer
+Spalte bis zu dem Textanfang der nächsten Spalte gedruckt. Die Füllzeichen bleiben
+so lange eingestellt, bis erneut die Anweisung \#fillchar\# gegeben wird. Insbesondere
+bleibt das Füllzeichen - genauso wie auch die eingestellten Spaltenpositionen -
+über das Tabellenende erhalten. Die Anweisung \#clear pos\# löscht - zusätzlich zu
+den Tabellenpositionen - auch das eingestellte Füllzeichen (setzt das Zeichen auf ' '
+zurück). 
+ 
+Beachten Sie, daß die Füllzeichen direkt gedruckt werden (also ohne Leerzeichen
+zwischen dem Spaltentext und den Füllzeichen). Möchten Sie einen Zwischenraum
+zwischen dem Spaltentext und den Füllzeichen haben, dann fügen Sie ein geschütz­
+tes Leerzeichen an den Spaltentext an oder setzen eins vor die nachfolgende Spalte. 
+ 
+Die Anweisung \#fillchar\# gilt für Zwischenräume zwischen allen Spalten. Soll nur #on("i")#ein#off("i")#
+Spaltenzwischenraum ausgefüllt werden, müssen Sie die \#fillchar\#-Anweisung in der
+Tabelle entsprechend geben. 
+ 
+____________________________________________________________________________ 
+ 
+   \#l pos (1.0)\#\#r pos (5.0)\#\#r pos (10.0)\#                        
+   \#table\#                                                         
+   1\#fillchar(".")\#    3\#fillchar(" ")\#   4                        
+   2\#fillchar(".")\#   17\#fillchar(" ")\#   6  
+   \#table end\#                                                     
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Druckbild: 
+ 
+#l pos (1.0)##r pos (5.0)##r pos(10.0)# 
+#table# 
+1#fillchar(".")#    3#fillchar(" ")#   4 
+2#fillchar(".")#   17#fillchar(" ")#   6 
+#tableend##clear pos# 
+ 
+ 
+ 
+ 
+Eingeschaltete Modifikationen gelten in diesem Fall auch für die Spaltenzwischen­
+räume. 
+#page# 
+ 
+#ib(9)#5.2.6.5. #ib#Tabellenpositionen löschen#ie##ie(9)# 
+#goalpage("clearpos")# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der #ib#\#clear pos\#-Anweisung#ie# löschen Sie alle eingestellten Positionen. 
+    #off("i")# 
+#free(1.0)# 
+Sollen gänzlich neue Positionen eingestellt werden, benutzen Sie die Anweisung 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   \##ib#clear pos#ie(1,"-Anweisung")#\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ohne Parameter. Sie löscht alle eingestellten Tabellenpositionen. Beachten Sie, daß
+\#clear pos\# auch das Füllzeichen für die \#fillchar\#-Anweisung löscht (es wird wieder
+ein ' ' voreingestellt). Eine einzelne Tabellenposition können Sie z.B. mit 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   \#clear pos (10.0)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+löschen. 
+#mark ("","")# 
+#page# 
+ 
+#goalpage("u")##goalpage("d")# 
+#ib(9)#5.2.7. #ib#Indizes#ie# und #ib#Exponenten#ie##ie(9)# 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Mit den Anweisungen #ib#\#u\##ie(1, "-Anweisung")#, #ib#\#d\##ie(1,"-Anweisung")# und #ib#\#e\##ie(1,"-Anweisung")# können Sie Exponenten und Indizes
+   schreiben. 
+   #off("i")# 
+#free(1.0)# 
+Die Anweisung \#u\# (steht für 'up') schaltet auf eine Exponenten-Schreibweise um
+und zwar so lange, bis die Anweisung \#e\# (steht für 'end') angetroffen wird. Dabei
+wird automatisch auf den nächst kleineren Schrifttyp umgeschaltet (sofern vorhanden). 
+ 
+____________________________________________________________________________ 
+ 
+     a\#u\#i,k\#e\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+     a#u#i,k#e# 
+ 
+ 
+ 
+Die \#d\#-Anweisung ('d' steht für 'down') ist für Indizes gedacht und arbeitet analog
+zur \#u\#-Anweisung. 
+ 
+____________________________________________________________________________ 
+ 
+     a\#d\#i,k\#e\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+     a#d#i,k#e# 
+ 
+ 
+Die automatische Umschaltung auf den nächst kleineren Schrifttyp erfolgt nur, wenn
+in der #ib#Fonttabelle#ie# ein nächst kleinerer Schrifttyp angegeben ist. Sonst wird der ein­
+gestellte Schrifttyp für den Exponenten beibehalten. 
+ 
+Nach der \#e\#-Anweisung wird automatisch wieder der Schrifttyp eingestellt, der vor
+der zugehörigen \#u\#-Anweisung galt. Die \#u\#- und \#e\#-Anweisungen bilden also
+Klammern. Innerhalb einer Anweisung kann jede beliebige, sinnvolle Textkosmetik-
+Anweisung stehen. Beachten Sie, daß Anweisungen innerhalb einer Klammer die
+Zeilenhöhe nicht verändern sollen. Wenn Sie beispielsweise eine \#type\#-Anweisung
+in eine Klammer schreiben, wird zwar der Index/Exponent in diesem Schrifttyp ge­
+druckt, aber der Drucker geht davon aus, daß die Zeilenhöhe nicht überschritten wird.
+Deshalb ist es angeraten, nur einen kleineren Schrifttyp innerhalb eines Index/Expo­
+nenten zu verwenden. Wie bereits erwähnt, wird auch in diesem Beispiel nach dem
+Klammerende auf den vorher eingestellten Schrifttyp zurückgestellt. 
+ 
+Die Index/Exponenten-Klammern können auch geschachtelt werden. 
+ 
+____________________________________________________________________________ 
+ 
+     a\#u\#um 1 hoch\#u\#noch 1 hoch\#e\#um 1 zurück\#e\# Grundlinie 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+       a#u#um 1 hoch#u#noch 1 hoch#e#um 1 zurück#e# Grundlinie 
+ 
+ 
+ 
+Es gelten folgende #on("b")#Einschränkungen#off("b")#: 
+ 
+1. Ein Exponent (Index) wird so positioniert, daß es in der Regel keine Überschrei­
+   bung mit der vorhergehenden (nachfolgenden) Zeile gibt. 
+ 
+2. Bei mehrfachen Exponenten oder Indizes oder bei Umschaltung auf einen anderen
+   Schrifttyp innerhalb eines Exponenten (Index) oder wenn nicht auf einen kleineren
+   Schrifttyp umgeschaltet werden kann, besteht die Möglichkeit, daß der Exponent
+   oder Index über die "normale" Zeile hinausragt. In diesem Fall kann es Über­
+   schreibungen geben, die Sie mit der #ib#\#linefeed\#-Anweisung#ie# ausgleichen können. 
+ 
+3. Eine Exponenten- oder Index-Klammer muß als Ganzes auf einer Zeile stehen. 
+ 
+4. Gleichzeitige Exponenten- und Index-Ausdrücke, die übereinander stehen
+   sollen, sind zur Zeit mit den \#u\#/\#d\#-Anweisungen nicht möglich. Jedoch funk­
+   tioniert folgendes: 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   a\#u\#Exponent\#d\#Index des Exponenten\#e\#\#e\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+   Druckbild: 
+ 
+   a#u#Exponent#d#Index des Exponenten#e##e# 
+ 
+ 
+ 
+5. Doppelblanks spielen innerhalb einer solchen Klammer keine Rolle, wirken also
+   wie zwei "normale" Leerzeichen und nicht als implizite Positionierung. Innerhalb
+   einer solchen Klammer werden Blanks, sofern die Anweisung \#block\# gegeben
+   wurde, nicht verbreitert. 
+ 
+6. Indizes oder Exponenten sollten nicht mit den Modifikationen \#underline\# und/oder
+   \#reverse\# zusammen verwendet werden, da z.B. ein Unterstreichen von Indizes
+   und Exponenten innerhalb einer unterstrichenen Zeile zu einem solchen Ergebnis
+   führt: 
+ 
+ 
+   Druckbild: 
+ 
+   #on("u")#Indizes und Exponenten   a#d#i,k#e#   a#u#i,k#e#   sollten nicht unterstrichen werden!#off("u")# 
+#page# 
+
diff --git a/doc/user/benutzerhandbuch.5b b/doc/user/benutzerhandbuch.5b
new file mode 100644
index 0000000..748e398
--- /dev/null
+++ b/doc/user/benutzerhandbuch.5b
@@ -0,0 +1,1632 @@
+#start(5.0,1.5)##pagenr("%",42)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Teil 5: Textkosmetik und Druck        
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+5 - %      GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        5 - % 
+#tableend##clearpos# 
+#end# 
+ 
+#ib(9)#5.3.   #ib#Pageform#ie##ie(9)# 
+#free(1.0)# 
+#ib(9)#5.3.1. #ib#Seitenweise formatieren#ie##ie(9)#  
+#goalpage("pageform")##goalpage ("autopageform")# 
+#free(1.0)# 
+   #on("i")# 
+   'pageform'/'autopageform' formatiert eine Datei seitenweise und erledigt Routine­
+   arbeiten wie die Plazierung von Fußnoten, Seitennumerierung usw. 
+   #off("i")# 
+#free(1.0)# 
+ 
+Das Programm 'pageform' können Sie mit dem Kommando 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   pageform ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+aufrufen. 'pageform' erzeugt aus der Eingabedatei (z.B.: "dateiname") eine Druck­
+datei, deren Name durch ein angehängtes '.p' gebildet wird (z.B.: "dateiname.p"). 
+ 
+Die von 'pageform' erzeugte Druckdatei besteht aus der Eingabedatei mit ggf. neu
+eingefügten Zeilen. Die eingesetzten Zeilen stammen aus \#head\#-, \#bottom\#- oder
+\#foot\#-Anweisungen. Dadurch erhöht sich die Zeilenanzahl der Datei. 
+ 
+Sie können in Kopf- oder Fußzeilen Seitennummern aufnehmen. Diese Seiten­
+nummern werden von 'pageform'/'autopageform' bei Seitenwechseln automatisch
+erhöht und an eine von Ihnen gekennzeichnete Stelle eingesetzt. Fußnoten können
+auch durch Nummern gekennzeichnet werden. Querverweise sind ebenfalls möglich. 
+#page# 
+Nachdem 'pageform' eventuelle Kopf-, Fuß- und Fußnotenzeilen eingefügt hat,
+berechnet es die Anzahl von Zeilen, die auf eine Seite passen, aus den Angaben für
+Seitenlänge und Zeilenvorschub und aus der Höhe der eingestellten Schrifttypen
+(\#type\#-Anweisung). Dann zeigt 'pageform' das errechnete Seitenende auf dem Bild­
+schirm an. Das Seitenende kann interaktiv verschoben werden, um es an eine ge­
+wünschte Stelle zu plazieren und es können Leerzeilen eingefügt/gelöscht werden, um
+Seiten gleich lang zu machen. Zusätzlich können Sie Seiten in Spalten ("Zeitungs­
+druck") aufteilen und diese interaktiv formatieren. 
+ 
+Bei mehreren Schrifttypen innerhalb einer Zeile wird als Zeilenhöhe automatisch die
+des größten Schrifttyps genommen. Dabei müssen Sie bedenken, daß zu Beginn der
+Zeile immer der Schrifttyp der vorherigen Zeile eingeschaltet ist. 
+#page# 
+ 
+#ib(9)#5.3.1.1. #ib#Automatische Seitenformatierung#ie(9)##ie# 
+#free(1.0)# 
+ 
+   #on("i")# 
+   'autopageform' arbeitet wie 'pageform', jedoch werden die Seitenenden automa­
+   tisch plaziert. 
+   #off("i")# 
+#free(1.0)# 
+'autopageform' sucht zuerst das rechnerische Seitenende. Ist dort ein Absatz vor­
+handen, wird die Seite an dieser Stelle beendet. Falls nicht, sucht 'autopageform'
+nach oben in den nächsten vier Zeilen nach einem Absatz. Wird keiner gefunden,
+wird die Seite am rechnerischen Seitenende beendet. 
+ 
+Ist die \#pageblock\#-Anweisung gegeben, wird zuerst nach oben in den vier letzten
+Zeilen nach einem Absatz gesucht, um dort die Seite zu beenden. Ist dort keiner
+vorhanden, wird auch über das rechnerische Seitenende hinweg versucht, die Seiten­
+länge zu plazieren (4 Zeilen). 'autopageform' beachtet in einem solchen Fall die
+'pagelength'-Anweisung, indem der Zeilenabstand gestaucht wird. 
+#page# 
+ 
+#ib(9)#5.3.1.2. #ib#Seitenende interaktiv verschieben#ie# #ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   In diesem Abschnitt wird beschrieben, welche interaktiven Möglichkeiten Ihnen
+   'pageform' bietet, Seiten zu gestalten. 
+   #off("i")# 
+#free(1.0)# 
+Auf dem Bildschirm wird das von 'pageform' errechnete jeweilige Seitenende unter
+Angabe der aktuellen Seitennummer angezeigt. Das Seitenende erscheint ungefähr in
+der Mitte des Bildschirmes und wird durch eine von 'pageform' erzeugte Zeile ge­
+kennzeichnet, die auch - nach erfolgter Seitenformatierung - in der Druckdatei zu
+sehen ist. Der EUMEL-Drucker druckt diese Zeile nicht. 
+ 
+____________________________________________________________________________ 
+ 
+Mehrere Fußnoten innerhalb einer Seite werden von 'pageform'/­
+'autopageform' in der Reihenfolge ihres Auftretens gesammelt und
+am Ende der Seite plaziert. Für eine entsprechende Trennung der
+Fußnoten voneinander (z.B. durch Leerzeilen) müssen Sie selbst
+sorgen. 
+\#page\#\#--------------------- Ende Seite 215 --------\#                
+Unter Umständen paßt die Fußnote nicht mehr auf die aktuelle
+Seite und muß deshalb von 'pageform'/'autopageform' auf die näch­
+ste Seite gebracht werden. 'pageform'/'autopageform' geht davon
+aus, daß die Kennzeichnung der Fußnote in der Zeile unmittelbar
+vor der Fußnote steht und bringt diese Zeile ebenfalls auf die
+neue Seite. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Über der Markierung erscheinen die letzten Zeilen der bereits verarbeiteten Seite,
+darunter die ersten Zeilen der nächsten Seite. Sie können nun mit Hilfe der Positio­
+nierungstasten die Markierung und damit das Seitenende nach oben verschieben.
+Damit vermeiden Sie, daß ein logisch zusammengehöriger Text auseinandergerissen
+wird und sogenannte "Waisenkinder" entstehen (letzte Zeile eines Abschnittes kommt
+auf die neue Seite). 
+ 
+Bei der interaktiven #ib#Formatierung#ie (1, " für Seiten")# können Sie die Markierung nicht über das errech­
+nete Ende einer Seite nach unten oder über das vorherige, bereits verarbeitete Seiten­
+ende nach oben verschieben. 
+ 
+Haben Sie jedoch zu Beginn die #ib#\#pageblock\##ie(1,"-Anweisung")#-Anweisung (siehe S. 5-91) gegeben,
+ist es erlaubt, die Seitenende-Markierung auch einige Zeilen über das rechnerische
+Seitenende hinaus zu bewegen. Betätigen Sie dann <CR> ,  wird der Drucker (sofern
+möglich) den Zeilenabstand auf dieser Seite stauchen. In diesem Fall sollten Sie
+darauf achten, daß das Seitenende bei einem Absatz immer #on("b")##on("i")#vor#off("b")##off("i")# eventuell vorhan­
+dene Leerzeilen plaziert wird. Andernfalls werden die Leerzeilen am Ende der Seite
+als Textzeile mitgezählt und es bleibt entsprechender Platz frei! 
+ 
+Innerhalb einer Fußnote kann die Markierung nicht verschoben werden. In diesem Fall
+wird interaktiv angefragt, ob die Fußnote auf der nächsten Seite fortgesetzt werden
+soll. Verneinen Sie die Anfrage, positioniert 'pageform' vor die Fußnote. Von dieser
+Stelle aus können Sie das Seitenende wie gewohnt verschieben. 
+ 
+Bejahen Sie dagegen die Anfrage nach dem Fußnotenumbruch, plaziert 'pageform'
+das Seitende an dieser Stelle innerhalb der Fußnote. Der restliche Teil der Fußnote
+kommt auf die nächste Seite mit einer Anmerkung ('Forts. von letzter Seite')#u##count#)#e#. 
+#foot# 
+#u##value#)#e# Bei fremdsprachlichen Texten sollten Sie nach 'pageform' diese Anmerkungen
+   in der '.p'-Datei ändern. 
+#end# 
+ 
+Entstehen bei der Seitenformatierung am Anfang einer Seite #ib#Leerzeilen#ie(1, " am Seitenanfang")# (z.B. durch
+Plazierung des Seitenendes zwischen zwei Absätzen), so werden diese von 'page­
+form' automatisch aus der Druckdatei entfernt. Möchten Sie #ib#Leerzeilen am Anfang
+einer Seite#ie#, dann sollten Sie die \#free\#-Anweisung in Verbindung mit der \#page\#-
+Anweisung verwenden. 
+ 
+Zusätzlich können Sie Leerzeilen in eine Seite der Druckdatei einfügen und/oder
+beliebige Zeilen löschen (vergl. b). 
+#page# 
+Folgende Operationen stehen Ihnen bei der interaktiven Seitenformatierung zur Ver­
+fügung: 
+ 
+#on("b")#a) #ib#Seitenende verschieben#ie#:#off("b")# 
+ 
+'pageform' berechnet das "rechnerische" Seitenende und zeigt dieses auf dem Bild­
+schirm durch die Markierung an. Die Markierung kann interaktiv verschoben werden: 
+ 
+      #on("b")#Taste             Bedeutung#off("b")# 
+ 
+      <CR>              Seitenende an diese Stelle plazieren. 
+ 
+ 
+      <^>               Seitenende eine Zeile nach oben verschieben. 
+ 
+ 
+      <v>               Seitenende eine Zeile nach unten verschieben (wenn
+                        vorher nach oben verschoben bzw. wenn \#pageblock\#-
+                        Anweisung gegeben ist). 
+ 
+ 
+      <HOP> <^>         Seitenende um einen Bildschirm nach oben verschieben. 
+ 
+ 
+      <HOP> <v>         Seitenende um einen Bildschirm nach unten verschieben. 
+ 
+ 
+      <ESC>             Abbruch der Seitenformatierung. 
+ 
+ 
+ 
+#on("b")#b) #ib#Leerzeilen einfügen#ie# und/oder #ib#Zeilen löschen#ie##off("b")# 
+ 
+Ist nach den Berechnungen von 'pageform' der Text ungünstig auf der Seite plaziert,
+können Sie in die Seite (der Druckdatei!) Leerzeilen einfügen und/oder Zeilen löschen.
+Dies kann beispielsweise sinnvoll sein, wenn durch die Löschung einer Zeile ein
+Absatz noch auf die Seite passen würde oder durch die Einfügung von Leerzeilen ein
+Absatz auf der letzten Zeile der Seite endet. Oft ist es auch sinnvoll, daß alle Seiten
+gleich lang sind. In diesem Fall sollten vor Kapiteln und Absätzen Leerzeilen eingefügt
+oder gelöscht werden. 
+ 
+Um Leerzeilen einzufügen und/oder Zeilen zu löschen, müssen Sie die Markierung
+wie unter a) beschrieben an die Stelle plazieren, an der die Änderung vorgenommen
+werden soll. 
+ 
+ 
+      #on("b")#Taste                Bedeutung#off("b")# 
+ 
+ 
+      <HOP>  <RUBIN>       Leerzeilen einfügen. Anstatt der Markierung können
+                           durch (u.U. mehrmaliges) <CR> Leerzeilen eingefügt
+                           werden. <HOP> <RUBIN> beendet den Vorgang (wie
+                           Zeileneinfügen im Editor). 
+ 
+      <HOP>  <RUBOUT>      Zeile löschen. Die Zeile unmittelbar oberhalb der
+                           Markierung wird gelöscht. 
+ 
+ 
+ 
+Anschließend berechnet 'pageform' die Seite erneut. 
+ 
+ 
+ 
+#on("b")#c) #ib(9)##ib#\#page\#-Anweisung bestätigen/löschen#ie(9)##ie##off ("bold")# 
+ 
+Wird von der Prozedur 'pageform' eine #ib#\#page\#-Anweisung#ie# angetroffen, so wird das
+gewünschte Seitenende auf Ihrem Bildschirm angezeigt. Die \#page\#-Anweisung
+können Sie entweder bestätigen oder löschen. 
+ 
+      #on("b")#Taste             Bedeutung#off("b")# 
+ 
+ 
+      <CR>              Seitenende bestätigen. 
+ 
+      <RUBOUT>          \#page\#-Anweisung ignorieren. Die Prozedur 'pageform'
+                        bearbeitet in diesem Fall die Datei weiter, als ob keine
+                        \#page\#-Anweisung angetroffen wurde. 
+ 
+      <ESC>             Abbruch der Seitenformatierung. 
+#page# 
+ 
+#ib(9)#5.3.2. #ib#Seitenlänge einstellen#ie##ie(9)# 
+#goalpage("pagelength")# 
+#free(0.7)# 
+    #on("i")# 
+    'pageform'/'autopageform' ist auf ein Schreibfeld von 25.0 cm eingestellt (ent­
+    spricht einem DIN A4-Schreibfeld). Wünschen Sie eine andere Seitenlänge,
+    müssen Sie die #ib#\#pagelength\#-Anweisung#ie# in den Text einfügen. 
+    #off("i")# 
+#free(0.7)# 
+____________________________________________________________________________ 
+ 
+   \#pagelength (20.0)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+stellt die Seitenlänge auf 20 cm ein. 
+ 
+Beachten Sie, daß 
+ 
+1. die neu eingestellte Seitenlänge immer erst ab der nächsten Seite gilt (die bislang
+   eingestellte Seitenlänge gilt noch für die aktuelle Seite). 
+ 
+2. die eingestellte Seitenlänge am Anfang der Datei (also vor der ersten Textzeile) für
+   die erste Seite gilt. 
+#mark ("", "")# 
+ 
+3. der Dezimalpunkt bei der Seitenlänge mit angegeben werden muß. 
+ 
+Die folgende Tabelle gibt die Seitenlänge für die am häufigsten gewählten Papier­
+größen an: 
+ 
+      #on("b")#Format          Seitenlänge      oberer und 
+                      (in cm)          unterer Rand#off("b")# 
+ 
+      DIN A4          25.0             je 2.35 cm 
+ 
+      DIN A5          18.0             je 2.15 cm 
+ 
+      DIN A4 quer     16.0             je 2.50 cm 
+#page# 
+ 
+#ib(9)#5.3.3. #ib#Zeilenabstand einstellen#ie##ie(9)# 
+#goalpage ("linefeed")# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der #ib#\#linefeed\#-Anweisung#ie# stellen Sie einen #ib#Zeilenvorschub#ie# relativ zu der
+   #ib#Schrifthöhe#ie# des eingestellten Schrifttyps ein. 
+   #off("i")# 
+#free(1.0)# 
+'pageform'/'autopageform' berechnet die Anzahl der Zeilen pro Seite immer in Ab­
+hängigkeit von dem eingestellten Schrifttyp. Haben Sie z.B. eine Schrift gewählt, die
+doppelt so hoch wie eine Schreibmaschinenschrift ist, bekommen Sie auch entspre­
+chend weniger Zeilen auf eine Seite. Um diesen Berechnungsvorgang brauchen Sie
+sich in der Regel nicht zu kümmern. 
+ 
+Anders verhält es sich, wenn ein anderer #ib#Zeilenabstand#ie# als der "normale" Abstand
+zwischen Zeilen eingestellt werden soll. In diesem Fall wird die \#linefeed\#-
+Anweisung eingesetzt. Der Parameter gibt an, um welchen Faktor eine Zeilenhöhe #on("i")##on("b")#ab
+der nächsten druckbaren Zeile#off("b")##off("i")# erhöht oder verringert werden soll. 
+ 
+____________________________________________________________________________ 
+ 
+   \#linefeed (2.0)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+druckt die folgenden Zeilen mit doppeltem Zeilenabstand. Nach Antreffen dieser An­
+weisung wird die Zeilenhöhe durch 2 * eingestellte Schrifttypgröße errechnet. Es wird
+also der Zeilenabstand zwischen den Zeilen entsprechend vergrößert, da die Schrift­
+größe gleich bleibt. Dies entspricht dem zweizeiligen Schreiben bei einer Schreib­
+maschine (wenn man davon absieht, daß auch hier unterschiedliche Schrifthöhen
+möglich sind). Ein 1 1/2 zeiliges Schreiben wäre mit 
+ 
+____________________________________________________________________________ 
+ 
+   \#linefeed (1.5)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+einzustellen. 
+ 
+____________________________________________________________________________ 
+ 
+   \#linefeed (0.5)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+stellt die Zeilenhöhe = 1/2 * eingestellte Schrifthöhe ein, so daß die Zeilen teilweise
+ineinander gedruckt werden (was bei manchen Druckern zu nicht lesbaren Resultaten
+führt). Bei \#linefeed (0.0)\# werden Zeilen übereinander gedruckt (druckerabhängig). 
+ 
+Beachten Sie, daß die Angabe in der \#linefeed\#-Anweisung relativ erfolgt. Bei allen
+anderen Anweisungen der Textkosmetik werden Angaben in Zentimetern verlangt. Die
+\#linefeed\#-Anweisung bildet somit eine Ausnahme. 
+#page# 
+ 
+#ib(9)#5.3.4. #ib#Platz freihalten#ie# #ie(9)# 
+#goalpage ("free")# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der #ib#\#free\#-Anweisung#ie# können Sie einen zusammenhängenden Teil auf einer
+   Seite freihalten. 
+   #off("i")# 
+#free(1.0)# 
+Die \#free\#-Anweisung setzen Sie an solchen Stellen im Text ein, an denen - nach
+dem Druck - Zeichnungen, Tabellen und ähnliches eingeklebt werden sollen. Sie
+können sie auch zwischen Absätzen, Kapiteln usw. einsetzen, wenn der Abstand nicht
+gleich dem Vielfachen der Zeilenhöhe ist. Es wird der in der \#free\#-Anweisung
+angegebene Platz freigehalten. 
+ 
+____________________________________________________________________________ 
+ 
+\#free (2.0)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+hält zwei Zentimeter frei. Paßt der angeforderte Platz nicht mehr auf die Seite, so wird
+er auf der nächsten Seite reserviert ('pageform'/'autopageform' plaziert das Seiten­
+ende vor die \#free\#-Anweisung). 
+ 
+ 
+ 
+#on("i")##on("b")#Praktischer Tip:#off("b")##off("i")# 
+Sie sollten eine \#free\#-Anweisung allein auf eine Zeile schreiben, damit Sie sie u.U.
+durch 'pageform' interaktiv entfernen können, wenn die \#free\#-Anweisung ungünstig
+an den Seitenanfang oder das Seitenende kommt. 
+#page# 
+ 
+#ib(9)#5.3.5. #ib#Neue Seite beginnen#ie##ie(9)# 
+#goalpage("page")# 
+#free(1.0)# 
+   #on("i")# 
+   An einigen Stellen im Text, z.B. zu Beginn eines neuen Kapitels, möchten Sie
+   unbedingt eine neue Seite anfangen. Dies erreichen Sie mit der #ib#\#page\#-
+   Anweisung#ie#. 
+   #off("i")#  
+#free(1.0)# 
+'pageform' meldet in diesem Fall, nach wie vielen Zentimetern auf der Seite die An­
+weisung angetroffen wurde. Sie können nun mit <CR> das Seitenende bestätigen oder
+die Anweisung (in der Druckdatei) löschen. Im letzteren Fall berechnet 'pageform' die
+Seite neu, als ob die \#page\#-Anweisung nicht dagewesen wäre. 
+ 
+Gleichzeitig können Sie mit Hilfe der #ib#\#page\#-Anweisung#ie(1, ", mit neuer Seitenummer")# eine neue Seitennummer
+für die neue Seite einstellen (vergl. Sie dazu die nächsten Abschnitte). 
+#page# 
+ 
+#ib(9)#5.3.6. #ib#Kopf- und Fußzeilen#ie##ie(9)# 
+#goalpage("head")##goalpage("bottom")# 
+#free(1.0)# 
+   #on("i")# 
+   Mit den #ib#\#head\#-#ie(1, "Anweisung")# und #ib#\#bottom\#-Anweisung#ie#en können Sie Zeilen am Anfang und
+   Ende jeder Seite einfügen. 
+   #off("i")# 
+#free(1.0)# 
+Sie schreiben Zeilen am Anfang ("#ib#Kopfzeilen#ie#") und Ende ("#ib#Fußzeilen#ie#") jeder Seite nur
+einmal und kennzeichnen sie mit Anweisungen. Diese Zeilen fügt 'pageform'/­
+'autopageform' dann an den entsprechenden Stellen ein. 
+ 
+____________________________________________________________________________ 
+ 
+   \#head\#                                               
+                Unser EUMEL-Benutzerhandbuch            
+                                                        
+   \#end\#                                                
+ 
+____________________________________________________________________________ 
+ 
+ 
+Diese Zeile (also die zwischen den \#head\#- und #ib#\#end\#-Anweisung#ie#en eingeschlos­
+sene Zeile) wird von 'pageform'/'autopageform' an den Anfang jeder Seite in die
+Druckdatei plaziert. 
+ 
+Entsprechendes gilt für Fußzeilen, die zwischen \#bottom\# und \#end\# eingeschlossen
+werden müssen: 
+ 
+____________________________________________________________________________ 
+ 
+   \#bottom\#                                       
+                                                  
+                   Autor: I. Listig               
+   \#end\#                                          
+ 
+____________________________________________________________________________ 
+ 
+ 
+#on("b")#Praktischer Tip#off("b")#: 
+ 
+Fügen Sie mindestens eine Leerzeile am Ende eines \#head\# bzw. am Anfang eines
+\#bottom\# ein, um den eigentlichen Text von den Kopf- bzw. Fußzeilen abzuheben. 
+ 
+ 
+'pageform'/'autopageform' zählt die Seiten, beginnend mit der Seitennummer '1'. (Wie
+man Seitennummern in die Kopf- und Fußzeilen bekommt, erfahren Sie im nächsten
+Abschnitt). Sie können nun getrennte Kopf- und Fußzeilen für gerade und ungerade
+Seiten gestalten (wie in diesem Benutzerhandbuch). Dies erfolgt mit den Anweisungen
+\#headeven\# und \#headodd\# für Seiten mit geraden und ungeraden Seitennummern;
+ebenso \#bottomeven\# und \#bottomodd\#. Diese Anweisungen müssen ebenfalls jeweils
+mit einer \#end\#-Anweisung beendet werden. 
+ 
+Sie haben die Möglichkeit, Kopf- und Fußzeilen mehrmals innerhalb einer Datei zu
+wechseln, um unterschiedliche Beschriftungen zu erhalten (z.B. kapitelweise). Dies ist
+jedoch nur sinnvoll, wenn es auf einer neuen Seite erfolgt, also unmittelbar #on("b")##on("is")#nach#off("b")##off("is")# einer
+\#page\#-Anweisung. 
+ 
+____________________________________________________________________________ 
+ 
+   \#page\# 
+   \#head\#                                             
+              Neuer Seitenkopf                        
+                                                      
+   \#end\#                                              
+ 
+____________________________________________________________________________ 
+ 
+ 
+Kopf- und Fußzeilen sollen überall gleiches Aussehen haben, unabhängig davon,
+welche Anweisungen im restlichen Text gegeben werden. Darum werden die bei der
+Definition einer Kopf- und Fußzeile aktuellen Werte für 
+ 
+ 
+  limit 
+  type 
+  linefeed 
+ 
+ 
+bei dem Einsetzen der Zeilen berücksichtigt. Für Kopf- oder Fußzeilen können Sie
+einen anderen Schrifttyp als im restlichen Text verwenden, indem Sie die \#type\#-
+Anweisung innerhalb eines \#head\#- oder \#bottom\#-Bereiches geben. Beachten Sie,
+daß nach \#head\#-, \#bottom\# und auch \#foot\#-Bereichen die oben genannten An­
+weisungen nicht automatisch zurückgestellt werden. Darum sollten Sie vor der
+\#end\#-Anweisung wieder auf die im übrigen Text verwendeten Werte zurückstellen. 
+ 
+____________________________________________________________________________ 
+ 
+   \#bottom\#                        
+   \#type ("klein")\#                
+                Autor: I. Listig   
+                                               (Schrifttyp 
+                                               zurückstellen): 
+   \#type ("normal")\#               
+   \#end\#                           
+ 
+____________________________________________________________________________ 
+ 
+ 
+#page# 
+ 
+#ib(9)#5.3.7. #ib#Seiten numerieren#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   In den Kopf- und Fußzeilen steht das #ib#'%'-Zeichen#ie# für die aktuelle Seiten­
+   nummer. 
+   #off("i")# 
+#free(1.0)# 
+Erscheint das '%'-Zeichen innerhalb eines Kopf- oder Fußbereiches, wird von
+'pageform'/'autopageform' beim Einsetzen dieser Zeilen auf jeder Seite die aktuelle
+#ib#Seitennummer#ie# eingesetzt (sind mehrere '%'-Zeichen vorhanden, wird die Seiten­
+nummer mehrmals eingesetzt). 
+ 
+____________________________________________________________________________ 
+ 
+   \#head\#                                    
+                 Seite: - % -                
+                                             
+   \#end\#                                     
+ 
+____________________________________________________________________________ 
+ 
+ 
+Wenn Sie die Seitenzahl in der Zeilenmitte oder am rechten Rand plazieren möchten,
+können Sie die Anweisungen \#center\# (siehe S. 5-93) oder \#right\# (siehe S. 5-94)
+verwenden. 
+ 
+Durch das Einrichten eines Fußbereiches können Sie die Seitennummern auch am
+unteren Ende einer Seite erzeugen. Beachten Sie, daß sich bei mehrstelligen Seiten­
+nummern die Zeilenlänge durch das Einsetzen vergrößert. 
+ 
+Um zum Beispiel das #ib#Vorhandensein einer Folgeseite#ie# in einem Fußbereich zu kenn­
+zeichnen, müssen Sie das '%'-Zeichen zweimal direkt hintereinander schreiben. 
+ 
+____________________________________________________________________________ 
+ 
+   \#bottom\#                                               
+                                                          
+   \#right\# %%                                             
+   \#end\#                                                  
+ 
+____________________________________________________________________________ 
+ 
+    
+In dem Beispiel oben wird die Seitenzahl rechtsbündig gedruckt. 
+ 
+ 
+Manchmal ist es notwendig und sinnvoll, einen Text in mehreren Dateien zu halten.
+Bei einer Folgedatei müssen Sie die Seitennummer dann neu setzen. Das erfolgt mit
+der \#pagenr\#- oder der \#page\#-Anweisung. 
+ 
+____________________________________________________________________________ 
+ 
+   \#page (4)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+bewirkt eine neue Seite. Die Seitennummer der neuen Seite ist '4'. 
+ 
+#goalpage("pagenr")# 
+ 
+Bei einigen Spezialanwendungen benötigen Sie unter Umständen mehr als eine
+Seitennummer. Beispielsweise soll ein Text nicht nur absolut, sondern auch jede Seite
+in jedem Kapitel separat durchgezählt werden. 
+ 
+____________________________________________________________________________ 
+ 
+   \#page (4711)\# 
+   \#pagenr ("$", 1)\# 
+   \#head\#                                            
+               Mein Buch         Seite: %  Kapitelseite: $ 
+                                                     
+   \#end\#                                             
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Anweisung #ib#\#pagenr#ie# ("$",1)\# veranlaßt, daß ab der nächsten Seite eine neue
+Numerierung durchgeführt wird. Dabei steht '$' stellvertretend für die neue Zahl. Die
+'1' bedeutet, daß bei der Numerierung mit '1' begonnen wird. 'pageform'/­
+'autopageform' erhöht bei jeder neuen Seite das Zeichen um '1' und setzt es ggf. in
+die Kopf- und Fußzeilen. Es sind zwei zusätzliche Seitenzeichen (neben dem '%')
+möglich. 
+ 
+Beachten Sie, daß die neuen Seitennummern immer erst ab der nächsten Seite gel­
+ten. Geben Sie die \#page (...)\#- oder die \#pagenr (...,...)\#-Anweisung am Anfang
+der Datei (also vor der ersten Textzeile), gelten die neuen Seitennummern für die
+erste Seite. 
+#page# 
+ 
+#ib(9)#5.3.8. #ib#Fußnoten#ie# schreiben#ie(9)# 
+#goalpage("foot")# 
+#free(1.0)# 
+   #on("i")# 
+   Fußnoten werden direkt im Text durch die Anweisungen \#foot\# und \#end\#
+   gekennzeichnet. Die Fußnoten plaziert 'pageform'/'autopageform' an das Ende
+   einer Seite. 
+   #off("i")#  
+#free(1.0)# 
+#ib#Fußnoten#ie# schreiben Sie direkt in den Text, am besten an der Stelle, an der später die
+Fußnote aufgerufen werden soll. Die Fußnote wird von 'pageform'/'autopageform' an
+das Ende einer Seite, ggf. vor die Fußzeilen, plaziert. Für die Kennzeichnung von
+Fußnoten und die entsprechende Markierung im Text sind Sie selbst zuständig. Aller­
+dings werden von 'pageform'/'autopageform' bei dem Einsetzen einer Fußnote am
+Ende einer Seite Unterstriche vor die Fußnoten eingefügt, damit Fußnoten vom lau­
+fenden Text abgehoben werden. 
+ 
+____________________________________________________________________________ 
+ 
+   \#foot\# 
+   *) Das ist die erste Anmerkung auf dieser Seite.                
+   \#end\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+______ 
+*) Das ist die erste Anmerkung auf dieser Seite. 
+ 
+ 
+Mehrere Fußnoten innerhalb einer Seite werden von 'pageform'/'autopageform' in der
+Reihenfolge ihres Auftretens gesammelt und am Ende der Seite plaziert. Für eine
+entsprechende Trennung der Fußnoten voneinander (z.B. durch Leerzeilen) müssen
+Sie selbst sorgen. 
+ 
+Unter Umständen paßt die Fußnote nicht mehr auf die aktuelle Seite und muß deshalb
+von 'pageform'/'autopageform' auf die nächste Seite gebracht werden. 'pageform'/­
+'autopageform' geht davon aus, daß die Kennzeichnung der Fußnote in der Zeile
+unmittelbar vor der Fußnote steht und bringt diese Zeile ebenfalls auf die neue Seite. 
+ 
+____________________________________________________________________________ 
+ 
+Es ist auch möglich, eine Fußnote innerhalb eines Abschnitts zu 
+schreiben, wie z.B. in dieser Zeile\#u\#*)\#e\#.\#foot\# 
+\#u\#*)\#e\# Fußnote in einem Abschnitt!                                 
+\#end\#                                                                
+Sie fahren anschließend ohne Unterbrechung mit dem Schreiben 
+Ihres Textes fort.                                                   
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild (nach lineform): 
+ 
+Es ist auch möglich, eine Fußnote innerhalb eines Abschnitts zu schreiben, wie z.B.
+in dieser Zeile#u#*)#e#. Sie fahren anschließend ohne Unterbrechung mit dem Schreiben#foot#
+#u#*)#e# Fußnote in einem Abschnitt! 
+#end# 
+Ihres Textes fort. 
+ 
+ 
+In diesem Fall ist es wünschenswert, daß 'lineform' die Zeile, die \#foot\# vorausgeht,
+mit der Zeile, die \#end\# folgt, auffüllt. Dies geschieht unter folgenden Bedingungen: 
+ 
+1. Hinter \#foot\# darf nichts mehr stehen, also auch kein Absatzzeichen. 
+ 
+2. Es werden so lange Worte von der Zeile nach \#end\# vor die \#foot\#-Anweisung
+   plaziert, bis die Zeile gefüllt oder die Zeile nach \#end\# leergeräumt ist. 
+ 
+3. Beachten Sie, daß Textkosmetik-Anweisungen ebenfalls mit über die Fußnote
+   genommen werden. Handelt es sich beispielsweise um eine \#type\#-Anweisung,
+   kann sich das Aussehen der Fußnote verändern! Darum ist es angeraten, even­
+   tuelle Anweisungen, die die Fußnote verändern sollen, innerhalb der Fußnote zu
+   plazieren. 
+ 
+Sie sollten vermeiden, umfangreiche Texte in Fußnoten zu schreiben (beispielsweise
+längere Zitate). Aus programmtechnischen Gründen begrenzt 'pageform'/'autopage­
+form' die maximale Länge von Fußnoten auf einer Seite auf 85% des effektiven
+Schreibfeldes (effektives Schreibfeld: Seitenlänge minus Länge von \#head\#- bzw.
+\#bottom\#-Zeilen). Nimmt eine Fußnote einen größeren Raum ein, bricht 'pageform'/
+'autopageform' die Seitenformatierung mit einer Fehlermeldung ab. 
+#page# 
+ 
+#ib(9)#5.3.8.1. #ib#Fußnoten numerieren#ie##ie(9)# 
+#goalpage("count")##goalpage("value")# 
+#free(1.0)# 
+   #on("i")# 
+   Gleichartige Textteile wie Lehrsätze, Beispiele, Fußnoten usw. werden i. allg.
+   durchnumeriert. Da Sie bei der Abfassung eines längeren Textes ihre genaue
+   Anzahl meist nicht vorausplanen können, übernimmt 'pageform'/'autopageform' die
+   Zählung. 
+   #off("i")#  
+#free(1.0)# 
+Durch die #ib#\#count\#-Anweisung#ie# wird 'pageform'/'autopageform' veranlaßt, einen
+internen Zähler (beginnend bei dem Wert 0) zu erhöhen und diesen Wert statt der
+\#count\#-Anweisungen in den Text einzusetzen. 
+ 
+____________________________________________________________________________ 
+ 
+   \#count\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+setzt den Wert 1 statt der Anweisung ein. Jede weitere \#count\#-Anweisung erhöht
+den internen Zähler und der Zählerwert wird wiederum eingesetzt: 
+ 
+____________________________________________________________________________ 
+ 
+     \#count\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+setzt den Wert 2 ein usw. Dadurch ist es möglich, beliebige Textteile (Kapitel,
+mathematische Sätze u.a.m.) fortlaufend zu numerieren, ohne auf die Numerierung
+beim Schreiben und Ändern des Textes zu achten. 
+ 
+Anmerkung: 
+Trifft 'lineform' auf eine \#count\#-Anweisung, so wird die Zeile berechnet, als ob drei
+Ziffern anstatt der Anweisung im Text ständen. 
+ 
+Mit der \#value\#-Anweisung können Sie den #on("b")##on("i")#letzten#off("i")##off("b")# erreichten count-Wert nochmals
+einsetzen. Das ist insbesondere für Fußnoten sinnvoll einsetzbar. 
+ 
+____________________________________________________________________________ 
+ 
+   Text ....... (\#count\#) 
+   \#foot\# 
+   (\#value\#) Text der Fußnote 
+   \#end\# 
+   Text ....... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Das Resultat sähe folgendermaßen aus: 
+ 
+   Text ....... (3) 
+   Text ....... 
+   ............... 
+   ______ 
+   (3) Text der Fußnote 
+ 
+Beachten Sie, daß in diesem Fall die \#value\#-Anweisung der \#count\#-Anweisung
+folgen muß, ohne daß eine weitere \#count\#-Anweisung dazwischen steht. Das liegt
+- wie bereits oben erwähnt - daran, daß die \#value\#-Anweisung immer den letzten
+\#count\#-Wert einsetzt. 
+ 
+Das können Sie umgehen, indem Sie die \#count\#- und \#value\#-Anweisungen mit
+einem TEXT-Parameter versehen, der als Kennzeichnung dient. 
+ 
+____________________________________________________________________________ 
+ 
+   \#count ("Merk1")\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+\#count ("Merk1")\# arbeitet ebenso wie \#count\# ohne Parameter und setzt für unser
+Kapitel hier den Wert 4 ein. Zusätzlich zu dem fortlaufend gezählten Wert (fortlau­
+fende Numerierung der Fußnoten) vermerkt 'pageform'/'autopageform' einen Wert, der
+bei Bedarf an irgendeiner anderen Stelle im Text durch \#value ("Merk1")\# wieder
+aufgerufen werden kann, zum Beispiel, wenn Sie auf eine andere Fußnote verweisen
+möchten. 
+ 
+____________________________________________________________________________ 
+ 
+   \#count\#\#count\# 
+   \#value("Merk1")\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die ersten zwei \#count\#-Anweisungen produzieren - in unserem Kapitel - die
+Werte 5 bzw. 6. Die \#value\#-Anweisung dagegen setzt den vermerkten Wert 4 ein. 
+ 
+Dies ist insbesondere sinnvoll, wenn Sie im Text auf eine Fußnote verweisen möch­
+ten. 
+ 
+Beispiel: 
+ 
+Sie schreiben einen mehrseitigen Prospekt über ein neues Produkt. Auf Seite 5 möch­
+ten Sie auf eine Fußnote verweisen, die auf einer anderen Seite steht. Dann fügen Sie
+'siehe auch Anmerkung (\#value("liefertermin")\#) in Ihren Text ein und fahren mit dem
+Schreiben fort. 'pageform'/'autopageform' setzt später die entsprechende Zahl für den
+Verweis ein. 
+ 
+Auf der Seite, auf die Sie Bezug nehmen, sieht das ganze folgendermaßen aus: 
+ 
+____________________________________________________________________________ 
+ 
+   Der Textverarbeitungskurs ist ein Lernprogramm für Anfänger. 
+   \#(count)("Liefertermin")\#) 
+   \#foot\# 
+   (\#(value)("Liefertermin")\#) 
+   Der Textverarbeitungskurs wird ab August erhältlich sein. 
+   \#end\# 
+   Das Programm ist auf den neuesten Erkenntnissen der Lehr­
+   forschung aufgebaut. Der Kurs umfaßt Lehrbuch, Arbeitsbuch und
+   sechs Kassetten. 
+ 
+____________________________________________________________________________ 
+ 
+ 
+#page# 
+Soll die Zahl für den Verweis bzw. für die Fußnote hochgestellt werden, fügen Sie die
+Anweisungen \#u\# und \#e\# hinzu. 
+ 
+____________________________________________________________________________ 
+ 
+   \#u\# (\#value("Liefertermin")\#)\#e\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+Im gedruckten Prospekt sähe es (nach 'lineform') wie folgt aus: 
+ 
+Der Textverarbeitungskurs ist ein Lernprogramm für Anfänger#u##count#)#e#.#foot# 
+#u##value#)#e#Der Textverarbeitungskurs wird ab August erhältlich sein. 
+#end# 
+Das Programm ist auf den neuesten Erkenntnissen der Lehrforschung aufgebaut. Der
+Kurs umfaßt Lehrbuch, Arbeitsbuch und sechs Kassetten. 
+ 
+Manchmal ist es notwendig (ebenso wie bei der Seitennummer), den internen Zähler
+neu zu setzen. 
+ 
+____________________________________________________________________________ 
+ 
+   \#setcount (13)\#\#count\# 
+ 
+____________________________________________________________________________ 
+#goalpage("setcount")# 
+ 
+produziert den Wert 13. 
+#page# 
+ 
+#ib(9)#5.3.9. #ib#Querverweise#ie# #ie(9)# 
+#goalpage("topage")##goalpage("goalpage")# 
+#free(1.0)# 
+   #on("i")# 
+   Mit den Anweisungen #ib#\#topage\##ie(1,"-Anweisung")# und #ib#\#goalpage\##ie(1,"-Anweisung")# sind Querverweise möglich, die
+   von 'pageform'/'autopageform' in die Druckdatei eingefügt werden. 
+   #off("i")# 
+#free(1.0)# 
+Mit Hilfe von Querverweisen soll auf andere Stellen im Text verwiesen werden, was
+nur bei längeren Texten üblich ist. Um dem Leser die mühselige Suche nach der
+Textstelle zu ersparen, gibt man in der Regel die Seitennummer an. Normalerweise
+steht die Seitennummer vor der Fertigstellung des Textes noch nicht fest. Auch in
+diesem Fall kann 'pageform'/'autopageform' helfen. Die \#topage\#-Anweisung ver­
+weist auf eine andere Seite im Text, an der sich eine Anweisung \#goalpage\# befinden
+muß. Statt der Anweisung \#topage\# wird die Seitennummer der Seite eingesetzt, auf
+der sich \#goalpage\# befindet. Damit jedes \#topage\# auch sein entsprechendes \#goal­
+page\# findet, geben Sie bei beiden Anweisungen einen TEXT-Parameter an. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   ... siehe auch auf Seite \#topage("Funktionstasten")\#  ... 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Auf einer anderen Seite befindet sich 
+ 
+____________________________________________________________________________ 
+ 
+    ...    \#goalpage("Funktionstasten")\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Nach 'Seite' wird die entsprechende Seitennummer eingesetzt. 
+ 
+Es ist möglich, mehrmals auf die gleiche (Ziel-)Seite zu verweisen. Sie müssen nur
+darauf achten, daß Sie immer das gleiche Merkmal (TEXT-Parameter) verwenden.
+Beachten Sie auch, daß die \#goalpage\#-Anweisungen sich in den Zeilen befinden
+müssen, die tatsächlich gedruckt werden. Setzen Sie sie nicht in die ersten Zeilen
+einer Seite oder eines Textes, die Anweisungen für das Layout enthalten. 
+ 
+Die Zahl der Querverweise darf 300 nicht übersteigen. #page# 
+ 
+#ib(9)#5.3.10. Kombination von Tabellen, Fußnoten
+       und Kopf- bzw. Fußzeilen#ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   In Fußnoten, \#head\#- oder \#bottom\#-Bereichen können Tabellen untergebracht
+   werden. 
+   #off("i")# 
+#free(1.0)# 
+____________________________________________________________________________ 
+ 
+\#head\#                                                 
+\#lpos(0.0)\#\#cpos(5.0)\#\#rpos(11.0)\#                     
+\#table\#                                                
+Korrekturen   EUMEL-Benutzerhandbuch   S.007           
+                                                       
+\#table end\#                                            
+\#end\#                                                  
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Die obigen Eingaben schreiben an jeden Seitenanfang folgenden Text: 
+ 
+#lpos(0.0)##cpos(5.0)##rpos(11.0)# 
+#table# 
+Korrekturen   EUMEL-Benutzerhandbuch   S.007 
+#table end##clear pos# 
+ 
+Die Tabelle sollte also vollständig in den oben erwähnten Bereichen enthalten sein. 
+#page# 
+ 
+#ib(9)#5.3.11. #ib#Formatierung von Spalten#ie##ie(9)# 
+#goalpage("columns")# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der \#columns\#-Anweisung ist es möglich, einen Text in #ib#Spalten#ie(1,"formatierung")# zu formatie­
+   ren ("Zeitungsdruck"). 
+   #off("i")# 
+#free(1.0)# 
+Durch die Angabe der \#columns\#-Anweisung wird 'pageform'/'autopageform' auf­
+gefordert, den Text in Spalten zu formatieren. Die Spaltenbreite müssen Sie mit der #ib#
+\#limit\#-Anweisung#ie (1, " für Spalten")# einstellen. 
+ 
+____________________________________________________________________________ 
+ 
+   \#limit (18.0)\# 
+   ... 
+   \#columns (2, 2.0)\# 
+   \#limit (8.0)\# 
+   ... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Anfangs schreiben Sie mit einer Zeilenbreite von 18 cm. Dann fordern Sie mit der
+\#columns\#-Anweisung zweispaltigen Druck an (zwischen den Spalten sollen 2 cm
+Abstand sein). Somit muß die \#limit\#-Anweisung (sie gilt für beide Spalten) auf 8 cm
+eingestellt werden. 
+ 
+Die interaktive #ib#Spaltenformatierung#ie# wird von 'pageform' wie gewohnt vorgenommen.
+Auf dem Bildschirm erscheint nun das Spaltenende, wobei die Nummer der Spalte
+angezeigt wird. Fußnoten werden spaltenweise eingeordnet und müssen somit die
+gleiche Zeilenbreite haben wie die restlichen Spalten. 
+ 
+'pageform'/'autopageform' erzeugt in der Druckdatei die Spalten hintereinander. Das
+folgende Beispiel zeigt einen Ausschnitt aus der Druckdatei mit Kopf- und Fußzeilen
+bei einem zweispaltigen Druck: 
+ 
+____________________________________________________________________________ 
+ 
+   head-Zeilen 
+   xx 
+   xx 
+   xx 
+   bottom-Zeilen 
+   \#page\#\#------- Ende Seite 1 Spalte 1 ----\# 
+   xx 
+   xx 
+   xx 
+   \#page\#\#------- Ende Seite 1 Spalte 2 ----\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die zweite Spalte erscheint also ohne Kopf- und Fußzeilen, die jedoch bei der
+Berechnung berücksichtigt werden. Beachten Sie, daß die Kopf- und Fußzeilen über
+die Spalten gehen können. Dies erreichen Sie durch geeignete \#limit\#-Anweisungen
+in den genannten Bereichen. 
+ 
+Die meisten Drucker plazieren die zweite Spalte im Druckbild neben die erste. Bei
+einigen wenigen Druckern müssen Sie die Spalten nebeneinander kleben. 
+ 
+Alle Anweisungen funktionieren beim spaltenweisen Formatieren wie üblich. Die
+\#free\#-Anweisung z.B. hält entsprechenden Platz in einer Spalte frei. Eine Aus­
+nahme bildet die #ib#\#page\#-Anweisung#ie (1, " für Spaltenende")#. Sie vollzieht hier ein #ib#Spaltenende#ie#. Die
+\#page\#-Anweisung mit einem Parameter (welcher die Seitennummer der nächsten
+Seite angibt) vollzieht dagegen ein Seitenende. 
+ 
+Die #ib#\#columns end\#-Anweisung#ie# beendet die spaltenweise #ib#Formatierung#ie(1, " spaltenweise")#. Sie wirkt wie
+eine \#page\#-Anweisung. 
+ 
+#ib#Überschriften#ie (1, " in Spalten")# (bzw. Textblöcke) über mehrere Spalten hinweg sind nur auf der ersten
+Seite direkt hinter der \#columns\#-Anweisung möglich. 
+ 
+____________________________________________________________________________ 
+ 
+   \#page\# 
+   \#limit (10.0)\# 
+   Überschriften (bzw. Textblöcke) über mehrere Spalten hinweg
+   sind nur auf der ersten Seite direkt hinter der \#columns\#-
+   Anweisung möglich. 
+ 
+ 
+   \#columns (2,2.0)\# 
+   \#limit (4.0)\# 
+   Die erste Spalte soll nur wenige Zeilen beinhalten. Das vor­
+   zeitige Beendigen der Spalte erreicht man mit der \#page\#-
+   Anweisung. 
+   \#page\# 
+   In der zweiten Spalte kann dann mit dem Schreiben des Textes
+   fortgefahren werden. 
+   ..................... 
+   ..................... 
+   ..................... 
+   ..................... 
+   ..................... 
+   \#columns end\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+#page# 
+Druckbild (mit 'lineform' bearbeitet): 
+ 
+ 
+    
+   Überschriften (bzw. Textblöcke) über mehrere Spalten hinweg sind nur auf
+   der ersten Seite direkt hinter der \#columns\#-Anweisung möglich. 
+   #columns (2,2.0)# 
+    
+   Die erste Spalte soll nur
+   wenige Zeilen beinhalten.
+   Das vorzeitige Beendigen
+   der Spalte erreicht man mit
+   der \#page\#-Anweisung. 
+   #page# 
+ 
+ 
+   In der zweiten Spalte kann
+   dann mit dem Schreiben
+   des Textes fortgefahren
+   werden. 
+   ..................... 
+   ..................... 
+   ..................... 
+ 
+#columns end# 
+ 
+ 
+ 
+ 
+Die Zeilen für die zweispaltige Überschrift werden berücksichtigt. Dies gilt jedoch nur
+unmittelbar hinter der \#columns\#-Anweisung. Möchten Sie diesen Effekt nochmals
+erzeugen, beenden Sie mit \#columns end\#, schreiben die breite Überschrift und
+schalten die \#columns\#-Anweisung wieder ein (jeweils unter richtiger Setzung von
+\#limit\#). 
+#page# 
+ 
+#ib(9)#5.4.   #ib#Index#ie##ie(9)# 
+#free(1.0)# 
+#ib(9)#5.4.1. Stichwort- und/oder#ib# 
+       Inhaltsverzeichnis#ie#se erstellen#ie(9)# 
+#free(1.0)# 
+ 
+   #on("i")# 
+   Mit dem Programm '#ib#index#ie(1, "-Kommando")#' können Sie Stichwort- und Inhaltsverzeichnisse er­
+   stellen. #ib#Stichwortverzeichnis#ie#se können sortiert werden. Mehrere Stichwortverzeich­
+   nisse können Sie durch 'index merge' zusammenführen. 
+   #off("i")# 
+#free(1.0)# 
+Durch den Aufruf von: 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   index ("dateiname.p") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+werden durch #ib#Indexanweisungen#ie# gekennzeichnete Worte in Dateien, den sogenannten
+Indexdateien, gespeichert. 
+ 
+Die Worte, die in einen Index übernommen werden sollen, müssen Sie in der Druck­
+datei für 'index' durch Anweisungen kennzeichnen. Solche #ib(1,"ff")#Indexanweisungen#ie# werden
+von den anderen Textbe- und -verarbeitungs-Programmen ('lineform', 'pageform',
+EUMEL-Drucker) ignoriert. Sie können  also bei dem Schreiben mit dem Editor
+gleich festlegen, welche Worte in einen Index aufgenommen werden sollen. 
+ 
+Solche Verzeichnisse von Worten werden im EUMEL-System allgemein als #ib#Index#ie#
+bezeichnet. 'index' kann ebenfalls benutzt werden, um ein #ib#Inhaltsverzeichnis#ie# und/oder
+ein Verzeichnis aller Abbildungen zu erstellen oder Literaturhinweise zu überprüfen. 
+ 
+Nachdem eine oder mehrere Indexdateien aus einer Druckdatei erstellt sind, werden
+die Indexdateien auf Anfrage alphabetisch sortiert. Bei einem Inhaltsverzeichnis sollten
+Sie die Sortierung natürlich ablehnen. Nach der Sortierung werden gleiche Einträge
+automatisch zusammengefaßt und die entsprechenden Seitennummern nacheinander
+aufgeführt. 
+ 
+ 
+ 
+#on("b")##on("i")#Praktischer Tip:#off("b")##off("i")# 
+Möchten Sie nur eine Sortierung, aber keine Zusammenfassung von Einträgen, dann
+lehnen Sie die Sortieranfrage ab. Anschließend können Sie die Indexdatei mit '#ib#lex sort#ie#
+("indexdateiname")' sortieren. Hierbei bleiben gleiche Einträge erhalten. 
+ 
+ 
+ 
+Das Programm 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   index merge ("dateiname.i1", "dateiname.i2") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+erlaubt es Ihnen, zwei durch 'index' erzeugte Verzeichnisse zusammenzuführen und
+- nach Anfrage - wieder zu sortieren. 
+#page# 
+ 
+#ib(9)#5.4.1.1. #ib#Worte für 'index' kennzeichnen#ie##ie(9)# #goalpage ("ib")##goalpage("ie")# 
+#free(1.0)# 
+   #on("i")# 
+   Worte, die in einen Index übernommen werden sollen, kennzeichnen Sie mit \#ib\#
+   und \#ie\#. 
+   #off("i")# 
+#free(1.0)# 
+Da in einem Index - neben dem eigentlichen Worteintrag - die #ib#Seitennummer#ie#
+enthalten sein soll, arbeitet das Programm 'index' nur mit einer #ib#Druckdatei#ie#, d.h. einer
+Ausgabedatei von 'pageform'/'autopageform'. Die Indexworte werden in #ib#Indexdateien#ie#
+gesammelt. Die Indexdateien erhalten den Namen der bearbeiteten Datei, an den ".i"
+und die Nummer des Index angefügt wird. 
+ 
+____________________________________________________________________________ 
+ 
+   ... Hier wird eine Eigenschaft des \#ib(1)\#EUMEL- 
+       Systems\#ie(1)\# beschrieben. ... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die durch die Anweisungen #ib#\#ib\##ie(1,"-Anweisung")# und #ib#\#ie\##ie(1,"-Anweisung")# gekennzeichneten Worte werden mit der
+dazugehörigen Seitennummer in die erste Indexdatei geschrieben. 
+ 
+Die Einträge in einer Indexdatei werden von den Seitennummern durch mindestens
+drei Punkte getrennt. Werden diese nicht gewünscht, können Sie sie leicht mit dem
+Editor entfernen. 
+ 
+ 
+Sie haben die Möglichkeit, bis zu neun unterschiedliche Indexdateien zu erstellen,
+z.B. gehen durch 
+ 
+____________________________________________________________________________ 
+ 
+   \#ib (1)\# und \#ie (1)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+gekennzeichnete Worte in die Indexdatei mit der Nummer 1, durch 
+ 
+____________________________________________________________________________ 
+ 
+   \#ib (9)\# und \#ie (9)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+gekennzeichnete Worte gehen in die Indexdatei mit der Nummer 9. Wenn Sie nur
+einen Index erstellen müssen, dürfen die \#ib\#- und \#ie\#-Anweisungen ohne Para­
+meter benutzt werden, was gleichbedeutend ist mit \#ib (1)\# und \#ie (1)\#. 
+ 
+ 
+ 
+Die durch \#ib\#- und \#ie\#-Anweisungen gekennzeichneten Worte können auch über
+Zeilengrenzen (mit Silbentrennungen) gehen. 
+ 
+____________________________________________________________________________ 
+ 
+   .... \#ib\#viele Index­ 
+   Anweisungen\#ie\# ... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+'index' zieht getrennte Worte zusammen (hier: 'viele Index-Anweisungen'). Möchten
+Sie einige Worte in verschiedenen Indexdateien haben, dürfen Sie die \#ib\#- und
+\#ie\#-Anweisungen auch "schachteln". Dies können Sie besonders bei Kapitelüber­
+schriften nutzen. 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   \#ib(9)\#Eine Anweisung: die '\#ib\#limit\#ie\#'-Anweisung\#ie(9)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+In diesem Beispiel wird das Inhaltsverzeichnis in die Indexdatei '9' gebracht, während
+der "allgemeine" Index in der Indexdatei '1' gesammelt wird. 
+#page# 
+ 
+#ib(9)#5.4.1.2. #ib#Nebeneinträge erzeugen#ie##ie(9)# 
+ 
+#free(1.0)# 
+   #on("i")# 
+   Sie haben die Möglichkeit, an die Seitennummer eines Eintrags einen beliebigen
+   Text anfügen zu lassen. 
+   #off("i")#  #free(1.0)# 
+Beispiel: 
+ 
+ 
+   EUMEL-System ... 27ff. 
+   Monitor ........ 13(Def.) 
+ 
+ 
+ 
+ 
+ 
+Dies wird durch eine weitere Form der \#ib\#-Anweisung ermöglicht: 
+ 
+____________________________________________________________________________ 
+ 
+   ... der \#ib(1,"(Kap.4)")\#EUMEL-Editor\#ie\# ist gut 
+   geeignet, Texte zu erstellen ... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+erzeugt den folgenden Eintrag: 
+ 
+ 
+ 
+Druckbild: 
+ 
+   EUMEL-Editor ... 1(Kap.4) 
+ 
+ 
+An einen Eintrag können Sie einen weiteren Text angefügen, um etwa Untereinträge
+zu bilden: 
+ 
+Druckbild: 
+ 
+  EUMEL-System .................................. 27 
+ 
+  EUMEL-System, komplexes ....................... 29 
+ 
+ 
+Das wird ebenfalls durch eine andere Form der \#ib\#-Anweisung ermöglicht: 
+ 
+____________________________________________________________________________ 
+ 
+   ... ist das \#ib\#EUMEL-System\#ie(1,", benutzerfreundliches")\#
+  wirklich ein benutzerfreundliches System ... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+erzeugt den folgenden Eintrag: 
+ 
+Druckbild: 
+ 
+  EUMEL-System, benutzerfreundliches ............ 28 
+ 
+ 
+ 
+Nach der Erstellung einer Indexdatei können - nach interaktiver Anfrage - die
+Einträge sortiert werden. Die Sortierung erfolgt alphabetisch nach DIN 5007, Abschnitt
+1 und 3.2 (Umlaute werden "richtig" eingeordnet). 
+ 
+ 
+ 
+Wie bereits erwähnt, können Sie 'index' vielseitig einsetzen: 
+ 
+a) Erstellung von Stichwortverzeichnissen: 
+   Wie bereits beschrieben. 
+ 
+b) Erstellung von Inhaltsverzeichnissen: 
+   Kapitelüberschriften mit eigenen Indexanweisungen klammern und durch 'index'
+   wie beschrieben verarbeiten. 
+ 
+   ____________________________________________________________________________ 
+ 
+      \#ib(9)\#6.1. Eine Datei drucken\#ie(9)\# 
+ 
+   _________________________________________________________________________ 
+ 
+ 
+   Dann sind Sie sicher, daß das Inhaltsverzeichnis bezüglich Seitennummern und
+   Kapitelüberschriften korrekt ist. 
+ 
+c) Erstellung von #ib#Abbildungsverzeichnisse#ie#n: 
+   Abbildungsüberschriften- bzw. -unterschriften wie Kapitelüberschriften verarbei­
+   ten. 
+ 
+d) Überprüfung von Literaturhinweisen auf Vollständigkeit: 
+   Sie klammern alle Literaturhinweise mit gesonderten Indexanweisungen. 
+ 
+   ____________________________________________________________________________ 
+ 
+      \#ib(8)\#/Meier82/\#ie(8)\#) 
+ 
+   _________________________________________________________________________ 
+ 
+   und überprüfen dann mit Hilfe dieser Indexdatei die Literaturverweise. So können
+   Sie sichergehen, daß alle Literaturverweise im Text auch in der Literaturaufstellung
+   stehen. 
+#page# 
+ 
+#ib(9)#5.4.1.3. #ib#Indexdateien zusammenführen#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Durch das Programm '#ib#index merge#ie(1,"-Kommando")#' können Sie eine Indexdatei in eine zweite
+   "einmischen". 
+   #off("i")#  
+#free(1.0)# 
+Es ist somit möglich, einen Index zu erstellen, der sich über mehrere Dateien er­
+streckt, indem Sie 'index' die Druckdateien dieser Dateien bearbeiten und an­
+schließend die entstandenen Indexdateien mit 'index merge' zusammenfassen lassen.
+Indexdateien können ggf. mit dem Editor bzw. 'lineform' und/oder 'pageform'/­
+'autopageform' bearbeitet und anschließend gedruckt werden. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   index merge ("1.kapitel.i1", "2.kapitel.i1") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+Hier wird die Indexdatei des 1. Kapitels in die Indexdatei des 2. Kapitels eingeordnet
+und auf Wunsch sortiert. 
+#page# 
+ 
+#ib(9)#5.5.   #ib#Outline#ie##ie(9)# 
+#goalpage("outline")# 
+#free(1.0)# 
+#ib(9)#5.5.1. Eine#ib# Strukturübersicht#ie# oder 
+       #ib#Zusammenfassung#ie# erstellen#ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Das Programm 'outline' erstellt aus einem Text eine Zusammenfassung aller
+   (Kapitel-) Überschriften und Stichworte, sofern diese mit #ib#Index-Anweisungen#ie#
+   gekennzeichnet sind. 
+   #off("i")# 
+#free(1.0)# 
+Manchmal sollen Stichworte oder das Inhaltsverzeichnis aus einem Text herausgeholt
+werden, ohne vorher 'pageform' durchlaufen zu müssen. Das ist dann nützlich, wenn
+Sie 
+ 
+-  Stichworte auf Korrektheit und Vollständigkeit überprüfen möchten; 
+-  die Reihenfolge von Kapiteln überprüfen müssen; 
+-  eine Übersicht durch Kapitel-Überschriften und Stichworte anfertigen möchten; 
+-  einen Text auf logische Zusammenstellung überprüfen. 
+ 
+ 
+In solchen Fällen hilft das Programm 'outline', das mit dem Monitor-Kommando 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   outline ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+aufgerufen wird. 'outline' arbeitet ähnlich wie 'index', indem es alle mit \#ib\# und \#ie\#
+markierten Textteile in eine Datei mit dem Zusatz 'outline' schreibt. Im Unterschied zu
+'index' muß die Eingabe-Datei keine Druckdatei ('.p'-Zusatz) sein. 
+ 
+Das Programm 'outline' fragt zuerst, mit welcher Indexnummer das Inhaltsverzeichnis
+versehen ist. Das ist notwendig, weil die Kapitelüberschriften gegenüber Stichwörtern
+in der 'outline'-Datei hervorgehoben werden (Einrückungen). 
+ 
+Eingabe-Datei ("dateiname"): 
+ 
+____________________________________________________________________________ 
+ 
+   ... 
+   \#ib(9)\#1. Kapitel\#ie(9)\# 
+   ... 
+   ...\#ib\#Stichwort 1\#ie\# 
+   \#ib\#Stichwort 2\#ie\#... 
+ 
+   \#ib(9)\#1.1. Kapitel\#ie(9)\# 
+   ... 
+   \#ib\#Stichwort 3\#ie\# 
+   usw... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Druckbild der erzeugten Datei ("dateiname.outline"): 
+ 
+   1. Kapitel 
+       Stichwort 1 
+       Stichwort 2 
+     1.1. Kapitel 
+          Stichwort 3 
+ 
+ 
+In diesem Beispiel werden alle Indizes mit Ausnahme der Kapitelüberschrift jeweils in
+einer Zeile aufgeführt und gegenüber der Kapitelüberschrift eingerückt. Ein neues
+Kapitel, sofern es dezimal gekennzeichnet ist, wird gegenüber einem Kapitel mit
+höherer Ordnung eingerückt. 
+#page# 
+ 
+#ib(9)#5.6. #ib#Print#ie##ie(9)##goalpage("print")#   
+#free(1.0)# 
+   #on("i")# 
+   Der #ib#EUMEL-Drucker#ie#, der mit dem #ib#'print'#ie(1,"-Kommando")#-Kommando angesprochen wird, ist
+   eine Software-Schnittstelle zu einem angeschlossenen Drucker. In diesem Kapitel
+   wird erklärt, wie Sie mit dem EUMEL-Drucker eine Datei drucken können und
+   welche speziellen Anweisungen den Drucker steuern. 
+   #off("i")#  
+#free(1.0)# 
+Jeder Drucker erbringt "hardwaremäßig" unterschiedliche Leistungen (z.B. Typen und
+Modifikationen). Diese Leistungen werden durch Eingabe spezieller Zeichenfolgen
+veranlaßt, die herstellerspezifisch sind. 
+ 
+Um vom EUMEL-System unterschiedliche Drucker auf gleiche Weise ansprechen zu
+können, wurde eine Software-Schnittstelle geschaffen, die #ib#EUMEL-Drucker#ie# ge­
+nannt wird. Der EUMEL-Drucker akzeptiert eine Datei und veranlaßt, daß diese in
+geeigneter Weise gedruckt wird. Weiterhin beachtet der EUMEL-Drucker die An­
+weisungen der Textkosmetik. Die Form der Anweisungen der Textkosmetik und des
+EUMEL-Druckers sind identisch. 
+#page# 
+ 
+#ib(9)#5.6.1. #ib#Eine Datei drucken#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Mit dem Kommando '#ib#print#ie#' können Sie dem EUMEL-Drucker eine Datei zum
+   Drucken übergeben. 
+   #off("i")# 
+#free(1.0)# 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   print ("dateiname")   
+ 
+____________________________________________________________________________ 
+ 
+ 
+In der Regel ist im EUMEL-System (Multi-User) ein "Spooler" installiert, so daß Sie
+sofort mit der Arbeit fortfahren können. Der EUMEL-Drucker arbeitet in diesem Fall
+parallel zu Ihren anderen Arbeiten. 
+#page# 
+ 
+#ib(9)#5.6.2. #ib#Anweisungen für den EUMEL-Drucker#ie##ie(9)# 
+#free(1.0)# 
+Ein Text (eine Datei) kann vom Drucker auch ohne Anweisungen gedruckt werden,
+etwa für Probedrucke. Für diesen Fall hat der Drucker vernünftige Voreinstellungen.
+Für einen "normalen" Text brauchen Sie keine speziellen Druckeranweisungen in den
+zu druckenden Text einzufügen, denn die Anweisungen für die Textkosmetik reichen
+zur Druckersteuerung aus. Nur wenn besondere Leistungen verlangt werden, wie z.B.
+Blocksatz oder den gedruckten Text an eine bestimmte Stelle zu plazieren, sind
+Druckeranweisungen notwendig. 
+ 
+Werden vom Drucker Leistungen verlangt, die hardwaremäßig nicht vorhanden sind,
+so sorgt der EUMEL-Drucker dafür, daß eine möglichst äquivalente Leistung erbracht
+wird. Fordern Sie beispielsweise einen nicht vorhandenen Schrifttyp an, wird mit
+dem Standard-Schrifttyp der jeweiligen Installation gedruckt. Damit ist es Ihnen
+möglich, einen Text, der eigentlich für einen anderen Drucker bestimmt ist, auf einem
+Drucker zu drucken, der die geforderte Type nicht kennt. 
+ 
+Wie bereits erwähnt, beachtet der EUMEL-Drucker die gleichen Anweisungen wie
+die Textkosmetik-Programme, aber einige Anweisungen sind nur für den Drucker
+implementiert. Eine #ib#\#type\#-Anweisung#ie# beispielsweise, die einen bestimmten Schrift­
+typ anfordert, wird vom EUMEL-Drucker als Befehlsfolge an den angeschlossenen
+Hardware-Drucker übergeben, sofern der Schrifttyp auf dem Drucker vorhanden ist.
+Wie die Anweisungen geschrieben werden müssen, wurde in der Beschreibung der
+Textkosmetik geschildert. 
+ 
+Anweisungen werden nicht gedruckt. Besteht eine Zeile nur aus Anweisungen, so wird
+diese Zeile vom EUMEL-Drucker nicht gedruckt. Im Gegensatz zu den Programmen
+der Textkosmetik werden unbekannte oder #ib#fehlerhafte Anweisungen#ie# vom EUMEL­
+Drucker ohne Fehlermeldung "verschluckt". 
+ 
+Neben den "normalen" Anweisungen, die nur in "\#"-Zeichen eingeschlossen wer­
+den, gibt es noch eine andere Form: 
+ 
+Kommentar-#ib#Anweisungen#ie(1,", Kommentar-")#: 
+ 
+   Werden in "\#-" und "-\#"-Zeichen eingeschlossen. Solche Anweisungen wer­
+   den ignoriert. 
+ 
+____________________________________________________________________________ 
+ 
+      .......................... 
+      Text...................... 
+      .......................... 
+      Kommentar-Anweisungen werden 
+      beim Drucken ignoriert. 
+      \#---- Ende der Seite 1 ---\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Die letze Zeile erscheint im gedruckten Text nicht. 
+#page# 
+#goalpage("block")# 
+#ib(9)#5.6.3. #ib#Blocksatz#ie# #ie(9)# 
+#free(1.0)# 
+#ib(9)#5.6.3.1. #ib#Randausgleich#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Die Anweisung #ib#\#block\##ie(1,"-Anweisung")# bewirkt einen Blocksatz beim Druck. 
+   #off("i")#  
+#free(1.0)# 
+Fügen Sie in den Text (meist am Anfang einer Datei) die Anweisung 
+ 
+____________________________________________________________________________ 
+ 
+     \#block\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ein, druckt der Drucker ab dieser Stelle alle Zeilen, die nicht mit einem Absatzkenn­
+zeichen versehen sind, im #ib#Blocksatz#ie#. Das heißt, daß durch Vergrößern der Wort­
+abstände alle Zeilen an der gleichen Position enden (rechter #ib#Randausgleich#ie#). Preis­
+werte Drucker können dies nur durch Einfügen ganzer Leerzeichen zwischen den
+Worten vornehmen, was sich oft beim Lesen störend bemerkbar macht. Bei qualitativ
+hochwertigen Druckern wird dagegen der Blocksatz durch Einfügen kleinerer Abstän­
+de zwischen den Worten erreicht. 
+ 
+Der Text einer Zeile wird durch Vergrößern der #ib#Wortlücken#ie(1, ", Vergrößern der")# auf die Zeilenlänge, die
+durch die \#limit\#-Anweisung eingestellt ist, verbreitert. 
+ 
+ 
+a) Es werden nicht verbreitert: 
+ 
+   -  Absatzzeilen; 
+   -  der Text bis zum letzten #ib#Mehrfachblank#ie#; 
+   -  führende Leerzeichen (#ib#Einrückung#ie#); 
+   -  ein Leerzeichen hinter einer Aufzählung (siehe dazu b); 
+   -  geschützte Blanks. 
+ 
+ 
+ 
+b) #ib#Aufzählungen#ie# gibt es nur nach einer Absatzzeile: 
+ 
+   -  "Spiegelstrich" (Bindestrich und Leerzeichen am Anfang der Zeile); 
+   -  Doppelpunkt als Ende des ersten Wortes (Position < 20); 
+   -  schliessende Klammer oder Punkt als Ende des ersten Wortes (Position < 7),
+      z.B. 1) oder 1. 
+#page# 
+#goalpage ("pageblock")# 
+ 
+#ib(9)#5.6.3.2. #ib#Seitenausgleich#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der #ib#\#pageblock\#-Anweisung#ie# wird der Drucker veranlaßt, einen Seiten­
+   ausgleich (ähnlich wie bei der \#block\#-Anweisung für den rechten Rand­
+   ausgleich) vorzunehmen. 
+   #off("i")# 
+#free(1.0)# 
+Durch die automatische oder interaktive Seitenformatierung oder durch einen Fuß­
+notenumbruch von 'pageform'/'autoform' bleiben oft am Ende einer Seite Zeilen leer.
+Dies können Sie durch die \#pageblock\#-Anweisung verhindern. Sie veranlaßt den
+Drucker, Zwischenräume (Fachbegriff: Durchschuß) zwischen den Zeilen einzufügen,
+so daß alle letzten Zeilen auf allen Seiten auf gleicher Höhe abschließen. Ebenso wie
+beim Randausgleich hängt die Güte des Druckergebnisses jedoch von den Fähig­
+keiten des angeschlossenen Druckers ab. 
+ 
+Beachten Sie jedoch, daß manche Verlage so bearbeitete Seiten nicht wünschen, weil
+bei Verwendung von zu dünnem Papier beim Druck Zeilen "durchscheinen" können,
+so daß das Lesen erschwert wird. 
+ 
+Ist die Anweisung \#pageblock\# gegeben, können Sie in 'pageform' die Seitengrenze
+auch über das rechnerische Seitenende hinaus plazieren. In diesem Fall werden die
+Zeilen vom Drucker gestaucht. 
+#mark ("", "")# 
+ 
+ 
+____________________________________________________________________________ 
+ 
+PAGEFORM für x Zeilen: dateiname ---> dateiname.p 
+ 
+____________________________________________________________________________ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ Seitenende verschieben: UP, DOWN / bestaetigen: RETURN / Abbruch: ESC 
+ 
+____________________________________________________________________________ 
+ 
+ 
+#page# 
+ 
+#ib(9)#5.6.4. #ib#Schreibfeld verschieben#ie##ie(9)# #goalpage("start")# 
+#free(1.0)# 
+   #on("i")# 
+   Durch die Anweisung #ib#\#start\# #ie(1,"-Anweisung")#ist es Ihnen möglich, das #ib#Schreibfeld#ie# beim Druck auf
+   dem Papier an eine andere Stelle zu plazieren. 
+   #off("i")# 
+#free(1.0)# 
+Der EUMEL-Drucker plaziert das Schreibfeld auf einem Drucker automatisch derart,
+daß ein genügender Rand verbleibt. Die Wirkung dieser Voreinstellung ist natürlich
+abhängig vom Drucker und der Installation. Mit der \#start\#-Anweisung können Sie
+die automatische Einstellung verändern. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   \#start (1.0, 2.0)\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+legt die linke, obere Ecke des Schreibfeldes fest (vom linken Rand 1 cm, vom oberen
+Rand 2 cm). Die standardmäßige Voreinstellung ist \#start (2.54, 2.35)\#. Die \#start
+(...)\#-Anweisung können Sie nur einmal pro Seite geben. 
+#page# 
+
diff --git a/doc/user/benutzerhandbuch.5c b/doc/user/benutzerhandbuch.5c
new file mode 100644
index 0000000..010cacd
--- /dev/null
+++ b/doc/user/benutzerhandbuch.5c
@@ -0,0 +1,711 @@
+#start(5.0,1.5)##pagenr("%",93)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Teil 5: Textkosmetik und Druck    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+5 - %      GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        5 - % 
+#tableend##clearpos# 
+#end# 
+#goalpage("center")# 
+#ib(9)#5.6.5. #ib#Zentriert drucken#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der #ib#\#center\#-Anweisung#ie# können Sie einen Text in der Mitte der Zeile drucken
+   lassen. 
+   #off("i")# 
+#free(1.0)# 
+ 
+Die \#center\#-Anweisung zentriert den Text einer Absatzzeile. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   \#center\#Diese Zeile wird zentriert gedruckt. 
+ 
+#mark ("", "")# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Druckbild: 
+ 
+          #center#Diese Zeile wird zentriert gedruckt. 
+#page# 
+ 
+#ib(9)#5.6.6. #ib#Rechtsbündig drucken#ie##ie(9)# 
+#goalpage("right")# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der #ib#\#right\#-Anweisung#ie# können Sie einen Teil einer Absatzzeile rechtsbündig
+   drucken. 
+   #off("i")# 
+#free(1.0)# 
+ 
+Die \#right\#-Anweisung veranlaßt, daß der nachfolgende Text rechtsbündig gedruckt
+wird. 
+ 
+____________________________________________________________________________ 
+ 
+   \#head\#                                           
+   \#center\#Diese Zeile wird zentriert\#right\#%       
+                                                    
+   \#end\#                                            
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Hierbei wird die Seitenzahl rechtsbündig gedruckt. 
+ 
+Beachten Sie, daß die \#center\#- und die \#right\#-Anweisung zusammen verwendet
+werden können. Beide Anweisungen wirken jedoch nur, wenn sie in einer Absatzzeile
+stehen. 
+ 
+#mark ("", "")# 
+#page# 
+ 
+#ib(9)#5.6.7. #ib#Übereinander drucken#ie##ie(9)# 
+#goalpage ("b")# 
+#free(1.0)# 
+   #on("i")# 
+   Mit der #ib#\#b\#-Anweisung#ie# können Sie zwei Zeichen übereinander drucken. 
+   #off("i")# 
+ 
+#free(1.0)# 
+Die \#b\#-Anweisung veranlaßt, daß zwei aufeinanderfolgende Zeichen, die durch die
+\#b\#-Anweisung verbunden sind, übereinander gedruckt werden. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+... 0\#b\#/ ... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+Druckbild: 
+ 
+... 0#b#/  ... 
+ 
+ 
+Das Zeichen '/' wird über das Zeichen '0' gedruckt. 'lineform'/'autoform' nimmt für die
+Zeilenberechnung nur ein Zeichen. Beachten Sie, daß direkt vor oder nach der
+\#b\#-Anweisung keine Anweisung oder kein Blank stehen darf. 
+#mark ("", "")# 
+#page# 
+ 
+#ib(9)#5.7. #ib#Textkosmetik-Makros#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   #ib#Makros#ie# verkürzen Ihren Arbeitsvorgang bei immer wiederkehrenden Textteilen
+   und/oder Anweisungen. 
+   #off("i")# 
+#free(1.0)# 
+Unter 'Makro' verstehen wir eine "große" Anweisung, die aus vielen kleinen besteht
+und die Sie mit Hilfe des Makronamens aufrufen können. 
+ 
+Textkosmetik-Makros kommen zum Einsatz bei: 
+ 
+-  immer wiederkehrenden Textteilen; 
+-  immer wiederkehrenden Anweisungssequenzen; 
+-  bei der Erstellung von Manuskripten, deren endgültige Form Sie anfänglich noch
+   nicht kennen oder die Sie noch ändern möchten; 
+-  oder bei Folgen von direkten Drucker-Anweisungen, die bestimmte Leistungen
+   erbringen. 
+ 
+Die Definition von einem oder mehreren #ib#Makros#ie# wird mit dem Editor vorgenommen.
+Diese #ib#Makro-Datei#ie# wird dann geladen. Von diesem Augenblick an "kennen" 'line­
+form'/'autoform' und 'pageform'/'autopageform' die Makros, d.h. die Textzeilen und/
+oder Anweisungen, die sich unter dem #ib#Makronamen#ie# "verbergen". 
+ 
+'lineform'/'autoform' beachtet die Anweisungen, die ggf. in den Makros enthalten sind.
+Sie erscheinen jedoch nicht in der Datei. Erst 'pageform'/'autopageform' setzt diese in
+die Druckdatei ein. 
+#page# 
+ 
+#ib(9)#5.7.1. Ein Makro-Beispiel#ie(9)# 
+#free(1.0)# 
+   #on("is")# 
+   Hier wird Ihnen ein einfaches Beispiel für einen Briefkopf gezeigt. 
+   #off("is")# 
+#free(1.0)# 
+Angenommen, Sie schreiben mit dem EUMEL-System Ihre Geschäftsbriefe. Sie
+haben einen Drucker zur Verfügung, mit dem Sie auch die Briefköpfe erstellen kön­
+nen. Für den #ib#Briefkopf#ie# schreiben Sie ein Makro \#kopf\# in eine Datei "macro defini­
+tionen": 
+ 
+____________________________________________________________________________ 
+ 
+  \#*kopf\#                                 
+  \#type("fett und gross")\#Firmenname      
+  \#type("fett")\#Softwareprodukte          
+  \#type("klein")\#Straße                   
+  Stadt                                   
+  \#type ("normal")\#                       
+  \#*macro end\#                            
+ 
+____________________________________________________________________________ 
+ 
+ 
+Der Name des Makros ist \#kopf\#. Beachten Sie, daß eine #ib#Makro-Definition#ie# mit dem
+Namen des Makros beginnen muß. Der #ib#Makroname#ie# muß dabei mit einem #on("b")#*#off("b")# gekenn­
+zeichnet werden, um ihn von "normalen" Text-Anweisungen unterscheiden zu kön­
+nen. Jedes Makro wird mit einer \#*macro end\#-Anweisung beendet. Sie dürfen
+mehrere Makros hintereinander in die Datei schreiben. 
+ 
+Nun müssen Sie das so definierte Makro 'laden': 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   #ib#load macros#ie# ("macro definitionen") 
+             
+____________________________________________________________________________ 
+#goalpage("load macros")##goalpage("list macros")# 
+ 
+ 
+Zur Kontrolle können Sie sich die geladenen Makros in das Notizbuch ausgeben
+lassen: 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   #ib#list macros#ie# 
+ 
+____________________________________________________________________________ 
+#mark ("", "")# 
+ 
+ 
+ 
+Nun haben Sie von jetzt an eine neue Anweisung (mit dem Namen \#kopf\#) zur Ver­
+fügung, mit der Sie einen Briefkopf in jeden Brief drucken können. Sie schreiben nun
+folgenden Brief: 
+ 
+____________________________________________________________________________ 
+ 
+   \#kopf\# 
+ 
+   Sehr geehrter Herr .... 
+ 
+   usw.  
+ 
+____________________________________________________________________________ 
+ 
+ 
+Beachten Sie hierbei, daß das Makro in Ihrem Text als Anweisung ohne #on("b")#*#off("b")# steht. Der
+#ib#Aufruf eines Makros#ie#, welches z.B. in einer von 'lineform' zu bearbeitenden Datei
+steht, unterscheidet sich also nicht von einer "normalen" Textanweisung. 
+ 
+Nachdem Sie mit 'lineform' den Brief zeilenweise formatiert haben, kontrollieren Sie
+die formatierte Datei. Hier hat sich noch nichts verändert. Die neue Anweisung \#kopf\#
+steht unverändert in der Datei. 'lineform' beachtet zwar alle Anweisungen und Text­
+zeilen eines Makros, setzt diese jedoch nicht in die Datei ein. Allerdings ist 'lineform'
+nicht in der Lage, die \#type\#- und \#limit\#-Anweisungen eines Makros zu erkennen,
+wenn es an erster Stelle in einer Datei steht und in dessen Definition gleich zu
+Anfang diese Anweisungen korrekt aufgeführt sind. Stattdessen fragt 'lineform' an­
+fangs 'type' und 'limit' an. Das können Sie umgehen, indem Sie mittels 'CR' die
+Abfrage in 'lineform' ignorieren. 
+ 
+Nun formatieren Sie die Datei, die den Brief enthält, mit 'pageform'/'autopageform'. In
+der Druckdatei ist nun die Anweisung \#kopf\# verschwunden. Dort stehen nun die
+Zeilen des #ib#Makrorumpf#ie#es. 'pageform'/'autopageform' setzt die Zeilen des Makros in
+die Druckdatei ein: 
+ 
+____________________________________________________________________________ 
+ 
+  \#type("fett und gross")\#Firmenname                          
+  \#type("fett")\#Softwareprodukte                              
+  \#type("klein")\#Straße                                       
+  Stadt                                                       
+  \#type ("normal")\#                                      
+                                                         
+                                                         
+  Sehr geehrter Herr ... 
+  usw. 
+ 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+#on("b")##on("i")#Anmerkung:#off("b")##off("i")#  
+Makros, die den gleichen Namen haben, aber sich durch die Anzahl der Parameter
+unterscheiden, sind nicht erlaubt. Es ist auch nicht gestattet, Makros innerhalb einer
+Makro-Definition aufzurufen. 
+ 
+Beachten Sie ferner, daß Makro-Texte so verwendet werden, wie sie mit 'load
+macros' geladen werden. 
+ 
+____________________________________________________________________________ 
+ 
+   \#*textanfang\#                      
+   \#limit(11.0)\#                      
+   \#block\#                            
+   \#pageblock\#                        
+   \#type("trium8")\#                   
+   \#*macro end\#                       
+ 
+____________________________________________________________________________ 
+ 
+ 
+Betätigen Sie in der Makro-Datei nach jeder Zeile die #taste1(" CR ")#-Taste (Absatz), dann
+erhalten Sie nach jedem \#...\# einen Absatz, was zum Beispiel bei Kapitelüberschriften
+wünschenswert ist, nicht jedoch bei kleineren Anweisungen, bei denen dann mitten im
+Satz ein Absatz erschiene. In solchen Anwendungen sollten Sie Makros ohne Absätze
+speichern. Beachten Sie ferner, daß aus programmtechnischen Gründen eine \#foot\#-
+oder die abschließende \#end\#-Anweisung einer Fußnote nicht in einem Makro ent­
+halten sein darf. 
+#page# 
+ 
+#ib(9)#5.7.2. Ein Beispiel mit #ib#Makro-Parameter#ie#n#ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Makro-Parameter erlauben es Ihnen, immer wiederkehrende Textteile, die sich
+   nur geringfügig voneinander unterscheiden, zu erzeugen. 
+   #off("i")#  
+#free(1.0)# 
+Ihnen fällt nun auf, daß Sie Ihr Makro noch etwas verbessern können. Sie möchten
+das Datum mit in den Briefkopf aufnehmen. Somit editieren Sie Ihre Makro-Datei
+folgendermaßen (beachten Sie die '$'-Zeichen): 
+ 
+____________________________________________________________________________ 
+ 
+   \#*kopf ($1)\#                                       
+   \#type("gross")\#Firmenname                          
+   \#type("fett")\#Softwareprodukte                     
+   \#type("klein")\#Straße                              
+   Stadtname                                          
+   \#type ("normal")\#                                  
+                                                      
+                                        Stadtname, den $1      
+   \#*macro end\#                                       
+ 
+____________________________________________________________________________ 
+ 
+ 
+Damit haben Sie dem \#kopf\#-Makro einen Parameter gegeben: '$1'; die Parameter
+werden numeriert. Ein zweiter Parameter würde '$2' heißen usw.. 
+ 
+Bei der Erstellung eines Briefes müssen Sie die Anweisung \#kopf\# mit dem jeweiligen
+Datum in einen Brief schreiben: 
+ 
+____________________________________________________________________________ 
+ 
+   \#kopf ("20.8.1986")\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+'pageform'/'autopageform' setzt nun das angegebene Datum direkt hinter 'Stadtname,
+den' in den Briefkopf ein (in der Druckdatei). Beachten Sie, daß alle Parameter einer
+Makro-Anweisung in Anführungszeichen stehen müssen (auch Zahlen). 
+#page# 
+ 
+#ib(9)#5.7.3. #ib#Makros für Manuskripte#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   Hier wird gezeigt, wie Sie mit Makros Anweisungen formulieren können, die
+   aussagen, um was es sich bei einem Text handelt, und nicht, in welchem Format
+   er gedruckt wird. 
+   #off("i")#  
+#free(1.0)# 
+Bei Manuskripten für Artikel, Bücher und Manuals wissen Sie oft vorher nicht, in
+welchem Format das Manuskript gedruckt werden wird. Zu diesem Zweck ist es
+ebenfalls nützlich, Makros zu verwenden. 
+ 
+____________________________________________________________________________ 
+ 
+   \#*kapitelanfang ($1)\#                                   
+   \#free (2.0)\#                                            
+   \#type ("gross")\#\#ib (9)\#$1\#ie (9)\#\#type ("normal")\#     
+                                                           
+   \#*macro end\#                                            
+ 
+____________________________________________________________________________ 
+ 
+ 
+In diesem Beispiel wird ein Makro für den Anfang eines Kapitels definiert. Zwischen
+zwei Kapiteln sollen hier zwei Zentimeter Zwischenraum bleiben, die Kapitel-
+Überschrift (als Parameter) wird in einer größeren Schrift gedruckt. Zusätzlich wird die
+Überschrift für ein Inhaltsverzeichnis in den 9. Index aufgenommen. Nach der Über­
+schrift wird eine Leerzeile eingeschoben, bevor der eigentliche Text anfängt. 
+ 
+Der Anwender dieses Makros schreibt also z.B. folgende Anweisung: 
+ 
+____________________________________________________________________________ 
+ 
+   \#kapitelanfang ("Ein Beispiel fuer Manuskripte")\#       
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Beachten Sie, daß die Kapitel-Überschrift nicht länger als eine Textzeile sein darf.
+Das liegt daran, daß 'lineform'/'autoform' zwar die Zeile bearbeitet, aber nicht in den
+Text einsetzt. 'pageform'/'autopageform' setzt also die unveränderte - nicht umge­
+brochene - Textzeile ein. 
+ 
+Sie können nun Makros für die meisten Textstrukturen definieren. Schreibkräfte
+brauchen dann in der Regel die meisten Text-Anweisungen nicht zu kennen, son­
+dern nur noch eine Anzahl von einfachen Makro-Anweisungen. 
+ 
+Die Makro-Definitionen können jederzeit geändert werden, um wechselnden Bedürf­
+nissen angepaßt zu werden, z.B. wenn ein Verlag ein bestimmtes Schreibformat
+verbindlich vorschreibt. In diesem Fall brauchen nicht alle Text-Dateien geändert zu
+werden, sondern nur die Makro-Definitionen. 
+ 
+Ein weiterer Vorteil einer solchen Vorgehensweise ist, daß die Makro-Anweisungen in
+diesem Fall angeben, #on("i")##on("b")#was#off("i")##off("b")# eine bestimmte Text-Struktur ist, und nicht, #on("i")##on("b")#wie#off("i")##off("b")# die
+Struktur behandelt werden soll. 
+ 
+#on("b")#Anmerkung#off("b")#: 
+In eine Makro-Definition sollten Sie ggf. \#limit\#-, \#type\#- und \#linefeed\#-
+Angaben einsetzen, um die Makros unabhängig von der Aufrufstelle zu machen. Ggf.
+sollten Sie auch die Datei vorher mit 'lineform' bearbeiten, um Trennungen vorzu­
+nehmen. 
+#page# 
+ 
+#ib(9)#5.8. Textkosmetik für Spezialisten#ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   In diesem Abschnitt werden Ihnen Kommandos und Anweisungen vorgestellt, die
+   in der Regel nur für Spezialfälle benötigt werden. 
+   #off("i")# 
+#free(1.0)# 
+ 
+#ib(9)#5.8.1. Schalter-Anweisungen für 
+       #ib#Kopf- und Fußbereiche#ie(1, "Schalter-Anweisungen für")##ie(9)# 
+#goalpage("head off")##goalpage("bottom off")# 
+#free(1.0)# 
+ 
+Mit den Textkosmetik-Anweisungen 
+ 
+____________________________________________________________________________ 
+ 
+   #ib#\#head off\##ie# 
+ 
+   #ib#\#bottom off\##ie# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+können Sie die Erzeugung von Kopf- oder Fußzeilen abschalten. Mit 
+ 
+ 
+____________________________________________________________________________ 
+ 
+      #ib#\#head on\##ie# 
+ 
+      #ib#\#bottom on\##ie# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+können Sie diese wieder erzeugen. Beachten Sie, daß diese Anweisungen an der
+Stelle beachtet werden, an der sie im Text stehen, d.h. diese Anweisungen gelten
+bereits für die Seite, auf der sie sich bei der 'pageform'-Bearbeitung befinden. Möch­
+ten Sie die Kopfzeilen für eine Seite abschalten, dann sollten Sie an dieser Stelle die
+#ib#\#head off\#-Anweisung#ie# geben. Um die Kopfzeilen für die nächste Seite wieder einzu­
+schalten, sollten Sie die #ib#\#head on\#-Anweisung#ie# an einer Stelle plazieren, von der Sie
+sicher sind, daß sie auf die folgende Seite gelangt (im Zweifelsfall nach einer
+\#page\#-Anweisung). 
+#mark ("", "")# 
+#page# 
+ 
+#ib(9)#5.8.1.1. #ib#Kopf- und Fußbereiche abstellen#ie##ie(9)# 
+#goalpage ("first head")##goalpage("last bottom")# 
+#free(1.0)# 
+   #on("i")# 
+   Mit '#ib#first head#ie#' bzw. '#ib#last bottom#ie#' können Sie Kopf- oder Fußbereiche auf der
+   ersten (letzten) Seite ab- oder wieder anschalten. 
+   #off("i")# 
+#free(1.0)# 
+Manchmal ist es notwendig, die Erzeugung von 'head'-Zeilen auf der ersten Seite
+(z.B. weil dort ein Briefkopf erscheint) und/oder 'bottom'-Zeilen auf der letzten Seite
+(weil keine Folgeseite existiert) zu verhindern. Mit dem Monitor-Kommando 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   #ib#first head (FALSE)#ie# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+können Sie bei 'pageform' die Erzeugung von 'head'-Zeilen auf der ersten Seite
+jeder Druckdatei abschalten. Die Erzeugung bleibt so lange abgeschaltet, bis sie
+wieder durch 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   #ib#first head (TRUE)#ie# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+angeschaltet wird. Das gleiche gilt analog für 'bottom'-Zeilen auf der letzten Seite:
+Ein- und Ausschalten durch 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   #ib#last bottom (FALSE)#ie# 
+ 
+____________________________________________________________________________ 
+#mark("","")# 
+ 
+bzw. 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   #ib#last bottom (TRUE)#ie# 
+ 
+____________________________________________________________________________ 
+#page# 
+ 
+#ib(9)#5.8.2. Textzeilen markieren#ie(9)# 
+#goalpage("mark")# 
+#free(1.0)# 
+Mit der Anweisung 
+ 
+ 
+____________________________________________________________________________ 
+ 
+  \#mark("markierungszeichen links","markierungszeichen rechts")\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+können Sie einen Textabschnitt an den Rändern (außerhalb des Schreibfeldes!) mit
+Texten markieren, wie z.B. im folgenden mit der Anweisung 
+ 
+#mark ("", "")# 
+ 
+____________________________________________________________________________ 
+ 
+   \#mark ("> ", " <")\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+#mark ("> ", "  <")# 
+Dabei gilt der erste Parameter für den linken und der zweite für den rechten Rand.
+Beachten Sie, daß Sie einen genügenden Zwischenraum zwischen der Markierung
+und dem Rand mit angeben müssen. 
+ 
+Die Markierung ist insbesondere für Manuals interessant, wo Änderungen gegen­
+über der letzten Version hervorgehoben werden. Das Markierungszeichen wird neben
+den linken und rechten Rand gedruckt (also außerhalb des von \#start\# und \#limit\#
+begrenzten Textfeldes). Für das Drucken der Markierung wird der/die Schrifttyp/ Modi­
+fikationen benutzt, die an der Stelle der \#mark\#-Anweisung eingeschaltet ist. Der
+eigentliche Text bleibt selbstverständlich unberührt. 
+#mark ("", "")# 
+ 
+Um nur einen Rand zu markieren, kann auch ein leerer Parameter angegeben
+werden. 
+ 
+____________________________________________________________________________ 
+ 
+   \#type ("pica")\#\#mark ("", " |")\#\#type ("normal")\# 
+ 
+____________________________________________________________________________ 
+    
+ 
+ 
+Mit der speziellen #ib#\#mark\#-Anweisung#ie# 
+ 
+____________________________________________________________________________ 
+ 
+   \#mark ("", "")\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+wird die Markierung ausgeschaltet. 
+ 
+Soll ein Kopf-, Fuß-, Fußnoten- oder Tabellenbereich markiert werden, sollten sich
+die Markierungsein- und ausschalt-Anweisungen vollständig in dem Bereich be­
+finden. 
+#page# 
+ 
+#ib(9)#5.8.3. #ib#Fußnoten pro Seite zählen#ie##ie(9)# 
+#goalpage("countperpage")# 
+#free(1.0)# 
+Manchmal wird gewünscht, daß die Fußnoten für jede Seite separat - also für jede
+Seite von 1 ab - gezählt werden. Das können Sie mit der Textkosmetik-Anweisung 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   \#count per page\# 
+ 
+____________________________________________________________________________ 
+ 
+ 
+erreichen. Sie schaltet von einer fortlaufenden Zählung auf eine seitenweise Zählung
+um. Diese Anweisung sollte am Dateianfang stehen. Sie kann für die betreffende
+Datei nicht mehr abgeschaltet werden. 
+#page# 
+ 
+#ib(9)#5.8.4. Behandlung falscher #ib#Silbentrennungen#ie(1, ", Behandlung von falschen")#: 
+       #ib#Ausnahmelexikon#ie##ie(9)# 
+#free(1.0)# 
+   #on("i")# 
+   In das Ausnahmelexikon können fehlerhaft getrennte Worte aufgenommen
+   werden. 
+   #off("i")# 
+#free(1.0)# 
+Es kann vorkommen, daß das Silbentrenn-Programm der Textkosmetik einige Worte
+immer wieder falsch trennt. Um dies zu vermeiden, können Sie diese Worte in ein
+#on("b")##on("i")#Ausnahmelexikon#off("b")##off("i")# speichern. Die Worte des Ausnahme-Lexikons werden bei einer
+Silbentrennung zuerst durchsucht. Wird ein Wort im Lexikon gefunden, dann wird das
+eigentliche Silbentrenn-Programm nicht mehr ausgeführt. 
+ 
+Die Ausnahmen müssen Sie - wie unten beschrieben - in einer Datei notieren und
+mit dem Monitor-Kommando 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   #ib#lade ausnahmen#ie# ("dateiname") 
+ 
+____________________________________________________________________________ 
+#goalpage("lade ausnahmen")# 
+ 
+ 
+in das Lexikon laden. Die Ausnahmen müssen Sie folgendermaßen in die Datei
+schreiben: 
+ 
+____________________________________________________________________________ 
+ 
+   Sprech-stun-de          
+   ins-be-son-de-re        
+   Raum                    
+   Bei-spiel               
+   ... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Sie können jederzeit neue Ausnahmen in das Lexikon hinzuladen (wiederum mit 'lade
+ausnahmen'). In diesem Fall wird angefragt, ob das Lexikon überschrieben werden
+soll. 
+ 
+ 
+ 
+Um zu kontrollieren, welche oder wie viele Ausnahmen sich im Lexikon befinden,
+können Sie 
+ 
+____________________________________________________________________________ 
+ 
+     gib kommando: 
+     #ib#entlade ausnahmen#ie# ("dateiname") 
+ 
+____________________________________________________________________________ 
+     #goalpage("entlade ausnahmen")# 
+ 
+geben. Das Lexikon wird dann in "dateiname" geschrieben. Auch hier können Sie
+weitere Ausnahmen hinzufügen und diese neu laden (aber diesmal überschreiben). 
+#mark ("", "")# 
+#page# 
+ 
+#ib(9)#5.8.5. #ib#Voreinstellungen ändern#ie#: 
+       Einige Monitor-Kommandos#ie(9)# 
+#free(1.0)# 
+#ib(9)#5.8.5.1. Wenige oder viele #ib#Silbentrennung#ie#en: 
+       #ib#Trennpunkt einstellen#ie##ie(9)# 
+#goalpage ("hyphenation width")# 
+#free(1.0)# 
+   #on("i")# 
+   Mit dem Kommando 'hyphenation width' können Sie bestimmen, an welchem
+   Punkt Worte zur Trennung angeboten werden. Die Trennbreite können Sie
+   zwischen 4 und 20 Prozent der Zeilenbreite einstellen. 
+   #off("i")# 
+#free(1.0)# 
+Viele Silbentrennungen in einem Text erschweren das Lesen. Nehmen Sie keine
+Silbentrennungen vor, wird der rechte Rand stark "ausgefranst" oder beim Blocksatz
+("rechter Randausgleich") müssen viele Zwischenräume zwischen den Worten ein­
+gefügt werden. Durch das Monitor-Kommando 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   #ib#hyphenation width#ie# (prozentuale angabe) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+unmittelbar vor dem Aufruf von 'autoform' oder 'lineform' können Sie den Punkt, an
+dem die Silbentrennung einsetzen soll, einstellen. Die Klammern enthalten eine ganze
+Zahl, die für Prozent der Zeilenbreite steht. Minimum sind 4, Maximum 20 Prozent.
+Beispielsweise stellt 'hyphenation width (5)' den Trennpunkt auf 5% der Zeilenbreite
+ein (voreingestellt ist 7). Bei einer Angabe von 20 werden somit sehr wenige Worte
+zur Silbentrennung angeboten, d.h. je größer die Prozentangabe, desto weniger Worte
+werden zur Trennung angeboten. Die Einstellung des Trennpunktes bestimmt also, ab
+wann ein Wort zur Silbentrennung untersucht wird. Andererseits bestimmt die Ein­
+stellung auch, wieviel Zwischenraum zwischen Worten eingefügt werden muß, um
+einen rechten Randausgleich zu erzielen. 
+#page# 
+ 
+#ib(9)#5.8.5.2. Anzahl #ib#Leerzeilen vor Fußnoten#ie# 
+       einstellen#ie(9)# 
+#goalpage("number empty")# 
+#free(1.0)# 
+   #on("i")# 
+   '#ib#number empty lines before foot#ie#' stellt die Anzahl der Leerzeilen vor Fußnoten ein. 
+   #off("i")# 
+#free(1.0)# 
+Die Anzahl der Leerzeilen vor #ib#Fußnoten#ie(1, ", Leerzeilen davor")# (voreingestellt ist eine Leerzeile) können Sie
+durch das Monitor-Kommando 'number empty lines before foot' einstellen. 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+   gib kommando: 
+   number empty lines before foot (3) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+stellt drei Leerzeilen vor dem Fußnotenblock ein. Beachten Sie, daß diese Einstellung
+so lange gilt, bis Sie das Monitor-Kommando erneut geben. 
+#mark("","")# 
+
diff --git a/doc/user/benutzerhandbuch.5d b/doc/user/benutzerhandbuch.5d
new file mode 100644
index 0000000..8a61f29
--- /dev/null
+++ b/doc/user/benutzerhandbuch.5d
@@ -0,0 +1,211 @@
+#start(5.0,1.5)##pagenr("%",116)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Teil 5: Textkosmetik und Druck    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+5 - %      GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        5 - % 
+#tableend##clearpos# 
+#end# 
+ 
+#ib(9)#5.9. Übersicht über die Anweisungen und 
+     Kommandos der EUMEL-Textkosmetik#ie(9)# 
+#free(1.0)# 
+   #on ("i")# 
+   Zuerst werden die am häufigsten benutzten Kommandos/Anweisungen beschrie­
+   ben. Danach sind (durch einen Strich getrennt) Kommandos/Anweisungen auf­
+   geführt, die seltener benötigt werden. 
+   #off ("i")# 
+#free(1.0)# 
+#on("b")# 
+#ib#Kommandos#ie##off("b")# 
+#free(1.0)# 
+   #on("i")# 
+   Kommandos werden im Monitor gegeben ('gib kommando :'). 
+   #off("i")#  
+#free(1.0)# 
+#lpos(0.0)##lpos(4.6)# 
+#table# 
+#on("b")#Kommando               Bedeutung#off("b")# 
+#free(1.0)# 
+#clearpos# 
+#lpos(0.0)##lpos(4.6)# 
+lineform ("x")                  Formatieren von Zeilen mit interaktiver Silben­
+                                trennung. 
+autoform ("x")                  Wie lineform, jedoch werden Silbentrennungen
+                                automatisch vorgenommen. 
+pageform ("x")                  Interaktives Formatieren von Seiten, mit Behand­
+                                lung von Fußnoten, Kopf- und Fußzeilen, Seiten­
+                                numerierung, Seitenquerverweisen usw. Erzeugt
+                                eine Druckdatei (Zusatz '.p'). 
+autopageform ("x")              Wie pageform, jedoch werden die Seitengrenzen
+                                automatisch plaziert. 
+print ("x")                     Datei drucken. 
+print ("x.p")                   Eine mit 'pageform' bearbeitete Datei drucken. 
+----------------                ----------------
+#page# 
+index ("x.p")                   Erstellt aus einer Druckdatei ein Stichwort-
+                                und/oder Inhaltsverzeichnis. 
+index merge ("a.i1","b.i1")     Führt Indexdateien zusammen. 
+outline ("x")                   Erstellt eine Übersicht aus Kapitelüberschriften
+                                und Stichworten. 
+hyphenation width (int)         Stellt die Trennbreite für die Silbentrennung ein. 
+load macros ("x")               Lädt Makros. 
+list macros                     Zeigt geladene Makros. 
+lade ausnahmen ("x")            Lädt Wörter, die von der Trennhilfe nicht korrekt 
+                                getrennt werden, in einen Ausnahme-Speicher. 
+entlade ausnahmen ("x")         Entlädt die Worte aus dem Ausnahme-Speicher 
+                                in die angegebene Datei. 
+first head (false)              Schaltet Kopfzeilen auf erster Seite aus. 
+first head (true)               Schaltet Kopfzeilen auf erster Seite wieder ein. 
+last bottom (false)             Schaltet Fußzeilen auf letzter Seite aus. 
+last bottom (true)              Schaltet Fußzeilen auf letzter Seite wieder ein. 
+number empty lines before foot  Stellt die Anzahl der Leerzeilen vor einer Fußnote 
+before foot                     ein. 
+#tableend##clearpos# 
+#page# 
+#on("b")# 
+#ib#Anweisungen#ie##off("b")# 
+#free(1.0)# 
+   #on ("i")# 
+   Anweisungen werden in die Datei geschrieben. Jede Anweisung muß in Anwei­
+   sungszeichen eingeschlossen werden. Als Parameter (diese werden in Klammern
+   eingeschlossen) kommen in Frage: 
+   'int'   bedeutet eine ganze Zahl: 17, 1, 311; 
+   'real'  bedeutet eine Zahl mit Dezimalpunkt (meist cm-Angabe): 0.5, 1.25; 
+   'text'  bedeutet eine Zeichen-Angabe. Muß in Anführungszeichen eingeschlos­
+           sen werden: "%", "meine datei". 
+           #off ("i")# 
+#free(1.0)# 
+#lpos(0.0)##lpos(4.6)# 
+#table# 
+#on("b")#Anweisung           Bedeutung#off("b")# 
+#clearpos# 
+#lpos(0.0)##lpos (4.6)# 
+ 
+type (text)                  Schrifttyp einstellen: \#type("trium8")\# 
+limit (real)                 Zeilenbreite einstellen: \#limit (16.0)\# 
+on (text)                    Modifikation einschalten: \#on("bold")\#. Erlaubt 
+                             sind: b(bold), r(everse), i(talic), u(nderline) 
+off (text)                   Modifikation ausschalten (siehe 'on'). 
+block                        Blocksatz (Randausgleich) einschalten. 
+head                         Kopfzeilen (für Seiten mit geraden/ungeraden 
+(bzw. headeven/headodd)      Seitennummern) definieren. 
+... -%-                      Platzhalter für Seitenzahl. 
+end                          Kopfzeilen-Ende (pageform).  
+bottom                       Wie oben, jedoch für Fußzeilen. 
+(bzw.                          
+bottomeven/bottomodd)          
+...                            
+end                          Fußzeilen-Ende 
+pagenr (text, int)           Seitennummer einstellen bzw. zusätzliches Sei­ 
+                             enzeichen ab nächster Seite einführen: 
+                             \#pagenr ("%", 17)\# 
+foot                         Fußnoten-Anfang. 
+...                            
+end                          Fußnoten-Ende. 
+free (real)                  Platz freihalten (in cm): \#free (1.27)\# 
+page                         Neue Seite: \#page\# 
+page (int)                   Neue Seite mit Seitennummer 17: \#page (17)\# 
+linefeed (real)              Zeilenhöhe relativ zum eingeschalteten Schrifttyp 
+                             verändern: \#linefeed (1.25)\# 
+pagelength (real)            Seitenlänge einstellen (ab nächster Seite in cm):
+                             \#pagelength (24.0)\# Nachfolgenden Zeilentext 
+center                       zentriert drucken. 
+right                        Nachfolgenden Zeilentext rechtsbündig drucken. 
+u ... e                      (steht für up) Exponent schreiben: \#u\#123\#e\# 
+d ... e                      (steht für down) Index schreiben. 
+start (real, real)           Schriftfeld (linke obere Ecke) einstellen: \#start 
+                             (1.0, 2.0)\# 
+------------                 ------------ 
+b                            Zwei Zeichen übereinander drucken. 
+bottom off                   Schaltet Fußzeilen aus. 
+bottom on                    Schaltet Fußzeilen ein. 
+bpos (real, real)            Der Text zwischen den angegebenen Tabellen­ 
+                             positionen wird im Blocksatz gedruckt. 
+clearpos                     Löscht alle Tabellenpositionen. 
+clearpos (real)              Löscht die angegebene Tabellenposition. 
+columns (int, real)          Formatieren von Spalten mit Zwischenraum: 
+                             \#columns (3, 1.0)\#, 3 Spalten mit 1 cm Zwischen­ 
+                             raum. 
+columnsend                   Beendigung der Spaltenformatierung. 
+count                        Interner Zähler für Fußnoten wird eingesetzt
+                             (pageform). 
+count (text)                 Wie oben, aber der Wert des internen Zählers 
+                             wird vermerkt: \#count ("neue Zahl")\# 
+count per page               Interner Zähler beginnt bei jeder Seite mit 1. 
+cpos (real)                  Zentrierende Tabellenposition. 
+dpos (real, text)            Um den angegebenen Text zentrierende Tabel­ 
+                             lenposition, meist Dezimalzeichen: 
+                             \#dpos (13.0, 2.")\# 
+fillchar (text)              Zwischenräume zwischen Tabellenpositionen wer­
+                             den mit dem angegebenen Text beim Drucken
+                             ausgefüllt. Beachten Sie, daß das Ausschalten der
+                             Füllzeichen durch 'niltext' erfolgt. 
+goalpage (text)              Stelle, auf die obige Anweisung verweist: \#goal­ 
+                             page ("1.Kapitel")\# 
+head off                     Schaltet Kopfzeile(n) aus. 
+head on                      Schaltet Kopfzeile(n) ein. 
+ib                           Anfang eines Stichworts oder einer Kapitel­
+                             überschrift kennzeichnen (Ablegen in Indexdatei 
+                             mit Zusatz '.i1'): \#ib\#ein Stichwort oder eine 
+                             Kapitelüberschrift\#ie\# 
+ib (int)                     Wie oben, jedoch wird Stichwort in angegebener 
+                             Indexdatei abgelegt. 
+ib (int, text)               Wie oben, jedoch erhält Eintrag in der Indexdatei 
+                             den angegebenen Text an die Seiten­ 
+                             nummer angefügt. 
+ie                           Beendigung der Stichwortmarkierung. 
+ie (int)                     Wie oben (int-Angabe muß der in der ib-An­ 
+                             weisung entsprechen). 
+ie (int, text)               Wie oben, jedoch wird die Textangabe hinter das 
+                             markierte Stichwort angefügt. 
+lpos (real)                  Linksbündige Tabellenposition. 
+mark (text, text)            Markierung rechts und links neben der Schreib­ 
+                             fläche ein-/ausschalten. 
+pageblock                    Einschalten des vertikalen Blocksatzes. Falls ein­
+                             geschaltet, kann mit 'pageform' auch über das
+                             (rechnerische) Seitenende formatiert werden. 
+rpos (real)                  Rechtsbündige Tabellenposition.
+setcount (int)               Zählerwert setzen: \#setcount (17)\# 
+table                        Anfang einer Tabelle. 
+...                            
+table end                    Ende einer Tabelle. 
+topage (text)                Seitenverweis (die Seitennummer, auf die verwie­ 
+                             sen wird, wird eingesetzt): 
+                             \#topage ("1.Kapitel")\# 
+value                        Letzter Zählerwert wird eingesetzt. 
+value (text)                 Wie oben, jedoch wird ein vermerkter Zählerwert
+                             eingesetzt: \#value ("Vermerk")\# 
+#tableend# 
+
diff --git a/doc/user/benutzerhandbuch.5e b/doc/user/benutzerhandbuch.5e
new file mode 100644
index 0000000..d515c6a
--- /dev/null
+++ b/doc/user/benutzerhandbuch.5e
@@ -0,0 +1,223 @@
+#start(5.0,1.5)##pagelength(17.4)##pagenr("%",121)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Teil 5: Textkosmetik und Druck     
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+5 - %      GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        5 - % 
+#tableend##clearpos# 
+#end# 
+ 
+#ib(9)#5.10. Fehlersituationen und Abhilfe#ie(9)# 
+ 
+#free(1.0)# 
+Was können Sie machen, wenn 
+ 
+ 
+...  bestimmte Anweisungen, die den Gesamttext betreffen, erst ab der zweiten
+     Seite wirksam werden? 
+ 
+ 
+     Textkosmetik-Anweisungen, die ab der ersten Seite für den ganzen Text gelten
+     sollen, müssen Sie als erstes, d.h. in die erste Zeile einer Datei, schreiben. Dies
+     bezieht sich u.a. auf 'pagelength', 'start', 'block', 'pageblock' etc., die noch vor
+     \#head\#- oder \#bottom\#-Anweisungen gesetzt werden müssen. 
+ 
+ 
+ 
+ 
+...  sich der Cursor nicht mehr bewegen läßt? 
+ 
+ 
+     Eine Möglichkeit besteht darin, daß Sie versehentlich die 'STOP' -Taste
+     (='CTRL a' gleichzeitig, d.h. Anhalten der Bildschirmausgabe) betätigt haben.
+     In diesem Fall drücken Sie die 'WEITER' -Taste ('CTRL c'  gleichzeitig, d.h.
+     Bildschirmausgabe fortführen). Alle Tastenanschläge, die Sie in der Zwischen­
+     zeit vollzogen haben, werden jetzt ausgeführt. 
+ 
+     Eine andere Möglichkeit wäre, daß Sie Ihre Datei/Task nicht ordnungsgemäß
+     verlassen haben. Versuchen Sie über die 'SV'-Taste und 'ESC h' wieder auf
+     die Monitor-Ebene zu gelangen, so daß Sie dann auf die Aufforderung 'gib
+     kommando' hin, wieder in Ihre Datei gelangen können. 
+ 
+ 
+ 
+ 
+...  Sie nur einen Dateiausschnitt löschen, duplizieren oder mit 'lineform' bearbeiten
+     möchten? 
+ 
+ 
+     Der betreffende Ausschnitt muß markiert werden. Zum Löschen benutzen Sie
+     die Tasten 'ESC RUBOUT'. Der Ausschnitt ist hiermit aber noch nicht 'voll­
+     ständig verschwunden', sondern Sie können ihn mit 'ESC RUBIN' an gleicher
+     oder anderer Stelle wieder hervorbringen, so lange bis Sie die Tasten erneut
+     benutzen. 
+ 
+     Das Duplizieren eines Textbereiches erfolgt nach dem Markieren durch das
+     Betätigen der Tastenfolge 'ESC d'. Hierbei bleibt der Originaltext erhalten und
+     kann beliebig oft dupliziert werden. Den duplizierten Text holen Sie sich mit
+     'ESC g' an die gewünschte Stelle in Ihrer Datei. 
+ 
+     Möchten Sie 'lineform' nur auf einen Ausschnitt anwenden, markieren Sie
+     diesen und geben nach 'ESC ESC' das Kommando 'lineform'. 
+ 
+ 
+ 
+ 
+...  beim Drucken die letzte bzw. die letzten beiden Zeilen auf einer gesonderten
+     Seite ausgedruckt werden? 
+ 
+ 
+     a) Sie müssen die Fonttabelle noch einrichten. 
+ 
+        oder 
+ 
+     b) Sie setzen die \#pageblock\#-Anweisung zu Beginn des Textes und "stau­
+        chen" um zwei Zeilen. 
+ 
+        oder 
+ 
+     c) Sie wählen eine kleineren Schrifttyp. 
+ 
+ 
+ 
+ 
+...  in Ihrer Datei die Meldung 
+ 
+     _______________________________________________________________________ 
+ 
+     FEHLER: FILE-Überlauf 
+ 
+     gib kommando: 
+     edit ("dateiname") 
+ 
+     _______________________________________________________________________ 
+      
+     erscheint und das Abschicken des Kommandos mittels der 'CR'-Taste aber nur
+     zu einer identischen Meldung (siehe oben) führt? 
+ 
+ 
+     Wenn Sie auf dem oben dargestellten Weg nach mehrmaligem Versuchen nicht
+     wieder in Ihre Datei gelangen, haben Sie die Möglichkeit, mit dem Kommando 
+ 
+     _______________________________________________________________________ 
+ 
+     gib kommando: 
+     reorganize ("dateiname") 
+ 
+     _______________________________________________________________________ 
+      
+ 
+     Ihre Datei neu zu 'organisieren', um 'Lücken', die durch Einfügen oder Löschen
+     entstanden sind, zu eliminieren. Die Datei beansprucht dann in der Regel auch
+     weniger Speicherplatz. 
+ 
+     Sind Sie wieder in Ihrer Datei, empfiehlt es sich, die große Datei in mehrere
+     kleine aufzuteilen. Entweder Sie halbieren oder (besser) Sie dritteln Ihre Text­
+     datei und verteilen den Text auf zwei bis drei Dateien. Zukünftig sollten Sie es
+     sich dann bei umfangreichen Texten zur Regel machen, nur ein logisch
+     zusammenhängendes Kapitel in einer Datei abzulegen. Sie sollten Ihre Datei nur
+     so groß halten, daß Ihnen noch genügend Raum zur Verfügung steht, Proze­
+     duren wie z.B. 'pageform' durchzuführen, durch die sich der Umfang einer Datei
+     (z.T. wesentlich) vergrößert. 
+ 
+ 
+ 
+ 
+...  bei Ihrem Text einige Wörter mit extrem großem Zwischenraum gedruckt
+     wurden? 
+ 
+ 
+     Sie haben in diesem Fall wahrscheinlich vergessen, die Absatzmarkierung zu
+     setzen, so daß aufgrund der \#block\#-Anweisung ein rechter Randausgleich
+     erfolgte, den Sie an dieser Stelle nicht wünschten. 
+ 
+ 
+ 
+ 
+...  eine Überschreibung erfolgt ist bzw. wenn 'lineform' eine Überschreibung
+     meldet? 
+ 
+ 
+     Eine solche Überschreibung kann auftreten, wenn Sie mit einer besonders
+     großen Type in Fettdruck (z.B. triumb14) schreiben (vgl. Sie hierzu auch Kapitel
+     5.2.6.). Um dies zu verhindern, können Sie zum einen die Anzahl der Blanks
+     zwischen den einzelnen Gliedern erhöhen oder zum anderen auch die
+     \#type\#-Anweisung in die vorhergehende Zeile setzen (n i c h t direkt v o r den
+     betreffenden Text). 
+ 
+ 
+ 
+ 
+...  nach der erfolgten Prozedur 'lineform' Ihre Tabellen durcheinander geraten
+     sind? 
+ 
+ 
+     Wenn Sie Tabellen schreiben, müssen Sie nach jeder Zeile die Absatzmarke
+     setzen. Sollen bei einigen Tabellenpositionen Spalten leer bleiben, müssen Sie
+     für diese Positionen ein geschütztes Blank einsetzen. 
+ 
+ 
+ 
+ 
+...  bei der Prozedur 'pageform' das Seitenende nicht interaktiv verschoben werden
+     kann, obwohl am Anfang der Datei eine \#pageblock\#-Anweisung gegeben
+     wurde? 
+ 
+ 
+     Eine \#page\#-Anweisung im Text bewirkt, daß Sie an dieser Stelle das Seiten­
+     ende nur bestätigen, die Anweisung löschen oder als dritte Möglichkeit, die
+     Seitenformatierung abbrechen können. Für den Fall, daß die \#page\#-
+     Anweisung nicht mehr zutrifft bzw. falsch gesetzt wurde, sollten Sie die Anwei­
+     sung löschen und das Seitenende interaktiv plazieren. 
+ 
+ 
+ 
+ 
+...  Sie bei der Erstellung eines Inhaltsverzeichnisses oder eines Indexes keine
+     Füllzeichen zwischen Text und Seitenangabe haben möchten? 
+ 
+ 
+     In diesem Fall gehen Sie mit 'ESC ESC' in den Kommandozustand und ändern
+     mit Hilfe von CA (Change All) die Füllzeichen in Leerzeichen um. Verwenden
+     Sie nicht nur einen Punkt, da sonst auch die Punkte zwischen den Ziffern der
+     Kapitelnumerierung verschwänden. Es kann bei einer ungeraden Anzahl von
+     Füllzeichen notwendig sein, nachträglich noch einige Punkte entfernen zu
+     müssen. 
+ 
+     _______________________________________________________________________ 
+ 
+        gib kommando: ".." CA " " 
+ 
+     _______________________________________________________________________ 
+
diff --git a/doc/user/benutzerhandbuch.6 b/doc/user/benutzerhandbuch.6
new file mode 100644
index 0000000..5e035d2
--- /dev/null
+++ b/doc/user/benutzerhandbuch.6
@@ -0,0 +1,474 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Teil 6: Spezialitäten    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+6 - %      GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        6 - % 
+#tableend##clearpos# 
+#end# 
+ 
+#kap("TEIL 6: Spezialitäten")# 
+#free(1.0)# 
+ 
+6.1. Notizbuch 
+#free(1.0)# 
+   Das Notizbuch erlaubt es u.a., Fehlermeldungen zwischenzeitig zu speichern und
+   am Ende einer Verarbeitung die Fehlermeldungen zusammen mit dem bearbeiteten
+   Text im Fenstereditor anzuzeigen. 
+#free(1.0)# 
+Das #ib#Notizbuch#ie# wird von den Programmen 'lineform' und 'pageform' zum Sammeln
+von Warnungen und Fehlermeldungen verwendet. Wenn das Fenster des Notizbuches
+an Bildschirm eröffnet ist, können Sie es handhaben wie das gewohnte Editorfenster. 
+ 
+Falls Sie das Notizbuch selbst beim Editieren für Notizen verwenden möchten, drük­
+ken Sie statt <ESC> <e> für den Fenstereditor die Tasten <ESC> <n> an beliebiger
+Stelle des Bildschirms. Durch dieses Kommando wird das Notizbuch statt einer Datei
+gezeigt. Sie sparen somit die Eingabe eines Dateinamens und können direkt mit allen
+vorgestellten Editorfunktionen im Notizbuch arbeiten. 
+ 
+ 
+#page# 
+____________________________________________________________________________ 
+ ................ handbuch teil6 .............. Zeile 56     
+\#kap("6.2. EUMEL-Zeichensatz")\# 
+\#free(1.0)\# 
+\#zus\# 
+   \#corner1("-5.0")\# 
+   Das EUMEL-System definiert einen Zeichensatz, der gewähr­ 
+   auf allen Maschinen überall gleich codiert werden. Dadurch ist 
+   Dateien und Programme ohne Konvertierungen zwischen EUMEL-Syst 
+   unterschiedlicher Hersteller zu übertragen. Der \#ib\#EUMEL- 
+   dem ASCII-Zeichensatz (DIN 66 003) mit Erweiterungen. 
+   \#box3("T","2","115.0")\# 
+ 
+ ................. notebook ................... Zeile 1     
+FEHLER Zeile 55: Modifikation nicht angeschaltet bei off: b 
+   >>> Anweisung in angegebener Zeilennummer überprüfen 
+WARNUNG Zeile 55: Umschaltung auf gleichen Schrifttyp: trium8 
+   >>> Schrifttyp wurde darum nicht verändert! 
+WARNUNG Zeile 75: Überschreibung nach >\#ib(9)\#6.2.< Fehlende 
+   >>> Bitte fehlende Leerzeichen einfügen 
+ 
+____________________________________________________________________________ 
+#page# 
+6.2. EUMEL-Zeichensatz 
+#free(1.0)# 
+ 
+    
+   Das EUMEL-System definiert einen Zeichensatz, der gewährleistet, daß Zeichen
+   auf allen Geräten gleich codiert werden. Dadurch ist es z.B. möglich, Dateien und
+   Programme ohne Konvertierungen zwischen EUMEL-Systemen unterschiedlicher
+   Hersteller zu übertragen. Der #ib#EUMEL-Zeichensatz#ie# beruht auf dem ASCII-
+   Zeichensatz (DIN 66 003) mit Erweiterungen. 
+    
+#free(1.0)# 
+ 
+Die Darstellung der einzelnen Zeichen hängt vom Endgerät ab. Die hier aufgeführten
+Zeichen sind i.A. auf allen Geräten vorhanden. Ein erweiterter Zeichensatz (mit ma­
+thematischen, diakritischen und griechischen Zeichen) ist nur auf Spezialgeräten
+verfügbar und wird deshalb hier nicht angegeben. 
+#page# 
+Beispiele zum Lesen der Tabelle: 
+ 
+              code (" ") ->  32 
+              code ("m") -> 109 
+  | 0   1   2   3   4   5   6   7   8   9 
+--+---------------------------------------- 
+3 |        SP   !   "   \#   $   %   &   ' 
+  | 
+4 | (   )   *   +   ,   -   .   /   0   1 
+  | 
+5 | 2   3   4   5   6   7   8   9   :   ; 
+  | 
+6 | <   =   >   ?   §   A   B   C   D   E 
+  | 
+7 | F   G   H   I   J   K   L   M   N   O 
+  | 
+8 | P   Q   R   S   T   U   V   W   X   Y 
+  | 
+9 | Z   [ ��\�  ]   ^   _   `   a   b   c 
+  | 
+10| d   e   f   g   h   i   j   k   l   m 
+  | 
+11| n   o   p   q   r   s   t   u   v   w 
+  | 
+12| x   y   z   |   }   ~ 
+  | 
+13| 
+  . 
+  .         
+  . 
+20| 
+  | 
+21|                 Ä   Ö   Ü   ä   ö   ü 
+  | 
+22| k   ­   \#       SP 
+  | 
+23| 
+  | 
+24| 
+  | 
+25|     ß 
+#page# 
+ 
+ 
+Anmerkungen: 
+ 
+1) SP bedeutet Leerzeichen ("blank"). 
+   
+2) Die Zeichen 'k', '-' und 'SP' mit den Codes 220, 221, 223 werden für die Zwecke
+   der Textkosmetik benötigt (Trenn-'k' bei der Umwandlung von 'ck' in 'kk'; Trenn­
+   zeichen; geschütztes Leerzeichen). 
+ 
+3) Das Zeichen '\#' (Code 222) ist druckbar, während das Zeichen '\#' (Code 35) nicht 
+   druckbar ist (Einleitungszeichen für Anweisungen der Textkosmetik und Drucker). 
+ 
+4) Das Zeichen SP (Code 223) wird zur besseren Identifizierung invers oder als
+   Unterstreichungsstrich auf dem Terminal dargestellt. In einem Ausdruck erscheint
+   es als ein Leerzeichen. 
+ 
+Falls Sie Zeichen ausgeben möchten, die nicht auf der Tastatur sind, müssen Sie den
+Code der gewünschten Zeichen zu Hilfe nehmen. 
+ 
+Bewegen Sie den Cursor dazu an die Stelle der Datei, an die das Sonderzeichen
+geschrieben werden soll und geben Sie nach <ESC> <ESC> ein: 
+ 
+ 
+____________________________________________________________________________ 
+ ................. dateiname .................. Zeile 123     
+ 
+               TABELLE 1 
+          _____________________ 
+          |                   | 
+ gib kommando : type(code(124))                                   
+ 
+ 
+ 
+____________________________________________________________________________ 
+#page# 
+6.3. Sortier-Programme 
+#free(1.0)# 
+ 
+    
+   Es stehen zwei verschiedene Sortier-Programme zur Verfügung: 'sort' (Sortierung
+   nach ASCII-Reihenfolge) und 'lex sort' (Sortierung nach deutschem Alphabet). 
+    
+#free(1.0)# 
+ 
+Die Sortierprogramme sortieren eine Datei zeilenweise. 
+ 
+Beispiel: 
+ 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ................. Zeile 1     
+ Berta ist eine Frau. 
+ Adam ist ein Mann. 
+      ... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+____________________________________________________________________________ 
+gib kommando : 
+#ib#sort#ie# ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ................. Zeile 1     
+ Adam ist ein Mann. 
+ Berta ist eine Frau. 
+      ... 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+Dabei werden die Zeilen-Anfänge solange zeichenweise miteinander verglichen, bis
+ein Unterschied auftritt und dann ggf. umgeordnet. Werden zwei ungleich lange Zeilen
+(Anzahl Zeichen/Zeile) miteinander verglichen, dann kann man sich die kürzere Zeile
+mit Leerzeichen auf die Länge der längeren Zeile verlängert denken. 
+ 
+Die Reihenfolge, in der die Zeilen sortiert werden, erfolgt nach dem ASCII-
+Zeichensatz in aufsteigender Reihenfolge (vergl EUMEL-Zeichencode): 
+ 
+ 
+    das Leerzeichen 
+    einige Sonderzeichen 
+    die Ziffern 
+    einige Sonderzeichen 
+    große Buchstaben 
+    einige Sonderzeichen 
+    kleine Buchstaben 
+    einige Sonderzeichen 
+    die Umlaute und ß 
+ 
+ 
+Das bedeutet, daß z.B. folgendermaßen sortiert wird: 
+ 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ................. Zeile 1     
+   Adam 
+   Ball 
+   Zuruf 
+   aber das ist ein Satz 
+   niemals 
+   Überlauf 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+ 
+Um zu erreichen, daß große und kleine Buchstaben gleichwertig behandelt werden,
+kann man das Kommando 
+ 
+____________________________________________________________________________ 
+gib kommando : 
+#ib#lex sort#ie# ("dateiname") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+geben. 
+ 
+In diesem Fall würde die sortierte Datei folgendermaßen aussehen: 
+ 
+____________________________________________________________________________ 
+ ................. dateiname ................. Zeile 1     
+   aber das ist ein Satz 
+   Adam 
+   Ball 
+   niemals 
+   Überlauf 
+   Zuruf 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Man beachte, daß der Umlaut 'Ü' wie 'Ue' behandelt wird (für die restlichen Umlaute
+gilt eine analoge Behandlung; ebenso wird 'ß' wie 'ss' behandelt). Weiterhin werden
+alle Sonderzeichen bei der Sortierreihenfolge ignoriert. 
+ 
+6.4 Fonttabellen 
+#free(1.0)# 
+ 
+   
+  Eine Fonttabelle enthält Angaben zu den druckbaren Zeichen. 
+                                   
+#free(1.0)# 
+ 
+Die Einstellung einer Fonttabelle#u#1)#e# erfolgt automatisch beim Einrichten der Drucker-
+Task (siehe Anhang). Um den Namen der in der Task eingestellten Fonttabelle zu
+erhalten geben Sie ein: 
+#foot# 
+1) Fonttabelle: Beschreibung der druckbaren Schrifttypen. 
+#end# 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+put(fonttable) 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Die Ausgabe liefert den Namen der in der Task eingestellten Fonttabelle. 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+put(fonttable) 
+agfa9 
+gib kommando: 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Um eine neue oder andere Fonttabelle einzustellen, etwa weil verschiedene Drucker
+benutzt werden können, geben Sie das 'fonttable' Kommando mit dem Namen der
+gewünschten Fonttabelle als Parameter an: 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+fonttable("name der fonttabelle") 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Eine weitergehende Beschreibung der eingestellten Fonttabelle erhalten Sie durch das
+Kommando 'list fonts': 
+ 
+____________________________________________________________________________ 
+ 
+gib kommando: 
+list fonts 
+ 
+____________________________________________________________________________ 
+ 
+ 
+Durch dieses Kommando erhalten Sie in das Notizbuch eine Aufstellung der Schrift­
+typen mit Angaben zu Namen der verfügbaren Schrifttypen in der Fonttabelle,
+Größenangaben zu den Schriftttypen etc. 
+ 
+____________________________________________________________________________ 
+ ................. notebook .................. Zeile 1     
+FONTTABELLE  :  "agfa9"; 
+  x einheit  =  160.0; 
+  y einheit  =  160.0; 
+ 
+  FONT  :  "micro",  "elanlist",  "bulletin22"; 
+    einrueckbreite   =  20; 
+    durchschuss      =  7; 
+    fonthoehe        =  30; 
+    fonttiefe        =  8; 
+    groesserer font  =  ""; 
+    kleinerer font   =  ""; 
+ 
+  FONT  :  "trium10"; 
+    einrueckbreite   =  31; 
+    durchschuss      =  6; 
+    fonthoehe        =  54; 
+    fonttiefe        =  15; 
+    groesserer font  =  "trium12"; 
+    kleinerer font   =  "trium8"; 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Anmerkung: 
+           - Falls mehrere Namen für einen Schrifttyp angegeben sind, können Sie
+             einen beliebigen dieser Namen in der \#type\#-Anweisung benutzen. 
+ 
+           - Größenangaben sind in 'Mikroschritten', d.h. den kleinstmöglichen
+             Schritten des jeweiligen Druckers angegeben und nicht etwa in mm. 
+ 
+           - Weitere Informationen entnehmen Sie ggf. dem Systemhandbuch. 
+ 
+#page# 
+6.5 Syntax der Kommandos 
+#free(1.0)# 
+code 
+   TEXT PROC code (INT CONST zahl) 
+   Wandelt 'zahl' in ein Zeichen um. Falls die Zahl kleiner als 32 oder größer als 254
+   ist, (siehe Codetabelle) muß mit unerwarteten Ergebnissen gerechnet werden. 
+ 
+ 
+   type(code(92)) 
+ 
+ 
+   INT PROC code (TEXT CONST zeichen) 
+   Wandelt 'zeichen' in die zugehörige EUMEL-Codierung um. Falls mehr als ein
+   Zeichen angegeben wird, ist das Resultat '-1'. 
+ 
+ 
+   put(code(92)) 
+ 
+ 
+ 
+list fonts 
+   PROC list fonts 
+   Listet die Fonts der eingestellten Tabelle ins #on("i")#notebook#off("i")#. 
+ 
+   PROC list fonts (TEXT CONST fonttable name) 
+   Listet die Fonts der angegebenen Fonttabelle ins #on("i")#notebook#off("i")#. Die vorher eingestellte
+   Fonttabelle bleibt jedoch weiter eingestellt. 
+ 
+ 
+   list fonts ("fonttab.alternativ") 
+ 
+ 
+ 
+lex sort 
+   PROC lex sort (TEXT CONST datei) 
+ 
+   Zeilenweise Sortierung nach (deutscher) lexikographischer Reihenfolge nach DIN
+   5007. 
+ 
+ 
+   lex sort ("telephonliste") 
+ 
+ 
+   PROC lex sort (TEXT CONST datei, INT CONST anfang) 
+ 
+   Wie 'lex sort', jedoch wird bei der Sortierung bei 'anfang' jeder Zeile begonnen. 
+ 
+ 
+   lex sort ("liste",20) 
+ 
+ 
+sort 
+   PROC sort (TEXT CONST datei) 
+ 
+   Die Prozedur 'sort' sortiert die Datei 'datei' zeilenweise. Die Sortierung erfolgt
+   nach der Ordnung, die der EUMEL-Zeichencode vorschreibt. Beispielsweise
+   werden Zeilen ("Sätze"), die mit Ziffern beginnen, vor Sätzen, die mit Buchstaben
+   anfangen, eingeordnet. Sätze, die mit großen Buchstaben beginnen, werden vor
+   Sätzen mit kleinen Buchstaben einsortiert. Weiterhin werden die Umlaute und das
+   "ß" nach allen anderen Buchstaben eingeordnet. 
+ 
+ 
+   sort ("liste") 
+ 
+ 
+   PROC sort (TEXT CONST datei, INT CONST anfang) 
+ 
+   Sortiert eine Datei wie obige Prozedur, jedoch wird bei der Sortierung nicht der
+   Anfang eines Satzes beachtet, sondern die Position 'anfang'. 
+ 
+ 
+   sort ("liste",10) 
+ 
+ 
+ 
+type 
+   PROC type (TEXT CONST zeichenkette) 
+ 
+   Fügt 'zeichenkette' in die aktuelle Position der editierten Datei ein. Besonders
+   nützlich in Verbindung mit der Prozedur 'code', um nicht auf der Tastatur enthal­
+   tene Zeichen in den Text zu bringen. 
+ 
+ 
+   type(code(200)) 
+
diff --git a/doc/user/benutzerhandbuch.anhang b/doc/user/benutzerhandbuch.anhang
new file mode 100644
index 0000000..5a58f95
--- /dev/null
+++ b/doc/user/benutzerhandbuch.anhang
@@ -0,0 +1,484 @@
+#start(5.0,1.5)##pagenr("%",1)##setcount(1)##block##pageblock##count per page# 
+#headeven# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+                     EUMEL-Benutzerhandbuch    
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#headodd# 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)##fillchar(" ")# 
+#table# 
+     Anhang                 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#table end##clear pos# 
+ 
+#end# 
+#bottomeven# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+A - %      GMD 
+#tableend##clearpos# 
+#end# 
+#bottomodd# 
+ 
+#lpos(0.0)##cpos(5.5)##rpos(11.0)# 
+#table# 
+#fillchar(" ")# 
+#on("u")#       #off("u")# 
+#fillchar(" ")# 
+GMD        A - % 
+#tableend##clearpos# 
+#end# 
+Aufbau und Installation 
+#free(0.5)# 
+  Diese Installationsanleitung dient nur als Beispiel und soll nicht die Anleitung zu
+  dem von Ihnen benutzten Gerät ersetzen. Insbesondere die hier beschriebene
+  Möglichkeit der Partitionierung ist kein Standard! 
+#free(0.5)# 
+Allgemeines über das Betriebssystem EUMEL 
+#free(0.5)# 
+ 
+Zum besseren Verständnis des Installierungsvorganges sei hier kurz der Aufbau des
+Betriebssystems EUMEL erläutert (Der EUMEL-Kenner mag diesen Abschnitt über­
+springen) : 
+ 
+Das System besteht im wesentlichen aus den folgenden Komponenten : 
+ 
+      -  SHard (#on("i")##on("b")#S#off("b")##off("i")#oftware - #on("i")##on("b")#Hard#off("b")##off("i")#ware Interface) 
+      -  Systemkern (EUMEL-0) 
+      -  darauf aufbauende Systemteile 
+ 
+Das #on("b")##ib#SHard#ie##off("b")# ist der #on("u")#hardwareabhängige#off("u")# Teil des Betriebssystems. Dieser Teil ist ver­
+antwortlich für den Informationsfluß zwischen der virtuellen Maschine EUMEL-0 und
+den einzelnen Hardwarekomponenten (Tastatur, Diskettenlaufwerk, Schnittstellen,
+usw.). 
+ 
+Der #on("b")#Systemkern#off("b")# (auch mit EUMEL-0 oder Urlader bezeichnet) ist der #on("u")#prozessorab­
+hängige#off("u")# Teil des Systems. Er bestimmt im wesentlichen die Leistung des Betriebssy­
+stems, da er als virtueller Prozessor den Befehlsumfang für den ELAN-Compiler
+definiert. Dieser Befehlsumfang wird dann auf den tatsächlichen Befehlsvorrat des
+hardwaremäßig vorhandenen Prozessors abgebildet. 
+ 
+Die auf dem Kern (EUMEL-0) #on("b")#aufbauenden Systemteile#off("b")# sind #on("u")#hardware- und prozes­
+sorunabhängig#off("u")#. Sie beinhalten den ELAN-Compiler und alle Tasks, Texte, insertier­
+ten ELAN-Pakete, benannte und unbenannte Datenräume eines EUMEL-Systems.
+Diese Systemteile bilden zusammen mit dem Systemkern EUMEL-0 den #goalpage("v2")##on("b")#EUMEL-
+Hintergrund#off("b")#, d.h. EUMEL-0 ist Teil des #ib#EUMEL-Hintergrundes#ie#. Momentan werden
+je nach Rechnertyp Diskette und Festplatte als Hintergrundspeichermedium für
+EUMEL unterstützt. 
+ 
+Der Begriff EUMEL-Hintergrund (HG) resultiert aus dem Konzept des virtuellen
+Speichers. Bei diesem Konzept wird der RAM-Speicherbereich der Hardware nur als
+Pufferbereich nach dem Demand-Paging-Verfahren benutzt, mit Ausnahme der
+residenten Systemteile (SHard und EUMEL-0). Das macht den Benutzer bezüglich
+seiner Programme und Daten unabhängig von der eigentlichen Größe des RAM-
+Speichers. Diese bestimmt lediglich den Durchsatz (Performance) des Systems, d.h. je
+größer der RAM-Bereich Ihres Rechners ist, desto schneller arbeitet das EUMEL-
+System. 
+ 
+EUMEL-0 befindet sich auf der ersten Hintergrunddiskette. Das Laden von
+EUMEL-0 und des restlichen EUMEL-Hintergrundes kann daher in einem Arbeits­
+gang geschehen. 
+ 
+Der Auslieferungs-Hintergrund ist noch nicht konfiguriert und stellt ausschließlich die
+im Handbuch beschriebenen Leistungen des Betriebssystems zur Verfügung. Er
+besteht im wesentlichen aus insertierten ELAN-Paketen, die den Leistungsumfang
+des Systems bestimmen (Single- oder Multiuser, mit oder ohne Textverarbeitung).
+Steht dieser Hintergrund auf mehreren Disketten (Multiuser-Hintergründe), dann sind
+diese fortlaufend numeriert. Die erste Hintergrunddiskette hat die Nummer 0, um
+daran zu erinnern, daß sich auf dieser Diskette auch der Systemkern EUMEL-0
+befindet. 
+ 
+Ein Hintergrund kann natürlich auch die Systemsicherung eines größeren Systems mit
+z.B. mehreren Megabytes sein. Sollten Sie später einmal Ihr bestehendes System
+durch ein anderes ersetzen wollen (Hintergrund überschreiben), so brechen Sie wäh­
+rend des Hochfahrens beim Speichertest das System durch Tastendruck ab und laden
+durch Anwahl von  2  'neuen Hintergrund vom Archiv laden' im Startdialog das neue
+System. 
+ 
+#on("i")##on("u")#ACHTUNG:#off("u")##off("i")#    Dabei gehen alle Daten des alten Systems unwiederbringlich verloren!
+            (Siehe dazu auch 'Laden eines EUMEL-Hintergrundes'.) 
+ 
+Zur besseren Verständlichkeit sollen an dieser Stelle noch die Begriffe 'Systemstart' 
+und 'Systemabschaltung' des EUMEL-Systems erläutert werden : 
+ 
+#on("i")##on("b")##ib#Systemstart#ie# :#off("b")##off("i")# 
+Wenn ein EUMEL-System gestartet wird (auch 'Hochfahren' genannt), und dies gilt
+auch für kleinere Diskettensysteme wie den 'Generierungseumel' (siehe Seite #topage("v1")#),
+wird zunächst das SHard geladen; dazu erscheint auf dem Bildschirm eine entspre­
+chende Meldung. Das SHard versucht nun den Systemkern vom Archivmedium (in der
+Regel Diskette) zu laden. Ist keine entsprechende Diskette eingelegt, so wird ver­
+sucht, EUMEL-0 vom Hintergrundmedium (Festplatte) zu laden. 
+ 
+Danach wird EUMEL-0 aktiv; auf dem Bildschirm erscheinen Angaben zu verfügba­
+ren Kanälen, RAM- und Hintergrundspeicher-Größe. Dann führt EUMEL-0 einen
+Speichertest durch, was daran zu erkennen ist, daß eine Folge von Sternchen (*) auf
+den Schirm geschrieben wird. Wird währenddessen eine beliebige Taste gedrückt,
+dann gelangt man nach dem Speichertest in den 'Startdialog'. 
+ 
+Nach dem Speichertest bzw. nach Wahl von <1> 'Systemstart' im Startdialog wird der
+Hintergrund aktiviert, was je nach Größe des Systems und Art des Hintergrundmedi­
+ums unterschiedlich lange dauert. 
+ 
+#on("i")##on("b")##ib#Systemabschaltung#ie# :#off("b")##off("i")# 
+Bevor man den Rechner ausschaltet, sollte jedes EUMEL-System ordnungsgemäß
+abgeschaltet werden. Das geschieht durch den Befehl 'shutup', den man in der Multi­
+user-Version von EUMEL im privilegierten Zweig des Taskbaumes erteilen muß. Nur
+dann ist gewährleistet, daß der aktuelle Zustand Ihres Systems gesichert ist. 
+ 
+Andernfalls gilt das System als abgebrochen, was daran zu erkennen ist, daß sich das
+System beim nächsten Systemstart mit 'RERUN' meldet. Dann kann nur am letzten
+Fixpunkt wieder aufgesetzt werden, und Ihre in letzter Zeit (normalerweise ca. 15
+Minuten) gesammelten Daten können verloren sein. 
+ 
+Installation des EUMEL-Systems 
+#free (1.0)# 
+ 
+#goalpage("a1")#A: Erforderliche Disketten 
+ 
+     -  EUMEL-Systemdiskette        : "Generierungseumel XY"#u#1)#e# 
+     -  EUMEL-Hintergrunddisketten  : "HG0" ... "HGn" 
+     -  EUMEL-Archivdisketten       : "std..." 
+     -  EUMEL-Archivdiskette        : "XY"   (Typabhängig) 
+     -  MS-DOS-Diskette             : "EUMELstart" 
+ 
+#foot# 
+1) XY steht für die Typbezeichnung eines Rechners wie: XT, AT, M24 usw. 
+   Die Anzahl der ausgelieferten Disketten ist auch typabhängig, da z.B.
+   'EUMELstart' nur benötigt wird, falls tatsächlich eine Partitionierung möglich ist. 
+#end# 
+ 
+Die Diskette #goalpage("v1")##on("u")#"Generierungseumel XY"#off("u")# ist ein kleines, jedoch vollständiges EUMEL-
+System. Auf diesem System laufen nach dem Hochfahren Programme ab, die im
+Dialog mit dem Benutzer die Generierung einer oder mehrerer EUMEL-Partitionen
+ermöglichen, diese Bereiche bezüglich schlechter Spuren untersuchen und das SHard
+auf der jeweiligen Partition installieren. #on("b")#Bei der Generierung darf diese Diskette nicht
+schreibgeschützt sein !#off("b")# 
+ 
+Die #on ("u")#Hintergrunddisketten "HG0" ... "HGn"#off ("u")# beinhalten das eigentliche Betriebssystem
+EUMEL. Es sind dies der Systemkern EUMEL-0 und die darauf aufbauenden Sy­
+stemteile (siehe Seite #topage("v2")#). 
+ 
+Die #on ("u")#Standardarchivdisketten "std..."#off ("u")# beinhalten ELAN-Programmpakete und Fontta­
+bellen, die Sie nach erfolgter Installation des Betriebssytems z.B. zum Zwecke einer
+Druckerinstallation oder erweiterter Rechenfunktionen benötigen werden. Sie finden
+dazu detaillierte Informationen in Ihrem Benutzer- und Systemhandbuch. 
+ 
+Die #on("u")#Archivdiskette "XY"#off ("u")# beinhaltet ELAN-Programmpakete, die Funktionen, die nicht
+zu den Standardleistungen von EUMEL bzw. der vorliegenden SHard-Version zählen. 
+ 
+Die Diskette #on("u")#"EUMELstart"#off("u")# ist eine MS-DOS Diskette und beinhaltet Kommando-
+Dateien. Falls Sie auch eine MS-DOS Partition eingerichtet haben, dann gewährlei­
+sten diese das Aktivieren einer EUMEL Partition mit gleichzeitigem Systemstart von
+MS-DOS aus. 
+#free (1.0)# 
+
+#goalpage("a2")#B: Partitionieren der Festplatte / Installation des SHard 
+ 
+ 
+Wenn Sie bereits ein Betriebssystem auf Ihrer Festplatte installiert haben, müssen Sie
+darauf achten, daß noch ausreichend Platz für ein EUMEL-System übrig ist. Da z.B.
+MS-DOS standardmäßig die gesamte Festplatte belegt, muß dieses System gesi­
+chert, mit dem MS-DOS-Kommando 'fdisk' gelöscht und entsprechend kleiner neu
+eingerichtet werden. Sie können auch bei der EUMEL-Installation alle bereits beste­
+henden Systeme löschen; dazu bietet Ihnen der Generierungseumel die Option
+#on("i")#Löschen der gesamten Partitionstabelle #off("i")# an. Dabei gehen jedoch alle bestehenden
+Daten verloren. Achten Sie also darauf, daß sie alle Daten vorher gesichert haben ! 
+ 
+#on("u")##on("i")#Hinweis:#off("i")##off("u")#    Bei Festplatten mit einer Kapazität über 32 Megabyte kann die Installa­
+            tion des SHard zu Problemen führen (Fehlermeldung #on("i")#Platte kann nicht
+            gelesen werden#off("i")# bei der Suche nach schlechten Spuren). Richten Sie
+            daher Ihre EUMEL-Partition(en) auf den ersten 32 Megabyte ein. 
+ 
+Um nun die Partitionierung für Ihr EUMEL-System vorzunehmen, legen Sie die
+Diskette 'Generierungseumel' in das Boot-Laufwerk. Sollte die Diskette mit einer
+Schreibschutzmarke versehen sein, dann müssen Sie diese vorher entfernen. 
+ 
+Schalten Sie nun den Rechner ein bzw. betätigen Sie den Tastatur-RESET, wenn Ihr
+Gerät bereits eingeschaltet ist, indem Sie die Tasten <CTRL> <ALT> <DEL> gleichzeitig
+betätigen. 
+ 
+Der Generierungseumel meldet sich zunächst mit folgender SHard-Meldung: 
+ 
+ 
+ 
+____________________________________________________________________________ 
+ 
+Setup - SHard für EUMEL auf XY und Kompatiblen V x.x 
+Copyright (C) 1985,86 
+EUMEL wird vom Hintergrund geladen 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Danach erscheinen die EUMEL-0 Meldungen zu HG-, RAM- und Pufferkapazität,
+bezogen auf den Diskettenhintergrundes des Generierungseumel. 
+ 
+#on("i")##on("u")#ACHTUNG:#off("u")##off("i")#    Der Generierungseumel soll während des Speichertests (Sternchen)
+            nicht unterbrochen werden. Geschieht dies versehentlich doch, dann
+            fahren Sie fort, indem Sie im Startdialog die Taste <1> für Systemstart
+            betätigen. Dann wird normal mit der Installation fortgefahren. Wählen
+            Sie keinesfalls <2> 'neuen Hintergrund vom Archive laden', solange sich
+            die Diskette 'Generierungseumel' im Archivlaufwerk befindet. 
+ 
+Nach dem Hochfahren des 'Generierungseumel' wird Ihnen eine Tabelle angezeigt,
+der Sie entnehmen können, ob bereits Partitionen auf der Festplatte eingerichtet und
+wie diese spezifiziert sind. 
+ 
+Angezeigt werden neben Größe, Start- und Endspur der einzelnen Partitionen auch
+eine Typ-Nr.; für EUMEL-Partitionen werden in aufsteigender Reihenfolge die
+Typ-Nummern 69 bis 72, für MS-DOS je nach Größe der eingerichteten Partition
+die Nummer 1 oder 4 vergeben. Die Typ-Nummern der eingerichteten Partitionen
+sollten Sie sich merken, da diese Angaben später von Bedeutung sind, wenn das
+Gesamtsystem für Partitionswechsel vorbereitet wird. Richten Sie mehrere EUMEL-
+Partitionen ein, dann können Sie diese ausschließlich über die Typ-Nummern identi­
+fizieren ! 
+ 
+Außerdem wird die gerade aktive Partition durch einen entsprechenden Eintrag in der
+Tabelle kenntlich gemacht. #on("b")#"Aktiv" ist die Partition, die nach dem nächsten Einschal­
+ten des Rechners bzw. nach dem nächsten Tastatur-RESET gebootet würde.#off("b")# 
+ 
+Sie können nun eine der folgenden Funktionen auswählen : 
+ 
+      -  Generieren einer EUMEL-Partition 
+      -  Aktivieren einer Partition 
+      -  Löschen einer EUMEL-Partition 
+      -  Löschen der gesamten Partitionstabelle 
+      -  Generierung beenden 
+ 
+Beim Generieren einer EUMEL-Partition werden lediglich Angaben zu Größe und
+Startzylinder abgefragt. Dafür werden Vorgaben gemacht, die Sie bestätigen können,
+indem Sie die <CR> Taste betätigen. 
+ 
+Beim Neueinrichten orientiert sich die Vorgabe für die Partitionsgröße an dem größten
+zusammenhängenden Freiraum auf Ihrer Platte, die Vorgabe für den Startzylinder
+orientiert sich dann an dem kleinsten zusammenhängenden Freiraum, auf dem eine
+Partition der gewählten Größe eingerichtet werden kann. 
+ 
+#on("i")##on("u")#ACHTUNG:#off("u")##off("i")#    Soll eine EUMEL-Version installiert werden, die nur 16 Megabyte
+            verwalten kann (1.7.3 bzw. 1.8.0), dann darf die Partition nicht größer
+            eingerichtet werden. Es kann hier keine generelle Aussage über die
+            Anzahl der zu reservierenden Spuren gemacht werden, da sehr ver­
+            schiedene Plattenaufteilungen angeboten werden. Entnehmen Sie die
+            entsprechenden Angaben bitte dem Festplatten-Handbuch Ihres Hard­
+            wareherstellers. 
+ 
+Das Löschen einer EUMEL-Partition geschieht nur logisch, nicht physisch, das heißt
+es wird nur der Eintrag in der Partitionstabelle gelöscht. Sollten Sie später an gleicher
+Stelle eine neue Partition einrichten und vorher diesen Bereich physisch nicht über­
+schrieben haben, dann würde nach dem Hochfahren des Rechners das alte System
+wieder gestartet. Die Meldung 'kein EUMEL-System gefunden'(siehe unten) erscheint
+dann nicht. 
+ 
+Haben Sie Ihre EUMEL-Partition(en) eingerichtet, dann achten Sie darauf, daß Sie
+Ihren Generierungseumel ordnungsgemäß wieder verlassen, da es sich hier, wie
+bereits erwähnt, um ein vollständiges EUMEL-System mit Fixpoint/Rerun-Logik
+handelt. Das 'shutup' wird automatisch ausgeführt, wenn Sie die Funktion '0. Gene­
+rierung beenden' wählen. 
+ 
+Wenn die Meldung 'ENDE' auf Ihrem Bildschirm erscheint, ist dieser Schritt der
+Installation beendet. Sie haben nun eine (oder mehrere) EUMEL-Partitionen einge­
+richtet und das SHard installiert. Bitte entfernen Sie jetzt die Diskette 'Generierungs­
+eumel' aus dem Diskettenlaufwerk. 
+#free (1.0)# 
+Laden eines EUMEL-Hintergrundes 
+ 
+#free(1.0)# 
+Im nächsten Schritt wird auf Ihrer Festplatte das EUMEL-System installiert, d.h. es
+wird ein Hintergrund auf der Festplatte erzeugt. 
+ 
+Dazu müssen Sie nach dem ordnungsgemäßen Beenden des Generierungseumel und
+Entfernen der Diskette aus dem Laufwerk den Tastatur-RESET betätigen. Dies
+geschieht entweder durch gleichzeitiges Betätigen der Tasten <CNTL> <ALT> <DEL>
+auf der Tastatur oder durch AUS- und wieder EIN-Schalten des Rechners (Bitte
+warten Sie einen Augenblick zwischen dem AUS- und EIN-Schalten). 
+ 
+Das System meldet sich nach kurzer Zeit mit folgender SHard-Meldung: 
+ 
+ 
+____________________________________________________________________________ 
+ 
+SHard für EUMEL auf XY, V x.x 
+Copyright (C) 1985,86 
+kein EUMEL-System gefunden 
+ 
+____________________________________________________________________________ 
+ 
+ 
+ 
+Sie legen nun die Hintergrunddiskette HG0 in das Boot-Laufwerk und betätigen eine
+Taste. 
+ 
+Der Systemkern wird nun geladen und es erscheinen die bereits oben erwähnten
+Angaben zu HG-, RAM- und Pufferkapazität, sowie zu den angeschlossenen
+Kanälen, diesmal jedoch bezogen auf die eingerichtete Festplatten-Partition. Wäh­
+rend des Speichertests drücken Sie bitte erneut eine Taste, um in den Startdialog zu
+gelangen und damit zu verhindern, daß EUMEL-0 versucht, das System zu starten.
+Sollten Sie dies versäumen, so erscheint die Meldung 'HG ungültig'. Sie haben dann
+erneut die Möglichkeit, durch Betätigen einer Taste in den Startdialog zu gelangen. 
+ 
+Hier wählen Sie den Menupunkt <2> 'neuen Hintergrund vom Archiv laden' und bestä­
+tigen die Frage 'Alten Hintergrund überschreiben' mit <j> für 'ja'. 
+ 
+Es erscheint ein Zähler auf dem Bildschirm, der die gelesenen Blöcke anzeigt. Verteilt
+sich Ihr Hintergrund auf mehrere Disketten, dann müssen Sie bei bei der Frage
+'Neues HG-Archiv eingelegt' die nächste Diskette einlegen und mit <j># #off("i")#  quittieren.
+Bitte beachten Sie dabei genau die Numerierung der HG-Disketten ! 
+ 
+Es können bei beschädigten Disketten Lesefehler auftreten; dann gibt das System
+eine der Meldungen 'Harter Lesefehler' bzw. 'Softerror' aus. Bei letzterem konnte der
+entsprechende Sektor nach mehrmaligem Versuch noch gelesen werden. Bei einem
+harten Lesefehler können Sie die Diskette nicht verwenden. 
+ 
+Wenn alle Disketten eingelesen sind, müssen Sie ein letztes mal den Tastatur-
+RESET betätigen, um das System zu starten. Vergessen Sie nicht, vorher die Hinter­
+grunddiskette aus dem Diskettenlaufwerk zu entfernen. 
+ 
+Wenn Sie jetzt während des Hochfahrens keine Taste drücken, dann startet der Lader
+durch und das EUMEL-System meldet sich mit 'System aufgebaut'. Dies dauert
+beim Auslieferungshintergrund wenige Sekunden, kann jedoch bei größeren Systemsi­
+cherungen auch mehrere Minuten in Anspruch nehmen; verlieren Sie dann bitte nicht
+allzu schnell die Geduld. 
+ 
+Da der Auslieferungs-Hintergrund unkonfiguriert ist, gelangt das System beim ersten
+Hochfahren nach der Installation sofort in den 'configurator'. Sie müssen jetzt den
+Kanal 1 entsprechend der vorhandenen Tastatur als "PC.german" oder "PC.ascii"
+konfigurieren. Sollten Sie eine EUMEL-Version 1.7.3 benutzen und diesen Konfigura­
+tionsdatenraum nicht zur Verfügung haben, dann konfigurieren Sie den Kanal 1 als
+"PC" und Terminal. Näheres dazu finden Sie im Systemhandbuch (Teil 1). 
+#page# 
+ Die einzelnen Schritte der Installation im Überblick 
+#free (0.5)# 
+#linefeed(1.5)# 
+   1. Die Diskette 'Generierungseumel' in das Laufwerk stecken 
+   2. Rechner einschalten oder Tastatur-RESET mit <CTRL>, <ALT> <DEL> 
+   3. EUMEL-Partition einrichten 
+   4. Generierung beenden und auf 'ENDE'-Meldung warten 
+   5. Diskette 'Generierungseumel' entnehmen 
+   6. Tastatur-RESET 
+   7. Die Meldung 'Kein EUMEL-System gefunden' abwarten. Wenn die Meldung
+      'EUMEL wird vom Hintergrund geladen' erscheint, dann weiter bei 9. 
+   8. Erste Hintergrunddiskette (HG0) einlegen und Taste drücken 
+   9. Beim Speichertest eine Taste betätigen, um in den Startdialog zu gelangen. 
+  10. Menupunkt <2> anwählen : Neuen Hintergrund vom Archiv laden 
+  11. Eventuell weitere HG-Disketten nach entsprechender Aufforderung einlegen
+      und mit <j> quittieren 
+  12. Tastatur-RESET nach entsprechender Aufforderung 
+  13. Nach dem Hochfahren des Systems Konfiguration lt. Systemhandbuch
+      vornehmen 
+  14. Ggf. in der Task 'SYSUR' ELAN-Pakete für Partitionswechsel insertieren. 
+      #linefeed (1.0)# 
+      Dazu  -  Falls eine EUMEL-Version 1.7.3 benutzt wird, zunächst das
+               Kommando #on("i")#free global manager#off("i")# in der Task 'configurator' absetzen 
+            -  Archivdiskette "XY" einlegen und anmelden : #on("i")#archive �("XY")#off("i")# 
+            -  Datei "XY install" von Archivdiskette lesen : 
+               #on("i")#fetch ("XY install", archive)#off("i")# 
+            -  Insertierung starten : #on("i")#run#off("i")# 
+Druckersoftware einrichten 
+ 
+#free(0.5)# 
+Um mit Ihrem EUMEL-System einen Drucker betreiben zu können, müssen Sie
+außer dem Anschluß des Druckers mit einem passenden Kabel auch die passende
+Software für diesen Drucker zur Verfügung stellen. Zu diesem Zweck dienen die
+Druckeranpassungen. 
+ 
+Das Standardarchive "std.printer" enthält Druckeranpassungen für die Ansteuerung
+diverser gebräuchlicher Druckertypen. Soll einer dieser Drucker an das EUMEL-
+System angeschlossen werden, so muß zuerst eine Task "#ib#PRINTER#ie#" als Sohntask
+von "SYSUR" mit dem Supervisorkommando 
+ 
+#linefeed (1.18)# 
+        begin ("PRINTER", "SYSUR") 
+#linefeed (1.0)# 
+ 
+eingerichtet werden. In dieser Task müssen dann die folgenden Schritte vollzogen
+werden: 
+ 
+-  Archiv anmelden: 
+#linefeed (1.18)# 
+        archive ("std.printer") 
+#linefeed (1.0)# 
+ 
+-  Druckeranpassung vom Archiv holen: 
+#linefeed (1.18)# 
+        fetch ("printer.druckertyp", archive) 
+#linefeed (1.0)# 
+ 
+-  Zeilennummergenerierung bei der Insertierung abschalten: 
+#linefeed (1.18)# 
+        check off 
+#linefeed (1.0)# 
+ 
+-  Druckeranpassung insertieren: 
+#linefeed (1.18)# 
+        insert ("printer.druckertyp") 
+#linefeed (1.0)# 
+ 
+Beispiel: 
+#linefeed (1.18)# 
+        archive ("std.printer") 
+        fetch ("printer.epson.fx", archive); 
+        check off; 
+        insert ("printer.epson.fx") 
+#linefeed (1.0)# 
+ 
+Nach der Insertierung wird zuerst nach dem #ib#Druckerkanal#ie# gefragt. Dieser sollte mit
+der Gerätetabelle 'transparent' konfiguriert sein. Dann werden ggf. druckerspezifische
+Fragen zur Papierbreite, Positionierungsart oder ähnlichem gestellt, die mit 'j' oder 'n'
+beantwortet werden müssen. Dabei werden alle Alternativantworten zu der jeweili­
+gen Frage hintereinander angeboten, bis eine Alternative mit 'j' beantwortet wird. 
+ 
+Als letzter Schritt kommt die Aufforderung das Archiv mit der passenden Fonttabelle
+einzulegen. Diese Fonttabelle, eine Beschreibung aller darstellbaren Zeichen in allen
+druckbaren Schrifttypen, ist  meistens auf derselben Diskette wie die Druckeranpas­
+sung. 
+ 
+Wenn die Generierung beendet ist, muß im Multi-User Betrieb in allen bestehenden
+Tasks - insbesondere in der Task 'PUBLIC' - die Fonttabelle mit dem fonttable-
+Kommando eingestellt werden. 
+ 
+Beispiel: 
+ 
+#linefeed (1.18)# 
+        fonttable("fonttab.epson.fx") 
+#linefeed (1.0)# 
+ 
+Von jeder Task aus kann danach mit dem Kommando 
+ 
+#linefeed (1.18)# 
+        print ("dateiname") 
+#linefeed (1.0)# 
+ 
+wird eine Datei ausgedruckt werden. 
+ 
+Das Einstellene einer Fonttabelle ist insbesondere Voraussetzung für 'lineform', 'page­
+form' etc. 
+ 
+Befindet sich keine passende Druckeranpassung für den anzuschließenden Drucker­
+typ auf dem Standardarchiv "std.printer", so sollte die Druckeranpassung "printer.std"
+benutzt werden. Diese Druckeranpassung ist eine universelle Druckeranpassung für
+alle Drucker, die mit ASCII-Code 13 ein 'Carriage Return' (d.h. Bewegung des
+Druckkopfes an den linken Rand) und mit ASCII-Code 10 eine Zeilenschaltung von
+1/6 Zoll vornehmen. Mit ihr kann dann in einem Schrifttyp (entweder 10 oder 12
+Zeichen pro Zoll, je nachdem welche Fonttabelle eingestellt ist) gedruckt werden. So
+erhält man wenigstens eine Minimalansteuerung des Druckers. 
+ 
+ 
+ 
+Druckersoftware im Single-User einrichten 
+ 
+ 
+Die Installation der Druckersoftware im Single-User erfolgt ähnlich wie die im Mul­
+ti-User. Hier brauchen nur die Schritte durchgeführt zu werden, die im Multi-User
+in der Task "PRINTER" druchgeführt werden müssen. Eine Task "PRINTER" braucht
+nicht eingerichtet zu werden. 
+
diff --git a/doc/warenhaus/Anhang Warenhaus b/doc/warenhaus/Anhang Warenhaus
new file mode 100644
index 0000000..9388ceb
--- /dev/null
+++ b/doc/warenhaus/Anhang Warenhaus	
@@ -0,0 +1,65 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (100)# 
+#headodd# 
+#center#gs-Warenhaus#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Warenhaus
+ 
+#end# 
+#center#1 
+ 
+#center##on("b")##Anhang#off("b")# 
+ 
+#on("b")##center#Muster für Codekarten#off("b")# 
+ 
+            +-------------------+
+            |  O O O O O O O O  |
+            |                   |
+            |                   |
+            |                   |
+            |                   |
+            |                   |
+            |                   |
+            |                   |
+            | ----------------- |
+            +-------------------+
+ 
+ 
+ 
+            +--------------------+
+            |                    |
+            |          O O O O   |
+            |                    |
+            |                    |
+            |W A R E N K A R T E |
+            |                    |
+            |                    |
+            |       Artikel      |
+            |  ----------------  |
+            |                    |
+            +--------------------+
+
+#page#      
+ 
+ 
+            +------------------------+
+            |                        |
+            |  O         O O O O O   |
+            |                        |
+            | K U N D E N K A R T E  |
+            |                        |
+            |                        |
+            | Name                   |
+            | ---------------------- |
+            |                        |
+            |                        |
+            +------------------------+
+
+
+
+
+
+
diff --git a/doc/warenhaus/Inhalt Warenhaus b/doc/warenhaus/Inhalt Warenhaus
new file mode 100644
index 0000000..a9b720d
--- /dev/null
+++ b/doc/warenhaus/Inhalt Warenhaus	
@@ -0,0 +1,50 @@
+#limit (11.5)##pagelength (16.5)##pageblock# 
+#start (1.8,0.0)# 
+Inhaltsverzeichnis 
+ 
+ 
+1      Was kann gs-Warenhaus                            1-1 
+ 
+2      Aufbau von gs-Warenhaus                          2-1 
+ 
+3      Installation von gs-Warenhaus                    3-1 
+3.1    Voraussetzungen                                  3-1 
+3.2    Lieferumfang                                     3-1 
+3.3    Installation                                     3-2 
+3.4    Einrichten mehrerer Hauptstellen                 3-8 
+ 
+4      Anschluß eines Codekartenlesers                  4-1 
+4.1    Hardware-Voraussetzungen                         4-1 
+4.2    Verwendung des MUFI                              4-2 
+4.2.1  Einstellungen am MUFI                            4-3 
+4.2.2  MUFI im Terminalkanal                            4-5 
+4.2.3  MUFI als Endgerät                                4-6 
+4.3    Verwendung des AKTRONIC-Adapters                 4-7 
+4.4    Konfiguration der seriellen Schnittstelle        4-8 
+4.5    Verbindung der Hardware-Komponenten              4-10 
+ 
+5      Beschreibung der Menufunktionen                  5-1 
+5.1    Kurzhinweise zur Bedienung des Menus             5-1 
+5.2    Menufunktionen zum Oberbegriff 'Info'            5-4 
+5.3    Menufunktionen zum Oberbegriff 'Eingabeart'      5-7 
+5.4    Menufunktionen zum Oberbegriff 'Kommandos'       5-9 
+5.5    Menufunktionen zum Oberbegriff 'Programme'       5-18 
+5.6    Menufunktionen zum Oberbegriff 'Filialdaten'     5-24 
+5.7    Menufunktionen zum Oberbegriff 'Archiv'          5-28 
+ 
+6      Beschreibung der Programmierschnittstelle        6-1 
+6.1    Schreibweisen und Syntaxregeln in GRIN-Programmen    6-4 
+6.2    Kontrollstrukturen                                   6-8 
+6.3    Detailbeschreibung der Warenhaus-Grundbefehle        6-13 
+ 
+7      Weitere Kommandos (für Systembetreuer)               7-1 
+ 
+Anhang:   Muster für Codekarten 
+
+
+
+
+
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus handbuch.impressum b/doc/warenhaus/gs-Warenhaus handbuch.impressum
new file mode 100644
index 0000000..3fbb371
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus handbuch.impressum	
@@ -0,0 +1,89 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#gs-Warenhaus
+ 
+ 
+ 
+ 
+#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# 
+ 
+#free (4.0)##on("b")# 
+#center#gs-Warenhaus
+ 
+ 
+#center#Benutzerhandbuch 
+ 
+ 
+#center#Version 1.0 
+ 
+ 
+#off("b")##center#copyright 
+#center#Eva Latta-Weber 
+#center#Software- und Hardware-Systeme, 1988 
+#center#ERGOS GmbH, 1990 
+#page# 
+#block# 
+#center#____________________________________________________________________________ 
+ 
+ 
+Copyright:  ERGOS GmbH   März 1990 
+ 
+                     Alle Rechte vorbehalten. Insbesondere ist die Überführung in
+                     maschinenlesbare Form sowie das Speichern in Informations­
+                     systemen, auch auszugsweise, nur mit schriftlicher Einwilligung
+                     der ERGOS GmbH gestattet. 
+ 
+ 
+#center#____________________________________________________________________________ 
+ 
+Es kann keine Gewähr übernommen werden, daß das Programm für eine
+bestimmte Anwendung geeignet ist. Die Verantwortung dafür liegt beim
+Anwender. 
+ 
+Das Handbuch wurde mit größter Sorgfalt erstellt. Für die Korrektheit und
+Vollständigkeit der Angaben kann keine Gewähr übernommen werden. Das
+Handbuch kann jederzeit ohne Ankündigung geändert werden. 
+ 
+Texterstellung   :  Dieser Text wurde mit der ERGOS-L3 Textverarbeitung
+                   erstellt und aufbereitet und auf einem Kyocera Laser­
+                   drucker gedruckt. 
+ 
+ 
+ 
+ 
+#center#___________________________________________________________________________ 
+ 
+ 
+ 
+Ergonomic Office Software GmbH 
+ 
+Bergstr. 7              Telefon: (02241) 63075 
+5200 Siegburg           Teletex: 2627-2241413=ERGOS 
+                        Telefax: (02241) 63078 
+ 
+ 
+#center#____________________________________________________________________________ 
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-1 b/doc/warenhaus/gs-Warenhaus-1
new file mode 100644
index 0000000..ca79094
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-1
@@ -0,0 +1,124 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (3)# 
+#headodd# 
+#center#gs-warenhaus#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-warenhaus
+ 
+#end# 
+#center#1  Was kann gs-Warenhaus 
+ 
+ 
+Das Programmpaket #on("b")#gs-Warenhaus#off("b")# entstand auf der Grundlage der projekt­
+orientierten Unterrichtseinheit "WARENHAUS", die vom 'Landesinstitut für Schule
+und Weiterbildung' (LSW) in Soest für den Bereich der 'Informations- und
+kommunikationstechnologischen Grundbildung' (kurz: GRIN) entwickelt wurde. 
+ 
+Unter #on("b")#1.1 Thema und Ziele #off("b")# ist in dem zugehörigen Begleitheft folgendes zu
+finden: 
+ 
+#i1#"Die Schülerinnen und Schüler sollen in dieser Unterrichtseinheit die An­
+wendungen neuer Technologien im Warenhaus kennenlernen und dabei sowohl
+die grundlegenden technologischen Zusammenhänge erarbeiten als auch die
+Auswirkungen reflektieren, die sich durch ihren Einsatz ergeben. Sie werden
+dabei nicht nur die Rolle der Kunden einnehmen, sondern auch die Interessen
+der Angestellten und die der Geschäftsleitung in ihre Beurteilung mit einbe­
+ziehen. 
+ 
+Diese komplexen Zusammenhänge werden den Schülerinnen und Schülern im 8.
+Schuljahr nähergebracht, indem sie veranlaßt werden, in einem Modell-Waren­
+haus selbst schrittweise das Modell eines Warenwirtschaftssystems aufzubauen
+und damit zu arbeiten. 
+ 
+In diesem Modell-Warenhaus kommt dem Umgang mit dem Computer eine
+besondere Bedeutung zu. Mit Hilfe des Rechners, an den ein Codekartenleser
+angeschlossen ist, und des zugehörigen Programms werden die wesentlichen
+Bestandteile eines modernen Kassensystems abgebildet. 
+ 
+Mit dem Codekartenleser kann das Merkmal des automatischen Dateneinlesens
+vereinfacht dargestellt werden. Programmabläufe, Bildschirmausgaben werden
+nicht nur über Tastatureingaben der Benutzer beeinflußt, sondern auch durch
+das Lesen verschlüsselter Informationen. Am Beispiel des Lesegerätes wird zum 
+#page# 
+einen der Rationalisierungseffekt an der Kasse verdeutlicht, es lassen sich zum
+anderen aber auch Fragen der Zugangsberechtigung durch maschinenlesbare
+Ausweiskarten ansprechen. 
+ 
+Das zur Verfügung stehende Programm erlaubt es, daß die Schülerinnen und
+Schüler schrittweise die zentralen Funktionen eines modernen Warenwirtschafts­
+systems kennenlernen. Neben der maschinellen Datenerfassung mit Hilfe des
+Lesegeräts und der Decodierung von Informationen sind dies z.B.: 
+ 
+- automatische Abrechnung, 
+- Speicherung von Warendaten, 
+- Kontrolle des Lagerbestandes, 
+- Informationen über Verkaufszahlen, 
+- automatische Nachbestellung, 
+- Speicherung von Kundendaten, 
+- Zusammenfassung von Informationen aus verschiedenen Filialen, 
+- Erstellen von Übersichten. 
+ 
+Die Schülerinnen und Schüler arbeiten dabei mit einer benutzerfreundlichen
+Programmierumgebung. Diese bietet einerseits die Möglichkeit, die Befehle direkt
+aufzurufen, mit denen alle Funktionen dieses vereinfachten Warenwirtschafts­
+systems ausgeführt werden können, wie etwa Dateien aufbauen, einkaufen und
+Listen erstellen. Andererseits stellt die Programmierumgebung weitere Befehle
+zur Verfügung, mit denen einige dieser Funktionen auch 'programmiert' werden
+können."#off("b")# 
+ 
+Soweit zu Thema und Zielen dieser Unterrichtseinheit. Für weitere didaktisch-
+methodische Informationen zu dieser Reihe verweisen wir auf das entsprechende
+Begleitheft des LSW. 
+(Vertrieb: Soester Verlagskontor, Jakobistraße 46, 4770 Soest; Bestellnummer 1710) 
+#page# 
+Da bei der Software-Entwicklung für GRIN vom LSW das Betriebssystem EUMEL nicht
+mit berücksichtigt wird, erscheint es notwendig, durch Eigeninitiativen wenigstens
+einige GRIN - Projekte unter EUMEL zur Verfügung zu stellen, um den Schulen, die
+mit EUMEL arbeiten, nicht gänzlich den Zugang zu GRIN zu verwehren. 
+ 
+Das Projekt WARENHAUS bietet sich dabei besonders an, weil die Vernetzungen
+innerhalb eines Warenwirtschaftssystems mit einem Mehrplatz-System und der
+Möglichkeit der Intertask-Kommunikation wesentlich wirklichkeitsnäher aufzeigbar
+sind als mit einem reinen Einzelplatz-System wie z.B. MS DOS, bei dem die
+Kommunikation nur über den Transport von Disketten geregelt wird. (Ein Netzwerk
+ist in der Software der LSW nicht vorgesehen.) 
+ 
+#on("b")#gs-Warenhaus#off("b")# umfaßt die wesentlichen Funktionen der vom LSW für MS DOS
+erstellten Programmierumgebung WARENHAUS-2. Es ist jedoch keine genaue 'Nach­
+bildung' dieser Software, sondern eher eine Realisierung des 'Vorbildes' unter
+Berücksichtigung der besonderen Gegebenheiten des EUMEL-Systems, wobei sowohl
+am äußeren Erscheinungsbild als auch inhaltlich Änderungen und Erweiterungen
+vorgenommen wurden. Eingebettet ist #on("b")#gs-Warenhaus#off("b")# in die menüorientierte
+Benutzerschnittstelle #on("b")#gs-DIALOG#off("b")#. 
+ 
+Ein Codekartenleser kann in Verbindung mit einem Interface (z.B. dem MUFI der
+Firma BICOS) verwendet werden, ist für die Nutzung des Programmes aber nicht
+unbedingt erforderlich. 
+ 
+Da zur Zeit der Entstehung dieses Programms GRIN an den Schulen noch nicht
+etabliert ist und man mit (vorerst) nur einem Projekt dem Ansatz von GRIN sicher
+nicht gerecht werden kann, ist #on("b")#gs-Warenhaus#off("b")# flexibel angelegt. Es enthält neben
+einer Programmierumgebung, in der die vom LSW für GRIN entwickelten Befehle und
+Syntaxregeln benutzt werden, eine weitere, in der in gewohnter ELAN-Syntax ge­
+arbeitet werden kann, so daß es z.B. ebenfalls für den Unterricht in Klasse 9/10 (für
+spezielle Fragestellungen evtl. auch in der Sek. II) verwendbar ist. 
+#page# 
+Natürlich ist #on("b")#gs-Warenhaus#off("b")# #i1#kein#off("b")# Verwaltungsprogramm für 'echte' Warenhäuser
+oder gar ganze Warenwirtschaftssysteme, es ist vielmehr ein Simulationsprogramm,
+das die Vorgänge in solch einem System anhand eines stark vereinfachten Modells
+klarmachen soll. Aus diesem Grunde werden Ihnen beim Umgang mit diesem Pro­
+gramm wahrscheinlich eine ganze Reihe von Erweiterungsmöglichkeiten und
+Funktionen einfallen, die das Programm nicht bietet. Denken Sie dabei bitte aber
+immer daran, daß #on("b")#gs-Warenhaus#off("b")# in erster Linie für den Einsatz in GRIN oder im
+WP-Unterricht konzipiert wurde, vornehmlich also von absoluten 'Anfängern' auf dem
+Gebiet des Umgangs mit Rechnern genutzt wird, die von einer zu großen Fülle von
+Programmfunktionen nur verwirrt würden. 
+ 
+Wir werden Ihnen in den folgenden Kapiteln dieses Handbuchs den Umgang mit den
+Funktionsangeboten von #on("b")#gs-Warenhaus#off("b")# erklären, auf die Umsetzungsmöglichkeiten
+der am Anfang dieses Kapitels erwähnten Ziele im Unterricht gehen wir jedoch nicht
+ein. Beschaffen Sie sich dafür bitte das bereits oben angegebene Begleitheft des LSW. 
+
diff --git a/doc/warenhaus/gs-Warenhaus-2 b/doc/warenhaus/gs-Warenhaus-2
new file mode 100644
index 0000000..f3f1284
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-2
@@ -0,0 +1,72 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (5)# 
+#headodd# 
+#center#gs-warenhaus#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-warenhaus
+ 
+#end# 
+#center##on("b")#2  Aufbau von gs-Warenhaus#off("b")# 
+ 
+#on("b")#gs-Warenhaus#off("b")# bietet die Möglichkeit, nicht nur #us#ein#use# Warenhaus, sondern eine
+Warenhaus-Kette im Modell nachzubilden. Solch eine Warenhauskette besteht hier
+stets aus einer #us#Hauptstelle#use# und einer oder mehrerer (bis zu 10) #us#Filialen#use#. Damit die
+Filialen auf die zentralen Daten der Warenhauskette zugreifen können, verfügt jede
+Hauptstelle über eine #us#Zentrale#use#, die jederzeit angerufen werden kann. Für die
+Kommunikation untereinander gehört zu jeder Filiale eine (Filial-) #us#Verwaltung#use#, bei
+der die aktuellen Filialdaten erfragt werden können. 
+ 
+ 
+Realisiert wird dieser Aufbau durch verschiedene Tasks und der Möglichkeit der
+Intertask-Kommunikation. Unter einer Task, in der #on("b")#gs-Warenhaus#off("b")# insertiert ist,
+können eine oder mehrere Tasks als Hauptstellen angemeldet werden (siehe '3.3
+Installation' und '7 Weitere Kommandos'). So kann man z.B. für verschiedene
+Klassen gleichzeitig Warenhausketten einrichten. Zu beachten ist, daß verschiedene
+Ketten untereinander völlig unabhängig sind und dadurch #us#nicht#use# miteinander
+kommunizieren können. 
+ 
+ 
+Jede Hauptstellen-Task richtet sich automatisch eine Sohn-Task als Zentrale ein.
+Werden nun Sohn-Tasks einer Hauptstellen-Task angemeldet, so werden diese zu
+Filialen der entsprechenden Hauptstelle, wobei ihnen automatisch eine Filialnummer
+zugeteilt wird, die identisch ist mit der Kanalnummer des benutzten Terminals.
+(Steht keine Mehrplatzanlage zur Verfügung, so läßt sich nur #us#eine#use# Filiale einrichten;
+die Filialnummer ist dann in der Regel 1.) 
+ 
+ 
+Die Filial-Tasks ihrerseits legen beim Starten von #on("b")#gs-Warenhaus#off("b")# automatisch jeweils
+eine Sohn-Task als (Filial-) Verwaltung an. 
+#page# 
+Insgesamt ergibt sich folgender schematischer Aufbau (die Pfeile zeigen die
+Kommunikationsmöglichkeiten an): 
+ 
+ 
+#on("b")# 
+                        W A R E N H A U S 
+                       /        |        \ 
+         Hauptstelle A     Hauptstelle B   Hauptstelle C  . . . 
+ 
+       /        |        \ 
+Zentrale A  Filiale A1  Filiale A2  . . . 
+    ^
+    |
+    |      Verwaltg.A1  Verwaltg.A2  . . . 
+    |           ^             ^
+    |           |             |
+    ---------------------------      . . . 
+#off("b")# 
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-3 b/doc/warenhaus/gs-Warenhaus-3
new file mode 100644
index 0000000..ffef881
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-3
@@ -0,0 +1,309 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (7)# 
+#headodd# 
+#center#gs-Warenhaus#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Warenhaus
+ 
+#end# 
+#center#1 
+ 
+#center##on("b")#3  Installation von gs-Warenhaus#off("b")# 
+ 
+ 
+Bevor Sie #on("b")#gs-Warenhaus#off("b")# auf Ihrem Computer benutzen können, müssen Sie das
+Programm zunächst installieren. Wenn #on("b")#gs-Warenhaus#off("b")# auf Ihrem System schon zur
+Verfügung steht, können Sie dieses Kapitel ruhig überspringen. 
+ 
+ 
+ 
+#on("b")#3.1  Voraussetzungen#off("b")# 
+ 
+Um #on("b")#gs-Warenhaus#off("b")# auf Ihrem Computer betreiben zu können, muß das EUMEL-
+Betriebssystem installiert sein. #on("b")#gs-Warenhaus#off("b")# setzt die Multi-User-Version voraus
+und ist lauffähig ab Version 1.8.0. #on("b")#gs-Warenhaus#off("b")# setzt weiterhin voraus, daß auf
+Ihrem Computer bereits das Programm #on("b")#gs-DIALOG#off("b")# (ab Version 1.1) installiert ist. 
+ 
+ 
+ 
+#on("b")#3.2  Lieferumfang#off("b")# 
+ 
+#on("b")#gs-Warenhaus#off("b")# wird auf einer Diskette geliefert, die alle notwendigen Programme
+enthält (die Installation von #on("b")#gs-DIALOG#off("b")# wird dabei vorausgesetzt!). Um den Inhalt
+der Diskette feststellen zu können, starten Sie Ihr System und bringen es dazu, daß
+'gib kommando:' erscheint. Dann legen Sie die Diskette ein und geben das
+Kommando: 
+ 
+ 
+#on("b")#archive("gs-Warenhaus"); list(archive); release(archive) <RETURN>#off("b")# 
+#page# 
+Anschließend erscheint eine Übersicht der auf dem Archiv vorhandenen Programme.
+Folgende Dateinamen sollten sich in der Übersicht befinden: 
+ 
+     "gs-MENUKARTE:Warenhaus" 
+     "gs-Warenhaus 0: ohne Kartenleser" 
+     "gs-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter" 
+     "gs-Warenhaus 0: mit Kartenleser an MUFI als Endgerät" 
+     "gs-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal" 
+     "--------------------------------------------" 
+     "gs-Warenhaus 1" 
+     "gs-Warenhaus 2" 
+     "gs-Warenhaus 3" 
+     "gs-Warenhaus 4" 
+     "gs-Warenhaus 5" 
+     "gs-Warenhaus/gen" 
+ 
+Eventuell können noch weitere Namen auf der Diskette vorhanden sein. Wenn Sie den
+Inhalt der Diskette kontrolliert haben und diese Dateien auf der Diskette vorhanden
+sind, können Sie #on("b")#gs-Warenhaus#off("b")# installieren. 
+ 
+Sollten Sie statt der Übersicht eine Fehlermeldung erhalten, überprüfen Sie bitte, ob
+die Diskette das richtige Format besitzt oder ob Ihr Diskettenlaufwerk Probleme
+macht. Sollten dagegen Programme fehlen, so reklamieren Sie die Diskette. 
+ 
+ 
+ 
+#on("b")#3.3  Installation#off("b")# 
+ 
+#on("b")#gs-Warenhaus#off("b")# muß in einer Task installiert werden, in der bereits das Programm
+#on("b")#gs-DIALOG#off("b")# zur Verfügung steht. Alle Söhne und Enkel der neuen Task können
+anschließend das Warenhaus-Modell aufrufen. Richten Sie also eine Task als Sohn
+#page# 
+der Task ein, in der auf Ihrem Computer bereits #on("b")#gs-DIALOG#off("b")# installiert ist. Wir
+nehmen hier an, daß #on("b")#gs-DIALOG#off("b")# in der Task 'MENU' installiert ist und die neue
+Task den Namen 'WARENHAUS' erhalten soll. (Sie können für die Task auch einen
+beliebigen anderen Namen wählen): 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+ 
+#off("b")# 
+  -->     gib supervisor kommando: 
+#on("b")# 
+          begin ("WARENHAUS","MENU") <RETURN> 
+#off("b")# 
+ 
+  -->     gib kommando: 
+ 
+(Arbeiten mehrere Personen mit dem Computer, dann ist es sinnvoll, diese Task vor
+unbefugtem Zugriff durch ein Passwort zu schützen. Wie das gemacht wird, können
+Sie in Ihrem EUMEL-Benutzerhandbuch erfahren.) 
+ 
+Legen Sie dann die Archivdiskette ein, auf der sich #on("b")#gs-Warenhaus#off("b")# befindet, und
+geben Sie die folgenden Kommandos: 
+ 
+#on("b")# 
+   archive ("gs-Warenhaus") <RETURN> 
+ 
+   fetch (ALL archive, archive) <RETURN> 
+ 
+   release (archive) <RETURN> 
+ 
+   run ("gs-Warenhaus/gen") <RETURN> 
+#off("b")# 
+ 
+Sie haben damit das Installationsprogramm gestartet und können die Diskette wieder
+aus dem Laufwerk nehmen. (Natürlich können Sie die Dateien auch mit Hilfe von
+#on("b")#gs-DIALOG#off("b")# von der Diskette holen. Achten Sie dann bitte darauf, daß sie #on("b")#alle#off("b")# oben
+angegebenen Dateien von der Diskette in Ihre Task holen). 
+#page# 
+Zunächst werden Sie nun aufgefordert, eine Interface-Anpassung für den Codekarten­
+leser auszuwählen. Dazu erscheint das folgende Menu auf dem Bildschirm: 
+ 
++----------------------------------------------------------------------+ 
+|center#Auswahl einer Interface-Anpassung für den Codekartenleser      | 
+|center#Wenn kein Kartenleser benutzt wird, <ESC><q> tippen!           | 
+|                                                                      | 
+|    Auswahl  e i n e r  Datei durch Ankreuzen                         | 
+|                                                                      | 
+|   ==>   � gs-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter        | 
+|         � gs-Warenhaus 0: mit Kartenleser an MUFI als Endgerät       | 
+|         � gs-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal   | 
+|                                                                      | 
+|                                                                      | 
+|                                                                      | 
+|                                                                      | 
+|   Info: <?>    Fertig: <ESC><q>    Abbrechen: <ESC><h>               | 
+|                                                                      | 
++-----------------------------------------------------------------------
+Soll kein Kartenleser benutzt werden, tippen Sie einfach <ESC><q>. Sonst fahren
+Sie den Pfeil mit den Cursor-Tasten in die gewünschte Zeile und drücken
+<RETURN>. Welche der angegebenen Anpassung für welchen Zweck die geeignete
+ist, wird in Kapitel 4 ("Anschluß eines Codekartenlesers") genauer beschrieben. 
+ 
+Daraufhin wird die Installation automatisch durchgeführt. Haben Sie die Anpassung
+für den 'AKTRONIC-Adapter' oder für das 'MUFI als Endgerät' ausgewält, so erscheint
+nach der Insertierung dieser Datei die Aufforderung 
+ 
+#center##on("b")#Gib Interface-Kanal:#off("b")# 
+ 
+Hier muß angegeben werden, an welchen Kanal (serielle Schnittstelle) das Interface
+angeschlossen werden soll (vgl. wiederum Kapitel 4). Der Interface-Kanal läßt sich
+auch später noch umstellen (vgl. Kapitel 7). 
+ 
+Wenn der Insertierungs-Vorgang abgeschlossen ist, müssen Sie noch einige Fragen
+beantworten: 
+ 
+#on("b")#Frage 1:#off("b")# #on("b")#Version für GRIN (j/n)?#off("b")# 
+ 
+Tippen Sie hier ein <j>, so werden später in der Programmierumgebung die
+'Soester' Befehle und Syntax-Regeln benutzt, ein <n> liefert die Programmier­
+umgebung für ELAN. Die Versions-Einstellung kann auch noch später geändert
+werden (vgl. Kapitel 7, Befehl 'grin'). 
+ 
+#on("b")#Frage 2:#off("b")# #on("b")#Soll diese Task Warenhaus-Hauptstelle sein (j/n)?#off("b")# 
+ 
+Das Tippen von <j> macht Ihre momentan benutzte Task zur (einzigen!) Waren­
+haus-Hauptstelle; Sie können dann (nach Beantwortung mindestens einer weiteren
+Frage, s.u.) in Söhnen dieser Task das Warenhaus-Programm starten. Allerdings ist es
+dann nicht mehr möglich, Sohntasks dieser Task zu Hauptstellen zu machen! 
+ 
+Möchten Sie aber mehrere Hauptstellen (evtl. für verschiedene Lerngruppen) ein­
+richten, so müssen Sie hier ein <n> tippen. In diesem Fall ist die Installation
+zunächst beendet und es erscheint der EUMEL-Eingangsbildschirm. Was Sie dann
+noch tun müssen, erfahren Sie in Kapitel 3.4; die folgenden Ausführungen können
+Sie überschlagen. 
+ 
+#on("b")#Frage 3:#off("b")# #on("b")#Mit Direktstart (j/n)?#off("b")# 
+ 
+Wenn Sie vor dem Benutzer die 'gib kommando:'-Ebene verbergen wollen, können
+Sie das System durch Tippen eines <j> so einstellen, daß sich sofort nach Ein­
+richten einer Sohntask das Menusystem meldet. Für den Anfänger kann das die
+Arbeit durchaus erleichtern. Wenn Sie das nicht möchten, tippen Sie hier ein <n>.
+Haben Sie die Frage mit <j> beantwortet, so erscheint noch eine (letzte) Abfrage: 
+ 
+#on("b")#Frage 4:#off("b")# #on("b")#Mit automatischem Löschen (j/n)?#off("b")# 
+ 
+Durch Tippen eines <j> legen Sie fest, daß in den Sohntasks nach Verlassen des
+Menus die jeweilige Task automatisch gelöscht wird. Tippen Sie ein <n>, dann wird
+nach Verlassen des Menus angefragt, ob die Task gelöscht werden soll. Wird die Frage
+bejaht, wird gelöscht - sonst wird die Task abgekoppelt (break) und kann durch
+'continue' wieder angekoppelt werden. 
+ 
+#on("b")#Anmerkung:#off("b")# In Tasks, in denen Sie die Frage nach dem Direktstart mit <j> beant­
+wortet haben, sollte nicht das Kommando 'monitor' gegeben werden, da Sie durch
+dieses Kommando auch diese Task zu einer Task machen, die sich direkt mit dem
+Menu meldet und ggf. bei Verlassen des Menus automatisch gelöscht wird! 
+ 
+ 
+Nachdem der EUMEL-Eingangsbildschirm zu sehen ist, können Sie nun #on("b")#gs-Waren­
+haus#off("b")# starten. Nehmen wir an, die Task 'WARENHAUS' sei Hauptstellen-Task. Sie ist
+damit automatisch Managertask, Sie können also Sohntasks anmelden: 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+ 
+#off("b")# 
+  -->     gib supervisor kommando: 
+#on("b")# 
+          begin ("Test","WARENHAUS") <RETURN> 
+#off("b")# 
+ 
+Statt 'Test' können Sie der Sohntask natürlich auch einen beliebigen anderen Namen
+geben. Wenn Sie einen Direktstart eingerichtet haben, erscheint nun sofort das
+#on("b")#gs-DIALOG#off("b")#-Emblem. 
+ 
+                                           +------------------------+
+                                           |   gs-DIALOG            |
+                                  +---------------------------+     |
+                                  |  Version 1.1              |     |
+                            +-----------------------------+   |     |
+                            | (C) 1987/88 Eva Latta Weber |   |     |
+                  +-------------------------------+       |   |-----+
+                  | (C) 1988 ERGOS GmbH           |       |   |
+                  |                               |       |---+
+         +------------------------------+         |       |
+         |    gggggggg     ssssssss     |         |-------+
+         |   ggg          sss    sss    |         |
+         |  ggg           sss           | --------+
+         |  ggg      gggg  ssssssss     |
+         |  ggg       ggg        sss    |
+         |   ggg      ggg        sss    |
+         |    gggggggggg  sssssssss     |
+         +------------------------------+
+ 
+               W A R E N H A U S 
+ 
+                   Filiale 1 
+#off("b")# 
+Andernfalls erscheint 
+ 
+#on("b")# 
+          gib kommando: 
+#off("b")# 
+ 
+Mit dem Kommando 
+ 
+          #on("b")#warenhaus <RETURN>#off("b")# 
+ 
+starten Sie #on("b")#gs-Warenhaus#off("b")# und erhalten zunächst ebenfalls das obige Emblem auf
+dem Bildschirm. Links unten sehen Sie, unter welcher Filialnummer diese Task nun
+von #on("b")#gs-Warenhaus#off("b")# geführt wird. Diese Nummer ist identisch mit der Kanalnummer,
+unter der das EUMEL-System Ihren Arbeitsplatz verwaltet. 
+ 
+Kurze Zeit später erscheint das WARENHAUS-Eingangsmenu. Wie Sie nun weiter mit
+#on("b")#gs-Warenhaus#off("b")# arbeiten können, erfahren Sie in Kapitel 5. 
+ 
+ 
+ 
+#on("b")#3.4  Einrichten mehrerer Hauptstellen#off("b")# 
+ 
+Wir gehen hier davon aus, daß Sie die Installation von #on("b")#gs-Warenhaus#off("b")# gemäß den
+Beschreibungen in Kapitel 3.3 bereits durchgeführt und dabei die Frage 2 ("Soll diese
+Task Warenhaus-Hauptstelle sein (j/n)?") mit 'nein' beantwortet haben. (Falls Sie
+Frage 2 mit 'ja' beantwortet haben und nun den Hauptstellen-Status der Task wieder
+rückgängig machen wollen, so lesen Sie zunächst in Kapitel 7 nach.) 
+ 
+Die Task, in der die Installation stattfand (wir nehmen weiterhin an, daß sie den
+Namen 'WARENHAUS' hat), wurde automatisch zur Managertask, das heißt, daß
+Söhne von ihr eingerichtet werden können. Bevor Sie in diesem Fall das Programm
+nutzen können, müssen Sie nun noch mindestens eine Sohntask zur Hauptstelle
+machen. Gehen Sie dabei folgendermaßen vor: 
+ 
+#on("b")# 
+          <SV>           (Supervisor - Taste) 
+ 
+#off("b")# 
+  -->     gib supervisor kommando: 
+#on("b")# 
+          begin ("Hauptstelle A","WARENHAUS") <RETURN> 
+#off("b")# 
+ 
+  -->     gib kommando: 
+ 
+ 
+Mit dem Kommando 
+ 
+#center##on("b")#warenhaus hauptstelle (TRUE)   <RETURN>#off("b")# 
+ 
+wird die Task 'Hauptstelle A' zur Warenhaus-Hauptstelle. 
+ 
+Zu beantworten sind dabei eine oder zwei Fragen; es sind dieselben, die auftauchen,
+wenn bei der Abfrage 'Soll diese Task Warenhaus-Hauptstelle sein (j/n)?' ein <j>
+getippt wird. Lesen Sie deshalb nun weiter in Kapitel 3.3 bei der Frage 3: 'Mit Direkt­
+start (j/n)?'. 
+ 
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-4 b/doc/warenhaus/gs-Warenhaus-4
new file mode 100644
index 0000000..2c5d7dc
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-4
@@ -0,0 +1,378 @@
+limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (11)# 
+#headodd# 
+#center#gs-Warenhaus#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Warenhaus
+ 
+#end# 
+#center#1 
+ 
+#center# #on("b")#4  Anschluß eines Codekartenlesers#off("b")# 
+ 
+ 
+Ein 'echter' Scanner oder Barcodeleser ist als automatisches Lesegerät für den Ein­
+satz im Unterricht nicht geeignet und kann unter EUMEL/ELAN unseres Wissens nach
+auch nicht angesteuert werden. #on("b")#gs-Warenhaus#off("b")# benutzt stattdessen (ebenso wie die
+Soester Software) den von der Firma AKTRONIC vertriebenen Codekartenleser für
+einfache 8-Bit-Lochkarten (siehe Anhang). 
+ 
+Die Verwendung eines Codekartenlesers ist für die Bedienung des Programms zwar
+nicht unbedingt notwendig, bietet jedoch beim Einsatz von #on("b")#gs-Warenhaus#off("b")# im Unter­
+richt neben den didaktischen Hintergründen (Modell für Scanner-Kasse) auch noch
+mancherlei Vorteile bezüglich des "Datenschutzes" (Änderungen an Kunden- oder
+Artikeldaten sowie Zugriffe auf Auskunftsfunktionen nur mit entsprechender Code­
+karte möglich), so daß sein Anschluß sehr empfohlen werden muß. 
+ 
+Allerdings ist solch ein Gerät nur mittels eines (relativ teuren) Interface-Systems
+anschließbar, dessen Anschaffung sich nur lohnt, wenn das System auch sonst noch
+zum Messen, Steuern, Regeln (= "Prozeßdatenverarbeitung", "PDV") im Unterricht
+genutzt wird. (#on("b")#ERGOS#off("b")# bietet mit #on("b")#"gs-Prozess"#off("b")# auch ein Programmpaket zur PDV
+unter EUMEL/ELAN an!) 
+ 
+ 
+ 
+#on("b")#4.1  Hardware-Voraussetzungen#off("b")# 
+ 
+Der Codekartenleser wird an einen Steckplatz des Interface-Systems MODUL-BUS der
+Firma AKTRONIC angeschlossen, wobei ein Einzel- oder Mehrfachsteckplatz mit
+Kombi- oder E/A-Karte oder eine Compact-Box benutzt werden können. 
+ 
+Da Eingaben von externen Geräten unter EUMEL in der Regel nur über eine serielle
+Schnittstelle möglich sind, benötigt man neben dem Kartenleser und dem MODUL-
+#page# 
+BUS-Steckplatz noch einen 'Adapter', der die parallelen Signale des MODUL-BUS-
+Systems in serielle Signale wandelt, die der Computer über eine serielle Schnittstelle
+(auch RS232- oder V24-Schnittstelle genannt) empfangen kann. Für erfahrene
+Elektronik-Bastler ist das Erstellen solch eines Adapters sicher eine lösbare Aufgabe,
+unter den fix und fertig kaufbaren Geräten haben wir allerdings nur zwei geeignete
+gefunden: das 'Multifunktionale Interface' (kurz: MUFI) der Firma BICOS und den
+'RS232-Adapter für das MODUL-BUS-System' der Firma AKTRONIC. Diese beiden
+Geräte werden auch von #on("b")#gs-Warenhaus#off("b")# unterstützt. 
+ 
+Die erforderliche Hardware-Konstellation stellt sich im Überblick also folgender­
+maßen dar: 
+ 
+#on("b")#
+   Computer <----> Adapter <----> Interface <----> Kartenleser 
+ 
+   (mit se-        ('MUFI'        ('MODUL- 
+    rieller          oder           BUS'- 
+    Schnitt-        'AKTRONIC-      Steck- 
+    stelle)          Adapter')      platz) 
+#off("b")# 
+ 
+ 
+#on("b")#4.2  Verwendung des MUFI#off("b")# 
+ 
+Das MUFI ist speziell für die Arbeit in einem Mehrplatz-System entwickelt worden. Es
+benötigt keine zusätzliche serielle Schnittstelle am Rechner, sondern kann einfach
+zwischen Rechner und Terminal 'in den Terminalkanal gesteckt' werden, sodaß man
+von diesem Terminal aus optimal auf das Interface-System zugreifen kann. Im Ideal­
+fall sollte jeder Arbeitsplatz mit der oben genannten Hardware ausgestattet sein, was
+aber momentan sicher nicht für jede Schule finanzierbar ist. Haben Sie zunächst nur
+ein (oder wenige) MUFI(s) zur Verfügung und möchten von verschiedenen Terminals
+(abwechselnd) auf ein Interface-System zugreifen oder verfügen Sie gar nicht über
+ein Terminal, sondern nur über einen Monitor (z.B. bei IBM-Kompatiblen), so
+können Sie das MUFI auch 'als Endgerät' an einer separaten seriellen Schnittstelle
+nutzen. 
+#page# 
+Für den Betrieb in einem Terminalkanal sollte das MUFI über eine sog. "Schnitt­
+stellen-Automatik" verfügen, die verhindert, daß das MUFI in ausgeschaltetem
+Zustand oder mit abgezogenem Netzstecker den Datenfluß vom Rechner zum
+Terminal unterbricht. Diese sehr sinnvolle Automatik wird von BICOS #on("b")#nicht#off("b")#
+standardmäßig eingebaut. Sie sollten bei eventuellen Bestellungen darauf achten. 
+ 
+ 
+#on("b")#4.2.1  Einstellungen am MUFI#off("b")# 
+ 
+Gleichgültig ob Sie das MUFI 'im Terminalkanal' oder 'als Endgerät' benutzen,
+müssen Sie zunächst am MUFI einige Einstellungen per DIP-Schalter im Inneren des
+MUFI vornehmen. Ziehen Sie dazu aber auf alle Fälle den Stecker aus der Steckdose!
+Lösen Sie dann die 4 Schrauben an der Unterseite des Gehäuses, heben das Oberteil
+vorsichtig ab und legen es neben das Unterteil, sodaß die Kabelverbindungen
+zwischen Unter- und Oberteil nicht belastet werden. 
+ 
+          +---------------------------------------------------+
+          |    +-------+   +------------+                     |
+          |    |       |   |            |        +---------+  |
+          |    +-------+   |            |        | DIP-    |  |
+          |    +-------+   |            |        | Schalter|  |
+Rück-     |    |       |   |            |        +---------+  |  Vorder-
+seite     |    +-------+   |            |   +--------------+  |  seite
+          |    +-------+   |  SCN68000  |   |              |  |
+          |    |       |   |            |   +--------------+  |
+          |    +-------+   |            |                     |
+          |    +-------+   |            |                     |
+          |    |       |   |            |                     |
+          |    +-------+   +------------+                     |
+          +---------------------------------------------------+
+ 
+ 
+ 
+#center#Abb.1:  MUFI geöffnet 
+#page# 
+Die kleine Plastikbox mit den DIP-Schaltern trägt die folgende Aufschrift: 
+ 
+#center##on("b")#O N   
+#center#1 2 3 4#off("b")# 
+ 
+Heben Sie den Deckel mit Hilfe eines kleinen Schraubendrehers o.ä. an der rechten
+Seite leicht an und klappen Sie ihn nach links um. Sie können nun die 4 DIP-
+Schalter sehen. 
+ 
+              +---------------------------------------+
+              |  +-----+  +-----+  +-----+  +-----+   |
+              |  |+++++|  |     |  |     |  |     |   |
+              |  |+++++|  |     |  |     |  |     |   |   ON
+              |  |+++++|  |     |  |     |  |     |   |
+              |  |+++++|  |     |  |     |  |     |   |
+              |  |     |  |     |  |     |  |     |   |
+              |  |     |  |     |  |     |  |     |   |
+              |  |     |  |     |  |     |  |     |   |
+              |  |     |  |+++++|  |+++++|  |+++++|   |
+              |  |     |  |+++++|  |+++++|  |+++++|   |
+              |  |     |  |+++++|  |+++++|  |+++++|   |  OFF
+              |  |     |  |+++++|  |+++++|  |+++++|   |
+              |  +-----+  +-----+  +-----+  +-----+   |
+              +---------------------------------------+
+
+                   1         2        3        4
+
+#center#Abb.2:  Mögliche DIP-Schalter-Stellung beim MUFI 
+ 
+   Dabei haben die DIP-Schalter folgende Bedeutung: 
+ 
+   1  ON   :    Modulbusbetrieb 
+      OFF  :    Parallelportbetrieb 
+   2  ON   :    RTS/CTS-Hardware-Handshake 
+      OFF  :    XON/XOFF-Protokoll 
+   3  ON   :    9600 Baud 
+      OFF  :    19200 Baud 
+   4  ON   :    Even Parity 
+      OFF  :    No Parity 
+ 
+In jedem Fall muß der DIP-Schalter 1 in Stellung #on("b")#ON#off("b")# gebracht werden. 
+#page# 
+Wenn Sie das MUFI im Terminalkanal betreiben wollen, müssen Sie die anderen
+Einstellungen so vornehmen, daß sie zu der Konfiguration des Terminals passen (vgl.
+auch Kapitel 4.4). Beträgt die Übertragungsrate 19200 Baud, so sollten Sie unbedingt
+mit dem XON/XOFF-Protokoll arbeiten - es sei denn, das Terminal unterstützt
+RTS/CTS! Wenn Sie das MUFI an einer separaten seriellen Schnittstelle als Endgerät
+betreiben wollen, #on("b")#muß#off("b")# der Datenaustausch mit dem RTS/CTS-Protokoll abgewickelt
+werden (Schalter 2 auf 'ON'!). Vergewissern Sie sich, daß Ihr Schnittstellen-Kabel
+auch darauf ausgelegt ist! Nach dieser Einstellung der DIP-Schalter ist das MUFI
+betriebsbereit. Fügen Sie die beiden Gehäuseteile wieder zusammen und ver­
+schrauben Sie sie wieder. 
+ 
+ 
+#on("b")#4.2.2  MUFI im Terminalkanal#off("b")# 
+ 
+Um das MUFI in den Terminalkanal einbauen zu können, müssen Sie zunächst am
+Terminal die Zuleitung vom Rechner lösen. Auf der Rückseite des MUFIs befinden
+sich zwei Stecker, die mit V24/1 und V24/2 bezeichnet sind. Stecken Sie an Stecker
+V24/2 das Kabel, das ursprünglich vom Computer zum Terminal führte. Sie
+benötigen jetzt noch ein weiteres (kurzes) V24-Kabel, um das MUFI mit dem
+Terminal zu verbinden. Dieses wird einerseits auf Stecker V24/1 am MUFI gesteckt
+und andererseits auf den Stecker am Terminal, von dem Sie das ursprüngliche Kabel
+zwischen Rechner und Terminal abgezogen haben. 
+ 
+          +--------------------------+
+          | +----------------------+ |
+          | |  V24/1       V24/2   | |
+          | |    |           |     | |
+          | +----|-----------|-----+ |
+          +------|-----------|-------+
+                 |           |
+                 |           |
+   ZUM     <-----+           +----->   ZUM
+   TERMINAL                            COMPUTER
+
+
+#center#Abb.3:  Einbau des MUFIs in den Terminalkanal 
+#page# 
+Die Verschaltung der V24-Kabel ist in der Bedienungsanleitung zum MUFI erläutert,
+ggf. können Sie entsprechende Kabel von der Firma BICOS beziehen. 
+ 
+Wenn alle Kabelverbindungen gesteckt sind, sollten Sie auf alle Fälle erst einmal #on("b")#bei
+ausgeschaltetem MUFI#off("b")# prüfen, ob das Terminal sich noch bedienen läßt. Wenn dieses
+keine Reaktion mehr zeigt, obwohl es vorher (ohne MUFI) reibungslos funktioniert
+hat, dann haben Sie entweder ein MUFI ohne "Schnittstellen-Automatik" vor sich
+(vgl. Kapitel 4.2, Seite 15), oder an den Kabelverbindungen stimmt irgendetwas nicht.
+In diesem Fall sollten Sie noch einmal alle Anschlüsse und evtl. auch die interne
+Verschaltung der Kabel überprüfen. 
+ 
+Schalten Sie dann das MUFI ein. Bei ebenfalls eingeschaltetem Terminal können nun
+einige Zeichen auf dem Bildschirm erscheinen, dieser Effekt ist normal. Funktioniert
+Ihr Terminal bei eingeschaltetem MUFI reibungslos, so sind alle Einstellungen richtig
+und Sie brauchen erst bei Kapitel 4.5 weiterzulesen. Andernfalls studieren Sie Kapitel
+4.4 unter Beachtung von Kapitel 4.2.1! 
+ 
+ 
+#on("b")#4.2.3  MUFI als Endgerät#off("b")# 
+ 
+Wenn Sie das MUFI als Endgerät an einer separaten seriellen Schnittstelle betreiben
+wollen, dann stecken Sie das vom Computer kommende Kabel auf den mit V24/2
+bezeichneten Stecker des MUFI. 
+ 
+Damit ein einwandfreier Betrieb gewährleistet ist, sollten Sie einen sog. 'Kurzschluß­
+stecker' auf den dann freien Stecker V24/1 des MUFIs stecken. Haben Sie einen
+solchen nicht zur Hand, können Sie auch zwei provisorische Drahtbrücken einsetzen:
+Verbinden Sie mit zwei kleinen Drähten einmal Pin (Öffnung) 2 mit Pin 3 und
+außerdem Pin 4 mit Pin 5. 
+ 
+Die Anpassung 'gs-Warenhaus 0: mit Kartenleser an MUFI als Endgerät' unterstützt
+standardmäßig nur den Betrieb von #on("b")#einem#off("b")# MUFI als Endgerät. Wie Sie vorgehen
+müssen, wenn Sie mehrere MUFIs in dieser Betriebsart benutzen wollen, erfahren Sie
+in Kapitel 7. 
+#page# 
+#on("b")#4.3  Verwendung des AKTRONIC-Adapters#off("b")# 
+ 
+Im Gegensatz zum MUFI ist der AKTRONIC-Adapter #on("b")#nicht#off("b")# für den Einbau in einen
+Terminalkanal geeignet, sondern kann nur als Endgerät an einer separaten seriellen
+Schnittstelle betrieben werden. Bevor Sie den Adapter an eine serielle Schnittstelle an­
+schließen, sollten Sie noch die eingestellte Baud-Rate überprüfen und gegebenenfalls
+neu einstellen. 
+ 
+Öffnen Sie dazu das Gehäuse des Adapters, indem Sie die vier Schrauben an der
+Unterseite lösen. Drehen Sie den Adapter so vor sich, daß die 25-polige D-Sub­
+miniaturbuchse von Ihnen weg zeigt. Vorn rechts sind dann zwei parallele 8-polige
+Pfostensteckerleisten sichtbar. 
+ 
+#center#25-pol. D-Subminiatur-Stecker 
+ 
+                  +---------------+
+                  |               |
+              +---+               +---+
+              | +------+              |
+              | |      |              |
+              | |      |              |
+              | |      |              |
+              | |      |              |
+              | +------+              |
+              | +------+              |
+              | |      |    +-------+ |
+              | +------+    |       | |
+              | +------+    +-------+ |
+              | |      |    +-------+ |
+              | +------+    |     <-|---------Jumperleiste
+              |             +-------+ |
+              +---+               +---+
+                  |   Baudrate    |
+                  +---------------+
+
+
+#center#Abb.4:  AKTRONIC-Adapter geöffmet 
+#page# 
+Auf einem Pfostensteckerpaar steckt ein 'Jumper', der gegebenenfalls (passend zu
+der Schnittstellen-Konfiguration im Computer, vgl. Kapitel 4.4) umgesteckt werden
+muß. 
+ 
+                            +---------+
+                            | ζ    ζ  |     300 
+                            | ζ    ζ  |     600 
+                            | ζ    ζ  |    1200 
+                            | ζ    ζ  |    2400 
+                            | ζ    ζ  |    4800 
+                            | ζ    ζ  |    9600 
+               Jumper     > | ζ    ζ  |   19200 
+                            | ζ    ζ  |   38400 
+                            +---------+
+                                          Baudrate 
+ 
+ 
+#center#Abb.5:  Mögliche Jumperposition beim AKTRONIC-Adapter 
+ 
+ 
+Am Adapter ist ein Kabel mit 25-poligem D-Subminiaturstecker bereits fest montiert.
+Sollte der Stecker nicht an Ihren Rechner passen, so müßten Sie ein entsprechendes
+Adapterkabel basteln oder kaufen. 
+ 
+Die Anpassung 'gs-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter' unterstützt
+standardmäßig nur den Betrieb von #on("b")#einem#off("b")# Adapter. Wie Sie vorgehen müssen, wenn
+Sie mehrere dieser Adapter benutzen wollen, erfahren Sie in Kapitel 7. 
+ 
+ 
+#on("b")#4.4  Konfiguration der seriellen Schnittstelle#off("b")# 
+ 
+Sie müssen nun noch dafür Sorge tragen, daß die Einstellungen am MUFI bzw. am
+AKTRONIC-Adapter mit den Einstellungen im Computer übereinstimmen. 
+#page# 
+Koppeln Sie dazu die Task 'configurator' an Ihr Terminal an (mit 'continue
+("configurator") <RETURN>') und geben Sie dann das Kommando 'configurate
+<RETURN>'. Für alle vorhandenen Kanäle werden Sie nun nacheinander gefragt,
+ob Sie eine Konfiguration vornehmen wollen. Bei den "interessanten" Kanälen ant­
+worten Sie mit 'ja' (<j>). Wollen Sie sich nur die aktuelle Konfiguration ansehen, so
+beantworten Sie alle weiterhin gestellten Fragen zu diesem Kanal mit 'ja' (<j>),
+dann bleibt die aktuelle Einstellung erhalten. (Der Konfigurationsdialog ist im
+EUMEL-Systemhandbuch auf den Seiten 6 - 8 detailliert beschrieben.) 
+ 
+Benutzen Sie ein MUFI, so müssen auf alle Fälle #on("b")#8 Datenbits#off("b")# und #on("b")#1 Stopbit#off("b")# einge­
+stellt sein und außerdem je nach DIP-Schalter-Stellung im MUFI (vgl. Kapitel 4.2.1)
+9600 oder 19200 Baud sowie 'no parity' oder 'even parity'. 
+ 
+Benutzen Sie das MUFI im Terminalkanal, so müssen Sie bei einer eventuellen
+Änderung der Konfiguration an diesen Stellen auch das entsprechende Terminal auf
+diese Werte einstellen! 
+ 
+Bei der Verwendung des MUFIs als Endgerät muß der Kanal, an den das MUFI ange­
+schlossen wird, darüberhinaus unbedingt auf die Betriebsarten 
+ 
+#center#transparent  und  RTS/CTS-Protokoll 
+ 
+eingestellt werden. 
+ 
+Verwenden Sie einen AKTRONIC-Adapter, so müssen für den entsprechenden Kanal
+folgende Konfigurationsmerkmale eingestellt werden: 
+ 
+#center#transparent, 8 Bit, 2 Stopbit, #on("b")#kein#off("b")# Protokoll 
+ 
+Die Baud-Rate ist gemäß der Jumper-Position im Adapter (vgl. Kapitel 4.3) einzu­
+stellen. 
+ 
+ 
+ 
+#on("b")#4.5  Verbindung der Hardware-Komponenten#off("b")# 
+ 
+Der Anschluß des Kartenlesers an den MODUL-BUS-Steckplatz ist denkbar einfach:
+Stecken Sie den 8-poligen Platinenstecker des Codekartenlesers in die Buchse des
+Digital-Einganges der Steckkarte bzw. Compact-Box und den 3-poligen Platinen­
+stecker in die passende Spannungsversorgungsbuchse (12 V) am Steckplatz bzw. auf
+der Compact-Box, fertig. Bei eingeschalteter Betriebsspannung muß nun der Code­
+kartenleser beleuchtet sein. (Falls Sie einen Mehrfachsteckplatz benutzen, benötigen
+Sie ein passendes Netzteil für diesen Steckplatz! Achten Sie auch darauf, daß in
+diesem Fall die Kombi- oder E/A-Karte in Steckplatz (Slot) 1 installiert ist.) 
+ 
+Nun müssen Sie noch die Verbindung zu dem verwendeten Adapter herstellen. Dabei
+ist es gleichgültig, ob Sie eine Compact-Box, einen Einzel- oder einen Mehrfachsteck­
+platz benutzen, denn alle diese Geräte verfügen über ein Anschlußkabel mit dem
+gleichen 25-poligen Stecker. 
+ 
+Den AKTRONIC-Adapter können Sie damit direkt an den Steckplatz anschließen,
+denn er verfügt bereits über eine entsprechende 25-polige Buchse. Hier müssen Sie
+dann nur noch die Stromversorgung des Adapters sichern, indem Sie das Kabel mit
+dem 3-poligen Platinenstecker in die passende Spannungsversorgungsbuchse (12 V)
+am Steckplatz oder auf der Compact-Box stecken. (Damit Codekartenleser und
+Adapter hier gleichzeitig versorgt werden können, ist in den Stecker eine Verzweigung
+eingebaut.) 
+ 
+Für das MUFI benötigen Sie ein weiteres Kabel, das an einem Ende einen 36-poligen
+Centronics-Stecker besitzt und an dem anderen einen 25-poligen D-Subminiatur­
+stecker (von der Firma BICOS zu beziehen). 
+ 
+Zum Ausprobieren des Kartenlesers benutzen Sie am besten die Menupunkte
+'Dezimalwert lesen' und 'Bitmuster lesen' unter dem Oberbegriff 'Kommandos' des
+Warenhaus-Menus. Eine Beschreibung dieser Punkte finden Sie in Kapitel 5.4. 
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-5 b/doc/warenhaus/gs-Warenhaus-5
new file mode 100644
index 0000000..c1164ad
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-5
@@ -0,0 +1,1468 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (20)# 
+#headodd# 
+#center#gs-Warenhaus#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Warenhaus 
+ 
+#end# 
+#center#1 
+ 
+#center##on("b")#5  Beschreibung der Menufunktionen#off("b")# 
+ 
+ 
+Nach Aufruf meldet sich #on("b")#gs-Warenhaus#off("b")# zunächst mit dem #on("b")#gs-DIALOG#off("b")#-Emblem
+(vgl. Kapitel 3.3). Kurze Zeit später erscheint das WARENHAUS-Eingangsmenu auf
+dem Bildschirm: 
+ 
+  +------------------------------------------------------------------------+
+  | WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv|
+  |------------------------------------------------------------------------|
+  |    |  b  Befehlsvorrat  |                                              |
+  |    | ------------------ |                                              |
+  |    |  a  Artikeldaten   |                                              |
+  |    |  k  Kundendaten    |                                              |
+  |    +--------------------+                                              |
+  |                                                                        |
+  |                                                                        |
+  |                                                                        |
+  |------------------------------------------------------------------------+
+  |                                                                        |
+  |  Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
+  +------------------------------------------------------------------------+
+
+#off("b")# 
+ 
+ 
+Bevor wir Ihnen die Bedeutung der einzelnen Menu-Punkte erklären, geben wir erst
+noch einige grundsätzliche Hinweise zur Bedienung des Menus für diejenigen Leser,
+die im Umgang mit Menus unter #on("b")#gs-DIALOG#off("b")# nicht geübt sind. 
+ 
+ 
+ 
+#on("b")#5.1  Kurzhinweise zur Bedienung des Menus#off("b")# 
+ 
+Die Bedienung des Menus ist sehr einfach. Eine ausführliche Beschreibung dazu
+finden Sie in den Unterlagen zum Programmsystem #on("b")#gs-DIALOG#off("b")#. An dieser Stelle
+sollen nur die wesentlichen Bedienungsvorgänge beschrieben werden. 
+#page# 
+-  Mit der Tastenfolge <ESC><?> können Sie sich Informationen zur Bedienung
+   des Menusystems in das Menu einblenden lassen 
+ 
+-  Mit den Pfeiltasten <rechts> und <links> können Sie zwischen den "Ober­
+   begriffen" in der Kopfzeile wählen. Der aktuelle Oberbegriff ist jeweils invers
+   dargestellt. Das ausgeklappte 'Pull-Down-Menu' bezieht sich auf diesen invers
+   dargestellten Oberbegriff. 
+ 
+-  Mit den Pfeiltasten <hoch> und <runter> können Sie zwischen den Menu­
+   funktionen wählen, die Ihnen im aktuellen Pull-Down-Menu zur Auswahl ange­
+   boten werden. Die aktuell angewählte Menufunktion wird jeweils invers darge­
+   stellt. Die Trennlinien, die in einigen Pull-Down-Menus sichtbar sind, dienen nur
+   der optischen Untergliederung; sie können nicht angewählt werden und werden
+   deshalb automatisch übersprungen. Die einzelnen Menupunkte sind "zyklisch
+   miteinander verknüpft", das heißt, man gelangt vom untersten Menupunkt
+   wieder zum obersten und umgekehrt. Menupunkte, vor denen ein Minuszeichen
+   steht ('-'), sind (zur Zeit) nicht aktivierbar; auch sie können nicht angewählt
+   werden und werden einfach übersprungen. 
+ 
+-  Durch Tippen der Fragezeichentaste (<?>) können Sie sich jeweils zur
+   aktuellen Menufunktion (invers im Pull-Down-Menu) Informationen in das Menu
+   einblenden lassen. 
+ 
+-  Um eine Menufunktion ausführen zu lassen, bewegen Sie sich mit den Pfeiltasten
+   auf die gewünschte Menufunktion im aktuellen Pull-Down-Menu und tippen
+   dann die <RETURN>-Taste. Steht vor dem gewünschten Menupunkt ein
+   einzelner Buchstabe oder eine Ziffer, so kann durch Tippen der entsprechenden
+   Taste diese Menufunktion dadurch direkt aufgerufen werden. Sobald eine Menu­
+   funktion aufgerufen worden ist, erscheint davor ein Stern ('*'). Daraus können
+   Sie entnehmen, daß das System bereits den Auftrag ausführt. 
+ 
+-  An verschiedenen Stellen werden Fragen an Sie gerichtet, die Sie mit 'ja' oder
+   'nein' beantworten müssen. Tippen Sie dazu entsprechend der Entscheidung die
+   Taste <j> (für 'ja') bzw. <n> (für 'nein'). 
+ 
+-  Werden Ihnen vom Menu aus Dateinamen zur Auswahl angeboten, so können Sie
+   den auf dem Bildschirm sichtbaren Pfeil vor den gewünschten Namen
+#page# 
+   positionieren. Mit den Tasten <x> oder <RETURN> können Sie den Namen
+   ankreuzen. Ist die Auswahl mehrerer Dateinamen möglich, so können Sie den
+   Vorgang wiederholen. Mit den Tasten <o> oder <RUBOUT> können Sie auch
+   ein Kreuz vor einem Namen wieder löschen. Daneben gibt es noch einige Tasten­
+   funktionen, die für die Bedienung recht hilfreich sein können. Tippen Sie
+   während der Auswahl die Fragezeichentaste (<?>), so werden Ihnen alle
+   Bedienungsmöglichkeiten auf dem Bildschirm angezeigt. Eine Auswahl, in der
+   mehrere Dateien angekreuzt werden dürfen, wird durch die Tastenfolge
+   <ESC><q> verlassen. Anschließend wird die eingestellte Operation mit den
+   angekreuzten Dateien ausgeführt. Sind Sie versehentlich in eine solche Auswahl
+   gelangt, so können Sie den Vorgang durch die Tastenkombination <ESC><h>
+   abbrechen. 
+ 
+-  An einigen Stellen werden Sie aufgefordert, eine Eingabe zu machen (z.B. einen
+   Dateinamen einzugeben). Wird Ihnen hier ein Vorschlag gemacht, den Sie
+   akzeptieren, so brauchen Sie zur Bestätigung nur die <RETURN>-Taste zu
+   tippen. Gefällt Ihnen der Vorschlag nicht oder wird Ihnen kein Vorschlag
+   gemacht, so machen Sie bitte die gewünschte Eingabe. Zum Schreiben stehen
+   Ihnen alle aus dem Editor bekannten Funktionen zur Verfügung. Mit der Taste
+   <RUBOUT> können Sie Buchstaben löschen, mit <RUBIN> einfügen. Die
+   Eingabe wird durch Tippen der <RETURN>-Taste abgeschlossen. Ist der von
+   Ihnen gewünschte Name schon in Ihrer Task vorhanden und steht in der Fußzeile
+   der Hinweis 'Zeigen: <ESC><z>', dann können Sie sich auch alle vor­
+   handenen Namen zur Auswahl anbieten lassen und durch Ankreuzen den beab­
+   sichtigten Namen auswählen. 
+ 
+-  Ihnen können auch mehrere Alternativen angeboten werden, zwischen denen Sie
+   wählen müssen. In der untersten Zeile eines solchen Kastens, in denen Ihnen die
+   Alternativen auf dem Bildschirm eingeblendet werden, sind die Möglichkeiten
+   aufgeführt, die darüber beschrieben sind. Mit den Pfeiltasten können sie die
+   Markierung auf die gewünschte Alternative positionieren und dann durch die
+   <RETURN>-Taste zur Ausführung bringen. (Manchmal ist das auch durch
+   Tippen der den Alternativen vorangestellten Buchstaben oder Ziffern möglich). 
+#page# 
+-  Durch die Tastenfolge <ESC><q> kann das Menu insgesamt verlassen
+   werden. Damit das nicht versehentlich geschieht, wird jeweils die Frage gestellt,
+   ob Sie das Menu tatsächlich verlassen wollen. Diese Frage beantworten Sie bitte je
+   nach Wunsch mit 'ja' oder 'nein' durch Tippen der Tasten <j> bzw. <n>. 
+ 
+ 
+#on("b")#5.2  Menufunktionen zum Oberbegriff 'Info'#off("b")# 
+ 
+Das auf dem Bildschirm sichtbare Pull-Down-Menu ist bereits oben abgebildet. 
+ 
+#on("b")#b Befehlsvorrat#off("b")# 
+ 
+     Mit dieser Funktion können Sie sich die Befehle, die Ihnen von der jeweils
+     eingestellten Programmierumgebung zur Verfügung gestellt werden, auf dem
+     Bildschirm anzeigen lassen. Anhand dieser Informationen können Sie auch
+     feststellen, ob in dem System, das Ihnen zur Verfügung steht, die 'GRIN-
+     Version' oder die 'ELAN-Version' eingestellt ist. 
+ 
+     Je nach Version gelangen Sie zunächst in eines der folgenden beiden Auswahl­
+     menus: 
+#on("b")# 
+     GRIN-Version: 
+ 
+ 
+                 +-------------------------------------------------+     
+                 |          d   Datei - Bearbeitung                |
+                 |          e   Einkaufen und Auskunft             |
+                 |          k   Kontroll - Strukturen              |
+                 |                                                 |
+                 |          z   Zurück zum Hauptmenü               |
+                 |                                                 |
+                 |    Datei   Kaufen/Auskunft   Kontroll   Zurück  |
+                 |                                                 |
+                 +-------------------------------------------------+
+#off("b")#
+#page#
+#on("b")# 
+     ELAN-Version: 
+ 
+                 +-------------------------------------------------+
+                 |          d   Datei - Bearbeitung                |
+                 |          e   Einkaufen und Auskunft             |
+                 |          s   Sonstige Befehle                   |
+                 |                                                 |
+                 |          z   Zurück zum Hauptmenü               |
+                 |                                                 |
+                 |   Datei   Kaufen/Auskunft   Sonstige   Zurück   |
+                 |                                                 |
+                 +-------------------------------------------------+
+
+#off("b")# 
+ 
+     Von hier aus können Sie zu jedem dort angegebenen Bereich eine Informa­
+     tionstafel abrufen. 
+ 
+     Aus jeder dieser Tafeln gelangen Sie wieder in die Auswahl zurück. Verlassen
+     Sie die Auswahl selbst, gelangen Sie zurück ins Ausgangsmenu. 
+ 
+ 
+#on("b")#a Artikeldaten#off("b")# 
+ 
+     Bei Aktivierung dieses Menupunktes erhalten Sie eine Kurzinformation über
+     Aufbau und Umfang der Artikeldaten: 
+#on("b")# 
+            +-------------------------------------------------------+
+            |    Ein Satz 'Artikeldaten' besteht aus:               |
+            |                                                       |
+            |               Artikelname                             |
+            |               Preis                                   |
+            |               Mindestbestand                          |
+            |            Bestand                                    |
+            |                                                       |
+            |  Es können Daten für maximal 15 Artikel gespeichert   |
+            |  werden. Die zugehörigen Artikelnummern sind 1...15.  |
+            |                                                       |
+            +-------------------------------------------------------+
+
+
+#off("b")# 
+ 
+     In allen Filialen müssen zu einer Artikelnummer stets der Artikelname und
+     Preis identisch sein, Bestand und Mindestbestand können beliebig gewählt
+     werden. Artikeldateien werden nur in den jeweiligen Filialen gehalten und
+     nicht in der Zentrale. 
+#page# 
+     Gegenüber der Soester Warenhaus-Version sind Artikeldaten um den Punkt
+     'Mindestbestand' erweitert worden, weil sich damit unserer Meinung nach eine
+     realistischere Nachbestellung realisieren läßt (vgl. auch Kapitel 5.4, 'Nachbe­
+     stellen'). 
+ 
+     Sollte Ihnen der Umfang des Warensortiments mit maximal 15 verschiedenen
+     Artikeln sehr gering vorkommen, so denken Sie bitte daran, daß die Artikel­
+     daten an jedem Arbeitsplatz erst einmal eingegeben werden müssen, was bei
+     Computer-Anfängern recht lange dauert. Außerdem kommt es nur bei einem
+     genügend kleinen Sortiment zu den methodisch-didaktisch erwünschten
+     Einkaufshäufungen bei bestimmten Produkten. 
+ 
+ 
+#on("b")#k Kundendaten#off("b")# 
+ 
+     Bei Aktivierung dieses Menupunktes erhalten Sie eine Kurzinformation über
+     Aufbau und Umfang der Kundendaten: 
+#on("b")# 
+          +----------------------------------------------------------+
+          |                  Nachname                                |
+          |                  Vorname                                 |
+          |                  Geschlecht                              |
+          |                                                          |
+          |   Es können Daten für maxomal 31 Kunden gespeichert      |
+          |   werden. Die zugehörigen Kundennummern sind 129...159.  |
+          |                                                          |
+          +----------------------------------------------------------+
+#off("b")# 
+ 
+     Die Zuordnung Kundennummer ---> Kunde muß in allen Filialen gleich sein.
+     Kundendateien werden von jeder Filiale und von der Zentrale geführt. 
+ 
+     Gegenüber der Soester Warenhaus-Version sind Kundendaten um die Punkte
+     'Nachname' und 'Geschlecht' erweitert worden, um dem Begriff Kunden#on("b")#daten#off("b")#
+     etwas gerechter zu werden. Die maximale Kundenanzahl von 31 entspricht
+     etwa der Größe einer Klasse. 
+#page# 
+#on("b")#5.3  Menufunktionen zum Oberbegriff 'Eingabeart'#off("b")# 
+ 
+Die Funktionen unter diesem Oberbegriff sind nur dann für Sie interessant, wenn Sie
+einen Codekartenleser verwenden. 
+#on("b")# 
++-------------------------------------------------------------------------+ 
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|-------------+-----------------+-----------------------------------------|
+|             |  *  Anzeigen    |                                         |
+|             | --------------- |                                         |
+|             |  k  Kartenleser |                                         |
+|             |  t  Tastatur    |                                         |
+|             +-----------------+                                         |
+|                                                                         |
+|                                                                         |
+|                                        +------------------------+       |
+|                                        | Die Eingabeart ist auf |       |
+|                                        |                        |       |
+|                                        |          Tastatur      |       |
+|                                        |                        |       |
+|                                        |          eingestellt   |       |
+|                                        +------------------------+       |
+|-------------------------------------------------------------------------|
+|  Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>  |
++-------------------------------------------------------------------------+
+#off("b")# 
+ 
+#on("b")#a Anzeigen#off("b")# 
+ 
+     Es wird die momentan eingestellte Eingabeart angezeigt. Möglich sind die
+     Eingabearten #on("b")#Tastatur#off("b")# und #on("b")#Kartenleser#off("b")#. Die Standardeinstellung ist
+     'Tastatur'! 
+ 
+ 
+#on("b")#k Kartenleser#off("b")# 
+ 
+     Die Eingabeart 'Kartenleser' wird eingestellt. Alle Artikelnummern, Kunden­
+     nummern und sonstige Codenummern (für Auskünfte) können danach nur
+     über den Kartenleser eingegeben werden. 
+#page# 
+     Diese Eingabeart kann nur eingestellt werden, wenn ein Kartenleser mit
+     funktionstüchtigem Interface angeschlossen ist. Sonst erfolgt eine ent­
+     sprechende Fehlermeldung. 
+ 
+     Fehlerfälle: 
+ 
+     - Kein Interface vorhanden! 
+       Ursache: Bei der Installation von #on("b")#gs-Warenhaus#off("b")# wurde angegeben, daß
+                kein Kartenleser benutzt werden soll. 
+ 
+     - Interface meldet sich nicht! 
+       Abhilfe: Überprüfen, ob der Adapter ordnungsgemäß angeschlossen und
+                eingeschaltet ist (vgl. Kapitel 4). Notfalls Eingabeart auf
+                'Tastatur' schalten; wenn ein MUFI verwendet wird, MUFI aus-
+                und nach kleiner Pause wieder einschalten; noch einmal die
+                Eingabe 'Kartenleser' anwählen. 
+ 
+     - TASK für Interface ist besetzt! 
+       (Kann nur beim Betrieb von MUFI als Endgerät oder bei AKTRONIC-Adapter
+        auftreten.) 
+       Abhilfe: Wenn irgendeine andere Task die Eingabeart 'Kartenleser' ein­
+                gestellt hat, dort auf 'Tastatur' umstellen. 
+ 
+     - Interface-Kanal belegt! 
+       (Kann nur beim Betrieb von MUFI als Endgerät oder bei AKTRONIC-Adapter
+        auftreten.) 
+       Abhilfe: Feststellen, welche Task an den Interface-Kanal angekoppelt ist
+                ('taskinfo (2)'), und diese dann abmelden ('break' oder 'end').
+                Die Nummer des Interface-Kanals kann mit dem Befehl 'put
+                (interfacekanal)' erfragt werden. 
+ 
+     - TASK für Interface existiert nicht! 
+       (Kann nur beim Betrieb von MUFI als Endgerät oder bei AKTRONIC-Adapter
+        auftreten.) 
+        Abhilfe: Task löschen; in der Vatertask das Kommando 'init interface­
+                 channel' geben; Task neu anmelden. 
+#page# 
+#on("b")#t Tastatur#off("b")# 
+ 
+     Die Eingabeart 'Tastatur' wird eingestellt. Alle Artikelnummern, Kunden­
+     nummern und sonstige Codenummern (für Auskünfte) können danach nur
+     über die Tastatur eingegeben werden. Ein etwa angeschlossener Codekarten­
+     leser ist bei dieser Einstellung nicht mehr ansprechbar. 
+ 
+ 
+ 
+#on("b")#5.4  Menufunktionen zum Oberbegriff 'Kommandos'#off("b")# 
+ 
+Dieses ist das zentrale Menu für den Benutzer von #on("b")#gs-Warenhaus#off("b")#. Unter diesem
+Oberbegriff finden Sie alle Funktionen, die notwendig sind, um die Abläufe innerhalb
+des Modell-Warenhauses zu simulieren. (Die angebotenen Menufunktionen ent­
+sprechen etwa den "Direktbefehlen" der Soester Software.) 
+#on("b")# 
++-------------------------------------------------------------------------+
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|---------------------+-------------------------------+-------------------|
+|                     |  w   Warendatei bearbeiten    |                   |
+|                     |  k   Kundendatei bearbeiten   |                   |
+|                     |  --------------------------   |                   |
+|                     |  e   Einkaufen                |                   |
+|                     |  --------------------------   |                   |
+|                     |  a   Auskunft einholen        |                   |
+|                     |  n   Nachbestellen            |                   |
+|                     |  --------------------------   |                   |
+|                     |  -   Dezimalwert lesen        |                   |
+|                     |  -   Bitmuster lesen          |                   |
+|                     +-------------------------------+                   |
+|                                                                         |
+|-------------------------------------------------------------------------|
+|    Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>|
++-------------------------------------------------------------------------+
+#off("b")# 
+ 
+Wird im Unterricht kein Kartenleser benutzt, so sind die eingegeben Daten völlig
+ungeschützt. Vor allem bei der Kundendatei muß sichergestellt werden, daß dort
+#page# 
+keine unsinnigen Eintragungen oder Änderungen vorgenommen werden, da alle
+Neueintragungen und Änderungen in dieser Datei auch in der Warenhaus-Zentrale
+wirksam werden und von dort aus auf Anfrage jeder Filiale mitgeteilt werden.
+Korrekturen können dadurch sehr mühsam werden. Natürlich sind ohne Kartenleser
+(und dem damit verbundenen 'Ausweis' Codekarte) auch jederzeit Einkäufe mit jeder
+beliebigen Kundennummer möglich. Auch hier sollten Sie etwaigem Mißbrauch
+vorbeugen. 
+ 
+ 
+#on("b")#w Warendatei bearbeiten#off("b")# 
+ 
+     Hiermit kann die Warendatei der Filiale aufgebaut und verändert werden. Der
+     Bildschirm sieht dabei wie folgt aus: 
+#on("b")# 
++------------------------------------------------------------------------+ 
+|WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|-----------------------------------+------------------------------------|
+|                                   |   Artikelnummer    :  1            |
+|                                   |                                    |
+|                                   |                                    |
+|                                   |   Artikelname      :  Bier (Kasten)| 
+|                                   |                                    |
+|                                   |   Preis            :  16.85        |
+|                                   |                                    |
+|                                   |   Mindestbestand   :  25           |
+|                                   |                                    |
+|                                   |   Bestand          :  20           |
+|                                   |                                    |
+|                                   |                                    |
+|                                   |       Alles richtig ?              |
+|                                   |                                    |
+|                                   |         Ja    Nein                 |
+|-----------------------------------+------------------------------------|
+|  Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++------------------------------------------------------------------------+
+#off("b")# 
+ 
+     Zunächst muß eine Artikelnummer (1...15) eingegeben werden (je nach
+     Einstellung über die Tastatur oder mittels einer Warenkarte über den Code­
+     kartenleser). Unzulässige Artikelnummern werden dabei nicht akzeptiert. 
+#page# 
+     Ist unter dieser Nummer bereits ein Artikel gespeichert, so werden die ent­
+     sprechenden Artikeldaten in dem rechten oberen Bildschirmfenster gezeigt
+     und können dort geändert oder einfach übernommen werden. Gibt es noch
+     keinen Artikel mit dieser Nummer, so sind neue Artikeldaten einzugeben. 
+ 
+     Dieser Vorgang wird solange wiederholt, bis bei der Eingabe der Artikelnummer
+     die Tastenfolge <ESC><q> gedrückt wird. 
+ 
+     Achten Sie darauf, daß in jeder Filiale der zu einer Artikelnummer gehörige
+     Artikel stets denselben Artikelnamen und -preis erhält. Bestand und Mindest­
+     bestand können unterschiedlich sein. 
+ 
+ 
+#on("b")#k Kundendatei bearbeiten#off("b")# 
+ 
+     Hiermit kann die Kundendatei der Filiale aufgebaut und verändert werden.
+     Ähnlich wie bei der Funktion 'Warendatei bearbeiten' erfolgen die Eingaben im
+     rechten oberen Bildschirmfenster. 
+ 
+     Zunächst muß eine Kundennummer (129...159) eingegeben werden (je nach
+     Einstellung über die Tastatur oder mittels einer Kundenkarte über den Code­
+     kartenleser). Unzulässige Kundennummern werden dabei nicht akzeptiert. 
+ 
+     Ist unter dieser Nummer bereits ein Kunde in der Filiale oder in der Zentrale
+     gespeichert, so werden die entsprechenden Kundendaten in dem rechten
+     oberen Bildschirmfenster gezeigt und können dort geändert oder einfach über­
+     nommen werden. Gibt es noch keinen Kunden mit dieser Nummer, so sind
+     neue Kundendaten einzugeben. (Neueingaben und Änderungen werden sofort
+     der Zentrale, aber nicht automatisch den andern Filialen mitgeteilt!) 
+ 
+     Dieser Vorgang wird solange wiederholt, bis bei der Eingabe der Kunden­
+     nummer die Tastenfolge <ESC><q> gedrückt wird. 
+#page# 
+#on("b")#e Einkaufen#off("b")# 
+ 
+     Zunächst wird eine Kundennummer (129...159) erfragt. Wird die Nummer
+     eines Kunden eingegeben, dessen Daten in der Filiale oder Zentrale bereits
+     gespeichert sind, so erscheint im linken Bildschirmfenster der Rechnungskopf
+     mit dem Namen des Kunden. Ist unter der Nummer noch kein Kunde einge­
+     tragen oder wird die Eingabe der Kundennummer durch die Tastenfolge
+     <ESC><q> abgebrochen, so enthält der Rechnungskopf keinen Kunden­
+     namen. 
+ 
+     Das eigentliche Einkaufen erfolgt nun durch die Eingabe von Artikelnummern
+     (1...15). Der zugehörige Artikelname und der Preis werden daraufhin in die
+     Rechnung eingetragen. 
+#on("b")# 
++------------------------------------------------------------------------+
+|WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|----------------------------------+-------------------------------------|
+|    RECHNUNG für Herrn B. Pollok  |  Artikelnummer   :  1               |
+|                                  |                                     |
+|      Bier (Kasten)         16.85 |                                     |
+|      Tageszeitung           0.80 |                                     |
+|      Pflaster               2.39 |                                     |
+|      Mehl                   0.79 |                                     |
+|      Seife                  1.80 |                                     |
+|      Weinbrand             12.75 |                                     |
+|      Zigaretten             3.80 |                                     |
+|      Brot                   2.29 |                                     |
+|      Schallplatte          19.90 |                                     |
+|      Geodreieck             2.35 |-------------------------------------|
+|      Videokassette         12.75 |  Artikelnummer eingeben             |
+|      Schulheft              0.85 |                                     |
+|                                  |  Stoptaste:  <ESC><q>               |
+|----------------------------------+-------------------------------------|
+|    Einkaufen                                                           |
++------------------------------------------------------------------------+
+#off("b")#                                                               |
+ 
+     Dieser Vorgang wird solange wiederholt, bis die Eingabe einer Artikelnummer
+     durch Tippen der Tastenfolge <ESC><q> abgebrochen wird. 
+ 
+     Abschließend wird der Rechnungsgesamtbetrag ausgegeben und gefragt, ob die
+     Rechnung gedruckt werden soll. 
+#page# 
+#on("b")#a Auskunft einholen#off("b")# 
+ 
+     Mit Hilfe dieses Kommandos lassen sich nach Einlesen einer Codenummer (je
+     nach Einstellung über Tastatur oder Codekartenleser) verschiedene Auskünfte
+     über die gespeicherten Daten abrufen. Es können #on("b")#Einzelauskünfte#off("b")# oder
+     #on("b")#Listenauskünfte#off("b")# eingeholt werden. Bei Eingabe einer falschen Nummer wird
+     die Auskunft abgebrochen! 
+ 
+ 
+     #on("b")#Einzelauskünfte:#off("b")# 
+ 
+     Codenummern  1...15 (Artikelnummern): 
+                  Die zugehörigen Artikeldaten werden im rechten oberen Bild­
+                  schirmfenster angezeigt. 
+ 
+     Codenummern  129...159 (Kundennummern): 
+                  Die zugehörigen Kundendaten werden im rechten oberen
+                  Bildschirmfenster angezeigt. 
+ 
+ 
+     #on("b")#Listenauskünfte:#off("b")# 
+ 
+     Hierbei liefern jeweils 3 benachbarte Codenummern von der Art her ähnliche
+     Auskunfts-Listen, die auf Wunsch auch ausgedruckt werden können. Die
+     mittlere Nummer bezieht die Auskünfte stets auf die eigene Filiale; die beiden
+     anderen sind nur effizient, wenn mehrere Filialen angemeldet sind. Dabei
+     werden bei Eingabe der linken Nummer die jeweiligen Daten #on("b")#aller#off("b")# Filialen
+     'aufaddiert' und in #on("b")#einer#off("b")# Gesamtliste ausgegeben. Bei Eingabe der rechten
+     Nummer hingegen werden die jeweiligen Listen von allen angeschlossenen
+     Filialen der Reihe nach abgerufen und #on("b")#hintereinander#off("b")# in eine Datei ge­
+     schrieben, sodaß man eine Zusammenstellung der entsprechenden #on("b")#Einzel#off("b")#-
+     Listen der Filialen erhält: 
+#page# 
+     Codenummern  66, 67, 68: 
+                  Die bisherigen Verkaufszahlen der einzelnen Waren werden
+                  gezeigt; die Listen sind sortiert nach diesen Zahlen ('Ver­
+                  kaufs-Hitlisten'). 
+ 
+     Codenummern  73, 74, 75: 
+                  Nach Eingabe einer Artikelnummer wird eine Liste aller
+                  Käufer dieses Artikels ausgegeben. 
+ 
+     Codenummern  77, 78, 79: 
+                  Diese Codes liefern Kundenlisten der Filialen. 
+ 
+     Codenummern  84, 85, 86: 
+                  Nach Eingabe einer Kundennummer wird eine Liste aller von
+                  diesem Kunden gekauften Artikel ausgegeben. 
+ 
+     Codenummern  89, 90, 91: 
+                  Diese Codes liefern die Lagerbestandslisten der Filialen. Sollte
+                  sich bei der Auskunft '90' herausstellen, daß der Bestand
+                  mehrerer Artikel unter den Mindestbestand abgesunken ist, ist
+                  es sinnvoll, als nächstes den Menupunkt 'Nachbestellen'
+                  anzuwählen (s.u.). 
+#page# 
+     Beispiel: Der Code '90' liefert bei entsprechend eingegebener Warendatei
+               folgende Auskunft: 
+#on("b")# 
+ +------------------------------------------------------------------------+ 
+ |   ............. Auskunft: Filiale 1 ................... Zeile 1        |
+ |                                                                        |
+ |      Lagerübersicht:                                                   |
+ | ---------------------------------------------------------------------- |
+ | ---------------------------------------------------------------------- |
+ |    |  Art.Nr.| Artikelname      |       Preis | Min.Best. | Bestand  | |
+ | ---+---------+------------------+-------------+-----------+----------+ |
+ |    |         |                  |             |           |          | |
+ |    |     1   | Bier (Kasten)    |      16.85  |      25   |     19   | |
+ |    |     2   | Tageszeitung     |       0.80  |      15   |     16   | |
+ |    |     3   | Pflaster         |       2.39  |      14   |     22   | |
+ |    |     4   | Mehl             |       0.79  |      32   |     58   | |
+ |    |     5   | Seife            |       1.80  |      27   |     49   | |
+ |    |     6   | Weinbrand        |      12.75  |      24   |     41   | |
+ |    |     7   | Zigaretten       |          4 +------------+--------+ | |
+ |    |     8   | Brot             |          2 |   Auskunft drucken ?| | |
+ |    |     9   | EMMA             |          3 |                     | | |
+ |    |    10   | Schallplatte     |         19 |      Ja     Nein    | | |
+ |    |    11   | Geodreieck       |          2 +---------------------+ | |
+ |    |         |                  |             |                      | |
+ |    |         |                  |             |                      | |
+ |    |         |                  |             |                      | |
+ |----------------------------------------------------------------------- |
+ |                          | Ändern: <Pfeile>   Bestätigen: <RETURN>     |
+ + -----------------------------------------------------------------------+
+
+#off("b")# 
+ 
+     Hinweis: Nur die zu den jeweils mittleren Codenummern gehörigen Aus­
+              kunftsfunktionen arbeiten mit Daten, die in der eigenen Task
+              gespeichert sind. Bei den übrigen Auskünften müssen Daten aus
+              anderen Filialverwaltungs-Tasks oder der Zentrale geholt werden,
+              so daß die Erstellung solch einer Auskunft recht zeitaufwendig ist.
+              Um zu lange Wartezeiten zu vermeiden, sollten nicht mehrere
+              Filialen gleichzeitig Auskünfte dieser Art einholen. 
+#page# 
+#on("b")#n Nachbestellen#off("b")# 
+ 
+     Auf dem Bildschirm wird eine Bestelliste ausgegeben, die alle Artikel enthält,
+     deren Bestand innerhalb der Filiale den Mindestbestand unterschritten hat. 
+ 
+     Die Nachbestellung ist so bemessen, daß diese Artikel wieder mit ihrem
+     doppelten Mindestbestand vorrätig sind. Die neuen Bestände werden auto­
+     matisch in die Warendatei der Filiale eingetragen. 
+ 
+     Auf Wunsch kann die Bestelliste ausgedruckt werden. 
+ 
+ 
+#on("b")#d Dezimalwert lesen#off("b")# 
+ 
+     Der aktuelle Wert, der vom Codekartenleser gelesen wird, wird (ähnlich wie bei
+     'Bitmuster lesen', s.u.) auf dem Bildschirm ausgegeben, bis <ESC><q>
+     gedrückt wird. Mit Hilfe dieses Kommandos kann man z.B. die Funktion des
+     Codekartenlesers testen und den Zusammenhang zwischen Bitmuster und
+     Dezimalwert klären. 
+ 
+     Dieser Menupunkt ist (ebenso wie der nächste) nur dann aufrufbar, wenn
+     unter #on("b")#Eingabeart#off("b")# der #on("b")#Kartenleser#off("b")# eingestellt ist. 
+ 
+ 
+#on("b")#b Bitmuster lesen#off("b")# 
+ 
+     Dieser Menupunkt ist nur dann aufrufbar, wenn unter #on("b")#Eingabeart#off("b")# der
+     #on("b")#Kartenleser#off("b")# eingestellt ist (vgl. Kapitel 5.3). 
+ 
+     Ist das der Fall, so wird hier das aktuelle Bitmuster, das vom Codekartenleser
+     gelesen wird, auf dem Bildschirm ausgegeben, bis <ESC><q> gedrückt
+     wird. 
+#on("b")# 
++-------------------------------------------------------------------------+
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|-----------------------------------+-------------------------------------|
+|                                   |                                     |
+|                                   |                                     |
+|                                   |      Bitmuster :    0I00III0        |
+|                                   |                                     |
+|                                   |                                     |
+|                                   |                                     |
+|                                   |                                     |
+|                                   |                                     |
+|                                   |                                     |
+|                                   |                                     |
+|                                   |                                     |
+|                                   |                                     |
+|                                   |     Lesen beenden mit <ESC><q>      |
+|                                   +-------------------------------------|
+|                                                                         |
+|    Bitmuster lesen                                                      |
++-------------------------------------------------------------------------+
+#off("b")# 
+ 
+     Ein Bitmuster besteht aus 8 Zeichen (z.B. 'OIOOIIIO'). Dabei zeigt jedes 'I' ein
+     Loch an der entsprechenden Stelle der Codekarte an, die sich gerade im
+     Kartenlesegerät befindet. Dieses Bitmuster entspricht der Dualzahl 01001110
+     (im 'Zweiersystem'); zu ihr gehört die Dezimalzahl 
+#on("b")# 
+ 
+      0 * 128 + 1 * 64 + 0 * 32 + 0 * 16 + 1 * 8 + 1 * 4 + 1 * 2 + 0 * 1 = 78. 
+#off("b")#
+ 
+     Mit Hilfe dieses Kommandos können Sie z.B. die Funktion des Codekarten­
+     lesers testen. Bei voller Beleuchtung aller 8 Sensoren muß das Bitmuster
+     'IIIIIIII' geliefert werden. Decken Sie einige Sensoren mit den Fingern oder
+     einer Lochkarte ab, so muß sich das Bitmuster auf dem Bildschirm ent­
+     sprechend verändern. Ist das nicht der Fall, so liegt ein Fehler vor. 
+ 
+     Prüfen Sie dann erst einmal, ob der Steckplatz mit Strom versorgt wird (Netz­
+     kabel in der Steckdose? Compact-Box mit Netzteil richtig verbunden?) Ist dort
+     alles in Ordnung, so könnte der Fehler noch in der Verbindung zum Adapter
+     liegen. (Steckplatz ordnungsgemäß mit Adapter verbunden? Richtiges Kabel
+     verwendet?) 
+#page# 
+     Sollten Sie auf diese Weise nicht zum Erfolg kommen, so verlassen Sie diesen
+     Menupunkt und wählen noch einmal den Oberbegriff 'Eingabeart' an. Stellen
+     Sie dort die Eingabeart zunächst auf 'Tastatur um' und dann wieder auf
+     'Kartenleser'. Treten hier Fehlermeldungen auf, so lesen Sie in Kapitel 5.3
+     nach. Läßt sich die Umstellung dagegen problemlos vornehmen, so müßte nun
+     auch das 'Bitmuster lesen' wieder funktionieren. 
+ 
+ 
+#on("b")#5.5  Menufunktionen zum Oberbegriff 'Programme'#off("b")# 
+ 
+#on("b")# 
++-------------------------------------------------------------------------+ 
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|---------------------+----------------------+----------------------------|
+|                     |  n  Neu erstellen    |                            |
+|                     |  a  Ansehen/Ändern   |                            |
+|                     |  ------------------  |                            |
+|                     |  s  Starten          |                            |
+|                     |  w  Wiederholen      |                            |
+|                     |  ------------------  |                            |
+|                     |  v  Verzeichnis      |                            |
+|                     |  ------------------  |                            |
+|                     |  l  Löschen          |                            |
+|                     |  d  Drucken          |                            |
+|                     |  ------------------  |                            |
+|                     |  k  Kopieren         |                            |
+|                     |  u  Umbenennen       |                            |
+|                     +----------------------+                            |
+|-------------------------------------------------------------------------|
+|   Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> | 
++-------------------------------------------------------------------------+
+#off("b")# 
+ 
+#on("b")#n Neu erstellen#off("b")# 
+ 
+     Mit dieser Funktion können Sie eine neue Programmdatei anlegen und
+     beschreiben. 
+ 
+     Sie werden zunächst nach einem Namen für die #on("b")#neue#off("b")# Programmdatei gefragt.
+     Geben Sie einen beliebigen Namen (#on("b")#ohne Anführungszeichen (!)#off("b")#) ein und
+#page# 
+     schließen Sie die Eingabe durch <RETURN> ab. Daraufhin wird Ihnen auf
+     dem Bildschirm eine neue Datei zum Beschreiben angeboten. 
+ 
+     Sollte schon eine Programmdatei mit diesem Namen in der Task vorhanden
+     sein, so werden Sie darauf aufmerksam gemacht. 
+ 
+     Sie können sich während des Schreibens die wichtigsten Tastenfunktionen des
+     Editors einblenden lassen. Tippen Sie dazu die Tastenfolge <ESC><?>. Es
+     erscheint dann das folgende Angebot aus dem Sie auswählen können: 
+ 
+#on("b")#                
+                +-----------------------------------------------------+
+                |             Der EUMEL - Editor                      |
+                |                                                     |
+                |      b ... Beschreibung desEditors                  |
+                |      w ... Wichtige Tasten                          |
+                |      p ... Positionieren der Schreibmarke           |
+                |      k ... Korrigieren im Text (Einfügen/Löschen)   |
+                |      m ... Markierte Textpassagen bearbeiten        |
+                |      l ... Lernen im Editor                         |
+                |      a ... Anweisungen im Editor (Kommandodialog)   |
+                |                                                     |
+                |      z ... Zurück in den Schreibmodus               |
+                |                                                     |
+                |      b   w   p   k   m   l   a   z                  |
+                |                                                     |
+                +-----------------------------------------------------+
+#off("b")# 
+     Fehlerfälle: 
+     -  Eine Programm-Datei mit dem vorgeschlagenen Namen existiert schon. 
+ 
+ 
+#on("b")#a Ansehen/ändern#off("b")# 
+ 
+     Mit dieser Funktion können Sie sich Dateien, die schon in Ihrer Task
+     existieren, ansehen oder auch verändern. 
+ 
+     Sie werden zunächst gefragt, ob Sie #on("b")#die zuletzt bearbeitete Programmdatei#off("b")#
+     ansehen bzw. verändern möchten (sofern Sie schon vorher mit #on("b")#gs-Warenhaus#off("b")#
+     in der Task gearbeitet haben). 
+#page# 
+     Bejahen Sie diese Frage, dann wird Ihnen diese Programmdatei zur Bear­
+     beitung angeboten. Verneinen Sie die Frage dagegen, so gelangen Sie in die
+     'Auswahl' (d.h es werden Ihnen alle Programmdateien in der Task zur Auswahl
+     angeboten). Nachdem Sie einen der Namen angekreuzt haben, wird Ihnen die
+     ausgewählte Programmdatei zur Bearbeitung auf dem Bildschirm angeboten. 
+ 
+     Fehlerfälle: 
+     - In der Task existiert noch keine Programmdatei. 
+ 
+ 
+#on("b")#s Starten#off("b")# 
+ 
+     Mit dieser Menufunktion können Sie ein fertiggestelltes Programm übersetzen
+     und ausführen lassen. 
+ 
+     Sie werden zunächst gefragt, ob #on("b")#das zuletzt bearbeitete Programm#off("b")# ausgeführt
+     werden soll. Bejahen Sie die Frage, so wird dieses Programm gestartet; ver­
+     neinen Sie die Frage dagegen, so gelangen Sie in die 'Auswahl'. Nach An­
+     kreuzen des gewünschten Programmnamens wird das ausgewählte Programm
+     ausgeführt. 
+ 
+     Sind im Programm noch Fehler enthalten, so werden das Programm und die
+     Fehlermeldungen gleichzeitig auf dem Bildschirm dargestellt (Paralleleditor)
+     und zur Korrektur angeboten. Für die Programmkorrektur stehen ebenfalls alle
+     Editorfunktionen zur Verfügung. 
+ 
+     Sollte Ihnen beim Programmieren ein Fehler unterlaufen sein (z.B. eine
+     Endlosschleife), so kann mit der Tastenfolge <ESC><h> der Programm­
+     ablauf abgebrochen werden ("Notbremse"). 
+#page# 
+#on("b")#w Wiederholen#off("b")# 
+ 
+     Mit dieser Funktion können Sie den Ablauf des zuletzt ausgeführten
+     Programms wiederholen, ohne daß das Programm neu übersetzt wird. 
+ 
+     Beachten Sie aber bitte, daß Veränderungen am Programmtext, die seit dem
+     letzten Programmlauf vorgenommen wurden, #on("b")#nicht#off("b")# berücksichtigt werden;
+     dazu muß  das Programm erneut mit der Menufunktion 'Starten' übersetzt
+     werden. 
+ 
+     Ist die Wiederholung eines Programmlaufs nicht möglich, so erfolgt ein Hin­
+     weis darauf. 
+ 
+ 
+#on("b")#v Verzeichnis#off("b")# 
+ 
+     Mit dieser Funktion können Sie sich einen Überblick über die in Ihrer Task
+     vorhandenen Programmdateien verschaffen. 
+ 
+     Nach Aufruf dieser Funktion wird eine Liste der Programmdateien auf dem
+     Bildschirm ausgegeben, die sich in Ihrer Task befinden. Da die Liste selbst
+     eine Text-Datei ist, kann Sie mit der Tastenkombination <ESC><q> ver­
+     lassen werden - hierauf wird auch in der letzten Bildschirmzeile hingewiesen.
+     Falls nicht alle Namen auf den Bildschirm passen, können Sie das Fenster mit
+     <HOP><runter> und <HOP><hoch> verschieben. 
+ 
+ 
+#on("b")#Löschen#off("b")# 
+ 
+     Mit dieser Funktion können Sie Programmdateien, die Sie nicht mehr
+     benötigen, die unnötig Platz belegen, löschen. Aber Vorsicht! Die Dateien
+     verschwinden durch diese Funktion unwiederbringlich! 
+ 
+     Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+     Ihrer Task befinden, zur Auswahl angeboten. Hier können Sie die gewünschten
+     Namen ankreuzen. Die Auswahl wird dann durch die Tastenfolge
+     <ESC><q> verlassen. 
+#page# 
+     Für jede einzelne Programmdatei wird noch einmal zur Sicherheit gefragt, ob
+     sie auch tatsächlich gelöscht werden soll. Zur Bestätigung tippen Sie bitte die
+     Taste <j> ('ja') - zur Verhinderung <n> ('nein'). 
+ 
+     Fehlerfälle: 
+     -  In der Task exsitiert noch keine Programmdatei 
+ 
+ 
+#on("b")#d Drucken#off("b")# 
+ 
+     Mit dieser Funktion können Sie Programmdateien über einen angeschlossenen
+     Drucker ausgeben lassen. 
+ 
+     Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+     Ihrer Task befinden, zur Auswahl angeboten. Hier können Sie die gewünschten
+     Namen ankreuzen. Die Auswahl wird dann durch die Tastenfolge
+     <ESC><q> verlassen. 
+ 
+     Die angekreuzten Programmdateien werden anschließend zum Drucker ge­
+     schickt. Der Vorgang wird auf dem Bildschirm protokolliert. 
+ 
+     Fehlerfälle: 
+     -  In der Task existiert noch keine Programmdatei. 
+     -  Der Drucker ist nicht funktionsbereit. 
+     -  Der Drucker wird nicht über die Task 'PRINTER' betrieben. 
+     -  Auf Ihrem System werden die Druckkosten abgerechnet. Sie müssen sich
+        mit einer Codenummer identifizieren. 
+ 
+ 
+#on("b")#k Kopieren#off("b")# 
+ 
+     Mit dieser Funktion können Sie sich eine Kopie einer bereits in der Task
+     vorhandenen Programmdatei anlegen. Das ist z.B. dann sinnvoll, wenn Sie sich
+     einen bestimmten 'Stand' aufbewahren wollen oder wenn Sie ein Programm
+     schreiben wollen, das einem bereits vorhandenen ähnelt. 
+#page# 
+     Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+     Ihrer Task befinden, zur Auswahl angeboten. Nach Ankreuzen eines Namens
+     wird die Auswahl automatisch verlassen. 
+ 
+     Anschließend wird der angekreuzte Name angezeigt und der Name für die
+     Kopie erfragt. Es muß ein Name eingetragen werden, der in dieser Task noch
+     nicht für eine Programmdatei vergeben wurde; ansonsten erfolgt ein Hinweis
+     darauf und es wird nicht kopiert! 
+ 
+     Da man aber oft für die Kopie einen ähnlichen Namen wie für das Original
+     wählt, wird der 'alte' Name vorgeschlagen. Aus genannten Gründen muß er
+     aber verändert werden. Sie können diesen Namen mit den üblichen Editier­
+     funktionen verändern oder mit <HOP><RUBOUT> löschen und ganz neu
+     eingeben. Sie sparen aber eine Menge Tipparbeit, wenn Sie einen langen
+     Namen nur an einer Stelle ändern wollen. 
+ 
+     Fehlerfälle: 
+     -  Eine Programmdatei mit dem gewünschten Namen existiert bereits in der
+        Task. 
+ 
+ 
+#on("b")#u Umbenennen#off("b")# 
+ 
+     Mit dieser Funktion können Sie einer bereits vorhandenen Programmdatei
+     einen neuen Namen geben. 
+ 
+     Nach Aufruf dieser Funktion werden Ihnen alle Programmdateien, die sich in
+     Ihrer Task befinden, zur Auswahl angeboten. Nach Ankreuzen eines Namens
+     wird die Auswahl automatisch verlassen. 
+ 
+     Anschließend wird dieser Name angezeigt und der zukünftige Name für die
+     Programmdatei erfragt. Es muß ein Name eingetragen werden, der in dieser
+     Task noch nicht für eine Programmdatei vergeben wurde - ansonsten erfolgt
+     ein Hinweis darauf und die Programmdatei wird nicht umbenannt! 
+#page# 
+     Da man aber oft den 'neuen' Namen in Anlehnung an den 'alten' Namen
+     wählt, wird der 'alte' Name vorgeschlagen. Aus genannten Gründen muß er
+     aber verändert werden. Sie können diesen Namen mit den üblichen Editier­
+     funktionen verändern oder mit <HOP><RUBOUT> löschen und ganz neu
+     eingeben. Sie sparen aber eine Menge Tipparbeit, wenn Sie einen langen
+     Namen nur an einer Stelle ändern wollen. 
+ 
+     Fehlerfälle: 
+     -  Eine Programmdatei mit dem gewünschten Namen existiert bereits in der
+        Task. 
+ 
+ 
+ 
+#on("b")#5.6  Menufunktionen zum Oberbegriff 'Filialdaten'#off("b")# 
+#on("b")# 
++-------------------------------------------------------------------------+
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv |
+|---------------------------------------+--------------------------+------|
+|                                       |  e   Eintragen/ergänzen  |      |
+|                                       |  z   Zusammenstellen     |      |
+|                                       |  ----------------------- |      |
+|                                       |  v   Verzeichnis         |      |
+|                                       |  ----------------------- |      |
+|                                       |  l   Löschen             |      |
+|                                       |  u   Umbenennen          |      |
+|                                       +--------------------------+      |
+|                                                                         |
+|                                                                         |
+|-------------------------------------------------------------------------|
+|    Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q>|
++-------------------------------------------------------------------------+
+
+#off("b")#
+ 
+#on("b")#e Eintragen/ergänzen#off("b")# 
+ 
+     Mit diesem Menupunkt können Sie Filialdaten-Dateien, die Sie z.B. von der
+     Vatertask oder von der Diskette geholt haben, in Ihrer Task laden. 
+#page# 
+     Ihnen werden zunächst alle vorhandenen Filialdaten-Dateien zur Auswahl
+     angeboten. Anschließend werden die angekreuzten Dateien in der Reihenfolge,
+     in der sie angekreuzt wurden, zur Filialverwaltung geschickt und die Daten
+     dort zu den bereits vorhandenen hinzugefügt. Gegebenenfalls wird auch die
+     zentrale Kundendatei ergänzt. Der Vorgang wird auf dem Bildschirm
+     protokolliert. 
+ 
+     Beachten Sie bitte, daß in der Filiale etwa vorhandene Daten dadurch nicht
+     überschrieben, sondern lediglich ergänzt werden. Ein gänzliches Beseitigen von
+     alten Daten gelingt nur durch Löschen der Filialtask. 
+ 
+     Fehlerfälle: 
+     -  In der Task exsitieren noch keine Filialdaten-Dateien. 
+ 
+ 
+#on("b")#z Zusammenstellen#off("b")# 
+ 
+     Mit dieser Funktion können Sie eine Datei anlegen, in der die aktuell in der
+     Filiale gehaltenen Daten zusammengestellt werden. Solch eine Datei kann man
+     sich jedoch nicht ansehen! 
+ 
+     Zunächst wird der Name der Datei erfragt, in die die Filialdaten geschrieben
+     werden sollen. Danach werden darin die aktuellen Daten gespeichert und es
+     wird eine 'Vollzugsmeldung' ausgegeben. 
+ 
+     Die Daten können dann später mit Hilfe der Archiv-Funktionen (vgl. Kapitel
+     5.7) z.B. auf einer Diskette gespeichert werden, damit Sie beim eventuellen
+     Löschen der Filialtask nicht verlorengehen. Eine Verwechselung mit
+     Programmdateien ist nicht möglich, da Namen für Filialdaten-Dateien (intern)
+     automatisch mit dem Präfix 'Filialdaten:' versehen werden. 
+ 
+     Fehlerfälle: 
+     -  Eine Filialdaten-Datei mit dem gewünschten Namen existiert bereits in der
+        Task. 
+#page# 
+#on("b")#v Verzeichnis#off("b")# 
+ 
+     Mit dieser Funktion können Sie sich einen Überblick über die in Ihrer Task
+     vorhandenen Filialdaten-Dateien verschaffen. 
+ 
+     Nach Aufruf dieser Funktion wird eine Liste der Filialdaten-Dateien auf dem
+     Bildschirm ausgegeben, die sich in Ihrer Task befinden. Da die Liste eine
+     Text-Datei ist, kann Sie mit der Tastenkombination <ESC><q> verlassen
+     werden - hierauf wird auch in der letzten Bildschirmzeile hingewiesen. Falls
+     nicht alle Namen auf den Bildschirm passen, können Sie das Fenster mit
+     <HOP><runter> und <HOP><hoch> verschieben. 
+ 
+ 
+#on("b")#l Löschen#off("b")# 
+ 
+     Mit dieser Funktion können Sie Filialdaten-Dateien, die Sie nicht mehr
+     benötigen und die unnötig Platz belegen, löschen. Aber Vorsicht! Die Dateien
+     verschwinden durch diese Funktion unwiederbringlich! 
+ 
+     Nach Aufruf dieser Funktion werden Ihnen alle Filialdaten-Dateien, die sich in
+     Ihrer Task befinden, zur Auswahl angeboten. Hier können Sie die gewünschten
+     Namen ankreuzen. Die Auswahl wird dann durch die Tastenfolge
+     <ESC><q> verlassen. 
+ 
+     Für jede einzelne Datei wird nachgefragt, ob sie auch tatsächlich gelöscht
+     werden soll. Zur Bestätigung tippen Sie bitte die Taste <j> ('ja') - zur Ver­
+     hinderung <n> ('nein'). 
+ 
+     Fehlerfälle: 
+     -  In der Task exsitiert noch keine Filialdaten-Datei. 
+#page# 
+#on("b")#u Umbenennen#off("b")# 
+ 
+     Mit dieser Funktion können Sie einer bereits vorhandenen Filialdaten-Datei
+     einen neuen Namen geben. 
+ 
+     Nach Aufruf dieser Funktion werden Ihnen alle Filialdaten-Dateien, die sich in
+     Ihrer Task befinden, zur Auswahl angeboten. Nach Ankreuzen eines Namens
+     wird die Auswahl automatisch verlassen. 
+ 
+     Anschließend wird dieser Name angezeigt und der zukünftige Name für die
+     Datei erfragt. Es muß ein Name eingetragen werden, der in dieser Task noch
+     nicht für eine Filialdaten-Datei vergeben wurde - ansonsten erfolgt ein Hinweis
+     darauf und die Datei wird nicht umbenannt! 
+ 
+     Da man aber oft den 'neuen' Namen in Anlehnung an den 'alten' Namen
+     wählt, wird der 'alte' Name vorgeschlagen. Aus genannten Gründen muß er
+     aber verändert werden. Sie können diesen Namen mit den üblichen Editier­
+     funktionen verändern oder mit <HOP><RUBOUT> löschen und ganz neu
+     eingeben. Sie sparen aber eine Menge Tipparbeit, wenn Sie einen langen
+     Namen nur an einer Stelle ändern wollen. 
+ 
+     Fehlerfälle: 
+     -  Eine Filialdaten-Datei mit dem gewünschten Namen existiert bereits in der
+        Task. 
+#page# 
+#on("b")#5.7  Menufunktionen zum Oberbegriff 'Archiv'#off("b")# 
+#on("b")# 
++--------------------------------------------------------------------------+
+| WARENHAUS:  Info  Eingabeart  Kommandos  Programme  Filialdaten  Archiv  |
+|---------------------------------------------+------------------------+---|
+|                                             |  r  Reservieren        |   |
+|                                             |  -  Neue Diskette      |   |
+|                                             |  --------------------  |   |
+|                                             |  -  Schreiben          |   |
+|                                             |  -  Checken            |   |
+|                                             |  -  Kombination        |   |
+|                                             |  -  Holen/Lesen        |   |
+|                                             |  -  Löschen            |   |
+|                                             |  --------------------  |   |
+|                                             |  -  Verzeichnis        |   |
+|                                             |  -  Drucken            |   |
+|                                             |  --------------------  |   |
+|      +-----------------------+              |  i  Initialisieren     |   |
+|      |  Dateiaustausch mit:  |              |  z  Zieltask einstellen|   |
+|      |   Archiv              |              +------------------------+   |
+|      |  Archivname:          |                                           |
+|      |   gs-Warenhaus        |                                           |
+|      +-----------------------+                                           |
+|--------------------------------------------------------------------------|
+|    Info:<ESC><?>/<?> Wahl:<Pfeile> Ausführen:<RETURN> Verlassen:<ESC><q> |
++--------------------------------------------------------------------------+
+#off("b")# 
+ 
+In diesem Kapitel werden alle die Menufunktionen beschrieben, die Ihnen unter dem
+Oberbegriff 'Archiv' im Menu angeboten werden. Mit den Funktionen in diesem Menu
+können Sie aber nicht nur Dateien auf dem Archiv behandeln, sondern auch in
+anderen Tasks im Multi-User-System oder über das EUMEL-Netz sogar auf anderen
+Rechnern! 
+ 
+Wenn Sie dieses Pull-Down-Menu gerade aufgeschlagen haben, sind nicht alle
+Funktionen aktivierbar! Um weitere Funktionen zu aktivieren, muß erst einer der
+aktivierbaren Menupunkte gewählt werden. 
+ 
+Bei der Archivbehandlung werden Ihnen jeweils alle in der Task vorhandenen Dateien
+zur Auswahl angeboten. Das System unterscheidet nicht von sich aus - wie unter den
+#page# 
+Oberbegriffen 'Programme' und 'Filialdaten' - zwischen Programm- und Filial­
+daten-Dateien. In den hier gezeigten Listen können Sie aber Filialdaten-Dateien
+daran erkennen, daß ihnen das Präfix 'Filialdaten:' vorangestellt ist. 
+ 
+ 
+#on("b")#r Reservieren#off("b")# (des Archivlaufwerks) 
+ 
+     Im EUMEL-Multi-User-System haben normalerweise mehrere Personen das
+     Zugriffsrecht auf das Archivlaufwerk. Allerdings muß der Zugriff so geregelt
+     werden, daß sich die Beteiligten dabei nicht gegenseitig "in die Quere
+     kommen". Ein Zugriff auf das Archivlaufwerk erfordert zunächst eine An­
+     meldung. Ist diese Anmeldung erfolgt, kann von den anderen Beteiligten so
+     lange nicht mehr auf das Laufwerk zugegriffen werden, bis es wieder freige­
+     geben worden ist. 
+ 
+     Diese Anmeldung des Archivlaufwerkes erfolgt über die Menufunktion 'r Reser­
+     vieren'. Greift bereits eine andere Task auf das Laufwerk zu, so erhalten Sie
+     darüber einen Hinweis auf dem Bildschirm. Ansonsten wird an Sie die Frage
+     gestellt, ob die Diskette eingelegt und das Laufwerk geschlossen ist. 
+ 
+     Erst zu diesem Zeitpunkt ist sichergestellt, daß Sie den alleinigen Zugriff auf
+     das Laufwerk haben. Deshalb sollten Sie, wenn Sie mit mehreren Personen am
+     Computer arbeiten, erst zum Zeitpunkt der Fragestellung die Diskette ins Lauf­
+     werk einlegen. 
+ 
+     Nachdem Sie die Diskette eingelegt und die Frage bejaht haben, ermittelt das
+     System selbständig den Namen der eingelegten Diskette, zeigt den Namen auf
+     dem Bildschirm (im kleinen Kasten links unten) an und aktiviert die anderen
+     Menupunkte des Pull-Down-Menus. 
+ 
+     Beim Verlassen des Pull-Down-Menus, wenn eine andere Zieltask eingestellt
+     wird oder wenn das Menu gänzlich verlassen wird, wird die Reservierung
+     automatisch aufgehoben! 
+#page# 
+     Fehlerfälle: 
+     -  Das Laufwerk ist von einer anderen Task belegt. 
+     -  Die Diskette ist falsch eingelegt oder das Laufwerk ist nicht richtig ge­
+        schlossen. 
+     -  Die Diskette ist nicht formatiert bzw. initialisiert. 
+     -  Die Diskette kann nicht gelesen werden (keine EUMEL-Diskette, Diskette
+        hat ein falsches Format, Diskette ist verschmutzt...). 
+ 
+ 
+#on("b")#n Neue Diskette#off("b")# (anmelden) 
+ 
+     Der Dateiaustausch mit einer Diskette ist nur dann möglich, wenn der im
+     System eingestellte Diskettenname (auf dem Bildschirm im kleinen Kasten
+     unten links sichtbar) mit dem tatsächlichen Namen der Diskette überein­
+     stimmt. Nach einem Diskettenwechsel ist das aber in der Regel nicht mehr der
+     Fall. Greift man dann auf die neu eingelegte Diskette zu, so erscheint die
+     Fehlermeldung: 'Falscher Archivname! Bitte neue Diskette anmelden!'. 
+ 
+     Das Anmelden einer neuen Diskette - ohne einen neuen Reservierungsvorgang
+     - wird durch diese Menufunktion ermöglicht. Nach Aktivieren dieses Menu­
+     punktes wird der Name der eingelegten Diskette ermittelt, im System eingestellt
+     und auf dem Bildschirm angezeigt. 
+ 
+     Im Gegensatz zur Menufunktion 'r Reservieren' greift das System ohne Anfrage
+     an den Benutzer auf das Archivlaufwerk zu (die Reservierung bleibt ja be­
+     stehen). Ist das Archivlaufwerk reserviert, so ist die Neuanmeldung einer Dis­
+     kette über diese Menufunktion weniger zeitaufwendig. 
+ 
+     Fehlerfälle: 
+     -  wie unter 'r Reservieren'. 
+#page# 
+#on("b")#s Schreiben#off("b")# (Kopieren) 
+ 
+     Alle Dateien der eigenen Task werden zur Auswahl angeboten. Wenn Sie die
+     Auswahl durch die Tastenfolge <ESC><q> verlassen, überprüft das System
+     zunächst, ob die Dateien in der eingestellten Zieltask schon vorhanden sind. Ist
+     das der Fall, wird erfragt, ob die dort vorhandenen Dateien überschrieben, d.h.
+     gelöscht werden dürfen (s.u.). Anschließend werden alle angekreuzten Dateien
+     in der Reihenfolge, in der Sie sie angekreuzt haben, in die eingestellte Zieltask
+     kopiert. Der Vorgang wird auf dem Bildschirm protokolliert. Die Original­
+     dateien in der eigenen Task bleiben dabei erhalten. 
+ 
+     Wenn in der Zieltask schon eine Datei existiert, die den gleichen Namen hat
+     wie eine Datei, die Sie dorthin kopieren möchten, so wird angefragt, ob die
+     vorher schon existierende Datei überschrieben (gelöscht!) werden soll. Bejahen
+     Sie diese Frage, so wird die bereits in der Zieltask existierende Datei (un­
+     wiederbringlich) gelöscht und die gewünschte Datei dorthin transportiert. Ein
+     Überschreiben aus Versehen ist nicht möglich, wenn Sie die an Sie gestellte
+     Frage sorgfältig beantworten. 
+ 
+     Verneinen Sie die Frage, so wird die Datei auch nicht hinübertransportiert! Sie
+     können die Datei aber umbenennen (Menufunktion 'u Umbenennen' unter
+     den Oberbegriffen 'Programme' bzw. 'Filialdaten') und anschließend mit
+     anderem Namen hinüberschreiben. 
+ 
+     Beachten Sie, daß beim Überschreiben einer Datei auf einer Archivdiskette der
+     Speicherplatz der alten (überschriebenen) Version im allgemeinen nicht
+     wiederverwendet werden kann. In einem solchen Fall könnte die Diskette voll
+     geschrieben werden, obwohl eigentlich genügend Platz vorhanden wäre. Zur
+     Optimierung wird deshalb zuerst überprüft, ob die angekreuzten Dateien
+     schon in der Zieltask vorhanden sind und löscht diese, wenn Sie Ihr Einver­
+     ständnis geben. Erst anschließend werden die Dateien insgesamt kopiert. 
+#page# 
+     Normalerweise ist als Zieltask das Archivlaufwerk der eigenen Station einge­
+     stellt. Mit der Menufunktion 'z Zieltask einstellen' kann diese Einstellung aber
+     verändert werden. 
+ 
+     Fehlerfälle: 
+     -  Die Diskette ist falsch eingelegt oder beschädigt. 
+     -  Die Diskette kann nicht beschrieben werden (Schreibfehler). 
+     -  Die Diskette ist voll. 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#c Checken#off("b")# 
+ 
+     Diese Menufunktion kann nur ausgeführt werden, wenn der Dateiaustausch
+     mit einem Archiv(manager) erfolgt - ansonsten ist diese Menufunktion auch
+     nicht aktivierbar. Die Menufunktion dient dazu, auf Diskette geschriebene
+     Dateien auf Lesefehler hin zu prüfen. Es empfiehlt sich, diese Prüfroutine auf
+     neu auf die Diskette geschriebene Dateien anzuwenden. Sehen Sie dazu auch
+     'k Kombination'. 
+ 
+     Alle Dateien der eingestellten Zieltask (Archiv) werden zur Auswahl angeboten.
+     Wenn Sie die Auswahl durch die Tastenfolge <ESC><q> verlassen, werden
+     alle angekreuzten Dateien in der Reihenfolge, in der Sie sie angekreuzt haben,
+     "gecheckt", d.h. auf Lesefehler hin überprüft. Der Vorgang wird auf dem Bild­
+     schirm protokolliert. 
+ 
+     Fehlerfälle: 
+     -  Lesefehler auf dem Archiv. 
+     -  Sehen Sie auch unter  'r Reservieren'. 
+#page# 
+#on("b")#k Kombination#off("b")# 
+ 
+     Diese Menufunktion ist eine Kombination aus den beiden Menufunktionen 's
+     Schreiben' und 'c Checken' (Sehen Sie weitere Informationen auch dort!). 
+ 
+     Alle Dateien der eigenen Task werden zur Auswahl angeboten. Wenn Sie die
+     Auswahl durch die Tastenfolge <ESC><q> verlassen, werden alle ange­
+     kreuzten Dateien in der Reihenfolge, in der Sie sie angekreuzt haben, in die
+     eingestellte Zieltask kopiert (gegebenenfalls müssen bereits vorhandene
+     Dateien gleichen Namens in der Zieltask gelöscht werden). Anschließend
+     werden alle Dateien, die gerade geschrieben wurden, gecheckt, d.h. auf Lese­
+     fehler hin untersucht. Beide Vorgänge werden auf dem Bildschirm
+     protokolliert. 
+ 
+     Da die 'Check' - Operation nur bei Archivmanagern zulässig ist, ist diese Menu­
+     funktionen ebenfalls nur bei Archivmanagern aktivierbar. Zur Erläuterung
+     sehen Sie bitte auch unter 'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#h Holen/Lesen#off("b")# 
+ 
+     Die Menufunktion dient dazu, Dateien, die bereits auf einer Archivdiskette oder
+     in einer anderen Task existieren, in die eigene Task zu kopieren. 
+ 
+     Alle Dateien der eingestellten Zieltask werden zur Auswahl angeboten. An­
+     schließend werden Kopien der angekreuzten Dateien in der Reihenfolge des
+     Ankreuzens in die eigene Task geholt. Das Original in der Zieltask bleibt dabei
+     unverändert! Der Vorgang wird auf dem Bildschirm protokolliert. 
+ 
+     Sind in der eigenen Task schon Dateien mit gleichem Namen vorhanden, so
+     wird gefragt, ob die 'alten' Dateien überschrieben (gelöscht) werden dürfen.
+     Nur wenn Sie zustimmen, werden die in Ihrer Task existierenden Dateien
+     (unwiederbringlich!) gelöscht und Kopien der gleichnamigen Dateien aus der
+     Zieltask angefertigt. 
+#page# 
+     Stimmen Sie dem Löschvorgang nicht zu, dann bleiben die bisherigen Dateien
+     in Ihrer Task erhalten - die Dateien aus der Zieltask werden dann aber auch
+     nicht in Ihre Task kopiert! Um dennoch die Kopien zu erhalten, können Sie die
+     namensgleichen Dateien in Ihrer Task umbenennen und dann erst die Dateien
+     aus der anderen Task anfordern. 
+ 
+     Normalerweise werden die Dateien vom Archiv der eigenen Station geholt. Mit
+     dem Menupunkt 'z Zieltask einstellen' kann diese Einstellung verändert
+     werden. 
+ 
+     Fehlerfälle: 
+     -  Lesefehler auf dem Archiv. 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              's Schreiben' 
+                              'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#l Löschen#off("b")# 
+ 
+     Die Menufunktion dient dazu, Dateien in der Zieltask (unwiederbringlich!) zu
+     löschen. Dazu werden alle Dateien der eingestellten Zieltask zur Auswahl ange­
+     boten. Anschließend werden die angekreuzten Dateien in der Reihenfolge ihres
+     Ankreuzens gelöscht. Zur Sicherheit muß noch einmal für jede einzelne Datei
+     bestätigt werden, daß sie auch tatsächlich gelöscht werden soll. 
+ 
+     Beachten Sie, daß beim Löschen einer Datei auf einer Archivdiskette der
+     Speicherplatz im allgemeinen nicht wieder verwendet werden kann. In einem
+     solchen Fall könnte die Diskette voll geschrieben werden, obwohl eigentlich
+     genügend Platz vorhanden wäre. Diese Probleme treten bei anderen Tasks, die
+     keine Archivmanager sind, nicht auf, da deren Speicherplatz intelligenter
+     verwaltet wird. 
+#page# 
+     Normalerweise ist als Zieltask das Archiv der eigenen Station eingestellt. Mit
+     dem Menupunkt 'z Zieltask einstellen' kann diese Einstellung verändert
+     werden. 
+ 
+     Fehlerfälle: 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              's Schreiben' 
+                              'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#v Verzeichnis#off("b")# 
+ 
+     Mit dieser Menufunktion können Sie sich einen Überblick über die in der
+     Zieltask (z.B. auf dem Archiv) vorhandenen Dateien verschaffen. 
+ 
+     Nach Aufruf der Funktion wird eine Liste der Dateien auf dem Bildschirm
+     ausgegeben, die sich in der Zieltask (z.B. auf dem Archiv) befinden. Ist die
+     Zieltask ein Archiv(manager), so wird auch angezeigt, wieviel Platz auf der
+     Diskette belegt ist. Da die Liste selbst eine Datei ist, kann sie mit der Tasten­
+     kombination <ESC><q> verlassen werden. Falls nicht alle Dateinamen auf
+     den Bildschirm passen, können Sie das Fenster mit <HOP><hoch> und
+     <HOP><runter> verschieben. 
+ 
+     Fehlerfälle: 
+     -  Sehen Sie unter  'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#d Drucken#off("b")# 
+ 
+     Das Verzeichnis der Dateien in der Zieltask, das man mit der Menufunktion 'v
+     Verzeichnis' auf dem Bildschirm angezeigt bekommt, kann mit dieser Menu­
+     funktion ausgedruckt werden. 
+#page# 
+     Zur Sicherheit wird angefragt, ob wirklich ein solches Dateiverzeichnis der
+     Zieltask gedruckt werden soll. Bejaht man die Frage, so wird ein Dateiver­
+     zeichnis erstellt und zum Drucker geschickt. 
+ 
+     Fehlerfälle: 
+     -  Der Drucker ist nicht funktionsbereit. 
+     -  Der Drucker wird nicht über die Task 'PRINTER' betrieben. 
+     -  Auf Ihrem System werden die Druckkosten abgerechnet. Sie müssen sich
+        mit einer Codenummer identifizieren. 
+ 
+ 
+#on("b")#i Initialisieren#off("b")# 
+ 
+     Diese Menufunktion gestattet es, frische Disketten zu formatieren, zu initiali­
+     sieren bzw. beschriebene Disketten vollständig zu löschen und ggf. dabei
+     umzubenennen. Bei Aufruf dieser Menufunktion wird - sofern noch nicht
+     geschehen - das Archivlaufwerk automatisch reserviert. 
+ 
+     Wenn Sie eine fabrikneue Diskette aus der Verpackung nehmen, müssen Sie
+     diese zunächst #on("b")#formatieren#off("b")#. Dabei wird die Diskette auf ein festgelegtes
+     physikalisches Format eingestellt. Ohne daß diese Operation vorausgegangen
+     ist, kann eine Diskette weder beschrieben noch gelesen werden. 
+ 
+     Prinzipiell braucht eine Diskette nur ein einziges Mal formatiert zu werden. Sie
+     können Sie jedoch jederzeit wieder formatieren - z.B. wenn Sie Disketten
+     haben, von denen Sie nicht genau wissen, für welche Zwecke sie zuvor ver­
+     wendet wurden. 
+ 
+     Wenn Sie diese Menufunktion aktivieren, werden Sie so zunächst gefragt, ob Sie
+     die Diskette auch formatieren wollen. Bejahen Sie die Frage, so werden Ihnen
+     mehrere Formate zur Auswahl angeboten: 
+#page# 
+#on("b")# 
+              +----------------------------------------+
+              |  Formatieren einer Diskette            |
+              |                                        |
+              |  Dies sind die möglichen Formate:      |
+              |                                        |
+              |       1 ....  40 Spur     -   360 KB   |
+              |       2 ....  80 Spur     -   720 KB   |
+              |       3 ....  5 1/4"      -   1,2 MB   |
+              |       4 ....  3 1/2"      -   1,4 MB   |
+              |       s ....  Standard    -   Format   |
+              |                                        |
+              |                                        |
+              |                 1   2   3   4   s      |
+              +----------------------------------------+ 
+
+#off("b")# 
+ 
+     Erkundigen Sie sich bei Ihrem Händler, welches Format Sie bei Ihrem Rechner
+     und den von Ihnen verwendeten Disketten einstellen müssen. Manche Rechner
+     unterstützen diese Operation innerhalb des EUMEL-Systems auch gar nicht,
+     das Formatieren muß dann irgendwie anders außerhalb des EUMEL-Systems
+     geschehen. 
+ 
+     Wenn Sie die Formatierung abgeschlossen oder auch übersprungen haben,
+     beginnt die eigentliche Initialisierung der Diskette. Dabei wird als erstes der
+     Archivname auf die Diskette geschrieben. Alle alten Daten, die sich ggf. auf der
+     Diskette befinden, werden bei diesem Vorgang unwiederbringlich (!) gelöscht. 
+ 
+     Zur Sicherheit überprüft das System in jedem Falle, ob es sich um eine EUMEL
+     - Diskette handelt, und erfragt Ihr Einverständnis, ob die Diskette wirklich
+     initialisiert werden soll. Geben Sie hierzu Ihr Einverständnis, dann wird noch
+     der (neue) Archivname erfragt. Hatte die Diskette schon einen Namen, dann
+     wird dieser zum Überschreiben angeboten. Wollen Sie den alten Archivnamen
+     beibehalten, so brauchen Sie nur die <RETURN>-Taste zu tippen, ansonsten
+     können Sie den Namen auch zuvor verändern oder einen ganz neuen Namen
+     hinschreiben. Anhand des ausgegebenen Namens können Sie auch über­
+     prüfen, ob Sie die richtige Diskette eingelegt haben. 
+#page# 
+     Das Initialisieren funktioniert natürlich nur, wenn Sie als Zieltask einen
+     Archivmanager eingestellt haben - ansonsten ist diese Menufunktion gesperrt
+     (nicht aktivierbar!). 
+ 
+     Fehlerfälle: 
+     -  Formatieren ist nicht auf dem System möglich. 
+     -  Sehen Sie auch unter  'r Reservieren' 
+                              'z Zieltask einstellen'. 
+ 
+ 
+#on("b")#z Zieltask einstellen#off("b")# 
+ 
+     Mit dieser Menufunktion können Sie festlegen, mit welcher Zieltask Sie
+     kommunizieren, d.h. z.B. Dateien austauschen möchten. Normalerweise ist
+     hier das Archiv am eigenen Rechner eingestellt. Das wird auch nach Auf­
+     klappen des Pull-Down-Menus im Kasten links unten angezeigt. 
+ 
+     Diese Menufunktion kann im Unterricht z.B. dazu genutzt werden, um fertig­
+     gestellte Hausaufgaben in eine bestimmte Task zu schicken (Vatertask) oder
+     um von dort z.B. vorgefertigte Programme und/oder Filialdaten-Dateien abzu­
+     holen. 
+ 
+     Sie können aber auch eine andere Task einstellen (z.B. die Vatertask oder die
+     Task 'PUBLIC'), um mit diesen Dateien auszutauschen oder um sich auch nur
+     einen Überblick über die dort vorhandenen Dateien zu verschaffen. Wenn Sie
+     mit Ihrem Rechner in ein EUMEL-Netz integriert sind, können Sie auch auf
+     Tasks anderer Rechner zugreifen oder auch Disketten von Laufwerken anderer
+     Rechner einlesen (z.B. wenn Sie Disketten anderer Formate haben, die von
+     Ihrem Rechner nicht gelesen werden können). 
+ 
+     Dabei werden zwei Anforderungen an die Zieltask gestellt: Sie muß existieren
+     und bereit für den Dateiaustausch sein, d.h es muß eine Managertask sein, auf
+     die Sie Zugriff haben. Versuchen Sie auf andere Tasks zuzugreifen, so erhalten
+     Sie entsprechende (Fehler-)Meldungen. 
+#page# 
+     Zu beachten ist noch, daß es im EUMEL-System verschiedene Arten von
+     Managertasks gibt - Archivmanager und normale Dateimanager. Der Unter­
+     schied besteht darin, daß ein Archivmanager vom Benutzer vor dem Zugriff
+     reserviert werden muß - anschließend hat nur dieser Benutzer (bis zur Aufga­
+     be der Reservierung) ein Zugriffsrecht auf den Manager. Normale Datei­
+     manager können dagegen von mehreren Benutzern in beliebiger Reihenfolge
+     angesprochen werden. 
+ 
+     Ein Archivmanager kann auch auf bestimmte Diskettenformate spezialisert
+     sein (z.B. auf das Lesen von DOS-Disketten). Manche Rechner haben auch
+     mehrere Archivmanager für verschiedene Laufwerke etc. Durch Einstellen
+     unterschiedlicher Archivmanager können Sie dann auf verschiedenen Lauf­
+     werken archivieren. 
+ 
+     Nach Aktivieren dieses Menupunktes werden Ihnen die folgenden Alternativen
+     angeboten: 
+#on("b")# 
+                    +-------------------------------------------+
+                    |     Dateiaustausch gewünscht mit:         |
+                    |                                           |
+                    |    a ...    Archiv (Eigene Station)       |
+                    |                                           |
+                    |    v ...   Vatertask                      |
+                    |                                           |
+                    |    p ...   'PUBLIC' (Eigene Station)      |
+                    |                                           |
+                    |    s ...   Sonstige Task                  |
+                    |                                           |
+                    |   Archiv   Vatertask   PUBLIC   Sonstige  |
+                    +-------------------------------------------+
+#off("b")# 
+ 
+     Da der Dateiaustausch mit dem Standardarchiv der eigenen Station (Task:
+     'ARCHIVE'), mit der Vatertask und der Task 'PUBLIC' recht häufig in Anspruch
+     genommen wird, sind diese drei Optionen unter den Alternativen direkt ange­
+     geben. Entscheiden Sie sich für eine dieser drei Tasks, so nimmt das System
+     alle notwendigen Einstellungen vor. Möchten Sie dagegen in Kontakt mit einer
+#page# 
+     anderen Task treten, so wählen Sie die Alternative 's ... Sonstige Task'. 
+     In diesem Falle haben Sie noch 3 Angaben zu machen: 
+ 
+     -  Zunächst werden Sie nach dem Namen der Zieltask gefragt. Geben Sie den
+        Namen der Zieltask - ohne Anführungsstriche (!) - ein und schließen Sie
+        die Eingabe mit der <RETURN>-Taste ab. (Den ausgegebenen Namen der
+        z.Z. eingestellten Task können Sie dabei verändern bzw. überschreiben.) 
+ 
+     -  Dann wird die Nummer der Station im EUMEL-Netz erfragt, auf der sich
+        die Zieltask befindet. Die Nummer Ihrer Station wird als Vorschlag ausge­
+        geben. Wollen Sie mit einer Task auf Ihrem Rechner kommunizieren, so
+        brauchen Sie diesen Vorschlag nur durch Drücken der <RETURN>-Taste
+        bestätigen - ansonsten tragen Sie zuvor die entsprechende Stationsnummer
+        ein. Ist Ihr Rechner nicht in ein EUMEL-Netz integriert, so wird die
+        Stationsnummer 0 (Null) ausgegeben. Bitte bestätigen Sie diese Stations­
+        nummer durch Tippen der <RETURN>-Taste. 
+ 
+     -  Zum Abschluß müssen Sie noch angeben, ob die eingestellte Zieltask ein
+        Archivmanager ist oder nicht. 
+ 
+     Das System versucht dann den Kontakt herzustellen. Je nachdem, welche
+     Einstellung Sie vorgenommen haben, sind bestimmte Funktionen innerhalb
+     des Menus nicht aktivierbar. Das System läßt nur die Funktionen zu, die
+     aufgrund Ihrer Einstellungen zulässig sind. 
+ 
+     Im Kasten links unten auf dem Bildschirm wird jeweils angezeigt, welche
+     Zieltask eingestellt ist. Erscheint in diesem Kasten auch ein Hinweis auf den
+     Archivnamen, so haben Sie einen Archivmanager eingestellt. Ist dagegen vor
+     dem Namen der Zieltask noch eine Zahl und ein Schrägstrich angegeben, so
+     haben Sie eine Zieltask auf einem anderen Rechner eingestellt. 
+ 
+     Bedenken Sie, daß Operationen mit Tasks auf anderen Stationen länger an­
+     dauern können - werden Sie nicht ungeduldig! 
+#page# 
+     Sie können die Einstellung der Zieltask jederzeit wieder verändern! 
+ 
+     Fehlerfälle: 
+     -  Die eingestellte Zieltask existiert nicht. 
+     -  Die eingestellte Zieltask existiert zwar, ist aber nicht empfangsbereit, d.h.
+        ein Zugriff von Ihrer Task aus ist nicht möglich! 
+     -  Das Netz ist nicht funktionsbereit (Collector-Task fehlt). 
+     -  Die Kommunikation war nicht erfolgreich. 
+     -  Die gewünschte Operation kann mit der eingestellten Zieltask nicht ausge­
+        führt werden (Zieltask ist z.B. gar kein Archivmanager - Sie aber ver­
+        suchen, das Laufwerk zu reservieren). 
+ 
+
+
+
+
+
+
+
+
diff --git a/doc/warenhaus/gs-Warenhaus-6 b/doc/warenhaus/gs-Warenhaus-6
new file mode 100644
index 0000000..3edf312
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-6
@@ -0,0 +1,589 @@
+#limit (11.0)##pagelength (16.5)##block#                                   
+#start (2.0,0.0)# 
+#page (61)# 
+#headodd# 
+#center#gs-Warenhaus#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Warenhaus
+ 
+#end# 
+#center#1 
+ 
+#center##on("b")#6  Beschreibung der Programmierschnittstelle#off("b")# 
+ 
+ 
+In allen GRIN-Projekten soll - zumindest als Erweiterung - der Aspekt des
+"algorithmischen Problemlösens" mit in den Unterricht eingebracht werden. Deshalb
+ist auch in dem Soester Programm zum Projekt WARENHAUS eine Programmier­
+schnittstelle realisiert, die es erlaubt, mit Hilfe eines eng begrenzten Befehlssatzes
+kleine Programme zur Steuerung der Abläufe im Modell-Warenhaus zu schreiben. 
+ 
+Wir haben lange überlegt, ob wir diese Programmierschnittstelle überhaupt nach­
+bilden sollten, weil wir der Meinung sind, daß beim Projekt WARENHAUS das
+algorithmische Problemlösen, wenn überhaupt, nur eine sehr untergeordnete Rolle
+spielt. Als Randproblematik kann man hier vielleicht untersuchen, wie die Menu-
+Funktionen unter dem Oberbegriff 'Kommandos' (vgl. Kapitel 5.4) aufgebaut sind,
+und man kann versuchen, diese in eigenen kleinen Programmen nach- oder umzu­
+bilden. 
+ 
+Unser zweites Problem war, ob wir uns bei einer eventuellen Nachbildung der
+Programmierschnittstelle auch wirklich streng an die Soester Vorgaben halten sollten,
+auch wenn sie unseren Vorstellungen und Konzepten teilweise zuwiderlaufen. Eigent­
+lich sind wir der Meinung, daß uns mit der Programmiersprache ELAN bereits ein
+ausgezeichnetes Hilfsmittel zur Verfügung steht, um auch in der Sekundarstufe I in
+das algorithmische Problemlösen einzuführen. Gerade das Refinementkonzept - die
+Methode der 'schrittweisen Verfeinerung' / der "Modularisierung im Kleinen" -
+scheint uns besonders geeignet, typische Denkweisen des algorithmischen Problem­
+lösens offenzulegen. Lediglich die Konstruktion einer Zählschleife und den Umgang
+mit den Fehlermeldungen des ELAN-Compilers halten wir bei Anfängern für etwas
+problematisch. 
+ 
+Wir haben uns deshalb entschlossen, Ihnen die Programmierschnittstelle in zwei
+Versionen zur Verfügung zu stellen: In der 'ELAN-Version' können Sie in der üblichen
+#page# 
+ELAN-Umgebung programmieren; das bietet sich z.B. an, wenn Sie #on("b")#gs-Warenhaus#off("b")#
+im Wahlpflichtbereich bzw. im Differenzierungsbereich 9/10 einsetzen möchten. Es
+ist dann dort nicht nötig, erst eine neue, weniger komfortable "Programmiersprache"
+zu erlernen. 
+ 
+Für den GRIN-Bereich enthält #on("b")#gs-Warenhaus#off("b")# eine weitere Programmierebene
+('GRIN-Version'), die an die Soester Vorgaben angelehnt ist, und die es erlaubt, die
+dort benutzten Schreibweisen von Befehlen und Kontrollstrukturen zu übernehmen.
+Allerdings haben wir dabei eine grundsätzliche Änderung bezüglich der Modularisie­
+rungsmöglichkeit von 'GRIN-Programmen' vorgenommen, auf die wir in Kapitel 6.1
+näher eingehen werden. 
+ 
+Ein 'GRIN-Programm' wird bei der Ausführung des Menupunktes 's Starten' (vgl.
+Kapitel 5.5) zunächst in ein ELAN-Programm übersetzt und dabei auf formale
+Korrektheit überprüft. Werden keine Fehler festgestellt, so wird nun seinerseits das
+ELAN-Programm vom Compiler übersetzt und anschließend ausgeführt. Als Benutzer
+werden Sie dabei nicht mit Fehlermeldungen des Compilers konfrontiert, da der
+#on("b")#gs-Warenhaus#off("b")#-Übersetzer vorher alle formalen Fehler abfängt und zum Korrigieren
+anbietet. 
+ 
+Sollte das System nach erfolgreicher Übersetzung und/oder Compilation bei der
+Ausführung des Programms einen Fehler "bemerken" (z.B. falscher Aufruf eines
+Befehles), so wird das Programm automatisch abgebrochen und die entsprechende
+Fehlermeldung mit der Nummer der Programmzeile, in der der Fehler bemerkt
+wurde, im unteren Teil des Bildschirmes in einem 'notebook' gezeigt. Im oberen Teil
+wird das Programm zum Verbessern angeboten, wobei der Cursor am Anfang der
+fehlerhaften Zeile steht (gilt auch für die 'ELAN-Version'). 
+ 
+In beiden Versionen der Programmierschnittstelle ist die Schreibweise der Befehle bis
+auf die Groß- und Kleinschreibung identisch. Folgende Befehle stehen zu Verfügung: 
+#page# 
+      GRIN-Version      |       ELAN-Version 
+------------------------+------------------------------
+  Artikelnummer lesen   |   artikelnummer lesen 
+  Artikeldaten eingeben |   artikeldaten eingeben 
+  Kundennummer lesen    |   kundennummer lesen 
+  Kundendaten eingeben  |   kundendaten eingeben 
+  neues Blatt           |   neues blatt 
+  Rechnungskopf         |   rechnungskopf 
+  Artikel kaufen        |   artikel kaufen 
+  Abrechnung            |   abrechnung 
+  Auskunft              |   auskunft 
+  Bildschirm neu        |   bildschirm neu 
+                        |   nachbestellen 
+                        |   dezimalwert lesen 
+                        |   bitmuster lesen 
+                        |
+ 
+ 
+Die drei letzten Befehle der ELAN-Version haben wir in den GRIN-Befehlssatz nicht
+mit aufgenommen, weil wir hier den Befehlssatz möglichst klein (und damit über­
+sichtlich) halten wollten und diese Befehle bereits unter dem Oberbegriff
+'Kommandos' als Menu-Funktionen zur Verfügung stehen. (Ebenso könnte man bei
+dem Befehl 'Auskunft' argumentieren. Die entsprechende Menu-Funktion 'Auskunft
+einholen' liefert bei jeder Anwahl jedoch immer nur #on("b")#eine#off("b")# Auskunft; in einem
+Programm kann man nun die Ausgabe mehrerer Auskünfte hintereinander
+realisieren.) 
+ 
+Die genaue Wirkung der Befehle werden wir in Kapitel 6.3 noch detailliert
+beschreiben. Sie entsprechen im wesentlichen den Soester Befehlen, die im
+WARENHAUS-Begleitheft des LSW (siehe Anhang) auf den Seiten 99/100 aufgelistet
+sind. (Die anderen dort zu findenden Befehle gehören eigentlich nicht in die Befehls­
+liste der Programmierschnittstelle, weil sie nicht von Programmen aus sondern nur in
+einem 'Direktbefehgs-Modus' als Kommando aufrufbar sind! Diese Befehle sind auch
+#page# 
+#on("b")#keine#off("b")# Programmierbefehle im eigentlichen Sinne, sondern entweder "Macros" zum
+"Handling" des Warenhausmodells oder Systemkommandos. #on("b")#gs-Warenhaus#off("b")# stellt
+diese Befehle unter ähnlichen Namen als Menu-Funktionen zur Verfügung.) 
+ 
+ 
+ 
+#on("b")#6.1  Schreibweisen und Syntaxregeln in GRIN-Programmen#off("b")# 
+ 
+Die Regeln, die beim Schreiben eines ELAN-Programms zu beachten sind, werden im
+EUMEL/ELAN-Benutzerhandbuch beschrieben; wir werden uns daher hier auf die
+GRIN-Version konzentrieren. 
+ 
+Beginnen wir mit einem Beispiel aus dem WARENHAUS-Begleitheft des LSW. Dort
+finden Sie auf Seite 70 (unten) das folgende Programm: 
+ 
+#on("b")#
+   PROGRAMM Rechnung schreiben 
+     neues Blatt 
+     Kundennummer lesen 
+     WENN nicht Stoptaste gedrückt 
+       Rechnungskopf 
+       WIEDERHOLE 
+         Artikelnummer lesen 
+         WENN nicht Stoptaste gedrückt 
+           Artikel kaufen 
+         ENDE WENN 
+       BIS Stoptaste gedrückt 
+       Abrechnung 
+     ENDE WENN 
+   ENDE PROGRAMM #off("b")# 
+ 
+Sie können dieses Programm ohne Änderungen übernehmen und starten,
+#on("b")#gs-Warenhaus#off("b")# wird es ohne Beanstandungen ausführen. Bezüglich der Übersicht­
+lichkeit und des Programmierstils kann man hier sicher geteilter Meinung sein,
+darauf gehen wir später noch ein. 
+#page# 
+Wir möchten Ihnen zunächst einige Regeln zur Schreibweise und Syntax in 'GRIN-
+Programmen' aufzeigen, die sich im obigen Beispiel-Programm beobachten lassen: 
+ 
+-  In jeder Zeile darf nur #on("b")#ein#off("b")# Befehl stehen; Befehgs-Trennzeichen (wie etwa das
+   Semikolon in ELAN) werden deshalb nicht verwendet. Leerzeichen können
+   beliebig gesetzt werden, auch leere Zeilen sind zulässig, nicht jedoch
+   Kommentare. 
+ 
+-  Das Arbeiten mit Variablen (gleich welcher Art) ist #on("b")#nicht#off("b")# möglich; alle Befehle
+   sind datentypfrei. 
+ 
+-  Schlüsselworte für Kontrollstrukturen (wie z.B. WIEDERHOLE, WENN etc.)
+   werden in GROSSBUCHSTABEN geschrieben, Ausführungsbefehle und
+   Bedingungen hingegen klein und gemäß den Regeln der deutschen Sprache mit
+   großem Anfangsbuchstaben bei Substantiven. Diese Festlegung bezüglich der
+   Groß- und Kleinschreibung ist bei den von #on("b")#gs-Warenhaus#off("b")# zur Verfügung ge­
+   stellten Befehlen #on("b")#verbindlich#off("b")#, d.h. alle Warenhaus-#on("b")#Grund#off("b")#befehle und Kontroll­
+   strukturen müssen (bis auf Leerzeichen) genauso geschrieben werden, wie sie in
+   den Kapiteln 6.2 und 6.3 vorgegeben werden! (In der Soester Software können
+   dagegen Groß- und Kleinbuchstaben beliebig verwendet werden, sodaß dort z.B.
+   neben 'neues Blatt' auch 'neues blatt', "NEueS BlaTT" u.ä. als identisch ange­
+   sehen werden.) 
+ 
+-  Jedes 'GRIN-Programm' beginnt mit dem 'Schlüsselwort' <PROGRAMM>,
+   gefolgt von einem Programmnamen, der beliebig gewählt werden kann, jedoch
+   noch in diese Zeile passen muß. Sinnvoll ist es, hier z.B. den Namen der
+   Programmdatei einzutragen. 
+ 
+-  Jedes 'GRIN-Programm' endet mit der Zeile <ENDE PROGRAMM>. Nach dieser
+   Zeile dürfen nur noch leere Zeilen folgen, es sei denn zwischen <PROGRAMM
+   Programmname> und <ENDE PROGRAMM> wurden Befehle benutzt, die
+   nicht zum Warenhaus-Grundbefehlssatz gehören. Solche Befehle müssen in einer
+   'Befehlserklärung' nach Programmende definiert werden. 
+#page# 
+Das obige Programm befriedigt vom äußeren Erscheinungbild her einen PASCAL-
+Programmierer wahrscheinlich völlig, einen ELAN-Verwöhnten jedoch sicher nicht.
+Die Soester WARENHAUS-Software bietet keinerlei Möglichkeit der Modularisierung
+#on("b")#innerhalb#off("b")# eines Programms (Refinement-/Prozedurkonzept o.ä.). Es gibt dort nur die
+Möglichkeit, fertiggestellte Programme unter dem Programmnamen dem Basis­
+befehlssatz "hinzuzufügen" - ein Vorgang, der dem Insertieren unter EUMEL/ELAN
+ähnelt. Obwohl es unter EUMEL/ELAN ein leichtes gewesen wäre, diese Möglichkeit
+ebenfalls zu realisieren, haben wir davon Abstand genommen, weil auf diese Weise an
+jedem Arbeitsplatz eine "eigene" Programmierumgebung entstehen würde. Wir sind
+der Meinung, daß für Schüler der Sekundarstufe I eine #on("b")#feste Modellumgebung als
+Basis#off("b")# vorhanden sein muß. Außerdem erscheint uns bei der Programmierung "im
+Kleinen" die "Bottom-Up"-Technik  unangemessen und für den Anfänger viel zu
+unübersichtlich zu sein; viel eher wäre hier die "Top-Down"-Methode angebracht. Wir
+haben daher die Programmierumgebung in anderer Richtung erweitert und eine
+Modularisierungsmöglichkeit realisiert, die dem Refinementkonzept nachempfunden
+ist und damit unseren didaktisch-methodischen Vorstellungen viel eher entspricht. 
+ 
+Bei #on("b")#gs-Warenhaus#off("b")# werden etwa benutzte 'eigene' Befehle #on("b")#innerhalb derselben#off("b")#
+Programmdatei 'erklärt' und zwar #on("b")#nach#off("b")# dem Ende des eigentlichen 'Haupt­
+programms', d.h. also nach der Zeile <ENDE PROGRAMM>. Mit Hilfe dieser Mög­
+lichkeit könnte das obige Programm besser strukturiert etwa so aussehen: 
+ 
+#on("b")#
+   PROGRAMM Rechnung schreiben 
+     neues Blatt 
+     Kundennummer lesen 
+     WENN nicht Stoptaste gedrückt 
+       einkaufen mit Rechnung 
+     ENDE WENN 
+   ENDE PROGRAMM 
+ 
+   einkaufen mit Rechnung: 
+     Rechnungskopf 
+     WIEDERHOLE 
+       Artikelnummer lesen 
+       Artikel eventuell kaufen 
+     BIS Stoptaste gedrückt 
+     Abrechnung 
+#page# 
+   Artikel eventuell kaufen: 
+     WENN nicht Stoptaste gedrückt 
+       Artikel kaufen 
+     ENDE WENN 
+#off("b")# 
+ 
+ 
+Sie sehen, das Programm ist so zwar etwas länger, aber erheblich übersichtlicher
+geworden. Für 'neue Befehle' und die zugehörigen 'Befehlserklärungen' gelten
+folgende Grundsätze: 
+ 
+-  Die 'Befehlserklärungen' müssen #on("b")#nach#off("b")# <ENDE PROGRAMM> aufgelistet
+   werden. Die Reihenfolge ist beliebig. 
+ 
+-  Eine 'Befehlserklärung' besteht aus dem zu erklärenden Befehl in (bis auf Leer­
+   zeichen) völlig identischer Schreibweise (!) und einem nachfolgenden Doppel­
+   punkt (:). 
+ 
+-  Ein 'neuer Befehl' darf alle möglichen Zeichen enthalten außer einem Doppel­
+   punkt (:). Außerdem darf solch ein Befehl #on("b")#nicht#off("b")# mit einem 'Schlüsselwort'
+   beginnen (vgl. Kapitel 6.2). 
+ 
+-  In 'Befehlserklärungen' können neben den Grundbefehlen auch wieder 'neue
+   Befehle' benutzt werden, die dann wiederum erklärt werden müssen. 
+ 
+-  Befehle dürfen nur #on("b")#einmal#off("b")# erklärt werden, auch wenn sie mehrfach benutzt
+   werden. 
+ 
+-  Es dürfen nur Befehle erklärt werden, die irgendwo auch wirklich benutzt
+   werden. 
+ 
+-  Befehlserklärungen sind nur möglich für #on("b")#Ausführungs-Befehle#off("b")#. Es lassen sich
+   also z.B. keine neuen Bedingungen oder Kontrollstrukturen erklären! 
+ 
+-  Es dürfen innerhalb eines Programms maximal 20 verschiedene 'neue Befehle'
+   verwendet werden. (Diese Grenze dürfte in Warenhaus-Programmen kaum ein­
+   mal erreicht werden!) 
+#page# 
+Formale Verstöße gegen diese Regeln werden bei dem Übersetzungsvorgang sofort
+beim Auftauchen des ersten Fehlers zur Korrektur angeboten. Dabei wird in der
+oberen Bildschirmhälfte das Programm editiert, wobei der Cursor an den Anfang der
+Zeile gesetzt wird, in der sich der (erste) Fehler befindet. In der unteren Bildschirm­
+hälfte wird über den Paralleleditor in einem 'notebook' die Art des Fehlers mit An­
+gabe der Zeilennummer genauer beschrieben. 
+ 
+In der Regel wird hier nur auf #on("b")#einen#off("b")# (nämlich den ersten auftauchenden) Fehler
+hingewiesen, so daß Sie das Programm evtl. mehrfach starten müssen, bis alle Fehler
+erkannt und beseitigt sind. Manchmal tauchen im Fehler-'notebook' aber auch
+mehrere Fehlermeldungen auf (z.B. wenn 'neue Befehle' nicht erklärt oder erklärte
+Befehle nicht benutzt wurden). In Extremfällen kann es dabei dazu kommen, daß
+nicht mehr das ganze Fehler-'notebook' auf dem Bildschirm sichtbar ist. In diesem
+Fall können Sie mit der Tastenfolge <ESC><w> den Cursor zwischen den beiden
+Bildschirmhälften hin- und herschalten und mit den Pfeiltasten evtl. nicht-sichtbare
+Teile des 'notebooks' oder der Programmdatei auf den Bildschirm holen. (Für
+genauere Informationen über den Umgang mit dem EUMEL-Editor lesen Sie bitte im
+EUMEL-Benutzerhandbuch nach.) 
+ 
+ 
+#on("b")#6.2  Kontrollstrukturen#off("b")# 
+ 
+Sowohl in ELAN-Programmen, als auch in GRIN-Programmen werden Kontroll­
+strukturen durch 'Schlüsselworte' gekennzeichnet, die grundsätzlich in
+GROSSBUCHSTABEN geschrieben werden müssen, um sie deutlich gegenüber Aus­
+führungsbefehlen und Bedingungen abzuheben. In GRIN-Programmen gibt es
+Schlüsselworte für den Anfang und das Ende eines Programms sowie für Schleifen
+und einseitige Abfragen. Wir notieren hier nur die in GRIN-Programmen möglichen
+Kontrollstrukturen und geben, wenn vorhanden, die zugehörige ELAN-Übersetzung in
+Klammern an. 
+ 
+ 
+#on("b")#Programm-Anfang/Ende:#off("b")# 
+ 
+   #on("b")#PROGRAMM#off("b")# <Programmname> 
+     <Anweisung 1> 
+     <Anweisung 2> 
+          . 
+          . 
+   #on("b")#ENDE PROGRAMM#off("b")# 
+ 
+ 
+Jedes GRIN-(Haupt-)Programm beginnt mit dem Schlüsselwort 'PROGRAMM', gefolgt
+von einem frei wählbaren Programmnamen, der jedoch in dieselbe Zeile passen
+muß. Die Zeile 'ENDE PROGRAMM' zeigt das Ende eines GRIN-(Haupt-)Programms
+an. Sowohl 'PROGRAMM', als auch 'ENDE PROGRAMM' dürfen in einer Programm­
+datei nur #on("b")#einmal#off("b")# verwendet werden. Entsprechende Schlüsselworte in ELAN-
+Programmen gibt es nicht. 
+ 
+ 
+#on("b")#Schleifen:#off("b")# 
+ 
+Schleifen müssen innerhalb des Hauptprogramms oder der Befehlserklärung, in der
+sie geöffnet werden, auch wieder geschlossen werden. Schachtelungen sind zwar
+zulässig, sollten aber aus Gründen der Übersichtlichkeit vermieden werden. Soll
+dennoch innerhalb einer Schleife eine weitere Schleife verwendet werden, so sollte die
+innere Schleife über einen 'neuen Befehl' in eine Befehlserklärung 'ausgelagert'
+werden. Folgende Schleifenarten sind möglich: 
+ 
+a) Zählschleife: 
+ 
+   #on("b")#WIEDERHOLE#off("b")# <n> #on("b")#MAL#off("b")#    (ELAN: INT VAR i; 
+     <Anweisung 1>              FOR i FROM 1 UPTO n REPEAT 
+     <Anweisung 2>                . 
+          .                       . 
+          .                       . 
+   #on("b")#ENDE WIEDERHOLE#off("b")#              END REPEAT) 
+ 
+ 
+Die Anweisungen innerhalb der Schleife werden <n> - mal ausgeführt. 
+ 
+ 
+b) Schleife mit Ausgangsbedingung: 
+ 
+ 
+   #on("b")#WIEDERHOLE#off("b")#            (ELAN: REPEAT 
+     <Anweisung 1>                . 
+     <Anweisung 2>                . 
+          .                       . 
+          .                       . 
+   #on("b")#BIS#off("b")# <Bedingung>              UNTIL bedingung END REPEAT) 
+ 
+ 
+Die Anweisungen innerhalb der Schleife werden mindestens einmal ausgeführt und
+dann solange wiederholt, bis die Bedingung erfüllt ist. Bei der Programmierung ist
+darauf zu achten, daß durch die Anweisungen die Bedingung erfüllt werden kann,
+denn sonst ist das Resultat eine 'Endlosschleife', deren Ausführung nur durch einen
+totalen Programmabbruch (<ESC><h>) beendet werden kann. 
+ 
+ 
+c) Zählschleife mit Ausgangsbedingung: 
+ 
+ 
+   #on("b")#WIEDERHOLE#off("b")# <n> #on("b")#MAL#off("b")#    (ELAN: INT VAR i; 
+     <Anweisung 1>              FOR i FROM 1 UPTO n REPEAT 
+     <Anweisung 2>                . 
+          .                       . 
+          .                       . 
+   #on("b")#BIS#off("b")# <Bedingung>              UNTIL bedingung END REPEAT) 
+ 
+ 
+Die Anweisungen innerhalb der Schleife werden <n>-mal ausgeführt. Im Gegensatz
+zur reinen Zählschleife können die Wiederholungen jedoch vorzeitig abgebrochen
+werden, nämlich dann, wenn nach irgendeinem Schleifendurchlauf die Bedingung
+erfüllt ist. 
+ 
+ 
+d) Endlosschleife: 
+ 
+ 
+   #on("b")#WIEDERHOLE#off("b")#            (ELAN: REPEAT 
+     <Anweisung 1>                . 
+     <Anweisung 2>                . 
+          .                       . 
+          .                       . 
+   #on("b")#ENDE WIEDERHOLE#off("b")#              END REPEAT) 
+ 
+ 
+Die Anweisungen innerhalb der Schleife werden immer wieder ausgeführt. Da keine
+begrenzte Anzahl von Durchläufen und auch keine Abbruchbedingung angegeben ist,
+kann diese Schleife nur durch einen totalen Programmabbruch (<ESC><h>)
+beendet werden. 
+ 
+(Die Schleifenarten c) und d) sind in der Soester WARENHAUS-Software nicht vor­
+ handen, ergaben sich bei der Konstruktion des #on("b")#gs-Warenhaus#off("b")#-Übersetzers wegen
+ der analogen Strukturen in ELAN jedoch quasi "von selbst", so daß wir sie auch
+ zugelassen haben. Schleifen mit Eingangsbedingung (ELAN: WHILE bedingung
+ REPEAT ... END REPEAT) sind für GRIN-Programme jedoch nicht realisiert.) 
+ 
+ 
+#on("b")#Einseitige Abfragen:#off("b")# 
+ 
+ 
+   #on("b")#WENN#off("b")# <Bedingung>      (ELAN: IF bedingung 
+     <Anweisung 1>                 THEN anweisung 1; 
+     <Anweisung 2>                      anweisung 2; 
+          .                                 . 
+          .                                 . 
+   #on("b")#ENDE WENN#off("b")#                    END IF) 
+ 
+ 
+Die Anweisungen werden nur ausgeführt, wenn die Bedingung erfüllt ist. (Eine Ent­
+sprechung zu der in ELAN möglichen 'zweiseitigen Abfrage' (IF ... THEN ... ELSE ...
+END IF) gibt es in der GRIN-Version nicht!) 
+ 
+Eine im Hauptprogramm oder in einer Befehlserklärung begonnene Abfrage ('WENN
+...') muß auch im selben Programmteil wieder beendet werden. Ähnlich wie bei
+Schleifen ist die Schachtelung von Abfragen innerhalb des Hauptprogramms oder
+einer Befehlserklärung zwar zulässig, führt aber zu unübersichtlichen Programmen.
+Auch hier sollte man innerhalb einer Abfrage eventuell notwendige weitere Abfragen
+durch 'neue Befehle' in Befehlserklärungen auslagern. 
+ 
+ 
+#on("b")#Zulässige Bedingungen:#off("b")# 
+ 
+#on("b")#Stoptaste gedrückt#off("b")#    (ELAN: stoptaste gedrückt) 
+ 
+   Die Bedingung ist erfüllt (d.h. liefert den Wert 'wahr'), wenn während des bis­
+   herigen Programmablaufs die Tastenfolge <ESC><q> getippt worden ist;
+   sonst ist sie nicht erfüllt (Wahrheitswert 'falsch'). (Das Tippen von <ESC><q>
+   beim Verlassen einer Datei hat jedoch #on("b")#keinen#off("b")# Einfluß auf den Wahrheitswert der
+   Bedingung!) 
+ 
+   Bei jeder Ausführung der Befehle 'Artikelnummer lesen', 'Kundennummer lesen'
+   und 'Auskunft' wird der Wahrheitswert der Bedingung zunächst immer auf
+   'falsch' gesetzt (siehe 6.3), so daß die Abfrage der Bedingung nach einem dieser
+   Befehle nur dann 'wahr' liefert, wenn #on("b")#während#off("b")# oder #on("b")#nach#off("b")# der letztmaligen Aus­
+   führung eines der drei Befehle <ESC><q> getippt wurde; ein etwa vorher
+   erfolgtes Tippen dieser Tastenfolge ist somit wirkungslos! 
+ 
+ 
+#on("b")#nicht Stoptaste gedrückt#off("b")#    (ELAN: NOT stoptaste gedrückt) 
+ 
+   Dieses ist das logische Gegenteil von 'Stoptaste gedrückt': 'nicht Stoptaste ge­
+   drückt' ist erfüllt, wenn 'Stoptaste gedrückt' #on("b")#nicht#off("b")# erfüllt ist und umgekehrt. 
+ 
+Um Probleme bei der Arbeit mit Terminals zu vermeiden, die nicht über den
+deutschen Zeichensatz verfügen (Umlaute!), ist bei beiden Bedingungen auch die
+Schreibweise 'gedrueckt' erlaubt. 
+ 
+ 
+ 
+#on("b")#6.3  Detailbeschreibung der Warenhaus-Grundbefehle#off("b")# 
+ 
+Wie bereits in 6.1 erwähnt, ist die im folgenden vorgegebene Schreibweise der Grund­
+befehle bezüglich Groß- und Kleinschreibung verbindlich; Leerzeichen dagegen
+können beliebig eingefügt oder auch weggelassen werden. Fett gedruckt steht immer
+der GRIN-Befehl, in Klammern dahinter der zugehörige ELAN-Befehl. 
+ 
+ 
+#on("b")#Artikelnummer lesen#off("b")#  (ELAN: artikelnummer lesen) 
+ 
+  -  Der Wahrheitswert der Bedingung 'Stoptaste gedrückt' wird zunächst auf
+     'falsch' gesetzt. 
+  -  Der Benutzer wird aufgefordert, eine Artikelnummer einzugeben. Je nach
+     Einstellung der 'Eingabeart' (vgl. Kapitel 5.3) erfolgt die Eingabe durch Ein­
+     tippen einer Zahl über die Tastatur oder durch Einschieben einer Warenkarte
+     in das Lesegerät. Eingaben über die Tastatur sind mit <RETURN> abzu­
+     schließen. Akzeptiert werden nur Werte von 1 bis 15, ansonsten erfolgt eine
+     Warnung, und die Eingabe wird wiederholt. 
+  -  Durch Tippen der Tastenfolge <ESC><q> kann dieser Befehl abgebrochen
+     werden, ohne daß eine Artikelnummer eingelesen wird. In diesem Falle wird
+     der Wahrheitswert der Bedingung 'Stoptaste gedrückt' auf 'wahr' gesetzt, sonst
+     bleibt der Wert auf 'falsch'. 
+  -  Durch Tippen der Tastenfolge <ESC><h> wird die Ausführung des
+     gesamten Programms abgebrochen. 
+ 
+ 
+#on("b")#Artikeldaten eingeben#off("b")#  (ELAN: artikeldaten eingeben) 
+ 
+  -  Der Befehl setzt voraus, daß zuvor eine Artikelnummer eingelesen wurde,
+     ansonsten erfolgt eine entsprechende Fehlermeldung. 
+  -  Die Angaben zu einem Artikel (Name, Preis, Mindestbestand, Bestand) können
+     eingegeben bzw. verändert werden. 
+  -  Alle Eingaben sind mit <RETURN> oder der Tastenfolge <ESC><q>
+     abzuschließen. Durch <ESC><q> wird der Wahrheitswert der Bedingung
+     'Stoptaste gedrückt' auf 'wahr' gesetzt. 
+  -  Nach Abschluß der Eingaben werden die Artikeldaten in der Filial-Verwaltung
+     gespeichert, worauf auch kurz hingewiesen wird. 
+  -  Durch Tippen der Tastenfolge <ESC><h> während der Eingaben wird die
+     Ausführung des gesamten Programms abgebrochen. 
+ 
+ 
+#on("b")#Kundennummer lesen#off("b")#  (ELAN: kundennummer lesen) 
+ 
+  -  Der Wahrheitswert der Bedingung 'Stoptaste gedrückt' wird zunächst auf
+     'falsch' gesetzt. 
+  -  Der Benutzer wird aufgefordert, eine Kundennummer einzugeben. Je nach
+     Einstellung der 'Eingabeart' (vgl. Kapitel 5.3) erfolgt die Eingabe durch Ein­
+     tippen einer Zahl über die Tastatur oder durch Einschieben einer Kundenkarte
+     in das Lesegerät. Eingaben über die Tastatur sind mit <RETURN> abzu­
+     schließen. Akzeptiert werden nur Werte von 129 bis 159, ansonsten erfolgt eine
+     Warnung, und die Eingabe wird wiederholt. 
+  -  Durch Tippen der Tastenfolge <ESC><q> kann dieser Befehl abgebrochen
+     werden, ohne daß eine Kundennummer eingelesen wird. In diesem Falle wird
+     der Wahrheitswert der Bedingung 'Stoptaste gedrückt' auf 'wahr' gesetzt, sonst
+     bleibt der Wert auf 'falsch'. 
+  -  Durch Tippen der Tastenfolge <ESC><h> wird die Ausführung des
+     gesamten Programms abgebrochen. 
+ 
+ 
+#on("b")#Kundendaten eingeben#off("b")#  (ELAN: kundendaten eingeben) 
+ 
+  -  Der Befehl setzt voraus, daß zuvor eine Kundennummer eingelesen wurde,
+     ansonsten erfolgt eine entsprechende Fehlermeldung. 
+  -  Die Angaben zu einem Kunden (Name, Vorname, Geschlecht) können einge­
+     geben bzw. verändert werden. 
+  -  Alle Eingaben sind mit <RETURN> oder der Tastenfolge <ESC><q>
+     abzuschließen. Durch <ESC><q> wird der Wahrheitswert der Bedingung
+     'Stoptaste gedrückt' auf 'wahr' gesetzt. 
+  -  Nach Abschluß der Eingaben werden die Kundendaten sowohl in der Filial-
+     Verwaltung als auch in der Zentrale gespeichert, worauf auch kurz hingewiesen
+     wird. 
+  -  Durch Tippen der Tastenfolge <ESC><h> während der Eingaben wird die
+     Ausführung des gesamten Programms abgebrochen. 
+ 
+ 
+#on("b")#neues Blatt#off("b")#  (ELAN: neues blatt) 
+ 
+  -  Das Rechnungsfenster auf dem Bildschirm wird gelöscht. 
+  -  Für die Ausgabe der nächsten Rechnung auf dem Drucker wird eine neue
+     Rechnungsdatei bereitgestellt. 
+ 
+ 
+#on("b")#Rechnungskopf#off("b")#  (ELAN: rechnungskopf) 
+ 
+  -  Ein Rechnungskopf wird auf dem Bildschirm ausgegeben. Falls zuvor eine
+     Kundenummer eingelesen worden ist, unter der bereits Kundendaten einge­
+     geben wurden, erscheint der Name des betreffenden Kunden im Rechnungs­
+     kopf. 
+  -  Der Rechnungskopf wird für einen eventuellen späteren Ausdruck in die
+     Rechnungsdatei geschrieben. 
+ 
+ 
+#on("b")#Artikel kaufen#off("b")#  (ELAN: artikel kaufen) 
+ 
+  -  Der Befehl setzt voraus, daß zuvor eine Artikelnummer eingelesen worden ist,
+     ansonsten erfolgt eine entsprechende Fehlermeldung. 
+  -  Artikelname und -preis werden auf den Bildschirm und in die Rechnungsdatei
+     geschrieben. 
+  -  Der Kauf wird intern in den entsprechenden Filial-Dateien registriert. 
+ 
+ 
+#on("b")#Abrechnung#off("b")#  (ELAN: abrechnung) 
+ 
+  -  Die Preise der gekauften Artikel werden addiert. 
+  -  Die Summe wird auf dem Bildschirm angezeigt und in die Rechnungsdatei
+     geschrieben. 
+  -  Der Benutzer wird gefragt, ob die Rechnung ausgedruckt werden soll. 
+ 
+ 
+#on("b")#Auskunft#off("b")#  (ELAN: auskunft) 
+ 
+  -  Der Wahrheitswert der Bedingung 'Stoptaste gedrückt' wird zunächst auf
+     'falsch' gesetzt. 
+  -  Der Benutzer wird aufgefordert, eine Codenummer einzugeben. Je nach Ein­
+     stellung der 'Eingabeart' (vgl. Kapitel 5.3) erfolgt die Eingabe durch Eintippen
+     einer Zahl über die Tastatur oder durch Einschieben einer Codekarte in das
+     Lesegerät. Eingaben über die Tastatur sind mit <RETURN> abzuschließen.
+     Akzeptiert werden nur zulässige Werte, ansonsten erfolgt eine Warnung, und
+     die Eingabe wird wiederholt. Die Bedeutungen der einzelnen Auskunftscodes
+     sind in Kapitel 5.4 unter der Menufunktion 'Auskunft einholen' beschrieben. 
+  -  Durch Tippen der Tastenfolge <ESC><q> kann der Befehl abgebrochen
+     werden, ohne daß eine Codenummer eingelesen wird. In diesem Falle wird der
+     Wahrheitswert der Bedingung 'Stoptaste gedrückt' auf 'wahr' gesetzt, sonst
+     bleibt der Wert auf 'falsch'. 
+  -  Durch Tippen der Tastenfolge <ESC><h> wird die Ausführung des
+     gesamten Programms abgebrochen. 
+ 
+ 
+#on("b")#Bildschirm neu#off("b")#  (ELAN: bildschirm neu) 
+ 
+  -  Der Programm-Eingangsbildschirm wird neu aufgebaut. Der Befehl wird
+     benötigt, wenn die Fenstereinteilung auf dem Bildschirm wiederhergestellt
+     werden soll (z.B. nach Ausgabe einer Liste bei dem Befehl 'Auskunft'). 
+  -  Der Befehl wird beim Starten eines GRIN-Programms automatisch ausgeführt;
+     bei ELAN-Programmen wird er automatisch am Anfang eines jeden Programms
+     eingefügt, wenn das Programm nicht mit diesem Befehl beginnt. 
+ 
+ 
+Neben diesen Befehlen stehen für ELAN-Programme noch drei weitere zur Verfügung,
+die nicht zum GRIN-Befehlssatz gehören: 
+ 
+        nachbestellen, 
+        dezimalwert lesen, 
+        bitmuster lesen. 
+ 
+Diese Befehle entsprechen in ihrer Wirkung den gleichnamigen Menufunktionen
+unter dem Oberbegriff 'Kommandos', die in Kapitel 5.4 beschrieben sind. 
+ 
+ 
+
diff --git a/doc/warenhaus/gs-Warenhaus-7 b/doc/warenhaus/gs-Warenhaus-7
new file mode 100644
index 0000000..3a55dfe
--- /dev/null
+++ b/doc/warenhaus/gs-Warenhaus-7
@@ -0,0 +1,235 @@
+#limit (11.0)##pagelength (16.5)##block# 
+#start (2.0,0.0)# 
+#page (69)# 
+#headodd# 
+#center#gs-Warenhaus#right#% 
+ 
+#end# 
+#headeven# 
+%#center#gs-Warenhaus 
+ 
+#end# 
+#center#1 
+ 
+#center##on("b")#7  Weitere Kommandos (für Systembetreuer)#off("b")# 
+ 
+ 
+Wenn Sie #on("b")#gs-Warenhaus#off("b")# installiert haben und mit dem Aufbau des Systems nach
+der automatischen Generierung zufrieden sind, dann ist dieses Kapitel nicht wichtig
+für Sie. Wir erklären Ihnen hier die Befehle, mit denen Sie die Einstellungen, die bei
+der Installation vorgenommen wurden, auch nachträglich noch ändern können.
+Beachten Sie bitte, daß aus Sicherheitsgründen eine Einstellungs#on("b")#änderung#off("b")# i.a. nur in
+der Task möglich ist, in der die entsprechende Einstellung vorgenommen wurde, es
+sei denn, dort wurde eine Einstellung gänzlich aufgehoben. Außerdem werden Ein­
+stellungsänderungen stets nur an Sohntasks weitergegeben ("vererbt"), die #on("b")#nach#off("b")# der
+Änderung angemeldet werden! 
+ 
+Die Standard-Installation sieht z.B. nur die Einrichtung #on("b")#einer#off("b")# Warenhaus-Hauptstelle
+vor. Wenn Sie tatsächlich nur eine Hauptstelle eingerichtet haben, nun aber doch
+mehrere Hauptstellen (für verschiedene Lerngruppen) betreiben wollen, so brauchen
+Sie das Programm nicht erneut zu insertieren! Machen Sie besser in der bisherigen
+Hauptstellen-Task den Hauptstellenstatus mit dem Kommando 'warenhaus haupt­
+stelle (FALSE)' rückgängig und richten Sie in Sohntasks mit dem Kommando 'waren­
+haus hauptstelle (TRUE)' wieder neue Hauptstellen ein. Außerdem können Sie in
+Hauptstellen-Tasks die Version für die Programmierschnittstelle umstellen ('grin
+(TRUE)' bzw. 'grin (FALSE)'). 
+ 
+Ähnlich verhält es sich mit dem Betrieb eines Adapters für das Kartenleser-Interface.
+Auch hier ist die Standard-Einstellung u.U. nur für den Betrieb #on("b")#eines#off("b")# Adapters ausge­
+legt. Möchten Sie mehrere Kartenleser anschließen, so sind bei der Verwendung von
+MUFIs im Terminalkanal keine Änderungen nötig, da hier jede Filialtask sowieso nur
+auf das MUFI zugreifen kann, das in den Kanal des Terminals geschaltet ist, an das
+die Task gekoppelt ist. Möchten Sie jedoch mehrere Kartenleser über Adapter an
+separaten seriellen Schnittstellen ansprechen, so müssen Sie dem System mehrere
+Kanalnummern mitteilen, die für verschiedene Filialtasks ja durchaus unterschied­
+lich sein können. Am geschicktesten erscheint es in diesem Fall, unter einer Haupt­
+stelle mehrere "Zwischentasks" einzurichten, in diesen jeweils die Interface-
+Kanalnummern festzulegen und die Filialtasks als Söhne dieser "Zwischentasks"
+anzumelden. Benennen Sie die "Zwischentasks" so, daß die eingestellte Kanal­
+nummer aus dem Namen ersichtlich ist, so ist gleich bei der Anmeldung einer Filial­
+task klar, welcher Kartenleser von dieser Task aus angesprochen werden kann. 
+ 
+Um diesen Aufbau zu realisieren, sollten Sie zunächst in der entsprechenden Haupt­
+stellentask einen etwa eingerichteten Direktstart mit dem Kommando 'warenhaus
+direktstart (FALSE)' aufheben. Ebenfalls in der Hauptstellentask wird dann mit dem
+Kommando 'init interface channel' eine etwa vorhandene Kanaleinstellung gelöscht,
+wenn Sie bei der Aufforderung 'Gib Interface-Kanal:' eine '0' eingeben.  Nun richten
+Sie für jeden vorhandenen Adapter (natürlich müssen auch entsprechend viele freie
+serielle Schnittstellen zur Verfügung stehen!) eine "Zwischentask" als Sohn der
+Hauptstellentask ein (z.B. 'Kanal 5', 'Kanal 6' etc.) und geben dort jeweils wieder das
+Kommando 'init interface channel'. Bei der Abfrage 'Gib Interface-Kanal:' geben Sie
+dann die entsprechende Kanalnummer ein (in unserem Beispiel 5 oder 6 etc.). Alle
+Söhne der Zwischentask 'Kanal 5' z.B. können dann (abwechselnd) den Kartenleser
+benutzen, der an den Adapter an Kanal 5 angeschlossen ist. In diesen Zwischentasks
+können Sie, wenn Sie möchten, mit dem Kommando 'warenhaus direktstart (TRUE)'
+einen Direktstart für die neu anzumeldenden Sohntasks (Filialen) einrichten.
+Ansonsten wird #on("b")#gs-Warenhaus#off("b")# in den Sohntasks aus der 'gib Kommando' - Ebene
+mit dem Befehl 'warenhaus' gestartet (vgl. Kapitel 3.3). 
+ 
+Sollten Sie beim Betrieb eines Codekartenlesers feststellen, daß die Wartezeit beim
+Einlesen einer Codekarte zu kurz oder zu lang ist, so können Sie auch diese ändern.
+Da die Wartezeit durch eine Schleife realisiert ist, in der laufend Werte vom Interface
+gelesen werden, ist sie abhängig von der Geschwindigkeit des verwendeten Rechners
+und von der gewählten Interface-Anpassung. Die Veränderung der Wartezeit erfolgt
+mit dem Kommando 'eingabesicherheit (n)', wobei n eine 'Integer'-Zahl sein muß.
+Bei sehr langsamen Systemen hat sich ein Wert von 3 als sinnvoll herausgestellt; bei
+schnellen Rechnern muß n etwa 10 oder noch größer sein. Ermitteln Sie den für
+Ihren Rechner geeigneten Wert bitte durch Ausprobieren. (Standardmäßig eingestellt
+ist n = 5.) 
+ 
+Mit Hilfe von drei Informationsprozeduren können Sie Informationen über den
+Systemzustand einholen: 'put (hauptstellenname)' liefert den Namen der zu­
+ständigen Hauptstellen-Task, 'put (interface anpassung)' zeigt den Namen der bei
+der Installation gewählten Interfaceanpassung für den Kartenleser, und 'put (inter­
+face channel)' liefert die Nummer des Kanals, über den ein Interface an separater
+serieller Schnittstelle angesprochen wird. 
+ 
+ 
+ 
+#on("b")#Detailbeschreibung der Befehle#off("b")#: 
+ 
+ 
+#on("b")#PROC eingabesicherheit (INT CONST n):#off("b")# 
+ 
+   -  stellt die Wartezeit beim Einlesen einer Artikel-, Kunden- oder Auskunfts­
+      codenummer in Abhängigkeit vom Absolutbetrag von n ein. Bei langsamen
+      Rechnern sollte abs(n) klein (ca. 3), bei schnellen Rechnern größer (ca. 10)
+      sein. 
+   -  Standardeinstellung ist 5. 
+   -  Der Befehl kann in jeder Task gegeben werden, in der #on("b")#gs-Warenhaus#off("b")#
+      insertiert ist. 
+ 
+ 
+#on("b")#PROC grin (BOOL CONST entscheidung):#off("b")# 
+ 
+   -  ist nur in Hauptstellentasks aufrufbar und in Tasks, die keiner Hauptstellen­
+      task untergeordnet sind. 
+   -  stellt die Version für die Programmierschnittstelle gemäß der 'entscheidung'
+      ein: 
+      TRUE ---> GRIN-Version, FALSE ---> ELAN-Version. 
+ 
+   Fehlerfälle: 
+      -  Dieser Befehl darf nur von der Task '...' aus gegeben werden! 
+ 
+ 
+#on("b")#TEXT PROC hauptstellenname:#off("b")# 
+ 
+   -  liefert den Namen der zuständigen Hauptstellentask. 
+   -  liefert 'niltext' (""), wenn in diesem Zweig des Taskbaumes noch keine
+      Hauptstelle existiert; es ist dann kein Warenhaus-Betrieb möglich! (vgl.
+      'PROC warenhaus hauptstelle') 
+ 
+ 
+#on("b")#PROC init interfacechannel:#off("b")# 
+ 
+   -  initialisiert eine unbenannte Sohntask ("-") zum Ansprechen des Interface­
+      systems über eine separate serielle Schnittstelle und existiert deshalb nur bei
+      den Anpassungen für 'MUFI als Endgerät' und 'AKTRONIK-Adapter'. 
+   -  erfragt zunächst eine Kanalnummer ('Gib Interface-Kanal:'); zulässig sind
+      Eingaben von 0 bis 24. 
+   -  löscht eine evtl. bereits vorhandene unbenannte Sohntask ("-"). 
+   -  richtet bei Eingabe einer Kanalnummer > 0 eine neue unbenannte Sohntask
+      ein und sperrt dieses Kommando für Sohntasks, die danach angemeldet
+      werden. 
+   -  hebt eine etwa gesetzte Sperrung bei Eingabe von 0 als Kanalnummer wieder
+      auf. 
+ 
+   Fehlerfälle: 
+      -  Dieses Kommando kann nur von der Task '...' aus gegeben werden! 
+      -  Unzulässige Kanalnummer! 
+ 
+ 
+#on("b")#TEXT PROC interface anpassung:#off("b")# 
+ 
+   -  liefert den Namen der bei der Installation ausgewählten Anpassung. Möglich
+      sind zur Zeit: 
+ 
+           "ohne Kartenleser", 
+           "mit Kartenleser an AKTRONIC-Adapter", 
+           "mit Kartenleser an MUFI als Endgerät", 
+           "mit Kartenleser an MUFI im Terminalkanal". 
+ 
+ 
+#on("b")#INT PROC interface channel:#off("b")# 
+ 
+   -  existiert nur bei den Anpassungen für den AKTRONIC-Adapter und MUFI als
+      Endgerät. 
+   -  liefert die Kanalnummer der seriellen Schnittstelle, über die das Interface­
+      system angesprochen wird. 
+   -  wird der Wert 0 geliefert, so kann in der Task keine Eingabe über einen
+      Kartenleser erfolgen (siehe 'PROC init interfacechannel'). 
+ 
+ 
+#on("b")#PROC warenhaus:#off("b")# 
+ 
+   -  ist nicht in Hauptstellentasks aufrufbar. 
+   -  startet #on("b")#gs-Warenhaus#off("b")# aus der 'gib Kommando' - Ebene oder wird bei einge­
+      richtetem Direktstart automatisch aufgerufen. 
+   -  richtet eine Sohntask als Filialverwaltung ein und kennzeichnet damit die
+      eigene Task für das System als 'aktive' Filiale. Der Name dieser Sohntask
+      enthält den Namen der zuständigen Hauptstellentask und die Filialnummer,
+      unter der die Filiale geführt wird. Diese Filialnummer ist identisch mit der
+      Kanalnummer des angekoppelten Terminals. 
+   -  löscht die Filialverwaltungstask, wenn das Warenhaus-Menu geregelt mit
+      <ESC><q> verlassen wird. Zu Kollisionen bezüglich der Filialnummer
+      kann es somit nur kommen, wenn an einem Arbeitsplatz das WARENHAUS-
+      Menu ungeregelt verlassen wird (z.B. durch Tippen der SV-Taste) und dann
+      an demselben Arbeitsplatz eine neue Filiale angemeldet werden soll. In
+      diesem Fall erhält die neue Task #on("b")#keine#off("b")# Filialverwaltung als Sohntask und ist
+      damit für den Warenhaus-Betrieb nicht brauchbar. Deshalb wird hier nach
+      Ausgabe einer Fehlermeldung sofort gefragt, ob die Task gelöscht werden soll. 
+ 
+   Fehlerfälle: 
+      -  Dieser Befehl darf nur von Söhnen dieser Task aus gegeben werden! 
+      -  Keine uebergeordnete Task ist 'warenhaus hauptstelle'! 
+      -  Filiale <n> ist bereits besetzt durch TASK '...'! 
+         Es ist so kein geregelter Warenhaus-Betrieb möglich! 
+ 
+ 
+#on("b")#PROC warenhaus direktstart (BOOL CONST entscheidung):#off("b")# 
+ 
+   -  richtet gemäß dem Wahrheitswert der 'entscheidung' einen Direktstart ein
+      oder hebt ihn wieder auf. 
+      Hat 'entscheidung' den Wert 'TRUE', so wird ein Direktstart eingerichtet. Es
+      erscheint zunächst die Frage 'Mit automatischem Löschen (j/n)?'. Durch den
+      Direktstart gelangt man beim Anmelden einer Sohntask nicht in die 'gib
+      Kommando' - Ebene, sondern sofort in das WARENHAUS-Menu. Wird die
+      obige Frage mit <j> beantwortet, so werden Sohntasks nach dem Ausstieg
+      aus dem WARENHAUS-Menu sofort gelöscht; andernfalls wird erst noch ge­
+      fragt, ob gelöscht werden soll. Bei Verneinung erfolgt ein 'break'. Die Ein­
+      richtung eines Direktstarts wird vom System vermerkt und der Befehl darauf­
+      hin in allen untergeordneten Tasks gesperrt. Sowohl der Direktstart als auch
+      die Sperrung sind nur wirksam für Sohntasks, die #on("b")#nach#off("b")# Ausführung dieses
+      Befehls angemeldet werden. 
+      Hat 'entscheidung' den Wert 'FALSE', so wird ein etwa eingerichteter Direkt­
+      start und die damit verbundene Sperrung des Befehls für neue Sohntasks
+      wieder aufgehoben. Die Aufhebung ist nur möglich in der Task, von der aus
+      der Direktstart eingerichtet wurde. 
+ 
+   Fehlerfälle: 
+      -  Der Direktstart kann nur aus der Task '...' geaendert werden! 
+ 
+ 
+#on("b")#PROC warenhaus hauptstelle (BOOL CONST entscheidung):#off("b")# 
+ 
+   -  macht je nach Wahrheitswert der 'entscheidung' eine Task zur Hauptstellen­
+      task ('TRUE') bzw. hebt diesen Status wieder auf ('FALSE'). Eine Task kann
+      nur Hauptstelle werden, wenn noch keine übergeordnete Task Hauptstelle ist.
+      Der Hauptstellenstatus kann danach auch nur in dieser Task wieder aufge­
+      hoben werden. 
+   -  löscht bei der Einrichtung der Hauptstelle eine etwa bereits vorhandene
+      "Zentrale" und richtet automatisch eine neue "Zentrale" in Form einer Sohn­
+      task ein, die den Namen der Vatertask mit dem Zusatz ".Zentrale" erhält und
+      in der später die zentrale Kundendatei gespeichert wird. Bei Aufhebung des
+      Hauptstellenstatus wird diese Task wieder gelöscht. 
+   -  fragt bei Einrichtung der Hauptstelle nach, ob ein Direktstart eingerichtet
+      werden soll ('Mit Direktstart (j/n)?') und ruft die Prozedur 'warenhaus
+      direktstart' entsprechend auf. 
+   -  Hebt bei Löschen des Hauptstellenstatus einen in der Task etwa einge­
+      richteten Direktstart automatisch auf. 
+ 
+   Fehlerfälle: 
+      -  Hauptstelle ist bereits die Task '...'! 
+      -  Dieses Kommando darf nur in der Task '...' gegeben werden! 
+ 
+
diff --git a/dos/block i-o b/dos/block i-o
new file mode 100644
index 0000000..554fcca
--- /dev/null
+++ b/dos/block i-o	
@@ -0,0 +1,180 @@
+PACKET disk block io DEFINES                    (* Copyright (C) 1986 *)
+                                                (* Frank Klapper      *)
+                                                (* 05.01.87           *)
+  read disk block,
+  read disk block and close work if error,
+  read disk cluster, 
+  write disk block,
+  write disk block and close work if error,
+  write disk cluster,
+  first non dummy ds page,
+
+  block no dump modus:
+
+BOOL VAR block no dump flag := FALSE;
+ 
+LET write normal = 0;
+
+INT CONST first non dummy ds page := 2;
+
+INT VAR error;
+
+PROC read disk block (DATASPACE VAR ds,
+                      INT CONST ds page no, 
+                      INT CONST block no):
+  IF block no dump flag THEN dump ("READ ", block no) FI;
+  check rerun;
+  read block (ds, ds page no, eublock (block no), error); 
+  IF error > 0
+    THEN lesefehler (error)
+  FI.
+ 
+END PROC read disk block;
+ 
+PROC read disk block (DATASPACE VAR ds,
+                      INT CONST ds page no, 
+                      REAL CONST block no):
+  IF block no dump flag THEN dump ("READ ", block no) FI;
+  check rerun;
+  read block (ds, ds page no, eublock (block no), error); 
+  IF error > 0
+    THEN lesefehler (error)
+  FI.
+ 
+END PROC read disk block;
+ 
+PROC read disk block and close work if error (DATASPACE VAR ds,
+                                              INT CONST ds page no, 
+                                              INT CONST block no):
+  IF block no dump flag THEN dump ("READ ", block no) FI;
+  check rerun;
+  read block (ds, ds page no, eublock (block no), error); 
+  IF error > 0
+    THEN close work;
+         lesefehler (error)
+  FI.
+ 
+END PROC read disk block and close work if error;
+ 
+PROC read disk block and close work if error (DATASPACE VAR ds,
+                                              INT CONST ds page no, 
+                                              REAL CONST block no):
+  IF block no dump flag THEN dump ("READ ", block no) FI;
+  check rerun;
+  read block (ds, ds page no, eublock (block no), error); 
+  IF error > 0
+    THEN close work;
+         lesefehler (error)
+  FI.
+ 
+END PROC read disk block and close work if error;
+
+PROC read disk cluster (DATASPACE VAR ds, 
+                        INT CONST first ds page no,
+                        REAL CONST cluster no): 
+  IF block no dump flag THEN dump ("CLUSTER ", cluster no) FI;
+  INT VAR i;
+  FOR i FROM 0 UPTO  sectors per cluster - 1 REP
+    read disk block (ds, first ds page no + i, block no + real (i))
+  PER.
+ 
+block no:
+  begin of cluster (cluster no).
+ 
+END PROC read disk cluster; 
+ 
+PROC lesefehler (INT CONST fehler code):
+  error stop (fehlertext).
+
+fehlertext:
+  SELECT fehler code OF
+    CASE 1: "Diskettenlaufwerk nicht betriebsbereit"
+    CASE 2: "Lesefehler"
+    OTHERWISE "Lesefehler " + text (fehler code)
+  END SELECT.
+
+END PROC lesefehler;
+
+PROC write disk block (DATASPACE CONST ds,
+                      INT CONST ds page no, 
+                      INT CONST block no):
+  IF block no dump flag THEN dump ("WRITE", block no) FI;
+  check rerun;
+  write block (ds, ds page no, write normal, eublock (block no), error); 
+  IF error > 0
+    THEN schreibfehler (error)
+  FI.
+ 
+END PROC write disk block;
+ 
+PROC write disk block (DATASPACE CONST ds,
+                      INT CONST ds page no, 
+                      REAL CONST block no):
+  IF block no dump flag THEN dump ("WRITE", block no) FI;
+  check rerun;
+  write block (ds, ds page no, write normal, eublock (block no), error); 
+  IF error > 0
+    THEN schreibfehler (error)
+  FI.
+ 
+END PROC write disk block;
+ 
+PROC write disk block and close work if error (DATASPACE CONST ds,
+                                              INT CONST ds page no, 
+                                              INT CONST block no):
+  IF block no dump flag THEN dump ("WRITE", block no) FI;
+  check rerun;
+  write block (ds, ds page no, write normal, eublock (block no), error); 
+  IF error > 0
+    THEN close work;
+         schreibfehler (error)
+  FI.
+ 
+END PROC write disk block and close work if error;
+ 
+PROC write disk block and close work if error (DATASPACE CONST ds,
+                                              INT CONST ds page no, 
+                                              REAL CONST block no):
+  IF block no dump flag THEN dump ("WRITE", block no) FI;
+  check rerun;
+  write block (ds, ds page no, write normal, eublock (block no), error); 
+  IF error > 0
+    THEN close work;
+         schreibfehler (error)
+  FI.
+ 
+END PROC write disk block and close work if error;
+
+PROC write disk cluster (DATASPACE CONST ds,
+                        INT CONST first ds page no,
+                        REAL CONST cluster no): 
+  IF block no dump flag THEN dump ("CLUSTER ", cluster no) FI;
+  INT VAR i;
+  FOR i FROM 0 UPTO sectors per cluster - 1 REP
+    write disk block (ds, first ds page no + i, block no + real (i))
+  PER.
+ 
+block no:
+  begin of cluster (cluster no).
+ 
+END PROC write disk cluster; 
+ 
+PROC schreibfehler (INT CONST fehler code):
+  error stop (fehlertext).
+
+fehlertext:
+  SELECT fehler code OF
+    CASE 1: "Diskettenlaufwerk nicht betriebsbereit"
+    CASE 2: "Schreibfehler"
+    OTHERWISE "Schreibfehler " + text (fehler code)
+  END SELECT.
+
+END PROC schreibfehler;
+
+PROC block no dump modus (BOOL CONST status):
+  block no dump flag := status
+
+END PROC block no dump modus;
+
+END PACKET disk block io;
+
diff --git a/dos/dir.dos b/dos/dir.dos
new file mode 100644
index 0000000..08456b5
--- /dev/null
+++ b/dos/dir.dos
@@ -0,0 +1,693 @@
+PACKET dir DEFINES                            (* Copyright (c) 1986, 87 *)
+                                              (* Frank Klapper          *)
+  open dir,                                   (* 02.03.88               *)
+  insert dir entry,
+  delete dir entry,
+  init dir ds,
+  file info,
+  format dir,
+
+  dir list,
+  file   exists,
+  subdir exists,
+  all files,
+  all subdirs:
+ 
+LET max dir entrys = 1000;
+
+(*-------------------------------------------------------------------------*)
+
+INITFLAG VAR dir block ds used := FALSE;
+DATASPACE VAR dir block ds;
+BOUND STRUCT (ALIGN dummy, ROW 64 REAL daten) VAR dir block;
+REAL VAR last read dir block no;
+
+PROC init dir block io:
+  last read dir block no := -1.0;
+  IF NOT initialized (dir block ds used)
+    THEN dir block ds := nilspace;
+         dir block := dir block ds
+  FI.
+
+END PROC init dir block io;
+
+PROC read dir block (REAL CONST block nr):
+  IF last read dir block no <> block nr
+    THEN last read dir block no := -1.0;
+         read disk block and close work if error (dir block ds, 2, block nr);
+         last read dir block no := block nr
+  FI.
+
+END PROC read dir block;
+
+PROC write dir block (REAL CONST block nr):
+  write disk block and close work if error (dir block ds, 2, block nr);
+  last read dir block no := block nr.
+
+END PROC write dir block;
+
+PROC write dir block:
+  IF last read dir block no < 0.0
+    THEN error stop ("Lesefehler")
+  FI;
+  write dir block (last read dir block no)
+
+END PROC write dir block;
+
+PROC get dir entry (TEXT VAR entry buffer, INT CONST block entry no):
+  (* 0 <= block entry no <= 15 *)
+  entry buffer := 32 * ".";
+  INT CONST replace offset := 4 * block entry no;
+  replace (entry buffer, 1, dir block.daten [replace offset + 1]);
+  replace (entry buffer, 2, dir block.daten [replace offset + 2]);
+  replace (entry buffer, 3, dir block.daten [replace offset + 3]);
+  replace (entry buffer, 4, dir block.daten [replace offset + 4]).
+
+END PROC get dir entry;
+
+PROC put dir entry (TEXT CONST entry buffer, INT CONST block entry no):
+  (* 0 <= block entry no <= 15 *)
+  INT CONST offset := 4 * block entry no;
+  dir block.daten [offset + 1] := entry buffer RSUB 1;
+  dir block.daten [offset + 2] := entry buffer RSUB 2;
+  dir block.daten [offset + 3] := entry buffer RSUB 3;
+  dir block.daten [offset + 4] := entry buffer RSUB 4.
+
+END PROC put dir entry;
+
+(*-------------------------------------------------------------------------*)
+
+LET DIRPOS = REAL;                  (* 16.0 * msdos block nr + entry no *)
+                                    (* 0 <= entry no <= 15              *)
+
+DIRPOS PROC dirpos (REAL CONST block nr, INT CONST entry nr):
+  block nr * 16.0 + real (entry nr).
+
+END PROC dir pos;
+
+REAL PROC block no (DIRPOS CONST p):
+  floor (p / 16.0)
+
+END PROC block no;
+
+INT PROC entry no (DIRPOS CONST p):
+  int (p MOD 16.0)
+
+END PROC entry no;
+
+PROC incr (DIRPOS VAR p):
+  p INCR 1.0.
+
+END PROC incr;
+
+(*-------------------------------------------------------------------------*)
+
+LET FREELIST = STRUCT (ROW max dir entrys DIRPOS stack,
+                       INT stacktop,
+                       DIRPOS begin of free area,
+                              end of dir,
+                       REAL dir root);                  (* erste Clusterno, 0 für Main Dir *)
+ 
+PROC init free list (FREELIST VAR flist, REAL CONST root):
+  flist.stacktop           := 0;
+  flist.begin of free area := dir pos (9.0e99, 0);
+  flist.end of dir         := dir pos (-1.0, 0);
+  flist.dir root           := root.
+
+END PROC init free list;
+ 
+PROC store (FREELIST VAR flist, DIRPOS CONST free pos):
+  flist.stacktop INCR 1;
+  flist.stack [flist.stack top] := free pos.
+
+END PROC store;
+
+PROC store begin of free area (FREELIST VAR flist, DIRPOS CONST begin):
+  flist.begin of free area := begin
+
+END PROC store begin of free area;
+
+PROC store end of dir (FREELIST VAR flist, DIRPOS CONST end):
+  flist.end of dir := end
+
+END PROC store end of dir;
+
+DIRPOS PROC free dirpos (FREELIST VAR flist):
+  enable stop;
+  DIRPOS VAR result;
+  IF flist.stacktop > 0
+    THEN pop
+    ELIF NOT free area empty
+    THEN first of free area
+    ELIF expansion alloweded
+    THEN allocate new dir cluster;
+         result := free dirpos (flist)
+    ELSE error stop ("Directory voll")
+  FI;
+  result.
+
+pop:
+  result := flist.stack [flist.stacktop];
+  flist.stacktop DECR 1.
+
+free area empty:
+  flist.begin of free area > flist.end of dir.
+
+first of free area:
+  result := flist.begin of free area;
+  incr (flist.begin of free area).
+
+expansion alloweded:
+  flist.dir root >= 2.0.
+
+allocate new dir cluster:
+  REAL CONST new dir cluster :: available fat entry;
+  REAL VAR last entry no;
+  search last entry no of fat chain;
+  fat entry (new dir cluster, last fat chain entry);
+  fat entry (last entry no, new dir cluster);
+  write fat;
+  store begin of free area (flist, dir pos (first new block, 0));
+  store end   of dir       (flist, dir pos (last  new block, 15));
+  init new dir cluster.
+
+search last entry no of fat chain:
+  last entry no := flist.dir root;
+  WHILE NOT is last fat chain entry (fat entry (last entry no)) REP
+    last entry no := fat entry (last entry no)
+  PER.
+
+first new block:
+  begin of cluster (new dir cluster).
+
+last new block:
+  begin of cluster (new dir cluster) + real (sectors per cluster - 1).
+
+init new dir cluster:
+  TEXT CONST empty dir entry :: 32 * ""0"";
+  INT VAR i;
+  FOR i FROM 0 UPTO 15 REP
+    put dir entry (empty dir entry, i)
+  PER;
+  disable stop;
+  REAL VAR block no := first new block;
+  WHILE block no <= last new block REP
+    write dir block (block no)
+  PER.
+
+END PROC free dirpos; 
+
+(*-------------------------------------------------------------------------*)
+
+LET FILEENTRY = STRUCT (TEXT date and time,
+                        REAL size,
+                             first cluster, 
+                        DIRPOS dirpos),
+
+    FILELIST = STRUCT (THESAURUS thes,
+                       ROW max dir entrys FILEENTRY entry);
+
+PROC init file list (FILELIST VAR flist):
+  flist.thes := empty thesaurus.
+
+END PROC init file list;
+
+PROC store file entry (FILELIST VAR flist, TEXT CONST entry text, DIRPOS CONST position):
+  INT VAR entry index;
+  insert (flist.thes, file name, entry index);
+  store file entry (flist.entry [entry index], entry text, position).
+ 
+file name:
+  TEXT CONST name pre  :: compress (subtext (entry text, 1, 8)),
+             name post :: compress (subtext (entry text, 9, 11));
+  IF name post <> ""
+    THEN name pre + "." + name post
+    ELSE name pre
+  FI.
+
+END PROC store file entry;
+
+PROC store file entry (FILEENTRY VAR fentry, TEXT CONST entry text, DIRPOS CONST position):
+  fentry.first cluster := real (entry text ISUB 14);
+  fentry.date and time := dos date + "  " + dos time;
+  fentry.size          := dint (entry text ISUB 15, entry text ISUB 16);
+  fentry.dirpos        := position.
+
+dos date:
+  day + "." + month + "." + year. 
+ 
+day: 
+  text2 (code (entry text SUB 25) MOD 32).
+ 
+month:
+  text2 (code (entry text SUB 25) DIV 32 + 8 * (code (entry text SUB 26) MOD 2)).
+ 
+year:
+  text (80 + code (entry text SUB 26) DIV 2, 2).
+
+dos time:
+  hour + ":" + minute. 
+ 
+hour: 
+  text2 (code (entry text SUB 24) DIV 8).
+ 
+minute: 
+  text2 (code (entry text SUB 23) DIV 32 + 8 * (code (entry text SUB 24) MOD 8)).
+ 
+END PROC store file entry;
+
+TEXT PROC text2 (INT CONST intvalue):
+  IF intvalue < 10
+    THEN "0" + text (intvalue)
+    ELSE text (int value)
+  FI.
+
+END PROC text2;
+
+DIRPOS PROC file entry pos (FILELIST CONST flist, TEXT CONST file name):
+  INT CONST link index :: link (flist.thes, file name);
+  IF link index = 0
+    THEN error stop ("Die Datei """ + file name + """ gibt es nicht")
+  FI;
+  flist.entry [link index].dir pos.
+
+END PROC file entry pos;
+
+PROC delete (FILELIST VAR flist, TEXT CONST file name):
+  INT VAR dummy;
+  delete (flist.thes, file name, dummy).
+
+END PROC delete;
+
+PROC file info (FILELIST CONST flist, TEXT CONST file name, REAL VAR first cluster no, storage):
+  INT CONST link index :: link (flist.thes, file name);
+  IF link index = 0
+    THEN error stop ("Die Datei """ + file name + """ gibt es nicht")
+  FI;
+  first cluster no := flist.entry [link index].first cluster;
+  storage          := flist.entry [link index].size
+
+END PROC file info;
+
+BOOL PROC contains (FILELIST VAR flist, TEXT CONST file name):
+  flist.thes CONTAINS file name
+
+END PROC contains;
+
+PROC list (FILE VAR f, FILELIST CONST flist):
+  INT VAR index := 0;
+  TEXT VAR name;
+  get (flist.thes, name, index);
+  WHILE index > 0 REP
+    list file;
+    get (flist.thes, name, index)
+  PER.
+
+list file:
+  write (f, centered name);
+  write (f, "  ");
+  write (f, text (flist.entry [index].size, 11, 0));
+  write (f, " Bytes belegt      ");
+  write (f, flist.entry [index].date and time); 
+(*COND TEST*)
+  write (f, "  +++  "); 
+  write (f, text (flist.entry [index].first cluster)); 
+(*ENDCOND*)
+  line (f).
+
+centered name:
+  INT VAR point pos := pos (name, ".");
+  IF point pos > 0
+    THEN name pre + "." + name post
+    ELSE text (name, 12)
+  FI.
+
+name pre:
+  text (subtext (name, 1, point pos - 1), 8).
+
+name post:
+  text (subtext (name, point pos + 1, point pos + 4), 3).
+ 
+END PROC list;
+
+(*-------------------------------------------------------------------------*)
+ 
+LET DIRENTRY = REAL,
+
+    DIRLIST = STRUCT (THESAURUS thes,
+                      ROW max dir entrys DIRENTRY entry);
+
+PROC init dir list (DIRLIST VAR dlist):
+  dlist.thes := empty thesaurus.
+
+END PROC init dir list;
+
+PROC store subdir entry (DIRLIST VAR dlist, TEXT CONST entry text):
+  INT VAR entry index;
+  insert (dlist.thes, subdir name, entry index);
+  dlist.entry [entry index] := real (entry text ISUB 14).
+
+subdir name:
+  TEXT CONST name pre  :: compress (subtext (entry text, 1, 8)),
+             name post :: compress (subtext (entry text, 9, 11));
+  IF name post <> ""
+    THEN name pre + "." + name post
+    ELSE name pre
+  FI.
+
+END PROC store subdir entry;
+
+REAL PROC first cluster of subdir (DIRLIST CONST dlist, TEXT CONST name):
+  INT CONST link index := link (dlist.thes, name);
+  IF link index = 0
+    THEN error stop ("Das Unterverzeichnis """ + name + """ gibt es nicht")
+  FI;
+  dlist.entry [link index].
+
+END PROC first cluster of subdir;
+
+BOOL PROC contains (DIRLIST CONST dlist, TEXT CONST subdir name):
+  dlist.thes CONTAINS subdir name
+
+END PROC contains;
+
+PROC list (FILE VAR f, DIRLIST CONST dlist):
+  INT VAR index := 0;
+  TEXT VAR name;
+  get (dlist.thes, name, index);
+  WHILE index > 0 REP
+    list dir;
+    get (dlist.thes, name, index)
+  PER.
+
+list dir:
+  write (f, centered name);
+  write (f, "   <DIR>");
+(*COND TEST*)
+  write (f, "  +++  ");                                 
+  write (f, text (dlist.entry [index]));  
+(*ENDCOND*)
+  line (f).
+
+centered name:
+  INT VAR point pos := pos (name, ".");
+  IF point pos > 0
+    THEN name pre + "." + name post
+    ELSE text (name, 12)
+  FI.
+
+name pre:
+  text (subtext (name, 1, point pos - 1), 8).
+
+name post:
+  text (subtext (name, point pos + 1, point pos + 4), 3).
+ 
+END PROC list;
+
+(*-------------------------------------------------------------------------*)
+
+LET DIR = BOUND STRUCT (FILELIST filelist,
+                        DIRLIST dirlist, 
+                        FREELIST freelist,
+                        TEXT path);
+ 
+DIR VAR dir;
+DATASPACE VAR dir ds;
+INITFLAG VAR dir ds used := FALSE;
+
+PROC open dir (TEXT CONST path string):
+  init dir block io;
+  init dir ds;
+  dir.path := path string;
+  load main dir;
+  TEXT VAR rest path := path string;
+  WHILE rest path <> "" REP
+    TEXT CONST sub dir name := next sub dir name (rest path);
+    load sub dir
+  PER.
+
+load main dir:
+  init file list (dir.filelist);
+  init dir  list (dir.dirlist);
+  init free list (dir.free list, 0.0);
+  store end of dir (dir.freelist, dirpos (last main dir sector, 15));
+  BOOL VAR was last dir sector := FALSE;
+  REAL VAR block no := first main dir sector;
+  INT VAR i;
+  FOR i FROM 1 UPTO dir sectors REP
+      load dir block (block no, was last dir sector);
+      block no INCR 1.0
+      UNTIL was last dir sector
+  PER. 
+
+first main dir sector:
+  real (begin of dir).
+
+last main dir sector:
+  real (begin of dir + dir sectors - 1).
+
+load sub dir:
+  REAL VAR cluster no := first cluster of sub dir (dir.dirlist, sub dir name);
+  was last dir sector := FALSE;
+  init file list (dir.filelist);
+  init dir  list (dir.dirlist);
+  init free list (dir.free list, cluster no);
+  WHILE NOT is last fat chain entry (cluster no) REP
+    load sub dir entrys of cluster;
+    cluster no := fat entry (cluster no)
+    UNTIL was last dir sector
+  PER.
+
+load sub dir entrys of cluster:
+  store end of dir (dir.freelist, dirpos (last block no of cluster, 15));
+  block no := begin of cluster (cluster no);
+  FOR i FROM 1 UPTO sectors per cluster REP
+    load dir block (block no, was last dir sector);
+    block no INCR 1.0
+    UNTIL was last dir sector
+  PER.
+
+last block no of cluster:
+  begin of cluster (cluster no) + real (sectors per cluster - 1).
+
+END PROC open dir;
+
+PROC load dir block (REAL CONST block no, BOOL VAR was last block): 
+  was last block := FALSE;
+  read dir block (block no);
+  INT VAR entry no;
+  TEXT VAR entry;
+  FOR entry no FROM 0 UPTO 15 REP 
+    get dir entry (entry, entry no);
+    process entry
+    UNTIL was last block
+  PER.
+
+process entry:
+  SELECT pos (""0"."229"", entry SUB 1) OF
+    CASE 1: end of dir search
+    CASE 2: (* root des aktuellen directorys oder des übergeordneten, also nichts tun *)
+    CASE 3: free entry
+    OTHERWISE volume label or file entry or subdir entry
+  END SELECT.
+
+end of dir search:
+  was last block := TRUE;
+  store begin of free area (dir.freelist, dir pos (block no, entry no)).
+
+free entry:
+  store (dir.freelist, dir pos (block no, entry no)).
+
+volume label or file entry or subdir entry:
+  INT CONST byte 11 :: code (entry SUB 12);
+  IF (byte 11 AND 8) > 0
+    THEN (* volume label *)
+  ELIF (byte 11 AND 16) > 0
+    THEN sub dir entry
+    ELSE file entry
+  FI.
+
+sub dir entry:
+  store subdir entry (dir.dir list, entry).
+
+file entry:
+  store file entry (dir.file list, entry, dir pos (block no, entry no)).
+
+END PROC load dir block; 
+ 
+TEXT PROC next subdir name (TEXT VAR path string):
+  TEXT VAR subdir name;
+  IF (path string SUB 1) <> "\"
+    THEN error stop ("ungültige Pfadbezeichnung")
+  FI;
+  INT CONST backslash pos :: pos (path string, "\", 2);
+  IF backslash pos = 0
+    THEN subdir name := subtext (path string, 2);
+         path string := ""
+    ELSE subdir name := subtext (path string, 2, backslash pos - 1);
+         path string := subtext (path string, backslash pos)
+  FI;
+  dos name (subdir name, read modus).
+
+END PROC next subdir name;
+
+PROC init dir ds:
+  IF initialized (dir ds used)
+    THEN forget (dir ds)
+  FI;
+  dir ds := nilspace;
+  dir := dir ds.
+
+END PROC init dir ds;
+
+PROC insert dir entry (TEXT CONST name, REAL CONST start cluster, storage):
+  DIRPOS CONST ins pos :: free dirpos (dir.free list);
+  TEXT CONST entry string :: entry name + ""32"" + (10 * ""0"") + dos time +
+                             dos date + entry start cluster + entry storage;
+  write entry on disk;
+  write entry in dir ds.
+
+entry name:
+  INT CONST point pos := pos (name, ".");
+  IF point pos > 0
+    THEN subtext (name, 1, point pos - 1) + (9 - point pos) * " " +
+         subtext (name, point pos + 1) + (3 - LENGTH name + point pos) * " "
+    ELSE name + (11 - LENGTH name) * " "
+  FI.
+ 
+dos time:
+  TEXT CONST akt time :: time of day (clock (1));
+  code ((minute MOD 8) * 32) + code (8 * hour + minute DIV 8).
+
+hour:
+  int (subtext (akt time, 1, 2)).
+
+minute:
+  int (subtext (akt time, 4, 5)).
+
+dos date:
+  TEXT CONST akt date :: date (clock (1));
+  code (32 * (month MOD 8) + day) + code ((year - 80) * 2 + month DIV 8).
+
+day: 
+  int (subtext (akt date, 1, 2)).
+
+month:
+  int (subtext (akt date, 4, 5)).
+
+year:
+  int (subtext (akt date, 7, 8)).
+
+entry start cluster:
+  TEXT VAR buffer2 := "12";
+  replace (buffer2, 1, low word (start cluster));
+  buffer2.
+
+entry storage:
+  TEXT VAR buffer4 := "1234";
+  replace (buffer4, 1, low  word (storage));
+  replace (buffer4, 2, high word (storage));
+  buffer4.
+
+write entry on disk:
+  read dir block (block no (ins pos));
+  put dir entry (entry string, entry no (ins pos));
+  write dir block.
+
+write entry in dir ds:
+  store file entry (dir.file list, entry string, ins pos).
+
+END PROC insert dir entry;
+
+PROC delete dir entry (TEXT CONST name):
+  TEXT VAR entry;
+  DIRPOS CONST del pos :: file entry pos (dir.filelist, name);
+  read dir block (block no (del pos));
+  get dir entry (entry, entry no (del pos));
+  put dir entry (""229"" + subtext (entry, 2, 32), entry no (del pos));
+  write dir block;
+  delete (dir.filelist, name);
+  store (dir.freelist, del pos).
+
+END PROC delete dir entry;
+
+PROC format dir:
+  init dir block io;
+  init dir ds;
+  build empty dir block;
+  REAL VAR block no := real (begin of dir);
+  disable stop;
+  FOR i FROM 1 UPTO dir sectors REP
+    write dir block (block no);
+    block no INCR 1.0
+  PER;
+  enable stop;
+  dir.path := "";
+  init file list (dir.file list);
+  init dir  list (dir.dir  list);
+  init free list (dir.free list, 0.0);
+  store begin of free area (dir.free list, dir pos (real (begin of dir), 0));
+  store end of dir (dir.free list, dir pos (last main dir sector, 15)).
+
+build empty dir block:
+  INT VAR i;
+  FOR i FROM 0 UPTO 15 REP
+    put dir entry (32 * ""0"",  i)
+  PER.
+
+last main dir sector:
+  real (begin of dir + dir sectors - 1).
+
+END PROC format dir;
+ 
+PROC file info (TEXT CONST file name, REAL VAR start cluster, size):
+  file info (dir.file list, file name, start cluster, size)
+
+END PROC file info;
+
+THESAURUS PROC all files:
+  THESAURUS VAR t := dir.filelist.thes;
+  t
+
+END PROC all files;
+
+THESAURUS PROC all subdirs:
+  dir.dirlist.thes
+
+END PROC all subdirs;
+
+BOOL PROC file exists (TEXT CONST file name):
+  contains (dir.filelist, file name)
+
+END PROC file exists;
+
+BOOL PROC subdir exists (TEXT CONST subdir name):
+  contains (dir.dirlist, subdir name)
+
+END PROC subdir exists;
+
+PROC dir list (DATASPACE VAR ds):
+  open list file;
+  head line (list file, list file head);
+  list (list file, dir.file list);
+  list (list file, dir.dir list).
+
+open list file:
+  forget (ds);
+  ds := nilspace;
+  FILE VAR list file := sequential file (output, ds);
+  putline (list file, "").
+ 
+list file head:
+  "DOS" + path string.
+
+path string:
+  IF dir.path <> ""
+    THEN "     PATH: " + dir.path
+    ELSE ""
+  FI.
+
+END PROC dir list;
+
+END PACKET dir;
+
diff --git a/dos/disk descriptor.dos b/dos/disk descriptor.dos
new file mode 100644
index 0000000..0b0d7fc
--- /dev/null
+++ b/dos/disk descriptor.dos	
@@ -0,0 +1,339 @@
+PACKET dos disk DEFINES                       (* Copyright (C) 1986, 87 *)
+                                              (* Frank Klapper          *)
+  (* Referenz: 3-22 *)                        (* 11.09.87               *)
+
+  open dos disk,
+
+  sectors per cluster,
+  fat copies,
+  dir sectors,
+  media descriptor,
+  fat sectors,
+
+  begin of fat,
+  fat entrys,
+  begin of dir,
+  begin of cluster,
+  cluster size,
+
+  bpb exists,
+  write bpb,
+
+  eu block,
+
+  bpb dump modus:
+
+INITFLAG VAR bpb ds initialisiert := FALSE;
+DATASPACE VAR bpb ds;
+BOUND STRUCT (ALIGN dummy, ROW 512 INT daten) VAR bpb;
+
+BOOL VAR bpb dump flag := FALSE;
+
+REAL VAR begin of data area;
+INT  VAR sectors per track,
+         heads;
+
+IF exists ("shard interface")
+  THEN load shard interface table
+FI;
+
+TEXT CONST bpb type 254 :: ""00""00""00"" +
+                           ""69""85""77""69""76""66""80""66"" +
+                           ""00""02"" +
+                           ""01"" +
+                           ""01""00"" +
+                           ""02"" +
+                           ""64""00"" +
+                           ""64""01"" +
+                           ""254"" +
+                           ""01""00"" +
+                           ""08""00"" +
+                           ""01""00"" +
+                           ""00""00"",
+           bpb type 255 :: ""00""00""00"" +
+                           ""69""85""77""69""76""66""80""66"" +
+                           ""00""02"" +
+                           ""02"" +
+                           ""01""00"" +
+                           ""02"" +
+                           ""112""00"" +
+                           ""128""02"" +
+                           ""255"" +
+                           ""01""00"" +
+                           ""08""00"" +
+                           ""02""00"" +
+                           ""00""00"";
+
+PROC open dos disk:
+  enable stop;
+  bpb ds an bound koppeln;
+  bpb lesen;
+  IF bpb ungueltig
+    THEN versuche pseudo bpb zu verwenden
+  FI;
+  ueberpruefe bpb auf gueltigkeit;
+  globale variablen initialisieren;
+  IF bpb dump flag
+    THEN dump schreiben
+  FI.
+
+bpb ds an bound koppeln:
+  IF NOT initialized (bpb ds initialisiert)
+    THEN bpb ds := nilspace;
+         bpb := bpb ds
+  FI.
+
+bpb lesen:
+  INT VAR return;
+  check rerun;
+  read block (bpb ds, 2, 0, return);
+  IF return <> 0
+    THEN lesefehler (return)
+  FI.
+
+bpb ungueltig:
+  (* Byte 12 = Byte 13 = ... = Byte 23 <==> Word 6 = ... = Word 11 *)
+  INT VAR word no;
+  FOR word no FROM 6 UPTO 10 REP
+    IF bpb.daten [word no + 1] <> bpb.daten [word no + 2]
+      THEN LEAVE bpb ungueltig WITH FALSE
+    FI
+  PER;
+  TRUE.
+
+versuche pseudo bpb zu verwenden:
+  lies ersten fat sektor;
+  IF fat sektor gueltig und pseudo bpb vorhanden
+    THEN pseudo bpb laden
+    ELSE error stop ("Format unbekannt")
+  FI.
+
+lies ersten fat sektor:
+  (* da der bpb in diesem Fall ungültig, lese ich den fat sektor in den bpb
+     Datenraum                                                             *)
+  check rerun;
+  read block (bpb ds, 2, 1, return);
+  IF return <> 0
+    THEN lesefehler (return)
+  FI.
+
+fat sektor gueltig und pseudo bpb vorhanden:
+  TEXT VAR fat start := "1234";
+  replace (fat start, 1, bpb.daten [1]);
+  replace (fat start, 2, bpb.daten [2]);
+  (fat start SUB 2) = ""255"" CAND (fat start SUB 3) = ""255"" CAND
+  pseudo bpb vorhanden.
+
+pseudo bpb vorhanden:
+  pos (""254""255"", fat start SUB 1) > 0.
+
+pseudo bpb laden:
+  INT VAR i;
+  FOR i FROM 1 UPTO 15 REP
+    bpb.daten [i] := bpb puffer ISUB i
+  PER.
+
+bpb puffer:
+  IF pseudo bpb name = ""255""
+    THEN bpb type 255
+    ELSE bpb type 254
+  FI.
+
+pseudo bpb name:
+  fat start SUB 1.
+
+ueberpruefe bpb auf gueltigkeit:
+  IF bytes per sector <> 512
+    THEN error stop ("DOS Format nicht implementiert (unzulässige Sektorgröße)")
+  FI;
+  IF (fat sectors > 64)
+    THEN error stop ("ungültige DOS Disk (BPB)")
+  FI.
+
+globale variablen initialisieren:
+  sectors per track  := bpb byte (25) * 256 + bpb byte (24);
+  heads              := bpb byte (27) * 256 + bpb byte (26);
+  begin of data area := real (reserved sectors + fat copies * fat sectors + dir sectors).
+
+dump schreiben:
+  dump ("Sektoren pro Cluster", sectors per cluster);
+  dump ("Fat Kopien          ", fat copies);
+  dump ("Dir Sektoren        ", dir sectors);
+  dump ("Media Descriptor    ", media descriptor);
+  dump ("Sektoren pro Fat    ", fat sectors);
+  dump ("Fat Anfang (0)      ", begin of fat (0));
+  dump ("Fat Einträge        ", fat entrys);
+  dump ("Dir Anfang          ", begin of dir).
+
+END PROC open dos disk;
+
+PROC lesefehler (INT CONST fehler code):
+  error stop (fehlertext).
+
+fehlertext:
+  SELECT fehler code OF
+    CASE 1: "Diskettenlaufwerk nicht betriebsbereit"
+    CASE 2: "Lesefehler"
+    OTHERWISE "Lesefehler " + text (fehler code)
+  END SELECT.
+
+END PROC lesefehler;
+
+TEXT VAR konvertier puffer := "12";
+
+INT PROC bpb byte (INT CONST byte no):
+  replace (konvertier puffer, 1, bpb.daten [byte no DIV 2 + 1]);
+  code (konvertier puffer SUB puffer pos).
+
+puffer pos:
+  IF even byte no
+    THEN 1
+    ELSE 2
+  FI.
+
+even byte no:
+  (byte no MOD 2) = 0.
+
+END PROC bpb byte;
+
+INT PROC bytes per sector:
+  bpb byte (12) * 256 + bpb byte (11)
+
+END PROC bytes per sector;
+
+INT PROC sectors per cluster:
+  bpb byte (13)
+
+END PROC sectors per cluster;
+
+INT PROC reserved sectors:
+  bpb byte (15) * 256 + bpb byte (14)
+
+END PROC reserved sectors;
+
+INT PROC fat copies:
+  bpb byte (16)
+
+END PROC fat copies;
+
+INT PROC dir sectors:
+  dir entrys DIV dir entrys per sector.
+
+dir entrys:
+  bpb byte (18) * 256 + bpb byte (17).
+
+dir entrys per sector:
+  16.
+
+END PROC dir sectors;
+
+REAL PROC dos sectors:
+  real (bpb byte (20)) * 256.0 + real (bpb byte (19))
+
+END PROC dos sectors;
+
+INT PROC media descriptor:
+  bpb byte (21)
+
+END PROC media descriptor;
+
+INT PROC fat sectors:
+  bpb byte (23) * 256 + bpb byte (22)
+
+END PROC fat sectors;
+
+INT PROC begin of fat (INT CONST fat copy no):
+  (* 0 <= fat copy no <= fat copies - 1 *)
+  reserved sectors + fat copy no * fat sectors
+
+END PROC begin of fat;
+
+INT PROC fat entrys:
+  anzahl daten cluster + 2.
+
+anzahl daten cluster:
+  int ((dos sectors - tabellen sektoren) / real (sectors per cluster)).
+
+tabellen sektoren:
+  real (reserved sectors + fat copies * fat sectors + dir sectors).
+
+END PROC fat entrys;
+
+INT PROC begin of dir:
+  reserved sectors + fat copies * fat sectors.
+
+END PROC begin of dir;
+
+REAL PROC begin of cluster (REAL CONST cluster no):
+  begin of data area + (cluster no - 2.0) * real (sectors per cluster)
+
+END PROC begin of cluster;
+
+INT PROC cluster size:
+  512 * sectors per cluster
+
+END PROC cluster size;
+
+BOOL PROC bpb exists (INT CONST no):
+
+  exists ("bpb ds") AND no > 0 AND no < 4.
+
+END PROC bpb exists;
+
+PROC write bpb (INT CONST no):
+  INT VAR return;
+  write block (old ("bpb ds"), no + 1, 0, 0, return);
+  IF return <> 0
+    THEN error stop ("Schreibfehler")
+  FI.
+
+END PROC write bpb;
+
+(* Da DOS-Partitionen maximal 32 MByte groß sein können, können die Blocknummern
+   durch 16 BIT unsigned Integer dargestellt werden. Die Werte die die 'eublock'-
+   Prozeduren liefern sind als solche zu verstehen                          *)
+
+INT PROC eu block (INT CONST dos block no):
+  IF hd version
+    THEN dos block no
+    ELSE dos block no floppy format
+  FI.
+
+dos block no floppy format:
+  IF page format
+    THEN head * eu sectors per head + trac * eu sectors + sector
+    ELSE head * eu sectors + trac * abs (eu heads) * eu sectors + sector
+  FI.
+
+page format:
+  eu heads < 0.
+
+sector:
+  dos block no MOD sectors per track.
+
+trac:
+  (dos block no DIV sectors per track) DIV heads.
+
+head:
+  (dos block no DIV sectors per track) MOD heads.
+
+eu sectors per head:
+  eu sectors * eu tracks.
+
+eu sectors:
+  eu last sector - eu first sector + 1.
+
+END PROC eu block;
+
+INT PROC eu block (REAL CONST dos block no):
+  eublock (low word (dos block no)).
+
+END PROC eublock;
+
+PROC bpb dump modus (BOOL CONST status):
+  bpb dump flag := status
+
+END PROC bpb dump modus;
+
+END PACKET dos disk;
+
diff --git a/dos/dos hd inserter b/dos/dos hd inserter
new file mode 100644
index 0000000..24be82b
--- /dev/null
+++ b/dos/dos hd inserter	
@@ -0,0 +1,41 @@
+IF NOT single user
+  THEN do ("IF name (myself) <> ""DOS HD"" THEN error stop (""Bitte der Task den Namen 'DOS HD' geben und neu starten"") FI");
+FI;
+
+archive ("austausch");
+check off;
+command dialogue (FALSE);
+fetch ("insert.dos", archive);
+fetch ("bpb ds", archive);
+IF single user
+  THEN do (PROC (TEXT CONST) gen s, ALL "insert.dos");
+       gen s ("manager/S.dos")
+  ELSE fetch (ALL "insert.dos", archive);
+       fetch ("manager/M.dos", archive);
+       release (archive);
+       do (PROC (TEXT CONST) gen m, ALL "insert.dos");
+       gen m ("manager/M.dos");
+FI;
+do ("hd version (TRUE)");
+forget ("insert.dos", quiet);
+forget ("dos hd inserter", quiet);
+IF NOT single user
+  THEN do ("dos manager (29)")
+FI.
+
+single user:
+  (pcb (9) AND 255) = 1.
+
+PROC gen m (TEXT CONST name):
+  insert (name);
+  forget (name, quiet)
+
+END PROC gen m;
+
+PROC gen s (TEXT CONST t):
+  fetch (t, archive);
+  insert (t);
+  forget (t, quiet)
+
+END PROC gen s;
+
diff --git a/dos/dos inserter b/dos/dos inserter
new file mode 100644
index 0000000..2f70b28
--- /dev/null
+++ b/dos/dos inserter	
@@ -0,0 +1,59 @@
+IF NOT single user
+  THEN do ("IF name (myself) <> ""DOS"" THEN error stop (""Bitte der Task den Namen 'DOS' geben und neu starten"") FI");
+FI; 
+ 
+archive ("austausch");
+check off;
+command dialogue (FALSE);
+hol ("shard interface");
+hol ("bpb ds");
+hol ("insert.dos");
+IF single user
+  THEN do (PROC (TEXT CONST) gen s, ALL "insert.dos");
+       gen s ("manager/S.dos")
+  ELSE do (PROC (TEXT CONST) hol, ALL "insert.dos");
+       hol ("manager/M.dos");
+       release (archive);
+       do (PROC (TEXT CONST) gen m, ALL "insert.dos");
+       gen m ("manager/M.dos");
+       putline ("jetzt mit 'dos manager' bzw. 'dos manager (channnel)' starten");
+FI;
+do ("hd version (FALSE)");
+do ("load shard interface table");
+forget ("shard interface", quiet);
+forget ("insert.dos", quiet);
+forget ("dos inserter", quiet).
+ 
+single user:
+  (pcb (9) AND 255) = 1.
+ 
+PROC gen m (TEXT CONST name):
+  insert (name);
+  forget (name, quiet)
+ 
+END PROC gen m;
+ 
+PROC gen s (TEXT CONST t):
+  hol (t);
+  insert (t);
+  forget (t, quiet)
+ 
+END PROC gen s;
+ 
+PROC hol (TEXT CONST t):
+  IF NOT exists (t)
+    THEN fetch (t, archive)
+  FI
+ 
+END PROC hol;
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+
+
diff --git a/dos/dos-dat-handbuch b/dos/dos-dat-handbuch
new file mode 100644
index 0000000..a1e4fd4
--- /dev/null
+++ b/dos/dos-dat-handbuch
@@ -0,0 +1,650 @@
+____________________________________________________________________________ 
+ 
+ 
+#on("b")##on ("u")# 
+#center#Betriebssystem E U M E L 
+#off ("u")# 
+ 
+ 
+#center#MS-DOS-DAT 
+ 
+ 
+ 
+ 
+#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# 
+#free(4.5)# 
+ 
+#center#Lesen und Schreiben 
+#center#von 
+#center#MS-DOS Dateien 
+ 
+#on ("b")##center#MS-DOS-DAT#off ("b")# 
+#free(1.5)# 
+ 
+ 
+#center#Version 2.0 
+ 
+#center#Stand 10.09.87 
+#page# 
+#pagenr ("%",1)##setcount (1)##block##pageblock##count per page# 
+#headeven# 
+% #center#MS-DOS-DAT 
+#center#____________________________________________________________ 
+ 
+#end# 
+#headodd# 
+#center#MS-DOS-DAT#right#% 
+#center#____________________________________________________________ 
+ 
+#end# 
+#on("bold")# 
+#ib#1. Allgemeines#ie# 
+#off ("b")# 
+ 
+Dieses Programm ermöglicht MS-DOS Dateien vom EUMEL aus von Disketten zu
+lesen und auf Disketten zu schreiben. Die Benutzerschnittstelle ist ähnlich der des
+EUMEL-Archivs organisiert. Der Benutzer kommuniziert mit einer Task des
+EUMEL-Systems, nämlich mit der Task 'DOS'. Diese wickelt dann über das Archiv­
+laufwerk die Diskettenzugriffe ab. Der Benutzer meldet die MS-DOS Diskette mit
+'reserve ("...", /"DOS")' an und kann dann mit 'list (/"DOS")', 'fetch ("...", /"DOS")',
+'save ("...", /"DOS")' und weiteren Kommandos auf die MS-DOS Diskette zugreifen.
+Für das Schreiben und Lesen (save, fetch) stehen insgesamt 7 verschiedene Be­
+triebsarten zur Verfügung. Man kann in eine Datei im ASCII Code mit und ohne
+Anpassung der Umlaute, im IBM-ASCII Code, im Atari-ST Code oder ganz ohne
+Codeumsetzung lesen bzw. schreiben. Die Betriebsart selbst wird beim Anmelden der
+MS-DOS Diskette durch den Textparameter des 'reserve'-Kommandos bestimmt. 
+ 
+Die gleiche Benutzerschnittstelle gilt für die Kommunikation mit der Task 'DOS HD'.
+Diese Task liest und schreibt aber nicht auf der Diskette, sondern in der MS-DOS
+Partition der Festplatte (falls vorhanden). 
+ 
+ 
+#on("bold")# 
+#ib#2. Benutzeranleitung #ie# 
+#off ("b")# 
+Im Normalfall will man als Benutzer eine EUMEL-Textdatei auf eine MS-DOS
+Diskette schreiben oder eine mit z.B. Word-Star erstellte MS-DOS-Textdatei in
+das EUMEL-System einlesen (implementierte Formate siehe Abschnitt 3). 
+ 
+Lesen einer MS-DOS-Datei: 
+ 
+#linefeed (1.25)# 
+#on ("b")# 
+  reserve ("file ascii german", /"DOS"); 
+  (* MS-DOS-Diskette ins Laufwerk einlegen *) 
+  fetch (filename, /"DOS"); 
+  release (/"DOS") 
+#off ("b")# 
+ 
+Schreiben einer MS-DOS-Datei: 
+ 
+#on ("b")# 
+  reserve ("file ascii german", /"DOS"); 
+  (* MS-DOS-Diskette ins Laufwerk einlegen *) 
+  save (filename, /"DOS"); 
+  release (/"DOS") 
+#off("b")# 
+#linefeed (1.0)# 
+ 
+ 
+Sollen statt der Umlaute []{|}\ verwendet werden, so ist statt "file ascii german" "file
+ascii" einzustellen. Eine genaue Beschreibung aller 7 möglichen Betriebsarten wird in
+Abschnitt 6 gegeben. Der Dateiname 'file name' unterliegt den im Abschnitt 4 be­
+schriebenen Einschränkungen. 
+ 
+ 
+#on("bold")# 
+#ib#3. Implementierte Formate#ie# 
+#off("b")#
+ 
+Diese Hardware ermöglicht das Bearbeiten von MS-DOS Disketten mit Hilfe der
+Task /"DOS" und (falls es sich um einen MS-DOS fähigen Rechner mit MS-DOS Parti­
+tion auf der Festplatte handelt) das Bearbeiten von Daten in der MS-DOS Partition
+der Platte. 
+ 
+#on("bold")# 
+#ib#3.1 Arbeiten mit der Task /"DOS"#ie# 
+#off ("b")# 
+ 
+Die Task /"DOS" verwendet das Archivlaufwerk als MS-DOS Datenträger. Es sind
+alle mit dem IBM-Format der DOS Version 2 und 3 kompatiblen Formate für 5.25
+Zoll und 3.5 Zoll Disketten implementiert, sofern diese 512 Byte große Sektoren
+verwenden und im ersten Sektor einen erweiterten BIOS-Parameterblock (BPB)
+enthalten (hierzu gehören auch mit dem Atari ST bearbeitete Disketten). Weiterhin
+sind die beiden von IBM verwendeten Formate der DOS Version 1 implementiert (5.25
+Zoll, ein- bzw. zweiseitig, 40 Spuren a 8 Sektoren). 
+ 
+Die einzige Hardwarevoraussetzung besteht darin, daß der Hardwareanpassungs­
+modul (SHard) alle von DOS benutzten Sektoren lesen und schreiben können muß. 
+ 
+#on("bold")# 
+#ib#3.2 Arbeiten mit der Task /"DOS HD"#ie# 
+#off ("b")# 
+ 
+Die Task /"DOS HD" verwendet die MS-DOS Partition der Festplatte als Daten­
+träger (falls eine solche vorhanden ist und das SHard diese ansprechen kann). Hier
+gibt es keine Beschränkungen bezüglich des Plattentyps. 
+ 
+ 
+#on("bold")# 
+#ib#4. Dateibenennung#ie# 
+#off ("b")# 
+ 
+Die Namen für MS-DOS Dateien unterliegen bestimmten Regeln. Ein Dateiname
+kann aus 
+-  einem bis acht Zeichen  oder 
+-  einem bis acht Zeichen gefolgt von einem Punkt und einer Namenserweiterung
+   von einem bis drei Zeichen 
+bestehen. 
+ 
+Gültige Zeichen sind 
+-  die Buchstaben A bis Z 
+-  die Ziffern 0 bis 9 
+-  die Sonder- und Satzzeichen $ \# & § ! ( ) { } 
+ 
+Da weitere Sonderzeichen in verschiedenen MS-DOS Versionen in unterschiedlich­
+em Umfang erlaubt sind, ist ihre Verwendung beim Schreiben (save) vom EUMEL aus
+nicht zugelassen. Beim Lesen und Löschen dagegen sind sie erlaubt. 
+ 
+Außerdem sind die Buchstaben a - z erlaubt. Diese werden beim Zugriff auf das
+MS-DOS Inhaltsverzeichnis (Directory) in große Buchstaben konvertiert. Durch das
+Kommando 'fetch ("Test", /"DOS")' wird also die MS-DOS Datei mit dem Namen
+'TEST' in die EUMEL Datei mit dem Namen 'Test' gelesen; 'save ("test", /"DOS")'
+überschreibt dann die MS-DOS-Datei 'TEST' (natürlich nach Anfrage). 
+ 
+ 
+#on("bold")# 
+#ib#5. Beschreibung der Kommandos#ie# 
+#off ("b")# 
+ 
+In diesem Abschnitt steht der Begriff Dostask beim Arbeiten mit der Floppy für die
+Task /"DOS" und beim Arbeiten mit der MS-DOS Partition der Platte für die Task
+/"DOS HD". Analog steht der Begriff Dosbereich beim Arbeiten mit der Floppy für die
+Floppy und beim Arbeiten mit der MS-DOS Partition der Platte für diese Partition. 
+ 
+#on("bold")# 
+THESAURUS OP ALL (TASK CONST task) 
+#off ("b")# 
+  Wird der 'ALL'-Operator für die Dostask aufgerufen, so wird ein Thesaurus ge­
+  liefert. In diesem Thesaurus sind alle im Dosbereich vorhandenen Dateien einge­
+  tragen. Die vorhandenen Unterinhaltsverzeichnisse (Subdirectories) werden nicht
+  eingetragen. 
+ 
+ 
+#on("bold")# 
+PROC check (TEXT CONST filename, TASK CONST task) 
+#off ("b")# 
+  Durch Aufruf dieser Prozedur für die Dostask wird die Datei 'filename' im Dosbe­
+  reich prüfgelesen. Es werden nur die mit Daten belegten Blöcke prüfgelesen. Sollen
+  auch der Einträge im Inhaltsverzeichnis überprüft werden, so erreicht man dies
+  durch vorheriges neues Anmelden mit der Prozedur 'reserve'. 
+ 
+ 
+#on("bold")# 
+PROC clear (TASK CONST task) 
+#off ("b")# 
+  Durch Aufruf dieser Prozedur für die Task /"DOS" wird die gesamte Diskette ge­
+  löscht. Mit dieser Prozedur können #on ("u")#nur MS-DOS formatierte Disketten#off ("u")# behandelt
+  werden. Soll eine Diskette dagegen für den Gebrauch unter MS-DOS initialisiert
+  werden, so ist sie auf einem MS-DOS-Rechner zu formatieren. 
+ 
+  Der Aufruf dieser Prozedur für die Task /DOS HD" ist aus Sicherheitsgründen nicht
+  erlaubt. 
+ 
+ 
+#on("bold")# 
+PROC erase (TEXT CONST filename, TASK CONST task) 
+#off ("b")# 
+  Durch Aufruf dieser Prozedur für die Dostask wird die Datei 'filename' im Dosbe­
+  reich gelöscht. 
+ 
+ 
+#on("bold")# 
+BOOL PROC exists (TEXT CONST name, TASK CONST task) 
+#off ("b")# 
+  Wird diese Prozedur für die Dostask aufgerufen, so liefert sie 'TRUE', falls eine
+  Datei mit dem Namen 'name' im Dosbereich existiert. Andernfalls liefert sie
+  'FALSE'. 
+ 
+ 
+#on("bold")# 
+PROC fetch (TEXT CONST filename, TASK CONST task) 
+#off ("b")# 
+  Durch Aufruf dieser Prozedur für die Dostask wird die Datei 'filename' aus dem
+  Dosbereich gelesen. Hierbei wird in der beim Anmelden (reserve ("...", dostask))
+  bestimmten Betriebsart gelesen (siehe Abschnitt 6). 
+ 
+ 
+#on("bold")# 
+PROC list (TASK CONST task) 
+#off ("b")# 
+  Wird diese Prozedur für die Dostask aufgerufen, so werden alle Dateien des In­
+  haltsverzeichnisses und alle Unterverzeichnisse des Dosbereichs aufgelistet. 
+ 
+ 
+#on("bold")# 
+PROC release (TASK CONST task) 
+#off ("b")# 
+  Der Aufruf dieser Prozedur für die Task Dostask hebt deren Reservierung auf.
+  Gleichzeitig wird auch der für block i/o benutzte Kanal freigegeben, so daß bei
+  Benutzung der Task /"DOS" der Archivkanal durch das EUMEL-Archiv wieder
+  benutzt werden kann. 
+ 
+  Um möglichst effizient arbeiten zu können, werden Inhaltsverzeichnis und Ket­
+  tungsblock des Dosbereichs als Kopie im EUMEL gehalten. Der hierdurch belegte
+  Speicher wird beim 'release' wieder freigegeben. Dies ist bei kleinen Systemen
+  besonders wichtig. 
+ 
+ 
+#on("bold")# 
+PROC reserve (TEXT CONST mode, TASK CONST task) 
+#off ("b")# 
+  Durch Aufruf für die Dostask werden Operationen mit dem Dosbereich angemel­
+  det. Gleichzeitig koppelt sich die Dostask an den entsprechenden Kanal an.
+  (/"DOS" an Kanal 31 und /"DOS HD" an Kanal 29). Die Anmeldung wird abge­
+  lehnt, wenn der für die MS-DOS Operationen benötigte Kanal belegt ist (z.B. bei
+  Kanal 31 durch eine Archiv­Operation). Ähnlich wie beim EUMEL-Archiv bleibt
+  diese Reservierung bis 5 Minuten nach dem letzten Zugriff gültig. 
+ 
+  Wird beim Arbeiten mit der Task /"DOS" die MS-DOS Diskette gewechselt, so
+  muß erneut 'reserve ("...", /"DOS")' aufgerufen werden. Nur so ist gewährleistet,
+  daß das Inhaltsverzeichnis der neuen Diskette geladen wird. 
+ 
+  Der Text 'mode' gibt die Betriebsart für das Schreiben und Lesen der Diskette
+  sowie den Pfad für das Bearbeiten von Subdirectories an und nicht wie beim
+  EUMEL-Archiv den Diskettennamen. Es gilt folgende Systax: 
+ 
+    modus :[\directory][\directory]...[\directory] 
+ 
+  Hierbei sind die Angaben in eckigen Klammern optional. Wird kein Pfad angege­
+  ben, so wird mit dem Hauptdirektory der Diskette gearbeitet. Ansonsten wird mit
+  dem Directory gearbeitet, welches durch den hinter dem Doppelpunkt angegeben
+  Pfad bezeichnet wird. Als 'modus' können alle in Abschnitt 6 beschriebenen Be­
+  triebsarten verwendet werden. 
+ 
+ 
+#on("bold")# 
+PROC save (TEXT CONST filename, TASK CONST task) 
+#off ("b")# 
+  Durch Aufruf dieser Prozedur für die Dostask wird die Datei 'filename' in den
+  Dosbereich geschrieben. Hierbei wird in der beim Anmelden (reserve ("...",
+  dostask)) bestimmten Betriebsart geschrieben (siehe Abschnitt 6). 
+ 
+ 
+#on("bold")# 
+#ib#6. Die Betriebsarten von 'fetch' und 'save'#ie# 
+ 
+#ib#6.1 Betriebsart: file ascii#ie# 
+ 
+#on("bold")# 
+fetch ("filename", dostask) 
+#off ("b")# 
+  Die MS-DOS Datei 'filename' wird in die EUMEL-Datei 'filename' kopiert. Dabei
+  werden von allen Zeichen nur die niederwertigen 7 Bit gemäß DIN 66 003, ASCII
+  Code, internationale Referenzversion interpretiert. Die Datei wird so aufbereitet, daß
+  ein Bearbeiten mit dem EUMEL-Editor möglich ist. Dies geschieht folgenderma­
+  ßen: 
+    -  Alle im EUMEL darstellbaren Zeichen werden auf diese abgebildet. 
+    -  Die Zeichenfolgen CR LF, LF CR, LF, CR (CR = carriage return, LF = line­
+       feed) beenden einen Satz in der MS-DOS-Datei. Dementsprechend wird
+       eumelseitig die aktuelle Zeile beendet. 
+    -  Das Zeichen FF (form feed) beendet eumelseitig die aktuelle Zeile. Außerdem
+       wird ein Satz mit dem Inhalt "\#page\#" eingefügt. 
+    -  TAB's (Code 9) werden mit Blanks zur nächsten 8ter-Position expandiert. 
+    -  'Ctrl z' in der MS-DOS Datei wird als Dateiende interpretiert. Fehlt dieses,
+       so wird bis zum letzten Zeichen des letzten Sektors der Datei gelesen. 
+    -  Alle anderen Zeichen mit 0 <= code (zeichen) <=  31 (Steuerzeichen)
+       werden durch eine Ersatzdarstellung dargestellt (der Code des Zeichens wird
+       als 3 stellige Dezimalzahl eingeschlossen von \#-Zeichen dargestellt). 
+ 
+ 
+#on("bold")# 
+save ("filename", dostask) 
+#off ("b")# 
+  Die EUMEL-Datei 'filename' wird nach MS-DOS geschrieben. Unter MS-DOS
+  wird der ASCII Code, internationale Referenzversion gemäß DIN 66 003 verwendet.
+  Dies geschieht folgendermaßen: 
+    -  Die EUMEL-spezifischen Druckzeichen (Trenn -, Trenn k, Druck \#, ge­
+       schütztes Blank) werden in -, k, \# und Blank umgesetzt. 
+    -  Alle in der internationalen Referenzversion des ASCII Codes vorhandenen
+       Eumel-Zeichen werden auf diese abgebildet. 
+    -  Alle in der internationalen Referenzversion des ASCII Codes nicht vorhande­
+       nen Eumel-Zeichen werden durch eine Ersatzdarstellung dargestellt (der
+       Code des Zeichens wird als 3 stellige Dezimalzahl eingeschlossen von
+       \#-Zeichen dargestellt) 
+    -  Steht in einer Zeile nur das Kommando '\#page\#' so wird dieses in ein Sei­
+       tenvorschubsteuerzeichen (""12"") umgewandelt. 
+    -  Eine dreistellige Dezimalzahl eingeschlossen von \# Zeichen wird als Ersatz­
+       darstellung für das Zeichen mit dem durch die Dezimalzahl angegebenen
+       Code betrachte. Diese Ersatzdarstellung wird beim Schreiben aufgelöst (d.h.
+       durch das entsprechende Zeichen ersetzt). 
+    -  Nach jeder Zeile wird 'carriage return' und ' linefeed' angefügt 
+    -  Am Ende der Datei wird 'ctrl z' angehängt. 
+ 
+ 
+#on("bold")# 
+#ib#6.2 Betriebsart: file ascii german#ie# 
+ 
+fetch ("filename", dostask) 
+#off ("b")# 
+  Die MS-DOS Datei 'filename' wird in die EUMEL-Datei 'filename' kopiert. Dabei
+  werden von allen Zeichen nur die niederwertigen 7 Bit gemäß DIN 66 003, ASCII
+  Code, deutsche Referenzversion interpretiert. Die Datei wird so aufbereitet, daß ein
+  Bearbeiten mit dem EUMEL-Editor möglich ist. Dies geschieht wie in der Be­
+  triebsart 'file ascii', jedoch stehen statt []{}|\ die Umlaute und ß zur Verfügung. 
+ 
+ 
+#on("bold")# 
+save ("filename", dostask) 
+#off ("b")# 
+  Die EUMEL-Datei 'filename' wird nach MS-DOS geschrieben. Unter MS-DOS
+  wird der ASCII Code, deutsche Referenzversion gemäß DIN 66 003 verwendet. Dies
+  geschieht wie in der Betriebsart 'file ascii', jedoch stehen statt []{}|\ die Umlaute
+  zur Verfügung. 
+ 
+ 
+#on("bold")# 
+#ib#6.3 Betriebsart: file ibm#ie# 
+ 
+fetch ("filename", dostask) 
+#off ("b")# 
+  Die MS-DOS Datei 'filename' wird in die EUMEL-Datei 'filename' kopiert. Dabei
+  werden alle Zeichen wie in der von IBM verwendeten Version des ASCII Codes
+  interpretiert. Die Datei wird so aufbereitet, daß ein Bearbeiten mit dem EUMEL-
+  Editor möglich ist. Dies geschieht folgendermaßen: 
+    -  Alle im EUMEL darstellbaren Zeichen werden auf diese abgebildet. 
+    -  Die Zeichenfolgen CR LF, LF CR, LF, CR (CR = carriage return, LF = line­
+       feed) beenden einen Satz in der MS-DOS-Datei. Dementsprechend wird
+       eumelseitig die aktuelle Zeile beendet. 
+    -  Das Zeichen FF (form feed) beendet eumelseitig die aktuelle Zeile. Außerdem
+       wird ein Satz mit dem Inhalt "\#page\#" eingefügt. 
+    -  TAB's (Code 9) werden mit Blanks zur nächsten 8ter-Position expandiert. 
+    -  Alle anderen Zeichen mit 0 <= code (zeichen) <=  31 (Steuerzeichen)
+       werden durch eine Ersatzdarstellung dargestellt (der Code des Zeichens wird
+       als 3 stellige Dezimalzahl eingeschlossen von \#-Zeichen dargestellt). 
+ 
+ 
+#on("bold")# 
+save ("filename", dostask) 
+#off ("b")# 
+  Die EUMEL-Datei 'filename' wird nach MS-DOS geschrieben. Unter MS-DOS
+  wird der ASCII Code in der von IBM verwendeten Version verwendet. Dies ge­
+  schieht folgendermaßen: 
+    -  Die EUMEL-spezifischen Druckzeichen (Trenn -, Trenn k, Druck \#, ge­
+       schütztes Blank) werden in -, k, \# und Blank umgesetzt. 
+    -  Alle in der IBM Version des ASCII Codes vorhandenen Eumel-Zeichen
+       werden auf diese abgebildet. 
+    -  Alle in der IBM Version des ASCII Codes nicht vorhandenen Eumel-Zeichen
+       werden durch eine Ersatzdarstellung dargestellt (der Code des Zeichens wird
+       als 3 stellige Dezimalzahl eingeschlossen von \#-Zeichen dargestellt) 
+    -  Steht in einer Zeile nur das Kommando '\#page\#' so wird dieses in ein Sei­
+       tenvorschubsteuerzeichen (""12"") umgewandelt. 
+    -  Eine dreistellige Dezimalzahl eingeschlossen von \# Zeichen wird als Ersatz­
+       darstellung für das Zeichen mit dem durch die Dezimalzahl angegebenen
+       Code betrachte. Diese Ersatzdarstellung wird beim Schreiben aufgelöst (d.h.
+       durch das entsprechende Zeichen ersetzt). 
+    -  Nach jeder Zeile wird 'carriage return' und ' linefeed' angefügt 
+ 
+ 
+#on("bold")# 
+#ib#6.4 Betriebsart: file atari st#ie# 
+ 
+fetch ("filename", dostask) 
+#off ("b")# 
+  Die MS-DOS Datei 'filename' wird in die EUMEL-Datei 'filename' kopiert. Dabei
+  werden alle Zeichen wie in der vom Atari ST verwendeten Version des ASCII Codes
+  interpretiert. Die Datei wird so aufbereitet, daß ein Bearbeiten mit dem EUMEL-
+  Editor möglich ist. Dies geschieht folgendermaßen: 
+    -  Alle im EUMEL darstellbaren Zeichen werden auf diese abgebildet. 
+    -  Die Zeichenfolgen CR LF, LF CR, LF, CR (CR = carriage return, LF = line­
+       feed) beenden einen Satz in der MS-DOS-Datei. Dementsprechend wird
+       eumelseitig die aktuelle Zeile beendet. 
+    -  Das Zeichen FF (form feed) beendet eumelseitig die aktuelle Zeile. Außerdem
+       wird ein Satz mit dem Inhalt "\#page\#" eingefügt. 
+    -  TAB's (Code 9) werden mit Blanks zur nächsten 8ter-Position expandiert. 
+    -  Alle anderen Zeichen mit 0 <= code (zeichen) <=  31 (Steuerzeichen)
+       werden durch eine Ersatzdarstellung dargestellt (der Code des Zeichens wird
+       als 3 stellige Dezimalzahl eingeschlossen von \#-Zeichen dargestellt). 
+ 
+ 
+#on("bold")# 
+save ("filename", dostask) 
+#off ("b")# 
+  Die EUMEL-Datei 'filename' wird nach MS-DOS geschrieben. Unter MS-DOS
+  wird der ASCII Code in der vom Atari ST verwendeten Version verwendet. Dies
+  geschieht folgendermaßen: 
+    -  Die EUMEL-spezifischen Druckzeichen (Trenn -, Trenn k, Druck \#, ge­
+       schütztes Blank) werden in -, k, \# und Blank umgesetzt. 
+    -  Alle in der vom Atari ST verwendeten Version des ASCII Codes vorhandenen
+       Eumel-Zeichen werden auf diese abgebildet. 
+    -  Alle in der vom Atari ST verwendeten  Version des ASCII Codes nicht
+       vorhandenen Eumel-Zeichen werden durch eine Ersatzdarstellung dargestellt
+       (der Code des Zeichens wird als 3 stellige Dezimalzahl eingeschlossen von
+       \#-Zeichen dargestellt) 
+    -  Steht in einer Zeile nur das Kommando '\#page\#' so wird dieses in ein Sei­
+       tenvorschubsteuerzeichen (""12"") umgewandelt. 
+    -  Eine dreistellige Dezimalzahl eingeschlossen von \# Zeichen wird als Ersatz­
+       darstellung für das Zeichen mit dem durch die Dezimalzahl angegebenen
+       Code betrachte. Diese Ersatzdarstellung wird beim Schreiben aufgelöst (d.h.
+       durch das entsprechende Zeichen ersetzt). 
+    -  Nach jeder Zeile wird 'carriage return' und ' linefeed' angefügt 
+ 
+ 
+#on("bold")# 
+#ib#6.5 Betriebsart: file transparent#ie# 
+ 
+fetch ("filename", dostask) 
+#off ("b")# 
+  Die MS-DOS Datei 'filename' wird in die EUMEL-Datei 'filename' kopiert. Dabei
+  werden von allen Zeichen alle 8 Bit interpretiert. Es werden keine Zeichen einge­
+  fügt, gelöscht oder gewandelt. Somit stehen dann auch CR und LF Zeichen in der
+  EUMEL-Datei. 
+ 
+  Da eine solche Datei noch Steuerzeichen enthält, ist beim Bearbeiten mit dem
+  Editor Vorsicht geboten. 
+ 
+ 
+#on("bold")# 
+save ("filename", dostask) 
+#off ("b")# 
+  Die EUMEL-Datei 'filename' wird nach MS-DOS geschrieben. Es werden keine
+  Codeumsetzungen durchgeführt. Insbesondere muß die EUMEL-Datei auch die CR
+  LF Sequenzen für das Zeilenende enthalten. 
+ 
+ 
+#on("bold")# 
+#ib#6.6 Betriebsart: row text#ie# 
+#off ("b")# 
+ 
+Diese Betriebsart ist nur für Programmierer interessant. Sie ist für die Umsetzung
+exotischer Codes in den EUMEL-Code mittels ELAN-Programmen gedacht. 
+ 
+#on("bold")# 
+fetch ("filename", dostask) 
+#off ("b")# 
+  Die MS-DOS Datei 'filename' wird in einen Datenraum mit folgender Struktur
+  kopiert: 
+ 
+    STRUCT (INT benutzte texte, ROW 4000 TEXT datensatz) 
+ 
+  Dabei bekommt der Datenraum den Type 1000. Der Integer 'benutzte texte' gibt an,
+  wieviele Elemente des ROW 4000 TEXT benutzt sind. In jedem benutzten Element
+  des ROW 4000 TEXT steht der Inhalt einer logischen Gruppe der MS-DOS Disket­
+  te. (Eine logische Gruppe umfaßt bei einer einseitig beschriebenen MS-DOS
+  Diskette 512 Byte und bei einer zweiseitig beschriebenen 1024 bzw. 2048 Byte). In
+  dieser Betriebsart werden keine Zeichen der MS-DOS Datei konvertiert oder
+  interpretiert, so daß also auch alle Steuerzeichen erhalten bleiben. 
+ 
+ 
+#on("bold")# 
+save ("filename", dostask) 
+#off ("b")# 
+  Hier bezeichnet 'filename' einen Datenraum der Struktur: 
+ 
+    STRUCT (INT benutzte texte, ROW 4000 TEXT datensatz) 
+ 
+  Dieser Datenraum muß den Type 1000 haben. 
+  Es werden die benutzten Texte (1 bis benutzte texte) aneinandergehängt und ohne
+  irgendwelche Konvertierungen bzw. Interpretationen als MS-DOS Datei 'filename'
+  geschrieben. Dies bedeutet, daß die Texte auch alle von MS-DOS benötigten
+  Steuerzeichen (z.B. 'ctrl z' als Dateiendekennzeichen) enthalten müssen. 
+ 
+ 
+#on("bold")# 
+#ib#6.7 Betriebsart: ds#ie# 
+#off ("b")# 
+Diese Betriebsart ist nur für den Programmierer interessant. Sie ermöglicht das Abbil­
+den von Datenstrukturen zwischen MS-DOS und EUMEL. 
+ 
+#on("bold")# 
+fetch ("filename", dostask) 
+#off ("b")# 
+  Die MS-DOS Datei 'filename' wird blockweise in den Datenraum 'filename' ko­
+  piert. Hierbei wird der erste Block der MS-DOS Datei in die 2. Seite des Daten­
+  raums kopiert. (Die 2. Seite eines Datenraums ist die erste, die von einer Daten­
+  struktur voll überdeckt werden kann). 
+ 
+ 
+#on("bold")# 
+save ("filename", dostask) 
+#off ("b")# 
+  Der Datenraum 'filename' wird ab seiner 2. Seite in die MS-DOS Datei 'filename'
+  geschrieben. Hierbei werden alle Seiten des Datenraums (auch die nicht allokier­
+  ten) bis einschließlich der letzten allokierten Datenraumseite geschrieben. 
+ 
+ 
+#on("bold")# 
+#ib#7. Installation#ie# 
+#off ("b")# 
+ 
+Die Software zur Generierung der Tasks /"DOS" und /"DOS HD" wird auf einem
+EUMEL-Archiv ausgeliefert. 
+ 
+#on("bold")# 
+#ib#7.1 Installation der Task /"DOS"#ie# 
+            
+#ib#7.1.1 Installation im Multi-User#ie# 
+#off ("b")# 
+ 
+Die Software muß in einer privilegierten Task mit dem Namen 'DOS' installiert wer­
+den. Dies geschieht folgendermaßen: 
+ 
+ 
+  begin  ("DOS", "SYSUR") 
+ 
+  archive  ("austausch"); 
+  fetch    ("dos inserter", archive); 
+  run      ("dos inserter") 
+ 
+ 
+Danach stehen die Prozeduren 
+ 
+ 
+  PROC dos manager 
+  PROC dos manager   (INT CONST channel) 
+ 
+ 
+zur Verfügung. Beide Prozeduren machen die aufrufende Task zur Kommunikations­
+task für das Schreiben und Lesen von MS-DOS Disketten. Die erste benutzt dazu
+den Archivkanal (Kanal 31), bei der zweiten ist der Kanal über den Parameter ein­
+stellbar. Eine dieser Prozeduren muß jetzt aufgerufen werden. 
+ 
+#on("bold")# 
+#ib#7.1.2. Installation im Single-User#ie# 
+#off ("b")# 
+ 
+Die Software wird im Monitor ('gib Kommando'-Modus) durch folgende Kommandos
+installiert: 
+ 
+ 
+  archive  ("austausch"); 
+  fetch    ("dos inserter", archive); 
+  run      ("dos inserter") 
+ 
+ 
+Für das Schreiben und Lesen von MS-DOS Disketten wird der Archivkanal (Kanal
+31) benutzt. 
+ 
+ 
+#on("bold")# 
+#ib#7.2 Installation der Task /"DOS HD"#ie# 
+#off ("b")# 
+ 
+Die Software muß in einer privilegierten Task mit dem Namen 'DOS HD' installiert
+werden. Dies geschieht folgendermaßen: 
+ 
+ 
+  begin  ("DOS HD", "SYSUR") 
+ 
+  archive  ("austausch"); 
+  fetch    ("dos hd inserter", archive); 
+  run      ("dos hd inserter") 
+ 
+ 
+Danach steht die Prozedur 
+ 
+ 
+  PROC dos manager 
+ 
+ 
+zur Verfügung. Sie macht die aufrufende Task zur Kommunikationstask für das
+Schreiben und Lesen in der MS-DOS Partition der Platte. Sie benutzt dazu den
+Kanal 29, der, wie im Portierungshandbuch für den 8086 beschrieben, implementiert
+sein muß. 
+ 
+#page# 
+#headeven# 
+#end# 
+ 
+ 
+ 
+ 
+ 
+Herausgegeben von: 
+ 
+   Gesellschaft für Mathematik und Datenverarbeitung mbH 
+   (GMD) 
+   Schloß Birlinghoven 
+   5205 Sankt Augustin 1 
+ 
+   und 
+ 
+   Hochschulrechenzentrum der Universität Bielefeld 
+   (HRZ) 
+   Universitätsstraße 
+   4800 Bielefeld 1 
+ 
+Autor: 
+ 
+   Frank Klapper 
+ 
+überarbeitet von: 
+ 
+   Thomas Müller 
+   Hansgeorg Freese (GMD) 
+ 
+Umschlaggestaltung: 
+ 
+   Hannelotte Wecken 
+
+
+
+
+
+
diff --git a/dos/dump b/dos/dump
new file mode 100644
index 0000000..5138162
--- /dev/null
+++ b/dos/dump
@@ -0,0 +1,49 @@
+PACKET dump DEFINES 
+ 
+  dump:
+
+TEXT VAR ergebnis := "";
+
+PROC dump (TEXT CONST kommentar, dump text):
+  ergebnis := kommentar;
+  ergebnis CAT ": ";
+  INT VAR i;
+  FOR i FROM 1 UPTO LENGTH dump text REP
+    zeichen schreiben
+  PER;
+  ergebnis schreiben.
+
+zeichen schreiben:
+  INT CONST char code :: code (dump text SUB i);
+  IF char code < 32
+     THEN ergebnis CAT ("$" + text (char code) + "$")
+     ELSE ergebnis CAT code (char code)
+  FI.
+
+END PROC dump;
+
+PROC dump (TEXT CONST kommentar, INT CONST dump int):
+  ergebnis := kommentar;
+  ergebnis CAT ": ";
+  ergebnis CAT text (dump int);
+  ergebnis schreiben.
+
+END PROC dump;
+
+PROC dump (TEXT CONST kommentar, REAL CONST dump real):
+  ergebnis := kommentar;
+  ergebnis CAT ": ";
+  ergebnis CAT text (dump real);
+  ergebnis schreiben.
+
+END PROC dump;
+
+PROC ergebnis schreiben:
+  FILE VAR f := sequential file (output, "logbuch");
+  putline (f, ergebnis);
+  ergebnis := "".
+
+END PROC ergebnis schreiben;
+
+END PACKET dump;
+
diff --git a/dos/eu disk descriptor b/dos/eu disk descriptor
new file mode 100644
index 0000000..5a61367
--- /dev/null
+++ b/dos/eu disk descriptor	
@@ -0,0 +1,107 @@
+PACKET eu disk DEFINES                       (* Copyright (C) 1986, 87 *)
+                                             (* Frank Klapper          *)
+                                             (* 05.01.87               *)
+  load shard interface table,
+  open eu disk,
+  eu size,
+  eu heads,
+  eu tracks,
+  eu first sector,
+  eu last sector:
+
+LET table length = 15,
+ 
+    size field         = 1,
+    head field         = 2,
+    track field        = 3,
+    first sector field = 4,
+    last  sector field = 5;
+
+ROW table length ROW 5 INT VAR format table;
+
+INT VAR table top := 0,
+        table pointer;
+
+PROC open eu disk:
+  enable stop;
+  init check rerun;
+  IF hd version
+    THEN LEAVE open eu disk
+  FI;
+  INT CONST blocks := archive blocks;
+  IF blocks <= 0
+    THEN error stop ("keine Diskette eingelegt")
+  FI;
+  search format table entry.
+
+search format table entry:
+  IF table top < 1
+    THEN error stop ("SHard-Interfacetabelle nicht geladen")
+  FI;
+  table pointer := 1;
+  WHILE format table [table pointer][size field] <> blocks REP
+    table pointer INCR 1;
+    IF table pointer > table top
+      THEN error stop ("Diskettenformat nicht implementiert")
+    FI
+  PER.
+
+END PROC open eu disk;
+
+PROC load shard interface table:
+  FILE VAR f := sequential file (input, "shard interface");
+  TEXT VAR line;
+  table top := 0;
+  WHILE NOT eof (f) REP
+    get line (f, line);
+    IF (line SUB 1) <> ";"
+      THEN load line
+    FI
+  PER.
+
+load line:
+  table top INCR 1;
+  IF table top > table length
+    THEN error stop ("Shard Interface Tabelle zu groß")
+  FI;
+  INT VAR blank pos := 1;
+  format table [table top][size field]         := next int;
+  format table [table top][head field]         := next int;
+  format table [table top][track field]        := next int; 
+  format table [table top][first sector field] := next int;
+  format table [table top][last  sector field] := next int.
+
+next int:
+  line := compress (subtext (line, blank pos)) + " ";
+  blank pos := pos (line, " ");
+  int (subtext (line, 1, blank pos - 1)).
+
+END PROC load shard interface table;
+ 
+INT PROC eu size:
+  format table [table pointer][size field]
+
+END PROC eu size;
+
+INT PROC eu heads:
+  format table [table pointer][head field]
+
+END PROC eu heads;
+
+INT PROC eu tracks:
+  format table [table pointer][track field]
+
+END PROC eu tracks;
+
+INT PROC eu first sector:
+  format table [table pointer][first sector field]
+
+END PROC eu first sector;
+
+INT PROC eu last sector:
+  format table [table pointer][last sector field]
+
+END PROC eu last sector;
+
+END PACKET eu disk;
+
diff --git a/dos/fat.dos b/dos/fat.dos
new file mode 100644
index 0000000..2890b1a
--- /dev/null
+++ b/dos/fat.dos
@@ -0,0 +1,369 @@
+PACKET dos fat DEFINES                      (* Copyright (C) 1985, 86, 87 *)
+                                            (* Frank Klapper              *)
+                                            (* 11.09.87                   *)
+  read fat,
+  write fat,
+  first fat block ok,
+  clear fat ds,
+  format fat,
+
+  fat entry,
+  last fat chain entry,
+  is last fat chain entry,
+  erase fat chain,
+  available fat entry:
+
+  (* Referenz: 4. *)
+
+LET fat size                = 16 384, (* maximal 64 Sektoren a 512 Byte (256 Worte) *)
+    max anzahl fat sektoren = 64;
+
+LET FAT = BOUND STRUCT (ALIGN dummy,
+                        ROW 256 INT block row,      (* für Kopie des 1. Fatsektors *)
+                        ROW fat size INT fat row); 
+
+DATASPACE VAR fat ds;
+INITFLAG  VAR fat ds used := FALSE;
+FAT       VAR fat struktur;
+
+.fat: fat struktur.fat row.
+
+REAL VAR erster moeglicher freier eintrag;
+
+BOOL VAR kleines fat format;
+
+PROC read fat:
+  fat ds initialisieren;
+  fat bloecke lesen;
+  fat format bestimmen;
+  erster moeglicher freier eintrag := 2.0.
+
+fat ds initialisieren:
+  clear fat ds;
+  fat struktur := fat ds.
+
+fat bloecke lesen:
+  LET kein testblock = FALSE;
+  INT VAR block no;
+  FOR block no FROM 0 UPTO fat sectors - 1 REP
+     fat block lesen (block no, kein testblock)
+  PER.
+
+fat format bestimmen:
+  IF fat entrys <= 4086
+    THEN kleines fat format := TRUE
+    ELSE kleines fat format := FALSE
+  FI.
+
+END PROC read fat;
+
+PROC write fat:
+  disable stop;
+  INT VAR block nr;
+  FOR block nr FROM 0 UPTO fat sectors - 1 REP
+    fat block schreiben (block nr)
+  PER.
+
+END PROC write fat;
+
+BOOL PROC first fat block ok:
+  (* überprüft, ob der erste Block der Fat auf Diskette und im Speicher
+     gleich ist                                                        *)
+  enable stop;
+  LET testblock = TRUE;
+  fat block lesen (0, testblock);
+  INT VAR i;
+  FOR i FROM 1 UPTO 256 REP
+    vergleiche woerter
+  PER; 
+  TRUE.
+
+vergleiche woerter:
+  IF fat [i] <> fat struktur.block row [i] 
+    THEN LEAVE first fat block ok WITH FALSE
+  FI. 
+
+END PROC first fat block ok;
+
+PROC clear fat ds:
+  IF initialized (fat ds used)
+    THEN forget (fat ds)
+  FI;
+  fat ds := nilspace.
+
+END PROC clear fat ds;
+
+PROC format fat:
+  fat ds initialisieren;
+  fat format bestimmen;
+  erster moeglicher freier eintrag := 2.0;
+  write first four fat bytes;
+  write other fat bytes;
+  vermerke schreibzugriffe;
+  write fat.
+
+fat ds initialisieren:
+  clear fat ds;
+  fat struktur := fat ds.
+
+fat format bestimmen:
+  IF fat entrys <= 4086
+    THEN kleines fat format := TRUE
+    ELSE kleines fat format := FALSE
+  FI.
+
+write first four fat bytes:
+  fat [1] := word (media descriptor, 255);
+  IF kleines fat format
+    THEN fat [2] := word (255, 0)
+    ELSE fat [2] := word (255, 255)
+  FI.
+
+write other fat bytes:
+  INT VAR i;
+  FOR i FROM 3 UPTO 256 * fat sectors REP
+    fat [i] := 0
+  PER.
+
+vermerke schreibzugriffe:
+  FOR i FROM 0 UPTO fat sectors - 1 REP
+    schreibzugriff (i)
+  PER.
+
+END PROC format fat;
+
+(*-------------------------------------------------------------------------*)
+
+REAL PROC fat entry (REAL CONST real entry no):
+  (* 0 <= entry no <= 22 000 *)
+  INT CONST entry no :: int (real entry no);
+  IF kleines fat format
+    THEN construct 12 bit value
+    ELSE dint (fat [entry no + 1], 0)
+  FI.
+
+construct 12 bit value:
+  INT CONST first byte no := entry no + entry no DIV 2;
+  IF entry no MOD 2 = 0
+    THEN real ((right byte MOD 16) * 256 + left byte)
+    ELSE real (right byte * 16 + left byte DIV 16)
+  FI.
+
+left byte:
+  fat byte (first byte no).
+
+right byte:
+  fat byte (first byte no + 1).
+
+END PROC fat entry;
+
+TEXT VAR convert buffer := "12";
+
+INT PROC fat byte (INT CONST no): 
+  replace (convert buffer, 1, word); 
+  IF even byte no
+    THEN code (convert buffer SUB 1)
+    ELSE code (convert buffer SUB 2)
+  FI. 
+ 
+even byte no:
+  no MOD 2 = 0.
+
+word: 
+  fat [no DIV 2 + 1]. 
+
+END PROC fat byte; 
+ 
+PROC fat entry (REAL CONST real entry no, real value):
+  (* 0 <= entry no <= 22 000 *)
+  INT CONST entry no :: int (real entry no),
+            value    :: low word (real value);
+  IF kleines fat format
+    THEN write 12 bit value
+    ELSE fat [entry no + 1] := value;
+         schreibzugriff (entry no DIV 256)
+  FI;
+  update first possible available entry.
+
+write 12 bit value:
+  INT CONST first byte no :: entry no + entry no DIV 2;
+  schreibzugriff (fat block of first  byte);
+  schreibzugriff (fat block of second byte);
+  write value.
+
+fat block of first byte:
+  first byte no DIV 512.
+
+fat block of second byte:
+  second byte no DIV 512.
+
+write value:
+  IF even entry no
+    THEN write fat byte (first  byte no, value MOD 256);
+         write fat byte (second byte no,
+                        (right byte DIV 16) * 16 + value DIV 256)
+    ELSE write fat byte (first byte no,
+                         (left byte MOD 16) + 16 * (value MOD 16));
+         write fat byte (second byte no, value DIV 16)
+  FI.
+
+even entry no:
+  entry no MOD 2 = 0.
+
+second byte no:
+  first byte no + 1.
+
+left byte:
+  fat byte (first byte no).
+
+right byte:
+  fat byte (second byte no).
+
+update first possible available entry:
+  IF value = 0
+    THEN erster moeglicher freier eintrag :=
+         min (erster moeglicher freier eintrag, real entry no)
+  FI.
+
+END PROC fat entry; 
+
+PROC write fat byte (INT CONST byte no, new value):
+  read old word;
+  change byte;
+  write new word.
+
+read old word: 
+  replace (convert buffer, 1, word).
+
+write new word:
+  word := convert buffer ISUB 1.
+
+word:
+  fat [byte no DIV 2 + 1].
+
+change byte:
+  replace (convert buffer, byte pos, code (new value)).
+
+byte pos:
+  byte no MOD 2 + 1.
+
+END PROC write fat byte;
+
+REAL PROC last fat chain entry:
+  IF kleines fat format
+    THEN  4 088.0
+    ELSE 65 528.0
+  FI.
+
+END PROC last fat chain entry;
+
+BOOL PROC is last fat chain entry (REAL CONST value):
+  value >= last fat chain entry
+
+END PROC is last fat chain entry;
+
+PROC erase fat chain (REAL CONST first entry no):
+  REAL VAR next entry no := first entry no,
+           act  entry no := 0.0;
+  WHILE next entry exists REP
+    act entry no  := next entry no;
+    next entry no := fat entry (act entry no);
+    fat entry (act entry no, 0.0)
+  PER.
+
+next entry exists:
+  NOT is last fat chain entry (next entry no).
+
+END PROC erase fat chain; 
+
+REAL PROC available fat entry:
+  (* da die fat weniger als 22 000 Einträge umfaßt, kann ich diese als
+     INTEGER berechnen                                                   *)
+  INT VAR i;
+  REAL VAR real i := erster moeglicher freier eintrag;
+  FOR i FROM int (erster moeglicher freier eintrag) UPTO fat entrys - 1 REP
+    IF fat entry (real i) = 0.0
+      THEN erster moeglicher freier eintrag := real i;
+           LEAVE available fat entry WITH erster moeglicher freier eintrag
+    FI;
+    real i INCR 1.0
+  PER;
+  close work;
+  error stop ("MS-DOS Datentraeger voll");
+  1.0e99.
+
+END PROC available fat entry;
+
+(*-------------------------------------------------------------------------*)
+
+PROC fat block lesen (INT CONST block nr, BOOL CONST test block):
+  (* 0 <= block nr <= fat sectors - 1 *)
+  disable stop;
+  IF NOT test block
+    THEN kein schreibzugriff (block nr)
+  FI;
+  INT VAR kopie nr;
+  FOR kopie nr FROM 0 UPTO fat copies - 1 REP
+    clear error;
+    read disk block (fat ds, ds seiten nr, disk block nr)
+    UNTIL NOT is error
+  PER;
+  IF is error
+    THEN close work
+  FI.
+
+ds seiten nr:
+  IF test block
+    THEN 2
+    ELSE block nr + 2 + 1
+  FI.
+
+disk block nr:
+  begin of fat (kopie nr) + block nr.
+
+END PROC fat block lesen;
+
+PROC fat block schreiben (INT CONST block nr):
+  IF war schreibzugriff (block nr)
+    THEN wirklich schreiben
+  FI.
+
+wirklich schreiben:
+  disable stop;
+  INT VAR kopie nr;
+  FOR kopie nr FROM 0 UPTO fat copies - 1 REP
+    write disk block and close work if error (fat ds, ds seiten nr, disk block nr)
+  PER;
+  kein schreibzugriff (block nr).
+
+ds seiten nr:
+  block nr + 2 + 1.
+
+disk block nr:
+  begin of fat (kopie nr) + block nr.
+
+END PROC fat block schreiben;
+
+(*-------------------------------------------------------------------------*)
+
+ROW max anzahl fat sektoren BOOL VAR schreib zugriff tabelle;
+
+PROC schreibzugriff (INT CONST fat sektor):
+  schreibzugriff tabelle [fat sektor + 1] := TRUE
+
+END PROC schreibzugriff;
+
+PROC kein schreibzugriff (INT CONST fat sektor):
+  schreibzugriff tabelle [fat sektor + 1] := FALSE
+
+END PROC kein schreibzugriff;
+
+BOOL PROC war schreibzugriff (INT CONST fat sektor):
+  schreibzugriff tabelle [fat sektor + 1]
+
+END PROC war schreibzugriff;
+
+(*-------------------------------------------------------------------------*)
+
+END PACKET dos fat;
+
diff --git a/dos/fetch b/dos/fetch
new file mode 100644
index 0000000..7cb7571
--- /dev/null
+++ b/dos/fetch
@@ -0,0 +1,371 @@
+PACKET fetch DEFINES                   (* Copyright (C) 1985, 86, 87 *)
+                                       (* Frank Klapper              *)
+                                       (* 27.04.87                   *) 
+  fetch,
+  check file:
+
+LET ascii             = 1,
+    ascii german      = 2,
+    transparent       = 3,
+    row text          = 5,
+    ds                = 6,
+    dump              = 7,
+    atari st          = 10,
+    ibm               = 11,
+
+  (*line end chars    = ""10""12""13"",*)
+    min line end char = ""10"",
+    max line end char = ""13"",
+    lf                = ""10"",
+    cr                = ""13"",
+    tab code          = 9,
+    lf  code          = 10,
+    ff  code          = 12,
+    cr  code          = 13,
+    ctrl z            = ""26"", 
+
+    page cmd          = "#page#",
+
+    row text length   = 4000,
+    row text type     = 1000;
+
+BOUND STRUCT (INT size,
+              ROW row text length TEXT cluster row) VAR cluster struct;
+
+FILE VAR file;
+
+TEXT VAR buffer;
+INT VAR buffer length;
+
+PROC fetch (TEXT CONST name, DATASPACE VAR file ds, INT CONST mode):
+
+  SELECT mode OF 
+    CASE ascii, ascii german, atari st, ibm, transparent:
+                      fetch filemode (file ds, name, mode)
+    CASE row text   : fetch row textmode (file ds, name)
+    CASE ds         : fetch dsmode       (file ds, name)
+    CASE dump       : fetch dumpmode     (file ds, name)
+    OTHERWISE error stop ("Unzulässige Betriebsart")
+  END SELECT.
+
+END PROC fetch;
+
+PROC fetch filemode (DATASPACE VAR file space, TEXT CONST name,
+                     INT CONST code type):
+  enable stop;
+  initialize fetch filemode;
+  open fetch dos file (name);
+  WHILE NOT was last fetch cluster REP
+    get text of cluster;
+    write lines;
+(***************************************)
+    IF lines (file) > 3900
+      THEN putline (file, ">>> FREMDDATEI FUER EUMEL ZU LANG. ES KÖNNEN DATEN FEHLEN <<<");
+           LEAVE fetch filemode
+    FI;
+(***************************************)
+  UNTIL file end via ctrl z
+  PER;
+  write last line if necessary; 
+  close fetch dos file.
+ 
+initialize fetch filemode:
+  buffer := "";
+  buffer length := 0;
+  forget (file space);
+  file space := nilspace;
+  file := sequential file (output, file space);
+  BOOL VAR file end via ctrl z := FALSE.
+ 
+get text of cluster:
+  cat next fetch dos cluster (buffer);
+  IF ascii code
+    THEN ctrl z is buffer end
+  FI;
+  adapt code (buffer, buffer length + 1, code type);
+  buffer length := length (buffer).
+
+ascii code:
+  (code type = ascii) OR (code type = ascii german).
+
+ctrl z is buffer end:
+  INT  CONST ctrl z pos :: pos (buffer, ctrl z, buffer length + 1);
+  file end via ctrl z := ctrl z pos > 0;
+  IF file end via ctrl z
+    THEN buffer := subtext (buffer, 1, ctrl z pos - 1);
+         buffer length := length (buffer)
+  FI.
+
+write lines:
+  INT VAR line begin pos := 1, line end pos;
+  compute line end pos;
+  WHILE line end pos > 0 REP
+    putline (file, subtext (buffer, line begin pos, line end pos));
+    exec (PROC (TEXT CONST, INT CONST) control char conversion, file, code type);
+    line begin pos := line end pos + 1;
+    compute line end pos
+  PER;
+  buffer := subtext (buffer, line begin pos);
+  buffer length := length (buffer);
+  IF buffer length > 5 000
+    THEN putline (file, buffer);
+         exec (PROC (TEXT CONST, INT CONST) control char conversion, file, code type);
+         buffer := "";
+         buffer length := 0
+  FI.
+
+compute line end pos:
+  line end pos := line begin pos;
+  REP
+    line end pos := pos (buffer, min line end char, max line end char, line end pos);
+    INT CONST line end code :: code (buffer SUB line end pos);
+    SELECT line end code OF
+      CASE lf code: look for cr
+      CASE 11     : line end pos INCR 1
+      CASE cr code: look for lf
+    END SELECT
+  UNTIL line end code <> 11
+  PER.
+
+look for cr:
+  IF line end pos = buffer length
+    THEN line end pos := 0
+  ELIF (buffer SUB line end pos + 1) = cr
+    THEN line end pos INCR 1
+  FI.
+
+look for lf:
+  IF line end pos = buffer length
+    THEN line end pos := 0
+  ELIF (buffer SUB line end pos + 1) = lf
+    THEN line end pos INCR 1
+  FI.
+
+write last line if necessary:
+  IF buffer length > 0
+    THEN putline (file, buffer);
+         exec (PROC (TEXT CONST, INT CONST) control char conversion, file, code type);
+  FI.
+
+END PROC fetch filemode;
+
+PROC adapt code (TEXT VAR text buffer, INT CONST start pos, code type):
+  SELECT code type OF
+    CASE ascii       : cancel bit 8
+    CASE ascii german: cancel bit 8; ascii german adaption
+    CASE atari st    : atari st adaption
+    CASE ibm         : ibm adaption
+  (*CASE transparent : do nothing *)
+  END SELECT.
+
+cancel bit 8:
+  INT VAR set pos := pos (text buffer, ""128"", ""255"", start pos);
+  WHILE set pos > 0 REP
+    replace (text buffer, set pos, seven bit char);
+    set pos := pos (text buffer, ""128"", ""255"", set pos + 1)
+  PER.
+
+seven bit char:
+  code (code (text buffer SUB set pos) AND 127).
+
+ascii german adaption:
+  change all by replace (text buffer, start pos, "[", "Ä");
+  change all by replace (text buffer, start pos, "\", "Ö");
+  change all by replace (text buffer, start pos, "]", "Ü");
+  change all by replace (text buffer, start pos, "{", "ä");
+  change all by replace (text buffer, start pos, "|", "ö");
+  change all by replace (text buffer, start pos, "}", "ü");
+  change all by replace (text buffer, start pos, "~", "ß").
+
+atari st adaption:
+  change all by replace (text buffer, start pos, ""142"", "Ä");
+  change all by replace (text buffer, start pos, ""153"", "Ö");
+  change all by replace (text buffer, start pos, ""154"", "Ü");
+  change all by replace (text buffer, start pos, ""132"", "ä");
+  change all by replace (text buffer, start pos, ""148"", "ö");
+  change all by replace (text buffer, start pos, ""129"", "ü");
+  change all by replace (text buffer, start pos, ""158"", "ß").
+
+ibm adaption:
+  change all by replace (text buffer, start pos, ""142"", "Ä");
+  change all by replace (text buffer, start pos, ""153"", "Ö");
+  change all by replace (text buffer, start pos, ""154"", "Ü");
+  change all by replace (text buffer, start pos, ""132"", "ä");
+  change all by replace (text buffer, start pos, ""148"", "ö");
+  change all by replace (text buffer, start pos, ""129"", "ü");
+  change all by replace (text buffer, start pos, ""225"", "ß").
+
+END PROC adapt code;
+
+PROC change all by replace (TEXT VAR string, INT CONST begin pos,
+                            TEXT CONST old, new):
+
+  INT VAR p := pos (string, old, begin pos);
+  WHILE p > 0 REP
+    replace (string, p, new);
+    p := pos (string, old, p + 1)
+  PER.
+
+END PROC change all by replace;
+
+PROC control char conversion (TEXT VAR string, INT CONST code type):
+
+  IF code type <> transparent
+    THEN code conversion
+  FI.
+
+code conversion:
+  INT VAR p := pos (string, ""0"", ""31"", 1);
+  WHILE p > 0 REP
+    convert char;
+    p := pos (string, ""0"", ""31"", p)
+  PER.
+
+convert char:
+  INT CONST char code := code (string SUB p);
+  SELECT char code OF
+    CASE tab code: expand tab
+    CASE lf  code: change (string, p, p, "")
+    CASE ff  code: change (string, p, p, page cmd)
+    CASE cr  code: change (string, p, p, "")
+    OTHERWISE ersatzdarstellung
+  END SELECT.
+
+expand tab:
+  change (string, p, p, (8 - (p - 1) MOD 8) * " ").
+
+ersatzdarstellung:
+  TEXT CONST t := text (char code);
+  change (string, p, p, "#" + (3 - length (t)) * "0" + t + "#").
+
+END PROC control char conversion;
+
+PROC fetch rowtextmode (DATASPACE VAR file space,
+                        TEXT CONST name):
+  enable stop; 
+  open fetch dos file (name);
+  initialize fetch rowtext mode;
+  WHILE NOT was last fetch cluster REP
+    cluster struct.size INCR 1;
+    cluster struct.cluster row [cluster struct.size] := "";
+    cat next fetch dos cluster (cluster struct.cluster row [cluster struct.size])
+  PER; 
+  close fetch dos file.
+ 
+initialize fetch row text mode:
+  forget (file space);
+  file space := nilspace;
+  cluster struct := file space;
+  type (file space, row text type);
+  cluster struct.size := 0.
+
+END PROC fetch rowtext mode;
+
+PROC fetch ds mode (DATASPACE VAR in ds, TEXT CONST name):
+  enable stop;
+  open fetch dos file (name);
+  init fetch dsmode;
+  WHILE NOT was last fetch cluster REP
+    read next fetch dos cluster (in ds, ds block no);
+  PER; 
+  close fetch dos file.
+ 
+init fetch dsmode:
+  forget (in ds);
+  in ds := nilspace;
+  INT VAR ds block no := 2.
+
+END PROC fetch ds mode;
+
+PROC fetch dumpmode (DATASPACE VAR file space, TEXT CONST name):
+  enable stop; 
+  open fetch dos file (name);
+  initialize fetch dumpmode;
+  WHILE NOT was last fetch cluster REP
+    TEXT VAR cluster buffer := "";
+    cat next fetch dos cluster (cluster buffer);
+    dump cluster
+    UNTIL offset > 50 000.0
+  PER; 
+  close fetch dos file.
+ 
+initialize fetch dump mode:
+  BOOL VAR fertig := FALSE;
+  REAL VAR offset := 0.0;
+  forget (file space);
+  file space := nilspace;
+  file := sequential file (output, file space).
+
+dump cluster:
+  TEXT VAR dump line;
+  INT VAR line, column;
+  FOR line FROM 0 UPTO (cluster size DIV 16) - 1 REP
+    build dump line;
+    putline (file, dump line);
+    offset INCR 16.0
+  UNTIL fertig
+  PER.
+
+build dump line:
+  TEXT VAR char line := "";
+  dump line := text (offset, 6, 0);
+  dump line := subtext (dump line, 1, 5);
+  dump line CAT "   ";
+  FOR column FROM 0 UPTO 7 REP
+    convert char;
+    dump line CAT " "
+  PER;
+  dump line CAT " ";
+  FOR column FROM 8 UPTO 15 REP
+    convert char;
+    dump line CAT " "
+  PER;
+  dump line CAT "  ";
+  dump line CAT char line.
+
+convert char:
+  TEXT CONST char :: cluster buffer SUB (line * 16 + column + 1);
+  IF char = ""
+    THEN fertig := TRUE;
+         dump line CAT "  ";
+         LEAVE convert char
+  FI;
+  INT CONST char code := code (char);
+  LET hex chars = "0123456789ABCDEF";
+  dump line CAT (hex chars SUB (char code DIV 16 + 1));
+  dump line CAT (hex chars SUB (char code MOD 16 + 1));
+  charline CAT show char.
+
+show char:
+  IF (char code > 31 AND char code < 127)
+    THEN char
+    ELSE "." 
+  FI.
+
+END PROC fetch dump mode;
+
+PROC check file (TEXT CONST name):
+  disable stop;
+  DATASPACE VAR test ds := nilspace;
+  enable check file (name, test ds);
+  forget (test ds);
+  IF is error
+    THEN clear error;
+         error stop ("Fehler beim Prüflesen der Datei """ + name + """")
+  FI.
+
+END PROC check file;
+
+PROC enable check file (TEXT CONST name, DATASPACE VAR test ds):
+  enable stop;
+  open fetch dos file (name);
+  WHILE NOT was last fetch cluster REP
+    INT VAR dummy := 2;
+    read next fetch dos cluster (test ds, dummy)
+  PER; 
+  close fetch dos file.
+ 
+END PROC enable check file;
+
+END PACKET fetch;
+
diff --git a/dos/fetch save interface b/dos/fetch save interface
new file mode 100644
index 0000000..27b4925
--- /dev/null
+++ b/dos/fetch save interface	
@@ -0,0 +1,70 @@
+PACKET fetch save DEFINES                   (* Copyright (C) 1986 *)
+                                            (* Frank Klapper      *)
+  save fetch mode,                          (* 22.04.87           *)
+  path:
+
+LET ascii        = 1,
+    ascii german = 2,
+    transparent  = 3,
+    row text     = 5,
+    ds           = 6,
+    dump         = 7,
+    atari st     = 10,
+    ibm          = 11;
+
+INT PROC save fetch mode (TEXT CONST reserve string):
+  TEXT VAR modus;
+  INT CONST p := pos (reserve string, ":");
+  IF p = 0
+    THEN modus := reserve string
+    ELSE modus := subtext (reserve string, 1, p - 1)
+  FI;
+  modus normieren;
+  IF modus = "FILEASCII"
+    THEN ascii
+  ELIF modus = "FILEASCIIGERMAN"
+    THEN asciigerman
+  ELIF modus = "FILEATARIST"
+    THEN atari st
+  ELIF modus = "FILEIBM"
+    THEN ibm
+  ELIF modus = "FILETRANSPARENT"
+    THEN transparent
+  ELIF modus = "ROWTEXT"
+    THEN row text
+  ELIF modus = "DS"
+    THEN ds
+  ELIF modus = "DUMP"
+    THEN dump
+    ELSE error stop ("Unzulässige Betriebsart"); -1
+  FI.
+
+modus normieren:
+  change all (modus, " ", "");
+  INT VAR i;
+  FOR i FROM 1 UPTO LENGTH modus REP
+    INT CONST char code :: code (modus SUB i);
+    IF is lower case
+      THEN replace (modus, i, upper case char)
+    FI
+  PER.
+
+is lower case:
+  char code > 96 AND char code < 123.
+
+upper case char:
+  code (char code - 32).
+
+END PROC save fetch mode;
+
+TEXT PROC path (TEXT CONST reserve string):
+  INT CONST p :: pos (reserve string, ":");
+  IF p = 0
+    THEN ""
+    ELSE subtext (reserve string, p + 1)
+  FI.
+
+END PROC path;
+ 
+END PACKET fetch save;
+
diff --git a/dos/get put interface.dos b/dos/get put interface.dos
new file mode 100644
index 0000000..1d6de92
--- /dev/null
+++ b/dos/get put interface.dos	
@@ -0,0 +1,368 @@
+PACKET dos get put DEFINES                   (* Copyright (C) 1986, 87 *)
+                                             (* Frank Klapper          *)
+                                             (* 11.12.87               *)
+  log modus,
+
+  open   dos disk,
+  close  dos disk,
+  access dos disk,
+
+  open  fetch dos file,
+  close fetch dos file,
+  cat  next fetch dos cluster,
+  read next fetch dos cluster,
+  was last fetch cluster,
+
+  open save dos file,
+  write next save dos cluster,
+  close save dos file,
+
+  erase dos file,
+
+  all dosfiles,
+  all dossubdirs,
+  dosfile exists,
+  dos list,
+
+  clear dos disk,
+  format dos disk:
+
+BOOL VAR log flag := FALSE;
+
+PROC log modus (BOOL CONST status):
+  log flag := status
+
+END PROC log modus;
+
+(*-------------------------------------------------------------------------*)
+
+LET max cluster size = 8192,   (* 8192 * 8 = 64 KB *)
+    reals per sector = 64;
+
+LET CLUSTER = BOUND STRUCT (ALIGN dummy, 
+                            ROW max cluster size REAL cluster row); 
+ 
+CLUSTER VAR cluster;
+DATASPACE VAR cluster ds;
+INITFLAG VAR cluster ds used := FALSE;
+
+TEXT VAR convert buffer;
+INT  VAR convert buffer length;
+
+PROC init cluster handle:
+  IF initialized (cluster ds used)
+    THEN forget (cluster ds)
+  FI;
+  cluster ds            := nilspace;
+  cluster               := cluster ds;
+  convert buffer        := "";
+  convert buffer length := 0.
+
+END PROC init cluster handle;
+
+PROC cat cluster text (REAL CONST cluster no, TEXT VAR destination, INT CONST to):
+  read disk cluster (cluster ds, 2, cluster no);
+  init convert buffer;
+  INT VAR i;
+  FOR i FROM 1 UPTO sectors per cluster * reals per sector REP
+    replace (convert buffer, i, cluster.cluster row [i])
+  PER;
+  destination CAT subtext (convert buffer, 1, to).
+
+init convert buffer:
+  IF convert buffer length < cluster size
+    THEN convert buffer CAT (cluster size - convert buffer length) * "*";
+         convert buffer length := cluster size
+  FI.
+
+END PROC cat cluster text;
+
+PROC write text to cluster (REAL CONST cluster no, TEXT CONST string):
+  IF LENGTH string < cluster size
+    THEN execute write text (text (string, cluster size))
+    ELSE execute write text (string)
+  FI;
+  write disk cluster (cluster ds, 2, cluster no).
+
+END PROC write text to cluster;
+
+PROC execute write text (TEXT CONST string):
+  INT VAR i;
+  FOR i FROM 1 UPTO sectors per cluster * reals per sector REP
+    cluster.cluster row [i] := string RSUB i
+  PER.
+
+END PROC execute write text;
+
+(*-------------------------------------------------------------------------*)
+
+BOOL VAR disk open := FALSE;
+TEXT VAR act path;
+
+REAL VAR last access time;
+
+PROC open dos disk (TEXT CONST path):
+  IF log flag THEN dump ("open dos disk", path) FI;
+  enable stop;
+  close work;
+  init cluster handle;
+  act path  := path;
+  disk open := TRUE
+
+END PROC open dos disk;
+
+PROC close dos disk:
+  IF log flag THEN dump ("close dos disk", "") FI;
+  enable stop;
+  disk open := FALSE;
+  close work;
+  init cluster handle;               (* Datenraumespeicher freigeben *)
+  clear fat ds;
+  init dir ds.
+
+END PROC close dos disk;
+
+PROC access dos disk:
+  enable stop;
+  IF NOT disk open
+    THEN error stop ("DOS-Arbeit nicht eröffnet")
+  FI;
+  IF work closed COR (last access more than 5 seconds ago CAND disk changed)
+    THEN open eu disk;          (* hier wird der RERUN Check initialisiert *)
+         open dos disk;
+         read fat;
+         open dir (act path);
+         last access time := clock (1);
+         open work
+  FI.
+
+last access more than 5 seconds ago:
+  abs (clock (1) - last access time) > 5.0.
+
+disk changed:
+  IF hd version
+    THEN FALSE
+    ELSE last access time := clock (1);
+         NOT first fat block ok
+  FI.
+
+END PROC access dos disk;
+
+(*-------------------------------------------------------------------------*)
+
+REAL VAR next fetch cluster,
+         fetch rest;                (* in Bytes *)
+
+PROC open fetch dos file (TEXT CONST file name):
+  IF log flag THEN dump ("open fetch dos file", file name) FI;
+  enable stop;
+  access dos disk;
+  file info (file name, next fetch cluster, fetch rest).
+
+END PROC open fetch dos file;
+
+BOOL PROC was last fetch cluster:
+  IF log flag THEN dump ("was last fetch cluster", "") FI;
+  is last fat chain entry (next fetch cluster) OR fetch rest <= 0.0.
+
+END PROC was last fetch cluster;
+
+PROC cat next fetch dos cluster (TEXT VAR buffer):
+  IF log flag THEN dump ("cat next fetch dos cluster", "") FI;
+  enable stop;
+  IF was last fetch cluster
+    THEN error stop ("fetch nach Dateiende")
+  FI;
+  IF fetch rest < real (cluster size)
+    THEN cat cluster text (next fetch cluster, buffer, int (fetch rest));
+         fetch rest := 0.0
+    ELSE cat cluster text (next fetch cluster, buffer, cluster size);
+         fetch rest DECR real (cluster size)
+  FI;
+  last access time := clock (1);
+  next fetch cluster := fat entry (next fetch cluster).
+
+END PROC cat next fetch dos cluster;
+
+PROC read next fetch dos cluster (DATASPACE VAR read ds, INT VAR start page):
+  IF log flag THEN dump ("read next fetch dos cluster", start page) FI;
+  enable stop;
+  IF was last fetch cluster
+    THEN error stop ("fetch nach Dateiende")
+  FI;
+  read disk cluster (read ds, start page, next fetch cluster);
+  last access time := clock (1);
+  start page INCR sectors per cluster;
+  next fetch cluster := fat entry (next fetch cluster);
+  IF fetch rest < real (cluster size)
+    THEN fetch rest := 0.0
+    ELSE fetch rest DECR real (cluster size)
+  FI.
+
+END PROC read next fetch dos cluster;
+
+PROC close fetch dos file:
+  IF log flag THEN dump ("close fetch dos file", "") FI;
+
+END PROC close fetch dos file;
+
+(*-------------------------------------------------------------------------*)
+
+TEXT VAR save name;
+REAL VAR first save cluster,
+         last save cluster,
+         save size;
+
+PROC open save dos file (TEXT CONST file name):
+  IF log flag THEN dump ("open save dos file", file name) FI;
+  enable stop;
+  access dos disk;
+  IF file exists (file name) OR subdir exists (file name)
+    THEN error stop ("die Datei """ + file name + """ gibt es schon")
+  FI;
+  save name := file name;
+  first save cluster := -1.0;
+  save size := 0.0.
+
+END PROC open save dos file;
+
+PROC write next save dos cluster (TEXT CONST buffer):
+  IF log flag THEN dump ("write next save dos cluster", "") FI;
+  enable stop;
+  REAL CONST save cluster := available fat entry;
+  write text to cluster (save cluster, buffer);
+  last access time := clock (1);
+  save size INCR real (LENGTH buffer);
+  IF first save cluster < 2.0
+    THEN first save cluster := save cluster
+    ELSE fat entry (last save cluster, save cluster)
+  FI;
+  fat entry (save cluster, last fat chain entry);
+  last save cluster := save cluster.
+
+END PROC write next save dos cluster;
+
+PROC write next save dos cluster (DATASPACE CONST save ds, INT VAR start page):
+  IF log flag THEN dump ("write next save dos cluster", start page) FI;
+  enable stop;
+  REAL CONST save cluster := available fat entry;
+  write disk cluster (save ds, start page, save cluster);
+  last access time := clock (1);
+  start page INCR sectors per cluster;
+  save size INCR real (cluster size);
+  IF first save cluster < 2.0
+    THEN first save cluster := save cluster
+    ELSE fat entry (last save cluster, save cluster)
+  FI;
+  fat entry (save cluster, last fat chain entry);
+  last save cluster := save cluster.
+
+END PROC write next save dos cluster;
+
+PROC close save dos file:
+  IF log flag THEN dump ("close save dos file", "") FI;
+  enable stop;
+  IF first save cluster < 2.0
+    THEN LEAVE close save dos file
+  FI;
+  fat entry (last save cluster, last fat chain entry);
+  write fat;
+  insert dir entry (save name, first save cluster, save size);
+  last access time := clock (1).
+
+END PROC close save dos file;
+
+(*-------------------------------------------------------------------------*)
+
+PROC erase dos file (TEXT CONST file name):
+  IF log flag THEN dump ("erase dos file", file name) FI;
+  enable stop;
+  access dos disk;
+  REAL VAR first cluster, size;
+  file info (file name, first cluster, size);
+  delete dir entry (file name);
+  erase fat chain (first cluster);
+  write fat;
+  last access time := clock (1).
+
+END PROC erase dos file;
+
+(*-------------------------------------------------------------------------*)
+
+THESAURUS PROC all dosfiles:
+  IF log flag THEN dump ("all dosfile", "") FI;
+  enable stop;
+  access dos disk;
+  all files.
+
+END PROC all dosfiles;
+
+THESAURUS PROC all dossubdirs:
+  IF log flag THEN dump ("all subdirs", "") FI;
+  enable stop;
+  access dos disk;
+  all subdirs.
+
+END PROC all dossubdirs;
+
+BOOL PROC dos file exists (TEXT CONST file name):
+  IF log flag THEN dump ("dos file exists", file name) FI;
+  enable stop;
+  access dos disk;
+  file exists (file name).
+
+END PROC dos file exists;
+
+PROC dos list (DATASPACE VAR list ds):
+  IF log flag THEN dump ("dos list", "") FI;
+  enable stop;
+  access dos disk;
+  dir list (list ds).
+
+END PROC dos list;
+
+(*-------------------------------------------------------------------------*)
+
+PROC clear dos disk:
+  IF log flag THEN dump ("clear dos disk", "") FI;
+  enable stop;
+  IF hd version
+    THEN error stop ("nicht implementiert")
+    ELSE access dos disk;
+         format dir;
+         format fat;
+         last access time := clock (1)
+  FI.
+
+END PROC clear dos disk;
+
+PROC format dos disk (INT CONST format code):
+
+  IF log flag THEN dump ("format dos disk (" + text (format code) + ")", "") FI;
+  enable stop;
+  IF NOT disk open
+    THEN error stop ("DOS-Arbeit nicht eröffnet")
+  FI;
+  IF hd version
+    THEN error stop ("nicht implementiert")
+    ELSE do format
+  FI.
+
+do format:
+  IF bpb exists (format code)
+    THEN close work;
+         format archive (format code);
+         open eu disk;
+         write bpb (format code);
+         open dos disk;
+         format dir;       (* enthält 'open dir' *)
+         format fat;       (* enthält 'read fat' *)
+         open work
+    ELSE error stop ("Format unzulässig")
+  FI;
+  last access time := clock (1).
+
+END PROC format dos disk;
+
+END PACKET dos get put;
+
diff --git a/dos/insert.dos b/dos/insert.dos
new file mode 100644
index 0000000..14f98cd
--- /dev/null
+++ b/dos/insert.dos
@@ -0,0 +1,14 @@
+dump
+konvert
+open
+eu disk descriptor
+disk descriptor.dos
+block i/o
+name conversion.dos
+fat.dos
+dir.dos
+get put interface.dos
+fetch save interface
+fetch
+save 
+
diff --git a/dos/konvert b/dos/konvert
new file mode 100644
index 0000000..c5c4c43
--- /dev/null
+++ b/dos/konvert
@@ -0,0 +1,75 @@
+PACKET konvert DEFINES                               (* Copyright (C) 1986 *)
+                                                     (* Frank Klapper      *)
+                                                     (* 28.10.86           *)
+  high byte,
+  low byte,
+  word,
+  change low byte,
+  change high byte,
+  dint,
+  high word,
+  low word:
+
+INT PROC high byte (INT CONST value):
+  TEXT VAR x := "  ";
+  replace (x, 1, value);
+  code (x SUB 2)
+
+END PROC high byte;
+
+INT PROC low byte (INT CONST value):
+  TEXT VAR x := "  ";
+  replace (x, 1, value);
+  code (x SUB 1)
+
+END PROC low byte; 
+ 
+INT PROC word (INT CONST low byte, high byte):
+  TEXT CONST x :: code (low byte) + code (high byte);
+  x ISUB 1
+
+END PROC word;
+
+PROC change low byte (INT VAR word, INT CONST low byte):
+  TEXT VAR x := "  ";
+  replace (x, 1, word);
+  replace (x, 1, code (low byte));
+  word := x ISUB 1
+
+END PROC change low byte;
+
+PROC change high byte (INT VAR word, INT CONST high byte):
+  TEXT VAR x := "  ";
+  replace (x, 1, word);
+  replace (x, 2, code (high byte));
+  word := x ISUB 1
+
+END PROC change high byte;
+
+REAL PROC dint (INT CONST low word, high word):
+  real low word + 65536.0 * real high word.
+
+real low word:
+  real (low byte (low word)) + 256.0 * real (high byte (low word)).
+
+real high word:
+  real (low byte (high word)) + 256.0 * real (high byte (high word)).
+
+END PROC dint;
+
+INT PROC high word (REAL CONST double precission int):
+  int (double precission int / 65536.0)
+
+END PROC high word;
+
+INT PROC low word (REAL CONST double precission int): 
+  string of low bytes ISUB 1.
+
+string of low bytes:
+  code (int (double precission int MOD 256.0)) +
+  code (int ((double precission int MOD 65536.0) / 256.0)). 
+ 
+END PROC low word; 
+ 
+END PACKET konvert;
+
diff --git a/dos/manager-M.dos b/dos/manager-M.dos
new file mode 100644
index 0000000..e27c513
--- /dev/null
+++ b/dos/manager-M.dos
@@ -0,0 +1,211 @@
+PACKET dos manager multi DEFINES             (* Copyright (C) 1985, 86, 87 *)
+                                             (* Frank Klapper              *)
+  provide channel,                           (* 16.10.87                   *)
+  dos manager:
+ 
+LET std archive channel = 31,
+
+    ack              = 0,
+    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,
+    clear code       = 18,
+    reserve code     = 19,
+    free code        = 20,
+    check read code  = 22,
+    format code      = 23,
+
+    log code         = 78,
+
+    quote            = """";
+
+BOUND STRUCT (TEXT name, pass) VAR msg;
+
+TASK VAR order task;
+
+INT VAR dos channel;
+
+INT VAR fetch save modus;
+
+REAL VAR last access time := 0.0;
+
+TASK VAR disk owner := niltask; 
+
+TEXT VAR save file name;
+
+PROC provide channel (INT CONST channel):
+  dos channel := channel
+
+END PROC provide channel;
+
+IF hd version
+  THEN provide channel (29)
+  ELSE provide channel (std archive channel)
+FI;
+
+PROC dos manager:
+  dos manager (dos channel)
+
+END PROC dos manager;
+
+PROC dos manager (INT CONST channel):
+  dos channel := channel;
+  task password ("-");
+  global manager
+        (PROC (DATASPACE VAR, INT CONST, INT CONST, TASK CONST) dos manager) 
+
+END PROC dos manager;
+
+PROC dos manager (DATASPACE VAR ds, INT CONST order code, phase,
+                  TASK CONST from task):
+  enable stop;
+  order task := from task;
+  msg := ds;
+  IF NOT (order task = disk owner) AND 
+     order code <> free code AND order code <> reserve code
+    THEN errorstop ("DOS nicht angemeldet")
+  FI;
+  IF order task = disk owner
+    THEN last access time := clock (1)
+  FI;
+  SELECT order code OF 
+    CASE fetch code     : fetch file 
+    CASE save code      : save file
+    CASE erase code     : erase file
+    CASE clear code     : clear disk
+    CASE exists code    : exists file
+    CASE list code      : list disk
+    CASE all code       : deliver directory
+    CASE reserve code   : reserve
+    CASE free code      : free
+    CASE check read code: check
+    CASE format code    : format
+    CASE log code       : send log
+    OTHERWISE errorstop ("unbekannter Auftrag für Task: " + name (myself))
+  END SELECT.
+
+fetch file:
+  fetch (dos name (msg.name, read modus), ds, fetch save modus);
+  manager ok (ds).
+
+check:
+  check file (dos name (msg.name, read modus));
+  manager message (expanded name (msg.name, read modus) + " ohne Fehler gelesen"). 
+
+format:
+  IF phase = 1
+    THEN manager question ("Diskette formatieren")
+    ELSE format dos disk (int (msg.name));
+         manager ok (ds)
+  FI.
+
+save file:
+  IF phase = 1
+    THEN save first phase
+    ELSE save second phase
+  FI.
+
+save first phase:
+  save file name := dos name (msg.name, write modus);
+  IF dos file exists (save file name)
+    THEN manager question (expanded name (msg.name, write modus) + " auf der MS-DOS Disk ueberschreiben")
+    ELSE send (order task, second phase ack, ds)
+  FI.
+
+save second phase:
+  IF dos file exists (save file name)
+    THEN erase dos file (save file name)
+  FI;
+  save (save file name, ds, fetch save modus);
+  forget (ds) ;
+  ds := nilspace ;
+  manager ok (ds).
+
+clear disk: 
+  IF phase = 1
+    THEN manager question ("Diskette loeschen")
+    ELSE clear dos disk;
+         manager ok (ds)
+  FI.
+
+erase file:
+  IF dos file exists (dos name (msg.name, read modus))
+    THEN IF phase = 1
+           THEN manager question (expanded name (msg.name, TRUE) + " auf der MS-DOS Disk loeschen")
+           ELSE erase dos file (dos name (msg.name, read modus));
+                manager ok (ds)
+         FI
+    ELSE manager message ("die Datei " + expanded name (msg.name, TRUE) + " gibt es nicht auf der MS-DOS Disk")
+  FI.
+ 
+exists file:
+  IF dos file exists (dos name (msg.name, read modus))
+    THEN manager ok (ds)
+    ELSE send (order task, false code, ds)
+  FI.
+
+list disk:
+  dos list (ds);
+  manager ok (ds).
+
+send log:
+  forget (ds);
+  ds := old ("logbuch");
+  manager ok (ds).
+
+deliver directory:
+  forget (ds);
+  ds := nilspace;
+  BOUND THESAURUS VAR all names := ds;
+  all names := all dos files;
+  manager ok (ds).
+
+reserve:
+  IF reserve or free permitted
+    THEN continue channel (dos channel);
+         disk owner := from task;
+         fetch save modus := save fetch mode (msg.name);
+         open dos disk (path (msg.name));
+         forget ("logbuch", quiet);
+         manager ok (ds)
+    ELSE errorstop ("Archivlaufwerk wird von Task """+ name (disk owner) + """ benutzt")
+  FI.
+
+reserve or free permitted :
+  from task = disk owner OR last access more than five minutes ago
+  OR disk owner = niltask OR NOT
+  (exists (disk owner) OR station(disk owner) <> station (myself)).
+
+last access more than five minutes ago :
+  abs (last access time - clock (1)) > 300.0.
+
+free: 
+  IF reserve or free permitted
+    THEN close dos disk;
+         disk owner := niltask;
+         break (quiet);
+         manager ok (ds)
+    ELSE manager message ("DOS nicht angemeldet")
+  FI.
+
+END PROC dos manager;
+
+PROC manager ok (DATASPACE VAR ds):
+  send (order task, ack, ds);
+  last access time := clock (1).
+
+END PROC manager ok;
+
+TEXT PROC expanded name (TEXT CONST name, BOOL CONST status):
+  text (quote + dos name (name, status) + quote, 14)
+
+END PROC expanded name;
+
+END PACKET dos manager multi;
+
diff --git a/dos/manager-S.dos b/dos/manager-S.dos
new file mode 100644
index 0000000..23885e6
--- /dev/null
+++ b/dos/manager-S.dos
@@ -0,0 +1,268 @@
+PACKET dos single DEFINES                       (* Copyright (C) 1985 *)
+                                                (* Frank Klapper      *)
+                                                (* 11.09.87           *)
+  /,
+  dos,
+  provide dos channel,
+  archive,
+  reserve,
+  release,
+  save,
+  fetch,
+  erase,
+  check,
+  exists,
+  ALL,
+  SOME,
+  clear,
+  list, 
+  format:
+
+LET std archive channel = 31,
+    main    channel = 1;
+
+INT VAR dos channel := std archive channel;
+INT VAR fetch save modus;
+
+TYPE DOSTASK = TEXT;
+
+DOSTASK CONST dos := "DOS";
+
+OP := (DOSTASK VAR d, TEXT CONST t):
+  CONCR (d) := t
+
+END OP :=;
+
+DOSTASK OP / (TEXT CONST text):
+  DOSTASK VAR d;
+  CONCR (d) := text;
+  d
+
+END OP /;
+
+BOOL PROC is dostask (DOSTASK CONST d):
+  CONCR (d) = "DOS"
+
+END PROC is dos task;
+
+PROC provide dos channel (INT CONST channel no):
+  dos channel := channel no
+
+END PROC provide dos channel;
+
+DATASPACE VAR space := nilspace;
+forget (space);
+
+PROC reserve (TEXT CONST string, DOSTASK CONST task):
+   IF is dostask (task)
+    THEN fetch save modus := save fetch mode (string);
+         open dos disk (path (string))
+    ELSE error stop ("die angesprochene Task existiert nicht")
+  FI.
+
+END PROC reserve;
+
+PROC archive (TEXT CONST string, DOSTASK CONST task):
+  reserve (string, task)
+
+END PROC archive;
+
+PROC release (DOSTASK CONST task):
+  IF is dos task (task)
+    THEN close dos disk
+    ELSE error stop ("die angesprochene Task existiert nicht")
+  FI.
+
+END PROC release;
+
+PROC fetch (TEXT CONST name, DOSTASK CONST from):
+  IF is dostask (from)
+    THEN fetch from dos disk
+    ELSE error stop ("die angesprochene Task existiert nicht")
+  FI.
+
+fetch from dos disk:
+  IF NOT exists (name) COR overwrite permitted
+    THEN do fetch 
+  FI.
+
+overwrite permitted:
+  say ("eigene Datei """) ; 
+  say (name) ; 
+  yes (""" auf der Diskette ueberschreiben"). 
+
+do fetch:
+  last param (name);
+  disable stop;
+  continue (dos channel);
+  fetch (dos name (name, read modus), space, fetch save modus);
+  continue (main channel);
+  IF NOT is error
+    THEN forget (name, quiet);
+         copy (space, name)
+  FI;
+  forget (space).
+
+END PROC fetch;
+
+PROC erase (TEXT CONST name, DOSTASK CONST task):
+  IF is dos task (task)
+    THEN do erase dos file
+    ELSE error stop ("die angesprochene Task existiert nicht")
+  FI.
+
+do erase dos file:
+  IF NOT exists (name, /"DOS")
+    THEN error stop ("die Datei """ + name + """ gibt es nicht")
+  ELIF yes ("""" + dos name (name, read modus)+ """ auf Der Diskette loeschen")
+    THEN disable stop;
+         continue (dos channel);
+         erase dos file (dos name (name, read modus));
+         continue (main channel)
+  FI.
+
+END PROC erase;
+
+PROC save (TEXT CONST name, DOSTASK CONST task):
+  IF is dos task (task)
+    THEN save to dos disk
+    ELSE error stop ("die angesprochene Task existiert nicht")
+  FI.
+
+save to dos disk:
+  TEXT CONST save file name :: dos name (name, write modus);
+  disable stop;
+  continue (dos channel);
+  IF NOT dos file exists (save file name) COR overwrite permitted
+    THEN IF dos file exists (save file name)
+           THEN erase dos file (save file name)
+         FI;
+         save (save file name, old (name), fetch save modus);
+  FI;
+  continue (main channel).
+
+overwrite permitted:
+  continue (main channel);
+  BOOL CONST result :: yes ("""" + save file name + """ auf der Diskette ueberschreiben");
+  continue (dos channel);
+  result.
+
+END PROC save;
+
+PROC check (TEXT CONST name, DOSTASK CONST from):
+  IF is dostask (from)
+    THEN disable stop;
+         continue (dos channel);
+         check file (dos name (name, read modus));
+         continue (main channel)
+    ELSE error stop ("die angesprochene Task existiert nicht")
+  FI.
+
+END PROC check;
+
+BOOL PROC exists (TEXT CONST name, DOSTASK CONST task):
+  IF is dos task (task)
+    THEN disable stop;
+         continue (dos channel);
+         BOOL VAR dummy := dos file exists (dos name (name, read modus));
+         continue (main channel);
+         enable stop;
+         dummy
+    ELSE error stop ("die angesprochene Task existiert nicht"); FALSE
+  FI.
+
+END PROC exists;
+
+PROC list (DOSTASK CONST from):
+  forget (space);
+  space := nilspace;
+  FILE VAR list file := sequential file (output, space);
+  list (list file, from);
+  modify (list file);
+  show (list file);
+  forget (space).
+
+ENDPROC list;
+
+PROC list (FILE VAR list file, DOSTASK CONST from):
+  IF is dos task (from)
+    THEN list dos disk
+    ELSE error stop ("die angesprochene Task existiert nicht")
+  FI.
+
+list dos disk:
+  disable stop;
+  continue (dos channel);
+  dos list (space);
+  continue (main channel);
+  enable stop;
+  output (list file);
+  FILE VAR list source := sequential file (output, space);
+  TEXT VAR line;
+  WHILE NOT eof (list source) REP
+    getline (list source, line);
+    putline (list file,   line)
+  PER.
+
+END PROC list;
+
+THESAURUS OP ALL (DOSTASK CONST task):
+  IF is dos task (task)
+    THEN disable stop;
+         continue (dos channel);
+         THESAURUS VAR dummy := all dos files;
+         continue (main channel);
+         enable stop;
+         dummy
+    ELSE error stop ("die angesprochene Task existiert nicht"); empty thesaurus
+  FI.
+
+END OP ALL;
+
+THESAURUS OP SOME (DOSTASK CONST task):
+  IF is dos task (task)
+    THEN disable stop;
+         continue (dos channel);
+         THESAURUS VAR dummy := all dos files;
+         continue (main channel);
+         enable stop;
+         SOME dummy
+    ELSE error stop ("die angesprochene Task existiert nicht"); empty thesaurus
+  FI.
+
+END OP SOME;
+
+PROC clear (DOSTASK CONST task):
+  IF is dos task (task)
+    THEN clear disk
+    ELSE error stop ("die angesprochene Task existiert nicht")
+  FI.
+
+clear disk:
+  disable stop;
+  IF yes ("Diskette loeschen")
+    THEN continue (dos channel);
+         clear dos disk;
+         continue (main channel)
+  FI.
+
+END PROC clear;
+
+PROC format (INT CONST format code, DOSTASK CONST task):
+  IF is dos task (task)
+    THEN format disk
+    ELSE error stop ("die angesprochene Task existiert nicht")
+  FI.
+
+format disk:
+  disable stop;
+  IF yes ("Diskette formatieren")
+    THEN continue (dos channel);
+         format dos disk (format code);
+         continue (main channel)
+  FI.
+
+END PROC format;
+
+END PACKET dos single;
+
diff --git a/dos/name conversion.dos b/dos/name conversion.dos
new file mode 100644
index 0000000..e72d838
--- /dev/null
+++ b/dos/name conversion.dos	
@@ -0,0 +1,77 @@
+PACKET name conversion DEFINES                  (* Copyright (C) 1985 *)
+                                                (* Frank Klapper      *)
+  dos name,                                     (* 31.12.86           *)
+
+  read  modus,
+  write modus:
+
+BOOL CONST read  modus :: TRUE,
+           write modus :: NOT read modus;
+
+LET upper case chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$#&§!()-{}`_",
+    lower case chars = "abcdefghijklmnopqrstuvwxyz";
+
+TEXT PROC dos name (TEXT CONST eu name, BOOL CONST read write modus):
+  enable stop;
+  INT CONST point pos :: pos (eu name, ".");
+  IF name extension exists
+    THEN changed name with extension
+    ELSE changed name without extension
+  FI.
+
+name extension exists:
+  point pos > 0.
+
+changed name with extension:
+  TEXT CONST name pre  :: compress (subtext (eu name, 1, point pos - 1)),
+             name post :: compress (subtext (eu name, point pos + 1));
+  IF LENGTH name pre = 0 OR LENGTH name pre > 8 OR LENGTH name post > 3
+    THEN error
+  FI;
+  IF LENGTH name post = 0
+    THEN new name (name pre, read write modus)
+    ELSE new name (name pre, read write modus) + "."
+       + new name (name post, read write modus)
+  FI.
+
+changed name without extension:
+  IF LENGTH eu name > 8 OR LENGTH euname < 1
+    THEN error
+  FI;
+  new name (eu name, read write modus).
+
+error:
+  error stop ("Unzulässiger Name").
+
+END PROC dos name;
+
+TEXT PROC new name (TEXT CONST old name, BOOL CONST read write modus):
+  TEXT VAR new := "";
+  INT VAR count;
+  FOR count FROM 1 UPTO LENGTH old name REP
+    convert char
+  PER;
+  new.
+
+convert char:
+  TEXT CONST char :: old name SUB count;
+  IF is lower case char
+    THEN new CAT (upper case chars SUB string pos)
+  ELIF is upper case char OR read write modus
+    THEN new CAT char
+  ELSE error stop ("Unzulässiger Name")
+  FI.
+
+is lower case char:
+  pos (lower case chars, char) > 0.
+
+is upper case char:
+  pos (upper case chars, char) > 0. 
+
+string pos:
+  pos (lower case chars, char).
+
+END PROC new name; 
+ 
+END PACKET name conversion;
+
diff --git a/dos/open b/dos/open
new file mode 100644
index 0000000..518c4b8
--- /dev/null
+++ b/dos/open
@@ -0,0 +1,66 @@
+PACKET open DEFINES                             (* Copyright (C) 1986 *)
+                                                (* Frank Klapper      *)
+  open  work,                                   (* 05.01.87           *)
+  close work,
+  work opened,
+  work closed,
+  init check rerun,
+  check rerun,
+
+  hd version:
+
+BOOL VAR open;
+INT VAR old session;
+
+BOOL VAR hd flag := FALSE;
+
+INITFLAG VAR packet := FALSE;
+
+PROC open work:
+  open := TRUE
+
+END PROC open work;
+
+PROC close work:
+  open := FALSE
+
+END PROC close work;
+
+BOOL PROC work opened:
+  IF NOT initialized (packet)
+    THEN close work
+  FI;
+  open
+
+END PROC work opened;
+
+BOOL PROC work closed:
+  NOT work opened
+
+END PROC work closed;
+
+PROC init check rerun:
+  old session := session
+
+END PROC init check rerun;
+
+PROC check rerun:
+  IF session <> old session
+    THEN close work;
+         error stop ("Diskettenzugriff im RERUN")
+  FI.
+
+END PROC check rerun;
+
+PROC hd version (BOOL CONST status):
+  hd flag := status
+
+END PROC hd version;
+
+BOOL PROC hd version:
+  hd flag
+
+END PROC hd version;
+
+END PACKET open;
+
diff --git a/dos/save b/dos/save
new file mode 100644
index 0000000..7e67e91
--- /dev/null
+++ b/dos/save
@@ -0,0 +1,233 @@
+PACKET save DEFINES                   (* Copyright (C) 1985, 86, 87 *)
+                                      (* Frank Klapper              *)
+                                      (* 27.04.87                   *)
+  save:
+
+LET ascii        = 1,
+    ascii german = 2,
+    transparent  = 3,
+    row text     = 5,
+    ds           = 6,
+    atari st     = 10,
+    ibm          = 11,
+
+    ff           = ""12"",
+    ctrl z       = ""26"",
+    cr lf        = ""13""10"",
+
+    row text mode length = 4000;
+
+TEXT VAR buffer;
+
+BOUND STRUCT (INT size,
+              ROW row text mode length TEXT cluster row) VAR cluster struct;
+
+PROC save (TEXT CONST file name, DATASPACE CONST file ds, INT CONST mode):
+
+  SELECT mode OF 
+    CASE ascii, ascii german, atari st, ibm, transparent:
+                      save filemode (file ds, filename, mode)
+    CASE row text   : save row textmode (file ds, filename)
+    CASE ds         : save dsmode       (file ds, filename)
+    OTHERWISE error stop ("Unzulässige Betriebsart")
+  END SELECT.
+
+END PROC save;
+
+PROC save filemode (DATASPACE CONST file space, TEXT CONST name, INT CONST code type):
+
+  enable stop;
+  open save dos file (name);
+  FILE VAR file := sequential file (modify, file space);
+  buffer := "";
+  INT VAR line no;
+  FOR line no FROM 1 UPTO lines (file) REP
+    to line (file, line no);
+    buffer cat file line;
+    WHILE length (buffer) >= cluster size REP
+      write next save dos cluster (subtext (buffer, 1, cluster size));
+      buffer := subtext (buffer, cluster size + 1)
+    PER
+  PER;
+  IF ascii code
+    THEN buffer CAT ctrl z
+  FI;
+  write rest;
+  close save dos file;
+  buffer := "".
+
+buffer cat file line:
+  exec (PROC (TEXT CONST, INT CONST) cat adapted line, file, code type).
+ 
+ascii code:
+  (code type = ascii) OR (code type = ascii german).
+
+write rest:
+  WHILE buffer <> ""
+    REP write next save dos cluster (subtext (buffer, 1, cluster size));
+        buffer := subtext (buffer, cluster size + 1)
+  PER.
+ 
+END PROC save filemode; 
+ 
+PROC cat adapted line (TEXT VAR line, INT CONST code type):
+
+  IF code type = transparent
+    THEN buffer CAT line
+    ELSE change esc sequences;
+         change eumel print chars;
+         SELECT code type OF
+           CASE ascii       : ascii change
+           CASE ascii german: ascii german change
+           CASE atari st    : atari st change
+           CASE ibm         : ibm change
+         END SELECT;
+         buffer CAT line;
+         IF (line SUB length (line)) <> ff
+           THEN buffer CAT cr lf
+         FI
+  FI.
+
+change esc sequences:
+  change all (line, "#page#", ff);
+  INT VAR p := pos (line, "#");
+  WHILE p > 0 REP
+    IF is esc sequence
+      THEN change (line, p, p+4, coded char)
+    FI;
+    p := pos (line, "#", p+1)
+  PER.
+
+is esc sequence:
+  LET digits = "0123456789";
+  (line SUB (p+4)) = "#"         CAND pos (digits, line SUB p+1) > 0 CAND
+  pos (digits, line SUB p+2) > 0 CAND pos (digits, line SUB p+3) > 0.
+
+coded char:
+  code (int (subtext (line, p+1, p+3))).
+
+change eumel print chars:
+  p := pos (line, ""220"", ""223"", 1);
+  WHILE p > 0 REP
+    replace (line, p, std char);
+    p := pos (line, ""220"", ""223"", p + 1)
+  PER.
+
+std char:
+ "k-# " SUB (code (line SUB p) - 219).
+
+ascii change: 
+  change all (line, "ß", "#251#");
+  p := pos (line, "Ä", "ü", 1);
+  WHILE p > 0 REP
+    change (line, p, p, ersatzdarstellung (line SUB p));
+    p := pos (line, "Ä", "ü", p + 1)
+  PER.
+
+ascii german change: 
+  change all (line, "[", "#091#");
+  change all (line, "\", "#092#");
+  change all (line, "]", "#093#");
+  change all (line, "{", "#123#");
+  change all (line, "|", "#124#");
+  change all (line, "}", "#125#");
+  change all (line, "~", "#126#");
+  change all (line, "ß", ""126"");
+  p := pos (line, "Ä", "ü", 1);
+  WHILE p > 0 REP
+    replace (line, p, umlaut in ascii german);
+    p := pos (line, "Ä", "ü", p + 1)
+  PER.
+
+umlaut in ascii german:
+  "[\]{|}" SUB (code (line SUB p) - 213).
+
+ibm change: 
+  change all (line, "ß", ""225"");
+  p := pos (line, "Ä", "ü", 1);
+  WHILE p > 0 REP
+    replace (line, p, umlaut in ibm);
+    p := pos (line, "Ä", "ü", p + 1)
+  PER.
+
+atari st change: 
+  change all (line, "ß", ""158"");
+  p := pos (line, "Ä", "ü", 1);
+  WHILE p > 0 REP
+    replace (line, p, umlaut in ibm);
+    p := pos (line, "Ä", "ü", p + 1)
+  PER.
+
+umlaut in ibm:
+  ""142""153""154""132""148""129"" SUB (code (line SUB p) - 213).
+
+END PROC cat adapted line;
+
+TEXT PROC ersatzdarstellung (TEXT CONST char):
+
+  TEXT CONST t :: text (code (char SUB 1));
+  "#" + (3 - length (t)) * "0" + t + "#"
+
+END PROC ersatzdarstellung;
+
+PROC save rowtextmode (DATASPACE CONST space, TEXT CONST name):
+
+  enable stop;
+  open save dos file (name);
+  init save row textmode;
+  WHILE line no < cluster struct.size REP
+    fill buffer;
+    write next save dos cluster (subtext (buffer, 1, cluster size));
+    remember rest
+  PER;
+  write rest;
+  close save dos file;
+  buffer := "".
+
+init save rowtextmode:
+  cluster struct  := space;
+  buffer := "";
+  INT VAR line no := 0.
+
+fill buffer:
+  WHILE line no < cluster struct.size AND NOT buffer full REP
+    line no INCR 1;
+    buffer CAT cluster struct.cluster row [line no]
+  PER.
+
+buffer full:
+  LENGTH buffer >= cluster size.
+
+remember rest:
+  buffer := subtext (buffer, cluster size + 1).
+
+write rest:
+  WHILE buffer <> ""
+    REP write next save dos cluster (subtext (buffer, 1, cluster size));
+        remember rest
+  PER.
+
+END PROC save rowtextmode;
+ 
+PROC save ds mode (DATASPACE CONST out ds, TEXT CONST name):
+
+  enable stop;
+  open save dos file (name);
+  INT VAR page no := first non dummy ds page;
+  get last allocated ds page; 
+  WHILE page no <= last allocated ds page REP
+    write next save dos cluster (out ds, page no);
+  PER;
+  close save dos file.
+
+get last allocated ds page:
+  INT VAR last allocated ds page := -1, 
+          i;
+  FOR i FROM 1 UPTO ds pages (out ds) REP
+    last allocated ds page := next ds page (out ds, last allocated ds page) 
+  PER.
+
+END PROC save ds mode;
+
+END PACKET save;
+
diff --git a/dos/shard interface b/dos/shard interface
new file mode 100644
index 0000000..20d9b76
--- /dev/null
+++ b/dos/shard interface	
@@ -0,0 +1,20 @@
+; ';' in Spalte 1 kennzeichnet eine Kommentarzeile
+; alle Werte müssen durch Blanks getrennt werden
+;
+;heads: Anzahl der Köpfe, positiv für cylinderorientiertes Lesen
+;                         negativ für seitenorientiertes Lesen
+;
+;size     heads   tracks    first sectors  last sector
+;=====================================================
+320        1       40         1              8
+360        1       40         1              9
+640       -2       40         1              8
+720       -2       40         1              9
+800        2       40         1             10
+1440      -2       80         1              9
+1600       2       80         1             10
+2400      -2       80         1             15
+1232       1       77         0             15
+2464      -2       77         0             15
+; END OF FILE
+
diff --git a/dynamo/dyn.33 b/dynamo/dyn.33
new file mode 100644
index 0000000..a17bd55
--- /dev/null
+++ b/dynamo/dyn.33
@@ -0,0 +1,2073 @@
+(**************************************************************************)
+(**************************************************************************)
+(******                                                              ******)
+(******                                                              ******)
+(******     DYNAMO - III - ELAN  PRECOMPILER                         ******)
+(******                                                              ******)
+(******                                                              ******)
+(******     AUTOREN :  R. Keil,                                      ******)
+(******                T. Froehlich                                  ******)
+(******                                                              ******)
+(******     VERSION :  3.3.7                                         ******)
+(******                                                              ******)
+(******                                                              ******)
+(******     AENDERUNGEN:                                             ******)
+(******     05.10.1983                                               ******)
+(******     06.05.1985 Hua&DC: forget("zzdyn.const")                 ******)
+(******     08.04.1986 Ley : Anpassung an 1.7.5                      ******)
+(******     02.04.1987 C.Fallis & C.Rensen  Einbettung in BOX        ******)
+(******     18.05.1988 dc: Udi Katzirs changes                       ******)
+(******                    should declare vector        eingeführt   ******)
+(******     20.05.1988 dc: already used in loop body    eingeführt   ******)
+(******                Fehlermeldung bei Ref. int index unterdrückt  ******)
+(******                weil sie wahrscheinlich selbst ein Fehler ist ******) 
+(******     21.07.1988 Christian Szymanski                           ******)
+(******                Ausbettung aus BOX                            ******)
+(******                                                              ******) 
+(******                                                              ******)
+(**************************************************************************)
+(**************************************************************************)
+
+ 
+PACKET dynamo compiler 33 DEFINES init std, dynamo, insert macro,
+                                  erase, table dump, graphic:
+ 
+(**********************  T  A  B  L  E  S  ********************************)
+ 
+LET max tab size  = 950,
+    max hash size = 300,
+    library       = ""15"TAB1"14"",
+    tab name      = ""15"TAB2"14"";
+
+BOOL VAR is draw := FALSE;
+
+TYPE TABLE  = STRUCT (ROW max tab size TEXT name, init, right part,
+                      ROW max tab size INT  type, line no, pred, mac,
+                                            index, index type,
+                      ROW max tab size BOOL in use, idef, rdef,
+                                            already used in loop body,
+                                            should declare vector, 
+                      (*18.5.88 dc: Änderung von Udi Katzir   *) 
+                      ROW max hash size INT class,
+                      INT tab size,
+                          tab beg);
+
+(* already used in loop body: is set to TRUE , if that table-element has been
+   used to generate a line within a loop  --> PROC gen loop      20.5.88 dc*)
+
+(* should declare vector : used when rows are declared and indicates if the*)
+(* length of the row is to be taken from the index of the current variable *)
+
+BOUND TABLE VAR tab;
+ 
+PROC enter (TEXT CONST name, right part, INT CONST type of equ) :
+ INT VAR tab pos;
+ INT CONST hash class := hash (name);
+ search (name, tab pos, lmp, equtype, hash class);
+ table index := tab pos;
+ enter equ.
+
+ enter equ :
+  IF not found OR subscript COR CONCR (tab).type (tabpos) = mac param
+   THEN enter name
+  ELIF type of equ = nequ
+   THEN enter nequ
+  ELIF CONCR (tab).right part (tab pos) = nt
+   THEN complete nequ
+   ELSE err (name, 1)
+  FI.
+ 
+ equtype :
+  IF subscript
+   THEN type of equ
+   ELSE nil
+  FI.
+ 
+ enter name :
+  CONCR (tab).tab size INCR 1;
+  tab size := CONCR (tab).tab size;
+  IF tab size > max tab size
+   THEN errorstop ("dynamo table overflow")
+  FI;
+  IF type of equ = nequ
+   THEN CONCR (tab).init       (tab size) := right part;
+        CONCR (tab).right part (tab size) := nt
+   ELSE CONCR (tab).init       (tab size) := nt;
+        CONCR (tab).right part (tab size) := right part
+  FI;
+  init element.
+ 
+ init element :
+  CONCR (tab).name       (tab size) := name;
+  CONCR (tab).type       (tab size) := type of equ;
+  CONCR (tab).line no    (tab size) := line no;
+  CONCR (tab).mac        (tab size) := lmp;
+  CONCR (tab).index      (tab size) := nil;
+  CONCR (tab).index type (tab size) := nil;
+  CONCR (tab).in use     (tab size) := FALSE;
+  CONCR (tab).idef       (tab size) := FALSE;
+  CONCR (tab).rdef       (tab size) := FALSE;
+  CONCR (tab).already used in loop body (tab size) := FALSE;
+  CONCR (tab).pred       (tab size) := CONCR (tab).class (hash class);
+  CONCR (tab).class    (hash class) := tab size.
+ 
+ enter nequ :
+  IF CONCR (tab).init (tab pos) <> nt
+   THEN err (name, 2)
+  FI;
+  CONCR (tab).init (tab pos) := right part.
+ 
+ complete nequ :
+  CONCR (tab).right part (tab pos) := right part;
+  CONCR (tab).type       (tab pos) := type of equ;
+  CONCR (tab).line no    (tab pos) := line no.
+END PROC enter;
+ 
+PROC test (TEXT CONST name, INT VAR tab pos, INT CONST last mp, type, 
+                                                       err no) :
+ search (name, tab pos, last mp, type);
+ IF not found
+  THEN err (err no)
+ FI
+END PROC test;
+ 
+PROC search (TEXT CONST name, INT VAR tab pos, INT CONST last mp, type) :
+ search (name, tab pos, last mp, type, hash (name)) 
+END PROC search;
+ 
+PROC search (TEXT CONST name, INT VAR tab pos,
+             INT CONST last mp, type, hash class) :
+ not found := TRUE;
+ tab pos := CONCR (tab).class (hash class);
+ WHILE tab pos <> nil CAND name not found REP
+  tab pos := CONCR (tab).pred (tab pos)
+ PER.
+ 
+ name not found :
+  not found := NOT (CONCR (tab).name (tab pos) = name 
+                    AND same macro AND type ok);
+  not found.
+ 
+ same macro :
+  CONCR (tab).mac (tab pos) = last mp.
+ 
+ type ok :
+  type = nil OR CONCR (tab).type (tab pos) = type.
+END PROC search;
+
+PROC insert macro (TEXT CONST source) :
+ dynamo (source, ""8"", FALSE);
+ kill (""8"");
+ IF errors = nil
+  THEN kill (library);
+       copy (tab name, library)
+ FI
+END PROC insert macro;
+
+PROC init std (TEXT CONST std name) :
+ lmp := nil;
+ kill (library);
+ tab := new (library);
+ FOR i FROM 1 UPTO max hash size REP
+  CONCR (tab).class (i) := nil
+ END REP;
+ CONCR (tab).tab size := nil;
+ enter std procs;
+ CONCR (tab).tab beg := tab size + 1.
+
+enter std procs :
+ FILE VAR std file := sequential file (input, std name);
+ TEXT VAR name, params;
+ WHILE NOT eof (std file) REP
+  get (std file, name);
+  test eof;
+  IF params = "()"
+   THEN params := ""
+  FI;
+  enter (name, params, std p)
+ END REP.
+
+ test eof :
+  IF name = "/*"
+   THEN LEAVE enter std procs
+   ELSE get (std file, params) 
+  FI.
+END PROC init std;
+ 
+PROC next sym :
+ next sym (scan buf, sym, type, scan position)
+END PROC next sym;
+ 
+PROC next sym (TEXT CONST buf) :
+ next sym (buf, sym, type, scan position)
+END PROC next sym;
+ 
+PROC test open bracket (TEXT CONST sym) :
+ IF sym <> "("
+  THEN err (sym, 6)
+ FI
+END PROC test open bracket;
+ 
+PROC test closing bracket (TEXT CONST sym) :
+ IF sym <> ")"
+  THEN err (sym, 58)
+ FI
+END PROC test closing bracket;
+ 
+PROC test bold (INT CONST err no) :
+ IF type <> bold
+  THEN err (err no)
+ FI
+END PROC test bold;
+ 
+PROC test equal (INT CONST err no) :
+ IF sym <> "="
+  THEN err (err no)
+ FI
+END PROC test equal;
+ 
+BOOL OP IN (TEXT CONST pattern, source) :
+ pos (source, pattern) > nil.
+END OP IN;
+ 
+PROC scan (TEXT CONST buf) :
+ scan buf := buf;
+ scan position := 1
+END PROC scan;
+ 
+PROC err (TEXT CONST a, INT CONST b) :
+ err (a, b, line no)
+END PROC err;
+ 
+PROC err (INT CONST i) :
+ err (sym, i, line no)
+END PROC err;
+ 
+PROC gen (TEXT CONST a) :
+ out buf CAT a
+END PROC gen;
+ 
+PROC gen (TEXT CONST a, b) :
+ out buf CAT a;
+ out buf CAT b
+END PROC gen;
+ 
+PROC gen (TEXT CONST a, b, c) :
+ out buf CAT a;
+ out buf CAT b;
+ out buf CAT c
+END PROC gen;
+ 
+PROC gen (TEXT CONST a, b, c, d) :
+ out buf CAT a;
+ out buf CAT b;
+ out buf CAT c;
+ out buf CAT d
+END PROC gen;
+ 
+PROC genln (TEXT CONST a, b, c) :
+ gen (a, b, c);
+ lf
+END PROC genln;
+ 
+PROC lf :
+ putline (target, outbuf);
+ outbuf := nt
+END PROC lf;
+ 
+PROC gen ln (TEXT CONST t) :
+ outbuf CAT t;
+ putline (target, outbuf);
+ outbuf := nt
+END PROC gen ln; 
+ 
+PROC erase (BOOL CONST b) :
+ erase option := b
+END PROC erase;
+ 
+PROC dynamo (TEXT CONST s) :
+ TEXT VAR target name := s + ".elan";
+ dynamo (s, target name, TRUE);
+ IF erase option
+  THEN kill (target name)
+ FI;
+ last param (s)
+END PROC dynamo;
+ 
+PROC dynamo :
+ dynamo (last param)
+END PROC dynamo;
+ 
+PROC graphic (BOOL CONST mode):
+  is draw := NOT mode
+END PROC graphic;
+
+(**********************  C  O  M  P  I  L  E  R  ************************)
+ 
+LET bold         = 1,    number       = 2,
+    delimiter    = 3,    eol          = 4,
+    aux          = 1,    rate         = 2,
+    level        = 3,    nequ         = 4,
+    mac name     = 6,    std p        = 7, 
+    sub init     = 8,    table        = 9,
+    for          = 10,   mac param    = 11,
+    const        = 12,   print        = 1,
+    plot         = 2,    global param = 1,
+    none         = 3,    max print no = 10,
+    supp         = 5,    any          = "ß";
+
+FILE VAR source, target;
+ 
+ROW max print no TEXT VAR print param;
+ 
+ROW 10 TEXT VAR plot name, id;
+ROW 10 INT  VAR scale pointer;
+ROW 10 TEXT VAR lower bound, upper bound;
+ROW 10 BOOL VAR l fixed scale, u fixed scale;
+ 
+TEXT VAR   buffer, left part, right part, outbuf, print buf,
+           headline, sym, plot buf, asterisk buffer,
+           macro name, noise buffer, constant, run buffer,
+           scan buf;
+ 
+INT  VAR   print param no, print line no, tab beg, type, line no,
+           plot line no, scale counter, plot param no,
+           last pos, lmp, index, (* lmp = Last Macro Position *)
+           index type, for index, i, tab size, expansion no,
+           table index, scan position, old tab beg;
+ 
+BOOL VAR   k, kl, is first, fixed scale, in macro,
+           in loop, not found, internal, subscript,
+           erase option := FALSE;
+ 
+TEXT CONST nt := "";
+
+INT CONST  nil := 0;
+ 
+
+(*$$$$$$$$$$ ZUSATZ C & C 20.2.87 eingefuegt : error listing $$$$$$$$$*)
+(* Diese Prozedur erzeugt einen zweigeteilten Bildschirm, wobei       *)
+(* die Datei 'procsource' (d.h. das Dynamo-Quellprogramm) in der      *)
+(* oberen Haelfte und die Fehlerdatei 'notebook' in der unteren       *)
+(* Haelfte steht.       *)
+
+PROC error listing (FILE VAR procsource) :     (* C.S. 21.07.88 *)
+ note edit (procsource);
+END PROC error listing;
+(*$$$$$$$$$$$$$$$$$$$$ ENDE ZUSATZ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*)
+
+
+PROC dynamo (TEXT CONST source name, target name, BOOL CONST pass2) :
+ init dynamo;
+ first pass;
+ IF no errors
+    THEN second pass
+    ELSE error listing(source);
+         error stop ("")                   (* C.S. 21.07.88 *)
+ (* Falls Fehler im ersten Durchlauf gefunden wurden, wird der zweite  *)
+ (* Durchlauf erst gar nicht durchgefuehrt, sondern das fehlerhafte    *)
+ (* Dynamo-Programm und die Fehlerdatei werden ausgegeben .            *)
+ FI.
+ 
+ first pass :
+  WHILE NOT eof (source) REP
+   read source line;
+   translate line
+  PER;
+  IF NOT pass2
+   THEN LEAVE dynamo
+  FI;
+  end of first pass.
+ 
+ second pass :
+  generate initializations;
+  generate equations.
+ 
+ generate initializations :
+  generate rts call;
+  generate noise card;
+  generate table part;
+  generate for variables;
+  generate variable part;
+  generate table init;
+  generate init print;
+  generate init plot;
+  generate init scale;
+  generate asterisk;
+  gen repeat.
+ 
+ generate equations :
+  generate print line;
+  generate plot line;
+  gen equations (level);
+  gen equations (aux);
+  gen equations (supp);
+  gen equations (rate);
+  gen end repeat;
+  IF no errors
+   THEN run (target name)
+   ELSE error listing(source);
+        error stop ("")                   (* C.S. 21.07.88 *)
+ (* Falls im zweiten Durchlauf Fehler gefunden wurden, wird das     *)
+ (* ELAN-Zielprogramm nicht ausgefuehrt, sondern das fehlerhafte    *)
+ (* Dynamo-Quellprogramm und die Fehlerdatei werden ausgegeben .    *)
+ FI.
+ 
+ init dynamo :
+  kill (target name);
+  init tables;
+  source          := sequential file (input,  source name);
+  target          := sequential file (output, target name);
+  print buf       := nt;
+  outbuf          := nt;
+  plot buf        := nt;
+  noise buffer    := nt;
+  asterisk buffer := nt;
+  macro name      := nt;
+  run buffer      := "zzdyn";
+  line no         := nil;
+  plot param no   := nil;
+  last pos        := nil;
+  lmp             := nil;
+  index           := nil;
+  index type      := nil;
+  expansion no    := nil;
+  in macro        := FALSE;
+  internal        := FALSE;
+  in loop         := FALSE;
+  is first        := TRUE;
+  tab beg         := CONCR (tab).tab beg;
+  old tab beg     := CONCR (tab).tab size + 1;
+  init errors.
+ 
+ init tables :
+  kill (tab name);
+  copy (library, tab name);
+  tab := old (tab name).
+ 
+ read source line :
+  line no INCR 1;
+  getline (source, buffer);
+  cout (line no);
+  scan (buffer);
+  next sym.
+ 
+ translate line :
+  TEXT VAR start := sym;
+  next sym;
+  WHILE sym = " " REP next sym PER;
+  SELECT
+   pos ("a c l n r print plot note EOL spec * x macro mend for s noise run ",
+        start + " ") OF
+   CASE 1      : enter equ (TRUE,  FALSE, aux,   9)
+   CASE 3, 31  : constant equ
+   CASE 5      : enter equ (TRUE,  FALSE, level, 11)
+   CASE 7      : enter equ (FALSE, FALSE, nequ,  56)
+   CASE 9      : enter equ (FALSE, TRUE,  rate,  12)
+   CASE 11     : print card
+   CASE 17     : plot card
+   CASE 22, 27 : (* comment; empty line *)
+   CASE 36     : gen headline
+   CASE 15     : enter equ (FALSE, FALSE, table, 13)
+   CASE 38     : continuation card
+   CASE 40     : macro card
+   CASE 46     : macro end
+   CASE 51     : for card
+   CASE 55     : enter equ (TRUE, FALSE, supp, 9)
+   CASE 57     : noise card
+   CASE 63     : run card
+   OTHERWISE   : err (start, 3)
+  END SELECT.
+ 
+ macro card :
+  IF in macro
+   THEN err (4)
+  FI;
+  in macro := TRUE;
+  get macro name;
+  get macro param list.
+ 
+ get macro name :
+  IF type = bold
+   THEN enter (sym, nt, mac name);
+        CONCR (tab).line no (tab size) := nil;
+        macro name := sym;
+        lmp := tab size
+   ELSE err (5)
+  FI.
+ 
+ get macro param list :
+  next sym;
+  test open bracket (sym);
+  next sym;
+  WHILE sym <> ")" REP
+   IF type = bold
+    THEN enter (sym, nt, mac param)
+    ELSE err (7)
+   FI;
+   next sym;
+   IF sym = ","
+    THEN next sym
+   FI
+  END REP;
+  test closing bracket (sym).
+ 
+ macro end :
+  lmp := nil;
+  in macro := FALSE.
+ 
+ constant equ :
+  REP
+   analyze constant equ;
+   enter (left part, constant, const);
+   last pos := tab size
+  UNTIL end of constants PER.
+ 
+ analyze constant equ :
+  test bold (10);
+  left part := sym;
+  next sym;
+  test equal (21);
+  get constant.
+ 
+ end of constants :
+  next sym;
+  test delimiter.
+ 
+ get constant :
+  next sym;
+   IF  NOT sym is number (constant)
+   THEN err (37)
+  FI.
+ 
+ print card :
+  IF print buf = nt
+   THEN print buf := subtext (buffer, scanposition - length (sym));
+        print line no := line no
+   ELSE print buf CAT "," + subtext (buffer, scanposition - length (sym))
+  FI;
+  last pos := print.
+ 
+ plot card :
+  IF plot buf = nt
+   THEN plot buf := subtext (buffer, scanposition - length (sym));
+        plot line no := line no;
+   ELSE plot buf CAT "/" + subtext (buffer, scanposition - length (sym))
+  FI;
+  last pos := plot.
+ 
+ gen headline :
+  asterisk buffer := "asterisk (""" + subtext (buffer, 3) + """);".
+ 
+ generate asterisk :
+  IF asterisk buffer <> nt
+   THEN genln (asterisk buffer)
+  FI.
+ 
+ continuation card :
+  skip blanks;
+  TEXT CONST tail := subtext (buffer, i);
+  SELECT last pos OF
+   CASE print : print buf CAT "," + tail
+   CASE plot  : plot buf  CAT "/" + tail
+   CASE none  : err (14)
+   OTHERWISE  : content CAT tail
+  END SELECT. 
+ 
+ content :
+  IF CONCR (tab).type (last pos) = nequ
+   THEN CONCR (tab).init (last pos)
+   ELSE CONCR (tab).right part (last pos)
+  FI.
+ 
+ skip blanks :
+  i := 1;
+  REP
+   i INCR 1
+  UNTIL (buffer SUB i) <> " " END REP.
+ 
+ for card :
+  REP
+   read for variable
+  UNTIL end of forlist END REP.
+ 
+ end of forlist :
+  IF sym = "/"
+   THEN next sym; FALSE
+   ELSE TRUE
+  FI.
+ 
+ read for variable :
+  TEXT VAR init;          (* left part  = name *)
+  test bold (15);         (* right part = obere Grenze *)
+  left part := sym;       (* init       = untere Grenze *)
+  next sym;
+  test equal (16);
+  next sym;
+  pass ranges;
+  enter (left part, right part, for);
+  CONCR (tab).init (tab size) := init.
+ 
+ pass ranges :
+  test number (init);
+  IF   sym <> ","
+  THEN err (18)
+  FI;
+  next sym;
+  test number (right part).
+ 
+ noise card :
+  IF NOT sym is number (noise buffer)
+   THEN err (66)
+  FI.
+ 
+ run card :
+  test bold (65);
+  run buffer := sym.
+ 
+ gen repeat :
+  lf;
+  genln ("WHILE time <= length REP");genln (" cout(int(time));");
+  genln (" set time (time);").
+ 
+ gen end repeat : 
+  genln ("UNTIL " + draw ad + "stop request PER;");
+  IF plot buf <> nt
+   THEN genln (draw ad + "end of program;")
+  FI;
+  genln ("END PROC target program").
+ 
+ generate rts call :
+  genln ("forget (""zzdyn.const"",quiet);");
+  genln ("run card (""", run buffer, """);");
+  genln ("run time system (PROC target program);");
+  lf;
+  genln ("PROC target program :").
+ 
+ generate noise card :
+  IF noise buffer <> nt
+   THEN genln (" initialize random (", noise buffer, ");")
+  FI.
+ 
+ generate plot line :
+  IF plot buf <> nt
+   THEN gen plots
+  FI.
+ 
+ gen plots :
+  genln (draw ad + " new plot line (time);");
+  FOR i FROM 1 UPTO plot param no REP
+   genln (draw ad + " plot (", plot name (i), ");");
+   genln ("IF " + draw ad + " stop request THEN LEAVE target program " +
+          "END IF;")
+  END REP.
+ 
+ generate print line :
+  IF print buf <> nt
+   THEN gen prints
+  FI.
+ 
+ gen prints :
+  genln (" new line (time);");
+  FOR i FROM 1 UPTO print param no REP
+   genln (" print (", printparam (i), ");")
+  END REP.
+ 
+ generate init plot :
+  INT VAR tab pos;
+  IF plot buf <> nt
+   THEN search ("pltper", tab pos, nil, const);
+        IF not found
+         THEN IF is draw THEN
+                err ("draw", 25, plot line no)
+              ELSE
+                err ("plot", 25, plot line no)
+              END IF
+         ELSE genln (draw ad + "initialize plot (""", plot buf, """);");
+(*$$$$$$$$$$$$$ ZUSATZ Februar87 C&C eingefuegt: pltper INCR 0 $$$$$$$$$*)
+              genln ("pltper INCR 0.0 ;");
+              genln (" (* um Warnung des ELAN-Compilers zu unterdruecken *)")
+(*$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDE ZUSATZ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*)
+        FI
+  FI.
+END PROC dynamo;
+ 
+PROC test number (TEXT VAR content) :
+ SELECT type OF
+  CASE bold   : content := sym
+  CASE number : content := trunc (sym)
+  OTHERWISE err (17)
+ END SELECT;
+ next sym
+END PROC test number;
+ 
+PROC enter equ (BOOL CONST x, y, INT CONST exp type, err no) :
+ get left part;
+ enter (left part, right part, exp type);
+ set index;
+ test global;
+ IF incorrect time script
+  THEN err (err no)
+ FI.
+ 
+ incorrect time script :
+  (k XOR x) OR (kl XOR y).
+ 
+ set index :
+  INT VAR last entry                  := table position;
+  last pos                            := last entry;
+  CONCR (tab).index      (last entry) := index;
+  CONCR (tab).index type (last entry) := index type.
+ 
+ table position :
+  IF exp type = nequ AND index type = nil AND NOT not found
+   THEN table index
+   ELSE tab size
+  FI.
+ 
+ test global :
+  IF in macro AND NOT internal
+   THEN search global
+  FI.
+ 
+ search global :
+  INT VAR tab pos;
+  search (left part, tab pos, lmp, mac param);
+  IF not found
+   THEN IF left part <> macro name
+         THEN err (left part, 64)
+        FI
+   ELSE CONCR (tab).index      (last entry) := tab pos;
+        CONCR (tab).index type (last entry) := -1;
+        CONCR (tab).index type (tab pos)    := global param;
+        CONCR (tab).index      (tab pos)    := last entry
+  FI.
+ 
+ get left part :
+  get name;
+  get time script;
+  get index.
+ 
+ get name :
+  internal := sym = "$";
+  IF internal
+   THEN next sym;
+        IF NOT in macro
+         THEN err (19)
+        FI
+  FI;
+  test bold (20);
+  left part := sym; next sym.
+ 
+ get time script :
+  IF sym = "."
+   THEN process time script
+   ELSE k := FALSE; kl := FALSE
+  FI;
+  subscript := sym = "(".
+ 
+ get index :
+  IF subscript
+   THEN process index
+   ELSE index := nil;
+        index type := nil
+  FI;
+  right part := subtext (buffer, scanposition);
+  test equal (21).
+ 
+ process time script :
+  next sym;
+  k := sym = "k"; kl := sym = "kl";
+  next sym.
+ 
+ process index :
+  next sym;
+  SELECT type OF
+   CASE number : index := int (sym)
+   CASE bold   : search for variable
+   OTHERWISE   : err (22)
+  END SELECT;
+  index type := type;
+  next sym;
+  test closing bracket (sym);
+  next sym.
+ 
+ search for variable :
+  test (sym, tab pos, lmp, for, 61);
+  index := tab pos.
+END PROC enter equ;
+ 
+PROC end of first pass :
+ INT VAR tab pos;
+ init time;
+ search macro calls;
+ search system constants.
+ 
+ init time :
+  search ("time", tab pos, nil, nequ);
+  IF not found
+   THEN enter ("time", "0.0", nequ)
+  FI; 
+  enter ("time", "time.j+dt", level).
+ 
+ search system constants :
+  sym := nt;
+  test ("dt", tab pos, nil, const, 35);
+  test ("length", tab pos, nil, const, 36).
+ 
+ search macro calls :
+  INT VAR old tabsize := tabsize;
+  FOR i FROM old tabbeg UPTO old tabsize REP
+   IF is normal equ
+    THEN enter global macro params
+   FI
+  END REP;
+  tab size := old tabsize.
+ 
+ is normal equ :
+  SELECT CONCR (tab).type (i) OF
+   CASE aux, rate, level, nequ, supp : TRUE
+   OTHERWISE                         : FALSE
+  END SELECT.
+ 
+ enter global macro params :
+  enter params (CONCR (tab).right part (i), FALSE);
+  enter params (CONCR (tab).init (i), TRUE).
+END PROC end of first pass;
+ 
+PROC enter params (TEXT CONST buf, BOOL CONST is init) :
+ TEXT VAR macro name;
+ IF pos (buf, "(") > nil
+  THEN read params
+ FI.
+ 
+ read params :
+  scan position := 1;
+  REP
+   next sym (buf, macro name, type, scan position);
+   IF type = bold
+    THEN next sym (buf);
+         IF sym = "("
+          THEN parameter list
+         FI
+   FI
+  UNTIL type = eol END REP.
+ 
+ parameter list :
+  INT VAR act param, tab pos;
+  search (macro name, tab pos, nil, nil);
+  IF NOT not found CAND CONCR (tab).type (tab pos) = mac name
+   THEN read param list
+  FI.
+ 
+ read param list :
+  CONCR (tab).index type (tab pos) INCR 1;
+  act param := tab pos;
+  REP
+   next sym (buf);
+   act param INCR 1;
+   IF CONCR (tab).type (act param) = mac param
+    THEN test parameter
+    ELSE err (macro name, 53)
+   FI
+  UNTIL end of parameter list END REP.
+ 
+ test parameter :
+  TEXT VAR param;
+  IF CONCR (tab).index type (act param) = global param
+   THEN get global param
+   ELSE get actual param
+  FI;
+  content CAT param + "%".
+ 
+ content :
+  IF is init
+   THEN CONCR (tab).init (act param)
+   ELSE CONCR (tab).right part (act param)
+  FI.
+ 
+ get global param :
+  INT VAR param index;
+  IF type = bold
+   THEN enter param
+  FI.
+ 
+ enter param :
+  param index := CONCR (tab).index (act param);
+  enter (sym, CONCR (tab).right part (param index),
+              CONCR (tab).type (param index));
+  CONCR (tab).init  (tab size) := CONCR (tab).init (param index);
+  CONCR (tab).index (tab size) := act param;
+  param := sym;
+  next sym (buf);
+  get time script.
+
+ get actual param :
+  INT VAR brackets := nil;
+  param := nt;
+  REP
+   param CAT sym;
+   next sym (buf);
+   get time script
+  UNTIL end of param END REP.
+ 
+ get time script :
+  IF sym = "."
+   THEN param CAT sym;
+        next sym (buf);
+        param CAT any;
+        next sym (buf)
+  FI.
+
+ end of param :
+  IF brackets = nil
+   THEN sym IN ",)"
+  ELIF sym = "("
+   THEN brackets INCR 1;
+        FALSE
+  ELIF sym = ")"
+   THEN brackets DECR 1;
+        TRUE
+   ELSE FALSE
+  FI.
+ 
+ end of parameter list :
+  SELECT pos (",)", sym) OF
+   CASE 1    : FALSE
+   CASE 2    : TRUE
+   OTHERWISE : err (50); TRUE
+  END SELECT.
+END PROC enter params;
+
+(*************************  P  A  S  S   2  ***************************)
+ 
+PROC generate init print :
+ INT VAR tab pos;
+ IF print buf <> nt
+  THEN test ("prtper", tab pos, nil, const, 24);
+       gen init
+ FI.
+ 
+ gen init :
+  print param no := nil;
+  headline := nt;
+  scan (print buf);
+  line no := print line no;
+  cout (line no);
+  REP
+   get parameter
+  UNTIL sym <> "," END REP;
+  genln ("initialize print (""", headline, """);");
+  (*$$$$$$$$$$$$$ ZUSATZ Februar87 C&C eingefuegt: prtper INCR 0 $$$$$$$$$$*)
+  genln ("prtper INCR 0.0 ;");
+  genln ("(* Um Warnung des ELAN-Compilers zu unterdruecken *)").
+  (*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ENDE ZUSATZ $$$$$$$$$$$$$$$$$$$$$$$*)
+ get parameter :
+  next sym;
+  test bold (33);
+  get print param.
+ 
+ get print param :
+  test (sym, tab pos, nil, nil, 32);
+  enter name.
+ 
+ enter name :
+  TEXT VAR act param := sym;
+  INT VAR pos := scanposition - length (sym);
+  test subscript (act param, 33);
+  print param no INCR 1;
+  print param (print param no) := act param;
+  headline CAT text (subtext (print buf, pos, scanposition - 1), 13);
+  headline CAT " ".
+END PROC generate init print;
+ 
+PROC test subscript (TEXT VAR act param, INT CONST err no) :
+ INT VAR tab pos;
+ next sym;
+ IF sym = "("
+  THEN test index
+ FI.
+ 
+ test index :
+  next sym;
+  act param CAT " SUB ";
+  act param CAT subscript;
+  next sym;
+  test closing bracket (sym);
+  next sym.
+ 
+ subscript :
+  SELECT type OF
+   CASE number : trunc (sym)
+   CASE bold   : search index
+   OTHERWISE   : err (err no); nt
+  END SELECT.
+ 
+ search index :
+  test (sym, tab pos, nil, for, 61);
+  sym.
+END PROC test subscript;
+ 
+PROC generate init scale :
+ IF plot buf <> nt
+  THEN gen plot card
+ FI.
+ 
+ gen plot card :
+  scale counter := 1;
+  plot param no := nil;
+  line no := plot line no;
+  cout (line no);
+  scan (plot buf);
+  REP
+   equal scale;
+   different scale
+  UNTIL type = eol OR sym = " " END REP;
+  generate scales.
+ 
+ equal scale :
+  fixed scale := FALSE;
+  REP
+   next sym;
+   single scale param
+  UNTIL sym <> "," END REP.
+ 
+ different scale :
+  IF sym = "/"
+   THEN scale counter INCR 1
+  ELIF type <> eol
+   THEN err (sym, 26, plot line no)
+  FI.
+ 
+ generate scales :
+  clear scales;
+  gen plot scales.
+ 
+ gen plot scales :
+  FOR i FROM 1 UPTO plot param no REPEAT
+   gen (draw ad + "plot scale (""", id (i), """, ",
+        text (scale pointer (i)));
+   gen (", ", lower scale, ", ", upper scale);
+   gen (", ", text (l fixed scale (i)), ", ", text (u fixed scale (i)));
+   genln (");")
+  END REP.
+ 
+ lower scale :
+  IF l fixed scale (i)
+   THEN lower bound (i)
+   ELSE "9.0e126"
+  FI.
+ 
+ upper scale :
+  IF u fixed scale (i)
+   THEN upper bound (i)
+   ELSE "-9.0e126"
+  FI.
+ 
+ clear scales :
+  FOR i FROM scale counter+1 UPTO plot param no REP
+   lower bound (i) := "0.0";
+   upper bound (i) := "0.0"
+  PER.
+ 
+ single scale param :
+  test bold (27);
+  enter plot param.
+ 
+ enter plot param :
+  TEXT VAR param := sym;
+  test subscript (param, 22);
+  plot param no INCR 1;
+  IF plot param no > 10
+   THEN err (64);
+        LEAVE generate init scale
+  FI;
+  plot name (plot param no) := param;
+  scalepointer (plot param no) := scalecounter;
+  set id;
+  set scale.
+ 
+ set id :
+  IF sym = "="
+   THEN next sym;
+        id (plot param no) := (sym SUB 1);
+        next sym
+   ELSE id (plot param no) := text (plot param no - 1)
+  FI.
+ 
+ set scale :
+  IF sym = "("
+   THEN get plot scale;
+        fixed scale := TRUE
+   ELIF NOT fixed scale
+    THEN l fixed scale (scale counter) := FALSE;
+         u fixed scale (scale counter) := FALSE;
+  FI.
+ 
+ get plot scale :
+  IF fixed scale
+   THEN err (28)
+  FI;
+  read scale param (lower bound, l fixed scale, 29);
+  IF sym <> ","
+   THEN err (30)
+  FI;
+  read scale param (upper bound, u fixed scale, 30);
+  test closing bracket (sym);
+  next sym.
+END PROC generate init scale;
+ 
+PROC read scale param (ROW 10 TEXT VAR bound, ROW 10 BOOL VAR fixed scale, 
+                       INT CONST err no) :
+ TEXT VAR scale;
+ INT VAR tab pos;
+ next sym;
+ IF type = bold
+  THEN test (sym, tab pos, nil, const, 61);
+       bound (scale counter) := sym;
+       fixed scale (scale counter) := TRUE
+ ELIF sym is number (scale)
+  THEN bound (scale counter) := scale;
+       fixed scale (scale counter) := TRUE
+ ELIF sym = "*"
+  THEN fixed scale (scale counter) := FALSE
+  ELSE err (err no)
+ FI;
+ next sym
+END PROC read scale param;
+ 
+BOOL PROC sym is number (TEXT VAR constant) :
+ constant := nt;
+ IF sym IN "+-"
+  THEN constant := sym; next sym
+ FI;
+ IF type = number
+  THEN constant CAT sym;
+       TRUE
+  ELSE FALSE
+ FI
+END PROC sym is number;
+ 
+PROC gen equations (INT CONST equ type) :
+ INT  VAR i;
+ gen normal equs;
+ end of init list;
+ gen index equs.
+ 
+ gen normal equs :
+  FOR i FROM tabbeg UPTO tabsize REP
+   IF is normal equ
+    THEN generate equ
+   FI
+  END REP.
+ 
+ generate equ :
+  declare variables (i, equ type, FALSE).
+ 
+ is normal equ :
+  CONCR (tab).type (i) = equ type
+  AND NOT CONCR (tab).rdef (i) AND CONCR (tab).index type (i) <= nil
+  AND NOT CONCR (tab).already used in loop body(i).
+
+ gen index equs :
+  FOR i FROM tabbeg UPTO tabsize REP
+   IF is index equ
+    THEN gen loop (i, equ type)
+   FI
+  END REP.
+ 
+ is index equ :
+  CONCR (tab).type (i) = equ type AND
+  NOT CONCR (tab).rdef (i) AND CONCR (tab).index type (i) > nil
+  AND NOT CONCR (tab).already used in loop body(i).
+
+END PROC gen equations;
+ 
+PROC gen loop (INT CONST i, equ type) :
+ for index := CONCR (tab).index (i);
+ TEXT VAR gen buf;
+ SELECT CONCR (tab).index type (i) OF
+  CASE bold   : gen for loop
+  CASE number : generate replace
+ END SELECT.
+ 
+ generate replace :
+  INT VAR k := i;
+  expression (equ type, gen buf, k);
+  gen replace (gen buf, k, text (for index)).
+ 
+ gen for loop :
+  gen (" FOR ", CONCR (tab).name (for index), " FROM ",
+                CONCR (tab).init (for index));
+  genln (" UPTO ", CONCR (tab).right part (for index), " REP");
+  in loop := TRUE;
+  IF equ type = sub init
+   THEN gen replace (equ type, i)
+   ELSE search equal indices
+  FI;
+  in loop := FALSE;
+  genln (" PER;").
+ 
+ search equal indices :
+  INT VAR j;
+  FOR j FROM i UPTO tab size REP
+   IF is same index
+    THEN gen replace (equ type, j);
+         CONCR (tab).already used in loop body(j):=TRUE
+   FI
+  END REP.
+ 
+ is same index :
+  for index                      = CONCR (tab).index (j)
+  AND CONCR (tab).index type (j) = bold
+  AND CONCR (tab).type (j)       = CONCR (tab).type (i)
+  AND NOT CONCR (tab).rdef (j)
+  AND NOT CONCR (tab).already used in loop body(j).
+
+END PROC gen loop;
+ 
+PROC gen replace (TEXT VAR gen buf, INT CONST table index) :
+ gen replace (gen buf, table index, CONCR (tab).name (for index))
+END PROC gen replace;
+ 
+PROC gen replace (TEXT VAR gen buf, INT CONST table index, TEXT CONST index):
+ gen (" replace (", CONCR (tab).name (table index), ", ", index);
+ genln (", ", gen buf, ");")
+END PROC gen replace;
+ 
+PROC gen replace (INT CONST equ type, tabpos) :
+ INT VAR no := tab pos;
+ TEXT VAR gen buf;
+ expression (equ type, gen buf, no);
+ gen replace (gen buf, no)
+END PROC gen replace;
+ 
+PROC generate for variables :
+ is first := TRUE;
+ FOR i FROM tab beg UPTO tab size REP
+  IF CONCR (tab).type (i) = for
+   THEN gen for var
+  FI
+ END REP;
+ end of init list.
+ 
+ gen for var :
+  set line no (i);
+  IF is first
+   THEN gen ("INT VAR  ");
+        is first := FALSE
+   ELSE continue init list
+  FI;
+  gen (CONCR (tab).name (i)).
+END PROC generate for variables;
+ 
+PROC generate variable part :
+ generate constants;
+ generate variables;
+ generate missed inits.
+ 
+ generate constants :
+  INT VAR i;
+  FOR i FROM tab beg UPTO tabsize REP
+   IF CONCR (tab).type (i) = const AND NOT CONCR (tab).idef (i)
+    THEN gen const
+   FI
+  END REP.
+ 
+ generate variables :
+  FOR i FROM tab beg UPTO tab size REP
+   SELECT CONCR (tab).type (i) OF
+    CASE level, aux, nequ, rate : gen normal equ
+   END SELECT
+  END REP.
+ 
+ generate missed inits :
+  FOR i FROM tab beg UPTO tab size REP
+   SELECT CONCR (tab).type (i) OF
+    CASE aux, rate : gen missed init
+   END SELECT;
+  END REP;
+  end of init list.
+ 
+ gen missed init :
+  IF sub init necessary
+   THEN declare variables (i, sub init, TRUE)
+  FI.
+ 
+ sub init necessary :
+  CONCR (tab).init (i) = nt AND
+  NOT CONCR (tab).idef (i) AND CONCR (tab).index type (i) <= nil.
+ 
+ gen normal equ :
+  IF equ not yet declared
+   THEN declare variables (i, nequ, TRUE)
+  FI.
+ 
+ equ not yet declared :
+  NOT CONCR (tab).idef (i) AND CONCR (tab).init (i) <> nt
+  AND CONCR (tab).index type (i) <= nil.
+ 
+ gen const :
+  gen linefeed;
+  gen (" ");
+  gen zz (i);
+  gen (CONCR (tab).name (i), " := ", "constant (""", CONCR (tab).name (i));
+  gen (""", ", CONCR (tab).right part (i), ")").
+END PROC generate variable part;
+ 
+PROC end of init list :
+ IF NOT is first
+  THEN is first := TRUE;
+       genln (";")
+ FI
+END PROC end of init list;
+ 
+PROC gen zz (INT CONST no) :
+ IF CONCR (tab).mac (no) > nil
+  THEN gen ("zz", CONCR(tab).name (CONCR(tab).mac (no)), text (expansion no))
+ FI
+END PROC gen zz;
+ 
+PROC declare variables (INT CONST no, equ type, BOOL CONST is init) :
+ INT VAR mac no := CONCR (tab).mac (no);
+ IF mac no > nil
+  THEN gen local equs
+  ELSE declare variable (no, equ type, is init)
+ FI.
+ 
+ gen local equs :
+  INT VAR no of expansions := CONCR (tab).indextype (mac no);
+  FOR expansion no FROM 1 UPTO no of expansions REP
+   declare variable (no, equ type, is init)
+  END REP.
+END PROC declare variables;
+ 
+PROC declare variable (INT CONST no, exp type, BOOL CONST init) :
+ TEXT VAR gen buf;
+ INT VAR i := no;
+ IF (init AND NOT CONCR (tab).idef (no)) OR
+    (NOT init AND NOT CONCR (tab).rdef (no))
+  THEN gen equ
+ FI.
+
+gen equ :
+ expression (exp type, gen buf, i);
+ IF init
+  THEN gen linefeed
+ FI;
+ gen (" ");
+ gen zz (i);
+ gen (CONCR (tab).name (i), " := ", gen buf);
+ IF NOT init
+  THEN genln (";")
+ FI
+END PROC declare variable;
+ 
+PROC gen linefeed :
+ IF is first
+  THEN is first := FALSE;
+       gen ("REAL VAR ")
+  ELSE continue init list
+ FI
+END PROC gen linefeed;
+ 
+PROC set line no (INT CONST index) :
+ line no := CONCR (tab).line no (index);
+ cout (line no)
+END PROC set line no;
+ 
+PROC continue init list :
+ genln (","); gen ("         ");
+END PROC continue init list;
+ 
+PROC gen tab var :
+ IF is first
+  THEN gen ("TAB VAR "); is first := FALSE
+  ELSE continue init list
+ FI
+END PROC gen tab var;
+ 
+PROC generate table part :
+ is first := TRUE;
+ FOR i FROM tabbeg UPTO tabsize REP
+  SELECT CONCR (tab).type (i) OF
+   CASE table :            gen tab declaration;
+                           gen tab init
+   CASE aux, rate, level : IF CONCR (tab).index type (i) = bold
+                            THEN
+                             IF CONCR(tab).type(i)=aux THEN 
+                                IF NOT CONCR(tab).should declare vector(i)
+                                   THEN  
+                                   find maximum index for current variable 
+                                 FI; 
+                                 IF CONCR(tab).should declare vector(i)
+                                   THEN  
+                                    gen row init 
+                                 FI   
+                              ELSE
+                                  gen row init
+                              FI            (*18.5.88 dc*)
+                           FI
+  END SELECT
+ END REP;
+ end of init list.
+ 
+gen tab declaration :
+ gen tab var;
+ gen (CONCR (tab).name (i), " := vector (", vec length);
+ genln (");");
+ is first := TRUE.
+ 
+gen tab init :
+ INT VAR elem no := 1;
+ scan (CONCR (tab).right part (i)); next sym;
+ set line no (i);
+ WHILE type is number REP
+  gen ("replace (", CONCR (tab).name (i), ", ", text (elem no));
+  genln (", ", constant, ");");
+  next sym;
+  elem no INCR 1
+ UNTIL end of constant list END REP.
+ 
+ type is number :
+  IF sym is number (constant)
+   THEN TRUE
+   ELSE err (40); FALSE
+  FI.
+ 
+ end of constant list :
+  test delimiter.
+ 
+ vec length :
+  INT VAR p, l := 1;
+  FOR p FROM 2 UPTO length (CONCR (tab).right part (i)) REP
+   IF (CONCR (tab).right part (i) SUB p) IN ",/"
+    THEN l INCR 1
+   FI
+  PER; text (l).
+ 
+ gen row init :
+  gen tab var;
+  gen (CONCR (tab).name (i), " := vector (", row length, ")").
+ 
+ row length :
+  set line no (i);
+  CONCR (tab).right part (CONCR (tab).index (i)).
+
+ find maximum index for current variable:
+   INT VAR maximum, place, k; 
+   TEXT VAR name::CONCR(tab).name(i); 
+   maximum:=int(CONCR(tab).right part(CONCR(tab).index(i))); 
+   place:=i; 
+   FOR k FROM tabbeg UPTO tabsize REPEAT 
+       check maximum of index and change if needed; 
+       CONCR(tab).should declare vector(k):=FALSE 
+   PER;
+   CONCR(tab).should declare vector(place):=TRUE. 
+  
+check maximum of index and change if needed: 
+   IF same variable CAND need to change 
+      THEN 
+         maximum:=int(CONCR(tab).right part(CONCR(tab).index(k))); 
+         place:=k 
+   FI. 
+
+need to change: 
+      maximum < int(CONCR(tab).right part(CONCR(tab).index(k))). 
+   
+same variable: 
+      name =CONCR(tab).name(k)  CAND CONCR(tab).index type(k) = 1. 
+   
+ 
+END PROC generate table part;
+ 
+BOOL PROC test delimiter :
+ SELECT pos ("/, EOL", sym) OF
+  CASE 1, 2 : next sym; FALSE
+  CASE 3, 4 : TRUE
+  OTHERWISE : err (62); TRUE
+ END SELECT
+END PROC test delimiter;
+ 
+PROC generate table init :
+ INT VAR i, tab pos;
+ FOR i FROM tabbeg UPTO tabsize REP
+  IF CONCR (tab).index type (i) > nil AND NOT CONCR (tab).idef (i)
+   THEN gen tab init
+  FI
+ END REP.
+ 
+ gen tab init :
+  SELECT CONCR (tab).type (i) OF
+   CASE nequ      : gen loop (i, nequ)
+   CASE aux, rate : gen missed table init
+   CASE mac name  : CONCR (tab).line no (i) := nil
+  END SELECT.
+ 
+ gen missed table init :
+  search (CONCR (tab).name (i), tab pos, nil, nequ);
+  IF not found
+   THEN gen loop (i, sub init)
+  FI.
+END PROC generate table init;
+ 
+PROC sort equ (INT CONST tab pos, equ type) :
+ IF in loop
+  THEN gen replace (equ type, tab pos)
+  ELSE declare variable (tab pos, equ type, equ type = nequ OR
+                                            equ type = sub init)
+ FI
+END PROC sort equ;
+ 
+PROC expression (INT CONST equtype, TEXT VAR gen buf, INT VAR no) :
+ TEXT VAR symbol, buf := equation;
+ INT VAR spos := 1, stype, tabpos;
+ gen buf := nt;
+ set line no (no);
+ test global equ;
+ compile equ;
+ IF CONCR (tab).mac (no) = nil
+    COR expansion no >= CONCR (tab).index type (CONCR (tab).mac (no))
+  THEN set def flag
+ FI.
+
+ test global equ :
+  IF CONCR (tab).index type (no) < nil
+   THEN replace global mac param
+  FI.
+ 
+ replace global mac param :
+  INT CONST param index := CONCR (tab).index (no);
+  search (actual parameter (CONCR (tab).rightpart (paramindex)),
+          tabpos, nil, nil);
+  no := tabpos;
+  expression (type of param, gen buf, no);
+  LEAVE expression.
+ 
+ type of param :
+  IF equ type = sub init
+   THEN CONCR (tab).type (no)
+   ELSE equ type
+  FI.
+ 
+ compile equ :
+  IF CONCR (tab).in use (no)
+   THEN err (CONCR (tab).name (no), 43)
+   ELSE pass expression
+  FI.
+ 
+ pass expression :
+  CONCR (tab).in use (no) := TRUE;
+  expression2 (equtype, no, spos, stype, genbuf, symbol, buf);
+  CONCR (tab).in use (no) := FALSE.
+ 
+ equation :
+  IF equtype = nequ
+   THEN CONCR (tab).init (no)
+   ELSE CONCR (tab).right part (no)
+  FI.
+ 
+ set def flag :
+  SELECT equtype OF
+   CASE nequ, sub init : CONCR (tab).idef (no) := TRUE
+   CASE level          : test level
+   OTHERWISE           : CONCR (tab).rdef (no) := TRUE
+  END SELECT.
+
+ test level :
+  IF CONCR (tab).init (no) = nt AND CONCR (tab).index type (no) = nil
+   THEN err (CONCR (tab).name (no), 39)
+  FI.
+END PROC expression;
+ 
+PROC expression2 (INT CONST equtype, no, INT VAR spos, stype,
+                  TEXT VAR gen buf, symbol, buf) :
+ next sym (buf, symbol, stype, spos);
+ REP
+  factor (equtype, no, spos, gen buf, buf, symbol, stype)
+ UNTIL is no operator END REP.
+ 
+ is no operator :
+  IF symbol IN "+-*/"
+   THEN gen buf CAT symbol;
+        next sym (buf, symbol, stype, spos);
+        process obelix;
+        FALSE
+   ELSE TRUE
+  FI.
+ 
+ process obelix :
+  IF symbol = "*"
+   THEN gen buf CAT symbol;
+        next sym (buf, symbol, stype, spos)
+  FI.
+END PROC expression2;
+ 
+TEXT PROC actual parameter (TEXT CONST params) :
+ INT VAR position := nil, old position;
+ FOR i FROM 1 UPTO expansion no REP
+  old position := position;
+  position := pos (params, "%", position + 1)
+ END REP;
+ subtext (params, old position + 1, position - 1).
+END PROC actual parameter;
+ 
+PROC factor (INT CONST equtype, no, INT VAR spos, TEXT VAR genbuf,
+                       buf, symbol, INT VAR stype) :
+ BOOL VAR dollar := symbol = "$";
+ INT VAR tab pos, mac num := CONCR (tab).mac (no);
+ IF dollar
+  THEN next sym (buf, symbol, stype, spos)
+ FI;
+ SELECT stype OF 
+  CASE number    : process number
+  CASE bold      : process quantity
+  CASE delimiter : process delimiter
+  OTHERWISE      : err (symbol, 44)
+ END SELECT.
+ 
+ process number :
+  gen buf CAT symbol;
+  next sym (buf, symbol, stype, spos).
+ 
+ process quantity :
+  TEXT VAR name := symbol, time script;
+  INT VAR old spos := spos;
+  next sym (buf, symbol, stype, spos);
+  IF mac num > nil
+   THEN search (name, tab pos, mac num, mac param);
+        IF not found
+         THEN search (name, tab pos, mac num, nil);
+              IF not found
+               THEN search (name, tab pos, nil, nil)
+              FI
+        FI
+   ELSE search (name, tab pos, nil, nil)
+  FI;
+  IF is global param
+   THEN search (name, tab pos, macro number of param, nil)
+  FI;
+  IF not found
+   THEN err (name, 46)
+   ELSE test type
+  FI.
+ 
+ is global param :
+  not found AND CONCR (tab).index (no) > nil
+  AND CONCR (tab).index type (no) = nil.
+ 
+ macro number of param :
+  CONCR (tab).mac (CONCR (tab).index (no)).
+ 
+ test type :
+  INT VAR nop;
+  BOOL VAR is equ := FALSE;
+  search table entry;
+  get time script;
+  type := CONCR (tab).type (tab pos);
+  SELECT type OF
+   CASE std p     : std function
+   CASE table     : (* nanu *)
+   CASE mac param : replace param
+   CASE mac name  : macro expansion
+   CASE const     : constant
+   OTHERWISE test quantity
+  END SELECT;
+  IF symbol = "("
+   THEN test index
+   ELIF is equ
+    THEN gen buf CAT name
+  FI.
+ 
+ search table entry :
+  IF CONCR (tab).index type (tab pos) > nil AND
+     CONCR (tab).type (tab pos) = n equ
+   THEN search correct table;
+        IF not found
+         THEN err (name, 46);
+              LEAVE process quantity
+        FI
+  FI.
+ 
+ search correct table :
+  not found := TRUE;
+  WHILE tab pos <> nil CAND table not found REP
+   tab pos := CONCR (tab).pred (tab pos)
+  END REP.
+ 
+ table not found :
+  not found := NOT (CONCR (tab).name (tab pos) = name
+                    AND not in macro AND type ok);
+  not found.
+ 
+ not in macro :
+  CONCR (tab).mac (tab pos) = nil.
+ 
+ type ok :
+  type := CONCR (tab).type (tab pos);
+  type = aux OR type = rate OR type = level.
+ 
+ test quantity :
+  IF CONCR (tab).mac (tab pos) > nil
+   THEN name := "zz" + CONCR (tab).name (CONCR (tab).mac (tab pos))
+                + text (expansion no) + name
+  FI;
+  is equ := TRUE;
+  SELECT equtype OF
+   CASE nequ    : initialization
+   CASE aux     : auxiliary
+   CASE level   : level equation
+   CASE sub init: substitute init
+   CASE supp    : supplementary
+   OTHERWISE    : rate equation
+  END SELECT.
+ 
+ get time script :
+  time script := nt;
+  IF symbol = "."
+   THEN next sym (buf, time script, stype, spos);
+        next sym (buf, symbol, stype, spos)
+  FI;
+  BOOL VAR is any := time script = any.
+
+ replace param :
+  buf := text (buf, old spos - 2) +
+         actual param + subtext (buf, spos - 1);
+  spos := old spos - 1;
+  next sym (buf, symbol, stype, spos);
+  factor (equtype, no, spos, genbuf, buf, symbol, stype);
+  LEAVE factor.
+ 
+ actual param :
+  TEXT VAR param := actual parameter (content);
+  IF param contains time script OR is number
+   THEN param
+   ELSE param + "." + any
+  FI.
+ 
+ param contains time script :
+  (param SUB (length (param))) = any.
+ 
+ is number :
+  pos ("0123456789", param SUB (length (param))) > 0.
+
+ content :
+  IF type = nequ AND CONCR (tab).index (no) = nil
+   THEN CONCR (tab).init (tab pos)
+   ELSE CONCR (tab).right part (tab pos)
+  FI.
+
+ test index :
+  gen buf CAT "(";
+  gen buf CAT name;
+  next sym (buf, symbol, stype, spos);
+  gen buf CAT " SUB ";
+  SELECT stype OF
+   CASE number : int index
+   CASE bold   : var index
+   OTHERWISE   : err (symbol, 48) 
+   END SELECT;
+  test offset;
+  test closing bracket (symbol);
+  gen buf CAT symbol;
+  next sym (buf, symbol, stype, spos).
+ 
+ test offset :
+  next sym (buf, symbol, stype, spos);
+  IF symbol IN "+-"
+   THEN pass offset
+  FI.
+ 
+ pass offset :
+  gen buf CAT symbol;
+  next sym (buf, symbol, stype, spos);
+  gen buf CAT trunc (symbol);
+  IF stype <> number
+   THEN err (symbol, 48) 
+  FI;
+  next sym (buf, symbol, stype, spos).
+ 
+ int index :
+(*IF CONCR (tab).index (no) <> int (symbol)
+   THEN err (symbol, 48); 
+        message("Starten Sie trotzdem das übersetzte ELAN Programm") FI;*) 
+(*20.5.88 dc: hier kommt eine falsche Fehlermeldung                     *) 
+  gen buf CAT trunc (symbol).
+  
+ var index :
+  search (symbol, tab pos, mac num, for);
+  gen buf CAT symbol;
+  IF incorrect index
+   THEN err (symbol, 48) 
+  FI.
+ 
+ incorrect index :
+  not found COR CONCR (tab).name (CONCR (tab).index (no)) <> symbol.
+  
+ std function :
+  test open bracket (symbol);
+  nop := length (CONCR (tab).right part (tab pos));
+  gen buf CAT (name + " (");
+  IF nop > nil
+   THEN pass actual params
+   ELSE next sym (buf, symbol, stype, spos);
+        test closing bracket (symbol)
+  FI;
+  next sym (buf, symbol, stype, spos);
+  IF act param <> nop
+   THEN err (symbol, 49)
+  FI.
+  
+ pass actual params :
+  INT VAR table pos := tab pos, act param := nil;
+  REP
+   act param INCR 1;
+   IF (CONCR (tab).right part (table pos) SUB act param) = "t"
+    THEN test if param is table
+    ELSE expression2 (equtype, no, spos, stype, gen buf, symbol, buf)
+   FI
+  UNTIL no more params END REP.
+ 
+ no more params :
+  gen buf CAT symbol;
+  SELECT pos (",)", symbol) OF
+   CASE 1     : FALSE
+   CASE 2     : TRUE
+   OTHERWISE  : err (symbol, 50); TRUE
+  END SELECT.
+ 
+ test if param is table :
+  next sym (buf, symbol, stype, spos);
+  IF s type = bold
+   THEN search (symbol, tab pos, mac num, nil);
+        IF not found
+         THEN err (symbol, 51)
+         ELSE gen table
+        FI
+   ELSE err (symbol, 52)
+  FI.
+ 
+ gen table :
+  IF CONCR (tab).type (tab pos) = table
+   THEN gen buf CAT symbol;
+        next sym (buf, symbol, stype, spos)
+  ELIF CONCR (tab).index type (tab pos) > nil
+   THEN factor (equtype, no, spos, genbuf, buf, symbol, stype)
+   ELSE err (symbol, 52)
+  FI.
+ 
+ macro expansion :
+  CONCR (tab).line no (tab pos) INCR 1;
+  gen buf CAT "zz";
+  gen buf CAT name;
+  gen buf CAT text (CONCR (tab).line no (tab pos));
+  gen buf CAT name;
+  get actual parameters.
+ 
+ get actual parameters :
+  TEXT VAR char;
+  test open bracket (symbol);
+  get macro parameter list;
+  next sym (buf, symbol, stype, spos).
+ 
+ get macro parameter list :
+  REP
+   get act param
+  UNTIL end of parameter list END REP.
+ 
+ end of parameter list :
+  SELECT pos (",)", char) OF
+   CASE 1    : FALSE
+   CASE 2    : TRUE
+   OTHERWISE : TRUE
+  END SELECT.
+ 
+ get act param :
+  INT VAR brackets := nil;
+  char := buf SUB spos;
+  REP
+   spos INCR 1;
+   char := buf SUB spos
+  UNTIL end of param END REP;
+  spos INCR 1.
+ 
+ end of param :
+  IF brackets = nil
+   THEN char IN ",)"
+  ELIF char = "("
+   THEN brackets INCR 1;
+        FALSE
+  ELIF char = ")"
+   THEN brackets DECR 1;
+        FALSE
+  ELSE FALSE
+ FI.
+ 
+ constant :
+  is equ := TRUE;
+  CONCR (tab).idef (tab pos) := TRUE.
+ 
+ initialization :
+  IF time script = nt OR is any
+   THEN IF NOT CONCR (tab).idef (tab pos)
+         THEN IF CONCR (tab).init (tab pos) <> nt
+               THEN sort equ (tab pos, equ type)
+              ELIF is sub init
+               THEN sort equ (tab pos, sub init)
+               ELSE err (symbol, 39)
+              FI
+        FI
+   ELSE err (time script, 56)
+  FI.
+ 
+ is sub init :
+  CONCR (tab).init (tab pos) = nt AND correct type (type).
+
+ auxiliary :
+  IF time script = aux time script OR is any
+   THEN IF NOT CONCR (tab).rdef (tab pos) AND type = aux
+         THEN sort equ (tab pos, equtype)
+        FI
+   ELSE err (time script, 57)
+  FI.
+ 
+ aux time script :
+  SELECT type OF
+   CASE aux, level :  "k"
+   CASE rate       :  "jk"
+   OTHERWISE       :  " "
+  END SELECT.
+ 
+ level equation :
+  IF time script <> level time script AND NOT is any
+   THEN err (time script, 59)
+  FI.
+ 
+ level time script :
+  SELECT type OF
+   CASE aux, level : "j"
+   CASE rate       : "jk"
+   OTHERWISE       : " "
+  END SELECT.
+ 
+ rate equation :
+  IF time script <> rate time script AND NOT is any
+   THEN err (time script, 60)
+  FI.
+ 
+ rate time script :
+  SELECT type OF
+   CASE aux, level : "k"
+   CASE rate       : "jk"
+   OTHERWISE       : " "
+  END SELECT.
+ 
+ supplementary :
+  IF time script <> supp time script AND NOT is any
+   THEN err (time script, 57)
+  FI.
+ 
+ supp time script :
+  SELECT type OF
+   CASE aux, level, supp : "k"
+   CASE rate             : "jk"
+   OTHERWISE             : " "
+  END SELECT.
+ 
+ substitute init :
+  IF NOT CONCR (tab).idef (tab pos)
+   THEN gen sub init equ
+  FI.
+ 
+ gen sub init equ :
+  IF CONCR (tab).index type (tab pos) > nil
+   THEN IF CONCR (tab).index type (no) = nil
+         THEN process index equ
+        FI
+  ELIF CONCR (tab).init (tab pos) = nt
+   THEN IF correct type (type) 
+         THEN sort equ (tab pos, equtype)
+        FI
+   ELSE sort equ (tab pos, nequ)
+  FI.
+
+ process index equ :
+  INT VAR table type := sub init;
+  IF type <> nequ
+   THEN search nequ
+  FI;
+  IF NOT CONCR (tab).idef (tab pos) AND correct type (type)
+   THEN end of init list;
+        gen loop (tab pos, table type);
+        CONCR (tab).idef (tab pos) := TRUE
+  FI.
+ 
+ search nequ :
+  search (CONCR (tab).name (tabpos), table pos, nil, nequ);
+  IF NOT (not found CAND CONCR (tab).idef (tab pos))
+   THEN type := nequ;
+        tab pos := table pos;
+        table type := type
+  FI.
+ 
+ process delimiter :
+  genbuf CAT symbol;
+  SELECT pos ("(+-", symbol) OF
+   CASE 1   : process bracket
+   CASE 2, 3: process monadic operator
+   OTHERWISE err (symbol, 44)
+  END SELECT.
+ 
+ process bracket :
+  expression2 (equtype, no, spos, stype, genbuf, symbol, buf);
+  test closing bracket (symbol);
+  gen buf CAT symbol;
+  next sym (buf, symbol, stype, spos);
+  IF symbol = "("
+   THEN gen buf CAT "*";
+        factor (equtype, no, spos, gen buf, buf, symbol, stype)
+  FI.
+ 
+ process monadic operator :
+  next sym (buf, symbol, stype, spos);
+  factor (equtype, no, spos, gen buf, buf, symbol, stype).
+END PROC factor;
+ 
+BOOL PROC correct type (INT CONST equ type) :
+ SELECT equ type OF
+  CASE aux, rate, nequ : TRUE
+  OTHERWISE            : FALSE
+ END SELECT.
+END PROC correct type; 
+
+TEXT PROC draw ad:
+  IF is draw THEN "b" ELSE "" END IF
+END PROC draw ad;
+
+(*$$$$$$$$$$$$$$$ ZUSATZ Februar 87 C&C geaendert: Ausgabe "dump" $$$$$$$$*)
+
+(* In dieser Prozedur wird eine Datei 'dump' angelegt, in der alle        *)
+(* Dynamo-Standardfunktionen, Macros und die programmspezifischen         *)
+(* Variablen und Konstanten eingetragen werden.                           *)
+
+PROC table dump :
+IF   exists ("dump")
+THEN forget("dump",quiet)
+FI;
+FILE VAR dump := sequential file(output, "dump");
+sysout("dump");
+ FOR i FROM 1 UPTO CONCR (tab).tab size REP
+  put (i);
+  put ("NAM :"); put (CONCR (tab).name (i));
+  put ("RP :"); put (CONCR (tab).right part (i));
+  put ("INI :"); put (CONCR (tab).init (i));
+  put ("IND :"); put (CONCR (tab).index (i));
+  put ("IT :"); put (CONCR (tab).index type (i));
+  put ("TYP :"); put (CONCR (tab).type (i));
+  line;
+ END REP;
+sysout("")
+END PROC table dump
+(*$$$$$$$$$$$$$$$$$$$$ ENDE ZUSATZ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*)
+END PACKET dynamo compiler 33
+
diff --git a/dynamo/dyn.abnahme b/dynamo/dyn.abnahme
new file mode 100644
index 0000000..e8c100d
--- /dev/null
+++ b/dynamo/dyn.abnahme
@@ -0,0 +1,19 @@
+NOTE 
+NOTE Ein einfaches Modell der Bevoelkerungsentwicklung
+NOTE
+L    BEVOELKERUNG.K=BEVOELKERUNG.J+DT*(GEBURTENRATE.JK-STERBERATE.JK)
+N    BEVOELKERUNG=1000
+R    GEBURTENRATE.KL=BEVOELKERUNG.K*WACHSTUMSFAKTOR
+N    GEBURTENRATE=10
+C    WACHSTUMSFAKTOR=0.01  das heisst: 1 Prozent
+R    STERBERATE.KL=BEVOELKERUNG.K*STERBEFAKTOR
+C    STERBEFAKTOR=0.001    das heisst: 1 Promille
+N    STERBERATE=10
+NOTE
+NOTE Simulationsparameter
+NOTE
+PLOT BEVOELKERUNG=B(0,2000)/GEBURTENRATE=G(0,40)/STERBERATE=S(0,6)
+C    DT=1
+C    PLTPER=1
+C    LENGTH=68
+
diff --git a/dynamo/dyn.bev b/dynamo/dyn.bev
new file mode 100644
index 0000000..5b759d3
--- /dev/null
+++ b/dynamo/dyn.bev
@@ -0,0 +1,50 @@
+NOTE     EIN BEVÖLKERUNGSMODELL DER BUNDESREPUBLIK DEUTSCHLAND
+NOTE
+NOTE     ANGABEN DER GEBURTENRATEN (GR) UND STERBEQUOTIENTEN (SQ)
+NOTE     AUS DEM STATISTISCHEN JAHRBUCH 1982
+NOTE
+FOR LJ=1,80                                                   LEBENSJAHRE
+FOR LJ2=2,80
+L   BEV.K(1)=BEV.J(1)+DT*(GB.J-A.J(1)-S.J(1))                 BABIES
+L   BEV.K(LJ2)=BEV.J(LJ2)+DT*(A.J(LJ2-1)-A.J(LJ2)-S.J(LJ2))   BEVÖLKERUNG 
+A   A.K(LJ)=(1-SQ(LJ))*BEV.K(LJ)
+A   S.K(LJ)=SQ(LJ)*BEV.K(LJ)
+A   GB.K=SCLPRD(BEV.K,15,44,GR,1)/2                  Geburten
+A   GBEV.K=SUM(BEV.K)                                Gesamtbevölkerung
+A   ZBEV.K=SUMV(BEV.K,16,59)    zahlende Bevölkerung (in Rentenversicherung)
+A   PRENT.K=SUMV(BEV.K,60,80)   potentielle Rentner
+NOTE  
+N   BEV(LJ)=IBEV(LJ)*1E3
+T   IBEV=
+X   584/585/590/609/652/728/780/843/927/980/
+X   1014/1032/1045/1049/1024/1003/986/959/929/903/
+X   884/857/850/845/841/844/854/872/854/810/
+X   756/676/722/826/829/905/1029/1062/1026/968/
+X   934/919/884/783/711/725/763/784/784/768/
+X   742/744/724/700/716/751/765/673/488/385/
+X   397/479/613/690/698/681/664/666/654/630/
+X   603/573/546/510/476/445/402/359/320/1681  
+NOTE 
+T   SQ=
+X .01965/.00123/.00082/.00082/.00082/.00055/.00055/.00055/.00055/.00055/
+X .00033/.00033/.00033/.00033/.00033/.00064/.00064/.00064/.00064/.00064/
+X .00183/.00183/.00183/.00183/.00183/.00131/.00131/.00131/.00131/.00131/
+X .00152/.00152/.00152/.00152/.00152/.00193/.00193/.00193/.00193/.00193/
+X .00302/.00302/.00302/.00302/.00302/.00497/.00497/.00497/.00497/.00497/
+X .00750/.00750/.00750/.00750/.00750/.01220/.01220/.01220/.01220/.01220/
+X .01868/.01868/.01868/.01868/.01868/.03146/.03146/.03146/.03146/.03146/
+X .05206/.05206/.05206/.05206/.05206/.08241/.08241/.08241/.08241/.175   
+NOTE   
+T   GR=
+X   .0008/.0041/.0138/.0274/.0453/.0597/.0745/.0861/.0933/.1025/
+X   .1067/.1074/.1050/.0963/.0872/.0753/.0642/.0531/.0430/.0360/
+X   .0297/.0225/.0184/.0144/.0114/.0087/.0063/.0044/.0031/.0020   
+NOTE  
+C   DT=1
+C   PLTPER=1
+C   PRTPER=1
+N   TIME=1982
+C   LENGTH=2000
+NOTE PRINT GB,A(1),S(1),BEV(1),BEV(2),GR(1),GR(15),GR(30)
+PRINT GBEV,BEV(1),BEV(40),BEV(60),BEV(63),BEV(65),ZBEV,PRENT
+
diff --git a/dynamo/dyn.cob b/dynamo/dyn.cob
new file mode 100644
index 0000000..eabb1b8
--- /dev/null
+++ b/dynamo/dyn.cob
@@ -0,0 +1,19 @@
+NOTE  COBWEB MODEL 27.11.81
+L     PREIS.K=PREIS.J+(DT)*K*(NACHFR.J-ANGEBOT.J)
+L     ANGEBOT.K=A+B*PREIS.J
+A     NACHFR.K=C-D*PREIS.K
+NOTE  B>0, D>0, K>0
+N     PREIS=0
+N     ANGEBOT=11
+C     K=1
+C     A=1.
+C     B=.9
+C     C=12.4
+C     D=1.2
+C     DT=.1
+C     LENGTH=10
+C     PRTPER=.1
+C     PLTPER=.1
+PLOT  PREIS=P/NACHFR=N(1,10)/ANGEBOT=A
+PRINT PREIS,ANGEBOT,NACHFR
+
diff --git a/dynamo/dyn.delaytest b/dynamo/dyn.delaytest
new file mode 100644
index 0000000..c475433
--- /dev/null
+++ b/dynamo/dyn.delaytest
@@ -0,0 +1,8 @@
+NOTE  GOODMAN S.248
+A     Y.K=DELAY3(X,D)
+C     D=50
+R     X.KL=TABLE(XT,TIME.K,0,125,25)
+T     XT=0/10/0/-10/0/10
+PLOT X=X,Y=Y(-10,10)
+SPEC DT=0.5,LENGTH=125,PLTPER=2
+
diff --git a/dynamo/dyn.errors b/dynamo/dyn.errors
new file mode 100644
index 0000000..64a4f27
--- /dev/null
+++ b/dynamo/dyn.errors
@@ -0,0 +1,68 @@
+gleichung doppelt definiert
+doppelte initialisierung
+falscher zeilentyp
+verschachtelte makro-definition
+makro-name erwartet
+'(' erwartet
+formaler parameter erwartet
+')' nach parameterliste erwartet
+bei auxiliaries nur subskription mit '.k' erlaubt
+bei konstanten-definition name erwartet
+bei levels nur subskription mit '.k' erlaubt
+bei rates nur subskription mit '.kl' erlaubt
+bei table-definition keine subskription erlaubt
+x - befehl hier nicht erlaubt
+bei for-definition name erwartet
+'=' nach for-variable erwartet
+bereichsangabe erwartet
+',' erwartet
+lokale gleichung nur in makro erlaubt
+bei definition name erwartet
+'=' erwartet
+index nicht korrekt
+')' nach indizierung erwartet
+prtper nicht definiert
+pltper nicht definiert
+'/' oder ',' bei plot erwartet
+name als plotparameter erwartet
+doppelte scale-angabe in einer gruppe
+erste scale-angabe erwartet
+zweite scale-angabe erwartet
+')' nach scale-angabe erwartet
+printparameter nicht definiert
+printparameter erwartet
+time darf nur initialisiert werden
+dt nicht definiert
+length nicht definiert
+bei konstanten-definition zahl erwartet
+bei initialisierung konstante erwartet
+levels muessen initialisiert werden
+konstante bei table erwartet
+'/' oder ',' erwartet
+table-definition ohne benutzung
+simultane gleichungen
+faktor erwartet
+time muss mit '.j' oder '.k' subskribiert werden
+symbol nicht definiert
+funktion nicht definiert
+unzulaessige indizierung
+falsche parameteranzahl
+falsches trennsymbol zwischen parametern
+als parameter table erwartet
+falscher parameter in tablefunktion
+zuviele aktuelle parameter
+')' nach makroaufruf fehlt
+rekursiver makroaufruf
+bei n-gleichung keine subskription erwartet
+falsche subskription in auxiliary-gleichung
+')' erwartet
+falsche subskription in level-gleichung
+falsche subskription in rate-gleichung
+for-variable nicht definiert
+konstante erwartet
+falsches real-format
+zu viele plot-parameter
+bei run-befehl dateiname erwartet
+als noise-parameter zahl erwartet 
+plot- und draw-Anweiungen dürfen im Programm nicht gemischt werden 
+
diff --git a/dynamo/dyn.forest b/dynamo/dyn.forest
new file mode 100644
index 0000000..5075925
--- /dev/null
+++ b/dynamo/dyn.forest
@@ -0,0 +1,47 @@
+NOTE                             23.04.1985 english version 22.11.1985
+note     forest management model 
+note 
+note  wood standing within the forest
+l        wood.k=wood.j+dt*(woodgrowth.jk-harvest.jk) 
+n        wood=startingwood 
+c        startingwood=15000                                     m**3
+r        woodgrowth.kl=wood.k*stocksfactor*cultivationfactor.k 
+c        stocksfactor=0.04                       growth in % of wood
+a        cultivationfactor.k=tabhl(tclfactor,clstate.k,0,1,0.1) 
+t        tclfactor=0/.1/.2/.3/.4/.5/.7/.95/1/1.05/1.2 
+r        harvest.kl=wood.k*harvestpercent.k*0.1
+a        harvestpercent.k=tabhl(tharvestpercent,ratio1.k,0.8,1.2,0.1) 
+t        tharvestpercent=0.1/0.3/0.35/0.4/0.6 
+a        ratio1.k=wood.k/maxstock 
+c        maxstock=16000 
+note 
+note  resources 
+l        resources.k=resources.j+dt*(income.jk-clexpense.jk-draw.jk)
+n        resources=startresources 
+c        startresources=100000     money units 
+r        income.kl=wood.k*harvestpercent.k*0.1*price 
+c        price=190                 money units per cubic m
+r        clexpense.kl=resources.k-constdraw 
+r        draw.kl=constdraw 
+c        constdraw=20000 
+note 
+note  cultivationstate (clstate; dimensionless ) 
+l        clstate.k=clstate.j+dt*(clbetter.jk-clworse.jk) 
+n        clstate=startclstate 
+c        startclstate=0.8
+r        clbetter.kl=clbetterfactor.k*(1-clstate.k) 
+a        clbetterfactor.k=tabhl(tclbetter,cultivationcost.k,80000,180000,100000) 
+t        tclbetter=0.0/0.1 
+a        cultivationcost.k=resources.k-constdraw 
+r        clworse.kl=clworsefactor.k*clstate.k 
+a        clworsefactor.k=tabhl(tclworse,cultivationcost.k,0,80000,80000) 
+t        tclworse=0.2/0 
+note 
+note 
+print wood,resources,clstate 
+plot wood=w/resources=r/clstate=c(0,1)
+c        dt=1 
+c        length=50 
+c        prtper=1 
+c        pltper=1
+
diff --git a/dynamo/dyn.forst7 b/dynamo/dyn.forst7
new file mode 100644
index 0000000..d767a50
--- /dev/null
+++ b/dynamo/dyn.forst7
@@ -0,0 +1,76 @@
+#papersize(20.5,61.0)# 
+#pagelength(59.0)# 
+#type("picac")# 
+NOTE     25.04.1985  14.30 
+note     forstbetriebsmodell 
+note 
+note  stehender Holzvorrat 
+l        holz.k=holz.j+dt*(zuwachs.jk-ernte.jk) 
+n        holz=startholz 
+c        startholz=15000        Angabe in Festmetern(fm)
+r        zuwachs.kl=holz.k*vorratsfaktor*pflegefaktor.k 
+c        vorratsfaktor=0.035    Zuwachs in % von holz
+a        pflegefaktor.k=tabhl(tpffaktor,pfzustand.k,0,1,0.1) 
+t        tpffaktor=.7/.7/.7/.7/.7/.8/.9/.95/1/1.05/1.2 
+r        ernte.kl=ernte1.k 
+a        ernte1.k=holz.k*ernteproz.k*ernteprozfak.k
+a        ernteproz.k=tabhl(ternproz,ratio1.k,0.5,1.2,0.1) 
+t        ternproz=0.02/0.025/0.03/0.03/0.03/0.035/0.06/0.08 
+a        ratio1.k=holz.k/maxvorrat 
+c        maxvorrat=16000 
+note 
+note  resourcen 
+l        resourcen.k=resourcen.j+dt*(einnahme.jk-eig.jk-pfausgaben.jk)
+n        resourcen=startresourcen 
+c        startresourcen=100000     Geldeinheiten 
+c        preis=190                 Geldeinheiten pro fm 
+r        einnahme.kl=ernte1.k*preis
+r        pfausgaben.kl=resourcen.k-eigenent.k
+r        eig.kl=eigenent.k
+a        anpassungsfaktor.k=tabhl(tanpass,ratio2.k,0.5,1.5,0.1) 
+t        tanpass=.5/.55/.6/.7/.9/1/1/1/1.1/1.2/1.3
+l        eigenent.k=min(eigenent.j*anpass.jk,resourcen.j)
+r        anpass.kl=anpassungsfaktor.k 
+n        eigenent=eigenentstart 
+c        eigenentstart=20000 
+note 
+note  arbeitseinheiten
+note
+l        arbeit.k=arbeit.j+dt*(pfausgaben.jk/preisae-arbeitsverbrauch.jk)
+n        arbeit=startarbeit 
+c        startarbeit=800
+c        preisae=100 ( preis pro arbeitseinheit in geldeinheiten ) 
+r        arbeitsverbrauch.kl=min(arbeit.k,notwarbeit.k)
+a        notwarbeit.k=tabhl(tnotwarb,pfzustand.k,0.0,1.0,0.1) 
+t        tnotwarb=1600/1550/1500/1450/1400/1300/1150/950/800/700/600 
+a        ratio2.k=arbeit.k/notwarbeit.k
+a        ernteprozfak.k=tabhl(ternteprozfak,ratio2.k,0.2,1.6,0.2) 
+t        ternteprozfak=.4/.5/1/2/1.05/1/.9/.7
+note 
+note  Pflegezustand (pfzustand; dimensionslose Größe) 
+l        pfzustand.k=pfzustand.j+dt*(pfverbess.jk-pfversch.jk) 
+n        pfzustand=startpfzustand 
+c        startpfzustand=0.8
+r        pfverbess.kl=smooth(pfx1.k,pfverzoeg) 
+a        pfx1.k=pfverbfaktor.k*(1-pfzustand.k)
+a        pfverbfaktor.k=tabhl(tpfverb,ratio2.k,.8,1.4,.2) 
+t        tpfverb=0/0/.1/0.2
+r        pfversch.kl=smooth(pfverschfaktor.k*pfzustand.k,pfverzoeg)
+c        pfverzoeg=2 
+a        pfverschfaktor.k=tabhl(tpfversch,ratio2.k,0,.8,.2) 
+t        tpfversch=.4/.2/.1/.05/0 
+note 
+note 
+note  print    ratio1,ratio2,eigenent,arbeit,pfzustand 
+plot     holz=h(1e4,2e4)/eigenent=e(0,2e5)/pfzustand=P(0,1)/ratio2=2(0,5)
+c        dt=1 
+c        length=50 
+note     prtper=1 
+c        pltper=1
+run  dyn.forst7
+
+
+
+
+
+
diff --git a/dynamo/dyn.gekoppeltependel b/dynamo/dyn.gekoppeltependel
new file mode 100644
index 0000000..3f2a961
--- /dev/null
+++ b/dynamo/dyn.gekoppeltependel
@@ -0,0 +1,19 @@
+NOTE gekoppelte pendel
+L    x1.k=x1.j+dt*v1.j
+L    x2.k=x2.j+dt*v2.j
+L    v1.k=v1.j+dt*(-d0/m1*x1.j-(d/m1)*(x1.j-x2.j))
+L    v2.k=v2.j+dt*(-d0/m2*x2.j-(d/m2)*(x2.j-x1.j))
+N    x1=a
+N    x2=0
+N    v1=0
+N    v2=0
+C    a=3
+C    m1=2
+C    m2=2
+C    d0=9
+C    d=2
+C    dt=0.1
+C    length=50
+C    pltper=0.3
+PLOT x1=1(-3,9)/x2=2(-9,3)
+
diff --git a/dynamo/dyn.grashasenfuchs b/dynamo/dyn.grashasenfuchs
new file mode 100644
index 0000000..046a1e1
--- /dev/null
+++ b/dynamo/dyn.grashasenfuchs
@@ -0,0 +1,42 @@
+NOTE 
+NOTE Raeuber-Beute-Beziehung nach VOLTERRA am Beispiel Fuchs-Hase
+NOTE Aenderung: mit FUTTER und CLIP-Funktion
+L    GRAS.K=CLIP(GRAS.J+DT*(WACHSR.JK-FRESSR.JK),0,GRAS.J,0)
+L    HASEN.K=CLIP(HASEN.J+DT*(HGRATE.JK-HSRATE.JK),0,HASEN.J,0)
+L    FUECHS.K=CLIP(FUECHS.J+DT*(FGRATE.JK-FSRATE.JK),0,FUECHS.J,0)
+R    WACHSR.KL=(GPROZ/100)*GRAS.K       GPROZ  Wachstumsprozente
+R    FRESSR.KL=GFRESS*HASEN.K*GRAS.K    GFRESS in: pro Hasen
+R    HGRATE.KL=HGK*HASEN.K*GRAS.K
+R    HSRATE.KL=TREFF*HASEN.K*FUECHS.K+HSTIRB*HASEN.K
+R    FGRATE.KL=FGK*HASEN.K*FUECHS.K
+R    FSRATE.KL=FSK*FUECHS.K
+NOTE 
+NOTE Gleichgewichtsbedingungen:
+NOTE HASEN=GPROZ/(100*Gfress)
+NOTE
+NOTE Hasengeburtenkoeffizient*GRAS=Trefferwahrscheinlichkeit*Fuechse
+NOTE                               +Hstirb
+NOTE Fuechsesterbekoeffizient=Fuechsegeburtenkoeffizient*Hasen
+NOTE   
+N    GRAS=IG
+N    HASEN=IH
+N    FUECHS=IF
+C    GPROZ=3       Graswachstum 3%
+C    GFRESS=3E-4  (Grasfressanteil) pro Hasen
+C    HGK=1E-3      Hasengeburtskoeff
+C    TREFF=4E-2    Trefferwahrscheinlichkeit
+C    HSTIRB=0.001  Hasensterbekoeffizient (ohne Fuechse)
+C    FGK=0.05      Fuechsegeburtenkoeffizient
+C    FSK=5         Fuechsesterbekoeffizient
+C    IG=1E+3
+C    IH=110
+C    IF=25
+NOTE
+NOTE SIMULATIONSPARAMETER
+NOTE
+C    DT=0.083
+C    PLTPER=.083     monatlich, 0.083=1/12  !
+C    LENGTH=5
+PLOT GRAS=G(995,1005)/HASEN=H(85,115)/FUECHS=F(15,35)
+
+
diff --git a/dynamo/dyn.help b/dynamo/dyn.help
new file mode 100644
index 0000000..e4f82c0
--- /dev/null
+++ b/dynamo/dyn.help
@@ -0,0 +1,24 @@
+      Im Dynamo Runtime-System stehen folgende Kommandos
+      zur Verfügung (Verlassen dieser Erklärung mit <ESC> q) :
+ 
+      run ...................... Ausführen des übersetzten Programms
+
+      c <Konstantenname>=Wert .. Änderung einer oder mehrerer Konstanten
+
+      ? ........................ Anzeige der Konstanten und ihrer Werte
+
+      quit ..................... Verlassen des Runtime-Systems
+
+      help ..................... Zeigt diese Erklärungen
+
+
+      Bei PRINT oder PLOT - Ausgaben sind folgende Kommandos möglich :
+
+      +  ....................... Nächster Bildschirm
+
+      o  ....................... (Off), keine Unterbrechung der Ausgabe
+
+      e  ....................... (End), Zurück zum Runtime-System
+
+      <ESC> .................... Abbruch der Ausgabe
+
diff --git a/dynamo/dyn.inserter b/dynamo/dyn.inserter
new file mode 100644
index 0000000..4b0b9d5
--- /dev/null
+++ b/dynamo/dyn.inserter
@@ -0,0 +1,54 @@
+put line ("DYNAMO 3.3+ wird generiert");
+line;
+WHILE noch nicht alle dateien da REPEAT          (* Christian Szymanski *)
+  hole dateien vom archiv                        (* 10.08.88            *)
+END REPEAT;
+putline ("Die Pakete werden insertiert.");
+putline ("Bitte warten !");
+checkoff;
+IF id(0) < 182
+  THEN insert ("dyn.kleiner182")
+FI ;
+insert ("dyn.tool");
+insert ("dyn.33");
+insert ("dyn.vec");
+insert ("dyn.proc");
+insert ("dyn.rts");
+insert ("dyn.plot+");
+insert ("dyn.plot"); 
+insert ("dyn.print");
+command dialogue (TRUE);
+do ("init errors (""dyn.errors"")");
+do ("init std (""dyn.std"")");
+do ("insert macro (""dyn.mac"")");
+do ("graphic (yes (""mit CGA-Grafik""))");
+putline ("dynamo-system generiert"); 
+check on.
+
+noch nicht alle dateien da:
+  THESAURUS VAR alle dateien := empty thesaurus;
+  IF id(0) < 182 THEN
+    insert (alle dateien,"dyn.kleiner182")
+  FI ;
+  insert (alle dateien, "dyn.tool");
+  insert (alle dateien, "dyn.33");
+  insert (alle dateien, "dyn.vec");
+  insert (alle dateien, "dyn.proc");
+  insert (alle dateien, "dyn.rts");
+  insert (alle dateien, "dyn.plot+");
+  insert (alle dateien, "dyn.plot");
+  insert (alle dateien, "dyn.print");
+  highest entry (alle dateien - all) > 0 .
+
+hole dateien vom archiv:
+  IF yes ("DYNAMO-Diskette eingelegt") THEN
+    archive ("dynamo");
+    fetch (ALL archive - all, archive);
+    release (archive)
+  FI.
+
+
+
+
+
+
diff --git a/dynamo/dyn.mac b/dynamo/dyn.mac
new file mode 100644
index 0000000..03a0f9f
--- /dev/null
+++ b/dynamo/dyn.mac
@@ -0,0 +1,44 @@
+macro delay1(in,del)
+a     delay1.k=$lv.k/del
+l     $lv.k=$lv.j+dt*(in.jk-delay1.j)
+n     $lv=del*in
+mend
+macro delay3(in,del)
+a     $dl.k=del/3
+l     $lv3.k=$lv3.j+dt*($rt2.jk-delay3.j)
+n     $lv3=$dl*in
+r     $rt2.kl=$lv2.k/$dl.k
+l     $lv2.k=$lv2.j+dt*($rt1.jk-$rt2.jk)
+n     $lv2=$lv3
+r     $rt1.kl=$lv1.k/$dl.k
+l     $lv1.k=$lv1.j+dt*(in.jk-$rt1.jk)
+n     $lv1=$lv3
+a     delay3.k=$lv3.k/$dl.k
+mend
+macro delay3p(in,del,ppl)
+a     delay3p.k=$lv3.k/$dl.k
+l     $lv3.k=$lv3.j+dt*($rt2.jk-delay3p.j)
+n     $lv3=$dl*in
+r     $rt2.kl=$lv2.k/$dl.k
+l     $lv2.k=$lv2.j+dt*($rt1.jk-$rt2.jk)
+n     $lv2=$lv3
+r     $rt1.kl=$lv1.k/dl.k
+l     $lv1.k=$lv1.j+dt*(in.jk-$rt1.jk)
+n     $lv1=$lv3
+a     $dl.k=del/3
+a     ppl.k=$lv3.k+$lv2.k+$lv1.k
+mend
+macro dlinf3(in,del)
+l     dlinf3.k=dlinf3.j+dt*($lv2.j-dlinf3.j)/$dl.j
+n     dlinf3=in
+l     $lv2.k=$lv2.j+dt*($lv1.j-$lv2.j)/$dl.j
+n     $lv2=in
+l     $lv1.k=$lv1.j+dt*(in.j-$lv1.j)/$dl.j
+n     $lv1=in
+a     $dl.k=del/3
+mend
+macro smooth(in,del)
+l     smooth.k=smooth.j+dt*(in.j-smooth.j)/del
+n     smooth=in
+mend
+
diff --git a/dynamo/dyn.mehreredelays b/dynamo/dyn.mehreredelays
new file mode 100644
index 0000000..6eac8fe
--- /dev/null
+++ b/dynamo/dyn.mehreredelays
@@ -0,0 +1,9 @@
+NOTE  GOODMAN S.248
+A     Y.K=DELAY3(X,D)
+A     Z.K=DELAY3(Y,D)
+C     D=50
+R     X.KL=TABLE(XT,TIME.K,0,125,25)
+T     XT=0/10/0/-10/0/10
+PLOT X=X,Y=Y,Z=Z(-10,10)
+SPEC DT=0.5,LENGTH=125,PLTPER=2
+
diff --git a/dynamo/dyn.natchez b/dynamo/dyn.natchez
new file mode 100644
index 0000000..e62c70d
--- /dev/null
+++ b/dynamo/dyn.natchez
@@ -0,0 +1,14 @@
+NOTE   Heiratsregeln der NATCHEZ Indianer 
+L   SUN.K=SWITCH(0,SUN.J,STINKARD.J)
+L   NOBLE.K=SWITCH(0,NOBLE.J+SUN.J,STINKARD.J)
+L   HONORED.K=SWITCH(0,HONORED.J+NOBLE.J,STINKARD.J)
+L   STINKARD.K=CLIP(STINKARD.J-NOBLE.J,0,STINKARD.J-NOBLE.J,0)
+N   SUN=20 
+N   NOBLE=10 
+N   HONORED=10 
+N   STINKARD=3000
+C   DT=1
+C   LENGTH=17
+C   PLTPER=1
+PLOT SUN=*,NOBLE=N,HONORED=H,STINKARD=S
+
diff --git a/dynamo/dyn.oszillator b/dynamo/dyn.oszillator
new file mode 100644
index 0000000..3f1e815
--- /dev/null
+++ b/dynamo/dyn.oszillator
@@ -0,0 +1,26 @@
+NOTE  OSZILLATOR
+L     X.K=X.J+Y.J*DT
+N     X=2
+L     Y.K=(Y.J+DT*(F/M-X.J*OMEGANULLQUADRAT.J))/(1+GAMMA.J*DT)
+N     Y=3
+C     M=5
+NOTE 
+NOTE  linearer harmonischer Oszillator mit BETA=0 und F=0
+NOTE 
+NOTE  gedaempfter           Oszillator mit BETA<>0 und F=0
+NOTE 
+NOTE  allgemeiner           Oszillator mit BETA<>0 und F=f(TIME)
+C     BETA=0.5
+A     GAMMA.K=BETA/M
+C     F=0
+C     K=1
+A     OMEGANULLQUADRAT.K=K/M
+NOTE  hier heisst eine Konstante"K". DYNAMO verwechselt das nicht mit .K !!
+C     DT=0.01
+NOTE  DT WIRD EXTRA SO KLEIN GEWAEHLT; DAMIT DIE ANNAEHERUNG GUT IST
+NOTE 
+NOTE  DAS GEHT AUF KOSTEN DER RECHENZEITEN !!!
+C     LENGTH=68 
+C     PLTPER=1
+PLOT  Y
+
diff --git a/dynamo/dyn.plot b/dynamo/dyn.plot
new file mode 100644
index 0000000..fe1228a
--- /dev/null
+++ b/dynamo/dyn.plot
@@ -0,0 +1,235 @@
+PACKET dynamo plotter           (* Änder.: C.Szymanski, 21.07.88 *)
+ DEFINES b initialize plot, b new plot line, b plot, b end of program,
+         b plot scale :
+ 
+LET maxvalue        = 200,
+    valuepagelength = 18,
+    max param numb  = 10;
+ 
+TYPE PLOTPARAM = STRUCT (TEXT name, id, 
+                         INT  scale pointer, 
+                         REAL lower bound, upper bound, 
+                         BOOL l fixed scale, u fixed scale); 
+ 
+ROW max param numb PLOTPARAM VAR plotparam;(* Enth. Plotparameter *)
+ROW maxvalue REAL VAR value;               (* Ausgabepuffer *)
+ROW max param numb ROW 5 REAL VAR scale;  (* Enth. errechnete Skalierungen *) 
+
+BOOL VAR plt;
+TEXT VAR headline;
+REAL VAR pltper, nextplot;
+INT VAR  value no, param no, plot line no,
+         plot param no, line no;
+INT CONST nil := 0;
+
+LET line1 = ".____________.____________.____________.____________.",
+    line2 = ".            .            .            .            .";
+ 
+PROC plot one page :
+ init plot routine;
+ plot values.
+ 
+ init plot routine :
+  print suppressed output;
+  plot line no := nil.
+ 
+ plot values : 
+  INT VAR act value := 1, i;
+  TEXT VAR plot buf;
+  line;
+  vdt;
+  line;
+  IF b stop request THEN LEAVE plot one page END IF;
+  sys page;
+  plot output (headline);
+  put scales;
+  WHILE act value < value no REP
+   put time;
+   gen line;
+   FOR i FROM 1 UPTO plot param no REP
+    plot single value
+   END REP;
+   plot output (plot buf + line0 + collision);
+   plot line no INCR 1;
+   act value INCR plot param no;
+   act value INCR 1
+  END REP.
+ 
+ put time :
+  plot buf := text (text (round (value (act value), 2)), 6).
+  (* Erstes Pufferelement enthaelt time *)
+ 
+ gen line :
+  TEXT VAR line0, collision := "";
+  line0 := act line.
+ 
+ act line :
+  IF (plot line no MOD 5) = nil (* Prueft, ob gestrichelte oder durch - *)
+   THEN line1                   (* gezogene Linie gedruckt wird *)
+   ELSE line2
+  FI.
+ 
+ plot single value :
+  INT VAR position := int ((x-low)*53.0/(up-low))+1; (*Interpolationsformel*)
+  position := limit;
+  IF pos ("._ ", line0 SUB position) > nil
+   THEN replace (line0, position, plotparam (i).id)
+   ELSE collision CAT plotparam (i).id
+  FI.
+ 
+ limit :
+  IF position > 53
+   THEN 53
+  ELIF position < 1
+   THEN 1
+   ELSE position
+  FI.
+ 
+ up :
+  scale (i) (5).                (* Oberer Grenzwert (der Skalierung) *)
+ 
+ low :
+  scale (i) (1).                (* Unterer Grenzwert *)
+ 
+ x :
+  value (act value + i).
+ 
+ put scales :                      (* Gibt Skalierung der Variablen aus *)
+  INT VAR j := 1, l, scalecounter;
+  WHILE j <= plot param no REP
+   plot buf := "     ";
+   FOR l FROM 1 UPTO 4 REP
+    plot buf CAT text (text (scale (j) (l)), 13)
+   END REP;
+   plot buf CAT text (scale (j) (5));
+   scalecounter := plotparam (j).scalepointer;
+   WHILE scalecounter = plotparam (j).scalepointer REP
+    plot buf CAT plotparam (j).id;
+    j INCR 1
+   UNTIL j > max param numb END REP;
+   plot output (plot buf)
+  END REP.
+END PROC plot one page;
+ 
+PROC b plot scale (TEXT CONST id, INT CONST scale pointer,
+                   REAL CONST lower bound, upper bound,
+                   BOOL CONST l fixed scale, u fixed scale) :
+                           (* Liest Skalierungen vom Zielprogramm ein *)
+ plot param no INCR 1;
+ plot param (plot param no).id := id;                      (*Variablenname *)
+ plot param (plot param no).scale pointer := scale pointer;(*Zeiger *)
+ plot param (plot param no).lower bound := lower bound;    (*Obere Grenze *)
+ plot param (plot param no).upper bound := upper bound;    (*Untere Grenze *)
+ plot param (plot param no).l fixed scale := l fixed scale;(*Fix-Skalierung*)
+ plot param (plot param no).u fixed scale := u fixed scale;
+END PROC b plot scale;
+ 
+PROC gen scales :
+ INT VAR act param, i;        (* Generiert Skalierungen fuer eine Seite *)
+ FOR act param FROM 1 UPTO plot param no REP
+  compute single scale
+ END REP.
+ 
+ compute single scale :
+  REAL VAR max := plotparam(plot param(act param).scale pointer).upper bound,
+           min := plotparam(plot param(act param).scale pointer).lower bound;
+  IF min > max THEN errorstop ("invalid scale") FI;
+  compute extreme scales;
+  FOR i FROM 1 UPTO 3 REP
+   scale (act param) (i+1) := (scale (act param) (5) - scale (act param) (1))
+                               * real (i) / 4.0 + scale (act param) (1)
+                              (* Interpolationsformel *)
+  END REP.
+ 
+ compute extreme scales :
+ (* Wenn die Skalierungen nicht gegeben sind, muessen sie berechnet werden.
+    Zur leichteren Lesbarkeit werden die Skalierungen nach oben bzw. unten
+    um jeweils eine Stelle gerundet *)
+  scale (act param) (5) := upper limit;
+  scale (act param) (1) := lower limit.
+ 
+ upper limit :
+  IF plot param (plot param (act param).scale pointer).u fixed scale
+   THEN max
+   ELSE round (floor (max) + 0.5, 0)
+  FI.
+ 
+ lower limit :
+  IF plot param (plot param (act param).scale pointer).l fixed scale
+   THEN min
+   ELSE round (floor (min) - 0.5, 0)
+  FI.
+END PROC gen scales;
+ 
+PROC b initialize plot (TEXT CONST h) :
+ headline      := h;
+ pltper        := get pltper;
+ plot line no  := value pagelength;
+ nextplot      := 0.0;
+ value no      := nil;
+ line no       := nil;
+ plot param no := nil
+END PROC b initialize plot;
+ 
+PROC b new plot line (REAL CONST time) :
+ plt := time >= nextplot;
+ IF plt                     (* Wird vom Zielprogramm aufgerufen, um *)
+  THEN add (time);          (* Zeilenvorschub durchzufuehren *)
+       line no INCR 1;
+       param no := nil
+ FI;
+ WHILE time >= nextplot REP (* Ist noetig, weil pltper ungleich dt sein *)
+  nextplot INCR pltper      (* kann *)
+ END REP
+END PROC b new plot line;
+ 
+PROC b end of program :        (* Druckt am Schluss evt. noch gepufferte *)
+ IF plot line no = value page length AND NOT stop request (* Werte aus *)
+  THEN gen scales;
+       plot one page
+ FI
+END PROC b end of program;
+ 
+PROC b plot (REAL CONST r) :
+ IF plt                       (* Wenn genuegend PLOT-Werte gepuffert *)
+  THEN get extreme value;     (* sind, wird eine neue Seite gedruckt *)
+       add (r);
+       IF param no = plot param no AND line no = value pagelength 
+        THEN gen scales;
+             plot one page;
+             value no := nil;
+             line no := nil
+       FI
+ FI.
+ 
+ get extreme value :
+  (* Sucht Maximal bzw. Minimalwert, falls keine festen Skalierungs- *)
+  (* grenzen angegeben wurden (im Quellprogramm)*)
+  param no INCR 1;
+  INT VAR act pointer := plot param (param no).scalepointer;
+  set lower bound;
+  set upper bound.
+ 
+ set lower bound :
+  IF NOT plot param (act pointer).l fixed scale AND
+     r < plot param (act pointer).lower bound
+   THEN plot param  (act pointer).lower bound := r
+  FI.
+ 
+ set upper bound :
+  IF NOT plot param (act pointer).u fixed scale AND
+     r > plot param (act pointer).upper bound
+   THEN plot param  (act pointer).upper bound := r
+  FI.
+END PROC b plot;
+ 
+PROC add (REAL CONST r) :   (* Puffert PLOT-Werte *)
+ value no INCR 1;
+ value (value no) := r
+END PROC add;
+ 
+END PACKET dynamo plotter;
+ 
+
+
+
diff --git a/dynamo/dyn.plot+ b/dynamo/dyn.plot+
new file mode 100644
index 0000000..db04dfc
--- /dev/null
+++ b/dynamo/dyn.plot+
@@ -0,0 +1,729 @@
+PACKET graphics DEFINES graphmode, 
+                        attribut, 
+                        palette, 
+                        move, 
+                        plot, 
+                        draw line, 
+                        draw linetype, 
+                        color, 
+                        draw to: 
+ 
+ 
+(* Autor: Giffeler GD *) 
+(* Datum: 31.03.1988  *) 
+(* Schönbeck SHard    *) 
+ 
+INT VAR linie :: -1, farbe :: 1, dummy; 
+ 
+ 
+PROC attribut (INT CONST nr): 
+ 
+(* 0..15 Vordergrundfarben fuer Textdarstellung    
+   0..7  Hintergrundfarben                         
+   Attribut fuer blinkende Darstellung (+128)   *) 
+ 
+  control (-3, nr, 0, dummy) 
+ 
+END PROC attribut; 
+ 
+ 
+PROC palette (INT CONST nr): 
+ 
+(* Farbauswahl fuer Grafikmodi *) 
+ 
+  control (-4, 0, nr, dummy) 
+ 
+END PROC palette; 
+ 
+ 
+PROC graphmode (INT CONST mode): 
+ 
+(*   0 -> TEXT 40*25 monochrom    
+     2 ->      80*25              
+     1 ->      40*25 farbig       
+     3 ->      80*25              
+     7 ->      80*25 Herkules     
+     4 -> GRAFIK 320*200 farbig       
+     5 ->                monochrom    
+     6 ->        640*200              
+    64 -> Olivetti 640*400 monochrom         
+    72 ->                  kleine Schrift 
+   512 -> Herkules 720*348 monochrom      *) 
+ 
+  control (-5, mode, 0, dummy) 
+ 
+END PROC graphmode; 
+ 
+ 
+PROC draw linetype (INT CONST pen, color): 
+ 
+(* Linienschraffur und Zeichenfarbe *) 
+ 
+  linie:= pen; 
+  farbe:= color; 
+  control (-8, linie, farbe, dummy) 
+ 
+END PROC draw linetype; 
+ 
+ 
+PROC draw linetype (INT CONST nr): 
+ 
+(* Ausschliessliche Aenderung der Linienschraffur *) 
+ 
+  linie:= nr; 
+  control (-8, linie, farbe, dummy) 
+ 
+END PROC draw linetype; 
+ 
+ 
+PROC color (INT CONST nr): 
+ 
+(* Ausschliessliche Aenderung der Zeichenfarbe *) 
+ 
+  farbe:= nr; 
+  control (-8, linie, farbe, dummy) 
+ 
+END PROC color; 
+ 
+ 
+PROC move (INT CONST x, y): 
+ 
+(* Bewegt Zeichencursor zu Koordinaten (0,0 = Links oben) *) 
+ 
+  control (-7, x, y, dummy) 
+ 
+END PROC move; 
+ 
+ 
+PROC move (REAL CONST x, y): 
+ 
+  control (-7, int(x+0.5), int(y+0.5), dummy) 
+ 
+END PROC move; 
+ 
+ 
+PROC draw to (INT CONST x, y): 
+ 
+(* Zeichnet Gerade von momentaner Zeichencursorposition nach x,y *) 
+ 
+  control (-6, x, y, dummy) 
+ 
+END PROC draw to; 
+ 
+ 
+PROC draw to (REAL CONST x, y): 
+ 
+  control (-6, int(x+0.5), int(y+0.5), dummy) 
+ 
+END PROC draw to; 
+ 
+ 
+PROC draw line (INT CONST x1, y1, x2, y2): 
+ 
+(* Zieht eine Linie von x1,y1 nach x2,y2 *) 
+ 
+  plot (x1, y1); 
+  draw to (x2, y2) 
+ 
+END PROC draw line; 
+ 
+ 
+PROC draw line (REAL CONST x1, y1, x2, y2): 
+ 
+  plot (x1, y1); 
+  draw to (x2, y2) 
+ 
+END PROC draw line; 
+ 
+ 
+PROC plot (INT CONST x, y): 
+ 
+(* Zeichnet einen Punkt *) 
+ 
+  control (-7, x, y, dummy); 
+  control (-6, x, y, dummy) 
+ 
+END PROC plot; 
+ 
+ 
+PROC plot (REAL CONST x, y): 
+ 
+  control (-7, int(x+0.5), int(y+0.5), dummy); 
+  control (-6, int(x+0.5), int(y+0.5), dummy) 
+ 
+END PROC plot; 
+ 
+ 
+PROC draw to (INT CONST x, y, f): 
+ 
+(* Zeichnet Gerade von momentaner Zeichencursorposition nach x,y *) 
+ 
+  color (f); 
+  control (-6, x, y, dummy) 
+ 
+END PROC draw to; 
+ 
+ 
+PROC draw to (REAL CONST x, y, INT CONST f): 
+ 
+  color (f); 
+  control (-6, int(x+0.5), int(y+0.5), dummy) 
+ 
+END PROC draw to; 
+ 
+ 
+PROC draw line (INT CONST x1, y1, x2, y2, f): 
+ 
+(* Zieht eine Linie von x1,y1 nach x2,y2 *) 
+ 
+  plot (x1, y1, f); 
+  draw to (x2, y2) 
+ 
+END PROC draw line; 
+ 
+ 
+PROC draw line (REAL CONST x1, y1, x2, y2, INT CONST f): 
+ 
+  plot (x1, y1, f); 
+  draw to (x2, y2) 
+ 
+END PROC draw line; 
+ 
+ 
+PROC plot (INT CONST x, y, f): 
+ 
+(* Zeichnet einen Punkt mit der Farbe f (0 = schwarz) *) 
+ 
+  color (f); 
+  control (-7, x, y, dummy); 
+  control (-6, x, y, dummy) 
+ 
+END PROC plot; 
+ 
+ 
+PROC plot (REAL CONST x, y, INT CONST f): 
+ 
+  color (f); 
+  control (-7, int(x+0.5), int(y+0.5), dummy); 
+  control (-6, int(x+0.5), int(y+0.5), dummy) 
+ 
+END PROC plot 
+ 
+ 
+END PACKET graphics; 
+ 
+ 
+PACKET dynamo plotter plus DEFINES configurate plot, 
+                                   initialize plot, 
+                                   new plot line, 
+                                   plot, 
+                                   end of program, 
+                                   stop request, 
+                                   plot scale: 
+ 
+(* DYNAMO Grafikausgabe           *) 
+(* Autor : Giffeler GD            *) 
+(* Datum : 29.04.1988, 03.06.1988 *) 
+(* Änder.: Christian Szymanski    *) 
+(*         21.07.88               *) 
+ 
+ 
+LET max value         = 330, 
+    value page length = 30, 
+    max param numb    = 10, 
+ 
+    PARAM = ROW value page length REAL, 
+    BIG   = ROW 300 REAL, 
+ 
+    max devices = 3, 
+    SWITCH      = STRUCT (TEXT bezeichnung, INT on, off, 
+                          zeichenbreite, zeichenhoehe, 
+                          h offset, 
+                          x, y, breite, hoehe), 
+    SIZE        = ROW max devices SWITCH; 
+ 
+ 
+TYPE PLOTPARAM = STRUCT (TEXT name, REAL lower bound, upper bound); 
+ 
+ 
+ROW max param numb PLOTPARAM VAR plotparam; 
+ROW max value REAL VAR value; 
+ 
+BOOL VAR plt, ende; 
+REAL VAR pltper, nextplot; 
+INT VAR  value no, param no, plot line no, mode nr, plot param no, line no, 
+         xp, yp; 
+ 
+SIZE CONST table :: SIZE: 
+           (SWITCH: ("CGA 640 * 200", 6, 2, 8, 8, 5, 4, 20, 615, 102), 
+            SWITCH: ("HGC 720 * 348", 512, 0, 0, 0, 0, 0, 0, 0, 0), 
+            SWITCH: ("OLI 640 * 400", 64, 2, 8, 16, 10, 4, 25, 615, 223)); 
+ 
+configurate plot; (* Erster Aufruf nach der Insertierung *) 
+ 
+ 
+PROC plot one page : 
+INT VAR loop nr, n, m; 
+PARAM VAR x, y; 
+BIG VAR xr, yr; 
+ 
+  kopfzeile ("Stuetzstellen:     ", TRUE); 
+  xp:= 1; yp:= 19; 
+  FOR loop nr FROM 1 UPTO plot param no REP 
+    werte aus value in x und y uebertragen; 
+    koordinatenkreuz (table[mode nr].x, table[mode nr].y, 
+                      table[mode nr].breite, table[mode nr].hoehe); 
+    x raster (table[mode nr].x, table[mode nr].y, 
+              table[mode nr].breite, table[mode nr].hoehe, n); 
+    zusatzinformationen ausgeben; 
+    spline (n, m, 1, x, y, xr, yr); 
+    draw picture (table[mode nr].x, table[mode nr].y, 
+                  table[mode nr].breite, table[mode nr].hoehe, 
+                  loop nr, m, 
+                  plot param[loop nr].lower bound, 
+                  plot param[loop nr].upper bound, 
+                  xr, yr); 
+    legende ausgeben 
+  PER; 
+  abbruch; 
+  graphmode(table[mode nr].off). 
+ 
+werte aus value in x und y uebertragen: 
+INT CONST erh :: plot param no + 1; 
+INT VAR z :: 1, w :: loop nr + 1; 
+ 
+  FOR n FROM 1 UPTO value no DIV erh REP 
+    x[n]:= value[z]; y[n]:= value[w]; 
+    z INCR erh; 
+    w INCR erh 
+  PER; 
+  n DECR 1; 
+  m:= n * 10. 
+ 
+zusatzinformationen ausgeben: 
+TEXT CONST xn :: text(x[n]); 
+ 
+  cursor (1, 17); put (x[1]); 
+  cursor (81 - LENGTH xn, 17); 
+  out (xn); 
+  cursor (74, 1). 
+ 
+legende ausgeben: 
+INT VAR xph, yph; 
+ 
+  cursor (xp, yp); 
+  put (plot param[loop nr].name + "="); 
+  put (plot param[loop nr].lower bound); 
+  put ("-"); 
+  put (plot param[loop nr].upper bound); 
+  get cursor (xph, yph); 
+  draw line (xph * table[mode nr].zeichenbreite -  8, 
+             yph * table[mode nr].zeichenhoehe - table[mode nr].h offset, 
+             xph * table[mode nr].zeichenbreite + 24, 
+             yph * table[mode nr].zeichenhoehe - table[mode nr].h offset); 
+  IF xp > 1 THEN line ELSE cursor (40, yph) FI; 
+  get cursor (xp, yp). 
+ 
+abbruch: 
+TEXT VAR eingabe; 
+ 
+  REP 
+    cursor (30, 1); 
+    put (39*" "+"(+, p, e)?"); 
+    inchar (eingabe); 
+    SELECT code (eingabe) OF 
+      CASE 43     : eingabe:= "" 
+      CASE 69, 101: ende:= TRUE; eingabe:= "" 
+      CASE 80, 112: phasendiagramm 
+    OTHERWISE out(""7"") 
+    END SELECT 
+  UNTIL eingabe = "" PER 
+ 
+END PROC plot one page; 
+ 
+ 
+PROC initialize plot (TEXT CONST h) : 
+INT VAR c :: 1, typ; 
+TEXT VAR sym, num; 
+ 
+  ende:= FALSE; 
+  pltper:= get pltper; 
+  plot line no:= value page length; 
+  nextplot:= 0.0; 
+  value no:= 0; 
+  line no:= 0; 
+  plot param no:= 0; 
+  kopfzeile zerlegen. 
+ 
+kopfzeile zerlegen: 
+  scan (h); 
+  REP 
+    next symbol (plot param[c].name); 
+    next symbol (sym, typ); 
+    IF sym = "(" THEN 
+      next symbol (num); 
+      next symbol (sym, typ); 
+      IF sym = ")" THEN 
+        plot param[c].name CAT ("(" + num + ")") 
+      FI 
+    FI; 
+    WHILE typ < 7 CAND NOT (sym = "(" COR sym = ",") REP 
+      next symbol (sym, typ) 
+    PER; 
+    IF typ < 7 CAND sym = "(" THEN 
+      REP next symbol (sym) 
+      UNTIL sym = "," PER; 
+      REP next symbol (sym, typ) 
+      UNTIL typ > 6 COR sym = "," COR sym = "/" PER 
+    FI; 
+    c INCR 1 
+  UNTIL typ > 6 PER 
+ 
+END PROC initialize plot; 
+ 
+ 
+PROC plot scale (TEXT CONST id, INT CONST scale pointer, 
+                 REAL CONST lower bound, upper bound, 
+                 BOOL CONST l fixed scale, u fixed scale) : 
+ 
+ plot param no INCR 1; 
+ plot param[plot param no].lower bound:= lower bound; 
+ plot param[plot param no].upper bound:= upper bound 
+ 
+END PROC plot scale; 
+ 
+ 
+PROC new plot line (REAL CONST time) : 
+ 
+  plt:= time >= nextplot; 
+  IF plt THEN 
+    add (time); 
+    line no INCR 1; 
+    param no:= 0 
+  FI; 
+  WHILE time >= nextplot REP 
+   nextplot INCR pltper 
+  PER 
+ 
+END PROC new plot line; 
+ 
+ 
+PROC plot (REAL CONST r): 
+ 
+  IF plt THEN 
+    param no INCR 1; 
+    add (r); 
+    IF NOT ende CAND param no = plot param no AND 
+                     line no = value page length THEN 
+      plot one page; 
+      value no:= 0; 
+      line no:= 0 
+    FI 
+  FI 
+ 
+END PROC plot; 
+ 
+ 
+PROC add (REAL CONST r): 
+ 
+  IF NOT ende THEN 
+    value no INCR 1; 
+    value[value no]:= r 
+  FI 
+ 
+END PROC add; 
+ 
+ 
+PROC spline (INT CONST n, m, s, PARAM CONST x, y, BIG VAR xr, yr): 
+ 
+{ Kubische Splineinterpolation 3. Grades; 2 fach Differenzierbar       } 
+{ Quelle: Rita Schmidt, Hahn-Meitner-Institut für Kernforschung Berlin } 
+{         "Spline-Prozeduren" (HMI-B 220)                              } 
+{ Umsetzung & Modifikation: Giffeler GD, 13.04.1988, 22.04.1988        } 
+ 
+{ n     = Anzahl der Stützstellen                                      } 
+{ m     = Anzahl der zu berechnenden Funktionswerte                    } 
+{ s     = Index des x-Startpunktes                                     } 
+{ x     = x-Werte der Stützstellen (linear steigend)                   } 
+{ y     = y-Werte der Stützstellen                                     } 
+{ xr    = x-Werte der Punkte, an denen die Funktion berechnet werden   } 
+{         soll                                                         } 
+{ yr    = y-Werte der Punkte, an denen die Funktion berechnet werden   } 
+{         soll                                                         } 
+ 
+ 
+INT  CONST nn :: n - 1; 
+REAL CONST steps :: (real(nn) * (x[2] - x[1])) / real(m - 1); 
+ 
+PARAM VAR q, au; 
+REAL  VAR hi, hk, hk1, dij, dim1j; 
+INT   VAR k, kk, j, m1, m2, m3; 
+ 
+  q[1]:= 0.0; 
+  yr[1]:= x[s]; 
+  FOR j FROM 2 UPTO m REP yr[j]:= yr[j - 1] + steps PER; 
+  xr:= yr; 
+  block 0; 
+  FOR k FROM 2 UPTO nn REP block 1 PER; 
+  FOR kk FROM 2 UPTO nn REP block 2 PER; 
+  FOR j FROM 1 UPTO m REP block 3 PER. 
+ 
+block 0: 
+  au[1]:= (y[3] - y[2] - y[2] + y[1]) / ((x[2] - x[1]) * (x[3] - x[2])); 
+  au[n]:= (y[n] - y[nn] - y[nn] + y[n - 2]) / 
+          ((x[n] - x[nn]) * (x[nn] - x[n - 2])). 
+ 
+block 1: 
+INT CONST km1 :: k - 1, kp1 :: k + 1; 
+ 
+  hk:= x[k] - x[km1]; 
+  hk1:= x[kp1] - x[k]; 
+  q[k]:=  - hk1 / (hk * (q[km1] + 2.0) + 2.0 * hk1); 
+  au[k]:= (hk * au[km1] - 6.0 * ((y[kp1] - y[k]) / hk1 - (y[k] - 
+          y[km1]) / hk)) * q[k] / hk1. 
+ 
+block 2: 
+  k:= nn - kk + 2; 
+  au[k]:= q[k] * au[k + 1] + au[k]. 
+ 
+block 3: 
+  zeige benutzer das du noch lebst; 
+  IF yr[j] < x[1] THEN 
+    m1:= 1; 
+    m2:= 2 
+  ELIF yr[j] > x[n] THEN 
+    m1:= n - 1; 
+    m2:= n 
+  ELSE 
+    m1:= 1; 
+    m2:= n; 
+    wiederholung 
+  FI; 
+  dij:= x[m2] - yr[j]; 
+  hi:= x[m2] - x[m1]; 
+  dim1j:= x[m1] - yr[j]; 
+  yr[j]:= 1.0 / 6.0 / hi * (au[m1] * dij ** 3 - au[m2] * dim1j ** 3 + 
+          (6.0 * y[m1] - hi ** 2 * au[m1]) * dij - (6.0 * y[m2] - hi ** 2 
+          * au[m2]) * dim1j). 
+ 
+wiederholung: 
+  REP 
+    m3:= (m2 + m1) DIV 2; 
+    IF yr[j] >= x[m3] THEN m1:= m3 ELSE m2:= m3 FI 
+  UNTIL m2 - m1 = 1 PER. 
+ 
+zeige benutzer das du noch lebst: 
+  cout (j) 
+ 
+END PROC spline; 
+ 
+ 
+PROC phasendiagramm: 
+REAL VAR l :: maxreal, u :: smallreal; 
+BIG VAR x, y; 
+INT VAR i, no1, no2; 
+ 
+  IF plot param no > 1 THEN 
+    partnerwahl; 
+    werte aus value uebertragen; 
+    kopfzeile ("Phasendiagramm", TRUE); 
+    koordinatenkreuz (table[mode nr].x, table[mode nr].y, 
+                      table[mode nr].breite, table[mode nr].hoehe+50); 
+    draw picture (table[mode nr].x, table[mode nr].y, 
+                  table[mode nr].breite, table[mode nr].hoehe+50, 
+                  1, i-1, l, u, x, y); 
+    legende 
+  FI. 
+ 
+partnerwahl: 
+  kopfzeile ("Phasendiagramm", FALSE); 
+  line (2); 
+  FOR i FROM 1 UPTO plot param no REP 
+    putline (text(i, 3) + " = " + plot param[i].name) 
+  PER; 
+  REP 
+    cursor (1, plot param no +5); 
+    put ("X-ACHSE:"); get (no1); 
+    cursor (1, plot param no +5); 
+    put ("Y-ACHSE:"); get (no2) 
+  UNTIL no1 > 0 CAND no1 <= plot param no CAND 
+        no2 > 0 CAND no2 <= plot param no CAND 
+        no1 <> no2 PER. 
+ 
+werte aus value uebertragen: 
+INT CONST erh :: plot param no + 1; 
+INT VAR n1 :: no1 + 1, n2 :: no2 + 1; 
+ 
+  FOR i FROM 1 UPTO value no DIV erh REP 
+    x[i]:= value[n1]; 
+    y[i]:= value[n2]; 
+    n1 INCR erh; 
+    n2 INCR erh 
+  PER. 
+ 
+legende: 
+  cursor (1, 23); 
+  putline ("X-Achse: " + plot param[no1].name); 
+  out     ("Y-Achse: " + plot param[no2].name) 
+ 
+END PROC phasendiagramm; 
+ 
+ 
+PROC draw picture (INT CONST x, y, xb, yb, schraffur, m, 
+                   REAL VAR lower bound, upper bound, 
+                   BIG CONST xr, yr): 
+ 
+{ Ausgabe einer Funktionskurve                                         } 
+{ Autor: Giffeler GD, 22.04.1988, 27.04.1988                           } 
+ 
+{ x           = X-Position (oben links = 0)                            } 
+{ y           = Y-Position (oben links = 0)                            } 
+{ xb          = Ausgabebreite                                          } 
+{ yb          = Ausgabehöhe                                            } 
+{ schraffur   = Linienschraffur (1 - 10)                               } 
+{ m           = Anzahl der Funktionswerte                              } 
+{ lower bound = Unterer Grenzwert (maxreal wenn Grenze beliebig)       } 
+{ upper bound = Oberer Grenzwert (smallreal wenn Grenze beliebig)      } 
+{ xr          = Durch SPLINE erzeugte X-Werte                          } 
+{ yr          = Durch SPLINE erzeugte Y-Werte                          } 
+ 
+ 
+ROW 10 INT CONST linienarten :: ROW 10 INT: (-1, -256, 3855, -240, 
+                                             21845, -1, -1, -1, -1, -1); 
+ 
+REAL VAR lbx :: maxreal, ubx :: smallreal; 
+INT VAR i; 
+ 
+  minimum und maximum fuer x und y berechnen; 
+  abmessungsparameter umwandeln; 
+  spannweite errechnen; 
+  linienschraffur bestimmen; 
+  eine funktion ausgeben. 
+ 
+minimum und maximum fuer x und y berechnen: 
+  FOR i FROM 1 UPTO m REP 
+    lower bound:= min (lower bound, yr[i]); 
+    upper bound:= max (upper bound, yr[i]); 
+    lbx:= min (lbx, xr[i]); 
+    ubx:= max (ubx, xr[i]) 
+  PER. 
+ 
+abmessungsparameter umwandeln: 
+REAL CONST xpos :: real (x), ypos :: real (y), 
+           breite :: real (xb), hoehe :: real (yb). 
+ 
+spannweite errechnen: 
+REAL CONST sy :: (upper bound - lower bound) / hoehe, 
+           sx :: (ubx - lbx) / breite. 
+ 
+linienschraffur bestimmen: 
+  draw linetype (linienarten [abs(schraffur) MOD 10]). 
+ 
+eine funktion ausgeben: 
+  move (xpos + (xr[1] - lbx) / sx, 
+        ypos + hoehe - (yr[1] - lower bound) / sy); 
+  FOR i FROM 2 UPTO m REP 
+    drawto (xpos + (xr[i] - lbx) / sx, 
+            ypos + hoehe - (yr[i] - lower bound) / sy) 
+  PER 
+ 
+END PROC draw picture; 
+ 
+ 
+PROC koordinatenkreuz (INT CONST nx, ny, breite, hoehe): 
+ 
+  anpassung; 
+  rahmen; 
+  pfeil oben; 
+  pfeil rechts. 
+ 
+anpassung: 
+INT CONST x :: nx - 1, 
+          y :: ny - 10, 
+          b :: breite + 21, 
+          h :: hoehe + 11. 
+ 
+rahmen: 
+  draw linetype (-1); 
+  draw line (x, y, x, y + h); 
+  draw to (x + b, y + h). 
+ 
+pfeil oben: 
+  draw line (x - 3, y + 4, x, y); 
+  draw to (x + 3, y + 4). 
+ 
+pfeil rechts: 
+  draw line (x + b - 5, y + h - 2, x + b, y + h); 
+  draw to (x + b - 5, y + h + 2) 
+ 
+END PROC koordinatenkreuz; 
+ 
+ 
+PROC x raster (INT CONST nx, ny, breite, hoehe, anzahl): 
+REAL CONST y :: real (ny + hoehe + 2), 
+           w :: real (breite) / real (anzahl); 
+REAL VAR s :: real (nx); 
+INT VAR i; 
+ 
+  FOR i FROM 1 UPTO anzahl REP 
+    s INCR w; 
+    plot (s, y) 
+  PER 
+ 
+END PROC x raster; 
+ 
+ 
+PROC configurate plot: 
+(*
+BOOL CONST cmd :: command dialogue; 
+INT VAR i; 
+ 
+  command dialogue (TRUE); 
+  REP 
+    bildschirmausgabe zur auswahl 
+  UNTIL (mode nr <= max devices AND mode nr > 0) CAND 
+        yes ("Eingabe richtig") PER; 
+  command dialogue (cmd). 
+ 
+bildschirmausgabe zur auswahl: 
+  page; 
+  putline ("CONFIGURATIONSTABELLE DYNAMO GRAFIK"); 
+  line (2); 
+  FOR i FROM 1 UPTO max devices REP 
+    putline (text(i)+" -- "+table[i].bezeichnung) 
+  PER; 
+  line (2); 
+  put ("Modus:"); 
+  get (mode nr) 
+ 
+*)
+mode nr := 1.     (* CGA *)
+END PROC configurate plot; 
+ 
+ 
+PROC kopfzeile (TEXT CONST message, BOOL CONST grafik): 
+ 
+  IF grafik THEN graphmode (table[mode nr].on) 
+  ELSE graphmode (table[mode nr].off) FI; 
+  out (""1"");                                     (* C.S. 21.07.88 *) 
+  out ("DYNAMO 3.3+"); 
+  cursor (79 - LENGTH message, 1); 
+  out (message) 
+ 
+END PROC kopfzeile; 
+ 
+ 
+PROC end of program : 
+ 
+  IF NOT ende CAND (value no DIV (plot param no + 1)) > 2 THEN 
+    plot one page 
+  FI 
+ 
+END PROC end of program; 
+ 
+ 
+BOOL PROC stop request: ende END PROC stop request 
+ 
+ 
+END PACKET dynamo plotter plus 
+
diff --git a/dynamo/dyn.print b/dynamo/dyn.print
new file mode 100644
index 0000000..36ea279
--- /dev/null
+++ b/dynamo/dyn.print
@@ -0,0 +1,43 @@
+PACKET dynamo printer DEFINES initialize print, new line, print :
+ 
+BOOL VAR prt;
+TEXT VAR headline;
+REAL VAR prtper, nextprint;
+ 
+PROC initialize print (TEXT CONST h) :
+ headline := h;
+ prtper := get prtper;
+ nextprint := 0.0
+END PROC initialize print;
+ 
+PROC new line (REAL CONST time) :
+ IF time >= nextprint
+  THEN do lf
+  ELSE prt := FALSE
+ FI; 
+ WHILE time >= nextprint REP
+  nextprint INCR prtper
+ PER.
+ 
+ do lf :
+  print line;
+  prt := TRUE;
+  IF pagefeed necessary OR NOT was print
+   THEN vdt;
+        sys page;
+        print headline
+  FI;
+  print (time).
+ 
+ print headline :
+  println ("TIME          " + headline).
+END PROC new line;
+ 
+PROC print (REAL CONST r) :
+ IF prt
+  THEN print output (text (text (round (r, 5)), 13))
+ FI
+END PROC print
+ 
+END PACKET dynamo printer
+
diff --git a/dynamo/dyn.proc b/dynamo/dyn.proc
new file mode 100644
index 0000000..a291a48
--- /dev/null
+++ b/dynamo/dyn.proc
@@ -0,0 +1,160 @@
+PACKET dynamo prozeduren DEFINES clip,fifge,switch,fifze,table,tabhl,
+                                 sclprd,sum,sumv,
+                                 noise,normrn,power,
+                                 pulse,step,ramp,
+                                 set time :
+(***************************************************D.Craemer 16. 2.1983 ***)
+(*    uses:
+                                 type TAB   (Tabellen), wert, laenge
+                                 abs
+                                 random
+ 
+      globale Variablen          simulationtime   wird durch das DYNAMO-
+                                                  Programm gesetzt und in
+                                                  den Funktionen, die zeit-
+                                                  lich ausgeloest werden,
+                                                  benutzt
+ 
+                                 lastpulse        Zeit des letzten Pulses
+ 
+ 
+*)
+ 
+REAL VAR simulation time,last pulse:=0.0;
+ 
+PROC set time (REAL CONST time) :
+ simulation time := time
+END PROC set time ;
+ 
+(************************ ab hier Funktionen *******************************)
+(************************ zur  Wertauswahl   *******************************)
+ 
+REAL PROC clip(REAL CONST p,q,r,s):
+     IF r>=s THEN p ELSE q FI
+     END PROC clip;
+ 
+REAL PROC fifge(REAL CONST p,q,r,s):
+    clip(p,q,r,s)
+     END PROC fifge;
+ 
+(* clip und fifge machen dasselbe, der Name fifge gibt die Funktion besser
+wieder: first if greater or equal
+        =     == =          =                                             *)
+ 
+REAL PROC switch (REAL CONST p,q,r):
+     IF r=0.0 THEN p ELSE q FI
+     END PROC switch;
+ 
+REAL PROC fifze (REAL CONST p,q,r):
+     switch(p,q,r)
+     END PROC fifze;
+ 
+(* Funktion switch oder fifze: first if zero
+                               =     == ==                              *)
+ 
+(************************ ab hier Funktionen *******************************)
+(************************ mit  Tabellen      *******************************)
+ 
+REAL PROC table (TAB CONST t, REAL CONST x, xlow, x high, xincr) :
+  IF x < x low OR x > x high
+  THEN putline("TABLE out of range: xlow="+text(xlow)+" x="+text(x)+ 
+               " xhigh="+text(xhigh)+" xincr="+text(xincr));0.0 
+  ELIF x=xhigh 
+       THEN wert(t,laenge(t))
+       ELIF x=xlow 
+            THEN wert(t,1) 
+            ELSE deliver interpolated value
+  FI.
+ 
+deliver interpolated value:
+  INT VAR index :: int((x-xlow)/xincr)+1;
+  REAL VAR m :: ((wert (t, index + 1) - wert (t, index)) / x incr),
+           b :: wert (t, index);
+ 
+  m * (x-(xlow+real(index-1)*xincr)) + b.
+END PROC table; 
+ 
+ 
+REAL PROC tabhl (TAB CONST t, REAL CONST x, xlow, x high, xincr) :
+  IF  xlow < x AND x < xhigh
+  THEN table(t,x,xlow,xhigh,xincr) 
+  ELIF x <= xlow 
+       THEN wert(t,1) 
+       ELSE wert(t,laenge(t))
+  FI 
+END PROC tabhl ;
+ 
+REAL PROC sclprd(TAB CONST tab1,REAL CONST erstes1,letztes1,TAB CONST tab2,
+                 REAL CONST erstes2):
+INT VAR i;
+REAL VAR summe:=0.0;
+FOR i FROM 0 UPTO int(letztes1-erstes1) REP
+    summe:=summe + wert(tab1,int(erstes1)+i)*wert(tab2,int(erstes2)+i)
+PER;
+summe
+END PROC sclprd;
+ 
+REAL PROC sumv(TAB CONST tab, REAL CONST erstes,letztes):
+REAL VAR summe:=0.0;
+INT VAR i;
+FOR i FROM int(erstes) UPTO int(letztes) REP
+    summe:=summe+wert(tab,i)
+PER;
+summe
+END PROC sumv;
+ 
+REAL PROC sum(TAB CONST tab):
+   sumv(tab,1.0,real(laenge(tab)))
+END PROC sum;
+ 
+(************************ ab hier Funktionen *******************************)
+(************************ mit  Zufallszahlen *******************************)
+ 
+REAL PROC noise(REAL CONST dummy):
+   random-0.5
+END PROC noise;
+ 
+REAL PROC normrn(REAL CONST mittelwert,stdvar):
+REAL VAR z:=0.0;
+INT VAR i;
+(* Methode nach NAYLOR et al.: Computer Simulation Technique, Wiley,NY 1966*)
+FOR i FROM 1 UPTO 12 REP
+   z:=z+random
+PER;
+z:=z-6.0;
+mittelwert+z*stdvar
+END PROC normrn;
+ 
+(************************ ab hier Funktionen *******************************)
+(************************ mit  Zeitausloesung ******************************)
+ 
+REAL PROC pulse(REAL CONST height,first,interval):
+IF simulationtime < first THEN lastpulse:=0.0; 0.0
+   ELIF abs(simulationtime-first) < smallreal THEN lastpulse:=simulationtime;
+                                               height
+   ELIF abs(simulationtime-(lastpulse+interval)) < smallreal THEN 
+                                               lastpulse:=simulationtime;
+                                               height
+   ELSE 0.0
+END IF
+END PROC pulse;
+ 
+REAL PROC step(REAL CONST height,steptime):
+   IF simulationtime<steptime THEN 0.0
+                              ELSE height
+   FI
+END PROC step;
+ 
+REAL PROC ramp(REAL CONST slope,start):
+   IF simulationtime<start THEN 0.0
+                           ELSE slope*(simulationtime-start)
+   FI
+END PROC ramp;
+ 
+REAL PROC power(REAL CONST basis,exponent):
+   basis**int(exponent)
+END PROC  power
+
+ 
+END PACKET dynamo prozeduren 
+
diff --git a/dynamo/dyn.quadrat b/dynamo/dyn.quadrat
new file mode 100644
index 0000000..fdd553a
--- /dev/null
+++ b/dynamo/dyn.quadrat
@@ -0,0 +1,13 @@
+NOTE  HIER BERECHNEN WIR DAS QUADRAT MITTELS ABLEITUNG !
+L     F.K=F.J+2*TIME.J*DT
+N     F=0
+C     DT=0.01
+NOTE  DT WIRD EXTRA SO KLEIN GEWAEHLT; DAMIT DIE ANNAEHERUNG GUT IST
+NOTE 
+NOTE  DAS GEHT AUF KOSTEN DER RECHENZEITEN !!!
+C     LENGTH=17 
+C     PLTPER=1
+PLOT  F
+C     PRTPER=1
+PRINT F
+
diff --git a/dynamo/dyn.rts b/dynamo/dyn.rts
new file mode 100644
index 0000000..c46684a
--- /dev/null
+++ b/dynamo/dyn.rts
@@ -0,0 +1,376 @@
+PACKET rts
+ DEFINES constant, vdt, get pltper, get prtper, was print,
+         println, print output, plot output, print line,
+         sys page, pagefeed necessary, print suppressed output, asterisk,
+         protokoll, default, set pagelength, run time system, b stop request,
+         scroll, run card :
+ (* Runtime - System *)
+ (* Autor : R. Keil                                             *)
+ (* Datum : 12.07.83     Aenderung: 19.06.84   D. Craemer       *)
+ (*                    2.Aenderung:  6.05.85   D. Craemer       *)
+ (* Änderung auf 1.8.2: Z. 288, Christian Szymanski, 10.08.88   *)
+ (* In der 2. Aenderung wurde dyn.const in zzdyn.const umbenannt*)
+ (* und alle Konstanten-Datenraeume bekommen ".const" angehaengt*)
+ (* Wird im rts das Kommando   run name  gegeben, so wird der   *)
+ (* augenblickliche Konstanten-Datenraum gerettet im Datenraum  *)
+ (* mit dem Namen:            "name.const"                      *)
+
+
+ 
+    LET esc           = ""27"",
+    max tab size  = 50,
+    bold          = 1,
+    number        = 2,
+    delimiter     = 3;
+
+TYPE CONSTANT = STRUCT (ROW max tab size TEXT name,
+                        ROW max tab size REAL value,
+                        INT tab size);
+
+BOUND CONSTANT VAR constants;
+
+FILE VAR sysout;
+TEXT VAR print buf, asterisk buffer, sym, const name,
+         const space name::"zzdyn.const";
+REAL VAR dt, length, prtper, pltper;
+INT VAR line no, page no, max pagelength, type;
+
+BOOL VAR vdt on, print, protocoll, terminal stop, is scroll,
+         is not first, run specified;
+
+ 
+default;
+ 
+PROC default :
+ protocoll      := FALSE;
+ max pagelength := 23;
+ is scroll      := TRUE;
+ run specified  := FALSE
+END PROC default;
+ 
+PROC set pagelength (INT CONST i) :
+ max pagelength := i
+END PROC set pagelength;
+ 
+PROC run card (TEXT CONST run name) :
+ IF exists (actual constants)
+  THEN constants := old (actual constants)
+  ELIF run name="zzdyn"
+  THEN constants := new (actual constants);
+       CONCR (constants).tab size := 0
+  ELSE copy (const space name, actual constants); 
+       constants := old (actual constants)
+ FI;
+ const space name := actual constants.
+
+ actual constants:
+    run name + ".const".
+
+END PROC run card;
+ 
+REAL PROC constant (TEXT CONST name, REAL CONST val) :
+ REAL VAR value;
+ INT VAR tab pos;
+ value := actual value;
+ set system consts.
+
+ actual value :
+  search constant (name, tab pos);
+  IF tab pos > 0
+   THEN CONCR (constants).value (tab pos)
+   ELSE new constant (name, val);
+        val
+  FI.
+
+ set system consts :
+  SELECT pos ("dt length prtper pltper ", name + " ") OF
+   CASE 1  : dt     := value
+   CASE 4  : length := value
+   CASE 11 : prtper := value
+   CASE 18 : pltper := value
+  END SELECT;
+  value.
+END PROC constant;
+ 
+PROC new constant (TEXT CONST name, REAL CONST val) :
+ CONCR (constants).tab size INCR 1;
+ IF CONCR (constants).tab size > max tab size
+  THEN errorstop ("ZUVIELE KONSTANTEN")
+ FI;
+ CONCR (constants).name  (CONCR (constants).tab size) := name;
+ CONCR (constants).value (CONCR (constants).tab size) := val
+END PROC new constant;
+
+PROC search constant (TEXT CONST name, INT VAR tab pos) :
+ INT VAR i;
+ FOR i FROM 1 UPTO CONCR (constants).tab size REP
+  IF name = CONCR (constants).name (i)
+   THEN tab pos := i;
+        LEAVE search constant
+  FI
+ END REP;
+ tab pos := 0
+END PROC search constant;
+
+REAL PROC get pltper :  (* Reicht 'pltper' (Plotperiode) heraus *)
+ pltper
+END PROC get pltper;
+ 
+REAL PROC get prtper :  (* Reicht 'prtper' (Printperiode) heraus *)
+ prtper 
+END PROC get prtper;
+ 
+PROC scroll (BOOL CONST b) :
+ is scroll := b
+END PROC scroll;
+ 
+PROC next sym :
+ next sym (sym, type)
+END PROC next sym;
+
+PROC rts err (TEXT CONST err mess) :
+ outline ("FEHLER BEI >>>" + sym + "<<< : " + err mess)
+END PROC rts err;
+
+PROC run time system (PROC target program) :
+ IF protocoll
+  THEN kill ("dyn.out");
+       sysout := sequential file (output, "dyn.out")
+ FI;
+ init rts;
+ REP
+  get command;
+  execute command
+ END REP.
+ 
+ get command :
+  TEXT VAR command;
+  print suppressed output;
+  line;
+  putline ("      dynamo runtime system :");
+  shift;
+  getline (command);
+  printline (command).
+
+ execute command :
+  scanner (command);
+  next sym;
+  TEXT VAR start := sym;
+  skip blanks;
+  SELECT pos ("run rerun quit help c ? EOL ", start + " ") OF
+   CASE 1, 5 : run
+   CASE 11   : quit
+   CASE 16   : show ("dyn.help")
+   CASE 21   : const equ
+   CASE 23   : dump consts
+   CASE 25   :
+   OTHERWISE : rts err ("KOMMANDO UNBEKANNT")
+  END SELECT.
+
+ run :
+  init rts;
+  IF type = bold OR type = delimiter
+   THEN run card (sym)
+  FI;
+  target program.
+
+ quit :
+  IF const space name = "zzdyn.const"
+   THEN kill (const space name)
+  FI;
+  LEAVE runtime system.
+
+ skip blanks :
+  REP
+   next sym
+  UNTIL sym <> " " END REP.
+
+ const equ :
+  REAL VAR value, dummy;
+  INT VAR tab pos;
+  REP
+   analyze constant equ;
+   search constant (const name, tab pos);
+   IF tab pos = 0
+    THEN sym := const name;
+         rts err ("KONSTANTE NICHT DEFINIERT")
+    ELSE CONCR (constants).value (tab pos) := value
+   FI
+  UNTIL end of constants END REP.
+
+ analyze constant equ :
+  IF type <> bold
+   THEN rts err ("NAME ERWARTET")
+  FI;
+  const name := sym;
+  next sym;
+  IF sym <> "="
+   THEN rts err ("^=^ ERWARTET")
+  FI;
+  get constant.
+
+ end of constants :
+  next sym;
+  IF sym = "/" OR sym = ","
+   THEN next sym; FALSE
+   ELSE TRUE
+  FI.
+
+ get constant :
+  next sym;
+  value := 1.0;
+  IF sym = "-" 
+   THEN value := -1.0; next sym
+  ELIF sym = "+"
+   THEN next sym
+  FI;
+  IF type = number
+   THEN value := value * real (sym)
+   ELSE rts err ("ZAHL ERWARTET")
+  FI.
+
+ dump consts :
+  INT VAR i;
+  FOR i FROM 1 UPTO CONCR (constants).tab size REP
+   IF (i MOD 2) = 1
+    THEN line; shift
+   FI;
+   out (text (CONCR (constants).name (i), 14),  " = ",
+        text (text (CONCR (constants).value (i)), 13))
+  END REP;
+  line.
+END PROC run time system;
+ 
+PROC shift :
+ out ("      ")
+END PROC shift;
+
+PROC init rts :
+ line no         := 0;
+ page no         := 0;
+ asterisk buffer := "";
+ print buf       := "";
+ print           := FALSE;
+ terminal stop   := FALSE;
+ is not first    := FALSE;
+ vdt on          := TRUE
+END PROC init rts;
+
+PROC protokoll (BOOL CONST b) :
+ protocoll := b
+END PROC protokoll;
+ 
+PROC print line :
+ BOOL VAR b := print;         (* Druckt Ausgabe - Puffer und *)
+ println (print buf);         (* loescht anschliessend den Inhalt *)
+ print buf := "";
+ print := b
+END PROC print line;
+ 
+PROC print suppressed output :
+ IF print buf <> ""           (* Druckt Ausgabe - Puffer, *)
+  THEN println (print buf);   (* falls gefuellt *)
+       print buf := ""
+ FI
+END PROC print suppressed output;
+ 
+PROC print output (TEXT CONST t) :
+ print buf CAT t;             (* Fuellt Ausgabe - Puffer *)
+ print buf CAT " "
+END PROC print output;
+ 
+PROC println (TEXT CONST t) :
+ print := TRUE;               (* Verteilt Ausgabe auf Bildschirm *)
+ line no INCR 1;              (* und Datei *)
+ outline (t);
+ IF line no = max page length
+  THEN line no := 0
+ FI;
+ IF is getcharety (esc)          (* bis einschl. 1.8.1: 'is incharety' *)
+  THEN terminal stop := TRUE 
+ FI.
+END PROC println;
+
+PROC outline (TEXT CONST t) :
+ printline (t);
+ putline (actual line).
+
+ actual line :
+  IF LENGTH (t) > 78
+   THEN text (t, 78)
+   ELSE t
+  FI.
+END PROC outline;
+
+PROC printline (TEXT CONST t) :
+ IF protocoll
+  THEN putline (sysout, t)
+ FI
+END PROC print line;
+
+PROC sys page :               (* Seitenvorschub auf Bildschirm und Datei *)
+ IF vdt on AND NOT is scroll AND is not first
+  THEN page
+  ELSE is not first := TRUE
+ FI;
+ IF protocoll
+  THEN putline (sysout, "#page#")
+ FI;
+ IF asterisk buffer <> ""
+  THEN page no INCR 1;
+       println ("PAGE " + text (page no, 3) + "  : " + asterisk buffer);
+ FI;
+ line no := 0
+END PROC sys page;
+ 
+BOOL PROC pagefeed necessary :
+ line no = 0                  (* Liefert TRUE, wenn Seitenende erreicht *)
+END PROC pagefeed necessary;  (* ist *)
+ 
+PROC plot output (TEXT CONST t) :
+ println (t);                 (* Ausgabeprozedur fuer das Plot - Programm *)
+ print := FALSE
+END PROC plot output;
+ 
+BOOL PROC b stop request :      (* Liefert TRUE, wenn 'End'-Kommando im VDT *)
+ terminal stop                  (* - Modus gegeben wird *)
+END PROC b stop request;
+ 
+BOOL PROC was print :         (* Liefert TRUE, falls Druckerprogramm *)
+ print.                       (* vorher eine Zeile gedruckt hat *)
+END PROC was print;
+ 
+PROC vdt :
+ IF vdt on AND is not first   (* VDT = Video Data Termination *)
+  THEN do vdt                 (* Verhindert Scrolling des Bildschirms *)
+ FI.
+ 
+ do vdt :
+  TEXT VAR t;
+  out ("TIPPEN SIE : '+'; 'o'; 'e' : ");
+  inchar (t);
+  out (t);
+  IF t = "+"                  (* '+' = Seitenvorschub *)
+   THEN
+   ELIF t = "o"               (* 'o' = Off; VDT wird abgeschaltet *)
+    THEN vdt on := FALSE
+   ELIF t = "e"               (* 'e' = End; Programm wird abgebrochen *)
+    THEN terminal stop := TRUE
+   ELSE out (""13""); vdt
+  FI;
+  line.
+END PROC vdt;
+ 
+PROC asterisk (TEXT CONST t) :
+ asterisk buffer := t
+END PROC asterisk;
+
+PROC out(TEXT CONST a,b,c) :
+ out(a);
+ out(b);
+ out(c)
+END PROC out;
+
+
+END PACKET rts;
+
diff --git a/dynamo/dyn.ruestungswettlauf b/dynamo/dyn.ruestungswettlauf
new file mode 100644
index 0000000..7b7c6b1
--- /dev/null
+++ b/dynamo/dyn.ruestungswettlauf
@@ -0,0 +1,32 @@
+note  ruestungswettlauf nach richardson 
+note 
+note  literatur: thiel "quantitaet oder begriff" S. 436 ff 
+note 
+l    eigenkriegspot.k=eigenkriegspot.j+dt*
+x    (k*gegenkriegspot.j-a*eigenkriegspot.j+g) 
+l    gegenkriegspot.k=gegenkriegspot.j+dt*
+x    (l*eigenkriegspot.j-b*gegenkriegspot.j+h) 
+note 
+note anfangswerte fuer eigenkriegspotential und gegenkriegspotential 
+note werden am gleichgewichtspunkt plus etwas mehrpot gegeben 
+note 
+n    eigenkriegspot=(k*h+b*g)/(a*b-k*l)+mehrpot 
+n    gegenkriegspot=(l*g+a*h)/(a*b-k*l) 
+note 
+note konstanten 
+note 
+c    k=2       verteidigungskoeffizient 
+c    l=1               "                des gegners 
+c    a=2       koeffizient fuer aufwand zur kriegsvorbereitung 
+c    b=3               " 
+c    g=7       koeffizient fuer aggressive absichten 
+c    h=9               " 
+c    mehrpot=3        stoerung des gleichgewichts durch mehr potential 
+plot eigenkriegspot=e,gegenkriegspot=g(unten,oben)
+c    dt=0.5 
+c    length=2050 
+n    time=1985 
+c    pltper=1
+c    unten=-11 
+c    oben=250
+
diff --git a/dynamo/dyn.simon b/dynamo/dyn.simon
new file mode 100644
index 0000000..b911159
--- /dev/null
+++ b/dynamo/dyn.simon
@@ -0,0 +1,28 @@
+NOTE Simons MODELL der sozialen Gruppe     Stand: 08.03.1983
+NOTE
+A   INTERAKT.K=A1*FREUNDLICH.K+A2*AKTIV.K
+L   FREUNDLICH.K=FREUNDLICH.J+DT*(B1*(INTERAKT.J-beta*FREUNDLICH.J))
+L   AKTIV.K=AKTIV.J+DT*(C1*(FREUNDLICH.J-gamma*AKTIV.J)+C2*(EINF-AKTIV.J))
+N   INTERAKT=beta*A2*C2*EINF/NENNER
+N   AKTIV=C2*(beta-A1)*EINF/NENNER
+N   FREUNDLICH=A2*C2*EINF/NENNER+STOERTERM
+N   NENNER=-C1*A2+(beta-A1)*(C2+C1*gamma)
+C   STOERTERM=0.4
+C   EINF=2
+NOTE 
+NOTE   Konstanten sind alle positiv vorausgesetzt
+NOTE   Stabil fuer beta>a1
+C   A1=1.0
+C   A2=1.5
+C   B1=1
+C   beta=1.0
+C   C1=1.4
+C   C2=1.5
+C   gamma=1.5 
+C   DT=0.1
+C   LENGTH=60
+C   PLTPER=0.5
+PLOT INTERAKT=i,FREUNDLICH=f,AKTIV=a(-10,10)
+PRINT INTERAKT,FREUNDLICH,AKTIV
+C   PRTPER=0.5
+
diff --git a/dynamo/dyn.std b/dynamo/dyn.std
new file mode 100644
index 0000000..a87b66d
--- /dev/null
+++ b/dynamo/dyn.std
@@ -0,0 +1,9 @@
+abs r arctan r arctand r cos r cosd r exp r floor r frac r 
+initializerandom r random r 
+ln r log2 r log10 r 
+max rr min rr 
+power rr round r 
+sin r sind r sqrt r tan r tand r 
+clip rrrr fifge rrrr switch rrr fifze rrr noise r normrn rr pulse rrr 
+ramp rr sclprd trrtr step rr sumv trr sum t table trrrr tabhl trrrr /* 
+
diff --git a/dynamo/dyn.steifedgl b/dynamo/dyn.steifedgl
new file mode 100644
index 0000000..b168fcd
--- /dev/null
+++ b/dynamo/dyn.steifedgl
@@ -0,0 +1,15 @@
+NOTE STIFF EQUATIONS  SIEHE: SIMULATION AUGUST 1980, SEITE 38
+L    Y1.K=Y1.J+DT*(-21*Y1.J+19*Y2.J-20*Y3.J)
+L    Y2.K=Y2.J+DT*(+19*Y1.J-21*Y2.J+20*Y3.J)
+L    Y3.K=Y3.J+DT*(+40*Y1.J-40*Y2.J-40*Y3.J)
+N    Y1=1
+N    Y2=0
+N    Y3=-1
+NOTE KONSTANTEN MUESSEN GEEIGNET GEWAEHLT WERDEN:  DT  SEHR KLEIN
+C LENGTH=20
+C DT=.01
+C PRTPER=1
+C PLTPER=1
+PRINT Y1,Y2,Y3
+PLOT  Y1,Y2,Y3
+
diff --git a/dynamo/dyn.tool b/dynamo/dyn.tool
new file mode 100644
index 0000000..65769d8
--- /dev/null
+++ b/dynamo/dyn.tool
@@ -0,0 +1,217 @@
+PACKET io handling DEFINES error listing, err, message, errors, init errors,
+                           text, kill, trunc, hash, no errors :
+(* Autor : R. Keil, Version vom 22.07.83, Änderung: C. Szymanski, 21.07.88 *)
+
+LET errmax        = 67,
+    max hash size = 300;
+ 
+ROW errmax TEXT VAR error;
+FILE VAR listfile;                    (* -> VERSION 3.2  *)
+BOOL VAR list;
+INT VAR errorno, i;
+ 
+PROC init errors (TEXT CONST fname) :
+ FILE VAR errorfile := sequential file (input, fname);
+ TEXT VAR buffer;
+ FOR i FROM 1 UPTO errmax WHILE NOT eof (errorfile) REP
+  getline (errorfile, buffer);
+  error (i) := buffer
+ END REP
+END PROC init errors;
+ 
+PROC init errors :
+  errorno := 0
+END PROC init errors;
+ 
+PROC error listing (TEXT CONST listname) :
+ list := listname <> "nolist";
+ IF list
+  THEN kill (listname);
+       listfile := sequential file (output, listname)
+ FI
+END PROC error listing;
+ 
+INT PROC errors :
+ error no
+END PROC errors;
+ 
+PROC err (TEXT CONST s, INT CONST m, line no) :
+ message ("Fehler in Zeile " + text (line no) + " bei >>" + s + "<< : "
+          + error (m));
+ errorno INCR 1
+END PROC err;
+ 
+BOOL PROC no errors :
+ IF errors = 0
+  THEN TRUE
+  ELSE display (text (error no) + " Fehler gefunden"13""10""); FALSE
+ FI
+END PROC no errors;
+
+PROC message (TEXT CONST m) :
+ IF list
+  THEN putline (list file, m);
+ FI;
+ note (m);                             (* C.S. 21.07.88 *)
+ note line;
+ display (m);
+ display (""13""10"")
+END PROC message;
+ 
+TEXT PROC text (BOOL CONST b) :
+ IF b
+  THEN "TRUE"
+  ELSE "FALSE"
+ FI
+END PROC text;
+ 
+PROC kill (TEXT CONST file name) :
+ command dialogue (FALSE);
+ forget (file name);
+ command dialogue (TRUE)
+END PROC kill;
+ 
+TEXT PROC trunc (TEXT CONST t) :
+ text (t, length (t) - 2)
+END PROC trunc;
+ 
+INT PROC hash (TEXT CONST word) :
+ INT VAR qs := 0;
+ FOR i FROM 1 UPTO length (word) REP
+  qs INCR code (word SUB i)
+ END REP;
+ (qs MOD max hash size) + 1.
+END PROC hash
+ 
+END PACKET io handling;
+ 
+ 
+(************************* S C A N N E R **************************)
+ 
+PACKET scan DEFINES next sym, scanner, scanpos :
+ 
+ 
+LET bold      = 1,          (* Autor : R. Keil, T. Froehlich *)
+    number    = 2,          (* Version vom 04.07.83 *)
+    delimiter = 3,
+    eol       = 4;
+ 
+TEXT VAR main buf, sym;
+INT  VAR position, type, cc, begin pos;
+ 
+PROC nextsym (TEXT CONST buf, TEXT VAR scan sym,
+              INT VAR scan type, pos) :
+ TEXT VAR char := buf SUB pos;
+ cc := code (char);
+ IF (cc >= 97 AND cc <= 122)
+  THEN process lower case
+ ELIF cc = 46 OR is int
+  THEN process real
+ ELIF (cc >= 65 AND cc <= 90)
+  THEN process upper case
+  ELSE process delimiter
+ FI.
+ 
+ process upper case :
+  scan type := bold;
+  scan sym  := low;
+  next char;
+  WHILE (cc >= 65 AND cc <= 90) OR is int REP
+   scan sym CAT low;
+   next char
+  END REP.
+ 
+ process lower case :
+  scan type := bold;
+  begin pos := pos;
+  REP
+   next char
+  UNTIL lower case char AND NOT is int END REP;
+  scan sym := subtext (buf, begin pos, pos - 1).
+ 
+ lower case char :
+  cc < 97 OR cc > 122.
+
+ process real :
+  process base;
+  process exponent;
+  scan type := number.
+ 
+ process base :
+  IF cc = 46
+   THEN next char;
+        IF is int
+         THEN scan sym := "0.";
+              process int
+         ELSE scan type := delimiter;
+              scan sym := ".";
+              LEAVE process real
+        FI
+   ELSE scan sym := "";
+        process int;
+        IF cc = 46
+         THEN scan sym CAT char;
+              next char;
+              IF is int
+               THEN process int
+               ELSE scan sym CAT "0"
+              FI
+         ELSE scan sym CAT ".0"
+        FI
+  FI.
+ 
+ process exponent :
+  IF cc = 69 OR cc = 101
+   THEN scan sym CAT "e";
+        next char;
+        IF cc = 43 OR cc = 45
+         THEN scan sym CAT char; next char
+        FI;
+        IF is int
+         THEN process int
+         ELSE err (char, 63, 0)
+        FI
+  FI.
+ 
+ process int :
+  WHILE is int REP
+   scan sym CAT char;
+   next char
+  END REP.
+ 
+is int :
+ cc >= 48 AND cc <= 57.
+ 
+ process delimiter :
+  IF cc = -1
+   THEN scan sym := "EOL"; scan type := eol
+   ELSE scan type := delimiter;
+        scan sym := char
+  FI;
+  pos INCR 1.
+ 
+ next char :
+  pos INCR 1; char := buf SUB pos; cc := code (char).
+ 
+ low :
+  IF cc >= 65 AND cc <= 90
+   THEN code (cc + 32)
+   ELSE char
+  FI.
+END PROC next sym;
+ 
+PROC scanner (TEXT CONST buf) :
+  main buf := buf; position := 1
+END PROC scanner;
+ 
+PROC next sym (TEXT VAR sym, INT VAR type) :
+  next sym (main buf, sym, type, position)
+END PROC next sym;
+ 
+INT PROC scanpos :
+ position
+END PROC scanpos
+ 
+END PACKET scan
+ 
+
diff --git a/dynamo/dyn.vec b/dynamo/dyn.vec
new file mode 100644
index 0000000..0554215
--- /dev/null
+++ b/dynamo/dyn.vec
@@ -0,0 +1,209 @@
+PACKET vector DEFINES TAB, :=, vector,         (* Autor : H.Indenbirken *)
+                      SUB, LENGTH, laenge, norm,  (* Stand : 24.09.81      *)
+                      nilvector, replace, =, <>, wert,
+                      +, -, *, /,
+                      get, put :
+ 
+LET n = 4000;
+ 
+TYPE TAB = STRUCT (INT lng, TEXT elem);
+TYPE INITTAB = STRUCT (INT lng, REAL value);
+ 
+INT VAR i;
+TEXT VAR t :: "12345678";
+TAB VAR v :: nilvector;
+ 
+ 
+REAL PROC wert (TAB CONST t, INT CONST i) :
+ t SUB i
+END PROC wert;
+ 
+OP := (TAB VAR l, TAB CONST r) :
+  l.lng := r.lng;
+  l.elem := r.elem
+ 
+END OP :=;
+ 
+OP := (TAB VAR l, INITTAB CONST r) :
+  l.lng := r.lng;
+  replace (t, 1, r.value);
+  l.elem := r.lng * t
+ 
+END OP :=;
+ 
+INITTAB PROC nilvector :
+   vector (1, 0.0)
+ 
+END PROC nilvector;
+ 
+INITTAB PROC vector (INT CONST lng, REAL CONST value) :
+  IF lng <= 0
+  THEN errorstop ("PROC vector : lng <= 0") FI;
+  INITTAB : (lng, value)
+ 
+END PROC vector;
+ 
+INITTAB PROC vector (INT CONST lng) :
+  vector (lng, 0.0)
+ 
+END PROC vector;
+ 
+REAL OP SUB (TAB CONST v, INT CONST i) :
+  test ("REAL OP SUB : ", v, i);
+  v.elem RSUB i
+ 
+END OP SUB;
+ 
+INT OP LENGTH (TAB CONST v) :
+  v.lng
+ 
+END OP LENGTH;
+ 
+INT PROC laenge (TAB CONST v) :
+  v.lng
+ 
+END PROC laenge;
+ 
+REAL PROC norm (TAB CONST v) :
+  REAL VAR result :: 0.0;
+  FOR i FROM 1 UPTO v.lng
+  REP result INCR ((v.elem RSUB i)**2) PER;
+  sqrt (result)  .
+ 
+END PROC norm;
+ 
+PROC replace (TAB VAR v, INT CONST i, REAL CONST r) :
+  test ("PROC replace : ", v, i);
+  replace (v.elem, i, r)
+ 
+END PROC replace;
+ 
+BOOL OP = (TAB CONST l, r) :
+  l.elem = r.elem
+END OP =;
+ 
+BOOL OP <> (TAB CONST l, r) :
+  l.elem <> r.elem
+END OP <>;
+ 
+TAB OP + (TAB CONST v) :
+  v
+END OP +;
+ 
+TAB OP + (TAB CONST l, r) :
+  test ("TAB OP + : ", l, r);
+  v := l;
+  FOR i FROM 1 UPTO v.lng
+  REP replace (v.elem, i, (l.elem RSUB i) + (r.elem RSUB i)) PER;
+  v
+ 
+END OP +;
+ 
+TAB OP - (TAB CONST a) :
+  v := a;
+  FOR i FROM 1 UPTO v.lng
+  REP replace (v.elem, i, - (a.elem RSUB i)) PER;
+  v
+ 
+END OP -;
+ 
+TAB OP - (TAB CONST l, r) :
+  test ("TAB OP - : ", l, r);
+  v := l;
+  FOR i FROM 1 UPTO v.lng
+  REP replace (v.elem, i, (l.elem RSUB i) - (r.elem RSUB i)) PER;
+  v
+END OP -;
+ 
+REAL OP * (TAB CONST l, r) :
+  test ("REAL OP * : ", l, r);
+  REAL VAR x :: 0.0;
+  FOR i FROM 1 UPTO l.lng
+  REP x INCR ((l.elem RSUB i) * (r.elem RSUB i)) PER;
+  x
+ 
+END OP *;
+ 
+TAB OP * (TAB CONST v, REAL CONST r) :
+  r*v
+ 
+END OP *;
+ 
+TAB OP * (REAL CONST r, TAB CONST a) :
+  v := a;
+  FOR i FROM 1 UPTO v.lng
+  REP replace (v.elem, i, r*(a.elem RSUB i)) PER;
+  v
+ 
+END OP *;
+ 
+TAB OP / (TAB CONST a, REAL CONST r) :
+  v := a;
+  FOR i FROM 1 UPTO v.lng
+  REP replace (v.elem, i, (a.elem RSUB i)/r) PER;
+  v
+ 
+END OP /;
+ 
+TEXT VAR error :: "";
+PROC test (TEXT CONST proc, TAB CONST v, INT CONST i) :
+  IF i > v.lng
+  THEN error := proc;
+       error CAT "subscript overflow (LENGTH v=";
+       error CAT text (v.lng);
+       error CAT ", i=";
+       error CAT text (i);
+       error CAT ")";
+       errorstop (error)
+  ELIF i < 1
+  THEN error := proc;
+       error CAT "subscript underflow (i = ";
+       error CAT text (i);
+       error CAT ")";
+       errorstop (error)
+  FI  .
+ 
+END PROC test;
+ 
+PROC test (TEXT CONST proc, TAB CONST a, b) :
+  IF a.lng <> b.lng
+  THEN error := proc;
+       error CAT "LENGTH a (";
+       IF a.lng <= 0
+       THEN error CAT "undefined"
+       ELSE error CAT text (a.lng) FI;
+       error CAT ") <> LENGTH b (";
+       error CAT text (b.lng);
+       error CAT ")";
+       errorstop (error)
+  FI
+ 
+END PROC test;
+ 
+PROC get (TAB VAR v, INT CONST lng) :
+  v.lng := lng;
+  v.elem := lng * "12345678";
+  REAL VAR x;
+  FOR i FROM 1 UPTO lng
+  REP get (x);
+      replace (v.elem, i, x)
+  PER  .
+ 
+END PROC get;
+ 
+PROC put (TAB CONST v, INT CONST laenge, fracs) :
+  FOR i FROM 1 UPTO v.lng
+  REP put (text (v.elem RSUB i, laenge, fracs)) PER
+ 
+END PROC put;
+ 
+PROC put (TAB CONST v) :
+  FOR i FROM 1 UPTO v.lng
+  REP put (text (v.elem RSUB i)) PER
+ 
+END PROC put;
+ 
+END PACKET vector;
+ 
+ 
+
diff --git a/dynamo/dyn.wachstum b/dynamo/dyn.wachstum
new file mode 100644
index 0000000..9f97bb9
--- /dev/null
+++ b/dynamo/dyn.wachstum
@@ -0,0 +1,19 @@
+NOTE 
+NOTE Ein einfaches Modell des Bevoelkerungswachstums
+NOTE
+L    BEVOELKERUNG.K=BEVOELKERUNG.J+DT*GEBURTENRATE.JK
+N    BEVOELKERUNG=ANFANGSBEVOELKERUNG
+C    ANFANGSBEVOELKERUNG=1000
+R    GEBURTENRATE.KL=BEVOELKERUNG.K*WACHSTUMSFAKTOR
+N    GEBURTENRATE=10
+C    WACHSTUMSFAKTOR=0.03  das heisst: 3 Prozent
+NOTE
+NOTE Simulationsparameter
+NOTE
+PLOT BEVOELKERUNG=B(1E3,9E4)/GEBURTENRATE=G(10,9E3)
+C    DT=1
+C    PLTPER=5
+C    LENGTH=300
+
+
+
diff --git "a/dynamo/dyn.wasser\303\266ko" "b/dynamo/dyn.wasser\303\266ko"
new file mode 100644
index 0000000..fe05881
--- /dev/null
+++ "b/dynamo/dyn.wasser\303\266ko"
@@ -0,0 +1,64 @@
+n t=15
+note***   wasserökosystem nach abel und reich
+note***   in: microextra 4/83 seite 34 ff
+note************************************************************************
+note*     hilfsgleichung fuer temperatur t
+note*     die zeit time in wochen
+
+a t.k=15+4*sin((time.k-10)*2*pi/52)    temperatur t; time in wochen
+c pi=3.1415
+note      gleichung fuer phytoplankton p
+
+l p.k=p.j+dt*(p.j*(p1*n.j*t.j-p2*z.j)(100-p.j)/100)  phytoplankton p
+note      gleichung fuer zooplankton  z
+
+l z.k=z.j+dt*(z.j*(p3*t.j*p.j+p4*n.j-(p5*f.j+p6*b.j)-1/p.j)(30-z.j)/30)
+note      gleichung fuer fische f
+l f.k=f.j+dt*(f.j*(p7*z.j-p8*b.j-p9/(z.j+p.j))(10-f.j)/10)
+
+note      gleichung fuer raubfisch barsch b
+
+l b.k=b.j+dt*(b.j*(p10*f.j+p11*z.j-1/(p12*f.j))(0.1-b.j)/0.1)
+
+note **** gleichung fuer naehrstoffmenge n
+
+l n.k=n.j+dt*(p13-n.j*(p14*p.j-p15*z.j))
+note **** anfangswerte ****************************************************
+n    p=p0
+n    z=z0
+n    f=f0
+n    b=b0 
+n    n=n0 
+c    p0=10
+c    z0=3
+c    f0=1
+c    b0=0.01
+c    n0=30          in kg/volumeneinheit bzw. Stück/volumeneinhe�[
+note ***** konstanten ********************************************************
+c    p1=0.006
+c    p2=1
+c    p3=0.006
+c    p4=0.03
+c    p5=1
+c    p6=100
+c    p7=0.33
+c    p8=100
+c    p9=1E-4
+c    p10=1
+c    p11=1
+c    p12=0.25
+c    p13=10
+c    p14=0.1
+c    p15=0.2
+note **** simulationskonstanten *********************************************
+c    dt=0.5
+c    length=60
+c    pltper=1
+note***** outputvariablen****************************************************
+a    lp.k=ln(p.k/p0)
+a    lz.k=ln(z.k/z0)
+a    lf.k=ln(f.k/f0)
+a    lb.k=ln(b.k/b0)
+a    logn.k=ln(n.k/n0)
+plot lp=p,lz=z,lf=f,lb=b,logn=n(-4,4)
+
diff --git a/dynamo/dyn.welt-forrester b/dynamo/dyn.welt-forrester
new file mode 100644
index 0000000..c3f9789
--- /dev/null
+++ b/dynamo/dyn.welt-forrester
@@ -0,0 +1,124 @@
+note weltmodell in der form fuer eumel dynamo       17.7.1987
+*    WORLD DYNAMICS W5 
+L    p.k=p.j+(dt)*(br.jk-dr.jk)  
+N    p=pi                        
+C    pi=1.65e9                   
+R    br.kl=(p.k)*(clip(brn,brn1,swt1,time.k))*(brfm.k)*(brmm.k) 
+X    *(brcm.k)*(brpm.k)          
+C    brn=.04                     
+C    brn1=.04                   
+C    swt1=1970                   
+A    brmm.k=tabhl(brmmt,msl.k,0,5,1) 
+T    brmmt=1.2/1/.85/.75/.77/.7  
+A    msl.k=ecir.k/(ecirn)       
+C    ecirn=1                    
+A    ecir.k=(cir.k)*(1-ciaf.k)*(nrem.k)/(1-ciafn) 
+A    nrem.k=table(nremt,nrfr.k,0,1,.25) 
+T    nremt=0/.15/.5/.85/1       
+A    nrfr.k=nr.k/nri          
+L    nr.k=nr.j+(dt)*(-nrur.jk)
+N    nr=nri                     
+C    nri=900e9                  
+R    nrur.kl=(p.k)*(clip(nrun,nrun1,swt2,time.k))*(nrmm.k) 
+C    nrun=1                     
+C    nrun1=1                    
+C    swt2=1970                   
+NOTE        equation 42 connects here from eq. 4 to eq.9 
+R    dr.kl=(p.k)*(clip(drn,drn1,swt3,time.k))*(drmm.k)*(drpm.k) 
+X    *(drfm.k)*(drcm.k)          
+C    drn=.028                    
+C    drn1=.028                   
+C    swt3=1970                   
+A    drmm.k=tabhl(drmmt,msl.k,0,5,.5) 
+T    drmmt=3/1.8/.8/.7/.6/.53/.5/.5/.5/.5
+A    drpm.k=table(drpmt,polr.k,0,60,10) 
+T    drpmt=.92/1.3/2/3.2/4.8/6.8/9.2 
+A    drfm.k=tabhl(drfmt,fr.k,0,2,.25) 
+T    drfmt=30/3/2/1.4/1/.7/.6/.5/.5 
+A    drcm.k=table(drcmt,cr.k,0,5,1) 
+T    drcmt=.9/1/1.2/1.5/1.9/3   
+A    cr.k=(p.k)/(la*pdn)          
+C    la=135e6                     
+C    pdn=26.5                   
+A    brcm.k=table(brcmt,cr.k,0,5,1) 
+T    brcmt=1.05/1/.9/.7/.6/.55     <
+A    brfm.k=tabhl(brfmt,fr.k,0,4,1) 
+T    brfmt=0/1/1.6/1.9/2 
+A    brpm.k=table(brpmt,polr.k,0,60,10) 
+T    brpmt=1.02/.9/.7/.4/.25/.15/.1 
+A    fr.k=(fpci.k)*(fcm.k)*(fpm.k)*(clip(fc,fc1,swt7,time.k))/fn 
+C    fc=1 
+C    fc1=1 
+C    fn=1 
+C    swt7=1970 
+A    fcm.k=table(fcmt,cr.k,0,5,1) 
+T    fcmt=2.4/.6/.4/.3/.2 
+A    fpci.k=tabhl(fpcit,cira.k,0,6,1) 
+T    fpcit=.5/1/1.4/1.7/1.9/2.05/2.2 
+A    cira.k=(cir.k)*(ciaf.k)/ciafn 
+C    ciafn=.3 
+A    cir.k=(ci.k/p.k) 
+L    ci.k=ci.j+(dt)*(cig.jk-cid.jk) 
+N    ci=cii 
+C    cii=.4e9 
+R    cig.kl=(p.k)*(cim.k)*(clip(cign,cign1,swt4,time.k)) 
+C    cign=.05 
+C    cign1=.05 
+C    swt4=1970 
+A    cim.k=tabhl(cimt,msl.k,0,5,1) 
+T    cimt=.1/1/1.8/2.4/2.8/3 
+R    cid.kl=(ci.k)*(clip(cidn,cidn1,swt5,time.k))   
+C    cidn=.025 
+C    cidn1=.025 
+C    swt5=1970 
+A    fpm.k=table(fpmt,polr.k,0,60,10)
+T    fpmt=1.02/.9/.65/.35/.2/.1/.05 
+A    polr.k=pol.k/pols 
+C    pols=3.6e9 
+L    pol.k=pol.j+(dt)*(polg.jk-pola.jk) 
+N    pol=poli 
+C    poli=.2e9 
+R    polg.kl=(p.k)*(clip(poln,poln1,swt6,time.k))*(polcm.k) 
+C    poln=1 
+C    poln1=1 
+C    swt6=1970
+A    polcm.k=tabhl(polcmt,cir.k,0,5,1) 
+T    polcmt=.05/1/3/5.4/7.4/8
+R    pola.kl=pol.k/polat.k 
+A    polat.k=table(polatt,polr.k,0,60,10) 
+T    polatt=.6/2.5/8/11.5/15.5/20 
+L    ciaf.k=ciaf.j+(dt/ciaft)*((cfifr.j*ciqr.j)-ciaf.j) 
+N    ciaf=ciaf1 
+C    ciaf1=.2 
+C    ciaft=15 
+A    cfifr.k=tabhl(cfifrt,fr.k,0,2,.5)
+T    cfifrt=1/.6/.3/.15/.1  
+A    ql.k=(qls)*(qlm.k)*(qlc.k)*(qlf.k)*(qlp.k) 
+C    qls=1 
+A    qlm.k=tabhl(qlmt,msl.k,0,5,1) 
+T    qlmt=.2/1/1.7/2.3/2.7/2.9 
+A    qlc.k=table(qlct,cr.k,0,5,.5) 
+T    qlct=2/1.3/1/.75/.55/.45/.38/.3/.25/.22/.2 
+A    qlf.k=tabhl(qlft,fr.k,0,4,1) 
+T    qlft=0/1/1.8/2.4/2.7
+A    qlp.k=table(qlpt,polr.k,0,60,10) 
+T    qlpt=1.04/.85/.6/.3/.15/.05/.02 
+NOTE      equation 42 located between eq. 4 and 9. 
+A    nrmm.k=tabhl(nrmmt,msl.k,0,10,1) 
+T    nrmmt=0/1/1.8/2.4/2.9/3.3/3.6/3.8/3.9/3.95/4 
+NOTE      input from eqn. 38 and 40 to eqn. 35 
+A    ciqr.k=tabhl(ciqrt,qlm.k/qlf.k,0,2,.5) 
+T    ciqrt=.7/.8/1/1.5/2 
+NOTE 
+NOTE control cards 
+NOTE 
+C    dt=.1 
+C    length=2100 
+N    time=1900 
+C    prtper=4 
+C    pltper=4 
+PLOT p=p(0,8e9)/polr=2(0,40)/ci=c(0,20e9)/ql=q(0,2)/nr=n(0,1e12)
+note PLOT fr=f,msl=m,qlc=4,qlp=5(0,2)/ciaf=a(.2,.6) 
+PRINT p,nr,ci,pol,ciaf 
+
+
diff --git a/dynamo/dyn.wohnen b/dynamo/dyn.wohnen
new file mode 100644
index 0000000..4e9b8b4
--- /dev/null
+++ b/dynamo/dyn.wohnen
@@ -0,0 +1,105 @@
+note   modell des wohnbaus in einer stadt
+note
+note   siehe Goodman: Study Notes in System Dynamics, Seite 332 ff
+note
+note   Bevölkerungs-Sektor
+note
+L    pop.k=pop.j+dt*(imr.jk-omr.jk-ndr.jk)
+N    pop=popi
+C    popi=30.3
+note
+note   pop   population (people)
+note   popi  population initial value
+note   imr   immigration rate  (people/year)
+note   omr   out-migration rate(people/year)
+note
+R    imr.kl=nim*ammp.k*pop.k
+C    nim=.145
+note
+note   nim   normal immigration (fraction/year)
+note   ammp  attractiveness for migration multiplier perceived (dimensionless)
+note
+A    ammp.k=smooth(amm.k,mpt)
+C    mpt=5
+note
+note   amm   attractiveness for migration multiplier (dimensionless)
+note   mpt   migrant perception time (years)
+note
+A    amm.k=table(ammt,hr.k,0,2,.25)
+T    ammt=.05/.1/.2/.4/1/1.6/1.8/1.9/2
+note
+note   ammt  attractiveness for migration multiplier table
+note   hr    housing ratio  (dimensionless)
+note
+A    dmm.k=1/amm.k
+note
+note   dmm   departure migration multiplier (dimensionless)
+note
+R    omr.kl=nom*dmm.k*pop.k
+C    nom=.02
+note 
+note   nom   normal out migration (fraction/year)
+note
+R    ndr.kl=pop.k*drf
+C    drf=.025
+note 
+note   ndr   net death rate  (people/year)
+note   drf   death rate factor (fraction/year)
+note*************************************************************************
+note   housing sector
+note*************************************************************************
+note
+L    h.k=h.j+dt*(hcr.jk-hdr.jk)
+N    h=hi
+c    hi=10
+note
+note   h     housing (units)
+note   hcr   housing construction rate (units/year)
+note   hdr   housing demolition rate  (units/year)
+note   hi    initial value of houses (units)
+note
+R    hcr.kl=nhc*hcm.k*lam.k*h.k
+C    nhc=.12
+note 
+note   nhc   normal housing construction (fraction/year)
+note   hcm   housing construction multiplier (dimensionless)
+note   lam   land availability multiplier (dimensionless)
+note
+A    hcm.k=table(hcmt,hr.k,0,2,.25)
+T    hcmt=2.5/2.4/2.3/2/1/.37/.2/.1/.05
+note
+A    hr.k=h.k/hd.k
+note
+note   hr    housing ratio(dimensionless)
+note   hd    housing desired (units)
+note
+A    hd.k=pop.k*upp
+C    upp=.33
+note
+note   upp   units per person (unit/person)
+note
+A    lam.k=table(lamt,lfo.k,0,1,.25)
+T    lamt=1/.8/.5/.2/0
+note
+note   lfo   land fraction occupied (dimensionless)
+note
+A    lfo.k=H.k*lpu/land
+C    lpu=1
+C    land=1500
+note
+note   lpu   land per unit(acres/unit)
+note   land  (acres)
+note
+R    hdr.kl=h.k/alth
+C    alth=50
+note
+note   alth  average lifetime of housing (years)
+note***********************************************************************
+note   control statements
+note***********************************************************************
+note
+plot h=h(0,2000)/pop=p(0,8000)/hcr=c,hdr=d(0,100)
+C    dt=1
+C    length=200
+C    pltper=2
+
diff --git a/dynamo/dyn.workfluc b/dynamo/dyn.workfluc
new file mode 100644
index 0000000..8016449
--- /dev/null
+++ b/dynamo/dyn.workfluc
@@ -0,0 +1,44 @@
+NOTE 
+NOTE *******************************************************************
+NOTE              MODEL OF WORKLOAD FLUCTUATIONS
+NOTE *******************************************************************
+NOTE              JOHN HENIZE                                  5.11.81 
+NOTE *******************************************************************
+NOTE 
+L    MM.K=MM.J+(DT)*(-MTR.J)              MANPOWER IN MARKETING
+N    MM=4  MEN
+L    MP.K=MP.J+(DT)*(MTR.J)               MANPOWER IN PRODUCTION
+N    MP=6  MEN
+NOTE
+L    JIP.K=JIP.J+(DT)*(JS.J-JC.J)         JOBS_IN_PROCESS
+N    JIP=6 JOBS
+A    JM.K=MM.K/MEJ                       JOBS MARKETED
+C    MEJ=2  MAN_MONTHS/JOB               MARKETING EFFORT PER JOB
+L    JS.K=JS.J+(DT/SD)*(JM.J-JS.J)        JOBS SOLD
+N    JS=JM
+C    SD=2 MONTH                          SALES DELAY
+A    JC.K=MP.K/AJS                       JOBS COMPLETED
+C    AJS=8 MAN_MONTH/JOB
+NOTE
+A    MTR.K=(BA.K+PMA.K)*MTC.K            MANPOWER TRANSFER RATE
+A    BA.K=MMJ*(JIP.K-DJIP)               BACKLOG ADJUSTMENT
+C    DJIP=6 JOBS                         DESIRED JOBS IN PROCESS
+C    MMJ=.15 MEN PER MONTH PER JOB       MEN REALLOCATED PER MONTH PER
+NOTE
+A    MTC.K=CLIP(MMC.K,PMC.K,BA.K,0)      MANPOWER TRANSFER CONSTRAINT
+A    MMC.K=MMR.K                         MARKETING MANPOWER CONSTRAINT
+A    MMR.K=MM.K/(MM.K+MP.K)              MARKETING MANPOWER RATIO
+A    PMC.K=PMR.K*PMR.K                   PRODUCTION MANPOWER CONSTRAINT
+A    PMR.K=MP.K/(MM.K+MP.K)              PRODUCTION MANPOWER RATIO
+NOTE
+A    PMA.K=SWITCH(0,PMA1.K,SW)           PRODUCTION MANPOWER ADJUSTMENT
+C    SW=0
+A    PMA1.K=(DMP.K-MP.K)/MAT
+A    DMP.K=JS.K*AJS                      DESIRED MANPOWER IN PRODUCTION
+C    MAT=10 MONTHS                       MANPOWER ADJUSTMENT TIME
+NOTE
+C    DT=.2
+C    LENGTH=120
+C    PLTPER=6
+PLOT MM=M,MP=P(0,10)/JIP=J(0,20)
+
diff --git a/dynamo/dyn.wurzel b/dynamo/dyn.wurzel
new file mode 100644
index 0000000..7f8e6e0
--- /dev/null
+++ b/dynamo/dyn.wurzel
@@ -0,0 +1,14 @@
+note theon von smyrnas verfahren
+note
+l uj.k=u.j
+l u.k=u.j+2*v.j
+l v.k=v.j+uj.j
+n uj=1
+n u=1
+n v=1
+a wurzelzwei.k=u.k/v.k
+print u,v,wurzelzwei
+c dt=1
+c length=20
+c prtper=1
+
diff --git a/dynamo/out.world b/dynamo/out.world
new file mode 100644
index 0000000..39859ce
--- /dev/null
+++ b/dynamo/out.world
@@ -0,0 +1,43 @@
+PAGE   1  : WORLD DYNAMICS W5
+P=P(0,8E9)/POLR=2(0,40)/CI=C(0,20E9)/QL=Q(0,2)/NR=N(0,1000E9) 
+     0.0          2.000000e9   4.000000e9   6.000000e9   8.000000e9p
+     0.0          10.          20.          30.          40.2
+     0.0          5.000000e9   1.000000e10  1.500000e10  2.000000e10c
+     0.0          .5           1.           1.5          2.q
+     0.0          2.500000e11  5.000000e11  7.500000e11  1.000000e12n
+1900. 2c________p__.__q_________.____________._______n____.
+1902. 2c        p  .   q        .            .       n    .
+1908. 2c        p  .      q     .            .       n    .
+1914. 2c         p .        q   .            .       n    .
+1920. 2 c         p.          q .            .      n     .
+1926. 2_c__________p____________q____________.______n_____.
+1932. 2  c         .p           .q           .      n     .
+1938. 2   c        .  p         .q           .     n      .
+1944. 2    c       .   p        . q          .     n      .
+1950. 2     c      .     p      Ω§Ω§         .    n       .
+1956. 2______c_____.______p_____.q___________.___n________.
+1962. 2       c    .        p   q            .  n         .
+1968. 2        c   .         p q.            . n          .
+1974. .2         c .           p.            .n           .q
+1980. .2          c.           q.p           n            .
+1986. .2___________.c_________q_.__p_______n_.____________.
+1992. . 2          . c       q  .   p     n  .            .
+1998. . 2          .   c    q   .     p n    .            .
+2004. .__2_________.____c_q_____._____np_____.____________.
+2010. .   2        .     c      .    n  p    .            .q
+2016. .   2        .    q c     .  n    p    .            .
+2022. .    2       .    q  c    . n      p   .            .
+2028. .     2      .   q    c   n       p    .            .
+2034. ._____2______.___q____c_n_._______p____.____________.
+2040. .      2     .   q    cn  .      p     .            .
+2046. .      2     .   q    c   .     p      .            .n
+2052. .      2     .   q   nc   .    p       .            .
+2058. .      2     .  q  n c    .   p        .            .
+2064. ._____2______.__q_n__c____.__p_________.____________.
+2070. .     2      .  q n c     . p          .            .
+2076. .    2       .  qn c      .p           .            .
+2082. .    2       . qn c       .p           .            .
+2088. .   2        . q c        p            .            .n
+2094. .__2_________.qnc________p.____________.____________.
+2100. .  2         .qc        p .            .            .n
+
diff --git a/eudas/Adressen b/eudas/Adressen
new file mode 100644
index 0000000..74f0e3d
Binary files /dev/null and b/eudas/Adressen differ
diff --git a/eudas/dummy.text b/eudas/dummy.text
new file mode 100644
index 0000000..0eb03b0
--- /dev/null
+++ b/eudas/dummy.text
@@ -0,0 +1,14 @@
+PACKET dummy text DEFINES 
+  lineform, pageform, autoform, autopageform : 
+ 
+PROC lineform (TEXT CONST datei) :  fehler  END PROC lineform; 
+PROC pageform (TEXT CONST datei) :  fehler  END PROC pageform; 
+PROC autoform (TEXT CONST datei) :  fehler  END PROC autoform; 
+PROC autopageform (TEXT CONST datei) :  fehler  END PROC autopageform; 
+ 
+PROC fehler : 
+  errorstop ("Keine Textverarbeitung installiert")
+END PROC fehler; 
+ 
+END PACKET dummy text; 
+
diff --git a/eudas/eudas.1 b/eudas/eudas.1
new file mode 100644
index 0000000..18607c4
--- /dev/null
+++ b/eudas/eudas.1
@@ -0,0 +1,52 @@
+PACKETeudassatzzugriffeDEFINES SATZ,:=,satzinitialisieren,felderzahl,feldlesen,feldbearbeiten,feldaendern,feldindex:LETb0=256,c0=2;LETd0=" ",e0="";LETf0=#101
+#" ist keine Feldnummer";TEXT VARg0:=c0*d0;TYPE SATZ=TEXT;OP:=(SATZ VARh0,SATZ CONSTi0):CONCR(h0):=CONCR(i0)END OP:=;PROCsatzinitialisieren(SATZ VARj0):satzinitialisieren(j0,0)END PROCsatzinitialisieren;PROCsatzinitialisieren(SATZ VARj0,INT CONSTk0):replace(g0,1,2*k0+3);INT VARl0;CONCR(j0):=e0;FORl0FROM1UPTOk0+1REP CONCR(j0)CATg0END REP END PROCsatzinitialisieren;INT PROCfelderzahl(SATZ CONSTj0):INT VARm0:=(CONCR(j0)ISUB1)DIV2;INT CONSTn0:=CONCR(j0)ISUBm0;REPm0DECR1UNTILm0<=0CORo0END REP;m0.o0:(CONCR(j0)ISUBm0)<>n0.END PROCfelderzahl;PROCfeldlesen(SATZ CONSTj0,INT CONSTp0,TEXT VARq0):r0(CONCR(j0),p0);IF NOTiserrorTHENq0:=subtext(CONCR(j0),s0,t0)END IF END PROCfeldlesen;PROCfeldbearbeiten(SATZ CONSTj0,INT CONSTp0,PROC(TEXT CONST,INT CONST,INT CONST)u0):r0(CONCR(j0),p0);IF NOTiserrorTHENu0(CONCR(j0),s0,t0)END IF END PROCfeldbearbeiten;INT VARs0,t0;PROCr0(TEXT CONSTj0,INT CONSTp0):IFv0THENerrorstop(text(p0)+f0)ELIFw0THENs0:=j0ISUBp0;t0:=(j0ISUBp0+1)-1ELSEs0:=1;t0:=0END IF.v0:p0<=0ORp0>b0.
+w0:p0+p0<(j0ISUB1)-1.END PROCr0;TEXT VARx0;PROCfeldaendern(SATZ VARj0,INT CONSTp0,TEXT CONSTq0):INT VARy0;INT CONSTz0:=((CONCR(j0)ISUB1)-2)DIV2;IFa1THENb1ELSEerrorstop(text(p0)+f0)END IF.a1:p0>0ANDp0<=b0.b1:INT CONSTc1:=p0-z0;IFc1<=0THENd1ELIFq0<>e0THENe1END IF.e1:INT CONSTf1:=CONCR(j0)ISUB(z0+1);x0:=subtext(CONCR(j0),g1,f1-1);CONCR(j0):=subtext(CONCR(j0),1,z0+z0);h1(CONCR(j0),1,z0,i1);j1;k1;CONCR(j0)CATx0;CONCR(j0)CATq0.i1:c1+c1.j1:INT CONSTl1:=f1+i1;FORy0FROMz0+1UPTOp0REPm1(CONCR(j0),l1)END REP.k1:m1(CONCR(j0),l1+length(q0)).g1:CONCR(j0)ISUB1.d1:INT CONSTs0:=CONCR(j0)ISUBp0,n1:=CONCR(j0)ISUB(p0+1);IFs0>length(CONCR(j0))THENo1ELSEp1END IF.o1:h1(CONCR(j0),p0+1,z0+1,length(q0));CONCR(j0)CATq0.p1:x0:=subtext(CONCR(j0),n1);CONCR(j0):=subtext(CONCR(j0),1,s0-1);h1(CONCR(j0),p0+1,z0+1,q1);CONCR(j0)CATq0;CONCR(j0)CATx0.q1:length(q0)-r1.r1:n1-s0.END PROCfeldaendern;PROCm1(TEXT VARj0,INT CONSTs1):replace(g0,1,s1);j0CATg0END PROCm1;PROCh1(TEXT VARj0,INT CONSTt1,u1,v1):INT VARy0;FORy0FROMt1UPTOu1
+REPreplace(j0,y0,w1+v1)END REP.w1:j0ISUBy0.END PROCh1;INT PROCfeldindex(SATZ CONSTj0,TEXT CONSTx1):INT VARt1:=(CONCR(j0)ISUB1)-1,y0:=1;REPt1:=pos(CONCR(j0),x1,t1+1);IFt1=0THEN LEAVEfeldindexWITH0END IF;y1UNTILz1CANDa2END REP;y0.y1:WHILE(CONCR(j0)ISUBy0)<t1REPy0INCR1END REP.z1:(CONCR(j0)ISUBy0)=t1.a2:(CONCR(j0)ISUB(y0+1))=t1+length(x1).END PROCfeldindex;END PACKETeudassatzzugriffe;
+PACKETeudasdateienDEFINES EUDAT,oeffne,satznr,dateiende,saetze,aufsatz,weiter,zurueck,satzlesen,satzaendern,satzloeschen,satzeinfuegen,feldlesen,feldaendern,feldbearbeiten,felderzahl,feldnamenlesen,feldnamenaendern,notizenlesen,notizenaendern,feldinfo,automatischerschluessel,dezimalkomma,wertberechnen,reorganisiere,sortiere,sortierreihenfolge,unsortiertesaetze:LETb0=531,c0=121,d0=5000,e0=3243,f0=64,g0=48;LET INTVEC=TEXT,INDEX=STRUCT(INTh0,i0,INTj0,k0,INTVECl0),EINTRAG=STRUCT(INTh0,i0,m0,n0,SATZo0),DATEI=STRUCT(INTfelderzahl,SATZp0,INTVECfeldinfo,TEXTq0,INTr0,s0,t0,INTu0,v0,INTw0,satznr,INTx0,y0,z0,INTa1,b1,ROW3TEXTc1,ROWb0INTd1,ROWc0INDEXindex,ROWd0EINTRAGe1);TYPE EUDAT=BOUND DATEI;LETf1="";LETg1=#201
+#"Datei ist keine EUDAS-Datei",h1=#202
+#"inkonsistente EUDAS-Datei",i1=#203
+#"EUDAS-Datei voll",j1=#204
+#"Nicht erlaubtes Dezimalkomma";TEXT VARk1;TEXT VARl1:="  ";INTVEC CONSTm1:=n1(f0,1);LETo1="";TEXT VARp1;INTVEC PROCn1(INT CONSTlength,q1):replace(l1,1,q1);length*l1END PROCn1;PROCinsert(INTVEC VARr1,INT CONSTpos,q1):INT CONSTbegin:=pos+pos-1;IFbegin<1THENs1ELIFbegin>length(r1)+1THENt1ELSEreplace(l1,1,q1);p1:=subtext(r1,begin);r1:=subtext(r1,1,begin-1);r1CATl1;r1CATp1END IF END PROCinsert;PROCdelete(INTVEC VARr1,INT CONSTpos):INT CONSTbegin:=pos+pos-1;IFbegin<1THENs1ELIFbegin>=length(r1)THENt1ELSEp1:=subtext(r1,begin+2);r1:=subtext(r1,1,begin-1);r1CATp1END IF END PROCdelete;INT PROCpos(INTVEC CONSTr1,INT CONSTq1):replace(l1,1,q1);INT VARbegin:=1;REPbegin:=pos(r1,l1,begin)+1UNTIL(beginAND1)=0ORbegin=1END REP;beginDIV2END PROCpos;PROCu1(INTVEC VARv1,w1,INT CONSTpos):INT CONSTbegin:=pos+pos-1;IFbegin<1THENs1ELIFbegin>length(v1)+1THENt1ELSEw1:=subtext(v1,begin);v1:=subtext(v1,1,begin-1)END IF END PROCu1;PROCx1(INTVEC VARv1,w1,INT CONSTpos):INT CONSTbegin:=pos+pos-1;IFbegin<1THENs1ELIFbegin
+>length(v1)+1THENt1ELSEw1:=subtext(v1,1,begin-1);v1:=subtext(v1,begin)END IF END PROCx1;.t1:errorstop(9,f1).s1:errorstop(10,f1).PROCy1(DATEI VARz1):z1.felderzahl:=0;z1.feldinfo:=o1;satzinitialisieren(z1.p0);z1.q0:=f1;z1.r0:=1;z1.s0:=1;z1.u0:=0;z1.t0:=0;z1.w0:=0;z1.v0:=1;z1.a1:=0;z1.c1(1):=f1;z1.c1(2):=f1;z1.c1(3):=f1;z1.satznr:=1;z1.x0:=1;z1.y0:=1;z1.z0:=1;z1.index(1).l0:=m1;z1.index(1):=INDEX:(0,0,1,1,n1(1,1));INT VARa2;FORa2FROM1UPTOb0REPz1.d1(a2):=0END REP;z1.e1(1):=EINTRAG:(0,0,1,0,b2).b2:z1.p0.END PROCy1;PROCoeffne(EUDAT VARz1,TEXT CONSTc2):enablestop;IF NOTexists(c2)THEN CONCR(z1):=new(c2);y1(CONCR(z1));type(old(c2),e0)ELIFtype(old(c2))=e0THEN CONCR(z1):=old(c2)ELSEerrorstop(g1)ENDIF END PROCoeffne;PROCoeffne(EUDAT VARz1,DATASPACE CONSTd2):IFtype(d2)<0THEN CONCR(z1):=d2;y1(CONCR(z1));type(d2,e0)ELIFtype(d2)=e0THEN CONCR(z1):=d2ELSEerrorstop(g1)END IF END PROCoeffne;PROCfeldlesen(EUDAT CONSTz1,INT CONSTe2,TEXT VARf2):feldlesen(g2,e2,f2).g2:z1.e1(z1.z0).o0.END PROCfeldlesen;PROC
+feldaendern(EUDAT VARz1,INT CONSTe2,TEXT CONSTh2):IFi2THENj2(CONCR(z1));k2;feldaendern(g2,e2,h2)END IF.i2:z1.z0<>1.k2:IFe2=1THENdisablestop;l2(CONCR(z1),m2(h2))END IF.g2:z1.e1(z1.z0).o0.END PROCfeldaendern;INT PROCfelderzahl(EUDAT CONSTz1):z1.felderzahlEND PROCfelderzahl;PROCfeldbearbeiten(EUDAT CONSTz1,INT CONSTe2,PROC(TEXT CONST,INT CONST,INT CONST)n2):feldbearbeiten(g2,e2,PROC(TEXT CONST,INT CONST,INT CONST)n2).g2:z1.e1(z1.z0).o0.END PROCfeldbearbeiten;PROCfeldnamenlesen(EUDAT CONSTz1,SATZ VARo2):o2:=z1.p0END PROCfeldnamenlesen;PROCfeldnamenaendern(EUDAT VARz1,SATZ CONSTp2):z1.p0:=p2;INT CONSTq2:=felderzahl(p2);IFq2>z1.felderzahlTHENr2;z1.felderzahl:=q2END IF.r2:z1.feldinfoCATn1(s2,-1).s2:q2-length(z1.feldinfo)DIV2.END PROCfeldnamenaendern;INT PROCfeldinfo(EUDAT CONSTz1,INT CONSTe2):z1.feldinfoISUBe2END PROCfeldinfo;PROCfeldinfo(EUDAT VARz1,INT CONSTe2,t2):replace(z1.feldinfo,e2,t2);IFpos(z1.q0,code(e2))>0THENz1.a1:=z1.w0END IF END PROCfeldinfo;INT PROCsatznr(EUDAT CONSTz1):z1.
+satznrEND PROCsatznr;BOOL PROCdateiende(EUDAT CONSTz1):z1.satznr>z1.w0END PROCdateiende;INT PROCsaetze(EUDAT CONSTz1):z1.w0END PROCsaetze;PROCu2(DATEI VARz1,INT CONSTx0,k0,satznr):IFx0<1ORx0>z1.s0CORk0<1ORk0>z1.index(x0).j0THENerrorstop(h1)END IF;disablestop;z1.x0:=x0;z1.y0:=k0;z1.satznr:=satznr;z1.z0:=z1.index(x0).l0ISUBk0END PROCu2;PROCaufsatz(EUDAT VARz1,INT CONSTv2):INT VARsatznr;IFv2<1THENsatznr:=1ELIFv2>z1.w0THENsatznr:=z1.w0+1ELSEsatznr:=v2END IF;w2(CONCR(z1),satznr)END PROCaufsatz;PROCaufsatz(EUDAT VARz1,TEXT CONSTx2):aufsatz(z1,1);IFy2THENweiter(z1,x2)END IF.y2:feldlesen(z1,1,k1);k1<>x2.END PROCaufsatz;PROCw2(DATEI VARz1,INT CONSTsatznr):IFz2THENu2(z1,1,1,1)END IF;INT VARx0:=z1.x0,a3:=z1.satznr-z1.y0;IFsatznr>z1.satznrTHENb3ELSEc3END IF;u2(z1,x0,k0,satznr).z2:satznr+satznr<z1.satznr.b3:WHILEd3REPa3INCRj0;x0:=z1.index(x0).i0END REP.d3:INT CONSTj0:=z1.index(x0).j0;a3+j0<satznr.c3:WHILEe3REPx0:=z1.index(x0).h0;a3DECRz1.index(x0).j0END REP.e3:a3>=satznr.k0:satznr-a3.END PROCw2;
+PROCweiter(EUDAT VARz1):f3(CONCR(z1))END PROCweiter;PROCf3(DATEI VARz1):IFg3THENh3END IF.g3:z1.z0<>1.h3:INT VARx0:=z1.x0,k0:=z1.y0;IFk0=index.j0THENx0:=index.i0;k0:=1ELSEk0INCR1END IF;u2(z1,x0,k0,z1.satznr+1).index:z1.index(x0).END PROCf3;PROCzurueck(EUDAT VARz1):i3(CONCR(z1))END PROCzurueck;PROCi3(DATEI VARz1):IFj3THENk3END IF.j3:z1.satznr<>1.k3:INT VARx0:=z1.x0,k0:=z1.y0;IFk0=1THENx0:=m0.h0;k0:=m0.j0ELSEk0DECR1END IF;u2(z1,x0,k0,z1.satznr-1).m0:z1.index(x0).END PROCi3;PROCweiter(EUDAT VARz1,TEXT CONSTx2):f3(CONCR(z1),x2)END PROCweiter;PROCf3(DATEI VARz1,TEXT CONSTx2):l3;WHILEm3CANDn3REPo3END REP;IFm3THENp3(z1,k0)ELSEw2(z1,z1.w0+1)END IF.l3:INT VARq3,k0:=z1.z0;IFn3THENr3(z1,m2(x2),k0,q3)ELSEo3END IF.m3:k0<>0.n3:feldlesen(g2,1,k1);k1<>x2.g2:z1.e1(k0).o0.o3:k0:=z1.e1(k0).i0.END PROCf3;PROCzurueck(EUDAT VARz1,TEXT CONSTx2):i3(CONCR(z1),x2)END PROCzurueck;PROCi3(DATEI VARz1,TEXT CONSTx2):l3;WHILEm3CANDn3REPs3END REP;IFm3THENp3(z1,k0)ELSEw2(z1,1)END IF.l3:INT VARk0:=z1.z0,q3;IFk0=1ORt3THEN
+r3(z1,m2(x2),q3,k0)END IF.m3:k0<>0.n3:k0=z1.z0ORt3.t3:feldlesen(g2,1,k1);k1<>x2.g2:z1.e1(k0).o0.s3:k0:=z1.e1(k0).h0.END PROCi3;PROCp3(DATEI VARz1,INT CONSTk0):INT CONSTu3:=z1.e1(k0).m0;INT VARy0:=1,satznr:=0;WHILEy0<>u3REPsatznrINCRz1.index(y0).j0;y0:=z1.index(y0).i0END REP;y0:=pos(z1.index(u3).l0,k0);satznrINCRy0;u2(z1,u3,y0,satznr).END PROCp3;INT VARindex;PROCv3(TEXT CONSTw3,INT CONSTx3,y3):INT VARz3:=x3;index:=0;IFy3-x3<4THENa4ELSEb4END IF;index:=indexMODb0+1.a4:WHILEz3<=y3REPindex:=index*4;indexINCRcode(w3SUBz3);z3INCR1END REP.b4:WHILEz3<=y3REPindexINCRindex;indexINCRcode(w3SUBz3);IFindex>16000THENindex:=indexMODb0END IF;z3INCR1END REP.END PROCv3;INT PROCm2(TEXT CONSTw3):v3(w3,1,length(w3));indexEND PROCm2;INT PROCm2(SATZ CONSTo0):feldbearbeiten(o0,1,PROC(TEXT CONST,INT CONST,INT CONST)v3);indexEND PROCm2;PROCr3(DATEI CONSTz1,INT CONSTm2,INT VARk0,c4):INT VARx0:=z1.r0;c4:=z1.d1(m2);k0:=0;BOOL VARd4:=TRUE;WHILEd4ANDc4<>0REPe4;o3END REP.e4:IFf4THENg4ELSEh4END IF.f4:z1.e1(c4).m0=z1.x0
+.g4:x0:=z1.x0;INT CONSTi4:=pos(l0,c4);IFi4=0THENerrorstop(h1)ELIFi4<=j4THENd4:=FALSE END IF.l0:z1.index(x0).l0.j4:z1.y0.h4:WHILEx0<>z1.e1(c4).m0REP IFx0=z1.x0THENd4:=FALSE;LEAVEe4ELSEx0:=z1.index(x0).h0END IF END REP.o3:IFd4THENk0:=c4;c4:=z1.e1(k0).h0END IF.END PROCr3;PROCk4(DATEI VARz1,INT CONSTm2):disablestop;INT CONSTk0:=z1.z0,h0:=z1.e1(k0).h0,i0:=z1.e1(k0).i0;IFi0<>0THENz1.e1(i0).h0:=h0ELSEz1.d1(m2):=h0END IF;IFh0<>0THENz1.e1(h0).i0:=i0END IF.END PROCk4;PROCl4(DATEI VARz1,INT CONSTm2,i0,h0):disablestop;INT CONSTk0:=z1.z0;z1.e1(k0).h0:=h0;z1.e1(k0).i0:=i0;IFh0<>0THENz1.e1(h0).i0:=k0END IF;IFi0<>0THENz1.e1(i0).h0:=k0ELSEz1.d1(m2):=k0END IF END PROCl4;PROCsatzlesen(EUDAT CONSTz1,SATZ VARo0):o0:=z1.e1(z1.z0).o0END PROCsatzlesen;PROCsatzaendern(EUDAT VARz1,SATZ CONSTm4):IF NOTdateiende(z1)THENn4END IF.n4:j2(CONCR(z1));disablestop;l2(CONCR(z1),m2(m4));g2:=m4.g2:z1.e1(z1.z0).o0.END PROCsatzaendern;PROCl2(DATEI VARz1,INT CONSTo4):IFp4THENq4END IF.p4:INT CONSTr4:=m2(g2);r4<>o4.q4:s4;t4.s4:
+k4(z1,r4).t4:INT VARh0,i0;r3(z1,o4,h0,i0);l4(z1,o4,h0,i0).g2:z1.e1(z1.z0).o0.END PROCl2;PROCsatzloeschen(EUDAT VARz1):IF NOTdateiende(z1)THENu4END IF.u4:disablestop;v4(CONCR(z1));w4(CONCR(z1));z1.w0DECR1.END PROCsatzloeschen;PROCv4(DATEI VARz1):x4(z1);INT CONSTk0:=z1.z0;k4(z1,m2(g2));z1.e1(k0).i0:=z1.u0;z1.u0:=k0.g2:z1.e1(k0).o0.END PROCv4;PROCsatzeinfuegen(EUDAT VARz1,SATZ CONSTm4):y4(CONCR(z1),m4)END PROCsatzeinfuegen;PROCy4(DATEI VARz1,SATZ CONSTm4):INT VARk0,h0,i0;enablestop;z4;a5;disablestop;z1.w0INCR1;b5(z1,k0);INT CONSTc5:=m2(k1);r3(z1,c5,i0,h0);l4(z1,c5,i0,h0);j2(z1).z4:IFz1.u0<>0THENk0:=z1.u0;z1.u0:=z1.e1(k0).i0ELIFz1.v0=d0THENerrorstop(i1)ELSEz1.v0INCR1;k0:=z1.v0END IF;z1.e1(k0).n0:=0;z1.e1(k0).o0:=m4.a5:feldlesen(m4,1,k1);IFz1.b1>0THEN IFk1=""THENd5;feldaendern(z1.e1(k0).o0,1,k1)END IF END IF.d5:k1:=text(z1.b1);k1:=e5+k1;IFz1.b1>32000THENz1.b1:=1ELSEz1.b1INCR1END IF.e5:(4-length(k1))*"0".END PROCy4;PROCautomatischerschluessel(EUDAT VARf5,BOOL CONSTg5):IFg5ANDf5.b1<0OR NOTg5
+ANDf5.b1>0THENf5.b1:=-f5.b1END IF END PROCautomatischerschluessel;BOOL PROCautomatischerschluessel(EUDAT CONSTf5):f5.b1>0END PROCautomatischerschluessel;INTVEC VARh5;PROCw4(DATEI VARz1):INT CONSTx0:=z1.x0,h0:=index.h0,i0:=index.i0;BOOL VARi5;delete(index.l0,z1.y0);index.j0DECR1;j5(z1,x0,i0,i5);IF NOTi5THENj5(z1,h0,x0,i5)END IF;k5(z1).index:z1.index(x0).END PROCw4;PROCj5(DATEI VARz1,INT CONSTz3,l5,BOOL VARi5):i5:=FALSE;IFz3<>0ANDl5<>0THENm5END IF.m5:INT CONSTn5:=index.j0,o5:=p5.j0;IFq5THENr5;i5:=TRUE END IF.q5:n5+o5<=g0ORn5=0ORo5=0.r5:index.j0INCRp5.j0;s5(z1,p5.l0,z3);index.l0CATp5.l0;t5.t5:index.i0:=p5.i0;IFindex.i0<>0THENz1.index(index.i0).h0:=z3ELSEz1.r0:=z3END IF;p5.i0:=z1.t0;z1.t0:=l5.index:z1.index(z3).p5:z1.index(l5).END PROCj5;PROCk5(DATEI VARz1):INT CONSTg2:=z1.satznr;u2(z1,1,1,1);w2(z1,g2)END PROCk5;PROCs5(DATEI VARz1,INTVEC CONSTl0,INT CONSTz3):INT VARa2;FORa2FROM1UPTOlength(l0)DIV2REPz1.e1(l0ISUBa2).m0:=z3END REP END PROCs5;PROCb5(DATEI VARz1,INT CONSTu5):INT VARx0:=z1.x0;IF
+index.j0>=f0THENv5END IF;index.j0INCR1;insert(index.l0,z1.y0,u5);z1.z0:=u5;z1.e1(u5).m0:=x0.v5:INT VARc5:=0;w5;IFc5<>0THENx5ELSEy5(z1)END IF;k5(z1);x0:=z1.x0.w5:IFz1.t0<>0THENc5:=z1.t0;z1.t0:=p5.i0ELIFz1.s0<c0THENz1.s0INCR1;c5:=z1.s0;p5.l0:=m1END IF.x5:z5;a6;p5.j0:=index.j0-b6;u1(index.l0,p5.l0,b6+1);index.j0:=b6;s5(z1,p5.l0,c5).z5:INT CONSTc6:=index.i0;IFc6<>0THENz1.index(c6).h0:=c5ELSEz1.r0:=c5END IF;p5.i0:=c6;p5.h0:=x0;index.i0:=c5.a6:INT VARb6;IFd6THENb6:=g0ELSEb6:=index.j0DIV2+1END IF.d6:c6=0.index:z1.index(x0).p5:z1.index(c5).END PROCb5;PROCy5(DATEI VARz1):INT VARx0:=1;REPe6;f6END REP.e6:BOOL VARi5;REP INT CONSTi0:=index.i0;j5(z1,x0,i0,i5)UNTIL NOTi5END REP;IFi0=0THEN LEAVEy5ELIFg6THENh6END IF.g6:INT CONSTi6:=g0-index.j0;i6>0.h6:x1(p5.l0,h5,i6+1);p5.j0DECRi6;s5(z1,h5,x0);index.l0CATh5;index.j0:=g0.f6:x0:=i0.index:z1.index(x0).p5:z1.index(i0).END PROCy5;TEXT VARj6:=",";LETk6=1;TEXT PROCdezimalkomma:j6END PROCdezimalkomma;PROCdezimalkomma(TEXT CONSTl6):IFlength(l6)<>1THENerrorstop(
+j1)ELSEj6:=l6ENDIF END PROCdezimalkomma;INT PROCunsortiertesaetze(EUDAT CONSTz1):z1.a1END PROCunsortiertesaetze;TEXT PROCsortierreihenfolge(EUDAT CONSTz1):z1.q0END PROCsortierreihenfolge;PROCj2(DATEI VARz1):IFm6(z1)THENdisablestop;z1.e1(z1.z0).n0INCRk6;z1.a1INCR1END IF END PROCj2;PROCx4(DATEI VARz1):IF NOTm6(z1)THENdisablestop;z1.e1(z1.z0).n0DECRk6;z1.a1DECR1END IF END PROCx4;BOOL PROCm6(DATEI CONSTz1,INT CONSTk0):(z1.e1(k0).n0ANDk6)=0END PROCm6;BOOL PROCm6(DATEI CONSTz1):m6(z1,z1.z0)END PROCm6;INTVEC VARn6;TEXT VARq0;TEXT VARo6,p6;PROCsortiere(EUDAT VARz1):q0:=z1.q0;IFq0=f1THENq6END IF;r6(CONCR(z1)).q6:INT VARa2;FORa2FROM1UPTOz1.felderzahlREPq0CATcode(a2)END REP.END PROCsortiere;PROCsortiere(EUDAT VARz1,TEXT CONSTs6):q0:=s6;r6(CONCR(z1))END PROCsortiere;PROCr6(DATEI VARz1):IFz1.q0<>q0THENz1.q0:=q0;z1.a1:=z1.w0+1ELIFz1.a1=0THEN LEAVEr6END IF;n6:=z1.feldinfo;IFt6THENu6(z1);z1.a1:=0ELSEv6(z1)END IF;w2(z1,1).t6:z1.w0DIVz1.a1<3.END PROCr6;PROCu6(DATEI VARz1):INT VARz0,o0:=1,w6;w2(z1,1);x4(
+z1);z0:=z1.z0;WHILEx6REPy6;z6;cout(o0)END REP;disablestop;y5(z1);u2(z1,1,1,1).x6:o0<z1.w0.y6:o0INCR1;w2(z1,o0);w6:=z0;z0:=z1.z0.z6:IFa7THENb7(z1,o0,z0);z0:=w6ELSEx4(z1)END IF.a7:z1.e1(w6).o0GROESSERz1.e1(z0).o0.END PROCu6;PROCv6(DATEI VARz1):INT VARa2;FORa2FROM1UPTOz1.v0REP IF NOTm6(z1,a2)THENb7(z1,z1.w0+1,a2);cout(a2)END IF END REP END PROCv6;PROCb7(DATEI VARz1,INT CONSTsatznr,z0):c7;d7.c7:INT VARe7:=1,f7:=satznr-1,g7;WHILEh7REPi7;j7END REP.h7:e7<=f7.i7:g7:=(e7+f7)DIV2;INT VARk7;w2(z1,g7);IF NOTm6(z1)THENl7END IF;k7:=z1.z0.l7:WHILEz1.satznr<f7REPf3(z1);IFm7THEN LEAVEl7END IF END REP;WHILEz1.satznr>e7REPi3(z1);IFm7THEN LEAVEl7END IF END REP;LEAVEc7.m7:m6(z1).j7:IFn7GROESSERz1.e1(z0).o0THENf7:=g7-1ELSEe7:=g7+1END IF.n7:z1.e1(k7).o0.d7:p3(z1,z0);IFz1.satznr<e7THENe7DECR1END IF;disablestop;x4(z1);o7;w4(z1);w2(z1,e7);b5(z1,z0);p7.o7:INT CONSTq7:=m2(g2);k4(z1,q7).p7:INT VARh0,i0;r3(z1,q7,h0,i0);l4(z1,q7,h0,i0).g2:z1.e1(z0).o0.END PROCb7;BOOL OP GROESSER(SATZ CONSTr7,s7):t7;u7;SELECTn6ISUBv7
+OF CASE0:w7CASE1:x7CASE2:y7OTHERWISEz7END SELECT.t7:INT VARa8:=1;WHILEa8<length(q0)REP INT CONSTv7:=code(q0SUBa8);feldlesen(r7,v7,o6);feldlesen(s7,v7,p6);SELECTn6ISUBv7OF CASE0:b8CASE1:c8OTHERWISEd8END SELECT;a8INCR2END REP;LEAVE GROESSER WITH FALSE.u7:BOOL VARe8;IF(q0SUB(a8+1))="-"THENe8:=FALSE ELSEe8:=TRUE END IF.c8:REAL VARf8,g8;wertberechnen(o6,f8);wertberechnen(p6,g8);IFf8<>g8THEN LEAVEt7END IF.b8:IF NOT(o6LEXEQUALp6)THEN LEAVEt7END IF.d8:IFo6<>p6THEN LEAVEt7END IF.x7:IFe8THENf8>g8ELSEf8<g8END IF.w7:IFe8THENo6LEXGREATERp6ELSEp6LEXGREATERo6END IF.y7:h8(o6);h8(p6);IFe8THENo6>p6ELSEo6<p6END IF.z7:IFe8THENo6>p6ELSEo6<p6END IF.END OP GROESSER;PROCwertberechnen(TEXT CONSTi8,REAL VARwert):LETj8="0123456789";TEXT VARk8:=j6,text;INT VARk0;INT CONSTl8:=length(i8);m8;WHILEk0<=l8REPn8;k0INCR1END REP;wert:=real(text).m8:k0:=pos(i8,"0","9",1);IFk0=0THENwert:=0.0;LEAVEwertberechnenELIFpos(i8,"-",1,k0)>0THENtext:="-"ELSEtext:=f1END IF;.n8:TEXT CONSTo8:=i8SUBk0;IFpos(j8,o8)>0THENtextCATo8ELIFo8=k8
+THENtextCAT".";k8:=f1END IF.END PROCwertberechnen;PROCh8(TEXT VARp8):IFlength(p8)<>8THENp8:=f1ELSEp8:=subtext(p8,7)+subtext(p8,4,5)+subtext(p8,1,2)END IF END PROCh8;PROCreorganisiere(TEXT CONSTc2):EUDAT VARq8,r8;oeffne(q8,c2);disablestop;DATASPACE VARd2:=nilspace;oeffne(r8,d2);s8(CONCR(q8),r8);IF NOTiserrorTHENforget(c2,quiet);copy(d2,c2)END IF;forget(d2)END PROCreorganisiere;PROCs8(DATEI VARq8,EUDAT VARr8):enablestop;t8;u8(q8,CONCR(r8)).t8:w2(q8,1);aufsatz(r8,1);WHILE NOTdateiendeREPsatzeinfuegen(r8,v8);cout(q8.satznr);f3(q8);weiter(r8)END REP.dateiende:q8.satznr>q8.w0.v8:q8.e1(q8.z0).o0.END PROCs8;PROCu8(DATEI VARq8,r8):r8.felderzahl:=q8.felderzahl;r8.p0:=q8.p0;r8.feldinfo:=q8.feldinfo;r8.q0:=q8.q0;r8.c1(1):=q8.c1(1);r8.c1(2):=q8.c1(2);r8.c1(3):=q8.c1(3)END PROCu8;PROCnotizenlesen(EUDAT CONSTz1,INT CONSTv2,TEXT VARw8):w8:=z1.c1(v2)END PROCnotizenlesen;PROCnotizenaendern(EUDAT VARz1,INT CONSTv2,TEXT CONSTw8):z1.c1(v2):=w8END PROCnotizenaendern;END PACKETeudasdateien;
+PACKETdatenverwaltungDEFINESoeffne,kopple,kette,zugriff,sichere,dateienloeschen,aufkoppeldatei,anzahlkoppeldateien,anzahldateien,aendernerlaubt,inhaltveraendert,eudasdateiname,folgedatei,dateiversion,anzahlfelder,feldnamenlesen,feldnamenbearbeiten,feldnummer,feldinfo,notizenlesen,notizenaendern,feldlesen,feldbearbeiten,feldaendern,satznummer,satzkombination,dateiende,weiter,zurueck,aufsatz,satzeinfuegen,satzloeschen,aenderungeneintragen,suchbedingung,suchbedingunglesen,suchbedingungloeschen,suchversion,satzausgewaehlt,markierungaendern,satzmarkiert,markierungenloeschen,markiertesaetze:LET INTVEC=TEXT,DATEI=STRUCT(TEXTname,SATZb0,INTVECc0,INTd0,INTe0,INTf0,DATASPACEg0,EUDATh0,SATZi0,BOOLj0,BOOLk0,l0,m0,TEXTn0,INTVECo0,INTp0),VERWEIS=STRUCT(INTq0,r0);LETs0="",t0="";LETmaxint=32767,u0=10,v0=256,w0=32;ROWu0DATEI VARx0;INT VARy0:=0,z0:=0,a1,b1:=0,c1,d1:=0,e1,f1,g1,h1:=0;BOOL VARi1:=TRUE,j1,k1;TEXT VARl1;ROWv0VERWEIS VARm1;ROWw0VERWEIS VARn1;INT VARo1;LETp1=#301
+#"Zuviel Dateien geoeffnet",q1=#302
+#"Datei existiert nicht",r1=#303
+#"Nicht moeglich, wenn auf Koppeldatei geschaltet",s1=#304
+#"Zu viele Felder",t1=#305
+#"Zu viele Koppelfelder",u1=#306
+#"keine Koppelfelder vorhanden",v1=#307
+#"kein direkter Dateizugriff bei geketteten oder gekoppelten Dateien",w1=#308
+#"keine Datei geoeffnet",x1=#309
+#"Datei nicht gesichert",y1=#310
+#"Suchmuster zu umfangreich";TEXT VARz1;TEXT VARa2:="  ";INTVEC VARb2;OP CAT(INTVEC VARtext,INT CONSTwert):replace(a2,1,wert);textCATa2END OP CAT;PROCinsert(INTVEC VARc2,INT CONSTd2,wert):INT CONSTe2:=d2+d2-2;b2:=subtext(c2,e2+1);c2:=subtext(c2,1,e2);c2CATwert;c2CATb2END PROCinsert;PROCdelete(INTVEC VARc2,INT CONSTd2):INT CONSTe2:=d2+d2-2;b2:=subtext(c2,e2+3);c2:=subtext(c2,1,e2);c2CATb2END PROCdelete;PROCf2(INTVEC VARc2,INT CONSTg2,h2):INT VARi2;FORi2FROMg2UPTOlength(c2)DIV2-1REPreplace(c2,i2,(c2ISUBi2)+h2)END REP END PROCf2;EUDAT VARj2;SATZ VARk2;PROCl2(TEXT CONSTm2):IFy0=u0THENerrorstop(p1)END IF;IF NOTexists(m2)THENerrorstop(q1)END IF;IFn2THENerrorstop(r1)END IF;oeffne(j2,m2)END PROCl2;PROCo2(DATEI VARq0,TEXT CONSTm2):IFj1THENq0.g0:=old(m2);oeffne(q0.h0,q0.g0)ELSEoeffne(q0.h0,m2)END IF;q0.e0:=0;q0.k0:=FALSE;q0.l0:=FALSE;q0.name:=m2;p2(q0)END PROCo2;PROCq2(INT CONSTr2):INT VARs2:=r2;WHILEx0(s2).e0<>0REPs2:=x0(s2).e0END REP;x0(s2).e0:=y0END PROCq2;PROCt2:IFdateiende(x0(1).h0)THEN
+aufsatz(1)ELSEaufsatz(satznr(x0(1).h0))END IF END PROCt2;PROCu2:c1:=felderzahl(x0(1).h0);d1:=c1;feldnamenlesen(x0(1).h0,x0(1).b0);o1:=0;INT VARi2;FORi2FROM1UPTOd1REPm1(i2).q0:=0END REP END PROCu2;PROCv2:h1INCR1;IFh1>32000THENh1:=-32000END IF END PROCv2;PROCoeffne(TEXT CONSTm2,BOOL CONSTw2):enablestop;dateienloeschen(FALSE);suchbedingungloeschen;l2(m2);j1:=w2;x2;o2(x0(y0),m2);t2;u2.x2:y0:=1;v2;g1:=0.END PROCoeffne;PROCkopple(TEXT CONSTm2):enablestop;IFy0=0THENerrorstop(w1)END IF;l2(m2);y2;z2;a3;o2(x0(y0),m2);b3.y2:feldnamenlesen(j2,k2);INT VARc0:=0;INTVEC VARc3:=t0;WHILEc0<felderzahl(j2)REPfeldlesen(k2,c0+1,z1);INT CONSTindex:=feldindex(x0(1).b0,z1);IFindex>0THENc0INCR1;c3CATindexEND IF UNTILindex=0END REP.z2:IFd1+felderzahl(j2)-c0>v0THENerrorstop(s1)ELIFo1+c0>w0THENerrorstop(t1)ELIFc0=0THENerrorstop(u1)END IF;y0INCR1;x0(y0).b0:=k2;x0(y0).c0:=c3;x0(y0).d0:=c0;INT VARd3:=c0;WHILEd3<felderzahl(j2)REPd1INCR1;d3INCR1;m1(d1).q0:=y0;m1(d1).r0:=d3END REP;FORd3FROM1UPTOc0REPe3END REP.e3:INT 
+CONSTf3:=c3ISUBd3;IFm1(f3).q0=0THENg3ELSEh3END IF.g3:o1INCR1;n1(o1).q0:=y0;n1(o1).r0:=d3;m1(f3).q0:=o1;m1(f3).r0:=1.h3:INT CONSTi3:=m1(f3).q0+m1(f3).r0;j3;m1(f3).r0INCR1;n1(i3).q0:=y0;n1(i3).r0:=d3.j3:INT VARk3;FORk3FROMo1DOWNTOi3REPn1(k3+1):=n1(k3)END REP;o1INCR1;FORk3FROM1UPTOc1REP IFm1(k3).q0>=i3THENm1(k3).q0INCR1END IF END REP.a3:z0INCR1;IFb1=0THENb1:=y0ELSEq2(b1)END IF.b3:v2;x0(y0).j0:=FALSE;x0(y0).m0:=FALSE;x0(y0).f0:=satznr(j2);l3(x0(y0)).END PROCkopple;PROCkette(TEXT CONSTm2):enablestop;IFy0=0THENerrorstop(w1)END IF;l2(m2);y0INCR1;o2(x0(y0),m2);q2(1);IFi1THENaufsatz(satznummer)END IF END PROCkette;PROCzugriff(PROC(EUDAT VAR)m3):IFy0>1ORn2THENerrorstop(v1)ELSEaenderungeneintragen;m3(x0(1).h0);v2;t2;u2;x0(1).l0:=TRUE ENDIF END PROCzugriff;PROCsichere(INT CONSTn3,TEXT CONSTm2):aenderungeneintragen;notizenaendern(x0(n3).h0,2,date);IFj1THENforget(m2,quiet);copy(x0(n3).g0,m2)END IF;x0(n3).l0:=FALSE END PROCsichere;PROCdateienloeschen(BOOL CONSTo3):aenderungeneintragen;IFn2THEN
+aufkoppeldatei(0)END IF;p3;q3.p3:z0:=0;b1:=0;x0(1).e0:=0;d1:=0;i1:=TRUE.q3:WHILEy0>0REP IFr3AND NOTo3THENerrorstop(x1);LEAVEdateienloeschenEND IF;forget(x0(y0).g0);y0DECR1END REP.r3:j1ANDx0(y0).l0.END PROCdateienloeschen;INT VARs3,t3,u3,v3,w3,x3,y3,z3;BOOL VARa4;INTVEC VARb4;SATZ VARc4;BOOL VARn2:=FALSE;INT VARd4:=0,e4:=1;BOOL PROCaufkoppeldatei:n2END PROCaufkoppeldatei;PROCaufkoppeldatei(INT CONSTf4):disablestop;v2;IFn2THENg4;n2:=FALSE;h4;i4ELSEj4;n2:=TRUE;k4 END IF.g4:a1:=s3;c1:=t3;d1:=u3;e1:=v3;g1:=x3;b1:=y3;x0(e4).e0:=z3;l4:=d4;k1:=a4;m4:=b4;n4:=c4;IFl4>0THENk8:=1ELSEk8:=-1END IF.
+i4:d4:=0;e4:=1;enablestop;aufsatz(satznummer);WHILEf1<>w3REPweiter(1)END REP.h4:x0(e4).f0:=satznr(x0(e4).h0);IFf4=1AND NOTdateiende(x0(a1).h0)THENo4END IF.o4:INT VARp4;FORp4FROM1UPTOx0(e4).d0REPfeldaendern(x0(a1).h0,q4,r4)END REP;w3:=1.q4:x0(e4).c0ISUBp4.r4:feldlesen(x0(e4).h0,p4,z1);z1.j4:s3:=a1;t3:=c1;u3:=d1;v3:=e1;w3:=f1;x3:=g1;y3:=b1;z3:=x0(f4).e0;a4:=k1;b4:=m4;c4:=n4.k4:a1:=f4;d4:=l4;e4:=f4;c1:=felderzahl(x0(f4).h0);d1:=c1;e1:=0;g1
+:=(length(x0(f4).o0)-1)DIV2;b1:=0;x0(f4).e0:=0;suchbedingungloeschen;aufsatz(x0(f4).f0).END PROCaufkoppeldatei;INT PROCanzahlkoppeldateien:z0END PROCanzahlkoppeldateien;INT PROCanzahldateien:y0END PROCanzahldateien;BOOL PROCaendernerlaubt:j1END PROCaendernerlaubt;BOOL PROCinhaltveraendert(INT CONSTs4):aenderungeneintragen;x0(s4).l0END PROCinhaltveraendert;TEXT PROCeudasdateiname(INT CONSTs4):x0(s4).nameEND PROCeudasdateiname;INT PROCfolgedatei(INT CONSTs4):IFs4=0THENb1ELSEx0(s4).e0END IF END PROCfolgedatei;INT PROCdateiversion:h1END PROCdateiversion;INT PROCanzahlfelder:d1END PROCanzahlfelder;PROCfeldnamenlesen(INT CONSTd3,TEXT VARname):IFd3<=c1THENfeldlesen(x0(e4).b0,d3,name)ELSEfeldlesen(t4,u4,name)END IF.t4:x0(m1(d3).q0).b0.u4:m1(d3).r0.END PROCfeldnamenlesen;PROCfeldnamenbearbeiten(INT CONSTd3,PROC(TEXT CONST,INT CONST,INT CONST)v4):IFd3<=c1THENfeldbearbeiten(x0(e4).b0,d3,PROC(TEXT CONST,INT CONST,INT CONST)v4)ELSEfeldbearbeiten(t4,u4,PROC(TEXT CONST,INT CONST,INT CONST)v4)END IF.
+t4:x0(m1(d3).q0).b0.u4:m1(d3).r0.END PROCfeldnamenbearbeiten;INT PROCfeldnummer(TEXT CONSTw4):INT VARx4:=c1,f4:=feldindex(x0(e4).b0,w4),s2:=b1;WHILEf4=0ANDs2<>0REPf4:=feldindex(x0(s2).b0,w4);y4;s2:=x0(s2).e0END REP;f4.y4:INT CONSTz4:=x0(s2).d0;IFf4=0THENx4INCRfelderzahl(x0(s2).h0);x4DECRz4ELSEf4INCRx4;f4DECRz4END IF.END PROCfeldnummer;INT PROCfeldinfo(INT CONSTd3):IFd3<=c1THENfeldinfo(x0(e4).h0,d3)ELSEfeldinfo(x0(t4).h0,u4)END IF.t4:m1(d3).q0.u4:m1(d3).r0.END PROCfeldinfo;PROCnotizenlesen(INT CONSTf4,TEXT VARa5):notizenlesen(x0(e4).h0,f4,a5)END PROCnotizenlesen;PROCnotizenaendern(INT CONSTf4,TEXT CONSTa5):notizenaendern(x0(e4).h0,f4,a5)END PROCnotizenaendern;PROCfeldlesen(INT CONSTd3,TEXT VARa5):IFd3<=c1THENfeldlesen(x0(a1).h0,d3,a5)ELSEb5END IF.b5:INT CONSTt4:=m1(d3).q0;IFx0(t4).j0THENfeldlesen(x0(t4).i0,u4,a5)ELSEfeldlesen(x0(t4).h0,u4,a5)END IF.u4:m1(d3).r0.END PROCfeldlesen;PROCfeldbearbeiten(INT CONSTd3,PROC(TEXT CONST,INT CONST,INT CONST)v4):IFd3<=c1THENfeldbearbeiten(x0(a1).h0,
+d3,PROC(TEXT CONST,INT CONST,INT CONST)v4)ELSEc5END IF.c5:INT CONSTt4:=m1(d3).q0;IFx0(t4).j0THENfeldbearbeiten(x0(t4).i0,u4,PROC(TEXT CONST,INT CONST,INT CONST)v4)ELSEfeldbearbeiten(x0(t4).h0,u4,PROC(TEXT CONST,INT CONST,INT CONST)v4)END IF.u4:m1(d3).r0.END PROCfeldbearbeiten;PROCfeldaendern(INT CONSTd3,TEXT CONSTa5):INT CONSTt4:=m1(d3).q0;IFd3<=c1THENd5ELSEe5END IF.d5:x0(a1).l0:=TRUE;IFf5CANDg5THENh5END IF;feldaendern(x0(a1).h0,d3,a5).f5:NOTn2CANDt4>0.g5:feldlesen(x0(a1).h0,d3,z1);z1<>a5.h5:INT VARi5:=u4,j5:=t4;REPk5(x0(l5));x0(l5).m0:=TRUE;feldaendern(x0(l5).i0,f3,a5);j5INCR1;i5DECR1UNTILi5=0END REP.e5:k5(x0(t4));IFm5THENx0(t4).k0:=TRUE;feldaendern(x0(t4).i0,u4,a5)END IF.m5:feldlesen(x0(t4).i0,u4,z1);z1<>a5.u4:m1(d3).r0.l5:n1(j5).q0.f3:n1(j5).r0.END PROCfeldaendern;PROCk5(DATEI VARq0):IF NOTq0.j0THENq0.j0:=TRUE;n5END IF.n5:IFdateiende(q0.h0)THENsatzinitialisieren(q0.i0,q0.d0);o5ELSEsatzlesen(q0.h0,q0.i0)END IF.o5:INT VARi2;FORi2FROM1UPTOq0.d0REPfeldlesen(q0.c0ISUBi2,z1);feldaendern(
+q0.i0,i2,z1)END REP.END PROCk5;PROCl3(DATEI VARq0):p5;q5.p5:feldlesen(x0(a1).h0,r5,n0).r5:q0.c0ISUB1.n0:q0.n0.q5:aufsatz(q0.h0,n0);WHILE NOTs5(q0)REPweiter(q0.h0,n0)END REP;IFdateiende(q0.h0)THENk5(q0)ELSEq0.j0:=FALSE END IF.END PROCl3;PROCt5:INT VARs2:=b1;WHILEs2<>0REPl3(x0(s2));s2:=x0(s2).e0END REP;f1:=1END PROCt5;BOOL PROCs5(DATEI CONSTq0):IF NOTdateiende(q0.h0)THENu5END IF;TRUE.u5:INT VARv5;FORv5FROM2UPTOq0.d0REPfeldlesen(x0(a1).h0,c0ISUBv5,z1);feldbearbeiten(q0.h0,v5,PROC(TEXT CONST,INT CONST,INT CONST)w5);IF NOTx5THEN LEAVEs5WITH FALSE END IF END REP.c0:q0.c0.END PROCs5;BOOL VARx5;PROCw5(TEXT CONSTy5,INT CONSTr2,z5):x5:=length(z1)+r2=z5+1CANDpos(y5,z1,r2,z5+1)=r2END PROCw5;LETa6=22101,b6="h",c6=""27"";BOOL VARd6;PROCe6:TEXT VARf6;d6:=FALSE;REPf6:=incharety;type(f6)UNTILf6=s0END REP END PROCe6;PROCg6:IFd6THENtype(c6)END IF END PROCg6;BOOL PROCh6:TEXT VARf6;REPf6:=incharety;IFf6=s0THEN LEAVEh6WITH FALSE ELSEi6END IF END REP;FALSE.i6:IFd6THENd6:=FALSE;j6ELSEk6END IF.j6:IFf6=b6THENl6
+;errorstop(a6,s0);LEAVEh6WITH TRUE ELSEtype(c6);type(f6)END IF.k6:IFf6=c6THENd6:=TRUE ELSEtype(f6)END IF.l6:REP UNTILgetcharety=s0END REP.END PROCh6;PROCweiter(INT CONSTm6):IF NOTi1THENaenderungeneintragen;n6END IF.n6:SELECTm6OF CASE1:o6CASE2:p6CASE3:q6END SELECT.o6:r6(FALSE).p6:e6;REPr6(k1);cout(satznummer)UNTILsatzausgewaehltORi1ORh6END REP;g6.q6:INT VARs6:=satznr(x0(a1).h0);WHILEt6ANDe0<>0REPu6;s6:=1END REP;aufsatz(x0(a1).h0,v6);cout(satznummer);t5;i1:=dateiende(x0(a1).h0);w6.t6:x6(x0(a1),s6+1);INT CONSTv6:=x0(a1).o0ISUBx0(a1).p0;v6<>maxint.e0:x0(a1).e0.END PROCweiter;PROCzurueck(INT CONSTm6):IFsatznummer>1THENaenderungeneintragen;y6END IF.y6:SELECTm6OF CASE1:z6CASE2:a7CASE3:b7END SELECT.z6:c7(FALSE).a7:e6;REPc7(k1);cout(satznummer)UNTILsatzausgewaehltORsatznummer=1ORh6END REP;g6.b7:INT VARs6:=satznr(x0(a1).h0);WHILEt6ANDa1<>1REPd7;s6:=maxint-1END REP;aufsatz(x0(a1).h0,e7);cout(satznummer);t5;i1:=FALSE;w6.t6:INT VARe7;x6(x0(a1),s6);IFx0(a1).p0=1THENe7:=1;TRUE ELSEe7:=x0(a1).o0ISUB(
+x0(a1).p0-1);FALSE END IF.END PROCzurueck;PROCr6(BOOL CONSTf7):g7;IFh7THENo6;t5ELSEf1INCR1END IF;w6.g7:INT VARs2:=b1;WHILEs2>0REPi7;s2:=x0(s2).e0END REP.i7:BOOL VARj7;k7(x0(s2),j7);IFj7THEN LEAVEg7END IF.h7:s2=0.o6:IFf7THENweiter(x0(a1).h0,l1)ELSEweiter(x0(a1).h0)END IF;WHILEdateiende(x0(a1).h0)REPl7UNTILi1END REP.l7:IFx0(a1).e0<>0THENu6;m7ELSEi1:=TRUE END IF.m7:aufsatz(x0(a1).h0,1).END PROCr6;PROCk7(DATEI VARq0,BOOL VARj7):IFdateiende(q0.h0)THENj7:=FALSE ELSEn7END IF.n7:j7:=TRUE;REPweiter(q0.h0,q0.n0);IFdateiende(q0.h0)THENj7:=FALSE;aufsatz(q0.h0,q0.n0)END IF UNTILs5(q0)END REP.END PROCk7;PROCc7(BOOL CONSTf7):WHILEsatznr(x0(a1).h0)=1CANDsatznummer>1REPd7;o7(x0(a1).h0)END REP;IFf7THENzurueck(x0(a1).h0,l1)ELSEzurueck(x0(a1).h0)END IF;i1:=FALSE;t5;w6END PROCc7;PROCu6:e1INCRsaetze(x0(a1).h0);a1:=x0(a1).e0END PROCu6;PROCd7:INT VARp7:=1;WHILEx0(p7).e0<>a1REPp7:=x0(p7).e0END REP;e1DECRsaetze(x0(p7).h0);a1:=p7END PROCd7;PROCaenderungeneintragen:INT VARs2:=b1;WHILEs2<>0REPq7;s2:=x0(s2).e0END 
+REP.q7:IFx0(s2).j0THENr7(x0(s2))END IF.END PROCaenderungeneintragen;PROCr7(DATEI VARq0):IFs7AND NOTt7THENu7ELIFv7ANDw7THENx7ELIFt7THENl3(q0)END IF;y7;k0:=FALSE;t7:=FALSE.s7:NOTdateiende(q0.h0)ANDk0.v7:felderzahl(i0)>q0.d0.w7:t7ORk0.x7:l0:=TRUE;feldlesen(i0,1,q0.n0);satzeinfuegen(q0.h0,i0).y7:q0.j0:=FALSE.u7:l0:=TRUE;satzaendern(q0.h0,i0).k0:q0.k0.t7:q0.m0.i0:q0.i0.l0:q0.l0.END PROCr7;PROCo7(EUDAT VARh0):aufsatz(h0,saetze(h0)+1)END PROCo7;PROCaufsatz(INT CONSTsatznr):aenderungeneintragen;a1:=e4;e1:=0;WHILEz7ANDa8REPu6END REP;aufsatz(x0(a1).h0,satznr-e1);t5;i1:=dateiende(x0(a1).h0);w6.z7:satznr-e1>saetze(x0(a1).h0).a8:x0(a1).e0<>0.END PROCaufsatz;INT PROCsatznummer:e1+satznr(x0(a1).h0)END PROCsatznummer;INT PROCsatzkombination:f1END PROCsatzkombination;BOOL PROCdateiende:i1END PROCdateiende;SATZ VARb8;satzinitialisieren(b8);PROCsatzeinfuegen:aenderungeneintragen;c8;satzeinfuegen(x0(a1).h0,b8);x0(a1).l0:=TRUE;d8;i1:=FALSE;w6.c8:x6(x0(a1),satznr(x0(a1).h0));f2(x0(a1).o0,x0(a1).p0,1).d8:f1
+:=1;INT VARs2:=b1;WHILEs2<>0REPo7(x0(s2).h0);s2:=x0(s2).e0END REP.END PROCsatzeinfuegen;PROCsatzloeschen:IF NOTi1THENaenderungeneintragen;e8;satzloeschen(x0(a1).h0);x0(a1).l0:=TRUE;aufsatz(satznummer)END IF.e8:IFsatzmarkiertTHENdelete(x0(a1).o0,x0(a1).p0);g1DECR1END IF;f2(x0(a1).o0,x0(a1).p0,-1).END PROCsatzloeschen;LETf8=100;ROWf8STRUCT(INTr0,g8,h8,i8,TEXTn0)VARj8;SATZ VARn4;INT VARl4,k8,l8:=1;BOOL VARm8,n8;suchbedingungloeschen;INT VARo8;LETp8=1,q8=2,r8=3,s8=4,t8=5,u8=6,v8=7,w8=8,x8=9;PROCw6:IFi1THENn8:=FALSE ELSEy8;n8:=z8END IF.y8:o8:=k8;WHILEo8>0REPa9;feldbearbeiten(b9,PROC(TEXT CONST,INT CONST,INT CONST)c9)END REP.a9:INT VARd9:=j8(o8).g8;IFd9>=256THENe9;f9END IF.e9:feldlesen((d9AND255)+1,z1).f9:IFg9=2THENh9END IF;j8(o8).n0:=z1.b9:j8(o8).r0.z8:o8<0.END PROCw6;PROCc9(TEXT CONSTy5,INT CONSTi9,j9):INT VARd9:=j8(o8).g8;IFd9>=256THENd9:=d9DIV256END IF;IFk9THENo8:=j8(o8).h8ELSEo8:=j8(o8).i8END IF.k9:SELECTd9OF CASEp8:l9CASEq8:m9CASEr8:n9CASEs8:o9CASEt8:p9CASEu8:q9CASEv8:r9CASEw8:s9CASEx8
+:t9OTHERWISE FALSE END SELECT.l9:SELECTg9OF CASE0:u9;z1LEXEQUALn0CASE1:u9;v9=w9OTHERWISElength(n0)=j9-i9+1ANDx9END SELECT.x9:i9>j9CORm9.m9:pos(y5,n0,i9,j9)=i9.n9:pos(y5,n0,j9+1-length(n0),j9)>0.o9:pos(y5,n0,i9,j9)>0.p9:u9;SELECTg9OF CASE0:n0LEXGREATERz1CASE1:v9<w9CASE2:h9;z1<n0OTHERWISEz1<n0END SELECT.q9:u9;SELECTg9OF CASE0:z1LEXGREATEREQUALn0CASE1:v9>=w9CASE2:h9;z1>=n0OTHERWISEz1>=n0END SELECT.r9:i9<=j9.s9:satzmarkiert.t9:TRUE.u9:z1:=subtext(y5,i9,j9).END PROCc9;TEXT PROCn0:j8(o8).n0END PROCn0;PROCh9:IFlength(z1)=8THEN TEXT CONSTy9:=subtext(z1,7,8);replace(z1,7,subtext(z1,1,2));replace(z1,1,y9)ELSEz1:=s0END IF END PROCh9;INT PROCg9:feldinfo(j8(o8).r0)END PROCg9;REAL PROCv9:REAL VARz9;wertberechnen(z1,z9);z9END PROCv9;REAL PROCw9:REAL VARz9;wertberechnen(n0,z9);z9END PROCw9;LETa10=";",b10=",",c10="..",d10="++",e10="--",f10="*";BOOL VARg10,h10,i10;INT VARj10,k10,l10,m10,n10;INTVEC VARm4;PROCsuchbedingung(INT CONSTd3,TEXT CONSTj8):INT VARr2:=1,o10:=0;INT CONSTp10:=length(j8)+1;k10:=0;n10
+:=d3;j10:=l4+1;WHILEr2<p10REPq10;r10;r2:=z5+2END REP;feldaendern(n4,d3,j8).q10:INT VARs10:=pos(j8,b10,r2);IFs10=0THENs10:=p10END IF;IFo10<r2THENt10END IF;INT CONSTz5:=min(s10,o10)-1.t10:k10INCR1;g10:=TRUE;IFk10>1THENk1:=FALSE END IF;o10:=pos(j8,a10,r2);IFo10=0THENo10:=p10END IF.r10:u10;h10:=TRUE;INT CONSTv10:=pos(j8,c10,r2,z5+1);IFw10THENx10(s0,x8,-k10)ELIFv10=0THENy10ELSEz10END IF.u10:IFsubtext(j8,r2,r2+1)=e10THENr2INCR2;i10:=TRUE ELSEi10:=FALSE END IF.w10:r2>z5.y10:IFa11THENb11ELSEc11END IF.a11:r2+1=z5CANDsubtext(j8,r2,z5)=d10.b11:x10(s0,w8,-k10).c11:INT VARd11:=pos(j8,f10,r2,z5+1);IFd11=0THENe11ELIFr2=z5THENf11ELSEg11;REPh11END REP END IF.e11:IFi11THENk1:=TRUE;l1:=j8END IF;x10(subtext(j8,r2,z5),p8,-k10).i11:d3=1ANDr2=1ANDz5=p10-1ANDj11AND NOTn2AND(j8SUB1)<>"&".j11:length(m4)<=2.f11:x10(s0,v8,-k10).g11:INT VARg8;IFd11=r2THENg8:=p8ELSEg8:=q8END IF.h11:IFg8<>p8THENk11END IF;r2:=d11+1;d11:=pos(j8,f10,r2,z5+1);IFd11=0THENd11:=z5+1;g8:=r8ELSEg8:=s8END IF.k11:TEXT CONSTn0:=subtext(j8,r2,
+d11-1);IFi10ORl11THEN IFi10THENh10:=TRUE END IF;x10(n0,g8,-k10);IFl11THEN LEAVEc11END IF ELSEx10(n0,g8,l4+2)END IF.l11:d11>=z5.z10:TEXT CONSTm11:=subtext(j8,r2,v10-1),n11:=subtext(j8,v10+2,z5);IFv10=r2THENx10(n11,t8,-k10)ELIFv10=z5-1THENx10(m11,u8,-k10)ELSEo11END IF.o11:IFi10THENx10(m11,u8,-k10);h10:=TRUE ELSEx10(m11,u8,l4+2)END IF;x10(n11,t8,-k10).END PROCsuchbedingung;PROCx10(TEXT CONSTp11,INT CONSTg8,h8):q11;r11;IFg10THENs11;t11;m10:=l4ELIFh10THENu11END IF;v11;w11.q11:m8:=FALSE;IFl4=d4THENl8INCR1;IFl8>32000THENl8:=1END IF END IF.r11:IFl4=f8THENsuchbedingungloeschen;errorstop(y1)ELSEl4INCR1;k8:=d4+1END IF.s11:IFk10>length(m4)DIV2THENm4CATl4;x11(k8,0,l4)END IF;IFk10=length(m4)DIV2THENl10:=0ELSEl10:=m4ISUB(k10+1)END IF.t11:x11(k8,-k10,l4);g10:=FALSE;h10:=FALSE.u11:x11(m10,l10,l4);m10:=l4;h10:=FALSE.v11:j8(l4).g8:=g8;j8(l4).r0:=n10;IFi10THENj8(l4).h8:=l10;j8(l4).i8:=h8ELSEj8(l4).h8:=h8;j8(l4).i8:=l10END IF.w11:IFy11THENz11ELSEa12END IF.y11:(p11SUB1)="&"CANDb12.b12:INT
+CONSTc12:=feldnummer
+(subtext(p11,2));c12>0.z11:j8(l4).g8:=c12-1+256*g8.a12:INT CONSTd12:=feldinfo(n10);IFd12=2AND(g8=t8ORg8=u8)THENz1:=p11;h9;j8(l4).n0:=z1ELSEj8(l4).n0:=p11END IF.END PROCx10;PROCx11(INT CONSTi9,wert,e12):INT VARi2;FORi2FROMi9UPTOl4-1REP IFj8(i2).h8=wertTHENj8(i2).h8:=e12ELIFj8(i2).i8=wertTHENj8(i2).i8:=e12END IF END REP END PROCx11;PROCsuchbedingunglesen(INT CONSTd3,TEXT VARj8):feldlesen(n4,d3,j8)END PROCsuchbedingunglesen;PROCsuchbedingungloeschen:disablestop;IFn2THENl4:=d4ELSEd4:=0;l4:=0END IF;k8:=-1;m4:=t0;satzinitialisieren(n4);k1:=FALSE;m8:=TRUE;n8:=NOTi1END PROCsuchbedingungloeschen;BOOL PROCsatzausgewaehlt:IF NOTm8THENw6;m8:=TRUE END IF;n8END PROCsatzausgewaehlt;INT PROCsuchversion:IFl4=d4THEN0ELSEl8END IF END PROCsuchversion;PROCx6(DATEI VARq0,INT CONSTy5):IF(q0.o0ISUBq0.p0)<y5THENf12ELSEg12END IF.f12:REPq0.p0INCR1UNTIL(q0.o0ISUBq0.p0)>=y5END REP.g12:WHILEq0.p0>1CAND(q0.o0ISUB(q0.p0-1))>=y5REPq0.p0DECR1END REP.END PROCx6;PROCmarkierungaendern:disablestop;IFsatzmarkiertTHENdelete(
+x0(a1).o0,x0(a1).p0);g1DECR1ELSEinsert(x0(a1).o0,x0(a1).p0,satznr(x0(a1).h0));g1INCR1END IF END PROCmarkierungaendern;BOOL PROCsatzmarkiert:INT CONSTy5:=satznr(x0(a1).h0);x6(x0(a1),y5);y5=(x0(a1).o0ISUBx0(a1).p0)END PROCsatzmarkiert;INT PROCmarkiertesaetze:g1END PROCmarkiertesaetze;PROCmarkierungenloeschen:disablestop;IFn2THENp2(x0(a1))ELSEh12END IF;g1:=0.h12:INT VARs2:=1;REPp2(x0(s2));s2:=x0(s2).e0UNTILs2=0END REP.END PROCmarkierungenloeschen;PROCp2(DATEI VARq0):q0.o0:=s0;q0.o0CATmaxint;q0.p0:=1END PROCp2;END PACKETdatenverwaltung;
+
diff --git a/eudas/eudas.2 b/eudas/eudas.2
new file mode 100644
index 0000000..0048409
--- /dev/null
+++ b/eudas/eudas.2
@@ -0,0 +1,62 @@
+PACKETverarbeitungDEFINESkopiere,stdkopiermuster,verarbeite,trage,eindeutigefelder,pruefe,wertemenge,feldmaske,tragesatz,holesatz,K,V,f,wert,zahltext,textdarstellung:SATZ VARb0,c0,d0;INT VARe0;BOOL VARf0;LETg0="",INTVEC=TEXT;INTVEC VARh0;TEXT VARi0:="  ";OP CAT(INTVEC VARj0,INT CONSTk0):replace(i0,1,k0);j0CATi0END OP CAT;PROCstdkopiermuster(TEXT CONSTl0,FILE VARm0):n0;INT VARo0;p0;q0;INT VARr0;FORr0FROM1UPTOo0REPs0;IFt0THENu0ELSEv0END IF END REP.p0:output(m0);EUDAT VARw0;IFexists(l0)THENoeffne(w0,l0)END IF.q0:IFexists(l0)CANDfelderzahl(w0)>0THENfeldnamenlesen(w0,b0);o0:=felderzahl(w0)ELSEx0;o0:=anzahlfelderEND IF.x0:TEXT VARy0;satzinitialisieren(b0);FORr0FROM1UPTOanzahlfelderREPfeldnamenlesen(r0,y0);feldaendern(b0,r0,y0)END REP.t0:feldnummer(y0)>0.s0:feldlesen(b0,r0,y0);put(m0,textdarstellung(y0)).u0:write(m0,"K f(");write(m0,textdarstellung(y0));putline(m0,");").v0:putline(m0,"K """";").END PROCstdkopiermuster;PROCkopiere(TEXT CONSTl0,FILE VARm0):z0(a1,m0).a1:"kopiere ("+
+textdarstellung(l0)+", ".END PROCkopiere;PROCz0(TEXT CONSTb1,FILE VARc1):d1;write(e1,b1);putline(e1,"PROC programmfunktion);");putline(e1,"PROC programmfunktion:");f1;putline(e1,"END PROC programmfunktion");g1;forget(h1,quiet).d1:TEXT VARh1;INT VARi1:=0;REPi1INCR1;h1:=text(i1)UNTIL NOTexists(h1)END REP;disablestop;FILE VARe1:=sequentialfile(output,h1);headline(e1,j1).f1:TEXT VARk1;input(c1);WHILE NOTeof(c1)REPgetline(c1,k1);putline(e1,k1)END REP.g1:TEXT CONSTl1:=std;run(h1);lastparam(l1).END PROCz0;PROCkopiere(TEXT CONSTl0,PROCm1):enablestop;INT VARn1;o1(n1);IFdateiendeTHENaufsatz(1);LEAVEkopiereELSEp1END IF;WHILE NOTdateiendeREPsatzinitialisieren(d0);e0:=1;m1;q1;satzeinfuegen(w0,d0);weiter(w0);weiter(n1)END REP;aufsatz(1).p1:f0:=TRUE;EUDAT VARw0;oeffne(w0,l0);aufsatz(w0,saetze(w0)+1);feldnamenlesen(w0,c0);h0:=g0.q1:IFf0THENfeldnamenaendern(w0,c0);f0:=FALSE END IF END PROCkopiere;OP K(TEXT CONSTy0,r1):IFf0THENs1;END IF;feldaendern(d0,h0ISUBe0,r1);e0INCR1.s1:INT VARt1:=feldindex(c0,y0);
+IFt1=0THENt1:=felderzahl(c0)+1;feldaendern(c0,t1,y0);END IF;h0CATt1.END OP K;PROCverarbeite(FILE VARu1):z0("verarbeite (",u1)END PROCverarbeite;PROCverarbeite(PROCv1):enablestop;INT VARn1;o1(n1);WHILE NOTdateiendeREPv1;weiter(n1)END REP;aufsatz(1)END PROCverarbeite;OP V(TEXT CONSTy0,r1):INT CONSTw1:=feldnummer(y0);IFw1=0THENx1(y0)ELSEfeldaendern(w1,r1)END IF END OP V;PROCo1(INT VARn1):n0;aufsatz(1);IFmarkiertesaetze>0THENn1:=3;IF NOTsatzmarkiertTHENweiter(n1)END IF ELSEn1:=2;IF NOTsatzausgewaehltTHENweiter(n1)END IF END IF END PROCo1;PROCn0:IFanzahldateien=0THENerrorstop(y1)END IF.END PROCn0;TEXT VARz1,a2;LETb2="""";TEXT PROCf(TEXT CONSTy0):INT CONSTw1:=feldnummer(y0);IFw1=0THENx1(y0);z1:=g0ELSEfeldlesen(w1,z1)END IF;z1END PROCf;REAL PROCwert(TEXT CONSTy0):INT CONSTw1:=feldnummer(y0);IFw1=0THENx1(y0);0.0ELSEfeldlesen(w1,z1);REAL VARc2;wertberechnen(z1,c2);c2END IF END PROCwert;REAL PROCwert(TEXT CONSTy0,INT CONSTd2):round(wert(y0),d2)END PROCwert;TEXT PROCzahltext(REAL CONSTe2,INT 
+CONSTd2):REAL CONSTf2:=round(abs(e2),d2);INT VARg2:=h2+d2+2;IFe2<0.0THENa2:="-"ELSEa2:=g0END IF;IFf2<1.0ANDf2<>0.0THENa2CAT"0";g2DECR1ENDIF;a2CATtext(f2,g2,d2);IFd2>0THENchange(a2,".",dezimalkomma)ELSEchange(a2,".",g0)END IF;a2.h2:max(0,decimalexponent(f2)).END PROCzahltext;TEXT PROCzahltext(TEXT CONSTy0,INT CONSTd2):zahltext(wert(y0),d2)END PROCzahltext;TEXT PROCtextdarstellung(TEXT CONSTi2):z1:=i2;changeall(z1,b2,b2+b2);j2;insertchar(z1,b2,1);z1CATb2;z1.j2:INT VARk2:=1;WHILEl2REPchange(z1,k2,k2,m2)END REP.l2:k2:=pos(z1,""0"",""31"",k2);k2>0.m2:b2+text(code(z1SUBk2))+b2.END PROCtextdarstellung;PROCx1(TEXT CONSTy0):errorstop(n2+textdarstellung(y0)+o2)END PROCx1;SATZ VARp2;EUDAT VARq2;LETj1=#501
+#"erzeugtes Programm",y1=#502
+#"keine Datei geoeffnet",r2=#503
+#"Kein Satz zum Tragen vorhanden",s2=#504
+#"Zieldatei hat falsche Felderzahl",t2=#505
+#" existiert nicht",u2=#506
+#" verletzt die Pruefbedingung.",v2=#507
+#" ist in der Zieldatei bereits vorhanden.",o2=#508
+#" ist nicht definiert.",w2=#509
+#" ist nicht in der Wertemenge.",x2=#510
+#" stimmt nicht mit der Maske ueberein.",y2=#511
+#"Satz ",n2=#512
+#"Das Feld ";INT VARz2;FILE VARa3;BOOL VARb3:=FALSE,c3,d3;TEXT VARe3;PROCtrage(TEXT CONSTl0,FILE VARf3,BOOL CONSTg3):disablestop;b3:=g3;IFb3THENa3:=f3;output(a3)END IF;h3(l0);b3:=FALSE END PROCtrage;PROCh3(TEXT CONSTl0):enablestop;INT VARn1;o1(n1);i3(l0);INT VARj3:=0;REP IF NOTk3THENweiter(n1)ELSEcout(satznummer+j3)END IF;IFdateiendeTHENaufsatz(1);LEAVEh3END IF;l3END REP.k3:IFn1=3THENsatzmarkiertELSEsatzausgewaehltEND IF.l3:c3:=TRUE;IFb3THENnotizenlesen(q2,1,e3);do(e3)END IF;IFc3THENm3;IFc3THENsatzloeschen;j3INCR1END IF END IF;IF NOTc3THENweiter(n1)END IF.END PROCh3;PROCi3(TEXT CONSTl0):IFdateiendeTHENerrorstop(r2)END IF;oeffne(q2,l0);z2:=0;IFfelderzahl(q2)=0THENp1ELIFfelderzahl(q2)<>anzahlfelderTHENerrorstop(s2)END IF;aufsatz(q2,saetze(q2)+1).p1:satzinitialisieren(p2,anzahlfelder);INT VARr0;FORr0FROM1UPTOanzahlfelderREPfeldnamenlesen(r0,z1);feldaendern(p2,r0,z1)END REP;feldnamenaendern(q2,p2).END PROCi3;PROCm3:IFz2>0CANDn3THENo3("",v2)ELSEp3;satzeinfuegen(q2,p2);weiter(q2)END IF.p3:
+satzinitialisieren(p2,anzahlfelder);INT VARr0;FORr0FROM1UPTOanzahlfelderREPfeldlesen(r0,z1);feldaendern(p2,r0,z1)END REP.n3:TEXT VARc1;INT CONSTq3:=satznr(q2);feldlesen(1,c1);d3:=FALSE;aufsatz(q2,c1);WHILE NOTdateiende(q2)REPr3;weiter(q2,c1)UNTILd3END REP;aufsatz(q2,q3);d3.r3:INT VARi1;d3:=TRUE;FORi1FROM2UPTOz2REPfeldlesen(q2,i1,z1);feldbearbeiten(i1,PROC(TEXT CONST,INT CONST,INT CONST)s3);IF NOTd3THEN LEAVEr3END IF END REP.END PROCm3;PROCs3(TEXT CONSTt3,INT CONSTu3,v3):IFw3COR(length(z1)>0CANDx3)THENd3:=FALSE END IF.w3:(v3-u3+1)<>length(z1).x3:pos(t3,z1,u3,v3+1)<>u3.END PROCs3;PROCo3(TEXT CONSTy3,z3):IFb3THENa4ELSEerrorstop(z3)END IF.a4:put(a3,y2);put(a3,satznummer);IFy3<>""THENwrite(a3,n2);write(a3,textdarstellung(y3))END IF;putline(a3,z3);c3:=FALSE.END PROCo3;PROCeindeutigefelder(INT CONSTb4):z2:=b4END PROCeindeutigefelder;PROCpruefe(TEXT CONSTy3,BOOL CONSTc4):IF NOTc4THENo3(y3,u2)END IF END PROCpruefe;PROCwertemenge(TEXT CONSTy3,d4):INT CONSTw1:=feldnummer(y3);IFw1=0THENo3(y3,o2)
+ELSEe4END IF.e4:INT VARk2:=0;LETf4=",";feldlesen(w1,z1);IFg4THEN LEAVEe4END IF;z1CATf4;REPk2:=pos(d4,z1,k2+1);IFk2=1ORk2>1CAND(d4SUBk2-1)=f4THEN LEAVEe4END IF UNTILk2=0END REP;o3(y3,w2).g4:INT CONSTh4:=length(d4)-length(z1);(d4SUBh4)=f4ANDpos(d4,z1,h4+1)>0.END PROCwertemenge;PROCfeldmaske(TEXT CONSTy3,i4):INT CONSTw1:=feldnummer(y3);IFw1=0THENo3(y3,o2)ELSEfeldlesen(w1,z1);j4END IF.j4:INT VARk2;TEXT CONSTk4:=code(length(i4)+1);TEXT VARl4:=""1"";FORk2FROM1UPTOlength(z1)REP TEXT CONSTm4:=z1SUBk2;n4UNTILl4=""END REP;IFo4THENo3(y3,x2)END IF.n4:INT VARp4:=1;WHILEp4<=length(l4)REP INT CONSTq4:=code(l4SUBp4);IF(i4SUBq4)="*"THENr4ELIFs4THENreplace(l4,p4,code(q4+1));p4INCR1ELSEdeletechar(l4,p4)END IF END REP.r4:IFq4=length(i4)THEN LEAVEfeldmaskeEND IF;p4INCR1;IFpos(l4,code(q4+1))=0THENinsertchar(l4,code(q4+1),p4)END IF.s4:SELECTpos("9XAa",i4SUBq4)OF CASE1:pos("0123456789",m4)>0CASE2:TRUE CASE3:pos("ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ",m4)>0CASE4:pos("abcdefghijklmnopqrstuvwxyzäöüß",m4)>0OTHERWISE(i4
+SUBq4)=m4END SELECT.o4:(l4=""CORpos(l4,k4)=0)ANDt4.t4:(i4SUBlength(i4))<>"*"ORpos(l4,code(length(i4)))=0.END PROCfeldmaske;PROCtragesatz(TEXT CONSTl0):i3(l0);INT CONSTu4:=satznr(q2);m3;satzloeschen;aufsatz(q2,u4)END PROCtragesatz;PROCholesatz(TEXT CONSTl0):n0;IF NOTexists(l0)THENerrorstop(textdarstellung(l0)+t2)END IF;oeffne(q2,l0);IFfelderzahl(q2)<>anzahlfelderTHENerrorstop(s2)ELIFsaetze(q2)=0THENerrorstop(r2)END IF;aufsatz(q2,saetze(q2));satzlesen(q2,p2);v4;satzloeschen(q2).v4:satzeinfuegen;INT VARr0;FORr0FROM1UPTOfelderzahl(p2)REPfeldlesen(p2,r0,z1);feldaendern(r0,z1)END REP.END PROCholesatz;END PACKETverarbeitung;
+PACKETeudasdruckenDEFINESdrucke,interpretiere,gruppentest,druckdatei,direktdrucken,maxdruckzeilen,gruppenwechsel,lfdnr:LETb0=25,SPEICHER=STRUCT(INTc0,d0,e0,f0,TEXTg0);ROWb0SPEICHER VARh0;INT VARi0;LETj0="",k0=" ",l0="  ";TEXT VARm0;PROCinterpretiere(INT CONSTn0,o0,PROC(INT CONST,TEXT VAR)p0):INT VARq0,r0:=0,s0:=0,t0:=o0;u0(n0);WHILE NOTv0REPw0;IFx0THENr0INCR1ELSEy0;z0END IF END REP.z0:IFa1(q0)THENb1ELSEc1;s0:=0END IF.b1:SELECTq0OF CASEd1:e1CASEf1:g1OTHERWISE LEAVEinterpretiereEND SELECT.y0:WHILEr0>0REPh1(k0);r0DECR1END REP.e1:i1(i0).g1:i1(s0).x0:j1=j0ORj1=k0.c1:INT VARk1:=0,l1:=0;BOOL VARm1:=FALSE;REPn1;k1INCR1;IFi0=3THENm1:=TRUE END IF UNTILo1END REP.o1:IFi0<=2THEN TRUE ELIFs0<>0THENk1=s0ELSEl1=0END IF.n1:INT VARp1:=1,q1:=0,r1:=0,s1:=1,t1:=1;m0:=j0;REP IFu1THENv1END IF;IFw1THENx1END IF;y1;s1INCR1END REP.u1:k1=0.v1:z1(a2.c0,a2.d0,a2.e0);IF NOTb2THENc2END IF.b2:a2.c0>length(j1).c2:INT CONSTd2:=e2(t0);IFd2>0THENfeldlesen(d2,a2.g0)ELSEp0(-d2,a2.g0)END IF;t0INCR1;a2.f0:=0;IFa2.g0<>j0THENl1
+INCR1END IF.w1:a2.e0>=4.a2:h0(s1).y1:INT CONSTreserve:=f2(a2);IFreserve>0THENg2ELSEr1DECRreserveEND IF.g2:q1INCRreserve;IFh2ANDq1>r1THENq1:=r1END IF;IFi2ANDj2THENk2END IF.h2:i0=2ORi0=4.i2:reserve=a2.d0.j2:(a2.e0AND1)=0.k2:IFa2.c0=1COR(j1SUB(a2.c0-1))=k0THEN INT VARl2:=m2(s1);WHILE(j1SUBl2)=k0REPl2INCR1;a2.d0INCR1;q1INCR1END REP END IF.x1:IFs1=1THEN IFb2THENn2END IF ELSEo2END IF.n2:IFm1THENh1(k0)ELSEh1(j1)END IF;LEAVEn1.o2:INT VARp2:=0,q2:=a2.c0;INT CONSTr2:=q2-length(j1);s2;t2;u2;v2.s2:IFr2>0THENq1INCRr2;q2DECR(r2-1)END IF;w2.w2:INT CONSTx2:=m2(s1-1),y2:=pos(j1,l0,x2,q2);IFy2>0THENq2:=y2;z2ELIFr2<0AND(j1SUB(q2-1))<>k0THENq2:=x2END IF.z2:INT VARa3:=q2+1;REPp2INCR1;a3INCR1UNTIL(j1SUBa3)<>k0END REP;q1INCRp2.t2:INT VARb3:=0;WHILEt1<s1REPc3;d3;e3;t1INCR1END REP.c3:INT CONSTc0:=f3.c0,d0:=f3.d0,e0:=f3.e0.d3:g3(p1,c0,m1);p1:=c0+d0.f3:h0(t1).e3:INT CONSTh3:=-f2(f3);IFh3=-d0ANDi3THENj3ELIFh3<=0THENk3ELIFi3ANDl3THENm3ELSEn3END IF.j3:b3INCRh3;IFh2THENo3END IF.o3:IFb3<0THENp3(-b3);b3:=0END IF.k3:IF
+q3THENp3(-h3)END IF;r3(f3);l1DECR1;IFs3THENt3ELSEb3INCRh3;u3END IF.q3:(e0AND2)=2.s3:(e0AND1)=1.t3:IF NOTq3THENp3(-h3)END IF.u3:IFh2ANDb3<0THENp3(-b3);b3:=0END IF.i3:NOTs3.l3:h3<=q1.m3:r3(f3);l1DECR1;b3INCRh3;q1DECRh3.n3:INT VARv3:=0,w3:=f3.f0+1,x3:=w3+d0-1;IFi3THENx3INCRq1END IF;IFq3ANDy3THENz3ELIFa4THENb4END IF;c4;IFi3THENb3INCRq1;q1:=0END IF.z3:INT CONSTd4:=length(f3.g0)-x3;w3INCRd4;x3INCRd4.a4:i0>=3.y3:NOTa4.c4:IFq3THENp3(v3)END IF;e4(f3.g0,w3,x3);IFf4THENp3(v3)END IF.f4:NOTq3.b4:IFpos(f3.g0,k0,w3,x3)>0THENg4END IF;INT CONSTh4:=pos(f3.g0,"!","�",x3+1);IFh4=0THENf3.f0:=length(f3.g0);l1DECR1ELSEf3.f0:=h4-1END IF.g4:x3INCR1;v3DECR1;WHILE(f3.g0SUBx3)<>k0REPx3DECR1;v3INCR1END REP;WHILE(f3.g0SUBx3)=k0REPx3DECR1;v3INCR1UNTILl2<w3END REP.u2:g3(p1,q2,m1);IFb3<0THEN IFq2<=length(j1)THENp3(-b3)END IF;p1:=q2ELSEp1:=q2+min(b3,p2)END IF.v2:IFr2>0THENi4;j4;LEAVEn1ELSEk4END IF.i4:IF NOTm1THENe4(j1,p1,length(j1))END IF.j4:INT VARl4:=length(m0);IF(m0SUBl4)=k0THEN REPl4DECR1UNTIL(m0SUBl4)<>k0END REP;
+m0:=subtext(m0,1,l4)END IF;IFm4THENm0CATk0END IF;h1(m0).m4:(j1SUB LENGTHj1)=k0AND(i0<>3ORl1=0).k4:q1:=0;r1:=0.END PROCinterpretiere;INT PROCm2(INT CONSTn4):h0(n4).c0+h0(n4).d0END PROCm2;INT PROCf2(SPEICHER CONSTo4):o4.d0-length(o4.g0)+o4.f0END PROCf2;LETp4="          ";PROCp3(INT CONSTq4):INT VARr4:=q4;WHILEr4>=10REPm0CATp4;r4DECR10END REP;WHILEr4>0REPm0CATk0;r4DECR1END REP END PROCp3;PROCr3(SPEICHER VARo4):IFo4.f0=0THENm0CATo4.g0ELSEe4(o4.g0,o4.f0+1,length(o4.g0))END IF;o4.f0:=length(o4.g0)END PROCr3;PROCg3(INT CONSTs4,t4,BOOL CONSTm1):IFm1THENp3(t4-s4)ELSEe4(j1,s4,t4-1)END IF END PROCg3;TEXT VARu4;PROCe4(TEXT CONSTv4,INT CONSTs4,t4):u4:=subtext(v4,s4,t4);m0CATu4END PROCe4;FILE VARw4;TEXT VARj1;INT VARx4;LETy4=#401
+#"keine schliessende Klammer in Feldmuster",z4=#402
+#"kein Kommando in Kommandozeile",a5=#403
+#"unbekanntes Kommando";LETb5="&",c5="%",d5="%",e5="<",f5=">";LETg5=#404
+#" "1"VOR "1"VORSPANN "2"WDH "2"WIEDERHOLUNG "3"NACH "3"NACHSPANN "4"ABK "4"ABKUERZUNGEN "5"GRUPPE "6"MODUS "7"MEHR "LETh5=1,i5=2,j5=3,k5=4,l5=5,d1=6,f1=7,m5=100;INT VARn5,o5,p5;BOOL VARv0,q5;.r5:lineno(w4).s5:n5:=maxlinelength(w4).PROCt5(TEXT CONSTu5):REPx4INCR1UNTIL(j1SUBx4)<>u5END REP END PROCt5;PROCz1(INT VARw3,v5,e0):w5;IFb2THENw3:=max(n5,length(j1))+1;v5:=0;e0:=5ELSEw3:=x4;x5END IF.w5:y5(b5,c5).b2:x4>length(j1).x5:TEXT CONSTz5:=j1SUBx4;IFz5=c5THENe0:=0ELSEe0:=4END IF;a6;feldnamenlesen;b6.a6:t5(z5);IFx4-1>w3THENc6END IF.c6:e0INCR3.feldnamenlesen:IF(j1SUBx4)=e5THENd6ELSEe6END IF;IFf6THENz1(w3,v5,e0);LEAVEz1END IF.f6:o5>p5.d6:o5:=x4+1;p5:=pos(j1,f5,o5);IFp5=0THENg6(y4,subtext(j1,x4));p5:=length(j1)ELSEp5DECR1END IF;x4:=p5+2.e6:o5:=x4;y5(k0,c5);INT CONSTh6:=pos(j1,b5,o5,x4);IFh6>0THENx4:=h6END IF;p5:=x4-1.b6:IFi6THENj6;t5(z5)END IF;v5:=x4-w3.i6:(j1SUBx4)=z5.j6:e0:=e0OR1.END PROCz1;PROCz1(TEXT VARname):INT VARk6,v5,l6;z1(k6,v5,l6);IFv5>0THENname:=subtext(j1,o5,p5)ELSEname:=j0END IF 
+END PROCz1;PROCy5(TEXT CONSTm6,n6):INT CONSTo6:=pos(j1,m6,x4),p6:=pos(j1,n6,x4);x4:=length(j1)+1;IFo6>0THENx4:=o6END IF;IFp6>0ANDp6<x4THENx4:=p6END IF END PROCy5;PROCu0(INT CONSTq6):toline(w4,q6);q5:=FALSE;v0:=eof(w4)END PROCu0;PROCw0:IFq5THENdown(w4)ELSEq5:=TRUE END IF;readrecord(w4,j1);x4:=1;v0:=lineno(w4)>=lines(w4)END PROCw0;BOOL PROCa1(INT VARq0):x4:=1;IF(j1SUB1)<>d5THEN FALSE ELIF(j1SUB2)<>d5THENr6;s6;TRUE ELSEq0:=m5;TRUE END IF.r6:TEXT VARt6;t5(k0);IFx4>length(j1)THENg6(z4,j1);q0:=0;LEAVEa1WITH TRUE END IF;INT CONSTu6:=pos(j1,k0,x4);IFu6=0THENt6:=subtext(j1,x4);t6CATk0;x4:=length(j1)+1ELSEt6:=subtext(j1,x4,u6);x4:=u6END IF.s6:INT CONSTv6:=pos(g5,t6);IFv6>0CAND(g5SUB(v6-2))=k0THENq0:=code(g5SUB(v6-1))ELSEq0:=0;g6(a5,t6);END IF.END PROCa1;PROCi1(INT VARw6):t5(k0);INT CONSTx6:=x4;WHILEy6REPx4INCR1END REP;IFx4>x6THENw6:=int(subtext(j1,x6,x4-1))ELSEw6:=-1END IF.y6:pos("0123456789",j1SUBx4)>0.END PROCi1;FILE VARz6;TEXT VARa7;BOOL VARb7;PROCc7(TEXT CONSTname):a7:=name;d7("PROC ",name,
+" :")END PROCc7;PROCe7:d7("END PROC ",a7,";")END PROCe7;PROCf7(TEXT CONSTg7):b7:=TRUE;putline(z6,g7)END PROCf7;PROCf7(TEXT CONSTh7,i7,j7):b7:=TRUE;d7(h7,i7,j7)END PROCf7;PROCd7(TEXT CONSTh7,i7,j7):write(z6,h7);write(z6,i7);write(z6,j7);line(z6)END PROCd7;TEXT VARk7;PROCf7(TEXT CONSTh7,INT CONSTl7,TEXT CONSTj7):k7:=subtext(j1,l7);f7(h7,k7,j7)END PROCf7;PROCm7(INT CONSTq6,n7):d7(";  interpretiere (",text(q6)+", "+text(n7),", PROC (INT CONST, TEXT VAR) abk);")END PROCm7;LETo7=#405
+#"kein % WIEDERHOLUNG gefunden",p7=#406
+#"Nur GRUPPE-Anweisung erlaubt",q7=#407
+#"keine ELAN-Anweisung im Initialisierungsteil nach Gruppendefinition",r7=#408
+#"illegale Gruppennummer",s7=#409
+#"diese Gruppe wurde schon definiert",t7=#410
+#"diese Abkuerzung ist nicht definiert",u7=#411
+#"dieser Abschnitt wurde schon einmal definiert",v7=#412
+#"falscher Modus",w7=#413
+#"diese Anweisung darf im Musterteil nicht vorkommen",x7=#414
+#"im Abkuerzungsteil darf keine Anweisung auftreten",y7=#415
+#"in dieser Zeile stehen zu viele Feldmuster",z7=#416
+#"das Druckmuster enthaelt zu viele Feldmuster",a8=#417
+#"nach dem ""&"" soll direkt der Name einer Abkuerzung folgen",b8=#418
+#"kein Doppelpunkt nach Abkuerzung",c8=#419
+#"Abkuerzung mehrfach definiert",d8=#420
+#"das Druckmuster enthaelt zu viele Abkuerzungen";LETe8=200,f8=4,g8=250,GRUPPE=STRUCT(BOOLh8,i8,TEXTg0),ABSCHNITT=STRUCT(INTo0,n0,TEXTc7);ROWe8INT VARe2;INT VARj8;ROWf8GRUPPE VARk8;ROW3ABSCHNITT VARl8;SATZ VARp0;TEXT VARm8;INT VARn8;OP CAT(TEXT VARo8,INT CONSTwert):TEXT VARp8:="  ";replace(p8,1,wert);o8CATp8END OP CAT;PROCq8:enablestop;u0(1);r8;s8;WHILE NOTv0REPt8END REP;u8.r8:INT VARq0;INT VARv8;n8:=0;satzinitialisieren(p0);m8:=j0;j8:=0;b7:=FALSE;l8(1):=ABSCHNITT:(0,0,"vorspann");l8(2):=ABSCHNITT:(0,0,"wdh");l8(3):=ABSCHNITT:(0,0,"nachspann");FORv8FROM1UPTOf8REPk8(v8).i8:=FALSE END REP.s8:BOOL VARw8:=FALSE;REP IFv0THENg6(o7);LEAVEq8END IF;w0;IFa1(q0)THENx8END IF END REP.x8:SELECTq0OF CASEm5:y8CASEl5:z8CASEh5,i5,j5:IF NOTw8THENc7("gruppen")END IF;e7;LEAVEs8OTHERWISE IFq0>0THENg6(p7)END IF END SELECT.y8:IFw8THENg6(q7,j1)ELSEreplace(j1,1,"  ");f7(j1)END IF.z8:IF NOTw8THENc7("gruppen");w8:=TRUE END IF;INT VARa9;i1(a9);IFa9<1ORa9>f8THENg6(r7,j1)ELIFk8(a9).i8THENg6(s7,j1)ELSEk8(a9).i8:=TRUE
+;b9END IF.b9:f7("gruppentest (",text(a9),", ");f7("            ",x4,");").t8:SELECTq0OF CASEh5:c9CASEi5:d9CASEj5:e9END SELECT.c9:f9(l8(1),q0).d9:i1(g9);i1(h9);f9(l8(2),q0).e9:f9(l8(3),q0).u8:IFb7THENi9;j9END IF;k9;IFb7THENl9;m9END IF.k9:FORv8FROM1UPTOn8REP IF(m8ISUBv8)>0THENg6(t7,n9,m8ISUBv8)ELSEo9END IF END REP.n9:TEXT VARp9;feldlesen(p0,v8,p9);p9.i9:FORv8FROM1UPTO3REP IFl8(v8).n0=0THENq9END IF END REP.q9:c7(l8(v8).c7);e7.j9:f7("PROC abk (INT CONST nr, TEXT VAR inhalt) :");IFn8>0THENf7("SELECT nr OF")ELSEf7("inhalt := text (nr)")END IF.o9:TEXT CONSTr9:=text(v8);f7("CASE "+r9," : inhalt := abk",r9).l9:IFn8>0THENf7("END SELECT")END IF;f7("END PROC abk;").m9:f7("drucke (PROC gruppen, PROC vorspann, PROC wdh, PROC nachspann)").END PROCq8;PROCf9(ABSCHNITT VARs9,INT VARq0):BOOL VARt9:=TRUE;c7(s9.c7);u9;v9;w9.u9:IFs9.n0<>0THENg6(u7,j1)END IF;s9.n0:=r5+1;s9.o0:=j8+1.v9:WHILE NOTv0REPw0;IFa1(q0)THENx9ELSEy9;z9END IF END REP;a10;LEAVEf9.x9:SELECTq0OF CASEm5:replace(j1,1,"  ");f7(j1);t9:=TRUE 
+CASEh5,i5,j5:a10;LEAVEf9CASEk5:a10;LEAVEv9CASEd1:y9;INT VARb10;i1(b10);IFb10<1ORb10>4THENg6(v7,j1)END IF CASEf1:y9OTHERWISE IFq0>0THENg6(w7)END IF END SELECT.y9:IFt9THENm7(r5,j8+1);t9:=FALSE END IF.a10:e7.z9:TEXT VARname;INT VARc10:=0;REPz1(name);IFname=j0THEN LEAVEz9END IF;c10INCR1;d10END REP.d10:IFc10>=b0THENg6(y7)END IF;IFj8=e8THENg6(z7)ELSEj8INCR1END IF;e10.e10:INT VARf10:=feldnummer(name);IFf10=0THENf10:=feldindex(p0,name);IFf10=0THENg10(name,r5);e2(j8):=-n8ELSEe2(j8):=-f10END IF ELSEe2(j8):=f10END IF.w9:BOOL VARh10:=TRUE;WHILE NOTv0REPw0;IFa1(q0)THENi10ELIFj10THENk10END IF END REP.i10:SELECTq0OF CASEh5,i5,j5:LEAVEw9OTHERWISE IFq0>0THENg6(x7)END IF END SELECT.k10:IFh10THENf7(".");h10:=FALSE END IF;IFl10THENm10ELSEf7(j1)END IF.l10:(j1SUB1)=b5.m10:TEXT VARn10;z1(n10);IFn10=j0THENg6(a8,j1);LEAVEm10END IF;o10;p10.o10:LETq10=":";x4DECR1;t5(k0);IF(j1SUBx4)=q10THENx4INCR1ELSEg6(b8,j1)END IF.p10:g10(n10,0);f7(r10,x4-1,"").r10:"abk"+text(feldindex(p0,n10)).j10:j1<>j0ANDj1<>k0.END PROCf9;
+PROCg10(TEXT CONSTname,INT CONSTq6):INT CONSTs10:=feldindex(p0,name);IFs10>0THENt10ELSEu10END IF.t10:IF(m8ISUBs10)>0THENreplace(m8,s10,q6)ELIFq6=0THENg6(c8,name)END IF.u10:IFn8=g8THENg6(d8)ELSEn8INCR1END IF;m8CATq6;feldaendern(p0,n8,name).END PROCg10;LETv10=#421
+#"FEHLER in Zeile ",w10=#422
+#" bei >>",x10=#423
+#"<<";PROCg6(TEXT CONSTy10,z10,INT CONSTq6):LETa11="   ";TEXT VARb11:=v10;b11CATtext(q6);IFz10<>j0THENb11CATw10;b11CATz10;b11CATx10END IF;note(b11);noteline;note(a11);note(y10);noteline;IFonlineANDcommanddialogueTHENline;putline(b11);put(a11);putline(y10)END IF END PROCg6;PROCg6(TEXT CONSTy10):g6(y10,j0,r5)END PROCg6;PROCg6(TEXT CONSTy10,z10):g6(y10,z10,r5)END PROCg6;LETc11=#424
+#"erzeugtes Programm",d11=#425
+#"keine Datei geoeffnet",e11=#426
+#"interner Fehler",f11=#427
+#"Druckausgabe steht in",g11=#428
+#"zum Drucker geschickt.",h11=#429
+#"direkt Drucken nicht moeglich",i11=#430
+#".a$";TEXT VARj11,k11;BOOL VARl11,m11,n11,o11;FILE VARp11;INT VARg9,h9,q11,r11,s11,t11:=4000,u11;PROCdrucke:drucke(lastparam)END PROCdrucke;PROCdrucke(TEXT CONSTv11):enablestop;lastparam(v11);w4:=sequentialfile(input,v11);modify(w4);IFanzahldateien=0THENerrorstop(d11)END IF;disablestop;w11;q8;IFanythingnotedTHENnoteedit(w4)ELIFb7THENx11ELSEdrucke(PROCy11,PROCz11,PROCa12,PROCb12)END IF;forget(c12,quiet).w11:TEXT VARc12;INT VARv8:=0;REPv8INCR1;c12:=text(v8)UNTIL NOTexists(c12)END REP;z6:=sequentialfile(output,c12);headline(z6,c11).x11:run(c12);lastparam(v11).END PROCdrucke;PROCy11:END PROCy11;PROCz11:d12(1)END PROCz11;PROCa12:d12(2)END PROCa12;PROCb12:d12(3)END PROCb12;PROCd12(INT CONSTe12):IFl8(e12).n0>0THENinterpretiere(l8(e12).n0,l8(e12).o0,PROC(INT CONST,TEXT VAR)f12)END IF END PROCd12;PROCf12(INT CONSTe12,TEXT VARg0):errorstop(e11);g0:=code(e12)END PROCf12;PROCdrucke(PROCg12,PROCh12,PROCi12,PROCj12):INT VARk12,l12,m12;enablestop;n12;o12;p12;u11:=1;WHILE NOTdateiendeREPq12;cout(
+satznummer);r12;weiter(k12);s12END REP;t12;u12;aufsatz(1).o12:l12:=0;aufsatz(1);IFmarkiertesaetze>0THENk12:=3;IF NOTsatzmarkiertTHENweiter(k12)END IF ELSEk12:=2;IF NOTsatzausgewaehltTHENweiter(k12)END IF END IF.p12:INT VARv8;FORv8FROM1UPTOf8REPk8(v8).g0:=j0END REP.q12:IFl12=0THENg12;v12;w12(PROCh12)ELSEm11:=FALSE;x12;y12END IF;l12:=satznummer;m12:=satzkombination.x12:l11:=FALSE;g12.y12:IFl11THENz12(l12,m12,PROCj12)END IF;u11INCR1;IFl11THENw12(PROCh12)END IF.r12:IFh9<1THENs5ELSEn5:=h9END IF;IFq11<g9THENtoline(p11,r11)ELSEtoline(p11,s11+1);r11:=s11+1;q11:=0END IF;i0:=1;i12;q11INCR1.s12:IFs11>t11THENu12;n12END IF.t12:v12;IFl12=0THENw12(PROCj12)ELSEz12(l12,m12,PROCj12)END IF;u0(1).END PROCdrucke;PROCv12:INT VARv8;FORv8FROM1UPTOf8REPk8(v8).h8:=TRUE END REP;m11:=TRUE;l11:=TRUE END PROCv12;PROCw12(PROCs9):q11:=g9;toline(p11,s11+1);s5;i0:=1;s9END PROCw12;PROCz12(INT CONSTl12,m12,PROCj12):INT CONSTa13:=satznummer,b13:=satzkombination;aufsatz(l12);WHILEsatzkombination<>m12REPweiter(1)END REP;w12
+(PROCj12);aufsatz(a13);WHILEsatzkombination<>b13REPweiter(1)END REP END PROCz12;PROCn12:IFaktuellereditor>0THENc13ELSEd13END IF;e13.c13:p11:=editfile;IFcol>1THENsplitline(p11,col,FALSE);down(p11);col(p11,1)END IF;s11:=lineno(p11)-1.d13:IF NOTn11THENf13END IF;p11:=sequentialfile(modify,k11);maxlinelength(p11,maxlinelength(w4));s11:=lines(p11).f13:INT VARr4:=0;REPr4INCR1;k11:=headline(w4)+i11+text(r4);UNTIL NOTexists(k11)END REP.e13:u0(1);WHILE NOTv0REPg13END REP.g13:w0;INT VARq0;IFa1(q0)THENh13ELSEh1(j1)END IF.h13:IFq0<>m5ANDq0<>l5THEN LEAVEe13END IF.END PROCn12;PROCu12:IFaktuellereditor>0THEN ELIFn11THENn11:=FALSE;ELIFo11THENdisablestop;i13ELSEline;put(f11);putline(textdarstellung(k11));pause(40)END IF.i13:TEXT CONSTw6:=std;lastparam(k11);do("print (std)");IFiserrorTHENclearerror;errorstop(h11)ELSEline;put(textdarstellung(k11));putline(g11);forget(k11,quiet);pause(40)END IF;lastparam(w6).END PROCu12;PROCh1(TEXT CONSTq6):IFq11>=g9ORq11=0THENinsertrecord(p11);writerecord(p11,q6);s11INCR1
+ELSEj13END IF;down(p11).j13:IFeof(p11)THENj11:=j0;insertrecord(p11);s11INCR1ELSEreadrecord(p11,j11)END IF;k13;writerecord(p11,j11).k13:INT CONSTl13:=n5*q11;WHILElength(j11)<l13REPj11CATk0END REP;j11CATq6.END PROCh1;PROCdirektdrucken(BOOL CONSTk12):o11:=k12END PROCdirektdrucken;BOOL PROCdirektdrucken:o11END PROCdirektdrucken;PROCdruckdatei(TEXT CONSTv11):k11:=v11;n11:=TRUE END PROCdruckdatei;TEXT PROCdruckdatei:k11END PROCdruckdatei;PROCmaxdruckzeilen(INT CONSTm13):t11:=m13END PROCmaxdruckzeilen;PROCgruppentest(INT CONSTa9,TEXT CONSTn13):IFn13<>k8(a9).g0THENk8(a9).g0:=n13;k8(a9).h8:=TRUE;l11:=TRUE ELSEk8(a9).h8:=FALSE END IF END PROCgruppentest;BOOL PROCgruppenwechsel(INT CONSTa9):IFa9>0THENk8(a9).h8ELSEm11END IF END PROCgruppenwechsel;TEXT PROClfdnr:text(u11)END PROClfdnr;END PACKETeudasdrucken;
+
diff --git a/eudas/eudas.3 b/eudas/eudas.3
new file mode 100644
index 0000000..98f0fae
--- /dev/null
+++ b/eudas/eudas.3
@@ -0,0 +1,58 @@
+PACKETfensterDEFINES FENSTER,fensterinitialisieren,fenstergroessesetzen,fenstergroesse,fensterveraendert,fensterzugriff,bildschirmneu:TYPE FENSTER=STRUCT(INTb0,c0);LETd0=16,BITVEKTOR=INT,GROESSE=STRUCT(INTe0,f0,g0,h0);ROWd0STRUCT(INTi0,j0,BITVEKTORk0,GROESSEl0)VARm0;INT VARn0:=1;BITVEKTOR VARo0;INT VARp0;FORp0FROM2UPTOd0REPm0(p0).i0:=0END REP;m0(1).i0:=1;m0(1).j0:=0;m0(1).k0:=0;m0(1).l0:=GROESSE:(1,1,79,24);PROCfensterinitialisieren(FENSTER VARf):f.b0:=1;m0(1).i0INCR1;f.c0:=n0;n0INCR1;IFn0>=32000THENn0:=-32000END IF END PROCfensterinitialisieren;PROCfenstergroessesetzen(FENSTER VARf,INT CONSTe0,f0,g0,h0):INT VARq0;r0;IFq0>d0THENs0;t0;u0END IF;v0.r0:q0:=1;WHILEq0<=d0REP IFw0THEN LEAVEr0END IF;q0INCR1END REP.w0:x0.e0=e0ANDx0.f0=f0ANDx0.g0=g0ANDx0.h0=h0.x0:m0(q0).l0.s0:q0:=1;WHILEq0<=d0REP IFm0(q0).i0=0THEN LEAVEs0END IF;q0INCR1END REP;errorstop("zu viele Fenstergroessen");LEAVEfenstergroessesetzen.t0:m0(q0).i0:=0;m0(q0).j0:=0;m0(q0).l0:=GROESSE:(e0,f0,g0,h0);m0(q0).k0:=0.u0:INT VARy0;FOR
+y0FROM1UPTOd0REP IFm0(y0).i0>0THENz0END IF END REP.z0:IFa1(b1,c1)THENsetbit(m0(q0).k0,y0);setbit(m0(y0).k0,q0)ELSEresetbit(m0(y0).k0,q0)END IF.b1:m0(q0).l0.c1:m0(y0).l0.v0:m0(f.b0).i0DECR1;f.b0:=q0;m0(q0).i0INCR1.END PROCfenstergroessesetzen;BOOL PROCa1(GROESSE CONSTa,d1):e1ANDf1.e1:IFa.e0<=d1.e0THENd1.e0<a.e0+a.g0ELSEa.e0<d1.e0+d1.g0END IF.f1:IFa.f0<=d1.f0THENd1.f0<a.f0+a.h0ELSEa.f0<d1.f0+d1.h0END IF.END PROCa1;PROCfenstergroesse(FENSTER CONSTf,INT VARe0,f0,g0,h0):e0:=x0.e0;f0:=x0.f0;g0:=x0.g0;h0:=x0.h0.x0:m0(f.b0).l0.END PROCfenstergroesse;PROCfensterveraendert(FENSTER CONSTf):m0(f.b0).j0:=0;o0:=o0ORg1.g1:m0(f.b0).k0.END PROCfensterveraendert;PROCfensterzugriff(FENSTER CONSTf,BOOL VARh1):h1:=bit(o0,f.b0);IFm0(f.b0).j0<>f.c0THENm0(f.b0).j0:=f.c0;h1:=TRUE END IF;o0:=o0ORg1;resetbit(o0,f.b0).g1:m0(f.b0).k0.END PROCfensterzugriff;PROCbildschirmneu:o0:=-1END PROCbildschirmneu;ROW16INT VARi1:=ROW16INT:(1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,-32767-1);PROCsetbit(BITVEKTOR 
+VARj1,INT CONSTq0):j1:=j1ORi1(q0)END PROCsetbit;PROCresetbit(BITVEKTOR VARj1,INT CONSTq0):j1:=j1AND(-1-i1(q0))END PROCresetbit;BOOL PROCbit(BITVEKTOR CONSTj1,INT CONSTq0):(j1ANDi1(q0))<>0END PROCbit;END PACKETfenster;
+PACKETeudasmenuesDEFINES
+##globalmanager,menuemanager,
+##lock,free,menuedateneinlesen,menuenamen,menueloeschen,waehlbar,ausfuehrtaste,menueanbieten,auswahlanbieten,wahl,eschopausfuehren,hilfeanbieten,statusanzeigen,dialogfenster,dialogfensterloeschen,dialog,neuerdialog,ja,editget,fehlerausgeben:ROW8TEXT VARb0:=ROW8TEXT:("MENUE","BILD","FELD","ENDE","AUSWAHL","VORSPANN","HILFE","SEITE");LETc0=1,d0=2,e0=3,f0=4,g0=5,h0=6,i0=7,j0=8;LETk0=2,integer=3,l0=4,m0=7;LETn0=#701
+#"FEHLER in Zeile ";FILE VARo0;TEXT VARp0,q0;PROCr0:IFeof(o0)THENp0:="%DUMMY"ELSEreadrecord(o0,p0);IFp0=s0THENp0:=t0END IF;cout(lineno(o0));down(o0)END IF END PROCr0;BOOL PROCu0:IF(p0SUB1)=v0THENw0ELSE FALSE END IF.w0:INT VARx0;replace(p0,1,t0);scan(p0);replace(p0,1,v0);nextsymbol(q0,x0);IFx0<>k0THENy0(z0);FALSE ELSE TRUE END IF.END PROCu0;BOOL PROCa1(INT CONSTb1):b0(b1)=q0END PROCa1;INT PROCc1:TEXT VARd1;INT VARx0;nextsymbol(d1,x0);IFx0=integerTHENint(d1)ELSE IFx0<>m0THENy0(e1)END IF;-1END IF END PROCc1;TEXT PROCf1:TEXT VARd1;INT VARx0;nextsymbol(d1,x0);IFx0=l0THENd1ELSE IFx0<>m0THENy0(g1)END IF;s0END IF END PROCf1;PROCy0(TEXT CONSTh1):note(n0);note(lineno(o0)-1);noteline;note(h1);noteline;line;putline(h1)END PROCy0;INT VARi1,j1,k1,l1;PROCm1(INT CONSTn1,o1):cursor(k1+n1-1,l1+o1-1)END PROCm1;LETp1=#702
+#"Zeile ist ohne Zusammenhang",q1=#703
+#"K Menuedaten im Speicher";PROCmenuedateneinlesen(TEXT CONSTr1):s1;o0:=sequentialfile(input,r1);modify(o0);toline(o0,1);WHILE NOTeof(o0)REPr0;IFu0THENt1ELIF NOTanythingnotedTHENy0(p1)END IF END REP;u1;IFanythingnotedTHENnoteedit(o0)END IF.t1:IFa1(c0)THENv1ELIFa1(g0)THENw1ELIFa1(i0)THENx1ELIF NOTanythingnotedTHENy0(p1)END IF.u1:IFonlineTHENline;put(y1DIV2);putline(q1)END IF.y1:dspages(z1(1))+dspages(z1(2))+dspages(z1(3)).END PROCmenuedateneinlesen;TYPE MENUE=STRUCT(SATZa2,b2,c2,TEXTd2,e2);BOUND ROW200MENUE VARf2;TEXT VARg2,h2;SATZ VARi2,j2;LETs0="",t0=" ",k2=" ",l2=2,v0="%",m2=""7"",n2=""27"",o2=""5"";LETp2=#704
+#"% BILD erwartet",q2=#705
+#"Feldnummer beim %FELD-Kommando fehlt",r2=#706
+#"% ENDE erwartet",s2=#707
+#"Name fehlt",z0=#708
+#"Kommandozeile enthaelt kein Kommando",e1=#709
+#"Parameter soll eine Zahl sein",g1=#710
+#"Parameter soll ein TEXT sein",t2=#711
+#"Wiederholungszeile fehlt";PROCv1:TEXT VARname:=f1;IFname=s0THENy0(s2)ELSE INT VARindex;u2;v1(f2(index))END IF.u2:index:=link(v2(2),name);IFindex=0THENinsert(v2(2),name,index)END IF.END PROCv1;PROCv1(MENUE VARw2):x2;y2;z2;a3;b3.x2:satzinitialisieren(w2.a2);satzinitialisieren(i2);satzinitialisieren(j2);h2:=s0;g2:=s0.y2:c3;INT VARd3:=1;REPr0;IFu0THEN LEAVEy2ELSEe3;d3INCR1END IF END REP.c3:r0;IF NOT(u0CANDa1(d0))THENy0(p2)END IF.e3:IF(p0SUBl2)=k2THENg2CATcode(d3);replace(p0,l2,t0)END IF;feldaendern(w2.a2,d3,p0).z2:WHILEa1(e0)REPf3END REP.f3:INT VARg3:=c1;IFg3=-1THENy0(q2);g3:=100END IF;h3;i3;j3.h3:feldaendern(i2,g3,f1).i3:TEXT CONSTk3:=f1;INT VARl3;FORl3FROM1UPTOlength(k3)REPh2CATcode(g3);h2CAT(k3SUBl3)END REP.j3:TEXT VARm3:=s0;r0;WHILE NOTu0REPm3CATp0;r0END REP;feldaendern(j2,g3,m3).a3:IF NOTa1(f0)THENy0(r2)END IF.b3:w2.b2:=i2;w2.c2:=j2;w2.d2:=h2;w2.e2:=g2.END PROCv1;LETn3=#712
+#"Kommando wird ausgeführt ..",o3=#713
+#""15"Gib Kommando: ",p3=#714
+#"falsche Ausfuehrtaste",q3=#715
+#" existiert nicht.";LETr3="                        ",s3=""15"",t3=""14"",u3="*"8"";INT VARv3:=0,w3,x3;BOOL VARy3,z3;TEXT VARa4,b4,c4:=" "1""2""3""8""10""13""27"",d4,e4:=s0;ROW6TEXT VARf4;FENSTER VARg4;fensterinitialisieren(g4);fenstergroessesetzen(g4,1,1,79,1);PROCwaehlbar(INT CONSTh4,i4,BOOL CONSTj4):IFj4THENk4ELSEl4END IF;y3:=TRUE.k4:IFlength(f4(h4))>=i4THENreplace(f4(h4),i4," ")END IF.l4:WHILElength(f4(h4))<i4REPf4(h4)CAT" "END REP;replace(f4(h4),i4,"-").END PROCwaehlbar;PROCausfuehrtaste(TEXT CONSTm4):IFlength(m4)<>1CORn4THENerrorstop(p3)ELSEreplace(c4,1,m4)END IF.n4:m4<>""13""ANDpos(c4,m4,2)>0.END PROCausfuehrtaste;PROCmenueanbieten(ROW6TEXT CONSTmenuenamen,FENSTER VARf,BOOL CONSTo4,PROC(INT CONST,INT CONST)p4):ROW6INT VARq4,r4,s4;INT VARt4,u4:=0,v4:=1,w4:=0,x4;TEXT VARy4;ROW6TEXT VARz4;s1;a5;b5;disablestop;REPc5;d5;e5END REP.a5:v3INCR1;INT CONSTf5:=v3;y4:=""6""0""0"";g5;h5;y4CATo2.g5:INT VARi5:=pos(menuenamen(1),".");IFi5>0THENy4CATsubtext(menuenamen(1),1,i5-1)END IF;y4CAT":   "
+.h5:x4:=0;WHILEx4<6CANDj5REPx4INCR1;k5;s4(x4):=1END REP.j5:menuenamen(x4+1)<>s0.k5:q4(x4):=length(y4);i5:=pos(menuenamen(x4),".");IFi5=0THENy4CATmenuenamen(x4)ELSEy4CATsubtext(menuenamen(x4),i5+1)END IF;y4CAT"   ";r4(x4):=length(y4)-1.b5:INT VARl5;FORl5FROM1UPTO6REPf4(l5):=s0END REP;y3:=TRUE;p4(0,0).c5:IFv4>0THENm5;n5;u4:=v4;v4:=0;o5ELIFv3<>f5THENa4:=y4;f4:=z4;v3:=f5ELIFy3THENz4:=f4END IF.m5:IFu4>0THENreplace(y4,q4(u4)," ");replace(y4,r4(u4)," ");IFz3THENp4(u4,-1)END IF END IF.n5:replace(y4,q4(v4),s3);replace(y4,r4(v4),t3);fensterveraendert(g4);a4:=y4;p5.o5:t4:=link(v2(2),menuenamen(u4));IFt4=0THENq5(menuenamen(u4));LEAVEmenueanbietenEND IF;z3:=FALSE;y3:=TRUE;fensterveraendert(f).d5:w4:=u4;r5(f2(t4),f,w4,s4(u4),PROC(INT CONST,INT CONST)p4).e5:SELECTw4OF CASE0:s5CASE1:t5CASE2:u5CASE3:v5CASE4:w5OTHERWISEx5END SELECT.u5:IFu4<x4THENv4:=u4+1ELSEv4:=1END IF.v5:IFu4>1THENv4:=u4-1ELSEv4:=x4END IF.x5:w4:=w4-10;IFw4<=x4THENv4:=w4END IF.t5:IFo4THEN BOOL VARy5:=FALSE;REPz5;a6UNTILb6END REP;IFy5
+THENbildschirmneu;dialogfensterloeschen;p4(u4,-2)END IF END IF.a6:IFc6THENy5:=TRUE;statusanzeigen(n3);cursor(1,2);out(d6);do(d4)END IF.c6:pos(d4,"!","�",1)>0.b6:NOTiserror.s5:IFz3THENp4(u4,-1)END IF;fensterveraendert(f);LEAVEmenueanbieten.w5:IFs4(u4)>0THENp4(t4,s4(u4))ELSEs4(u4):=-s4(u4)END IF.END PROCmenueanbieten;PROCp5:BOOL VARe6;fensterzugriff(g4,e6);IFe6THENout(a4)END IF END PROCp5;PROCr5(MENUE CONSTw2,FENSTER VARf,INT VARf6,wahl,PROC(INT CONST,INT CONST)p4):INT VARg6:=0;h6;i6(f);IFx3=0THENw3:=0END IF;neuerdialog;j6;REPp5;k6;l6END REP.h6:IFwahl>length(w2.e2)THENwahl:=w3;ELIFiserrorTHENfehlerausgeben;p4(f6,-2);END IF.j6:IFy3THENm6;n6;y3:=FALSE END IF.m6:b4:=r3;INT VARl5;FORl5FROM1UPTOlength(f4(f6))REPreplace(b4,code(w2.e2SUBl5),f4(f6)SUBl5)END REP.n6:INT VARo6;FORo6FROM1UPTOlength(w2.e2)REP INT CONSTp6:=code(w2.e2SUBo6);IFp6>x3THEN LEAVEn6END IF;q6(w2.a2,p6)END REP.k6:REPr6;IFiserrorTHENs6ELSE LEAVEk6END IF END REP.r6:TEXT VARt6;BOOL VARu6:=FALSE;WHILEx3<i1REPt6:=getcharety;v6END 
+REP;w6;x6(w2,wahl);y6(t6).v6:IFt6=s0THENz6;x3INCR1;a7ELSE LEAVEr6END IF.z6:IF NOTz3ANDx3=0THENp4(f6,0);z3:=TRUE END IF.a7:IFx3=code(w2.e2SUBwahl)THENb7(w2.a2,x3,TRUE);w3:=wahlELSEb7(w2.a2,x3,FALSE)END IF;IFx3=i1THENu6:=TRUE END IF.w6:IFu6AND NOTiserrorTHENp4(f6,-2);IFiserrorTHENclearerrorEND IF END IF.s6:fehlerausgeben;p5;x3:=0.l6:INT VARc7;SELECTg6OF CASE0:d7CASE1:e7CASE2:f7END SELECT.d7:SELECTpos(c4,t6)OF CASE1:g7CASE2:g6:=1CASE3:h7CASE4:i7CASE5:j7CASE6:k7CASE7:l7CASE8:g6:=2OTHERWISEm7END SELECT.e7:SELECTpos(""1""3""10"",t6)OF CASE1:n7CASE2:o7CASE3:p7OTHERWISEout(m2)END SELECT;g6:=0.f7:SELECTpos(""1""27"?qh",t6)OF CASE1:eschopausfuehrenCASE2:q7CASE3:r7CASE4,5:s7OTHERWISEt7END SELECT;g6:=0.h7:w4:=2;LEAVEr5.i7:IFwahl>1THENwahlDECR1ELSEwahl:=length(w2.e2)END IF.j7:w4:=3;LEAVEr5.k7:IFwahl<length(w2.e2)THENwahlINCR1ELSEwahl:=1END IF.l7:k7.m7:IFu7THENv7ELIFw7THENx7ELIFt6<=" "THENpush(n2+t6)END IF.u7:pos("123456",t6)>0.v7:w4:=code(t6)-38;LEAVEr5.w7:c7:=0;REPc7:=pos(w2.d2,t6,c7+1)UNTIL(c7MOD
+2)=0END REP;c7>0ANDy7.y7:code(w2.d2SUBc7-1)<=length(w2.e2).x7:wahl:=code(w2.d2SUBc7-1);x6(w2,wahl);IF(f4(f6)SUBwahl)<>"-"THENz7(w2,wahl,x3);w4:=4;LEAVEr5END IF.n7:wahl:=1.o7:wahl:=1.p7:wahl:=length(w2.e2).t7:IFa8THENwahl:=code(w2.d2SUBc7-1);w4:=4;LEAVEr5ELSEpush(lernsequenzauftaste(t6))END IF.a8:c7:=0;REPc7:=pos(w2.d2,t6,c7+1)UNTIL(c7MOD2)=0CAND(c7=0CORb8)END REP;c7>0.b8:code(w2.d2SUBc7-1)>length(w2.e2).q7:w4:=1;LEAVEr5.r7:TEXT VARc8;feldlesen(w2.b2,wahl,c8);hilfeanbieten(c8,d8);IFiserrorTHENfehlerausgebenEND IF;p4(f6,-2);i6(f).s7:w4:=0;LEAVEr5.g7:IF(f4(f6)SUBwahl)<>"-"THENz7(w2,wahl,x3);w4:=4;LEAVEr5END IF.w4:f6.END PROCr5;PROCi6(FENSTER CONSTf):BOOL VARe6;fensterzugriff(f,e6);fenstergroesse(f,k1,l1,j1,i1);IFe6THENx3:=0;m1(1,1)END IF END PROCi6;PROCx6(MENUE CONSTw2,INT CONSTwahl):INT CONSTe8:=code(w2.e2SUBwahl);IFw3>0THEN IFw3=wahlTHENq6(w2.a2,e8)ELSE INT CONSTf8:=code(w2.e2SUBw3);b7(w2.a2,f8,FALSE);b7(w2.a2,e8,TRUE);w3:=wahlEND IF END IF;m1(1,e8)END PROCx6;PROCy6(TEXT VARg8):
+enablestop;getchar(g8)END PROCy6;PROCz7(MENUE CONSTw2,INT VARwahl,INT CONSTx3):INT CONSTl1:=code(w2.e2SUBwahl);IFh8THENi8END IF;TEXT VARm3;feldlesen(w2.c2,wahl,m3);IFm3<>s0ANDm3<>t0THENdo(m3);bildschirmneu;wahl:=-wahlEND IF.h8:x3>=l1.i8:m1(1,l1);out(u3).END PROCz7;PROCeschopausfuehren:TEXT VARj8:=s0,k8;lernsequenzauftastelegen(""0"",s0);push(""27""1""0""0"");editget(j8,32000,0,""0"","",k8);j8:=lernsequenzauftaste(""0"");IFj8<>s0THENl8ELSEm8END IF.l8:REPgetchar(k8)UNTILpos(""1""2""8""11""12"",k8)=0END REP;lernsequenzauftastelegen(k8,j8).m8:getchar(k8).END PROCeschopausfuehren;INT VARn8,o8,p8;PROCq6(SATZ CONSTa2,INT CONSTq8):m1(1,q8);IF(b4SUBq8)<>t0THENout(b4SUBq8)ELSEfeldbearbeiten(a2,q8,PROC(TEXT CONST,INT CONST,INT CONST)r8)END IF END PROCq6;PROCr8(TEXT CONSTs8,INT CONSTn8,o8):out(s8SUBn8+o8-o8)END PROCr8;PROCb7(SATZ CONSTa2,INT CONSTd3,BOOL CONSTt8):enablestop;IFt8THENq6(a2,d3);out(s3);n8:=3;p8:=1;ELSEm1(1,d3);IF(b4SUBd3)="-"THENout("-");n8:=2ELSEn8:=1END IF;p8:=0END IF;u8(a2,d3)END 
+PROCb7;PROCb7(SATZ CONSTa2,INT CONSTd3):n8:=1;p8:=0;u8(a2,d3)END PROCb7;PROCu8(SATZ CONSTa2,INT CONSTd3):IFd3<=felderzahl(a2)THENv8ELSEo8:=0END IF;w8.v8:feldbearbeiten(a2,d3,PROC(TEXT CONST,INT CONST,INT CONST)x8).w8:IFk1+j1>=80ANDp8=0THENout(o2)ELSEj1-o8-p8-1TIMESOUTt0;y8;out(":")END IF.y8:IFp8>0THENout(t3)END IF.END PROCu8;PROCx8(TEXT CONSTz8,INT CONSTa9,b9):INT CONSTc9:=a9-1;n8INCRc9;o8:=min(b9,j1+c9-p8-1);outsubtext(z8,n8,o8);o8DECRc9END PROCx8;PROCz5:LETd9=""27"k";TEXT VARe9;fensterveraendert(g4);f9;g9;REPh9UNTILe9<>d9END REP;IFpos(d4,"!","�",1)>0THENe4:=d4END IF.f9:IFiserrorTHENfehlerausgeben;d4:=e4ELSEd4:=s0END IF.g9:cursor(1,1);out(o3);j1-15TIMESOUTt0;out(t3).h9:cursor(16,1);editget(d4,32000,62,"","kh",e9);IFiserrorTHENclearerrorELIFe9=d9THENd4:=e4ELIFe9=i9THENd4:=s0END IF.END PROCz5;PROCq5(TEXT CONSTr1):errorstop(textdarstellung(r1)+q3)END PROCq5;TYPE AUSWAHL=STRUCT(SATZj9,k9,l9,TEXTm9,n9,o9);BOUND ROW200AUSWAHL VARp9;PROCw1:TEXT VARname:=f1;IFname=s0THENy0(s2)ELSE INT VAR
+index:=link(v2(3),name);IFindex=0THENinsert(v2(3),name,index)END IF;w1(p9(index))END IF END PROCw1;PROCw1(AUSWAHL VARa):x2;IFq9THENr9END IF;y2;s9.x2:satzinitialisieren(a.j9);satzinitialisieren(a.k9);satzinitialisieren(a.l9);a.m9:=s0;a.n9:=s0;a.o9:=s0.q9:r0;u0CANDa1(h0).r9:INT VARd3:=1;REPr0;IFu0THEN LEAVEr9ELSEt9;d3INCR1END IF END REP.t9:feldaendern(a.j9,d3,p0).y2:c3;d3:=1;BOOL VARu9:=TRUE;REPr0;IFu0THENv9;LEAVEy2ELSEe3;d3INCR1END IF END REP.c3:IF NOT(u0CANDa1(d0))THENy0(p2)END IF.v9:IFu9THENy0(t2)END IF.e3:IFu9THENw9ELSEx9END IF.w9:IFpos(p0,k2)>0THENy9;d3:=0;u9:=FALSE ELSEfeldaendern(a.k9,d3,p0)END IF.y9:z9;a.m9:=p0;a10.z9:INT VARb10:=0;REPb10:=pos(p0,k2,b10+1);IFb10>0THENa.n9CATcode(b10)END IF UNTILb10=0END REP.a10:FORb10FROM1UPTOlength(a.n9)-1REPa.o9CATcode(c10-4)END REP;a.o9CAT""0"".c10:code(a.n9SUBb10+1)-code(a.n9SUBb10).x9:feldaendern(a.l9,d3,p0).s9:IF NOTa1(f0)THENy0(r2)END IF.END PROCw1;LETd10=""1""8""10"",e10="+"27"q";LETf10=#716
+#"Fenster zu klein",g10=#717
+#"AUSWAHL:  Ankreuzen: 'x'  Durchstreichen: 'o'  Beenden: ESC q  Hilfe: ESC ?";INT VARh10,i10,j10,k10,l10,m10,n10,o10;LET INTVEC=TEXT;INTVEC VARp10;TEXT VARq10;PROCauswahlanbieten(TEXT CONSTname,FENSTER CONSTf,TEXT CONSTr10,PROC(TEXT VAR,INT CONST)s10):s1;INT CONSTindex:=link(v2(3),name);IFindex=0THENq5(name)ELSEr5(p9(index),f,r10,PROC(TEXT VAR,INT CONST)s10)END IF END PROCauswahlanbieten;PROCr5(AUSWAHL CONSTa,FENSTER CONSTf,TEXT CONSTr10,PROC(TEXT VAR,INT CONST)s10):INT VARx3:=0,g6:=0;enablestop;t10;statusanzeigen(g10);u10;v10;w10;REPk6;x10END REP.t10:BOOL VARy10;fensterzugriff(f,y10);fenstergroesse(f,k1,l1,j1,i1).u10:INT VARz10:=1024;h10:=z10;REPz10:=z10DIV2;s10(p0,h10);IFp0=s0THENh10DECRz10ELSEh10INCRz10END IF UNTILz10=1END REP;s10(p0,h10);IFp0=s0THENh10DECR1END IF.w10:INT VARa11:=k10+1,b11:=1,c11:=1;p10:=s0;q10:=a.n9.v10:j10:=felderzahl(a.j9);k10:=j10+felderzahl(a.k9);i10:=length(a.n9);l10:=(h10+i10-1)DIVi10;m10:=k10+l10;n10:=m10+felderzahl(a.l9);o10:=0;IFk10>=i1THENerrorstop(f10)
+END IF.k6:REPr6;IFiserrorTHENclearerror;x3:=0ELSE LEAVEk6END IF END REP.r6:TEXT VARt6;WHILEx3<i1REPt6:=getcharety;v6END REP;x6;y6(t6).v6:IFt6=s0THENx3INCR1;d11ELSE LEAVEr6END IF.d11:INT CONSTe11:=x3+o10;m1(1,x3);IFx3<=j10THENb7(a.j9,x3)ELIFe11<=k10THENb7(a.k9,e11-j10)ELIFe11<=m10THENf11ELSEb7(a.l9,e11-m10)END IF.f11:g11(a,h11,PROC(TEXT VAR,INT CONST)s10).h11:(e11-k10-1)*i10+1.x6:m1(code(q10SUBb11),a11).x10:SELECTg6OF CASE0:d7CASE1:e7CASE2:f7END SELECT.d7:SELECTpos(""1""2""3""8""9""10""13""27" +x-o",t6)OF CASE1:g6:=1CASE2:h7CASE3:i7CASE4:j7CASE5:i11CASE6:k7CASE7:l7CASE8:g6:=2CASE9:j11CASE10,11:k11CASE12,13:l11OTHERWISEm7END SELECT.e7:SELECTpos(""1""2""3""8""10""13"+x-o",t6)OF CASE1:n7CASE2:m11CASE3:o7CASE4:n11CASE5:p7CASE6:o11CASE7,8:p11CASE9,10:q11OTHERWISEout(m2)END SELECT;g6:=0.f7:SELECTpos(""1"19?qh",t6)OF CASE1:eschopausfuehrenCASE2:r11CASE3:s11CASE4:r7CASE5:s7CASE6:errorstop(s0)OTHERWISEt7END SELECT;g6:=0.h7:IFb11<i10ANDc11<h10THENb11INCR1;c11INCR1END IF.i7:IFc11>i10THENa11DECR1;
+c11DECRi10;IFa11<=j10THENa11INCR1;o10DECR1;x3:=j10END IF END IF.j7:IFb11>1THENb11DECR1;c11DECR1END IF.i11:IFb11=i10THENpush(""13"")ELSEpush(""1""2"")END IF.k7:IFc11+i10<=h10THENa11INCR1;c11INCRi10;IFa11>i1THENa11DECR1;o10INCR1;x3:=j10END IF END IF.l7:IFa11+o10<m10THENpush(d10)END IF.j11:push(e10).k11:IFt11(c11)=0ANDc11<=h10THENp10CATc11;IFa11<=x3THENu11(a11,b11,length(p10)DIV2)END IF END IF.l11:INT CONSTv11:=t11(c11);IFv11>0THENw11;x11END IF.w11:change(p10,2*v11-1,2*v11,s0).m7:IFt6<t0THENpush(lernsequenzauftaste(t6))ELSEout(m2)END IF.n7:n11;y11.m11:WHILEc11<h10ANDb11<i10REPc11INCR1;b11INCR1END REP.o7:IFa11=j10+1THENz11ELSEy11END IF.z11:INT VARa12:=min(i1-j10,o10);o10DECRa12;INT CONSTb12:=c12;a11INCRb12;c11DECR(a12-b12)*i10;IFa12>0THENx3:=j10END IF.c12:max(0,k10-j10-o10).y11:WHILEc11>i10ANDa11>j10+1REPa11DECR1;c11DECRi10END REP.n11:c11DECR(b11-1);b11:=1.p7:IFa11=i1THENd12ELSEe12END IF.d12:a12:=min(i1-j10,n10-a11-o10);o10INCRa12;INT CONSTf12:=max(0,a11+o10-m10+g12);a11DECRf12;c11INCR(a12
+-f12)*i10;IFa12>0THENx3:=j10END IF.g12:IFb11-1>h10MODi10THEN1ELSE0END IF.e12:WHILEa11<i1ANDc11+i10<=h10REPa11INCR1;c11INCRi10END REP.o11:o10INCR(a11-j10-1);a11:=j10+1;x3:=j10.p11:INT VARh12;FORh12FROM1UPTOh10REP IFt11(h12)=0THENp10CATh12END IF END REP;x11.q11:p10:=s0;x11.r7:hilfeanbieten(r10,f);statusanzeigen(g10);x3:=0.s7:LEAVEr5.t7:push(lernsequenzauftaste(t6)).r11:a11:=k10+1;c11:=1;b11:=1;o10:=0;x3:=j10.s11:IFm10<=i1THENa11:=m10ELSEa11:=max(j10+1,i1+m10-n10)END IF;o10:=m10-a11;b11:=(h10-1)MODi10+1;c11:=h10;x3:=j10.END PROCr5;PROCx11:INT VARg8,i12,h12;h12:=j12;FORg8FROMk12UPTOl12REP FORi12FROM1UPTOi10REPu11(g8,i12,t11(h12));h12INCR1END REP END REP.j12:max(0,o10-k10+j10)*i10+1.k12:max(j10,k10-o10)+1.l12:min(i1,m10-o10).END PROCx11;TEXT VARm12:="xx";INT PROCt11(INT CONSTn12):replace(m12,1,n12);INT VARl3:=0;REPl3:=pos(p10,m12,l3+1)UNTILl3=0ORl3MOD2=1END REP;(l3+1)DIV2END PROCt11;OP CAT(INTVEC VARo12,INT CONSTwert):replace(m12,1,wert);o12CATm12END OP CAT;PROCg11(AUSWAHL CONSTa,INT CONST
+h11,PROC(TEXT VAR,INT CONST)s10):INT VARl3:=1,n12,i12:=1;FORn12FROMh11UPTOh11+i10-1REPoutsubtext(a.m9,l3,p12-5);q12;s10(p0,n12);INT CONSTr12:=min(s12,length(p0));outsubtext(p0,1,r12);l3:=p12+r12+2;i12INCR1END REP;w8.p12:code(q10SUBi12).q12:INT CONSTt12:=t11(n12);IFt12=0THENout("    o ")ELSEout(text(t12,3));out(" x ")END IF.s12:IFi12=i10THENj1-p12-1ELSEcode(a.o9SUBi12)END IF.w8:outsubtext(a.m9,l3,j1);IFk1+j1>=80THENout(o2)ELSEj1-max(l3,length(a.m9))TIMESOUTt0END IF.END PROCg11;PROCu11(INT CONSTp0,u12,wert):m1(code(q10SUBu12)-4,p0);IFwert=0THENout("    o ")ELSEout(text(wert,3));out(" x ")END IF END PROCu11;INT PROCwahl(INT CONSTv12):IFv12+v12<=length(p10)THENp10ISUBv12ELSE0END IF END PROCwahl;LETw12=200,x12=5000;LET HILFE=STRUCT(INTy12,ROWw12THESAURUSz12,ROWw12SATZa13,ROWx12SATZb13);BOUND HILFE VARc13;INT VARd13,e13,f13,g13;BOOL VARh13:=FALSE;LETi13=#718
+#"Das Hilfsgebiet existiert bereits",j13=#719
+#"Diese Seite ist in der anderen Hilfe nicht vorhanden";PROCx1:TEXT VARname:=f1;BOOL VARk13;IFname=s0THENy0(s2)ELSEl13;m13;n13END IF.l13:INT CONSTo13:=pos(name,"/");TEXT VARp13;IFo13=0THENp13:=nameELSEp13:=subtext(name,1,o13-1)END IF;q13;r13.q13:INT VARs13:=link(v2(1),p13);k13:=FALSE;IFs13=0THENinsert(v2(1),p13,s13);c13.z12(s13):=emptythesaurus;satzinitialisieren(c13.a13(s13));ELIFo13=0THENy0(i13);LEAVEx1ELIFh13THENk13:=TRUE END IF.r13:INT VARt13;TEXT VARu13:=subtext(name,o13+1);IFo13=0THENt13:=1ELSEt13:=link(c13.z12(s13),u13);IFt13=0AND NOTk13THENinsert(c13.z12(s13),u13,t13)END IF END IF.m13:INT VARv13:=c13.y12;IFv13<0THENv13:=0END IF;TEXT VARw13:=s0;r0;WHILEu0CANDa1(j0)REPx13END REP.x13:INT CONSTy13:=c1;TEXT CONSTz13:=f1;IFz13<>s0THENa14;r0ELSEb14END IF.a14:TEXT VARc14;d14(z13,c14);IFy13+y13<=length(c14)THENw13CAT(c14ISUBy13)ELIF NOT(anythingnotedORk13)THENy0(j13)END IF.b14:INT VARd3:=1;IF NOTk13THENv13INCR1;w13CATv13;satzinitialisieren(c13.b13(v13))END IF;REPr0;IFu0THEN LEAVEb14ELIF
+ NOTk13THENfeldaendern(c13.b13(v13),d3,p0);d3INCR1END IF END REP.n13:IF NOTa1(f0)THENy0(r2)END IF;IF NOT(anythingnotedORk13)THENfeldaendern(c13.a13(s13),t13,w13);c13.y12:=v13END IF.END PROCx1;PROCd14(TEXT CONSTname,TEXT VARw13):INT CONSTo13:=pos(name,"/");INT VARp13,t13:=0;IFo13=0THENp13:=link(v2(1),name)ELSEp13:=link(v2(1),subtext(name,1,o13-1));e14END IF;IFt13=0THENt13:=1END IF;IFp13=0THENerrorstop(f14)ELSEfeldlesen(c13.a13(p13),t13,w13)END IF.e14:IFp13>0THENt13:=link(c13.z12(p13),subtext(name,o13+1))END IF.END PROCd14;LETf14=#720
+#"Hilfe existiert nicht",g14=#721
+#"Hilfe ist leer",h14=#722
+#"HILFE:  Beenden: ESC q     Seite weiter: ESC w     Seite zurueck: ESC z";PROChilfeanbieten(TEXT CONSTname,FENSTER CONSTf):enablestop;s1;TEXT VARw13;i14;d14(name,w13);IFw13=s0THENerrorstop(g14)ELSEj14END IF.i14:fensterveraendert(f);fenstergroesse(f,d13,e13,f13,g13).j14:k14;statusanzeigen(h14);INT VARa13:=1;REPl14;m14END REP.l14:INT CONSTn14:=w13ISUBa13;o14(c13.b13(n14)).m14:TEXT VARt6;REPgetchar(t6);IFt6=n2THENgetchar(t6);a6;LEAVEm14ELSEout(m2)END IF END REP.a6:SELECTpos("qwz?"1"",t6)OF CASE1:LEAVEhilfeanbietenCASE2:p14CASE3:q14CASE4:r14CASE5:eschopausfuehrenOTHERWISEout(m2)END SELECT.p14:IF2*a13<length(w13)THENa13INCR1END IF.q14:IFa13>1THENa13DECR1END IF.r14:a13:=1.END PROChilfeanbieten;PROCo14(SATZ CONSTs14):INT VARd3;FORd3FROM1UPTOg13REPcursor(d13,e13+d3-1);feldbearbeiten(s14,d3,PROC(TEXT CONST,INT CONST,INT CONST)t14)END REP;cursor(d13,e13+g13-1)END PROCo14;PROCt14(TEXT CONSTa2,INT CONSTa9,b9):IFb9-a9+1>f13THENo8:=a9+f13-1ELSEo8:=b9END IF;outsubtext(a2,a9,o8);IFd13+f13>=80THENout(
+o2)ELSEf13+a9-o8-1TIMESOUTt0END IF END PROCt14;PROCstatusanzeigen(TEXT CONSTstatus):cursor(1,1);out(status);out(o2);fensterveraendert(g4)END PROCstatusanzeigen;LETd6=""4"",u14=""27"?",v14=""27"q",i9=""27"h";LETw14=#723
+#" ? (j/n) ",x14=#724
+#"jJ",y14=#725
+#"nN",z14=#726
+#"FRAGE:  Bejahen: j,J    Verneinen: n,N    Abbrechen: ESC h    Hilfe: ESC ?",a15=#727
+#"EINGABE:  Bestätigen: RETURN    Abbrechen: ESC h    Hilfe: ESC ?",b15=#728
+#"EINGABE:  Bestätigen: RETURN   Zeigen: ESC z   Abbruch: ESC h  Hilfe: ESC ?",c15=#729
+#""15"!!! FEHLER !!! "14"     Quittieren: ESC q     Hilfe zur Meldung: ESC ?";FENSTER VARd8;fensterinitialisieren(d8);INT VARd15,e15,f15,g15,h15;PROCdialogfenster(INT CONSTn1,o1,i15,j15):fenstergroessesetzen(d8,n1,o1,i15,j15);e15:=n1;f15:=o1;g15:=i15;h15:=j15END PROCdialogfenster;PROCneuerdialog:d15:=h15END PROCneuerdialog;PROCdialog:BOOL VARe6;fensterzugriff(d8,e6);d15INCR1;IFd15>h15ORe6THENdialogfensterloeschen;d15:=1END IF;cursor(e15,f15+d15-1).END PROCdialog;PROCdialogfensterloeschen:BOOL CONSTk15:=e15+g15>=80;d15:=0;REPcursor(e15,f15+d15);IFk15THENout(o2)ELSEg15TIMESOUTt0END IF;d15INCR1UNTILd15>=h15END REP.END PROCdialogfensterloeschen;BOOL PROCja(TEXT CONSTl15,r10):REPstatusanzeigen(z14);dialog;out(l15);out(w14);k14;m15END REP;FALSE.m15:TEXT VARt6;REPgetchar(t6);IFpos(x14,t6)>0THENout(t6);LEAVEjaWITH TRUE ELIFpos(y14,t6)>0THENout(t6);LEAVEjaWITH FALSE ELIFt6=n2THENn15ELSEout(m2)END IF END REP.n15:getchar(t6);IFt6="?"THENhilfeanbieten(r10,d8);neuerdialog;LEAVEm15ELIFt6="h"THEN
+errorstop(s0);LEAVEjaWITH FALSE ELIFt6=""1""THENeschopausfuehrenELSEout(m2)END IF.END PROCja;PROCeditget(TEXT CONSTo15,TEXT VARt6,TEXT CONSTp15,r10):TEXT VARe9;q15;dialog;out(o15);out(t0);editget(t6,1000,r15,"","?hq"+p15,e9);IFe9=u14THENhilfeanbieten(r10,d8);neuerdialog;editget(o15,t6,p15,r10)ELIFe9=i9ORe9=v14THENerrorstop(s0)ELIFlength(e9)=2THENt6:=e9END IF.q15:IFpos(p15,"z")>0THENstatusanzeigen(b15)ELSEstatusanzeigen(a15)END IF.r15:g15-length(o15)-1.END PROCeditget;PROCfehlerausgeben:TEXT CONSTh1:=errormessage;IFerrorcode=1THENpage;bildschirmneuEND IF;clearerror;k14;IFh1<>s0THENstatusanzeigen(c15);s15;t15;neuerdialogEND IF.s15:dialog;out(m2);out(">>> ");outsubtext(errormessage,1,g15).t15:TEXT VARt6;getchar(t6);IFt6=n2THENn15END IF.n15:getchar(t6);IFt6="?"THENhilfeanbieten("FEHLER/"+text(errorcode),d8)ELIFt6=""1""THENeschopausfuehrenEND IF.END PROCfehlerausgeben;PROCk14:WHILEgetcharety<>s0REP END REP END PROCk14;LETu15=3,v15=12,w15=14,x15=1070,y15=1068,z15=1069,a16=0,b16=2;ROWu15
+DATASPACE VARz1;ROWu15THESAURUS VARv2;BOOL VARc16:=FALSE;INITFLAG VARd16;PROCs1:IF NOTinitialized(d16)THENe16END IF.e16:BOOL VARb6:=c16;f16;IFb6THENg16ELSEmenueloeschen(FALSE)END IF.f16:INT VARh16;FORh16FROM1UPTOu15WHILEb6REPi16END REP.i16:
+##INT VARj16,k16;FORk16FROM1UPTO10REPforget(z1(h16));z1(h16):=nilspace;pingpong(father,x15+h16,z1(h16),j16);IFj16=a16THEN LEAVEi16ELIFj16<>b16THENpause(15)END IF UNTILj16=b16END REP;forget(z1(h16));z1(h16):=nilspace;
+##b6:=FALSE.END PROCs1;THESAURUS PROCmenuenamen(INT CONSTh16):s1;IFh16<0THENc13.z12(-h16)ELSEv2(h16)END IF END PROCmenuenamen;PROCmenueloeschen(TEXT CONSTname,INT CONSTh16):s1;IFh16<0THENl16(name,c13.z12(-h16))ELSEl16(name,v2(h16))END IF END PROCmenueloeschen;PROCl16(TEXT CONSTname,THESAURUS VARz8):INT CONSTindex:=link(z8,name);IFindex>0THENdelete(z8,index)END IF END PROCl16;PROCmenueloeschen(BOOL CONSTm16):INT VARh16;d16:=TRUE;h13:=m16;FORh16FROM1UPTOu15REPforget(z1(h16));z1(h16):=nilspace;v2(h16):=emptythesaurusEND REP;g16END PROCmenueloeschen;PROCg16:c13:=z1(1);f2:=z1(2);p9:=z1(3)END PROCg16;
+##LETn16=#730
+#"Datei wird von anderer Task geaendert.",o16=#731
+#"Auftrag nur fuer Soehne erlaubt";THESAURUS VARp16:=emptythesaurus;ROW200TASK VARq16;TEXT VARr16;BOUND STRUCT(TEXTname,s16,t16)VARu16;PROCmenuemanager(DATASPACE VARv16,INT CONSTw16,x16,TASK CONSTy16):enablestop;c16:=TRUE;IFw16>=y15ANDw16<=x15+u15THENz16ELSE IFw16=v15ORw16=w15THENa17END IF;freemanager(v16,w16,x16,y16)END IF.z16:IFw16=y15THENb17ELIFw16=z15THENc17ELSEd17END IF.b17:u16:=v16;e17(u16.name,y16);send(y16,a16,v16).c17:u16:=v16;f17(u16.name);send(y16,a16,v16).a17:IFx16=1THENg17ELSEf17(r16)END IF.g17:u16:=v16;r16:=u16.name;IFh17THENerrorstop(n16)END IF.h17:INT VARv12:=link(p16,r16);v12>0CAND NOT(q16(v12)=y16).d17:IFy16<myselfTHENs1;forget(v16);v16:=z1(w16-x15);send(y16,a16,v16)ELSEerrorstop(o16)END IF.END PROCmenuemanager;PROCe17(TEXT CONSTr1,TASK CONSTi17):INT VARl5:=link(p16,r1);IFl5=0THENinsert(p16,r1,l5);j17;q16(l5):=i17ELIFexists(q16(l5))THEN IF NOT(q16(l5)=i17)THENerrorstop(n16)END IF ELSEq16(l5):=i17END IF.j17:IFl5=0THENk17;insert(p16,r1,l5)END IF.k17:TEXT VARl17;l5:=0;
+REPget(p16,l17,l5);IFl5=0THEN LEAVEk17END IF;IF NOTexists(l17)OR NOTexists(q16(l5))THENdelete(p16,l5)END IF END REP.END PROCe17;PROCf17(TEXT CONSTr1):INT VARl5;delete(p16,r1,l5)END PROCf17;PROCglobalmanager:globalmanager(PROC(DATASPACE VAR,INT CONST,INT CONST,TASK CONST)menuemanager)END PROCglobalmanager;
+##PROClock(TEXT CONSTr1,TASK CONSTm17):call(y15,r1,m17)END PROClock;PROCfree(TEXT CONSTr1,TASK CONSTm17):call(z15,r1,m17)END PROCfree;END PACKETeudasmenues;
+
diff --git a/eudas/eudas.4 b/eudas/eudas.4
new file mode 100644
index 0000000..4605022
--- /dev/null
+++ b/eudas/eudas.4
@@ -0,0 +1,150 @@
+PACKETsatzanzeigeDEFINESanzeigefenster,bildausgeben,aendern,einfuegen,suchen,feldauswahl,rollen,exitdurch,exitzeichen:LETb0=256;LETc0=" ",d0="",e0=""5"",f0=""15"",g0=" "14"",h0=" "14" ";ROWb0STRUCT(INTi0,j0)VARk0;INT VARl0,m0,n0:=24,o0:=79,p0:=1,q0:=1,r0,s0,t0:=0,u0:=0,v0:=dateiversion-1,w0:=0;BOOL VARx0:=TRUE,y0:=TRUE,z0:=FALSE,a1;FENSTER VARfenster;fensterinitialisieren(fenster);DATASPACE VARb1,c1;FILE VAReditfile;TEXT VARd1,e1;LETf1=#801
+#"Anzeigefenster zu klein";PROCanzeigefenster(INT CONSTg1,h1,i1,j1):IFi1>=39THENfenstergroessesetzen(fenster,g1,h1,i1,j1);y0:=g1+i1>=80;o0:=i1;n0:=j1;q0:=g1;p0:=h1;x0:=TRUE ELSEerrorstop(f1)END IF END PROCanzeigefenster;PROCk1:BOOL VARfensterveraendert;fensterzugriff(fenster,fensterveraendert);IFfensterveraendertTHENa1:=TRUE END IF END PROCk1;PROCl1:IFm1ORx0THENn1;o1;p1;q1;r1;s1END IF.m1:v0<>dateiversion.n1:l0:=0;WHILEl0<anzahlfelderREPl0INCR1;k0(l0).i0:=l0END REP;m0:=1.o1:INT VARi0;r0:=11;FORi0FROM1UPTOanzahlfelderREPfeldnamenbearbeiten(i0,PROC(TEXT CONST,INT CONST,INT CONST)t1)END REP;r0:=min(r0,o0DIV2);s0:=o0-r0-3.q1:a1:=TRUE.r1:forget(c1);c1:=nilspace;IFm1ANDz0THENforget(b1);z0:=FALSE END IF.s1:v0:=dateiversion;w0:=anzahldateien;x0:=FALSE.END PROCl1;PROCt1(TEXT CONSTu1,INT CONSTv1,w1):r0INCRlength(u1)-length(u1);r0:=max(r0,w1-v1+1)END PROCt1;PROCrollen(INT CONSTx1):m0:=m0+x1;IFm0<1THENm0:=1ELIFm0>y1THENm0:=max(y1,1)END IF;a1:=TRUE.y1:l0-n0+3.END PROCrollen;PROCfeldauswahl(TEXT 
+CONSTz1):l1;a2;a1:=TRUE.a2:l0:=length(z1);INT VARb2;FORb2FROM1UPTOl0REPk0(b2).i0:=code(z1SUBb2)END REP;m0:=1.END PROCfeldauswahl;INT VARc2;PROCd2:type(c1,-1);editfile:=sequentialfile(modify,c1);editinfo(editfile,-1);toline(editfile,1);col(editfile,1);maxlinelength(editfile,10000);c2:=1END PROCd2;.e2:c2<=l0.PROCf2(PROC(TEXT CONST,INT CONST)g2):h2;IFeof(editfile)THENg2("",i0)ELIFi2THENj2;k2;g2(e1,i0)ELIFl2THENreadrecord(editfile,e1);k2;g2(e1,i0);down(editfile)ELSEexec(PROC(TEXT CONST,INT CONST)g2,editfile,i0);down(editfile)END IF.h2:INT CONSTv1:=c2,i0:=k0(v1).i0;REPc2INCR1UNTILc2>l0CORm2END REP.m2:k0(c2).i0<>i0.i2:c2-v1>1.j2:e1:="";REPexec(PROC(TEXT CONST,INT CONST)n2,editfile,length(e1));down(editfile)UNTILeof(editfile)ORlineno(editfile)=c2END REP.l2:INT CONSTo2:=len(editfile);subtext(editfile,o2,o2)=c0.END PROCf2;PROCn2(TEXT CONSTp2,INT CONSTq2):IFq2>0CAND(e1SUBq2)<>c0CAND(p2SUB1)<>c0THENe1CATc0END IF;e1CATp2END PROCn2;PROCk2:INT VARo2:=length(e1);WHILE(e1SUBo2)=c0REPo2DECR1END REP;e1
+:=subtext(e1,1,o2)END PROCk2;BOOL VARr2;PROCeinfuegen(PROCs2):enablestop;l1;IFl0>0THENd2;k1;t2(PROCs2);satzeinfuegen;r2:=TRUE;u2END IF END PROCeinfuegen;PROCu2:WHILEe2REPf2(PROC(TEXT CONST,INT CONST)v2)END REP;aenderungeneintragenEND PROCu2;PROCv2(TEXT CONSTw2,INT CONSTi0):IF NOTr2CORw2<>d0THENfeldaendern(i0,w2)END IF END PROCv2;PROCaendern(PROCs2):enablestop;IFdateiendeTHENeinfuegen(PROCs2)ELSEx2END IF.x2:l1;IFl0>0THENd2;k1;y2(a1);z2;t2(PROCs2);r2:=FALSE;u2END IF.z2:a3:=1;WHILEa3<=l0REPfeldbearbeiten(k0(a3).i0,PROC(TEXT CONST,INT CONST,INT CONST)b3);insertrecord(editfile);writerecord(editfile,e1);down(editfile);a3INCR1END REP;toline(editfile,1).END PROCaendern;INT VARa3;PROCb3(TEXT CONSTu1,INT CONSTv1,w1):e1:=subtext(u1,c3,d3).c3:v1+k0(a3).j0.d3:IFe3THENw1ELSEv1+k0(a3+1).j0-1END IF.e3:a3=l0CORk0(a3+1).i0<>k0(a3).i0.END PROCb3;PROCsuchen(PROCs2):enablestop;l1;IFl0>0THENd2;k1;IFsuchversion<>0THENf3END IF;t2(PROCs2);g3END IF.f3:a3:=1;WHILEa3<=l0REPinsertrecord(editfile);h3;down(editfile)
+;a3INCR1END REP;toline(editfile,1).h3:IFk0(a3).j0=0THENsuchbedingunglesen(k0(a3).i0,e1);writerecord(editfile,e1)END IF.g3:suchbedingungloeschen;WHILEe2REPf2(PROC(TEXT CONST,INT CONST)i3)END REP.END PROCsuchen;PROCi3(TEXT CONSTj3,INT CONSTi0):suchbedingung(i0,j3)END PROCi3;PROCbildausgeben(BOOL CONSTk3):enablestop;l1;k1;IFk3ORa1ORl3THENy2(a1);t0:=satznummer;u0:=satzkombination;m3(TRUE)ELSEn3(TRUE)END IF.l3:satznummer<>t0ORu0<>satzkombination.END PROCbildausgeben;INT VARj0;BOOL VARo3;PROCy2(BOOL CONSTp3):INT VARb2:=1,q3:=0;o3:=TRUE;WHILEb2<=l0OR NOTo3REPr3END REP.r3:IFo3CANDk0(b2).i0=q3THENs3ELSE IFt3THENu3END IF;k0(b2).j0:=j0;feldbearbeiten(k0(b2).i0,PROC(TEXT CONST,INT CONST,INT CONST)v3);b2INCR1END IF.s3:IFp3THENw3(b2)ELSEk0(b2).j0:=j0;b2INCR1END IF.t3:b2>l0CORk0(b2).i0<>q3.u3:IFo3THENx3ELSEy3(b2);k0(b2).i0:=q3END IF.x3:q3:=k0(b2).i0;j0:=0.END PROCy2;PROCv3(TEXT CONSTu1,INT CONSTv1,w1):INT CONSTz3:=w1-v1-j0+1;IFz3>s0-2THENj0INCRs0-2;a4;o3:=FALSE ELSEj0INCRz3;o3:=TRUE END IF.a4:INT VAR
+b4:=v1+j0-1;IFc4ANDd4THEN WHILE(u1SUBb4)<>c0REPb4DECR1;j0DECR1END REP END IF.c4:(u1SUBb4)<>c0.d4:pos(u1,c0,b4-s0,b4-1)>0.END PROCv3;PROCy3(INT CONSTb2):INT VARe4;FORe4FROMl0DOWNTOb2REPk0(e4+1):=k0(e4)END REP;l0INCR1;a1:=TRUE END PROCy3;PROCw3(INT CONSTb2):INT VARe4;FORe4FROMb2+1UPTOl0REPk0(e4-1):=k0(e4)END REP;l0DECR1;a1:=TRUE END PROCw3;INT VARf4;TEXT VARg4,h4,i4,j4:="",k4;LETl4=#802
+#""15" Bild verschoben ! ESC 1 druecken ! "14"";LETm4=""3""10"19"11""12"q?hpg";LETn4=1,o4=2,p4=3,q4=4,r4=5,s4=6,t4=7,u4=8,v4=9,w4=10,x4=11;PROCt2(PROCs2):INT VARy4:=m0;lernsequenzauftastelegen("D",date);REPm3(FALSE);z4;a5;b5;c5UNTILd5END REP;toline(editfile,1);col(editfile,1).z4:IFlines(editfile)<l0+1THENoutput(editfile);line(editfile,l0-lines(editfile)+2);modify(editfile)END IF.a5:IFm0<>1THENe5(m0-1,h4)END IF;e5(f5,i4);toline(editfile,y4).f5:min(l0+1,m0+n0-1).b5:openeditor(groesstereditor+1,editfile,TRUE,q0+r0+3,p0,s0,g5);edit(groesstereditor,m4+j4,PROC(TEXT CONST)h5).g5:min(l0-m0+2,n0).c5:y4:=lineno(editfile);i5;SELECTf4OF CASEn4:j5CASEo4:k5CASEp4:l5CASEq4:m5CASEr4:n5CASEs4:o5CASEu4:s2;a1:=TRUE CASEv4:errorstop(d0)CASEw4:p5CASEx4:q5END SELECT.i5:INT CONSTr5:=col(editfile);col(editfile,1);IFm0<>1THENs5(m0-1,h4)END IF;s5(f5,i4);col(editfile,r5).j5:INT VARt5;t5:=y4-m0;rollen(-n0+1);y4:=m0+t5.k5:t5:=y4-m0;rollen(n0-1);y4:=min(m0+t5,l0).l5:rollen(-999);y4:=1.m5:t5:=y4-m0;rollen(999);y4:=
+min(m0+t5,l0).n5:toline(editfile,y4);u5;y3(y4).u5:readrecord(editfile,e1);g4:=subtext(e1,r5);e1:=subtext(e1,1,r5-1);writerecord(editfile,e1);down(editfile);insertrecord(editfile);writerecord(editfile,g4).o5:toline(editfile,y4);IFr5=1AND(v5CANDw5ORx5CANDy5)THENz5ELSEa6END IF.v5:y4<>l0.w5:k0(y4+1).i0=k0(y4).i0.x5:y4<>1.y5:k0(y4-1).i0=k0(y4).i0.z5:deleterecord(editfile);w3(y4).a6:readrecord(editfile,e1);e1:=subtext(e1,1,r5-1);writerecord(editfile,e1).p5:forget(b1);b1:=c1;z0:=TRUE.q5:IFz0THENforget(c1);c1:=b1;editfile:=sequentialfile(modify,c1)END IF.d5:f4=t4.END PROCt2;PROCh5(TEXT CONSTb6):enablestop;setbusyindicator;f4:=pos(m4,b6);IFf4>0THENk4:=b6;quitELIFpos(j4,b6)>0THENf4:=t4;k4:=b6;quitELIFkommandoauftaste(b6)<>d0THENstdkommandointerpreter(b6)ELSEnichtsneuEND IF END PROCh5;PROCe5(INT CONSTb2,TEXT VARc6):toline(editfile,b2);readrecord(editfile,c6);writerecord(editfile,l4)END PROCe5;PROCs5(INT CONSTb2,TEXT CONSTc6):toline(editfile,b2);IFeof(editfile)CORpos(editfile,l4,1)=0THENtoline(
+editfile,1);down(editfile,l4);IFeof(editfile)THENtoline(editfile,b2);insertrecord(editfile)END IF END IF;writerecord(editfile,c6)END PROCs5;PROCexitzeichen(TEXT CONSTd6):j4:=d6END PROCexitzeichen;TEXT PROCexitdurch:k4END PROCexitdurch;INT VARe6;LETf6=#803
+#"ENDE.",g6=#804
+#"SUCH+",h6=#805
+#"SUCH-",i6=#806
+#"MARK+",j6=#807
+#"MARK-",k6=#808
+#" Feld    "14" ",l6=#809
+#" Satz   ",m6=#810
+#"< KOPPEL >";LETn6=".....",o6="       ";PROCm3(BOOL CONSTp6):INT VARq6:=p0+1,r6:=0;INT CONSTs6:=m0+n0-2;n3(p6);e6:=m0;WHILEe6<=s6REPt6;u6;v6;q6INCR1;e6INCR1END REP;a1:=FALSE.t6:IFa1THENcursor(q0,q6);IFe6<=l0THENw6ELIFe6=l0+1THENx6ELSEy6END IF END IF.w6:out(f0);IFk0(e6).i0=r6THENr0TIMESOUTc0ELSEr6:=k0(e6).i0;feldnamenbearbeiten(r6,PROC(TEXT CONST,INT CONST,INT CONST)z6)END IF;out(g0).x6:out(f0);o0-4TIMESOUT".";out(h0).y6:IFy0THENout(e0)ELSEo0TIMESOUTc0END IF.u6:IFp6ANDe6<=l0THENcursor(q0+r0+3,q6);feldbearbeiten(k0(e6).i0,PROC(TEXT CONST,INT CONST,INT CONST)a7)END IF.v6:IF NOTa1THEN TEXT CONSTinput:=getcharety;IFinput<>d0THENpush(input);IFpos(j4,input)>0THENt0:=0;LEAVEm3END IF END IF END IF.END PROCm3;PROCn3(BOOL CONSTp6):b7;c7;cursor(q0,p0);IF NOTp6THENoutsubtext(d1,1,r0+3);LEAVEn3END IF;replace(d1,r0+7,d7);replace(d1,r0+14,e7);out(d1);cursor(q0+o0-5,p0);out(text(m0)).b7:TEXT VARsatznr;satznr:=text(satznummer);IFanzahlkoppeldateien>0AND NOTaufkoppeldateiTHENsatznrCAT"-";satznrCATtext(
+satzkombination)END IF.c7:replace(d1,7,o6);replace(d1,7,satznr).d7:IFsuchversion=0THENn6ELIFsatzausgewaehltTHENg6ELSEh6END IF.e7:IFdateiendeTHENf6ELIFmarkiertesaetze=0THENn6ELIFsatzmarkiertTHENi6ELSEj6END IF.END PROCn3;PROCz6(TEXT CONSTu1,INT CONSTv1,w1):IFw1-v1>=r0THENoutsubtext(u1,v1,v1+r0-1)ELSEoutsubtext(u1,v1,w1);r0-w1+v1-1TIMESOUTc0END IF END PROCz6;PROCa7(TEXT CONSTu1,INT CONSTv1,w1):INT VARo2;IFe6=l0CORf7THENo2:=w1ELSEo2:=v1+k0(e6+1).j0-1END IF;outsubtext(u1,v1+k0(e6).j0,o2);IFy0THENout(e0)ELSEg7TIMESOUTc0END IF.f7:k0(e6+1).i0<>k0(e6).i0.g7:s0-o2+v1+k0(e6).j0-1.END PROCa7;PROCp1:d1:=text(l6,r0+3);d1CATf0;INT VARe4;INT CONSTh7:=o0-length(d1)-11;FORe4FROM1UPTOh7REPd1CAT"."END REP;d1CATk6;i7.i7:TEXT VARj7;IFaufkoppeldateiTHENj7:=m6ELSEj7:=eudasdateiname(1)END IF;j7:=subtext(j7,1,h7-20);j7CATc0;replace(d1,r0+21,c0);replace(d1,r0+22,j7).END PROCp1;END PACKETsatzanzeige;
+PACKETuebersichtsanzeigeDEFINESuebersicht,uebersichtsfenster:ROW24INT VARb0;ROW24INT VARc0;FENSTER VARfenster;fensterinitialisieren(fenster);INT VARd0:=24,e0:=79,f0:=1,g0:=1,h0,i0:=-1;BOOL VARj0,k0;TEXT VARl0;LETm0="",n0=""15"",o0=""14"",p0=" ",q0=""7"",r0=""5"";LETs0=#901
+#""15"Satznr. ",t0=#902
+#"  << DATEIENDE >>",u0=#903
+#"UEBERSICHT:   Rollen: HOP OBEN, HOP UNTEN   Beenden: ESC q   Hilfe: ESC ?";PROCuebersichtsfenster(INT CONSTv0,w0,x0,y0):fenstergroessesetzen(fenster,v0,w0,x0,y0);j0:=v0+x0>=80;d0:=y0;e0:=x0;f0:=w0;g0:=v0END PROCuebersichtsfenster;PROCuebersicht(TEXT CONSTz0,PROCa1):TEXT VARb1;BOOL VARc1;INT VARd1:=1,e1:=0,f1:=1;fensterzugriff(fenster,c1);statusanzeigen(u0);g1;k0:=FALSE;h1;REPi1;j1;k1END REP.g1:IFz0=m0THENl1ELSEl0:=z0;i0:=dateiversionEND IF.l1:IFi0<>dateiversionTHENm1;i0:=dateiversionEND IF.m1:INT VARn1;l0:=m0;FORn1FROM1UPTOanzahlfelderREPl0CATcode(n1)END REP.i1:WHILEe1<d0REPb1:=getcharety;IFb1<>""THEN LEAVEi1END IF;o1;e1INCR1END REP;p1;getchar(b1).o1:IFe1=0THENq1ELIFe1=1THENr1ELSEs1END IF.q1:cursor(g0,f0);out(s0);h0:=e0-10;INT VARfeldindex;FORfeldindexFROM1UPTOlength(l0)WHILEh0>0REPfeldnamenbearbeiten(code(l0SUBfeldindex),PROC(TEXT CONST,INT CONST,INT CONST)t1)END REP;u1;cursor(g0+e0-1,f0);out(o0).r1:v1(1);w1(1);x1.s1:cursor(g0,f0+e1);IFdateiendeTHENb0(e1):=0;h0:=e0;u1ELSEy1;w1(e1);
+x1END IF.y1:weiter(2);z1;b0(e1):=satznummer;c0(e1):=satzkombination.z1:IF NOT(satzausgewaehltORdateiende)THEN LEAVEuebersichtEND IF.j1:IFd1<e1THENw1(d1)END IF;cursor(g0,f0+d1).p1:k0:=TRUE;WHILEb0(d1)=0REPd1DECR1END REP;w1(d1);v1(d1);a2;k0:=FALSE.k1:SELECTf1OF CASE1:b2CASE2:c2CASE3:d2END SELECT.b2:SELECTpos(""3""10""1""27"+-",b1)OF CASE1:e2CASE2:f2CASE3:f1:=2CASE4:f1:=3CASE5:g2CASE6:h2OTHERWISEout(q0)END SELECT.c2:SELECTpos(""3""10""13"",b1)OF CASE1:i2CASE2:j2CASE3:k2OTHERWISEout(q0)END SELECT;f1:=1.d2:SELECTpos("19qh?",b1)OF CASE1:l2CASE2:m2CASE3,4:n2CASE5:o2OTHERWISEout(q0)END SELECT;f1:=1.e2:IFd1>1THENd1DECR1;ELSEp2(1);e1:=1END IF.f2:IF NOTdateiendeTHEN IFd1<d0-1THENd1INCR1ELSEb0(1):=b0(2);c0(1):=c0(2);e1:=1END IF END IF.g2:IF NOTsatzmarkiertTHENmarkierungaendernEND IF.h2:IFsatzmarkiertTHENmarkierungaendernEND IF.i2:IFd1>1THENd1:=1ELSEp2(d0-1);e1:=1END IF.j2:IFd1=d0-1AND NOTdateiendeTHENweiter(2);h1;e1:=1ELSEd1:=d0-1END IF.k2:IFd1<>1THENb0(1):=b0(d1);c0(1):=c0(d1);d1:=1;e1:=1END IF.
+l2:aufsatz(1);IF NOTsatzausgewaehltTHENweiter(2)END IF;h1;d1:=1;e1:=1.m2:aufsatz(32767);h1;p2(d0-2);e1:=1.n2:k0:=true;w1(d1);LEAVEuebersicht.o2:a1;statusanzeigen(u0);e1:=0.END PROCuebersicht;PROCp2(INT CONSTq2):INT VARn1;v1(1);FORn1FROM1UPTOq2WHILEsatznummer>1REPzurueck(2)END REP;h1END PROCp2;PROCv1(INT CONSTr2):aufsatz(b0(r2));WHILEsatzkombination<>c0(r2)REPweiter(1)END REP END PROCv1;PROCh1:b0(1):=satznummer;c0(1):=satzkombinationEND PROCh1;BOOL PROCs2(INT CONSTr2):satznummer=b0(r2)CANDsatzkombination=c0(r2)END PROCs2;PROCt1(TEXT CONSTt2,INT CONSTu2,v2):INT CONSTd0:=min(h0,v2-u2+1);outsubtext(t2,u2,u2+d0-1);h0DECRd0;IFh0>=2THENout(", ");h0DECR2ELIFh0=1THENout(",");h0:=0END IF END PROCt1;PROCw1(INT CONSTr2):cursor(g0,f0+r2);IFk0THENout(n0)ELSEout(p0)END IF;outtext(text(b0(r2)),1,5);IFk0THENout(o0)ELSEout(p0)END IF;h0:=e0-7END PROCw1;PROCu1:IFj0THENout(r0)ELSEh0TIMESOUTp0END IF END PROCu1;PROCx1:IFsatzausgewaehltTHENa2;w2ELIFdateiendeTHENout(t0);h0DECR17ELSEa2;out("<< >>");h0DECR5END 
+IF;u1.w2:INT VARfeldindex;FORfeldindexFROM1UPTOlength(l0)WHILEh0>0REPfeldbearbeiten(code(l0SUBfeldindex),PROC(TEXT CONST,INT CONST,INT CONST)t1)END REP.END PROCx1;PROCa2:IFsatzmarkiertTHENout("+ ")ELSEout("- ")END IF;h0DECR2END PROCa2;END PACKETuebersichtsanzeige;
+PACKETeudassteuerungDEFINESeudas,einzelsicherung,suchen,aendern,einfuegen,prueffehlereditieren,feldstruktur,dateiverwaltung,archivverwaltung,edit,dateinamenanfordern,ausfuehrung,einzelausfuehrung:LETb0=1003,c0=3243;LETd0="",e0=" ",f0=""27"z",g0=""4"",h0=""5"";FILE VARi0;DATASPACE VARj0;INT VARk0,l0:=dateiversion-1;FENSTER VARm0,n0,o0,p0;TEXT VARq0;fensterinitialisieren(m0);fensterinitialisieren(n0);fensterinitialisieren(o0);fensterinitialisieren(p0);fenstergroessesetzen(m0,1,2,79,23);fenstergroessesetzen(n0,1,2,15,22);fenstergroessesetzen(o0,16,2,64,22);fenstergroessesetzen(p0,1,24,79,1);dialogfenster(16,2,64,22);anzeigefenster(16,2,64,23);uebersichtsfenster(1,2,79,23);TEXT VARr0;BOOL VARs0:=FALSE;LETt0=#1001
+#"EUDAS.Öffnen",u0=#1002
+#"EUDAS.Einzelsatz",v0=#1003
+#"EUDAS.Gesamtdatei",w0=#1004
+#"EUDAS.Drucken",x0=#1005
+#"EUDAS.Dateien",y0=#1006
+#"EUDAS.Archiv";LETz0=#1007
+#"EUDAS kann nicht unter EUDAS aufgerufen werden",a1=#1008
+#"Suchbedingung einstellen",b1=#1009
+#"Alle Saetze drucken",c1=#1010
+#"Alle markierten Satze drucken",d1=#1011
+#"Aktuellen Satz drucken",e1=#1012
+#"Mit neuer Auswahl noch einmal",f1=#1013
+#"Akt.Datei: ",g1=#1014
+#" Datum: ";PROCh1:cursor(30,6);out("EEEEE U   U DDDD    A    SSSS");cursor(30,7);out("E     U   U D   D  A A  S");cursor(30,8);out("EEE   U   U D   D AAAAA  SSS");cursor(30,9);out("E     U   U D   D A   A     S");cursor(30,10);out("EEEEE  UUU  DDDD  A   A SSSS");cursor(30,12);out("Version 4.3");cursor(30,13);out("Stand: 13.08.87");cursor(30,15);out("(C) COPYRIGHT:");cursor(30,16);out("Thomas Berlage");cursor(30,17);out("Software-Systeme")END PROCh1;PROCeudas:IFaktuellereditor>0THENi1ELIFs0THENerrorstop(z0)ELSEj1END IF.j1:page;bildschirmneu;h1;k0:=heapsize;k1;disablestop;s0:=TRUE;menueanbieten(ROW6TEXT:(t0,u0,v0,w0,x0,y0),n0,TRUE,PROC(INT CONST,INT CONST)l1);s0:=FALSE;enablestop;m1;page;bildschirmneuEND PROCeudas;PROCi1:TEXT VARn1;o1;m1;IFp1THEN LEAVEi1END IF;q1(FALSE);aufsatz(1);r1(n1);REPs1;uebersicht(n1,PROCt1);o1;u1UNTILv1END REP;dateienloeschen(FALSE).p1:INT VARw1;FORw1FROM1UPTOanzahldateienREP IFinhaltveraendert(w1)THEN LEAVEp1WITH TRUE END IF END REP;FALSE.s1:IFja(a1,
+"JA/Suchmuster")THENsuchen;allesneuEND IF.u1:IFmarkiertesaetze=0CANDx1THENdateinamenanfordern(y1);einzelausfuehrung(PROC(TEXT CONST)z1,b0);ELIFmarkiertesaetze>0CANDa2THENdateinamenanfordern(y1);einzelausfuehrung(PROC(TEXT CONST)z1,b0);markierungenloeschenELIFb2THENmarkierungenloeschen;markierungaendern;dateinamenanfordern(y1);einzelausfuehrung(PROC(TEXT CONST)z1,b0);markierungenloeschenEND IF.x1:ja(b1,"JA/alle Satze").a2:ja(c1,"JA/alle markierten").b2:ja(d1,"JA/Einzelsatz drucken").v1:NOTja(e1,"JA/noch einmal").END PROCi1;PROCo1:bildschirmneu;cursor(1,1);out(g0);cursor(15,1);23TIMESOUT(""10":"8"")END PROCo1;PROCz1(TEXT CONSTc2):d2;disablestop;drucke(c2);e2;o1END PROCz1;PROCl1(INT CONSTf2,g2):enablestop;SELECTf2OF CASE0:h2CASE1:i2(g2)CASE2:j2(g2)CASE3:k2(g2)CASE4:l2(g2)CASE5:dateiverwaltung(g2)CASE6:archivverwaltung(g2)END SELECT.h2:IFanzahldateien=0THENm2(FALSE);n2(FALSE)ELIF NOTaendernerlaubtTHENn2(FALSE)END IF;o2;waehlbar(6,6,p2);waehlbar(6,9,NOTp2);IFq2THENwaehlbar(1,8,FALSE);
+waehlbar(6,7,FALSE)END IF.q2:FALSE.END PROCl1;PROCm2(BOOL CONSTr2):INT VARs2;waehlbar(1,4,r2);waehlbar(1,5,r2);waehlbar(1,7,r2);FORs2FROM1UPTO11REPwaehlbar(2,s2,r2)END REP;waehlbar(3,1,r2);waehlbar(3,4,r2);waehlbar(3,6,r2);waehlbar(4,1,r2)END PROCm2;PROCo2:BOOL VARr2:=anzahldateien=1ANDaendernerlaubt;waehlbar(1,6,r2);waehlbar(3,5,r2);r2:=anzahldateien>0ANDanzahldateien<10AND NOTaufkoppeldatei;waehlbar(1,2,r2);waehlbar(1,3,r2)END PROCo2;PROCn2(BOOL CONSTr2):INT VARs2;FORs2FROM7UPTO10REPwaehlbar(2,s2,r2)END REP;waehlbar(3,2,r2);waehlbar(3,3,r2)END PROCn2;PROCk1:fensterveraendert(p0);r0:=""6""23""0"";r0CATf1;IFanzahldateien>0THENr0CAT"""";r0CATeudasdateiname(1);r0CAT""""END IF;IFanzahldateien>1THENr0CAT" .. "END IF;r0CAT""5""6""23"";r0CATcode(79-length(date)-length(g1));r0CATg1;r0CATdateEND PROCk1;PROCt2(TEXT CONSTu2,v2):BOOL VARw2;fensterzugriff(p0,w2);IFw2THENout(r0);cursor(35,24);out(u2);IFv2<>d0THENout("""");outsubtext(v2,1,22-length(u2));out(""" ")END IF END IF END PROCt2;THESAURUS 
+VARx2:=emptythesaurus;BOOL VARy2,z2:=FALSE;TASK VARa3;TEXT VARb3:=d0,c3:=d0;LETd3=#1015
+#" Manager: ",e3=#1017
+#"Keine Sicherung noetig.",f3=#1018
+#"Interne Arbeitskopien loeschen",g3=#1019
+#"Arbeitskopie ",h3=#1020
+#" unveraendert.",i3=#1021
+#" veraendert! Sichern",j3=#1022
+#"Alte Version ueberschreiben",k3=#1023
+#"Sondern unter dem Namen:",l3=#1024
+#" ueberschreiben",m3=#1025
+#"Datei wieder sortieren",n3=#1026
+#"Notizen",o3=#1027
+#"Name Managertask:",p3=#1028
+#"Task existiert nicht !",q3=#1029
+#"Wollen Sie etwas veraendern (eine Arbeitskopie anlegen)",r3=#1030
+#"Alle Markierungen gelöscht.",s3=#1032
+#"Pruefbedingungen",t3=#1033
+#"Feldnamen oder Feldtypen aendern",u3=#1034
+#"Feldnamen anfuegen",v3=#1035
+#"Neuer Feldname:",w3=#1036
+#"Neuer Typ (TEXT,DIN,ZAHL,DATUM):",x3=#1037
+#"Neue Feldnamen",y3=#1038
+#"TEXT",z3=#1039
+#"DIN",a4=#1040
+#"ZAHL",b4=#1041
+#"DATUM",c4=#1042
+#"Alte Feldreihenfolge aendern",d4=#1043
+#""7"ACHTUNG: System voll, Dateien loeschen!";PROCi2(INT CONSTg2):SELECTg2OF CASE0:e4CASE1:f4CASE2:g4CASE3:h4CASE4:i4CASE5:j4CASE6:k4CASE7:l4CASE8:m4OTHERWISEn4END SELECT;t2(d3,b3);o4;p4.e4:IFanzahldateien=0THENl1(0,0)END IF.f4:m1;q1(TRUE).g4:disablestop;q4;ausfuehrung(PROC(TEXT CONST)r4,c0);s4;enablestop;o2.h4:disablestop;q4;ausfuehrung(PROC(TEXT CONST)t4,c0);s4;enablestop;o2.i4:IFaendernerlaubtTHENu4ELSEdialog;out(e3);v4END IF;w4.u4:INT VARw1;FORw1FROM1UPTOanzahldateienREPeinzelsicherung(w1)END REP;IFja(f3,"JA/Dateien loeschen")THENx4;dateienloeschen(TRUE)END IF.w4:IFanzahldateien=0THENm2(FALSE);n2(FALSE)END IF;o2;k1.v4:INT CONSTy4:=anzahldateien;dateienloeschen(FALSE);FORw1FROM1UPTOy4REP IFz4(w1)THENa5(eudasdateiname(w1))END IF END REP.j4:b5;dialogfensterloeschen.k4:zugriff(PROC(EUDAT VAR)feldstruktur).l4:c5;dialogfensterloeschen.m4:b3:="";fensterveraendert(p0);editget(o3,b3,"","GET/multi task");IFb3=""THENz2:=FALSE ELIFexists(/b3)THENa3:=task(b3);z2:=TRUE ELSEz2:=FALSE;b3:="";
+errorstop(p3)END IF.p4:IFheapsize-k0>4THENcollectheapgarbage;k0:=heapsizeEND IF.n4:IFg2=-1THENdialogfensterloeschen;fensterveraendert(p0);LEAVEi2END IF.END PROCi2;PROCm1:BOOL VARd5:=FALSE;IFaendernerlaubtTHENe5END IF;IFd5THENdialogEND IF.e5:INT VARw1;FORw1FROM1UPTOanzahldateienREP IFinhaltveraendert(w1)THENeinzelsicherung(w1);d5:=TRUE;f5END IF END REP.f5:IFw1=1CANDstd=eudasdateiname(1)THENlastparam(d0)END IF.END PROCm1;PROCeinzelsicherung(INT CONSTw1):g5;IFinhaltveraendert(w1)THEN IFja(h5,"JA/sichere")THENi5END IF ELSEdialog;out(h5)END IF.g5:TEXT VARh5:=g3;h5CATtextdarstellung(eudasdateiname(w1));IFinhaltveraendert(w1)THENh5CATi3ELSEh5CATh3END IF.i5:TEXT VARname:=eudasdateiname(w1);IFja(j3,"JA/alte version")THENforget(name,quiet)ELIFz4(w1)THENerrorstop(d0)ELSEj5END IF;sichere(w1,name);k5.j5:editget(k3,name,"","GET/Sicherungsname");IFexists(name)THENl5END IF.l5:IFja(textdarstellung(name)+l3,"JA/ueber")THENforget(name,quiet)ELSEeinzelsicherung(w1);LEAVEeinzelsicherungEND IF.k5:EUDAT VAR
+m5;oeffne(m5,name);IFn5CANDo5THENp5;sortiere(m5)END IF.n5:sortierreihenfolge(m5)<>d0CANDunsortiertesaetze(m5)>0.o5:ja(m3,"JA/Sicherungssortierung").END PROCeinzelsicherung;PROCq1(BOOL CONSTq5):IFaendernerlaubtTHENx4END IF;dateienloeschen(TRUE);m2(FALSE);n2(FALSE);forget(j0);disablestop;q4;y2:=q5;einzelausfuehrung(PROC(TEXT CONST)r5,c0);s4;o2;enablestop;IFanzahldateien>0THENm2(TRUE);n2(aendernerlaubt)END IF END PROCq1;PROCq4:IFz2THENx2:=ALLa3END IF END PROCq4;PROCs4:x2:=emptythesaurus;k1END PROCs4;PROCx4:INT VARw1;FORw1FROM1UPTOanzahldateienREP IFz4(w1)THENs5END IF END REP.s5:IFt5THENdisablestop;u5;save(eudasdateiname(w1),a3);v5;enablestop;forget(eudasdateiname(w1),quiet)ELSEfree(eudasdateiname(w1),a3)END IF;w5(w1,FALSE).t5:exists(eudasdateiname(w1)).END PROCx4;PROCx5:IFz4(anzahldateien)ANDaendernerlaubtTHENforget(eudasdateiname(anzahldateien),quiet)END IF END PROCx5;PROCr5(TEXT CONSTc2):BOOL VARy5;z5;oeffne(c2,y5);x5.z5:IFa6ANDy2THENb6(c2);EUDAT VARm5;oeffne(m5,c2);feldstruktur(m5);y5
+:=TRUE ELSEy5:=y2CANDja(q3,"JA/oeffne");c6(c2,y5)END IF.a6:NOTexists(c2)AND NOT(x2CONTAINSc2).END PROCr5;PROCr4(TEXT CONSTc2):c6(c2,aendernerlaubt);kette(c2);x5END PROCr4;PROCt4(TEXT CONSTc2):c6(c2,aendernerlaubt);kopple(c2);x5END PROCt4;PROCc6(TEXT CONSTc2,BOOL CONSTd6):BOOL VARe6:=FALSE;IFz2THENf6END IF;w5(anzahldateien+1,e6).f6:IF(x2CONTAINSc2)CAND(NOTexists(c2)CORg6)THEN IFd6THENlock(c2,a3)END IF;forget(c2,quiet);fetch(c2,a3);e6:=TRUE END IF.g6:ja(textdarstellung(c2)+h6,"JA/fetch").END PROCc6;PROCw5(INT CONSTi6,BOOL CONSTe6):WHILElength(c3)<i6REPc3CATe0END REP;replace(c3,i6,j6).j6:IFe6THEN"-"ELSEe0END IF.END PROCw5;BOOL PROCz4(INT CONSTi6):IFlength(c3)<i6THEN FALSE ELSE(c3SUBi6)<>e0END IF END PROCz4;PROCb5:notizenlesen(3,q0);DATASPACE VARk6:=nilspace;FILE VARf:=sequentialfile(output,k6);disablestop;headline(f,n3);l6(f,q0,m0,"EDIT/Notizen");forget(k6);enablestop;IFaendernerlaubtTHENnotizenaendern(3,q0)END IF END PROCb5;PROCl6(FILE VARf,TEXT VARm6,FENSTER CONSTn6,TEXT CONSTo6):LETp6=
+"#-#";enablestop;q6;r6;s6.q6:INT VARt6:=1,u6;REPu6:=pos(m6,p6,t6);IFu6=0THENputline(f,subtext(m6,t6))ELSEputline(f,subtext(m6,t6,u6-1))END IF;t6:=u6+3UNTILu6=0ORt6>length(m6)END REP.r6:modify(f);edit(f,n6,o6,TRUE).s6:TEXT VARv6;m6:=d0;input(f);WHILE NOTeof(f)REPgetline(f,v6);w6;m6CATv6;m6CATp6END REP.w6:IF(v6SUBlength(v6))=e0THENv6:=subtext(v6,1,length(v6)-1)END IF.END PROCl6;PROCfeldstruktur(EUDAT VARm5):SATZ VARx6;feldnamenlesen(m5,x6);IFy6THENz6END IF;IFja(t3,"JA/Feldaendern")THENa7END IF.y6:IFfelderzahl(x6)>0THENja(u3,"JA/feldnamen")ELSE TRUE END IF.z6:DATASPACE VARk6:=nilspace;FILE VARf:=sequentialfile(output,k6);disablestop;b7(f,x6);forget(k6);enablestop;feldnamenaendern(m5,x6).a7:c7;auswahlanbieten("EUDAS-Felder",o0,"AUSWAHL/Felder",PROC(TEXT VAR,INT CONST)d7);INT VARe7:=1;WHILEwahl(e7)>0REPf7;e7INCR1END REP;feldnamenaendern(m5,x6).c7:satzinitialisieren(g7);FORe7FROM1UPTOfelderzahl(x6)REPfeldlesen(x6,e7,q0);feldaendern(g7,e7,h7+textdarstellung(q0))END REP.h7:"("+i7(feldinfo(m5,
+e7))+") ".f7:TEXT VARj7;feldlesen(x6,wahl(e7),j7);editget(v3,j7,"","GET/feldname");feldaendern(x6,wahl(e7),j7);TEXT VARk7:=i7(feldinfo(m5,wahl(e7)));REPeditget(w3,k7,"","GET/feldtyp")UNTILl7(k7)>=-1END REP;feldinfo(m5,wahl(e7),l7(k7)).END PROCfeldstruktur;PROCc5:enablestop;DATASPACE VARk6:=nilspace;FILE VARf:=sequentialfile(output,k6);headline(f,s3);notizenlesen(1,q0);disablestop;l6(f,q0,m0,"EDIT/Pruefbed");forget(k6);enablestop;IFaendernerlaubtTHENnotizenaendern(1,q0)END IF.END PROCc5;PROCb7(FILE VARf,SATZ VARx6):enablestop;m7;n7.m7:modify(f);headline(f,x3);edit(f,o0,"EDIT/Feldnamen",TRUE).n7:INT VARe7:=felderzahl(x6);input(f);WHILE NOTeof(f)REPgetline(f,q0);w6;e7INCR1;feldaendern(x6,e7,q0)END REP.w6:IF(q0SUBlength(q0))=e0THENq0:=subtext(q0,1,length(q0)-1)END IF.END PROCb7;TEXT PROCi7(INT CONSTk7):SELECTk7+1OF CASE0:y3CASE1:z3CASE2:a4CASE3:b4OTHERWISEd0END SELECT END PROCi7;INT PROCl7(TEXT CONSTo7):IFo7=y3THEN-1ELIFo7=z3THEN0ELIFo7=a4THEN1ELIFo7=b4THEN2ELSE-2END IF END PROCl7;PROCo4:
+INT VARp7,q7;storage(p7,q7);IFq7>p7THENneuerdialog;dialog;out(d4)END IF END PROCo4;BOOL VARr7,s7:=FALSE,t7:=FALSE;LETu7=#1044
+#"SATZ AENDERN:    Abbruch: ESC h    Beenden: ESC q    Hilfe: ESC ?",v7=#1045
+#"SATZ EINFUEGEN:    Abbruch: ESC h    Beenden: ESC q    Hilfe: ESC ?",w7=#1046
+#"SUCHMUSTER EINGEBEN:    Abbruch: ESC h    Beenden: ESC q    Hilfe: ESC ?",x7=#1047
+#"Umschalten auf Koppeldatei ",y7=#1048
+#"Koppelfelder uebernehmen",z7=#1049
+#"Ungueltige Satznummer",a8=#1050
+#"Neue Satznummer:",b8=#1051
+#" Bitte warten.. ",c8=#1052
+#"wzK",d8=#1053
+#"wz";LETe8=""6""23""0"              :",f8=""6""23""0"              :"5"";PROCj2(INT CONSTg2):SELECTg2OF CASE0:g8CASE1:h8CASE2:i8CASE3:j8CASE4:k8CASE5:l8CASE6:m8CASE7:n8CASE8:o8CASE9:p8CASE10:q8CASE11:r8CASE12:s8CASE13:t8CASE14:u8CASE15:v8CASE16:w8OTHERWISEx8END SELECT;o4.g8:exitzeichen(d8).h8:p5;weiter(2);bildausgeben(FALSE).i8:p5;zurueck(2);bildausgeben(FALSE).k8:suchen;bildausgeben(TRUE).l8:suchbedingungloeschen;bildausgeben(FALSE).j8:TEXT VARy8:=d0;z8;editget(a8,y8,"","GET/auf satz");INT CONSTa9:=int(y8);IFy8=d0THENbildausgeben(FALSE)ELIFlastconversionokTHENaufsatz(a9);bildausgeben(FALSE)ELSEerrorstop(z7)END IF.n8:einfuegen;bildausgeben(TRUE).o8:aendern;bildausgeben(TRUE).m8:markierungaendern;bildausgeben(FALSE).p8:b9;z8;dateinamenanfordern(c9);einzelausfuehrung(PROC(TEXT CONST)d9,c0);bildausgeben(TRUE).q8:b9;z8;dateinamenanfordern(e9);einzelausfuehrung(PROC(TEXT CONST)holesatz,c0);bildausgeben(TRUE).r8:TEXT VARf9;z8;g9(f9);IFf9<>d0THENfeldauswahl(f9)END IF;bildausgeben(TRUE).s8:h9
+;rollen(-23);IFanzahldateien>0THENbildausgeben(FALSE)END IF.t8:h9;rollen(23);IFanzahldateien>0THENbildausgeben(FALSE)END IF.u8:h9;rollen(-9999);IFanzahldateien>0THENbildausgeben(FALSE)END IF.v8:h9;rollen(9999);IFanzahldateien>0THENbildausgeben(FALSE)END IF.w8:IFaufkoppeldateiTHENi9ELSEj9END IF;IFanzahldateien>0THENbildausgeben(TRUE)END IF.i9:IF(t7ORs7)THENk9;l9ELSEaufkoppeldatei(0)END IF;o2.k9:z8;IF NOTdateiendeCANDja(y7,"JA/uebernehmen")THENaufkoppeldatei(1)ELSEaufkoppeldatei(0)END IF.l9:s7:=FALSE;IFt7THENt7:=FALSE;aendernELSEm9(TRUE)END IF.x8:IFg2=-2THEN IFanzahldateien>0THENn9;bildausgeben(FALSE)ELSEz8END IF ELSEdialogfensterloeschen;fensterveraendert(p0)END IF.n9:out(e8).z8:out(f8).END PROCj2;PROCsuchen:disablestop;exitzeichen("");statusanzeigen(w7);suchen(PROCo9);exitzeichen(d8)END PROCsuchen;PROCo9:hilfeanbieten("EDIT/Suchen",o0)END PROCo9;PROCp5:statusanzeigen(b8)END PROCp5;PROCeinfuegen:m9(FALSE)END PROCeinfuegen;PROCm9(BOOL CONSTp9):BOOL VARq9:=p9;r9;REPstatusanzeigen(v7);IFq9
+THENaendern(PROCs9);q9:=FALSE ELSEeinfuegen(PROCs9)END IF;t9;u9END REP.u9:SELECTpos(c8,exitdurch)OF CASE0:IFr7THENsatzloeschenENDIF;LEAVEm9CASE1:IFr7THENsatzloeschenELSEp5;weiter(2)END IF CASE2:IFr7THENsatzloeschenELSEp5;zurueck(2)END IF CASE3:j9;IFaufkoppeldateiTHENs7:=TRUE;LEAVEm9END IF;q9:=TRUE END SELECT.END PROCm9;PROCs9:hilfeanbieten("EDIT/Einfuegen",o0)END PROCs9;PROCr9:IFanzahlkoppeldateien>0AND NOTaufkoppeldateiTHENexitzeichen(c8)ELSEexitzeichen(d8)END IF END PROCr9;PROCaendern:r9;kommandoauftastelegen("F","prueffehler editieren");REPstatusanzeigen(u7);aendern(PROCv9);t9;w9END REP.w9:SELECTpos(c8,exitdurch)OF CASE0:IFr7THENsatzloeschenENDIF;LEAVEaendernCASE1:IFr7THENsatzloeschenELSEp5;weiter(2)END IF CASE2:IFr7THENsatzloeschenELSEp5;zurueck(2)END IF CASE3:j9;IFaufkoppeldateiTHENt7:=TRUE;LEAVEaendernEND IF END SELECT.END PROCaendern;PROCv9:hilfeanbieten("EDIT/Aendern",o0)END PROCv9;PROCprueffehlereditieren:IFl0=dateiversionTHENmodify(i0);edit(i0)END IF END
+PROCprueffehlereditieren;PROCj9:INT VARw1:=folgedatei(0);WHILEw1>0REPout( f8);IFx9THENaufkoppeldatei(w1);o2;LEAVEj9END IF;w1:=folgedatei(w1)END REP.x9:ja(x7+textdarstellung(eudasdateiname(w1)),"JA/umschalten").END PROCj9;PROCy9(TEXT CONSTv6,INT CONSTz9):outsubtext(v6,a10);out(h0).a10:pos(v6,e0,6)+1+z9-z9.END PROCy9;PROCt9:feldbearbeiten(1,PROC(TEXT CONST,INT CONST,INT CONST)b10)END PROCt9;PROCb10(TEXT CONSTx6,INT CONSTt6,u6):r7:=t6<3ORt6>length(x6)+u6-u6END PROCb10;PROCh9:cursor(15,24)END PROCh9;PROCd9(TEXT CONSTc2):IFexists(c2)THENc10ELSEb6(c2)END IF;p5;tragesatz(c2).c10:IFd10(c2)<>0THENerrorstop(e10)END IF.END PROCd9;PROCg9(TEXT VARf9):auswahlanbieten("EUDAS-Anzeigefelder",o0,"AUSWAHL/Anzeigefelder",PROC(TEXT VAR,INT CONST)f10);f9:=d0;INT VARy8:=1;WHILEwahl(y8)>0REPf9CATcode(wahl(y8));y8INCR1END REP END PROCg9;LETr8=#1054
+#"Angezeigte Felder auswaehlen",g10=#1055
+#" aufsteigend sortieren";DATASPACE VARh10;PROCk2(INT CONSTg2):SELECTg2OF CASE1:i10CASE2:j10CASE3:k10CASE4:l10CASE5:m10CASE6:n10OTHERWISEn4END SELECT;o4.j10:b9;dateinamenanfordern(c9);einzelausfuehrung(PROC(TEXT CONST)o10,c0).i10:b9;dateinamenanfordern(c9);einzelausfuehrung(PROC(TEXT CONST)p10,c0);dialogfensterloeschen;t2("","").k10:dateinamenanfordern(q10);ausfuehrung(PROC(TEXT CONST)r10,b0);dialogfensterloeschen;t2("","").l10:TEXT VARs10;r1(s10);uebersicht(s10,PROCt1);dialogfensterloeschen;t2("","").m10:zugriff(PROC(EUDAT VAR)t10).n10:markierungenloeschen;dialog;out(r3).n4:IFg2=-1THENdialogfensterloeschen;fensterveraendert(p0)ELIFg2=-2THENt2("","")END IF.END PROCk2;PROCb9:IFd10(std)<>0THENlastparam(d0)END IF END PROCb9;PROCo10(TEXT CONSTc2):BOOL VARu10;IFexists(c2)THENc10;v10ELSEb6(c2);u10:=FALSE END IF;BOOL CONSTw10:=ja(x10,"JA/sortieren");p5;y10;trage(c2,i0,u10);z10;IFw10THEN EUDAT VARm5;oeffne(m5,c2);sortiere(m5)END IF.c10:IFd10(c2)<>0THENerrorstop(e10)END IF.v10:u10:=ja(a11,
+"JA/testen").y10:IFu10THENforget(j0);j0:=nilspace;i0:=sequentialfile(output,j0);l0:=dateiversionELSEforget(j0);l0:=dateiversion-1END IF.z10:IFu10CANDlines(i0)>0THENdialog;put(lines(i0));put(b11)END IF.END PROCo10;PROCr10(TEXT CONSTc2):IF NOTexists(c2)THENc11(c2,"EDIT/Verarbeite")END IF;d2;FILE VARf:=sequentialfile(input,c2);disablestop;verarbeite(f);e2.END PROCr10;PROCr1(TEXT VARs10):s10:=d0;IFja(r8,"JA/Ub.Felder")THENg9(s10)END IF END PROCr1;PROCt1:hilfeanbieten("UEBERSICHT",m0)END PROCt1;PROCp10(TEXT CONSTc2):disablestop;h10:=nilspace;d11(c2);forget(h10)END PROCp10;PROCd11(TEXT CONSTc2):TEXT VARe11:="";FILE VARf;EUDAT VARm5;BOOL VARw10:=FALSE;enablestop;IFexists(c2)THENf11ELSEb6(c2)END IF;editget(g11,e11,"","GET/kopiermuster");IFexists(e11)THENf:=sequentialfile(input,e11)ELSEh11;stdkopiermuster(c2,f)END IF;modify(f);i11;j11.f11:IFd10(c2)<>0THENerrorstop(e10)END IF;oeffne(m5,c2);IFsortierreihenfolge(m5)<>d0THENw10:=ja(x10,"JA/sortieren")END IF.h11:IFe11=d0THENf:=sequentialfile(output,
+h10)ELSEb6(e11);f:=sequentialfile(output,e11)END IF.i11:edit(f,m0,"EDIT/Kopiermuster",TRUE);d2;kopiere(c2,f).j11:IFw10THENoeffne(m5,c2);sortiere(m5)END IF.END PROCd11;INT PROCd10(TEXT CONSTc2):INT VARw1;FORw1FROM1UPTOanzahldateienREP IFeudasdateiname(w1)=c2THEN LEAVEd10WITHw1END IF END REP;0END PROCd10;PROCc11(TEXT CONSTc2,k11):IF NOTexists(c2)THENb6(c2)END IF;FILE VARf:=sequentialfile(modify,c2);edit(f,m0,k11,TRUE)END PROCc11;PROCd2:p5;cursor(1,2);out(g0);bildschirmneuEND PROCd2;PROCt10(EUDAT VARm5):TEXT VARl11:=sortierreihenfolge(m5);IFl11=d0CORm11THENn11;p5;sortiere(m5,l11)ELSEp5;sortiere(m5)END IF.m11:ja(c4,"JA/Sortierfelder").n11:feldnamenlesen(m5,g7);auswahlanbieten("EUDAS-Sortierfelder",o0,"AUSWAHL/Sortierfelder",PROC(TEXT VAR,INT CONST)d7);INT VARe7:=1;l11:=d0;WHILEwahl(e7)<>0REPl11CATcode(wahl(e7));o11;e7INCR1END REP.o11:feldlesen(g7,wahl(e7),q0);IFja(textdarstellung(q0)+g10,"JA/Sortierrichtung")THENl11CAT"+"ELSEl11CAT"-"END IF.END PROCt10;PROCf10(TEXT VARname,INT CONSTy8):IF
+y8<=anzahlfelderTHENfeldnamenlesen(y8,name)ELSEname:=d0END IF END PROCf10;LETp11=#1056
+#"Ausgabe automatisch zum Drucker",q11=#1057
+#"Ausgabe in bestimmte Datei",r11=#1058
+#"Name Ausgabedatei:",x10=#1059
+#"Zieldatei anschliessend sortieren",a11=#1060
+#"Pruefbedingungen testen",b11=#1061
+#"Prueffehler festgestellt",e10=#1062
+#"Zieldatei darf nicht geoeffnet sein",g11=#1063
+#"Name Kopiermuster (RET=Std):";LETs11=#1093
+#" zeilenweise formatieren",t11=#1094
+#" seitenweise formatieren";BOOL VARu11:=FALSE,v11:=FALSE;PROCl2(INT CONSTg2):SELECTg2OF CASE1:w11CASE2:x11CASE3:y11CASE4:z11CASE5:a12OTHERWISEn4END SELECT;o4.w11:dateinamenanfordern(y1);ausfuehrung(PROC(TEXT CONST)b12,b0);dialogfensterloeschen;t2("","").x11:direktdrucken(ja(p11,"JA/direkt drucken"));IF NOTdirektdruckenCANDja(q11,"JA/Druckdatei")THEN TEXT VARc2:=d0;editget(r11,c2,"","GET/Druckdatei");IFc2<>d0THENdruckdatei(c2)END IF END IF.y11:ausfuehrung(PROC(TEXT CONST)c12,b0);dialogfensterloeschen;t2("","").z11:ausfuehrung(PROC(TEXT CONST)print,b0).a12:ausfuehrung(PROC(TEXT CONST)d12,b0);dialogfensterloeschen;t2("","").n4:IFg2=-1THENdialogfensterloeschen;fensterveraendert(p0)ELIFg2=-2THENt2("","")END IF.END PROCl2;PROCe2:IFe12THENclearerrorEND IF.e12:iserrorCANDerrormessage=d0.END PROCe2;PROCb12(TEXT CONSTc2):IF NOTexists(c2)THENc12(c2)END IF;d2;disablestop;drucke(c2);e2END PROCb12;PROCc12(TEXT CONSTc2):c11(c2,"EDIT/Druckmuster")END PROCc12;PROCprint(TEXT CONSTc2):do("print ("+
+textdarstellung(c2)+")")END PROCprint;PROCd12(TEXT CONSTc2):IFja(textdarstellung(c2)+s11,"JA/zeilenform")THENf12END IF;IFja(textdarstellung(c2)+t11,"JA/seitenform")THENseitenformatierenEND IF.f12:IFu11THENautoform(c2)ELSElineform(c2)END IF;page;bildschirmneu.seitenformatieren:IFv11THENautopageform(c2)ELSEpageform(c2)END IF;bildschirmneu.END PROCd12;PROCg12(BOOL CONSTh12,i12):u11:=h12;v11:=i12END PROCg12;TEXT VARj12;LETk12=#1064
+#" Task: ",l12=#1065
+#"Neuer Name:",m12=#1066
+#"Zieldatei:",n12=#1067
+#" belegt ",o12=#1068
+#"KB.",p12=#1069
+#" existiert nicht.",q12=#1070
+#" in dieser Task loeschen",r12=#1071
+#" neu einrichten";PROCdateiverwaltung(INT CONSTg2):enablestop;SELECTg2OF CASE0:s12CASE1:t12CASE2:u12CASE3:v12CASE4:w12CASE5:x12CASE6:y12OTHERWISEn4END SELECT;o4.s12:j12:=name(myself).y12:ausfuehrung(PROC(TEXT CONST)z12,0).v12:ausfuehrung(PROC(TEXT CONST)a13,0).u12:ausfuehrung(PROC(TEXT CONST)a5,0).t12:disablestop;DATASPACE VARb13:=nilspace;FILE VARf:=sequentialfile(output,b13);list(f);IF NOTiserrorTHENedit(f,o0,"SHOW/Uebersicht",FALSE)END IF;forget(b13);enablestop;c13.w12:ausfuehrung(PROC(TEXT CONST)d13,0).x12:ausfuehrung(PROC(TEXT CONST)e13,0).n4:IFg2=-1THENdialogfensterloeschen;fensterveraendert(p0)ELIFg2=-2THENt2(k12,j12)END IF.END PROCdateiverwaltung;PROCc13:WHILEgetcharety<>d0REP END REP END PROCc13;PROCz12(TEXT CONSTc2):IFtype(old(c2))=c0THENreorganisiere(c2)ELSEreorganize(c2)END IF END PROCz12;PROCa13(TEXT CONSTc2):TEXT VARf13:=c2;IFexists(c2)THENeditget(l12,f13,"","GET/rename")END IF;rename(c2,f13)END PROCa13;PROCa5(TEXT CONSTc2):IFg13THENerrorstop(e10)ELIFexists(c2)CANDh13
+THENforget(c2,quiet)END IF.g13:d10(c2)<>0.h13:ja(textdarstellung(c2)+q12,"JA/forget").END PROCa5;PROCd13(TEXT CONSTc2):TEXT VARi13:=d0;editget(m12,i13,"","GET/copy");copy(c2,i13)END PROCd13;PROCe13(TEXT CONSTc2):dialog;out(textdarstellung(c2));IFexists(c2)THENout(n12);put(dspages(old(c2))DIV2);out(o12)ELSEout(p12)END IF END PROCe13;TEXT VARj13:=d0,k13:="ARCHIVE";INT VARl13:=0;THESAURUS VARm13;BOOL VARn13,p2:=TRUE,o13;LETp13=#1072
+#" Ziel: ",q13=#1073
+#"Archiv heisst ",r13=#1074
+#"Name des Archivs:",s13=#1075
+#"Name Zielarchiv:",t13=#1076
+#"Nr. der Zielstation (od. RETURN):",u13=#1077
+#"Ist das Zielarchiv ein Archivmanager",v13=#1078
+#"Archivdiskette vorher formatieren",w13=#1079
+#"Neuer Archivname:",h6=#1080
+#" im System ueberschreiben",x13=#1081
+#" auf Archiv loeschen",y13=#1082
+#"Archiv ",z13=#1083
+#" ueberschreiben",a14=#1084
+#"Archiv initialisieren",b14=#1085
+#" auf Archiv ueberschreiben";LETc14=#1095
+#"Passwort: ",d14=#1096
+#"Passwort stimmt nicht mit der ersten Eingabe überein",e14=#1097
+#"Passwort zur Kontrolle bitte nochmal eingeben.",f14=#1098
+#"Passwort loeschen",g14=#1099
+#"Unzlaessige Stationsnummer",h14=#1100
+#"Angegebene Task ist kein Manager";PROCarchivverwaltung(INT CONSTg2):enablestop;SELECTg2OF CASE0:i14CASE1:j14CASE2:k14CASE3:l14CASE4:m14CASE5:n14CASE6:o14CASE7:p14CASE8:q14CASE9:r14OTHERWISEs14END SELECT;o4.i14:n13:=FALSE.m14:IFp2THENt14END IF;p5;m13:=ALLu14;ausfuehrung(PROC(TEXT CONST)v14,0).l14:disablestop;w14;p5;m13:=ALLu14;IFx14THENm13:=ALLu14END IF;enablestop;y14(PROC(TEXT CONST)z14).n14:IFp2THENt14END IF;p5;m13:=ALLu14;y14(PROC(TEXT CONST)n14).j14:w14;disablestop;p5;DATASPACE VARb13:=nilspace;f:=sequentialfile(output,b13);list(f,u14);IFx14THENlist(f,u14)END IF;IF NOTiserrorTHENmodify(f);toline(f,1);writerecord(f,headline(f));headline(f,d0);edit(f,o0,"SHOW/Uebersicht",FALSE)END IF;forget(b13);c13;enablestop.k14:w14;a15;FILE VARf:=sequentialfile(output,b15);disablestop;p5;list(f,u14);IFx14THENlist(f,u14)END IF;enablestop;modify(f);insertrecord(f);writerecord(f,headline(f));print(b15);forget(b15,quiet).a15:INT VARs2:=0;TEXT VARb15;REPs2INCR1;b15:="Archivliste "+text(s2)UNTIL NOT
+exists(b15)END REP.o14:w14;IFja(v13,"JA/format")THENc15ELIFd15THEN IFe15THEN LEAVEo14END IF ELSE IFf15THEN LEAVEo14END IF END IF;j5;g15.c15:p5;disablestop;u5;format(u14);v5;enablestop.d15:reserve("",u14);p5;disablestop;m13:=ALLu14;BOOL CONSTh15:=x14;clearerror;enablestop;h15.e15:NOTja(y13+textdarstellung(j13)+z13,"JA/archiv loeschen").f15:NOTja(a14,"JA/archiv init").j5:editget(w13,j13,"","GET/Archivname");reserve(j13,u14).g15:p5;disablestop;u5;clear(u14);v5.p14:TEXT VARi15:=k13;IFn13THENrelease(u14);n13:=FALSE END IF;editget(s13,i15,"","GET/Zielarchiv");IFi15=d0THEN LEAVEp14END IF;j15;p2:=ja(u13,"JA/Zielmanager");k15;waehlbar(6,6,p2);waehlbar(6,9,NOTp2);bildschirmneu;t2(p13,l15+k13).j15:TEXT VARm15:=text(station(myself));IFstation(myself)<>0THENeditget(t13,m15,"","GET/Zielstation")END IF.k15:l13:=int(m15);IF NOTlastconversionokTHENerrorstop(g14)END IF;k13:=i15;n15(u14).l15:IFl13=0THENd0ELSEtext(l13)+"/"END IF.r14:TEXT VARo15:=d0;editget(r13,o15,"","GET/Archivname");reserve(o15,u14);n13
+:=TRUE.s14:IFg2=-1THEN IFn13THENrelease(u14)END IF;dialogfensterloeschen;fensterveraendert(p0)ELIFg2=-2THENt2(p13,l15+k13)END IF.END PROCarchivverwaltung;TASK PROCu14:IFl13=0THENtask(k13)ELSEl13/k13END IF END PROCu14;PROCn15(TASK CONSTo7):INT VARs2;IFstation(o7)=station(myself)THEN FORs2FROM1UPTO5REP IFstatus(o7)=2ORstatus(o7)=6THEN LEAVEn15END IF;pause(10)END REP;errorstop(h14)END IF END PROCn15;PROCt14:TEXT VARw13:=j13;editget(r13,w13,"","GET/Archivname");IF NOTn13ORw13<>j13THENreserve(w13,u14);n13:=TRUE END IF;j13:=w13END PROCt14;PROCw14:IF NOTn13ANDp2THENreserve(j13,u14);n13:=TRUE END IF END PROCw14;BOOL PROCx14:IFp2ANDiserrorTHEN TEXT CONSTp15:=errormessage;IFsubtext(p15,1,14)=q13CANDsubtext(p15,16,20)<>"?????"THENclearerror;q15;LEAVEx14WITH TRUE END IF END IF;FALSE.q15:j13:=subtext(p15,16,length(p15)-1);reserve(j13,u14).END PROCx14;PROCv14(TEXT CONSTc2):disablestop;IF NOT(m13CONTAINSc2)CORr15THENs15;p5;u5;save(c2,u14);v5END IF.r15:ja(textdarstellung(c2)+b14,"JA/save").s15:INT 
+CONSTy8:=d10(c2);IFy8>0CANDaendernerlaubtCANDinhaltveraendert(y8)THENeinzelsicherung(y8)END IF.END PROCv14;PROCz14(TEXT CONSTc2):disablestop;IF NOTexists(c2)CORg6THENp5;u5;fetch(c2,u14);v5END IF.g6:ja(textdarstellung(c2)+h6,"JA/fetch").END PROCz14;PROCn14(TEXT CONSTc2):disablestop;IF NOT(m13CONTAINSc2)CORn14THENp5;u5;erase(c2,u14);v5END IF.n14:ja(textdarstellung(c2)+x13,"JA/erase").END PROCn14;PROCu5:o13:=commanddialogue;commanddialogue(FALSE)END PROCu5;PROCv5:commanddialogue(o13)END PROCv5;PROCy14(PROC(TEXT CONST)t15):TEXT VARc2:=d0;editget(u15,c2,"z","GET/Dateiname");IFc2=f0THENv15ELSElastparam(c2);t15(c2)END IF.v15:w15(m13,0);auswahlanbieten("EUDAS-Archivauswahl",o0,"AUSWAHL/Archiv",PROC(TEXT VAR,INT CONST)x15);y15(PROC(TEXT CONST)t15).END PROCy14;PROCq14:BOUND ROW2TEXT VARz15;DATASPACE VARk6:=nilspace;z15:=k6;disablestop;a16(z15(1));IFz15(1)=d0THENb16ELSEc16END IF;forget(k6).b16:IFja(f14,"JA/pw loeschen")THENdialog;dialog;enterpassword(d0)END IF.c16:dialog;out(e14);a16(z15(2));IF
+z15(1)<>z15(2)THENerrorstop(d14)ELSEdialog;dialog;enterpassword(z15(1))END IF.END PROCq14;PROCa16(TEXT VARd16):enablestop;dialog;out(c14);getsecretline(d16)END PROCa16;SATZ VARg7;LETu15=#1086
+#"Name der Datei:",c9=#1087
+#"Name der Zieldatei:",q10=#1088
+#"Name der Verarbeitungsvorschrift:",y1=#1089
+#"Name des Druckmusters:",e9=#1090
+#"Name der Quelldatei:";LETe16=#1101
+#"Keine Datei zur Auswahl vorhanden.";TEXT VARf16:=u15,g16;PROCw15(THESAURUS CONSTo7,INT CONSTk7):i16;h16;j16;k16.h16:g16:=d0;INT VARs2;FORs2FROM1UPTOanzahldateienREP INT CONSTl16:=feldindex(g7,eudasdateiname(s2));IFl16>0THENg16CATcode(l16)END IF END REP.i16:INT VARm16:=1,t6:=0;satzinitialisieren(g7);REPget(o7,q0,t6);IFq0=d0THEN LEAVEi16ELIFk7=0CORtype(old(q0))=k7THENfeldaendern(g7,m16,q0);m16INCR1END IF END REP.j16:t6:=0;REPget(x2,q0,t6);IFq0=d0THEN LEAVEj16ELIF NOT(o7CONTAINSq0)THENfeldaendern(g7,m16,q0);m16INCR1END IF END REP.k16:IFm16=1THENdialog;out(e16);errorstop(d0)END IF.END PROCw15;PROCx15(TEXT VARv2,INT CONSTm16):IFm16<256THENfeldlesen(g7,m16,v2);IFpos(g16,code(m16))>0THENv2:="<!> "+textdarstellung(v2)ELIFv2<>d0THENv2:=textdarstellung(v2)END IF ELSEv2:=d0END IF END PROCx15;PROCy15(PROC(TEXT CONST)t15):INT VARm16:=1;REP IFwahl(m16)=0THEN LEAVEy15ELSEfeldlesen(g7,wahl(m16),q0);dialog;out(text(m16,3));out(". ");out(textdarstellung(q0));lastparam(q0);t15(q0)END IF;m16INCR1END REP END 
+PROCy15;PROCausfuehrung(PROC(TEXT CONST)t15,INT CONSTk7):enablestop;TEXT VARc2;dateinamenanfordern(c2,k7);IFc2=f0THENy15(PROC(TEXT CONST)t15)ELSElastparam(c2);t15(c2)END IF END PROCausfuehrung;PROCeinzelausfuehrung(PROC(TEXT CONST)t15,INT CONSTk7):enablestop;TEXT VARc2;dateinamenanfordern(c2,k7);IFc2=f0THEN IFwahl(1)=0THENerrorstop(d0)ELSEfeldlesen(g7,wahl(1),c2)END IF END IF;lastparam(c2);t15(c2)END PROCeinzelausfuehrung;PROCdateinamenanfordern(TEXT CONSTu2):f16:=u2END PROCdateinamenanfordern;PROCdateinamenanfordern(TEXT VARc2,INT CONSTk7):IFexists(std)AND(k7=0CORtype(old(std))=k7)THENc2:=stdELSEc2:=d0END IF;disablestop;editget(f16,c2,"z","GET/Dateiname");f16:=u15;enablestop;IFc2=d0THENerrorstop(d0)ELIFc2=f0THENw15(all,k7);auswahlanbieten("EUDAS-Dateiauswahl",o0,"AUSWAHL/Datei",PROC(TEXT VAR,INT CONST)x15);p5END IF END PROCdateinamenanfordern;PROCd7(TEXT VARv2,INT CONSTm16):IFm16<=256THENfeldlesen(g7,m16,v2)ELSEv2:=d0END IF END PROCd7;PROCb6(TEXT CONSTc2):IF NOTja(textdarstellung(c2)+
+r12,"JA/einrichten")THENerrorstop(d0)END IF END PROCb6;LETn16=#1091
+#"EDITIEREN:   Abbruch: ESC h   Verlassen: ESC q   Hilfe: ESC ?",o16=#1092
+#"ZEIGEN:   Blättern: HOP OBEN, HOP UNTEN   Ende: ESC q   Hilfe: ESC ?";INT VARp16;BOOL VARq16,r16;PROCedit(FILE VARf,FENSTER CONSTfenster,TEXT CONSTk11,BOOL CONSTaendern):INT VARs16,t16,u16,v16;fenstergroesse(fenster,s16,t16,u16,v16);fensterveraendert(fenster);enablestop;w16;q16:=aendern;REPx16;openeditor(groesstereditor+1,f,aendern,s16,t16,u16,v16);edit(groesstereditor,"eqvw19dpgn"9"?hF",PROC(TEXT CONST)y16);z16END REP.w16:IFaendernANDt16<3ANDv16>22ANDs16<14ANDu16>75THENr16:=TRUE ELSEr16:=FALSE END IF.z16:SELECTp16OF CASE0:LEAVEeditCASE1:hilfeanbieten(k11,fenster)CASE2:errorstop(d0)END SELECT.END PROCedit;PROCx16:IFq16THENstatusanzeigen(n16)ELSEstatusanzeigen(o16)END IF END PROCx16;PROCy16(TEXT CONSTa17):p16:=pos("?h",a17);IFp16>0THENquitELIFr16CANDa17="F"THENb17;x16ELSEstdkommandointerpreter(a17);x16;bildschirmneuEND IF END PROCy16;PROCb17:IFanzahlfelder>0THENc17;d17;e17END IF.c17:INT VARe7;satzinitialisieren(g7,anzahlfelder);FORe7FROM1UPTOanzahlfelderREPfeldnamenlesen(e7,q0);
+feldaendern(g7,e7,q0)END REP.d17:auswahlanbieten("EUDAS-Editfelder",o0,"AUSWAHL/Feldnamen",PROC(TEXT VAR,INT CONST)d7).e17:INT VARm16:=1;WHILEwahl(m16)>0REP IFm16>1THENpush(e0)END IF;feldnamenlesen(wahl(m16),q0);push("""");push(q0);push("""");m16INCR1END REP.END PROCb17;END PACKETeudassteuerung;
+
diff --git a/eudas/eudas.generator b/eudas/eudas.generator
new file mode 100644
index 0000000..96269e9
--- /dev/null
+++ b/eudas/eudas.generator
@@ -0,0 +1,86 @@
+INT VAR size, used;
+BOOL VAR einzeln,sparen;
+IF (pcb (9) AND 255) = 1 THEN
+  errorstop ("Nicht für Single-User-Systeme geeignet")
+END IF;
+storage (size, used);
+einzeln := size - used < 500;
+soehne loeschen;
+forget ("eudas.generator", quiet);
+page;
+putline ("EUDAS - automatische Generierung");
+putline ("Version 4.3 vom 31.07.87");
+line;
+sparen := no ("Ausfuehrliche Hilfstexte installieren");
+line;
+disable stop;
+do ("TEXT VARt:=additionalcommands");
+IF is error THEN
+  clear error;
+  enable stop;
+  gen ("dummy.text")
+END IF;
+enable stop;
+IF id (0) < 175 THEN
+  gen ("pos.173")
+END IF;
+IF NOT einzeln THEN
+  holen ("eudas.1");
+  holen ("eudas.2");
+  holen ("eudas.3");
+  holen ("eudas.4");
+  holen ("eudas.init");
+  release (archive)
+END IF;
+check off;
+gen ("eudas.1");
+gen ("eudas.2");
+gen ("eudas.3");
+gen ("eudas.4");
+IF anything noted THEN
+  push (""27"q"); note edit; pause (100)
+END IF;
+holen ("eudas.init");
+IF einzeln THEN
+  release (archive)
+END IF;
+IF sparen THEN do ("menue loeschen (TRUE)") END IF;
+do("menuedaten einlesen (""eudas.init"")");
+forget ("eudas.init", quiet);
+check on;
+do ("global manager");
+
+PROC vom archiv (TEXT CONST datei):
+  out (""""); out (datei); putline (""" wird geholt.");
+  fetch (datei, archive)
+END PROC vom archiv;
+
+PROC holen (TEXT CONST datei) :
+  IF NOT exists (datei) THEN vom archiv (datei) END IF
+END PROC holen;
+
+PROC gen (TEXT CONST datei) :
+  holen (datei);
+  out (""""); out (datei); out (""" wird uebersetzt: ");
+  insert (datei);
+  forget (datei, quiet)
+END PROC gen;
+
+PROC soehne loeschen :
+
+  command dialogue (TRUE);
+  access catalogue;
+  TASK VAR sohn := son (myself);
+  WHILE NOT is niltask (sohn) REP
+    TASK CONST naechster := brother (sohn);
+    IF yes ("Sohntask """ + name (sohn) + """ loeschen") THEN
+      end (sohn)
+    ELIF yes ("Generierung abbrechen") THEN
+      errorstop ("")
+    END IF;
+    sohn := naechster
+  END REP
+
+END PROC soehne loeschen;
+
+
diff --git a/eudas/eudas.init b/eudas/eudas.init
new file mode 100644
index 0000000..54fa28d
--- /dev/null
+++ b/eudas/eudas.init
@@ -0,0 +1,1463 @@
+% MENUE "EUDAS.Öffnen"
+% BILD
+--------------
+EUDAS-Datei
+O Öffnen
+E Ketten
+K Koppeln
+--------------
+Arbeitskopie
+S Sichern
+--------------
+Aktuelle Datei
+N Notizen
+F Feldstrukt.
+P Prüfbeding.
+--------------
+Mehrbenutzer
+M Manager
+--------------
+% FELD 1 "EUDAS/1O" "oO"
+% FELD 2 "EUDAS/1E" "eE"
+% FELD 3 "EUDAS/1K" "kK"
+% FELD 4 "EUDAS/1S" "sS"
+% FELD 5 "EUDAS/1N" "nN"
+% FELD 6 "EUDAS/1F" "fF"
+% FELD 7 "EUDAS/1P" "pP"
+% FELD 8 "EUDAS/1M" "mM"
+% ENDE
+% MENUE "EUDAS.Einzelsatz"
+% BILD
+--------------
+Positionieren
+W Weiter
+Z Zurück
+N Satz.Nr
+--------------
+Suchbedingung
+S Setzen
+L Löschen
+M Markierung
+--------------
+Datensatz
+E Einfügen
+A Ändern
+T Tragen
+H Holen
+--------------
+F Feldauswahl
+--------------
+% FELD 1 "EUDAS/2W" "wW"
+% FELD 2 "EUDAS/2Z" "zZ"
+% FELD 3 "EUDAS/2N" "nN"
+% FELD 4 "EUDAS/2S" "sS"
+% FELD 5 "EUDAS/2L" "lL"
+% FELD 6 "EUDAS/2M" "mM"
+% FELD 7 "EUDAS/2E" "eE"
+% FELD 8 "EUDAS/2A" "aA"
+% FELD 9 "EUDAS/2T" "tT"
+% FELD 10 "EUDAS/2H" "hH"
+% FELD 11 "EUDAS/2F" "fF"
+% FELD 12 "" ""3""
+% FELD 13 "" ""10""
+% FELD 14 "" "1"
+% FELD 15 "" "9"
+% FELD 16 "" "K"
+% ENDE
+% MENUE "EUDAS.Gesamtdatei"
+% BILD
+--------------
+Satzauswahl
+K Kopieren
+T Tragen
+V Verändern
+U Übersicht
+--------------
+Aktuelle Datei
+S Sortieren
+--------------
+Alle Markier.
+L Löschen
+--------------
+% FELD 1 "EUDAS/3K" "kK"
+% FELD 2 "EUDAS/3T" "tT"
+% FELD 3 "EUDAS/3V" "vV"
+% FELD 4 "EUDAS/3U" "uU"
+% FELD 5 "EUDAS/3S" "sS"
+% FELD 6 "EUDAS/3L" "lL"
+% ENDE
+% MENUE "EUDAS.Drucken"
+% BILD
+--------------
+Satzauswahl
+D Drucken
+--------------
+Druckausgabe
+R Richtung
+--------------
+Textdatei
+E Editieren
+A Ausdrucken
+N Nachbearb.
+--------------
+% FELD 1 "EUDAS/4D" "dD"
+% FELD 2 "EUDAS/4R" "rR"
+% FELD 3 "EUDAS/4E" "eE"
+% FELD 4 "EUDAS/4A" "aA"
+% FELD 5 "EUDAS/4N" "nN"
+% ENDE
+% MENUE "EUDAS.Dateien"
+% BILD
+--------------
+Dateien System
+U Übersicht
+--------------
+Datei
+L Löschen
+N Umbenennen
+K Kopieren
+P Platzbedarf
+A Aufräumen
+--------------
+% FELD 1 "EUDAS/5U" "Uu"
+% FELD 2 "EUDAS/5L" "Ll"
+% FELD 3 "EUDAS/5N" "Nn"
+% FELD 4 "EUDAS/5K" "Kk"
+% FELD 5 "EUDAS/5P" "Pp"
+% FELD 6 "EUDAS/5R" "Aa"
+% ENDE
+% MENUE "EUDAS.Archiv"
+% BILD
+--------------
+Dateien Archiv
+U Übersicht
+D Üb. Drucken
+--------------
+Datei
+K Kopieren
+  vom Archiv
+S Schreiben
+  auf Archiv
+L Löschen
+  auf Archiv
+--------------
+Archivdiskette
+I Init
+--------------
+Z Zielarchiv
+P Passwort
+R Reservieren
+--------------
+% FELD 1 "EUDAS/6U" "Uu"
+% FELD 2 "EUDAS/6D" "Dd"
+% FELD 3 "EUDAS/6K" "Kk"
+% FELD 4 "EUDAS/6S" "Ss"
+% FELD 5 "EUDAS/6L" "Ll"
+% FELD 6 "EUDAS/6I" "Ii"
+% FELD 7 "EUDAS/6Z" "Zz"
+% FELD 8 "EUDAS/6P" "Pp"
+% FELD 9 "EUDAS/6R" "Rr"
+% ENDE
+% AUSWAHL "EUDAS-Felder"
+% VORSPANN
+--------------------------------------------------------------
+ Bitte die Felder, die geaendert werden sollen, ankreuzen:
+% BILD
+--------------------------------------------------------------
+      
+--------------------------------------------------------------
+% ENDE
+% AUSWAHL "EUDAS-Sortierfelder"
+% VORSPANN
+--------------------------------------------------------------
+ Bitte die Felder, nach denen sortiert werden soll, in Reihen-
+ folge ankreuzen:
+% BILD
+--------------------------------------------------------------
+      
+--------------------------------------------------------------
+% ENDE
+% AUSWAHL "EUDAS-Anzeigefelder"
+% VORSPANN
+--------------------------------------------------------------
+ Bitte die Felder, die angezeigt werden sollen, in Reihenfolge
+ ankreuzen:
+% BILD
+--------------------------------------------------------------
+      
+--------------------------------------------------------------
+% ENDE
+% AUSWAHL "EUDAS-Editfelder"
+% VORSPANN
+--------------------------------------------------------------
+ Bitte die Felder ankreuzen, die in die Datei übernommen
+ werden sollen:
+% BILD
+--------------------------------------------------------------
+      
+--------------------------------------------------------------
+% ENDE
+% AUSWAHL "EUDAS-Archivauswahl"
+% VORSPANN
+--------------------------------------------------------------
+ Auswahl der Dateien auf dem Archiv.
+ Gewuenschte Datei(en) bitte ankreuzen:
+% BILD
+--------------------------------------------------------------
+      
+--------------------------------------------------------------
+% ENDE
+% AUSWAHL "EUDAS-Dateiauswahl"
+% VORSPANN
+--------------------------------------------------------------
+ Auswahl der vorhandenen Dateien.
+ Gewuenschte Datei(en) bitte ankreuzen:
+% BILD
+--------------------------------------------------------------
+      
+--------------------------------------------------------------
+% ENDE
+% HILFE "EUDAS/Allgemein" 
+% SEITE 1 
+--- MENÜBEDIENUNG --- 
+Das Menü dient zur Auswahl von Funktionen. Die Funktionen sind 
+durch einen vorangestellten Buchstaben gekennzeichnet. Mit den
+Pfeiltasten können Sie die Markierung zu einer beliebigen
+Position auf und ab bewegen. Diese Funktion können Sie dann
+durch Drücken der Leertaste ausführen. Durch ESC '?' (nachein-
+ander gedrückt) erhalten Sie Informationen zur gerade
+markierten Funktion. 
+Funktionen, die im momentanen Zustand nicht ausgeführt werden
+können, sind durch ein Minuszeichen gekennzeichnet. 
+In der obersten Bildschirmzeile sind weitere Menüs aufgeführt,
+die Sie aufrufen können. Das aktuelle Menü ist invers
+markiert. Ein anderes Menü wählen Sie durch Drücken der
+Pfeiltasten RECHTS oder LINKS.
+Wollen Sie das Programm wieder verlassen, drücken Sie die
+ESC-Taste und 'q' hintereinander. 
+--- 
+% ENDE 
+% HILFE "EUDAS/1O" 
+% SEITE 1 
+--- Öffnen zum Bearbeiten --- 
+Diese Funktion öffnet eine EUDAS-Datei zur anschließenden Bear­
+beitung. Sie können angeben, ob Sie die Datei nur ansehen oder
+auch ändern wollen. Die vorher geöffnete Datei wird ggf. ge­
+sichert. Wenn Sie eine neue Datei angeben, wird diese einge­
+richtet. Dabei müssen Sie die Feldnamen eingeben. 
+ 
+=> Hinweise zur Menübedienung auf der zweiten Seite (ESC 'w') 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/1E" 
+% SEITE 1 
+--- EUDAS-Datei ketten 
+Mit dieser Funktion können Sie eine EUDAS-Datei logisch an die
+bereits geöffnete Datei anketten. Dazu müssen jedoch die beiden
+Dateien in ihrer Feldstruktur übereinstimmen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/1N" 
+% SEITE 1 
+--- Notizen ansehen/ändern --- 
+Mit dieser Funktion können Sie der aktuell geöffneten Datei
+Notizen zuordnen bzw. sich die vorherigen Notizen ansehen. Dazu
+wird der normale Editor verwendet. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/1M" 
+% SEITE 1 
+--- Manager (Mehrbenutzerbetrieb) --- 
+Mit dieser Funktion können Sie die Task festlegen, aus der beim
+Öffnen automatisch EUDAS-Dateien geholt werden können. Dadurch
+können mehrere Benutzer auf die gleiche Datei zugreifen, jedoch
+immer nur einer ändern. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/1F" 
+% SEITE 1 
+--- Feldstruktur ändern --- 
+Mit dieser Funktion können Sie 
+ 
+1. neue Feldnamen anfügen 
+   Sie können neue Feldnamen der Datei am Ende anfügen. Sie
+   müssen die Namen untereinander im Editor in der gewünschten
+   Reihenfolge angeben. Vorher werden Sie jedoch gefragt, ob
+   Sie diese Funktion überhaupt ausführen wollen. 
+ 
+2. Feldnamen und Feldtypen ändern 
+   In diesem Teil wird Ihnen eine Auswahl aller vorhandenen
+   Felder angeboten, in der jeweils auch der Typ angegeben ist.
+   Wenn Sie diese Funktion nicht ausführen wollen, beenden Sie
+   die Auswahl einfach mit ESC q. Sonst wählen Sie die Felder
+   aus, deren Namen oder Typ Sie ändern wollen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/1P" 
+% SEITE 1 
+--- Prüfbedingungen --- 
+Bei dieser Funktion können Sie im Editor ein Prüfpro­
+gramm eingeben, das mit der Datei gespeichert wird und beim
+Reintragen neuer Sätze ausgeführt wird. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/1K" 
+% SEITE 1 
+--- EUDAS-Datei koppeln --- 
+Mit dieser Funktion können Sie eine Datei angeben, die zu den
+bisher geöffneten Dateien dazugekoppelt wird. Anschließend
+werden zu jedem Satz der existierenden Datei die in den Koppel­
+feldern übereinstimmenden Sätze der Koppeldatei gezeigt. 
+Als Koppelfelder werden dabei die ersten Felder der Koppeldatei
+betrachtet, die auch in der geöffneten Datei vorhanden sind. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/3S" 
+% SEITE 1 
+--- Aktuelle Datei sortieren --- 
+Mit dieser Funktion kann die aktuell geöffnete EUDAS-Datei
+sortiert werden. Die Reihenfolge, in der die Felder berücksich­
+tigt werden, kann vorher angegeben werden. Eventuell müssen
+zum richtigen Sortieren Feldtypen vergeben werden (s.
+"Feldstrukt."). 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/1S" 
+% SEITE 1 
+--- Aktuelle Dateien sichern --- 
+EUDAS arbeitet bei Änderungen immer auf Sicherheitskopien der
+Dateien. Wenn Ändern erlaubt ist, müssen geänderte Arbeits­
+kopien mit dieser Funktion gesichert werden. Für eine veränder­
+te Datei kann dabei auch ein neuer Name angegeben werden, damit
+die alte Version erhalten bleibt. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2W" 
+% SEITE 1 
+--- Satz weiter --- 
+Diese Funktion geht zum nächsten Satz und zeigt ihn an. Wenn
+eine Suchbedingung eingestellt ist, werden nicht ausgewählte
+Sätze übersprungen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2Z" 
+% SEITE 1 
+--- Satz zurück --- 
+Diese Funktion geht zum vorigen Satz. Wenn eine Suchbedingung
+eingestellt ist, werden nicht ausgewählte Sätze übersprungen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2S" 
+% SEITE 1 
+--- Suchbedingung setzen --- 
+Mit dieser Funktion kann eine Suchbedingung als Suchmuster
+eingegeben werden, die angibt, welche Sätze bearbeitet werden
+sollen. Die vorher eingestellte Suchbedingung wird automatisch
+gelöscht. Die Bedingungen für die einzelnen Felder können im
+Editor eingegeben werden. 
+ 
+mögliche Bedingungen: 
+  Text     identisch mit     Text..       größergleich 
+  *Text    endet mit         ..Text       kleiner 
+  Text*    beginnt mit       Text..Text   zwischen 
+  *Text*   enthält           *            nicht leer 
+ 
+  --Bed      Verneinung 
+ 
+Kombination von Bedingungen: 
+  Bedingungen für verschiedene Felder: 
+    UND 
+  Komma zwischen Bedingungen: 
+    lokales ODER (Prio höher als UND) 
+  Semikolon zwischen Bedingungen: 
+    globales ODER (Prio niedriger als UND) 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2L" 
+% SEITE 1 
+--- Suchbedingung löschen --- 
+Mit dieser Funktion kann eine eingestellte Suchbedingung wieder
+gelöscht werden, so daß wieder alle Sätze sichtbar sind. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2N" 
+% SEITE 1 
+--- auf Satz Nr. --- 
+Mit dieser Funktion kann ein bestimmter Satz direkt angewählt
+werden. Dazu müssen Sie lediglich dessen Satznummer angeben. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2E" 
+% SEITE 1 
+--- neuen Satz einfügen --- 
+Mit dieser Funktion wird vor dem aktuellen Satz ein neuer Satz
+eingefügt. Die Inhalte dieses zunächst leeren Satzes können Sie
+mit Hilfe des Editors neben die einzelnen Feldnamen schreiben. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2A" 
+% SEITE 1 
+--- Satz ändern --- 
+Mit dieser Funktion können Sie die Inhalte des aktuellen Satzes
+verändern. Am Bildschirm können Sie die Daten mit Hilfe des
+Editors ändern, löschen und Neues hinzufügen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2M" 
+% SEITE 1 
+--- Markierung ein/aus --- 
+Mit dieser Funktion können Sie einen Satz markieren, damit
+später nur die markierten Sätze bearbeitet werden. Ist der Satz
+schon markiert, wird die Markierung wieder gelöscht. Wenn min­
+destens ein Satz markiert ist, erscheint die Markierungsinfor­
+mation in der Überschrift. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/3L" 
+% SEITE 1 
+--- Alle Markierungen loeschen --- 
+Mit dieser Funktion werden alle Markierungen in der Datei
+gelöscht. Die Markierungsinformation wird nicht mehr angezeigt.
+Die Markierungen werden auch beim neuen Öffnen gelöscht, da sie
+nicht permanent in der Datei gespeichert sind. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2T" 
+% SEITE 1 
+--- Einzelsatz tragen --- 
+Mit dieser Funktion kann der aktuelle Satz in eine andere Datei
+transportiert werden. Anschließend wird er gelöscht. Der Satz
+wird am Ende der Zieldatei angefügt, wobei diese gegebenenfalls
+eingerichtet wird. Den Namen der Zieldatei können Sie eingeben. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2H" 
+% SEITE 1 
+--- Einzelsatz holen --- 
+Diese Funktion holt den letzten Satz einer anderen Datei und
+fügt ihn vor dem aktuellen Satz ein. Damit wird das letzte
+'Tragen' wieder rückgängig gemacht. Die Dateien müssen gleiche
+Felderzahl haben. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/3U" 
+% SEITE 1 
+--- Übersicht --- 
+Mit dieser Funktion können Sie sich eine Übersicht über mehrere
+Sätze verschaffen. Es werden vom aktuellen Satz an alle durch
+die Suchbedingung spezifizierten Sätze angezeigt, jeder Satz in
+einer Zeile. In dieser Übersicht können Sie blättern und auch
+bestimmte Sätze zur späteren Bearbeitung markieren. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/2F" 
+% SEITE 1 
+--- Auswahl Felder --- 
+Mit dieser Funktion kann gewählt werden, welche Felder in
+welcher Reihenfolge angezeigt werden sollen. Alle Felder
+werden zum Ankreuzen angeboten. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/4D" 
+% SEITE 1 
+--- Drucken nach Muster --- 
+Mit dieser Funktion können die Inhalte der Datei nach einem
+Druckmuster ausgedruckt werden. Das Druckmuster ist eine Text­
+datei und muß vorher erstellt werden. Es gibt die Form des
+Ausdrucks an. Über den Aufbau eines Druckmusters lesen Sie am
+besten das Benutzerhandbuch. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/3T" 
+% SEITE 1 
+--- Satzauswahl tragen --- 
+Diese Funktion trägt alle durch die Suchbedingung oder durch
+Markierung ausgewählten Sätze in eine andere Datei und löscht
+sie danach. Die Zieldatei muß gleiche Felderzahl haben, damit
+keine Information verlorengeht. Beim Tragen können auch die
+Prüfbedingungen der Zieldatei geprüft werden, wenn Sie die
+entsprechende Frage bejahen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/4E" 
+% SEITE 1 
+--- Textdatei erstellen/aendern --- 
+Mit dieser Funktion kann eine Textdatei erstellt, geändert oder
+angesehen werden. Es wird der normale Editor verwendet. Mit
+dieser Funktion werden auch Druckmuster bearbeitet. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/3K" 
+% SEITE 1 
+--- Satzauswahl kopieren --- 
+Diese Funktion kopiert alle durch die Suchbedingung oder durch
+Markierung ausgewählten Sätze in eine andere Datei. Welche
+Felder in welcher Reihenfolge kopiert werden sollen, wird durch
+ein Kopiermuster bestimmt, das nach der Struktur der Zieldatei
+bestimmt wird und dann von Ihnen noch geändert werden kann. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/4R" 
+% SEITE 1 
+--- Richtung Ausgabe --- 
+Mit dieser Funktion können Sie festlegen, ob die Ausgabe des
+Druckvorgangs direkt anschließend ausgedruckt werden soll, oder
+in eine Datei gespeichert wird. Sie können den Namen dieser
+Datei eingeben, anderenfalls wählt sich EUDAS selbst einen
+Namen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/4A" 
+% SEITE 1 
+--- Textdatei ausdrucken --- 
+Mit dieser Funktion wird eine Textdatei direkt ausgedruckt. Die
+Datei kann Anweisungen zur Druckersteuerung enthalten, die Sie
+dem EUMEL-Benutzerhandbuch entnehmen können. Sie können hiermit
+Ausgabedateien des Druckprozesses und das Druckmuster selbst
+ausdrucken. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/3V" 
+% SEITE 1 
+--- Ändern nach Vorschrift --- 
+Diese Funktion ermöglicht es, alle durch die Suchbedingung oder
+durch Markierung ausgewählten Sätze nach einer Vorschrift auto­
+matisch zu ändern. Die Art der Änderungen wird dabei durch ein
+Verarbeitungsmuster festgelegt, das vorher als Textdatei er­
+stellt werden muß. Über die Form des Verarbeitungsmusters s.
+Benutzerhandbuch. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/4N" 
+% SEITE 1 
+--- Textdatei nachbearbeiten --- 
+Mit dieser Funktion können Sie eine Datei zeilenweise und
+seitenweise formatieren (lineform/pageform). Dies dient an
+dieser Stelle zur Bearbeitung von Druckdateien, die
+verschiedene oder Proportionalschriften enthalten. Sie werden
+jeweils für jede der beiden Funktionen gefragt, ob Sie sie
+ausführen wollen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/6S" 
+% SEITE 1 
+--- Schreiben auf Archiv --- 
+Diese Funktion schreibt eine oder mehrere Dateien auf das
+Archiv. Der Archivname muß vorher eingegeben werden. Dann kann
+entweder der Name der gewünschten Datei eingegeben werden oder
+mit ESC 'z' eine Auswahl von Dateien angekreuzt werden. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/5A" 
+% SEITE 1 
+--- Datei aufräumen --- 
+Diese Funktion reorganisiert eine Datei, an der viel geändert
+wurde, zur Platz- und Zeitersparnis. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/5K" 
+% SEITE 1 
+--- Datei kopieren --- 
+Mit dieser Funktion kann eine beliebige Datei logisch kopiert
+werden. Die Kopie ist identisch mit dem Original und belegt den
+gleichen Platz, erst bei Änderungen werden unterschiedliche
+Daten gespeichert. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/5P" 
+% SEITE 1 
+--- Platzbedarf Datei --- 
+Diese Funktion gibt an, wieviel Platz eine Datei im System
+belegt. Dieser Platz kann aber mit anderen Dateien geteilt
+sein. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/6D" 
+% SEITE 1 
+--- Archivübersicht drucken --- 
+Diese Funktion druckt die Übersicht der Archivdateien aus. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/6I" 
+% SEITE 1 
+--- Archiv initialisieren --- 
+Diese Funktion initialisiert einen Archivträger vor dem
+Beschreiben. Sämtliche Daten werden gelöscht. Auf Wunsch kann
+der Datenträger auch formatiert werden (falls vom System
+unterstützt). 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/6Z" 
+% SEITE 1 
+--- Zielarchiv einstellen --- 
+Mit dieser Funktion kann eine Managertask angegeben werden, auf
+die die Archivfunktionen angewendet werden. Dies dient sowohl
+zur Ansteuerung von mehreren Archiven (z.B. über Netz) als auch
+zur Kommunikation mit anderen Managern. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/6P" 
+% SEITE 1 
+--- Passwort --- 
+Mit dieser Funktion können Sie das Passwort einstellen, das
+beim Versenden von Dateien an andere Tasks verwendet wird. Beim
+Schreiben einer Datei wird das Passwort der Datei mitgegeben
+und beim Lesen wird überprüft, ob das Passwort übereinstimmt.
+Das Passwort kann in der Form Schreibpasswort/Lesepasswort
+angegeben werden. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/6R" 
+% SEITE 1 
+--- Reservieren --- 
+Mit dieser Funktion können Sie einen Kanalmanager (z.B.
+DOS-Task) reservieren. Die Reservierung wird beim Verlassen des
+Archivmenüs wieder aufgehoben. Den Parameter zur Reservierung
+(Modus bei DOS-Task) können Sie angeben. Bei normalen Archiv­
+tasks wird die Reservierung automatisch vorgenommen, daher ist
+diese Funktion dann gesperrt. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/6K" 
+% SEITE 1 
+--- Kopieren vom Archiv --- 
+Diese Funktion kopiert eine Datei vom Archiv ins System. Der
+Archivname wird automatisch bestimmt. Sie können dann entweder
+den gewünschten Dateinamen angeben oder mit ESC 'z' eine Aus­
+wahl aller Dateien auf dem Archiv abrufen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/5N" 
+% SEITE 1 
+--- Datei Namen ändern --- 
+Mit dieser Funktion können Sie für eine Datei auf dem System
+einen neuen Namen vergeben. Wenn Sie den neuen Namen eingeben,
+wird Ihnen der alte Name angeboten. Sie können ihn ändern oder
+ganz überschreiben. Dadurch ersparen Sie sich bei kleinen
+Änderungen das Neutippen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/6L" 
+% SEITE 1 
+--- Löschen auf Archiv --- 
+Diese Funktion ermöglicht es, eine Datei auf dem Archiv zu
+löschen. Der Platz dieser Datei wird jedoch nur dann wiederver­
+wendet, wenn keine Dateien mehr dahinter stehen. Der Archivname
+muß eingegeben werden. Sie können bei der Eingabe des Datei­
+namens mit ESC 'z' eine Dateiauswahl abrufen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/5L" 
+% SEITE 1 
+--- Datei löschen --- 
+Diese Funktion löscht eine Datei auf dem System nach Anfrage.
+Sie können den Dateinamen eingeben oder mit ESC 'z' eine Aus­
+wahl aller vorhandenen Dateien abrufen. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/6U" 
+% SEITE 1 
+--- Übersicht Archiv --- 
+Diese Funktion liefert eine Übersicht der Dateien auf dem
+Archiv. Verlassen Sie diese Übersicht mit ESC 'q'. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "EUDAS/5U" 
+% SEITE 1 
+--- Übersicht Dateien --- 
+Diese Funktion liefert eine Übersicht über alle im System vor­
+handenen Dateien. Verlassen Sie diese Übersicht mit ESC 'q'. 
+--- 
+% SEITE 1 "EUDAS/Allgemein" 
+% ENDE 
+% HILFE "AUSWAHL/Allgemein" 
+% SEITE 1 
+--- AUSWAHL --- 
+Mit Hilfe der Auswahl ist es möglich, aus einem Angebot einen
+Teil auszuwählen. Die gewünschten Namen werden einfach in
+beliebiger Reihenfolge angekreuzt und anschließend in dieser
+Reihenfolge verwendet. 
+Die Schreibmarke (Cursor) gibt an, welcher Name gerade ange­
+kreuzt werden kann. Mit den Pfeiltasten kann der Cursor auf den
+Kreisen bewegt werden. 'x' kreuzt einen Namen an, 'o' löscht
+die Ankreuzung wieder. 
+Mit ESC 'q' wird die Auswahl verlassen. ESC 'a' bricht die
+Auswahl und die folgende Funktion ab. Falls das Angebot nicht
+auf den Bildschirm paßt, wird es gerollt. ESC '1' positioniert
+immer auf den Anfang und ESC '9' auf das Ende der Auswahl. Mit
+HOP 'x' werden alle noch nicht angekreuzten Namen angekreuzt,
+mit HOP 'o' werden alle Ankreuzungen gelöscht. 
+--- 
+% ENDE 
+% HILFE "AUSWAHL/Felder" 
+% SEITE 1 
+--- 
+Sie können hier alle Felder ankreuzen, die Sie ändern wollen.
+Ändern können Sie den Feldnamen und den Feldtyp. Wollen Sie
+keine Felder ändern, drücken Sie einfach ESC 'q'. 
+--- 
+% SEITE 1 "AUSWAHL/Allgemein" 
+% ENDE 
+% HILFE "AUSWAHL/Sortierfelder" 
+% SEITE 1 
+--- 
+Kreuzen Sie hier die Felder an, die bei der Sortierung berück­
+sichtigt werden sollen. Die Reihenfolge des Ankreuzens ist
+wichtig. Beim Vergleich zweier Sätze wird erst das als erstes
+angekreuzte Feld verglichen und danach die Einordnung der Sätze
+bestimmt. Ist dieses Feld bei beiden gleich, wird das nächste
+angekreuzte Feld untersucht usw. 
+--- 
+% SEITE 1 "AUSWAHL/Allgemein" 
+% ENDE 
+% HILFE "AUSWAHL/Anzeigefelder" 
+% SEITE 1 
+--- 
+Kreuzen Sie hier alle Felder an, die Sie angezeigt haben möch­
+ten. Die Felder erscheinen in der angekreuzten Reihenfolge. Für
+beide Arten der Anzeige können Sie eine separate Feldauswahl
+einstellen. 
+--- 
+% SEITE 1 "AUSWAHL/Allgemein" 
+% ENDE 
+% HILFE "AUSWAHL/Feldnamen" 
+% SEITE 1 
+--- 
+Durch Blättern in der Auswahl können Sie die Schreibweise der
+Feldnamen ansehen. Die Namen, die Sie ankreuzen, werden danach
+mit Anführungsstrichen in die gerade editierte Datei übernommen. 
+--- 
+% SEITE 1 "AUSWAHL/Allgemein" 
+% ENDE 
+% HILFE "AUSWAHL/Archiv" 
+% SEITE 1 
+--- 
+Diese Auswahl zeigt alle auf dem Archiv vorhandenen Dateien an.
+Kreuzen Sie die Dateien an, die Sie bearbeiten möchten. Die
+Dateien werden in der angekreuzten Reihenfolge verwendet. 
+--- 
+% SEITE 1 "AUSWAHL/Allgemein" 
+% ENDE 
+% HILFE "AUSWAHL/Datei" 
+% SEITE 1 
+--- 
+Diese Auswahl zeigt alle Dateien auf dem System, die Sie ver­
+wenden können. Kreuzen Sie die gewünschte(n) Datei(en) an. 
+--- 
+% SEITE 1 "AUSWAHL/Allgemein" 
+% ENDE 
+% HILFE "FEHLER/Allgemein" 
+% SEITE 1 
+--- FEHLERMELDUNGEN --- 
+Fehlermeldungen werden von einem Programm abgesetzt, wenn es
+seine Funktion nicht durchführen kann. Der Text der Meldung
+identifiziert die Ursache des Problems. Zur Zeit liegen noch
+keine meldungsspezifischen Informationen vor, schauen Sie ggf.
+in das Benutzerhandbuch. 
+--- 
+% ENDE 
+% HILFE "FEHLER/9" 
+% SEITE 1 
+--- 
+Diese Fehlermeldung deutet auf einen internen Programmfehler
+(wenn Sie nicht selber ein Programm geschrieben haben). Melden
+Sie diesen Fehler bitte, damit eine Korrektur vorgenommen
+werden kann. Schreiben Sie sich dazu die Begleitumstände auf
+(welche Datei haben Sie benutzt, welche Funktion). Versuchen
+Sie gegebenenfalls, den Fehler zu wiederholen. Es ist nämlich
+z.B. wichtig, ob der Fehler nur bei einer bestimmten Datei
+auftritt oder ganz "zufällig". Wenn Sie vermuten, daß der
+Fehler an einer bestimmten Datei liegt, sichern Sie diese Datei
+bitte auf einer Diskette, um sie eventuell einschicken zu
+können. 
+--- 
+% ENDE 
+% HILFE "FEHLER/10" 
+% SEITE 1 "FEHLER/9" 
+% ENDE 
+% HILFE "FEHLER/11" 
+% SEITE 1 "FEHLER/9" 
+% ENDE 
+% HILFE "FEHLER/14" 
+% SEITE 1 "FEHLER/9" 
+% ENDE 
+% HILFE "GET/Allgemein" 
+% SEITE 1 
+--- EINGABE --- 
+Die Eingabe erwartet von Ihnen eine bestimmte Information, die
+Sie eingeben sollen. Die Art der Information wird durch den
+Anforderungstext angegeben. Wenn Sie sich beim Eintippen ver­
+schrieben haben, können Sie mit den Pfeiltasten zurückgehen
+und den Text korrigieren. Eine bereits dastehende Information
+können Sie überschreiben. RUBOUT löscht ein Zeichen, RUBIN
+schaltet in den Einfügemodus (Zeichen werden nicht mehr über­
+schrieben). Beenden Sie die Eingabe mit RETURN. ESC 'h' bricht
+die Eingabe und die folgende Funktion ab. Wenn in der Status­
+zeile angegeben, können Sie mit ESC 'z' eine Auswahl verfüg­
+barer Namen abrufen, die Sie dann Ankreuzen können. 
+--- 
+% ENDE 
+% HILFE "GET/Sicherungsname" 
+% SEITE 1 
+--- 
+Sie können jetzt den Namen angeben, unter dem die Arbeitskopie
+gespeichert werden soll. Ihnen wird der alte Name zum Über­
+schreiben angeboten. Drücken Sie nur RETURN, wird der alte Name
+genommen und die alte Version überschrieben. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/Dateiname" 
+% SEITE 1 
+--- 
+Bitte geben Sie den Namen der Datei ein, mit dem die Operation
+ausgeführt werden soll. Mit ESC 'z' können Sie sich die zur
+Verfügung stehenden Namen auch als Auswahl zeigen lassen. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/feldname" 
+% SEITE 1 
+--- 
+Sie können den Namen des angegebenen Feldes ändern, indem Sie
+den alten Namen überschreiben bzw. korrigieren. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/feldtyp" 
+% SEITE 1 
+--- 
+Sie können hier einen von vier möglichen Typen eingeben: 
+ TEXT  normaler Text mit Vergleich nach EUMEL-Code. 
+ DIN   Text, der nach DIN 5007 verglichen wird (Umlaute rich­
+       tig, Groß-/Kleinschreibung und Sonderzeichen ignoriert). 
+ ZAHL  Alle nichtnumerischen Zeichen außer Minus und Dezimal­
+       komma werden beim Vergleichen ignoriert. 
+ DATUM Datum der Form "tt.mm.jj" 
+Die Feldtypen werden beim Sortieren und Suchen beachtet. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/auf Satz" 
+% SEITE 1 
+--- 
+Sie können hier die Satznummer des Satzes eingeben, den Sie
+sehen wollen. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/copy" 
+% SEITE 1 
+--- 
+ Geben Sie hier den Namen für die logische Kopie der Datei an.
+ Dieser Name darf keine existierende Datei bezeichnen. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/Archivname" 
+% SEITE 1 
+--- 
+Geben Sie den Namen des eingelegten Archivs ein (zur Sicher­
+heit). Der zuletzt verwendete Name wird zum Ändern angeboten. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/rename" 
+% SEITE 1 
+--- 
+Sie können den alten Namen der Datei durch Überschreiben und
+Korrigieren ändern. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/Druckdatei" 
+% SEITE 1 
+--- 
+Geben Sie hier den Namen der Datei ein, in die die Ausgabe des
+Druckprozesses geschrieben werden soll. Diese Datei wird nur
+für den nächsten Druckvorgang verwendet. Sie müssen den Namen
+also jedes Mal wieder neu angeben. Existiert die Datei schon,
+wird die Ausgabe an das Ende angehängt. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/Zielarchiv" 
+% SEITE 1 
+--- 
+Geben Sie hier entweder den Namen einer Archivtask ein
+(normalerweise "ARCHIVE") oder einer anderen Managertask. Bei
+Netzbetrieb können Sie auch die Station anschließend angeben. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/Zielstation" 
+% SEITE 1 
+--- 
+Geben Sie hier die Stationsnummer der Zieltask ein. Wenn sich
+die Zieltask in Ihrem eigenen System befindet, brauchen Sie nur
+RETURN zu drücken. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/multi task" 
+% SEITE 1 
+--- 
+Sie können hier den Namen einer EUDAS-Managertask angeben
+(EUDAS muß in dieser Task insertiert sein). Wenn Sie keinen
+Namen angeben, werden keine entsprechenden Abfragen beim Öffnen
+mehr gemacht. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "GET/kopiermuster" 
+% SEITE 1 
+--- 
+Geben Sie den Namen einer Datei ein, in der das Kopiermuster
+stehen soll. Drücken Sie einfach RETURN, wenn Sie das Muster
+nicht aufbewahren wollen. Wenn die Datei noch nicht existiert,
+wird das Standard-Kopiermuster in die Datei geschrieben.
+Anschließend kann das Muster noch im Editor geändert werden. 
+--- 
+% SEITE 1 "GET/Allgemein" 
+% ENDE 
+% HILFE "JA/Allgemein" 
+% SEITE 1 
+--- FRAGEN --- 
+Das Programm stellt Ihnen eine Frage, die Sie bejahen oder
+verneinen können. Sie bejahen die Frage, indem Sie 'j' drücken
+und verneinen Sie mit 'n' (beides groß oder klein). Mit ESC 'h'
+können Sie die Funktion abbrechen. 
+--- 
+% ENDE 
+% HILFE "JA/oeffne" 
+% SEITE 1 
+--- 
+Beantworten Sie die Frage mit 'n', wenn Sie die Datei nur anse­
+hen wollen. In diesem Fall wird keine Sicherheitskopie er­
+stellt. Verneinen Sie die Frage, wird eine interen Kopie ange­
+legt, die Sie dann verändern können. Die Kopie muß nach dem
+Ändern gesichert werden. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/alte version" 
+% SEITE 1 
+--- 
+Wenn Sie diese Frage bejahen, wird die Arbeitskopie unter dem
+angegebenen Namen gesichert. Die alte Version geht dadurch
+verloren. Wenn Sie die Frage verneinen, haben Sie Gelegenheit,
+einen neuen Namen anzugeben, damit die alte Version erhalten
+bleiben kann. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/Datei loeschen" 
+% SEITE 1 
+--- 
+Beim Sichern hatten Sie Gelegenheit, alle veränderten Dateien
+zu sichern. Die Sicherheitskopien können damit gelöscht werden.
+Dazu bejahen Sie die Frage. Wenn die Dateien jedoch noch geöff­
+net bleiben sollen, oder Sie eine Datei aus Versehen nicht
+gesichert haben, müssen Sie diese Frage verneinen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/sichere" 
+% SEITE 1 
+--- 
+Die interne Arbeitskopie der angegebenen Datei wurde gegenüber
+dem Original verändert. Wenn Sie diese Änderungen behalten
+wollen, müssen Sie die Frage bejahen. Sie haben dann noch die
+Möglichkeit, die geänderte Version unter neuem Namen zu
+sichern, um die alte Version zu behalten. Wenn Sie die Frage
+verneinen, gehen die Änderungen verloren und das Original
+bleibt erhalten. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/ueber" 
+% SEITE 1 
+--- 
+Sie haben für die Arbeitskopie einen Namen angegeben, der noch
+existiert. Bejahen Sie die Frage, wird die alte Datei dieses
+Namens überschrieben. Anderenfalls erhalten Sie eine neue Gele­
+genheit, einen Namen einzugeben. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/Sicherungssortierung" 
+% SEITE 1 
+--- 
+Die angegebene Datei war früher schon einmal sortiert worden.
+Die Sortierung wurde jedoch durch nachfolgende Änderungen
+zerstört. Wenn Sie die Datei wieder sortiert haben wollen,
+beantworten Sie die Frage mit 'j'. Die Sortierung dauert nicht
+lange, wenn nur wenige Sätze verändert wurden. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/feldnamen" 
+% SEITE 1 
+--- 
+Falls Sie neue Felder zu den existierenden anfügen wollen,
+müssen Sie diese Frage bejahen. Sie erhalten dann Gelegenheit,
+die neuen Namen im Editor einzugeben. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/Sortierfelder" 
+% SEITE 1 
+--- 
+Die Reihenfolge, in der die Felder bei der Sortierung berück­
+sichtigt werden, ist in der EUDAS-Datei intern gespeichert.
+Wenn Sie diese Reihenfolge, die beim letzten Sortieren angege­
+ben wurde, ändern möchten, müssen Sie die Frage bejahen. Sie
+können dann die neue Feldreihenfolge auswählen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/sortieren" 
+% SEITE 1 
+--- 
+Wenn Sie diese Frage bejahen, wird die Zieldatei nach Ausfüh­
+rung der Funktion in ihrer eingestellten Feldreihenfolge sor­
+tiert. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/forget" 
+% SEITE 1 
+--- 
+Wenn Sie diese Frage bejahen, wird die Datei wirklich gelöscht.
+Wenn Sie die Datei irrtümlich gewählt haben, müssen Sie die
+Frage verneinen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/direkt drucken" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, wird das Ergebnis des Druckens am
+Ende des Vorgangs ausgedruckt. Anderenfalls wird das Ergebnis
+in einer Datei zwischengespeichert. Sie können die Ausgabe dann
+noch behandeln, ehe Sie sie ausdrucken. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/einrichten" 
+% SEITE 1 
+--- 
+Sie haben eine Datei angegeben, die noch nicht existiert. Wenn
+Sie die Frage bejahen, wird die Datei neu eingerichtet. Ande­
+renfalls wird die Funktion abgebrochen, so daß Sie Gelegenheit
+haben, die Funktion mit einem neuen Namen zu wiederholen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/testen" 
+% SEITE 1 
+--- 
+Wenn Sie diese Frage bejahen, werden beim Tragen die Prüfbedin­
+gungen der Zieldatei abgefragt. Sätze, die diese Bedingungen
+nicht erfüllen, werden nicht getragen und können danach geän­
+dert werden. Beim Ändern wird dann jeweils die den Satz betref­
+fende Meldung ausgegeben. Die Prüfbedingungen der Zieldatei
+können Sie mit der Funktion "Feldstruktur aendern" angeben oder
+ändern. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/save" 
+% SEITE 1 
+--- 
+Die angegebene Datei befindet sich bereits auf dem Archiv. Wenn
+Sie die Datei überschreiben wollen, müssen Sie die Frage beja­
+hen. Ansonsten wird die Datei nicht auf das Archiv geschrieben
+(keine Wirkung). 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/fetch" 
+% SEITE 1 
+--- 
+Die angegebene Datei ist bereits im System vorhanden. Wenn Sie
+diese Datei überschreiben wollen, müssen Sie die Frage bejahen.
+Anderenfalls wird keine Aktion vorgenommen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/erase" 
+% SEITE 1 
+--- 
+Zur Sicherheit wird gefragt, ob Sie die angegebene Datei wirk­
+lich auf dem Archiv löschen wollen. Wenn Sie die Frage vernei­
+nen, wird keine Aktion durchgeführt. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/Druckdatei" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, können Sie für die Ausgabedatei
+einen bestimmten Namen angeben. Anderenfalls wird ein Name
+"EUDAS-Ausgabe.n" automatisch von EUDAS vergeben. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/Zielmanager" 
+% SEITE 1 
+--- 
+Ein Archivmanager ist eine Task, die tatsächlich ein
+physikalisches Speichermedium (Diskette) bedient, das für den
+jeweiligen Benutzer reserviert werden muß. Normale Managertasks
+können von mehreren Benutzern gleichzeitig angesprochen werden. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/format" 
+% SEITE 1 
+--- 
+Wenn Ihr Rechner dies unterstützt, können Sie Archivdisketten
+vor dem Initialisieren noch physikalisch formatieren. Dies ist
+immer dann notwendig, wenn eine Diskette neu ist (vor der
+ersten Benutzung) oder wenn Schreibfehler aufgetreten sind, die
+sich nicht mehr reparieren lassen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/archiv loeschen" 
+% SEITE 1 
+--- 
+Wenn Sie irrtümlich die falsche Diskette eingelegt haben oder
+eine andere Funktion ausführen wollten, können Sie die Funktion
+durch Verneinen der Frage abbrechen. Achten Sie auf den
+angegebenen Archivnamen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/archiv init" 
+% SEITE 1 
+--- 
+Wenn Sie aus Versehen die falsche Funktion gewählt haben,
+können Sie die Funktion durch Verneinen der Frage abbrechen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/Feld aendern" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, werden Ihnen alle vorhandenen
+Felder zum Ankreuzen angeboten. Sie können dann für die
+angekreuzten Felder die Namen und Feldtypen ändern. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/alle Saetze" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, werden anschließend alle Sätze, die
+in der Übersicht zu sehen waren, gedruckt. Den Namen des
+Druckmusters können Sie dann gleich eingeben. Wenn Sie keinen
+oder nur den aktuellen Satz drucken wollen, müssen Sie die
+Frage verneinen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/alle markierten" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, werden anschließend alle markierten
+Sätze gedruckt. Den Namen des Druckmusters können Sie dann
+gleich eingeben. Wenn Sie keinen oder nur den aktuellen Satz
+drucken wollen, müssen Sie die Frage verneinen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/Einzelsatz drucken" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, wird der aktuelle (markierte) Satz
+gedruckt. Den Namen des Druckmusters können Sie dann gleich
+eingeben. Wenn Sie keinen Satz drucken wollen, müssen Sie die
+Frage verneinen. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/noch einmal" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, können Sie noch einmal die Datei
+mit einer neuen Suchbedingung ansehen und erneut drucken. Sonst
+kehren Sie wieder in den Editor zurück. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/Ub. Felder" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, können Sie einzelne Felder in einer
+bestimmten Reihenfolge für die Übersichtsanzeige auswählen.
+Anderenfalls werden alle Felder angezeigt. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/Suchmuster" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, können Sie eine Suchbedingung für
+die angezeigten Sätze angeben. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/umschalten" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, schalten Sie auf die genannte
+Koppeldatei um. Damit wird diese Datei zeitweise als einzige
+geöffnete betrachtet. Damit können Sie einen bestimmten Satz
+aufsuchen, den Sie später beim Zurückschalten übernehmen
+können. Verneinen Sie die Frage, werden Ihnen weitere mögliche
+Koppeldateien angeboten, oder Sie kehren ohne Schaden zurück. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/uebernehmen" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, werden die Koppelfelder des jetzt
+ausgewählten Satzes in den aktuellen Satz der ersten Datei
+übernommen, an dem Sie dann weiter ändern können. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/Sortierrichtung" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, wird die Datei nach dem genannten
+Feld in aufsteigender Richtung sortiert, anderenfalls in
+absteigender. Für weitere Felder können Sie wieder eine andere
+Richtung angeben. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/zeilenform" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, wird die angegebene Datei
+zeilenweise interaktiv formatiert. Der Text wird unter
+Berücksichtigung der Schrifttypen gleichmäßig auf die Zeilen
+verteilt. Beachten Sie die Wirkung der Absatzmarken! 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/seitenform" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, wird die angegebene Datei
+interaktiv seitenweise formatiert. Der Text wird bis zur
+angegebenen Seitenlänge auf die Seiten verteilt. Dabei werden
+Seitenköpfe und Fußnoten eingefügt. Das Ergebnis steht in der
+Datei "xxx.p". 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "JA/pw loeschen" 
+% SEITE 1 
+--- 
+Wenn Sie die Frage bejahen, wird das Passwort gelöscht und das
+leere Passwort eingestellt. Anderenfalls bleibt das alte
+Passwort erhalten. 
+--- 
+% SEITE 1 "JA/Allgemein" 
+% ENDE 
+% HILFE "EDIT/Allgemein" 
+% SEITE 1 
+--- EDITOR --- 
+Mit dem Editor können Sie einen Text zeilenweise eingeben.
+Dabei können Sie den Cursor mit den Pfeiltasten bewegen. RUBOUT
+löscht ein Zeichen, RUBIN schaltet in den Einfügemodus um. Für
+weitere Informationen zum Editor s. EUMEL-Benutzerhandbuch. ESC
+'q' verläßt den Editor normal. Mit ESC 'h' wird die Funktion
+abgebrochen. 
+--- 
+% ENDE 
+% HILFE "EDIT/Feldnamen" 
+% SEITE 1 
+--- 
+Sie können hier die neuen Feldnamen in der gewünschten Reihen­
+folge untereinander eingeben. Jeder Feldname muß in einer
+Zeile stehen und ohne Anführungsstriche geschrieben sein. 
+--- 
+% SEITE 1 "EDIT/Allgemein" 
+% ENDE 
+% HILFE "EDIT/Pruefbed" 
+% SEITE 1 
+--- 
+Sie können hier die Prüfbedingungen der Datei eingeben bzw.
+ändern. Die Prüfbedingungen sind ein ELAN-Programm. Da ELAN-
+Programme formatfrei sind, kann es sein, daß Ihr Programm beim
+nächsten Mal anders erscheint, als Sie es eingegeben haben. 
+--- 
+% SEITE 1 "EDIT/Allgemein" 
+% ENDE 
+% HILFE "EDIT/Notizen" 
+% SEITE 1 
+--- 
+Sie können jetzt zu der angegebenen Datei beliebige Notizen
+eingeben bzw. ändern. Sie befinden sich im Editor und können
+die gleichen Funktionen wie bei der normalen Texteingabe
+verwenden. 
+--- 
+% SEITE 1 "EDIT/Allgemein" 
+% ENDE 
+% HILFE "EDIT/Suchen" 
+% SEITE 1 
+--- 
+Sie können jetzt eine Selektionsbedingung einstellen. Dazu
+müssen Sie jeweils neben den Feldnamen eine Bedingung schrei­
+ben. Mögliche Bedingungen sind: 
+ Text         muß gleich sein 
+ Text*        muß mit Text anfangen 
+ *Text        muß mit Text enden 
+ *Text*       enthält Text 
+ Text..       muß größer oder gleich Text sein 
+ ..Text       muß kleiner als Text sein oder mit Text anfangen 
+ Text1..Text2 liegt zwischen den beiden Texten 
+"--" verneint eine Bedingung. Weitere Bedingungen und Kombina­
+tion von Bedingungen s. EUDAS-Benutzerhandbuch. 
+--- 
+% SEITE 1 "EDIT/Allgemein" 
+% ENDE 
+% HILFE "EDIT/Einfuegen" 
+% SEITE 1 
+--- 
+Sie können hier die Inhalte eines neuen Satzes eingeben, der
+vor dem aktuellen Satz eingefügt wird. 
+Spezielle Tastenkombinationen: 
+ ESC RUBOUT     Rest der Zeile löschen 
+ ESC RUBIN      Zeile aufbrechen 
+ ESC OBEN       nach oben blättern 
+ ESC UNTEN      nach unten blättern 
+ ESC '1'        auf erste Zeile 
+ ESC '9'        auf letzte Zeile 
+ ESC 'h'        Abbruch, der Satz wird nicht eingefügt 
+ ESC 'w'        Beenden und gleich den nächsten Satz einfügen 
+ ESC 'D'        aktuelles Tagesdatum schreiben 
+--- 
+% SEITE 1 "EDIT/Allgemein" 
+% ENDE 
+% HILFE "EDIT/Aendern" 
+% SEITE 1 
+--- 
+Sie können die Inhalte des aktuellen Satzes hier abändern. 
+Spezielle Tastenkombinationen: 
+ ESC RUBOUT     Rest der Zeile löschen 
+ ESC RUBIN      Zeile aufbrechen 
+ ESC OBEN       nach oben blättern 
+ ESC UNTEN      nach unten blättern 
+ ESC '1'        auf erste Zeile 
+ ESC '9'        auf letzte Zeile 
+ ESC 'h'        Abbruch, der Satz bleibt unverändert 
+ ESC 'w'        Beenden und gleich den nächsten Satz ändern 
+ ESC 'D'        aktuelles Tagesdatum schreiben 
+--- 
+% SEITE 1 "EDIT/Allgemein" 
+% ENDE 
+% HILFE "EDIT/Druckmuster" 
+% SEITE 1 "EDIT/Allgemein" 
+% ENDE 
+% HILFE "EDIT/Verarbeite" 
+% SEITE 1 
+--- 
+Sie können hier eine Verarbeitungsvorschrift eingeben. Die
+Verarbeitungsvorschrift ist ein ELAN-Programm. Ein Feld wird
+geändert durch den Operator "V": 
+  "Feldname" V "neuer Feldinhalt"; 
+Statt des neuen Feldinhalts kann auch ein beliebiger ELAN-Aus­
+druck angegeben werden. Mit 
+  f ("Feldname") 
+wird der Inhalt eines Feldes als Text geliefert. 
+--- 
+% SEITE 1 "EDIT/Allgemein" 
+% ENDE 
+% HILFE "EDIT/Kopiermuster" 
+% SEITE 1 
+--- 
+Sie können das hier angegebene Kopiermuster verändern. Sollen
+Felder nicht kopiert werden, brauchen Sie nur die entsprechen­
+den Zeilen zu löschen. Soll eine Feld andere Inhalte bekommen,
+geben Sie in dem Ausdruck 
+  "Feldname" K f ("Feldname"); 
+hinter dem K einen anderen ELAN-Ausdruck ein. Die Reihenfolge
+der K-Ausdrücke bestimmt die Reihenfolge der Feldnamen in der
+Zieldatei, wenn die Zieldatei noch nicht existierte. 
+--- 
+% SEITE 1 "EDIT/Allgemein" 
+% ENDE 
+% HILFE "UEBERSICHT" 
+% SEITE 1 
+--- 
+In diesem Modus können Sie sich alle Sätze der Datei durch
+Blättern ansehen. Der aktuelle Satz ist jeweils markiert. Die
+eingestellte Suchbedingung wird beachtet. Mit den Pfeiltasten
+OBEN und UNTEN bewegen Sie sich vorwärts und rückwärts in der
+Datei. Mit HOP OBEN, HOP UNTEN und HOP RETURN blättern Sie wie
+im Editor. Mit ESC '1' gelangen Sie an den Anfang, mit ESC '9'
+an das Ende der Datei. Mit '+' und '-' können Sie die
+Markierung des aktuellen Satzes für spätere Verarbeitung
+ändern. Verlassen Sie die Übersicht mit ESC 'q'. 
+--- 
+% ENDE 
+% HILFE "SHOW/Uebersicht" 
+% SEITE 1 
+--- 
+In der gezeigten Dateiübersicht können Sie mit HOP OBEN und HOP
+UNTEN blättern, wenn nicht alle Dateien auf eine Seite passen.
+Verlassen Sie die Übersicht mit ESC 'q'. 
+--- 
+% ENDE 
+
diff --git a/eudas/pos.173 b/eudas/pos.173
new file mode 100644
index 0000000..a9706a3
--- /dev/null
+++ b/eudas/pos.173
@@ -0,0 +1,19 @@
+PACKET xpos DEFINES x pos : 
+INT PROC x pos (TEXT CONST a, b, INT CONST c, d) : 
+  pos (a, b, c, d) 
+END PROC x pos; 
+END PACKET x pos; 
+PACKET pos 173 DEFINES pos: 
+INT PROC pos (TEXT CONST a, b, INT CONST c, d) : 
+  x pos (a, b, c, d+1) 
+END PROC pos; 
+END PACKET pos 173; 
+PACKET add 173 DEFINES split line, reserve : 
+PROC split line (FILE VAR f, INT CONST spalte, BOOL CONST dummy) : 
+  split line (f, spalte) 
+END PROC split line; 
+PROC reserve (TEXT CONST modus, TASK CONST task) : 
+  call (19, modus, task) 
+END PROC reserve; 
+END PACKET add 173; 
+
diff --git a/graphic/Beispiel.Kreuz b/graphic/Beispiel.Kreuz
new file mode 100644
index 0000000..e29f24a
--- /dev/null
+++ b/graphic/Beispiel.Kreuz
@@ -0,0 +1,41 @@
+initialisiere picfile;
+zeichne die x achse;
+zeichne die y achse;
+zeichne die z achse;
+stelle das achsenkreuz dar  .
+
+initialisiere picfile:
+  PICFILE VAR p :: picture file ("KREUZ")  .
+
+zeichne die x achse:
+  PICTURE VAR x achse := nilpicture;
+  move (x achse, -1.0, 0.0, 0.0);
+  draw (x achse, "-X", 0.0, 0.0, 0.0);
+  draw (x achse,  1.0, 0.0, 0.0);
+  draw (x achse, "+X", 0.0, 0.0, 0.0);
+  put picture (p, x achse)  .
+
+zeichne die y achse:
+  PICTURE VAR y achse := nilpicture;
+  move (y achse, 0.0, -1.0, 0.0);
+  draw (y achse, "-Y", 0.0, 0.0, 0.0);
+  draw (y achse, 0.0, 1.0, 0.0);
+  draw (y achse, "+Y", 0.0, 0.0, 0.0);
+  put picture (p, y achse)  .
+
+zeichne die z achse:
+  PICTURE VAR z achse := nilpicture;
+  move (z achse, 0.0, 0.0, -1.0);
+  draw (z achse, "-Z", 0.0, 0.0, 0.0);
+  draw (z achse,  0.0, 0.0, 1.0);
+  draw (z achse, "+Z", 0.0, 0.0, 0.0);
+  put picture (p, z achse)  .
+
+stelle das achsenkreuz dar:
+  viewport (p, 0.0, 1.0, 0.0, 1.0);
+  window (p, -1.1, 1.1, -1.1, 1.1);
+  oblique (p, 0.25, 0.15);
+  plot (p)  .
+
+
+
diff --git a/graphic/Beispiel.Sinus b/graphic/Beispiel.Sinus
new file mode 100644
index 0000000..beac7cd
--- /dev/null
+++ b/graphic/Beispiel.Sinus
@@ -0,0 +1,45 @@
+initialisiere picfile;
+zeichne überschrift;
+zeichne achsen;
+zeichne sinuskurve;
+wähle darstellung;
+plot (p)  .
+
+initialisiere picfile:
+  PICFILE VAR p :: picture file ("SINUS")  .
+
+zeichne überschrift:
+  PICTURE VAR überschrift :: nilpicture;
+  move (überschrift, -pi/2.0, 1.0);
+  draw (überschrift, "sinus (x)  [-pi, +pi]", 0.0, 1.0, 0.6);
+  put picture (p, überschrift)  .
+
+zeichne achsen:
+  PICTURE VAR achsen :: nilpicture;
+  zeichne x achse;
+  zeichne y achse;
+  put picture (p, achsen)  .
+
+zeichne x achse:
+  move (achsen, -pi, 0.0);
+  draw (achsen,  pi, 0.0)  .
+
+zeichne y achse:
+  move (achsen, 0.0, -1.0);
+  draw (achsen, 0.0, +1.0)  .
+
+zeichne sinuskurve:
+  PICTURE VAR sinus :: nilpicture;
+  REAL VAR x :: -pi;
+
+  move (sinus, x, sin (x));
+  REP x INCR 0.1;
+      draw (sinus, x, sin (x))
+  UNTIL x >= pi PER;
+
+  put picture (p, sinus)  .
+
+wähle darstellung:
+  window (p, -pi, pi, -1.0, 1.3);
+  viewport (p, 0.0, 0.0, 0.0, 0.0)  .
+
diff --git a/graphic/GRAPHIK.Picfile b/graphic/GRAPHIK.Picfile
new file mode 100644
index 0000000..3accf52
--- /dev/null
+++ b/graphic/GRAPHIK.Picfile
@@ -0,0 +1,738 @@
+PACKET picture DEFINES                        (*Autor: Heiko.Indenbirken *)
+               PICTURE,                       (*Stand:    12.03.1985     *)
+               :=, CAT, nilpicture,           (*Änderung: 20.08.85/10:38 *)
+               draw, draw r,                  (*Änderung: 05.08.86/12:21 *)
+               move, move r,
+               mark, bar, circle,
+               length, dim, pen, where,
+               extrema, rotate, stretch, translate,
+               picture:
+
+LET draw key      = 1,
+    move key      = 2,
+    text key      = 3,
+    move r key    = 4,
+    draw r key    = 5,
+    bar 2 key     = 6,
+    bar 3 key     = 7,
+    circle key    = 8,
+    mark key      = 9,
+    max length    = 31974;
+
+LET overflow  = "Picture overflow",
+    pen range = "pen out of range [0-16]",
+    dim 3     = "Picture is 3 dimensional",
+    dim 2     = "Picture is 2 dimensional",
+    dim init  = "Picture isn't initialized",
+    wrong key = "wrong key code",
+    nil       = "",
+    zero      = ""0"";
+
+TYPE PICTURE = STRUCT (INT dim, pen, TEXT points);
+
+
+INT VAR read pos;
+REAL VAR x, y, z;
+TEXT VAR r1 :: 8*zero, r2 :: 16*zero, r3 :: 24*zero, i1 :: 2*zero;
+
+OP := (PICTURE VAR l, PICTURE CONST r) :
+  CONCR (l) := CONCR (r)
+END OP :=;
+
+OP CAT (PICTURE VAR l, PICTURE CONST r) :
+  check dim (l, r.dim);
+  IF length (l.points) > max length - length (r.points)
+  THEN errorstop (overflow) FI;
+
+  l.points CAT r.points
+END OP CAT;
+
+PICTURE PROC nilpicture :
+  PICTURE : (0, 1, nil)
+END PROC nilpicture;
+
+PICTURE PROC nilpicture (INT CONST pen):
+  PICTURE : (0, pen, nil)
+END PROC nilpicture;
+
+PROC draw (PICTURE VAR p, TEXT CONST text, REAL CONST angle, height, bright):
+  write (p.points, text, angle, height, bright, text key)
+END PROC draw;
+
+PROC draw (PICTURE VAR p, REAL CONST x, y, z) :
+  check dim (p, 3);
+  write (p.points, x, y, z, draw key)
+END PROC draw;
+
+PROC draw (PICTURE VAR p, REAL CONST x, y) :
+  check dim (p, 2);
+  write (p.points, x, y, draw key)
+END PROC draw;
+
+PROC draw r (PICTURE VAR p, REAL CONST x, y, z) :
+  check dim (p, 3);
+  write (p.points, x, y, z, draw r key)
+END PROC draw r;
+
+PROC draw r (PICTURE VAR p, REAL CONST x, y) :
+  check dim (p, 2);
+  write (p.points, x, y, draw r key)
+END PROC draw r;
+
+PROC move (PICTURE VAR p, REAL CONST x, y, z) :
+  check dim (p, 3);
+  write (p.points, x, y, z, move key)
+END PROC move;
+
+PROC move (PICTURE VAR p, REAL CONST x, y) :
+  check dim (p, 2);
+  write (p.points, x, y, move key)
+END PROC move;
+
+PROC move r (PICTURE VAR p, REAL CONST x, y, z) :
+  check dim (p, 3);
+  write (p.points, x, y, z, move r key)
+END PROC move r;
+
+PROC move r (PICTURE VAR p, REAL CONST x, y) :
+  check dim (p, 2);
+  write (p.points, x, y, move r key)
+END PROC move r;
+
+PROC bar (PICTURE VAR p, REAL CONST width, height, INT CONST pattern):
+  check dim (p, 2);
+  write (p.points, width, height, pattern, bar 2 key)
+END PROC bar;
+
+PROC bar (PICTURE VAR p, REAL CONST from, to, height, INT CONST pattern):
+  check dim (p, 2);
+  write (p.points, from, to, height, pattern, bar 3 key)
+END PROC bar;
+
+PROC circle (PICTURE VAR p, REAL CONST radius, from, to, INT CONST pattern):
+  check dim (p, 2);
+  write (p.points, radius, from, to, pattern, circle key)
+END PROC circle;
+
+PROC mark (PICTURE VAR p, REAL CONST size, INT CONST no):
+  write (p.points, size, no, mark key)
+END PROC mark;
+
+PROC write (TEXT VAR points, REAL CONST x, y, z, INT CONST key) :
+  IF length (points) < max length
+  THEN points CAT code (key); 
+       replace (r3, 1, x);
+       replace (r3, 2, y);
+       replace (r3, 3, z);
+       points CAT r3
+  ELSE errorstop (overflow) FI
+END PROC write;
+
+PROC write (TEXT VAR points, REAL CONST x, y, INT CONST key) :
+  IF length (points) < max length
+  THEN points CAT code (key); 
+       replace (r2, 1, x);
+       replace (r2, 2, y);
+       points CAT r2
+  ELSE errorstop (overflow) FI
+END PROC write;
+
+PROC write (TEXT VAR points, REAL CONST x, y, INT CONST n, key) :
+  IF length (points) < max length
+  THEN points CAT code (key); 
+       replace (r2, 1, x);
+       replace (r2, 2, y);
+       points CAT r2;
+       replace (i1, 1, n);
+       points CAT i1
+  ELSE errorstop (overflow) FI
+END PROC write;
+
+PROC write (TEXT VAR points, REAL CONST x, y, z, INT CONST n, key) :
+  IF length (points) < max length
+  THEN points CAT code (key); 
+       replace (r3, 1, x);
+       replace (r3, 2, y);
+       replace (r3, 3, z);
+       points CAT r3;
+       replace (i1, 1, n);
+       points CAT i1 
+  ELSE errorstop (overflow) FI
+END PROC write;
+
+PROC write (TEXT VAR points, TEXT CONST t, REAL CONST angle, height, bright,
+            INT CONST key) :
+  IF max length - length (points) >= length (t)
+  THEN points CAT code (key);
+       replace (i1, 1, length (t));
+       points CAT i1;
+       points CAT t;
+       replace (r3, 1, angle);
+       replace (r3, 2, height);
+       replace (r3, 3, bright);
+       points CAT r3
+  FI;
+END PROC write;
+
+PROC write (TEXT VAR points, REAL CONST size, INT CONST no, key) :
+  IF length (points) < max length
+  THEN points CAT code (key); 
+       replace (r1, 1, size);
+       points CAT r1;
+       replace (i1, 1, no);
+       points CAT i1;
+  ELSE errorstop (overflow) FI
+END PROC write;
+
+PROC check dim (PICTURE VAR p, INT CONST dim):
+  IF p.dim = dim
+  THEN
+  ELIF p.dim = 0
+  THEN p.dim := dim
+  ELSE errorstop (dimension) FI  .
+
+dimension:
+  IF p.dim = 2
+  THEN dim 2
+  ELIF p.dim = 3
+  THEN dim 3
+  ELSE dim init FI  .
+
+END PROC check dim;
+
+INT PROC length (PICTURE CONST p):
+  length (p.points)
+END PROC length;
+
+INT PROC dim (PICTURE CONST pic) :
+  pic.dim
+END PROC dim;
+
+PICTURE PROC pen (PICTURE CONST p, INT CONST pen) :
+  IF pen < 0 OR pen > 16
+  THEN errorstop (pen range) FI;
+
+  PICTURE:(p.dim, pen, p.points)
+END PROC pen;
+
+INT PROC pen (PICTURE CONST p) :
+  p.pen
+END PROC pen;
+
+PROC where (PICTURE CONST p, REAL VAR x, y) :
+  IF p.dim = 0
+  THEN x := 0.0;  y := 0.0
+  ELIF p.dim = 3
+  THEN errorstop (dim 3)
+  ELSE x := subtext (p.points, length (p.points)-15, length (p.points)-8) RSUB 1;
+       y := subtext (p.points, length (p.points)-7,  length (p.points)) RSUB 1
+  FI
+END PROC where;
+
+PROC where (PICTURE CONST p, REAL VAR x, y, z) :
+  IF p.dim = 0
+  THEN x := 0.0;  y := 0.0;  z := 0.0
+  ELIF p.dim = 2
+  THEN errorstop (dim 2)
+  ELSE x := subtext (p.points, length (p.points)-23, length (p.points)-16) RSUB 1;
+       y := subtext (p.points, length (p.points)-15, length (p.points)-8) RSUB 1;
+       z := subtext (p.points, length (p.points)-7,  length (p.points)) RSUB 1;
+  FI
+END PROC where;
+
+
+PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y max, z min, z max) :
+  x min := max real;  x max :=-max real;
+  y min := max real;  y max :=-max real;
+  z min := max real;  z max :=-max real;
+  read pos := 0; 
+  INT CONST pic length := length (p.points);
+  WHILE read pos < pic length
+  REP check position PER  .
+
+check position :
+  read pos INCR 1;
+  SELECT code (p.points SUB read pos) OF
+  CASE draw key : calc extrema
+  CASE move key : calc extrema
+  CASE move r key : calc rel extrema
+  CASE draw r key : calc rel extrema
+  CASE text key : read pos INCR next int + 24
+  CASE bar 2 key : read pos INCR 18
+  CASE bar 3 key, circle key : read pos INCR 26
+  CASE mark key: read pos INCR 4 
+  OTHERWISE errorstop (wrong key) END SELECT  . 
+
+calc extrema :
+  x := next real;  y := next real;  z := next real;
+  x min := min (x min, x);  x max := max (x max, x);
+  y min := min (y min, y);  y max := max (y max, y);
+  z min := min (z min, z);  z max := max (z max, z)  .
+
+calc rel extrema :
+  x INCR next real;  y INCR next real;  z INCR next real;
+  x min := min (x min, x);  x max := max (x max, x);
+  y min := min (y min, y);  y max := max (y max, y);
+  z min := min (z min, z);  z max := max (z max, z)  .
+
+next real :
+  read pos INCR 8;
+  subtext (p.points, read pos-7, read pos) RSUB 1  .
+
+next int :
+  read pos INCR 2;
+  subtext (p.points, read pos-1, read pos) ISUB 1  .
+
+END PROC extrema;
+
+PROC extrema (PICTURE CONST p, REAL VAR x min, x max, y min, y max):
+  x min := max real;  x max :=-max real;
+  y min := max real;  y max :=-max real;
+  read pos := 0; 
+  INT CONST pic length := length (p.points);
+  WHILE read pos < pic length
+  REP check position PER  .
+
+check position :
+  read pos INCR 1;
+  SELECT code (p.points SUB read pos) OF
+  CASE draw key : calc extrema
+  CASE move key : calc extrema
+  CASE move r key : calc rel extrema
+  CASE draw r key : calc rel extrema
+  CASE text key : read pos INCR next int + 24
+  CASE bar 2 key : read pos INCR 18
+  CASE bar 3 key, circle key : read pos INCR 26
+  CASE mark key: read pos INCR 4 
+  OTHERWISE errorstop (wrong key) END SELECT  . 
+
+calc extrema :
+  x := next real;  y := next real;
+  x min := min (x min, x);  x max := max (x max, x);
+  y min := min (y min, y);  y max := max (y max, y)  .
+
+calc rel extrema :
+  x INCR next real;  y INCR next real;
+  x min := min (x min, x);  x max := max (x max, x);
+  y min := min (y min, y);  y max := max (y max, y)  .
+
+next real :
+  read pos INCR 8;
+  subtext (p.points, read pos-7, read pos) RSUB 1  .
+
+next int :
+  read pos INCR 2;
+  subtext (p.points, read pos-1, read pos) ISUB 1  .
+
+END PROC extrema;
+
+PROC rotate (PICTURE VAR p, REAL CONST angle) :
+  REAL CONST s :: sind( angle ), c := cosd( angle );
+  transform (p, ROW 4 ROW 3 REAL : 
+               (ROW 3 REAL : ( 1.0,  0.0,  0.0 ),
+                ROW 3 REAL : ( 0.0,   c ,   s  ),
+                ROW 3 REAL : ( 0.0,  -s ,   c  ),
+                ROW 3 REAL : ( 0.0,  0.0,  0.0 )))
+END PROC rotate;
+
+PROC rotate (PICTURE VAR p, REAL CONST phi, theta, lambda ) :
+  REAL CONST s   :: sind ( theta ), c   :: cosd ( theta ),
+             s p :: sind (  phi  ), s l :: sind ( lambda ),
+             ga  :: cosd (  phi  ), c l :: cosd ( lambda ),
+             be  :: s p * s l,      al  :: s p * c l, c1 :: 1.0 - c;
+  transform (p, ROW 4 ROW 3 REAL : 
+               (ROW 3 REAL : ( al*al*c1 + c , be*al*c1+ga*s, ga*al*c1-be*s ),
+                ROW 3 REAL : ( al*be*c1-ga*s, be*be*c1 + c , ga*be*c1+al*s ),
+                ROW 3 REAL : ( al*ga*c1+be*s, be*ga*c1-al*s, ga*ga*c1 + c  ),
+                ROW 3 REAL : (      0.0     ,      0.0     ,      0.0    )))
+END PROC rotate; 
+ 
+PROC stretch (PICTURE VAR pic, REAL CONST sx, sy) : 
+  stretch (pic, sx, sy, 1.0) 
+END PROC stretch;
+
+PROC stretch (PICTURE VAR p, REAL CONST sx, sy, sz) :
+  transform (p, ROW 4 ROW 3 REAL : 
+               (ROW 3 REAL : ( sx, 0.0, 0.0),
+                ROW 3 REAL : (0.0,  sy, 0.0),
+                ROW 3 REAL : (0.0, 0.0,  sz),
+                ROW 3 REAL : (0.0, 0.0, 0.0)))
+END PROC stretch;
+
+PROC translate (PICTURE VAR p, REAL CONST dx, dy) : 
+  translate (p, dx, dy, 0.0) 
+END PROC translate;
+
+PROC translate (PICTURE VAR p, REAL CONST dx, dy, dz) :
+  transform (p, ROW 4 ROW 3 REAL : 
+               (ROW 3 REAL : (1.0, 0.0, 0.0),
+                ROW 3 REAL : (0.0, 1.0, 0.0),
+                ROW 3 REAL : (0.0, 0.0, 1.0),
+                ROW 3 REAL : ( dx,  dy,  dz)))
+END PROC translate;
+
+PROC transform (PICTURE VAR p, ROW 4 ROW 3 REAL CONST a) :
+  INT CONST pic length := length (p.points);
+  INT VAR begin pos;
+  read pos := 0; 
+  x := 0.0; y := 0.0; z := 0.0;
+  IF p.dim = 2
+  THEN transform 2 dim pic
+  ELSE transform 3 dim pic FI  .
+ 
+transform 2 dim pic:
+  WHILE read pos < pic length
+  REP transform 2 dim position PER  .
+
+transform 2 dim position:
+  read pos INCR 1;
+  SELECT code (p.points SUB read pos) OF
+  CASE draw key : transform 2 dim point 
+  CASE move key : transform 2 dim point 
+  CASE move r key : transform 2 dim point 
+  CASE draw r key : transform 2 dim point 
+  CASE text key : read pos INCR next int + 24
+  CASE bar 2 key : read pos INCR 18
+  CASE bar 3 key, circle key : read pos INCR 26
+  CASE mark key: read pos INCR 4 
+  OTHERWISE errorstop (wrong key) END SELECT  . 
+
+transform 2 dim point:
+  begin pos := read pos+1;
+  x := next real;  y := next real;
+  transform (a, x, y, z); 
+  replace (r2, 1, x);
+  replace (r2, 2, y);
+  replace (p.points, begin pos, r2)  .
+
+transform 3 dim pic:
+  WHILE read pos < pic length
+  REP transform 3 dim position PER  .
+
+transform 3 dim position :
+  read pos INCR 1;
+  SELECT code (p.points SUB read pos) OF
+  CASE draw key : transform 3 dim point 
+  CASE move key : transform 3 dim point 
+  CASE move r key : transform 3 dim point 
+  CASE draw r key : transform 3 dim point 
+  CASE text key : read pos INCR next int + 24
+  CASE bar 2 key : read pos INCR 18
+  CASE bar 3 key, circle key : read pos INCR 26
+  CASE mark key: read pos INCR 4
+  OTHERWISE errorstop (wrong key) END SELECT  . 
+
+transform 3 dim point:
+  begin pos := read pos+1;
+  x := next real;  y := next real; z := next real;
+  transform (a, x, y, z); 
+  replace (r3, 1, x);
+  replace (r3, 2, y);
+  replace (r3, 3, z);
+  replace (p.points, begin pos, r3)  .
+
+next real :
+  read pos INCR 8;
+  subtext (p.points, read pos-7, read pos) RSUB 1  .
+
+next int :
+  read pos INCR 2;
+  subtext (p.points, read pos-1, read pos) ISUB 1  .
+
+END PROC transform;
+
+PROC transform (ROW 4 ROW 3 REAL CONST a, REAL VAR x, y, z) :
+  REAL CONST ox :: x, oy :: y, oz :: z;
+  x := ox*a(1)(1) + oy*a(2)(1) + oz*a(3)(1) + a(4)(1);
+  y := ox*a(1)(2) + oy*a(2)(2) + oz*a(3)(2) + a(4)(2);
+  z := ox*a(1)(3) + oy*a(2)(3) + oz*a(3)(3) + a(4)(3)
+END PROC transform;
+
+PROC picture (PICTURE CONST pic, TEXT VAR points, INT VAR dim, pen):
+  dim    := pic.dim;
+  pen    := pic.pen;
+  points := pic.points;
+END PROC picture;
+
+END PACKET picture;
+
+PACKET picfile DEFINES                        (*Autor: Heiko Indenbirken *)
+                                              (*Stand:    23.02.1985     *)
+               PICFILE, :=, picture file,     (*Änderung: 13.10.89/23:11 *)
+               select pen, selected pen, background, 
+               set values, get values,
+               view, viewport, window,
+               oblique, orthographic, perspective,
+               extrema,
+
+               to pic, up, down,
+               eof, picture no, pictures,
+               delete picture, insert picture,
+               read picture, write picture,
+               get picture, put picture:
+
+
+LET no picfile = "dataspace is no PICFILE",
+    pen range  = "pen out of range",
+    pos under  = "Position underflow",
+    pos over   = "Position overflow",
+    pic over   = "PICFILE overflow";
+
+LET max pics = 1024,
+    pic dataspace = 1103;
+
+
+TYPE PICFILE = BOUND STRUCT (INT size, pos, background,
+                             ROW 16 ROW 3 INT pens,
+                             ROW 3 ROW 2 REAL sizes,
+                             ROW 2 ROW 2 REAL limits,
+                             ROW 4 REAL angles,
+                             ROW 2 REAL obliques,
+                             ROW 3 REAL perspectives
+                             ROW max pics PICTURE pic);
+
+INT VAR i;
+
+OP := (PICFILE VAR l, PICFILE CONST r):
+  EXTERNAL 260
+END OP :=;
+
+OP := (PICFILE VAR p, DATASPACE CONST d) :
+  IF type (d) = pic dataspace
+    THEN CONCR (p) := d
+  ELIF type (d) < 0
+    THEN type (d, pic dataspace) ;
+         CONCR (p) := d ;
+         init picfile dataspace ;
+  ELSE errorstop (no picfile) FI .
+ 
+init picfile dataspace :
+  r.size := 0;
+  r.pos  := 1;
+  r.background := 0;
+  r.sizes := ROW 3 ROW 2 REAL : (ROW 2 REAL : (0.0, 1.0),
+                                 ROW 2 REAL : (0.0, 1.0),
+                                 ROW 2 REAL : (0.0, 1.0));
+  r.limits := ROW 2 ROW 2 REAL : (ROW 2 REAL : (0.0, 0.0),
+                                  ROW 2 REAL : (0.0, 0.0));
+  r.angles := ROW 4 REAL : (0.0, 0.0, 0.0, 0.0);
+  r.obliques := ROW 2 REAL : (0.0, 0.0);
+  r.perspectives := ROW 3 REAL : (0.0, 0.0, 0.0);
+  FOR i FROM 1 UPTO 16
+  REP r.pens [i] := ROW 3 INT : (1, 0, 1) PER  .
+
+r : CONCR (CONCR (p)).
+END OP :=;
+ 
+DATASPACE PROC picture file (TEXT CONST name) :
+  IF exists (name)
+  THEN old (name)
+  ELSE new (name) FI 
+END PROC picture file;
+
+PROC select pen (PICFILE VAR p, INT CONST pen, colour, thickness, line type):
+  IF pen < 1 OR pen > 16
+  THEN errorstop (pen range) FI;
+  p.pens   [pen] := ROW 3 INT : (colour, thickness, line type)
+END PROC select pen;
+
+PROC selected pen (PICFILE CONST p, INT CONST pen,
+                                    INT VAR colour, thickness, line type):
+  IF pen < 1 OR pen > 16
+  THEN errorstop (pen range) FI;
+  colour    := p.pens [pen][1];
+  thickness := p.pens [pen][2];
+  line type := p.pens [pen][3];
+END PROC selected pen;
+
+INT PROC background (PICFILE CONST p):
+  p.background
+END PROC background;
+
+PROC background (PICFILE VAR p, INT CONST colour):
+  p.background := colour
+END PROC background;
+
+PROC get values (PICFILE CONST p,
+                 ROW 3 ROW 2 REAL VAR size, 
+                 ROW 2 ROW 2 REAL VAR limits,
+                 ROW 4 REAL VAR angles,
+                 ROW 2 REAL VAR oblique,
+                 ROW 3 REAL VAR perspective) : 
+  size        := p.sizes;
+  limits      := p.limits;
+  angles      := p.angles;
+  oblique     := p.obliques;
+  perspective := p.perspectives;
+
+END PROC get values;
+ 
+PROC set values (PICFILE VAR p,
+                 ROW 3 ROW 2 REAL CONST size, 
+                 ROW 2 ROW 2 REAL CONST limits,
+                 ROW 4 REAL CONST angles,
+                 ROW 2 REAL CONST oblique,
+                 ROW 3 REAL CONST perspective) : 
+  p.sizes        := size;
+  p.limits       := limits;
+  p.angles       := angles;
+  p.obliques     := oblique;
+  p.perspectives := perspective;
+
+END PROC set values;
+ 
+PROC view (PICFILE VAR p, REAL CONST alpha):
+  p.angles [1] := alpha
+END PROC view;
+
+PROC view (PICFILE VAR p, REAL CONST phi, theta):
+  p.angles [2] := sind (theta) * cosd (phi);
+  p.angles [3] := sind (theta) * sind (phi);
+  p.angles [4] := cosd (theta);
+END PROC view;
+
+PROC view (PICFILE VAR p, REAL CONST x, y, z):
+  p.angles [2] := x;
+  p.angles [3] := y;
+  p.angles [4] := z
+END PROC view;
+
+PROC viewport (PICFILE VAR p,REAL CONST hor min,hor max,vert min,vert max) :
+  p.limits := ROW 2 ROW 2 REAL : (ROW 2 REAL : (hor min, hor max),
+                                  ROW 2 REAL : (vert min, vert max))
+END PROC viewport;
+
+PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max) :
+  window (p, x min, x max, y min, y max, 0.0, 1.0)
+END PROC window;
+
+PROC window (PICFILE VAR p, REAL CONST x min, x max, y min, y max, z min, z max) :
+  p.sizes := ROW 3 ROW 2 REAL : (ROW 2 REAL : (x min, x max),
+                                 ROW 2 REAL : (y min, y max),
+                                 ROW 2 REAL : (z min, z max))
+END PROC window;
+
+PROC oblique (PICFILE VAR p, REAL CONST a, b) :
+  p.obliques := ROW 2 REAL : (a, b);
+  p.perspectives := ROW 3 REAL : (0.0, 0.0, 0.0)
+END PROC oblique;
+
+PROC orthographic (PICFILE VAR p) :
+  p.obliques := ROW 2 REAL : (0.0, 0.0);
+  p.perspectives := ROW 3 REAL : (0.0, 0.0, 0.0)
+END PROC orthographic;
+ 
+PROC perspective (PICFILE VAR p, REAL CONST cx, cy, cz) :
+  p.obliques := ROW 2 REAL : (0.0, 0.0);
+  p.perspectives := ROW 3 REAL : (cx, cy, cz)
+END PROC perspective;
+ 
+PROC extrema (PICFILE VAR p, REAL VAR x min, x max, y min, y max) :
+  REAL VAR dummy;
+  extrema (p, x min, x max, y min, y max, dummy, dummy)
+END PROC extrema;
+
+PROC extrema (PICFILE VAR p, REAL VAR x min,x max,y min,y max,z min,z max) :
+  REAL VAR new x min, new x max, new y min, new y max, new z min, new z max;
+  x min := max real;  x max := - max real;
+  y min := max real;  y max := - max real;
+  z min := max real;  z max := - max real;
+  FOR i FROM 1 UPTO p.size
+  REP IF dim (p.pic [i]) = 2
+      THEN extrema (p.pic [i], new x min, new x max, new y min, new y max) 
+      ELSE extrema (p.pic [i], new x min, new x max, new y min, new y max,
+                               new z min, new z max)
+      FI;
+      x min := min (x min, new x min); x max := max (x max, new x max); 
+      y min := min (y min, new y min); y max := max (y max, new y max); 
+      z min := min (z min, new z min); z max := max (z max, new z max); 
+  PER
+END PROC extrema;
+
+PROC to pic (PICFILE VAR p, INT CONST n):
+  IF n < 1
+  THEN errorstop (pos under)
+  ELIF n <= p.size+1 AND n <= max pics
+  THEN p.pos := n
+  ELSE errorstop (pos over) FI
+END PROC to pic;
+
+PROC up (PICFILE VAR p):
+  to pic (p, p.pos-1)
+END PROC up;
+
+PROC up (PICFILE VAR p, INT CONST n):
+  to pic (p, p.pos-n)
+END PROC up;
+
+PROC down (PICFILE VAR p):
+  to pic (p, p.pos+1)
+END PROC down;
+
+PROC down (PICFILE VAR p, INT CONST n):
+  to pic (p, p.pos+n)
+END PROC down;
+
+BOOL PROC eof (PICFILE CONST p):
+  p.pos >= p.size
+END PROC eof;
+
+INT PROC picture no (PICFILE CONST p):
+  p.pos
+END PROC picture no;
+
+INT PROC pictures (PICFILE CONST p):
+  p.size
+END PROC pictures;
+
+PROC delete picture (PICFILE VAR p) :
+  INT VAR i;
+  FOR i FROM p.pos+1 UPTO p.size
+  REP p.pic [i-1] := p.pic [i] PER;
+
+  p.pic [p.size] := nilpicture;
+  IF p.size > 1
+  THEN p.size DECR 1 FI
+END PROC delete picture;
+
+PROC insert picture (PICFILE VAR p) :
+  INT VAR i;
+  IF p.size >= max pics
+  THEN errorstop (pic over)
+  ELSE p.size INCR 1;
+       FOR i FROM p.size DOWNTO p.pos+1
+       REP p.pic [i] := p.pic [i-1] PER;
+
+       p.pic [p.pos] := nilpicture;
+  FI
+END PROC insert picture;
+
+PROC read picture (PICFILE VAR p, PICTURE VAR pic) :
+  pic := p.pic (p.pos)  .
+END PROC read picture;
+ 
+PROC write picture (PICFILE VAR p, PICTURE CONST pic) :
+  p.pic (p.pos) := pic  .
+END PROC write picture;
+
+PROC get picture (PICFILE VAR p, PICTURE VAR pic) :
+  IF p.pos > p.size
+  THEN errorstop (pos over)
+  ELSE pic := p.pic [p.pos];
+       p.pos INCR 1;
+  FI 
+END PROC get picture;
+
+PROC put picture (PICFILE VAR p, PICTURE CONST pic) :
+  IF p.pos > max pics
+  THEN errorstop (pic over)
+  ELSE p.pic [p.pos] := pic;
+
+       IF p.pos > p.size
+       THEN p.size INCR 1 FI;
+       p.pos INCR 1
+  FI 
+END PROC put picture;
+
+END PACKET picfile
+
diff --git a/graphic/GRAPHIK.Plot b/graphic/GRAPHIK.Plot
new file mode 100644
index 0000000..5087abb
--- /dev/null
+++ b/graphic/GRAPHIK.Plot
@@ -0,0 +1,285 @@
+PACKET basis plot DEFINES                     (* Autor: Heiko Indenbirken*)
+                                              (* Stand: 12.04.85         *)
+                                              (*Änderung: 06.08.86/10:03 *)
+(*  ******************  Hardwareunabhängiger Teil  ********************* *)
+(*                                                                       *)
+(*                                                                       *)
+(*      Im Harwareunabhängigen Paket 'basis plot' werden folgende        *)
+(*      Prozeduren definiert:                                            *)
+(*      Procedure       :  Bedeutung                                     *)
+(*      ---------------------------------------------------------------- *)
+(*       move           :  Positioniert auf (x, y,[z]) in Weltkoordinaten*)
+(*       draw           :  Zeichnet eine Linie bis zum Punkt (x, y, [z]).*)
+(*       move r         :  Positioniert (x, y, [z]) weiter               *)
+(*       draw r         :  Zeichnet (x, y, [z]) weiter                   *)
+(*                                                                       *)
+(*       draw           :  Zeichnet einen Text                           *)
+(*                                                                       *)
+(*       mark           :  Marker mit (no, size)                         *)
+(*       bar            :  Balken mit (width, height, pattern)           *)
+(*       bar            :  Balken mit (from, to, width, pattern)         *)
+(*       circle         :  Kreis(segment) mit (radius, from, to, pattern)*)
+(*                                                                       *)
+(*       where          :  Gibt die aktuelle Stiftposition (x, y, [z])   *)
+(*                                                                       *)
+(*************************************************************************)
+
+       move, draw,
+       move r, draw r,
+       mark, bar, circle,
+       where:
+
+LET POS = STRUCT (REAL x, y, z);
+
+POS VAR pos :: POS : (0.0, 0.0, 0.0);
+INT VAR h :: 0, v :: 0;
+
+PROC move (REAL CONST x, y) :
+  transform (x, y, 0.0, h, v);
+  move (h, v);
+  pos := POS : (x, y, 0.0)
+END PROC move;
+
+PROC move (REAL CONST x, y, z) :
+  transform (x, y, z, h, v);
+  move (h, v);
+  pos := POS : (x, y, z)
+END PROC move;
+
+PROC draw (REAL CONST x, y) :
+  transform (x, y, 0.0, h, v);
+  draw (h, v);
+  pos := POS : (x, y, 0.0)
+END PROC draw;
+
+PROC draw (REAL CONST x, y, z) :
+  transform (x, y, z, h, v);
+  draw (h, v);
+  pos := POS : (x, y, z) 
+END PROC draw;
+
+PROC move r (REAL CONST x, y) :
+  transform (pos.x+x, pos.y+y, pos.z, h, v);
+  move (h, v);
+  pos := POS : (pos.x+x, pos.y+y, pos.z)
+END PROC move r;
+
+PROC move r (REAL CONST x, y, z) :
+  transform (pos.x+x, pos.y+y, pos.z+z, h, v);
+  move (h, v);
+  pos := POS : (pos.x+x, pos.y+y, pos.z+z)
+END PROC move r;
+
+PROC draw r (REAL CONST x, y) :
+  transform (pos.x+x, pos.y+y, pos.z, h, v); 
+  draw (h, v);
+  pos := POS : (pos.x+x, pos.y+y, pos.z)
+END PROC draw r;
+
+PROC draw r (REAL CONST x, y, z) :
+  transform (pos.x+x, pos.y+y, pos.z+z, h, v);
+  draw (h, v);
+  pos := POS : (pos.x+x, pos.y+y, pos.z+z)
+END PROC draw r;
+
+PROC where (REAL VAR x, y) :
+  x := pos.x;  y := pos.y
+END PROC where;
+
+PROC where (REAL VAR x, y, z) :
+  x := pos.x;  y := pos.y;  z := pos.z
+END PROC where;
+
+PROC draw (TEXT CONST msg, REAL CONST angle, height percent, width percent):
+  draw (msg, angle, height (height percent), width (width percent))  .
+END PROC draw;
+
+PROC mark (REAL CONST size, INT CONST no):
+  marker (h, v, no, diagonal (size))
+END PROC mark;
+
+PROC bar (REAL CONST width, height, INT CONST pattern):
+  INT VAR diff, up, zero x, zero y;
+  transform (0.0, 0.0, 0.0, zero x, zero y);
+  transform (width*0.5, height, 0.0, diff, up);
+  bar (h-(diff-zero x), v, h+(diff-zero x), v+(up-zero y), pattern);
+  move (h, v) 
+
+END PROC bar;
+
+PROC bar (REAL CONST from, to, height, INT CONST pattern):
+  INT VAR from h, to h, up;
+  transform (from, height, 0.0, from h, up);
+  transform (to,   height, 0.0, to h, up);
+  bar (from h, v, to h, up, pattern);
+  move (h, v) 
+
+END PROC bar;
+
+PROC circle (REAL CONST rad, from, to, INT CONST pattern):
+  circle (h, v, diagonal (rad), from, to, pattern)  .
+
+END PROC circle;
+
+ENDPACKET basis plot;
+
+PACKET plot DEFINES plot:                     (*Autor: Heiko Indenbirken *)
+                                              (*Stand:    13.10.89/22:31 *)
+
+LET draw key      = 1,
+    move key      = 2,
+    text key      = 3,
+    move r key    = 4,
+    draw r key    = 5,
+    bar 2 key     = 6,
+    bar 3 key     = 7,
+    circle key    = 8,
+    mark key      = 9;
+
+LET dim error = "PICTURE not initialized",
+    key error = "wrong key code: ";
+
+TEXT VAR points;
+INT VAR pic length, pic pen, pic dim, read pos;
+PICTURE VAR pic;
+
+PROC plot (PICTURE CONST pic):
+  init plot;
+  IF pic dim = 2
+  THEN plot two dim pic
+  ELIF pic dim = 3
+  THEN plot three dim pic
+  ELIF NOT (pic dim = 0 AND pic length = 0)
+  THEN errorstop (dim error) FI;
+  points := ""  .
+
+init plot:
+  picture (pic, points, pic dim, pic pen);
+  pic length := length (points);
+  read pos := 0  .
+
+plot two dim pic:
+  WHILE read pos < pic length
+  REP plot two dim position PER  .
+
+plot two dim position :
+  read pos INCR 1;
+  SELECT key OF
+  CASE draw key:   draw (next real, next real)
+  CASE move key:   move (next real, next real)
+  CASE move r key: move r (next real, next real)
+  CASE draw r key: draw r (next real, next real)
+  CASE text key:   draw (next text, next real, next real, next real)
+  CASE bar 2 key:  bar (next real, next real, next int) 
+  CASE bar 3 key:  bar (next real, next real, next real, next int) 
+  CASE circle key: circle (next real, next real, next real, next int) 
+  CASE mark key:   mark (next real, next int) 
+  OTHERWISE errorstop (key error + text (key)) END SELECT  . 
+
+plot three dim pic:
+  WHILE read pos < pic length
+  REP plot three dim position  PER  .
+
+plot three dim position :
+  read pos INCR 1;
+  SELECT key OF
+  CASE draw key:   draw (next real, next real, next real)
+  CASE move key:   move (next real, next real, next real)
+  CASE move r key: move r (next real, next real, next real)
+  CASE draw r key: draw r (next real, next real, next real)
+  CASE text key:   draw (next text, next real, next real, next real)
+  CASE bar 2 key:  bar (next real, next real, next int) 
+  CASE bar 3 key:  bar (next real, next real, next real, next int)
+  CASE circle key: circle (next real, next real, next real, next int) 
+  CASE mark key:   mark (next real, next int) 
+  OTHERWISE errorstop (key error + text (key)) END SELECT  . 
+
+key:
+  code (points SUB read pos)  .
+
+END PROC plot;
+
+REAL PROC next real:
+  read pos INCR 8;
+  subtext (points, read pos-7, read pos) RSUB 1  .
+END PROC next real;
+
+INT PROC next int:
+  read pos INCR 2;
+  subtext (points, read pos-1, read pos) ISUB 1  .
+END PROC next int;
+
+TEXT PROC next text:
+  INT CONST text length :: next int;
+  read pos INCR text length;
+  subtext (points, read pos-text length+1, read pos)  .
+END PROC next text;
+
+PROC plot (TEXT CONST name) :
+  PICFILE VAR p :: old (name);
+  plot (p);
+END PROC plot;
+
+PROC plot (PICFILE VAR p) :
+  set projektion;
+  disable stop;
+  begin plot;
+  clear screen;
+  plot pictures (p);
+  errorcheck;
+  end plot  .
+
+set projektion:
+  ROW 3 ROW 2 REAL VAR size;
+  ROW 2 ROW 2 REAL VAR limit;
+  ROW 4 REAL VAR angles;
+  ROW 2 REAL VAR oblique;
+  ROW 3 REAL VAR perspective;
+
+  get values (p, size, limit, angles, oblique, perspective);
+  set values (size, limit, angles, oblique, perspective)  .
+
+clear screen:
+  INT VAR x0, y0, x1, y1, h max, v max;
+  REAL VAR x cm, y cm;
+
+  IF background (p) > -1
+  THEN clear
+  ELSE drawing area (x cm, y cm, h max, v max);
+       new values (x cm, y cm, h max, v max, x0, x1 , y0, y1);
+       set range (max (0, x0), max (0, y0), min (h max, x1), min (v max, y1))
+  FI  .
+
+errorcheck:
+  IF is error
+  THEN line;
+       put line ("Erorr at PICTURE No " + text (picture no (p)));
+  FI  .
+
+END PROC plot;
+
+PROC plot pictures (PICFILE VAR p):
+  INT VAR back :: abs (background (p)), no;
+  enable stop;
+  FOR no FROM 1 UPTO pictures (p)
+  REP to pic (p, no);
+      read picture (p, pic);
+
+      IF this picture is ok
+      THEN set pen of pic;
+           plot (pic)
+      FI
+  PER  .
+
+this picture is ok:
+  pen (pic) <> 0 AND length (pic) > 0  .
+
+set pen of pic:
+  INT VAR colour, thick, type;
+  selected pen (p, pen (pic), colour, thick, type);
+  set pen (back, colour, thick, type)  .
+
+END PROC plot pictures;
+
+END PACKET plot
+
diff --git a/graphic/GRAPHIK.Plotter b/graphic/GRAPHIK.Plotter
new file mode 100644
index 0000000..a55e515
--- /dev/null
+++ b/graphic/GRAPHIK.Plotter
@@ -0,0 +1,247 @@
+PACKET plotter DEFINES plotter:               (*Autor: Heiko Indenbirken *)
+                                              (*Stand:    13.10.89/22:31 *)
+                                              (*Änderung: 08.09.86/15:47 *)
+
+LET POS = STRUCT (REAL x, y, z);
+
+POS VAR pos :: POS : (0.0, 0.0, 0.0);
+INT VAR h :: 0, v :: 0;
+
+PROC move (REAL CONST x, y) :
+  transform (x, y, 0.0, h, v);
+  move (h, v);
+  pos := POS : (x, y, 0.0)
+END PROC move;
+
+PROC move (REAL CONST x, y, z) :
+  transform (x, y, z, h, v);
+  move (h, v);
+  pos := POS : (x, y, z)
+END PROC move;
+
+PROC draw (REAL CONST x, y) :
+  transform (x, y, 0.0, h, v);
+  draw (h, v);
+  pos := POS : (x, y, 0.0)
+END PROC draw;
+
+PROC draw (REAL CONST x, y, z) :
+  transform (x, y, z, h, v);
+  draw (h, v);
+  pos := POS : (x, y, z) 
+END PROC draw;
+
+PROC move r (REAL CONST x, y) :
+  transform (pos.x+x, pos.y+y, pos.z, h, v);
+  move (h, v);
+  pos := POS : (pos.x+x, pos.y+y, pos.z)
+END PROC move r;
+
+PROC move r (REAL CONST x, y, z) :
+  transform (pos.x+x, pos.y+y, pos.z+z, h, v);
+  move (h, v);
+  pos := POS : (pos.x+x, pos.y+y, pos.z+z)
+END PROC move r;
+
+PROC draw r (REAL CONST x, y) :
+  transform (pos.x+x, pos.y+y, pos.z, h, v); 
+  draw (h, v);
+  pos := POS : (pos.x+x, pos.y+y, pos.z)
+END PROC draw r;
+
+PROC draw r (REAL CONST x, y, z) :
+  transform (pos.x+x, pos.y+y, pos.z+z, h, v);
+  draw (h, v);
+  pos := POS : (pos.x+x, pos.y+y, pos.z+z)
+END PROC draw r;
+
+PROC draw (TEXT CONST msg, REAL CONST angle, height percent, width percent):
+  draw (msg, angle, height (height percent), width (width percent))  .
+END PROC draw;
+
+PROC mark (REAL CONST size, INT CONST no):
+  marker (h, v, no, diagonal (size))
+END PROC mark;
+
+PROC bar (REAL CONST width, height, INT CONST pattern):
+  INT VAR diff, up, zero x, zero y;
+  transform (0.0, 0.0, 0.0, zero x, zero y);
+  transform (width*0.5, height, 0.0, diff, up);
+  bar (h-(diff-zero x), v, h+(diff-zero x), v+(up-zero y), pattern);
+  move (h, v) 
+
+END PROC bar;
+
+PROC bar (REAL CONST from, to, height, INT CONST pattern):
+  INT VAR from h, to h, up;
+  transform (from, height, 0.0, from h, up);
+  transform (to,   height, 0.0, to h, up);
+  bar (from h, v, to h, up, pattern);
+  move (h, v) 
+
+END PROC bar;
+
+PROC circle (REAL CONST rad, from, to, INT CONST pattern):
+  circle (h, v, diagonal (rad), from, to, pattern)  .
+
+END PROC circle;
+
+
+(*                                                                       *)
+LET draw key      = 1,
+    move key      = 2,
+    text key      = 3,
+    move r key    = 4,
+    draw r key    = 5,
+    bar 2 key     = 6,
+    bar 3 key     = 7,
+    circle key    = 8,
+    mark key      = 9;
+
+LET dim error = "PICTURE not initialized",
+    key error = "wrong key code: ";
+
+TEXT VAR points;
+INT VAR pic length, pic pen, pic dim, read pos;
+PICTURE VAR pic;
+
+PROC plot (PICTURE CONST pic):
+  init plot;
+  IF pic dim = 2
+  THEN plot two dim pic
+  ELIF pic dim = 3
+  THEN plot three dim pic
+  ELIF NOT (pic dim = 0 AND pic length = 0)
+  THEN errorstop (dim error) FI;
+  points := ""  .
+
+init plot:
+  picture (pic, points, pic dim, pic pen);
+  pic length := length (points);
+  read pos := 0  .
+
+plot two dim pic:
+  WHILE read pos < pic length
+  REP plot two dim position PER  .
+
+plot two dim position :
+  read pos INCR 1;
+  SELECT key OF
+  CASE draw key:   draw (next real, next real)
+  CASE move key:   move (next real, next real)
+  CASE move r key: move r (next real, next real)
+  CASE draw r key: draw r (next real, next real)
+  CASE text key:   draw (next text, next real, next real, next real)
+  CASE bar 2 key:  bar (next real, next real, next int) 
+  CASE bar 3 key:  bar (next real, next real, next real, next int) 
+  CASE circle key: circle (next real, next real, next real, next int) 
+  CASE mark key:   mark (next real, next int) 
+  OTHERWISE errorstop (key error + text (key)) END SELECT  . 
+
+plot three dim pic:
+  WHILE read pos < pic length
+  REP plot three dim position  PER  .
+
+plot three dim position :
+  read pos INCR 1;
+  SELECT key OF
+  CASE draw key:   draw (next real, next real, next real)
+  CASE move key:   move (next real, next real, next real)
+  CASE move r key: move r (next real, next real, next real)
+  CASE draw r key: draw r (next real, next real, next real)
+  CASE text key:   draw (next text, next real, next real, next real)
+  CASE bar 2 key:  bar (next real, next real, next int) 
+  CASE bar 3 key:  bar (next real, next real, next real, next int)
+  CASE circle key: circle (next real, next real, next real, next int) 
+  CASE mark key:   mark (next real, next int) 
+  OTHERWISE errorstop (key error + text (key)) END SELECT  . 
+
+key:
+  code (points SUB read pos)  .
+
+END PROC plot;
+
+REAL PROC next real:
+  read pos INCR 8;
+  subtext (points, read pos-7, read pos) RSUB 1  .
+END PROC next real;
+
+INT PROC next int:
+  read pos INCR 2;
+  subtext (points, read pos-1, read pos) ISUB 1  .
+END PROC next int;
+
+TEXT PROC next text:
+  INT CONST text length :: next int;
+  read pos INCR text length;
+  subtext (points, read pos-text length+1, read pos)  .
+END PROC next text;
+
+PROC plotter (TEXT CONST name) :
+  PICFILE VAR p :: old (name);
+  plotter (p);
+END PROC plotter;
+
+PROC plotter (PICFILE VAR p) :
+  set projektion;
+  disable stop;
+  begin plot;
+  clear screen;
+  plot pictures (p);
+  errorcheck;
+  end plot  .
+
+set projektion:
+  ROW 3 ROW 2 REAL VAR size;
+  ROW 2 ROW 2 REAL VAR limit;
+  ROW 4 REAL VAR angles;
+  ROW 2 REAL VAR oblique;
+  ROW 3 REAL VAR perspective;
+  get values (p, size, limit, angles, oblique, perspective);
+  set values (size, limit, angles, oblique, perspective)  .
+
+clear screen:
+  INT VAR x0, y0, x1, y1, h max, v max;
+  REAL VAR x cm, y cm;
+
+  IF background (p) > -1
+  THEN clear
+  ELSE drawing area (x cm, y cm, h max, v max);
+       new values (x cm, y cm, h max, v max, x0, x1 , y0, y1);
+       set range (max (0, x0), max (0, y0), min (h max, x1), min (v max, y1))
+  FI  .
+
+errorcheck:
+  IF is error
+  THEN line;
+       put line ("Erorr at PICTURE No " + text (picture no (p)));
+  FI  .
+
+END PROC plotter;
+
+PROC plot pictures (PICFILE VAR p):
+  INT VAR back :: abs (background (p)), no;
+  enable stop;
+  FOR no FROM 1 UPTO pictures (p)
+  REP to pic (p, no);
+      read picture (p, pic);
+
+      IF this picture is ok
+      THEN set pen of pic;
+           plot (pic)
+      FI
+  PER  .
+
+this picture is ok:
+  pen (pic) <> 0 AND length (pic) > 0  .
+
+set pen of pic:
+  INT VAR colour, thick, type;
+  selected pen (p, pen (pic), colour, thick, type);
+  set pen (back, colour, thick, type)  .
+
+END PROC plot pictures;
+
+END PACKET plotter
+
+
diff --git a/graphic/GRAPHIK.Server b/graphic/GRAPHIK.Server
new file mode 100644
index 0000000..dfe5f62
--- /dev/null
+++ b/graphic/GRAPHIK.Server
@@ -0,0 +1,97 @@
+PACKET multi user plotter:                       (* Autor : Rudolf Ruland  *)
+                                                 (* Stand : 24.03.86       *)
+                                              (*Änderung: 09.09.86/15:32 *)
+ 
+INT VAR c;
+put ("gib Plotterkanal : "); get (c);
+
+  server channel (c);
+  station only (FALSE) ;
+  spool duty ("Ausgabe mit dem Plotter");
+  spool control task (myself);
+ 
+LET ack              = 0 ,
+ 
+    fetch code       = 11 ,
+    param fetch code = 21 ,
+    picfile type     = 1103 ;
+
+INT VAR reply, old heap size, sender station;
+TEXT VAR picfile name, userid, password, sendername;
+PICFILE VAR picfile ;
+
+DATASPACE VAR ds, picfile ds;
+ 
+BOUND STRUCT (TEXT picfile name, userid, password, sendername, INT station) VAR msg;
+BOUND TEXT VAR error msg ;
+ 
+spool manager (PROC plotter);
+ 
+PROC plotter :
+
+  disable stop ;
+  command dialogue (FALSE);
+  ds := nilspace; picfile ds := nilspace; 
+  continue (server channel) ;
+    check error ("Kanal belegt");
+ 
+  old heap size := heap size ;
+  REP
+    execute plot ;
+ 
+    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 plotter ;
+
+ 
+PROC execute plot :
+
+  enable stop ;
+  forget (picfile ds) ; picfile ds := nilspace ;
+  call (father, fetch code, picfile ds, reply) ;
+  IF reply = ack CAND type (picfile ds) = picfile type
+     THEN get picfile params;
+          plot picfile
+  FI ;
+ 
+. get picfile 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;
+            picfile name   := msg. picfile name;
+            userid         := msg. userid;
+            password       := msg. password;
+            sendername     := msg. sender name;
+            sender station := msg. station;
+    FI;
+ 
+. plot picfile :
+    picfile := picfile ds;
+    plotter (picfile)  .
+
+ENDPROC execute plot ;
+ 
+ 
+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 plotter ;
+
diff --git a/graphic/GRAPHIK.Transform b/graphic/GRAPHIK.Transform
new file mode 100644
index 0000000..54690cc
--- /dev/null
+++ b/graphic/GRAPHIK.Transform
@@ -0,0 +1,366 @@
+PACKET transformation DEFINES transform,      (* Autor: Heiko Indenbirken*)
+                              diagonal,       (* Stand: 12.04.85         *)
+                              height, width,  (*Änderung: 05.08.86/13:14 *)
+                              set values,     (*Änderung: 17.09.86/19:57 *)
+                              get values,
+                              new values,
+                              projektion,
+                              window,
+                              viewport,
+                              view,
+                              oblique,
+                              orthographic,
+                              perspective:
+(* *******************  Hardwareunabhängiger Teil  ********************* *)
+(*     transform:   Die Prozedur projeziert einen 3-dimensionalen Vektor *)
+(*     ----------   (x, y, z) auf einen 2-dimensionalen (h, v)           *)
+(*     diagonal     Die Prozedur berechnet die Pixel als Prozent der     *)
+(*     ----------   Diagonalen der Zeichenfläche                         *)
+(*     height       Die Prozedur berechnet die Pixel als Prozent der     *)
+(*     ----------   Höhe der Zeichenfläche                               *)
+(*     width        Die Prozedur berechnet die Pixel als Prozent der     *)
+(*     ----------   Breite der Zeichenfläche                             *)
+(*                                                                       *)
+(*     set values:  Mit dieser Prozedur werden die Projektionsparameter  *)
+(*     -----------  gesetzt.                                             *)
+(*                  size:          Weltkoordinatenbereich                *)
+(*                           ((xmin,xmax),(ymin,ymax),(zmin,zmax))       *)
+(*                  limits:  Zeichenfläche                               *)
+(*                           ((h min, h max), (v min, v max))            *)
+(*                           Bei Werten < 2.0 werden die Werte als       *)
+(*                           Prozente interpretiert, ansonsten als       *)
+(*                           cm-Grössen.                                 *)
+(*     get values:  Übergibt die aktuellen Werte                         *)
+(*     -----------                                                       *)
+(*     new values:  Berechnet die neue Projektionsmatrix                 *)
+(*     -----------                                                       *)
+(*=======================================================================*)
+
+BOOL VAR perspective projektion :: FALSE;
+INT VAR hor pixel, vert pixel, i;
+REAL VAR  hor cm, vert cm,
+          h min limit, h max limit, v min limit, v max limit;
+ROW 5 ROW 5 REAL VAR p;
+ROW 3 ROW 2 REAL VAR size;
+ROW 2 ROW 2 REAL VAR limits;
+ROW 4 REAL VAR angles;
+ROW 2 REAL VAR obliques;
+ROW 3 REAL VAR perspectives;
+
+(*                 Initialisieren der Projektionsmatrizen                *)
+INT VAR d;
+window (0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
+viewport (0.0, 0.0, 0.0, 0.0);
+view (0.0, 0.0, 1.0);
+view (0.0);
+orthographic;
+new values  (27.46, 19.21, 274, 192, d, d, d, d);
+
+PROC projektion (ROW 5 ROW 5 REAL VAR matrix):
+  matrix := p
+END PROC projektion;
+
+PROC oblique (REAL CONST a, b) :
+  set values (size, limits, angles, ROW 2 REAL : (a, b), ROW 3 REAL : (0.0, 0.0, 0.0)) 
+END PROC oblique;
+
+PROC orthographic :
+  set values (size, limits, angles, ROW 2 REAL : (0.0, 0.0), ROW 3 REAL : (0.0, 0.0, 0.0))
+END PROC orthographic;
+
+PROC perspective (REAL CONST cx, cy, cz) :
+  set values (size, limits, angles, ROW 2 REAL : (0.0, 0.0), ROW 3 REAL : (cx, cy, cz))
+END PROC perspective;
+
+PROC window (REAL CONST x min, x max, y min, y max) :
+  window (x min, x max, y min, y max, 0.0, 1.0)
+END PROC window;
+
+PROC window (REAL CONST x min, x max, y min, y max, z min, z max) :
+  set values (ROW 3 ROW 2 REAL : (ROW 2 REAL : (x min, x max),
+                                  ROW 2 REAL : (y min, y max),
+                                  ROW 2 REAL : (z min, z max)),
+              limits, angles, obliques, perspectives)
+END PROC window;
+
+PROC viewport (REAL CONST h min, h max, v min, v max) :
+  set values (size, ROW 2 ROW 2 REAL : (ROW 2 REAL : (h min, h max), 
+                                        ROW 2 REAL : (v min, v max)),
+              angles, obliques, perspectives)
+END PROC view port;
+
+PROC view (REAL CONST alpha) :
+  set values (size, limits, ROW 4 REAL : (alpha, angles(2), angles (3), angles (4)),
+              obliques, perspectives)
+END PROC view;
+
+PROC view (REAL CONST phi, theta):
+  set values (size, limits, ROW 4 REAL : (angles (1), sind (theta) * cosd (phi),
+                                          sind (theta) * sind (phi), cosd (theta)),
+              obliques, perspectives)
+END PROC view;
+
+PROC view (REAL CONST x, y, z) :
+  set values (size, limits, ROW 4 REAL : (angles (1), x, y, z), obliques, perspectives)
+END PROC view;
+
+PROC get values (ROW 3 ROW 2 REAL VAR act size, 
+                 ROW 2 ROW 2 REAL VAR act limits,
+                 ROW 4 REAL VAR act angles,
+                 ROW 2 REAL VAR act obliques,
+                 ROW 3 REAL VAR act perspectives) : 
+  act size        := size;
+  act limits      := limits;
+  act angles      := angles;
+  act obliques     := obliques;
+  act perspectives := perspectives;
+
+END PROC get values;
+
+PROC set values (ROW 3 ROW 2 REAL CONST new size, 
+                 ROW 2 ROW 2 REAL CONST new limits,
+                 ROW 4 REAL CONST new angles,
+                 ROW 2 REAL CONST new obliques,
+                 ROW 3 REAL CONST new perspectives) : 
+  size        := new size;
+  limits      := new limits;
+  angles      := new angles;
+  obliques     := new obliques;
+  perspectives := new perspectives
+
+END PROC set values;
+
+PROC new values (INT VAR h min range, h max range, v min range, v max range):
+  new values (hor cm, vert cm, hor pixel, vert pixel, 
+              h min range, h max range, v min range, v max range)
+END PROC new values;
+
+PROC new values (REAL CONST size hor, size vert,
+                 INT CONST pixel hor, pixel vert,
+                 INT VAR h min range, h max range,
+                         v min range, v max range):
+   remember screensize;
+   calc views;
+   calc projektion; 
+   calc limits;
+   calc projection frame;
+   normalize projektion;
+   set picture range;
+   set perspective mark  .
+
+remember screensize:
+  hor cm     := size hor;
+  vert cm    := size vert;
+  hor pixel  := pixel hor;
+  vert pixel := pixel vert  .
+
+calc views :
+  calc diagonale;
+  calc projektion;
+  calc angles;
+  calc normale;
+  calc matrix;
+  calc alpha angle  .
+
+calc diagonale:
+  REAL VAR diagonale := sqrt (angles [2] * angles [2] +
+                              angles [3] * angles [3] +
+                              angles [4] * angles [4])  .
+
+calc projektion:
+  REAL VAR projektion := sqrt (angles [2] * angles [2] +
+                               angles [4] * angles [4])  .
+
+calc angles:
+  REAL VAR sin p, cos p, sin t, cos t, sin a, cos a;
+
+  IF diagonale = 0.0
+  THEN sin p :=  0.0;  cos p :=  1.0;
+       sin t :=  0.0;  cos t :=  1.0
+  ELIF projektion = 0.0
+  THEN sin p :=  angles [3] / diagonale;
+       cos p :=  projektion / diagonale;
+       sin t :=  0.0;  cos t :=  1.0
+  ELSE sin p :=  angles [3] / diagonale;
+       cos p :=  projektion / diagonale;
+       sin t :=  angles [2] / projektion;
+       cos t :=  angles [4] / projektion
+  FI  .
+
+calc normale:
+  REAL VAR   sin p sin t := sin p * sin t,
+             sin p cos t := sin p * cos t,
+             cos p sin t := cos p * sin t,
+             cos p cos t := cos p * cos t,
+
+             dx          := size [1][2] - size [1][1],
+             dy          := size [2][2] - size [2][1],
+             dz          := size [3][2] - size [3][1],
+             norm az     := obliques [1] ,
+             norm bz     := obliques [2] ,
+             norm cx     := perspectives [1] / dx,
+             norm cy     := perspectives [2] / dy,
+             norm cz     := perspectives [3] / dz  .
+
+calc matrix:
+p :=  ROW 5 ROW 5 REAL :
+      (ROW 5 REAL : (  cos t       / dx - cos p sin t / dx * norm az ,
+                     - sin p sin t / dx - cos p sin t / dx * norm bz,
+                       0.0,
+                                        - cos p sin t / dx * norm cz,
+                       0.0 ),
+       ROW 5 REAL : (                   - sin p       / dy * norm az,
+                       cos p       / dy - sin p       / dy * norm bz,
+                       0.0, 
+                                        - sin p       / dy * norm cz,
+                       0.0 ),
+       ROW 5 REAL : (  sin t       / dz + cos p cos t / dz * norm az,
+                     + sin p cos t / dz + cos p cos t / dz * norm bz,
+                       0.0,
+                                        cos p cos t / dz * norm cz,
+                       0.0 ),
+       ROW 5 REAL : (- norm cx, - norm cy, 0.0, 1.0, 0.0 ),
+       ROW 5 REAL : (0.0, 0.0, 0.0, 0.0, 1.0))  .
+
+calc alpha angle:
+  IF angles (1) = 0.0
+  THEN set alpha as y vertical
+  ELSE sin a := sind (angles (1));
+       cos a := cosd (angles (1))
+  FI  .
+ 
+set alpha as y vertical :
+  REAL VAR r := sqrt (p(2)(1)**2 + p(2)(2)**2);
+  IF r = 0.0
+  THEN sin a := 0.0;
+       cos a := 1.0
+  ELSE sin a :=-p(2)(1)/r;
+       cos a := p(2)(2)/r
+  FI  .
+
+calc limits :
+  IF limits as percent
+  THEN calc percent limits
+  ELSE calc centimeter limits FI  .
+
+limits as percent:
+  limits [1][2] < 2.0 AND limits [2][2] < 2.0  .
+
+max limits:
+  h min limit := 0.0;
+
+  v min limit := 0.0;
+  v max limit := real (pixel vert)  .
+
+calc percent limits:
+  h min limit := real (pixel hor) * limits (1)(1)*size vert / size hor;
+  v min limit := limits (2)(1) * real (pixel vert);
+
+  IF limits [1][2] = 0.0
+  THEN h max limit := real (pixel hor)
+  ELSE h max limit := real (pixel hor) * limits [1][2]*size vert / size hor FI;
+
+  IF limits [2][2] = 0.0
+  THEN v max limit := real (pixel vert)
+  ELSE v max limit := limits (2)(2) * real (pixel vert)  FI  .
+
+calc centimeter limits:
+  h min limit := real (pixel hor) * (limits (1)(1)/size hor);
+  v min limit := real (pixel vert) * (limits (2)(1)/size vert);
+
+  IF limits [1][2] = 0.0
+  THEN h max limit := real (pixel hor)
+  ELSE h max limit := real (pixel hor) * (limits (1)(2)/size hor) FI;
+ 
+  IF limits [2][2] = 0.0
+  THEN v max limit := real (pixel vert)
+  ELSE v max limit := real (pixel vert) * (limits (2)(2)/size vert) FI  .
+
+calc projection frame:
+  REAL VAR h min := max real,  h max :=-max real,
+           v min := max real,  v max :=-max real;
+ 
+  extrema (size [1][1], size [2][1], size [3][1], h min, h max, v min, v max); 
+  extrema (size [1][2], size [2][1], size [3][1], h min, h max, v min, v max);
+  extrema (size [1][2], size [2][2], size [3][1], h min, h max, v min, v max); 
+  extrema (size [1][1], size [2][2], size [3][1], h min, h max, v min, v max);
+  extrema (size [1][1], size [2][1], size [3][2], h min, h max, v min, v max); 
+  extrema (size [1][2], size [2][1], size [3][2], h min, h max, v min, v max);
+  extrema (size [1][2], size [2][2], size [3][2], h min, h max, v min, v max); 
+  extrema (size [1][1], size [2][2], size [3][2], h min, h max, v min, v max)  .
+
+normalize projektion :
+  REAL VAR sh := (h max limit - h min limit) / (h max - h min),
+           sv := (v max limit - v min limit) / (v max - v min),
+           dh := h min limit - h min*sh,
+           dv := v min limit - v min*sv;
+
+  FOR i FROM 1 UPTO 5
+  REP REAL CONST p  i 1 := p (i)(1);
+      p (i)(1) :=  (p  i  1  * cos a - p (i)(2) * sin a) * sh;
+      p (i)(2) :=  (p  i  1  * sin a + p (i)(2) * cos a) * sv
+  PER;
+  p (5)(1) := dh;
+  p (5)(2) := dv  .
+
+set picture range:
+  h min range := int (h min limit-0.5);
+  h max range := int (h max limit+0.5);
+  v min range := int (v min limit-0.5);
+  v max range := int (v max limit+0.5)  .
+
+set perspective mark:
+  perspective projektion := perspectives [3] <> 0.0  .
+
+END PROC new values;
+ 
+PROC transform (REAL CONST x, y, z, INT VAR h, v) :
+  IF perspective projektion
+  THEN REAL CONST w :: 1.0/(x*p (1)(4) + y*p (2)(4) + z*p (3)(4) + 1.0);
+       h := int ((x*p (1)(1)+y*p (2)(1)+z*p (3)(1) + p (4)(1))*w + p (5)(1));
+       v := int ((x*p (1)(2)+y*p (2)(2)+z*p (3)(2) + p (4)(2))*w + p (5)(2))
+  ELSE h := int (x*p (1)(1)+y*p (2)(1)+z*p (3)(1) + p (5)(1));
+       v := int (x*p (1)(2)+y*p (2)(2)+z*p (3)(2) + p (5)(2));
+  FI;
+END PROC transform;
+
+PROC extrema (REAL CONST x, y, z, REAL VAR h min, h max, v min, v max):
+  REAL VAR h, v;
+  IF perspective projektion
+  THEN REAL CONST w :: 1.0/(x*p (1)(4) + y*p (2)(4) + z*p (3)(4) + 1.0);
+       h := (x*p (1)(1)+y*p (2)(1)+z*p (3)(1) +p (4)(1))*w;
+       v := (x*p (1)(2)+y*p (2)(2)+z*p (3)(2) +p (4)(2))*w
+  ELSE h := (x*p (1)(1)+y*p (2)(1)+z*p (3)(1));
+       v := (x*p (1)(2)+y*p (2)(2)+z*p (3)(2))
+  FI;
+ 
+ IF h < h min
+ THEN h min := h
+ ELIF h > h max
+ THEN h max := h FI;
+
+ IF v < v min
+ THEN v min := v
+ ELIF v > v max
+ THEN v max := v FI
+
+END PROC extrema;
+
+INT PROC diagonal (REAL CONST percent):
+  int (percent * 0.01 * diagonale + 0.5)  .
+
+diagonale:
+  sqrt ((h max limit-h min limit) ** 2 + (v max limit-v min limit) ** 2) .
+
+END PROC diagonal;
+
+INT PROC height (REAL CONST percent):
+  int (percent * 0.01 * (v max limit-v min limit) + 0.5)
+END PROC height;
+
+INT PROC width (REAL CONST percent):
+  int (percent * 0.01 * (h max limit-h min limit) + 0.5)
+END PROC width;
+
+END PACKET transformation
+
diff --git a/graphic/GRAPHIK.vektor plot b/graphic/GRAPHIK.vektor plot
new file mode 100644
index 0000000..8bef1e4
--- /dev/null
+++ b/graphic/GRAPHIK.vektor plot	
@@ -0,0 +1,506 @@
+PACKET clipping DEFINES set range,            (*Autor: Heiko Indenbirken *)
+                        get range,            (*Stand:    27.06.85/12:39 *)
+                        clip:                 (*Änderung: 11.08.86/15:02 *)
+
+INT VAR x min :: 0, x max :: 1024, y min :: 0, y max :: 1024;
+
+PROC set range (INT CONST h min, v min, h max, v max):
+  IF h min >= h max OR v min >= v max
+  THEN errorstop ("Incorrect Range") FI;
+  x min := h min;  x max := h max;
+  y min := v min;  y max := v max
+END PROC set range;
+
+PROC get range (INT VAR h min, v min, h max, v max):
+  h min := x min;  h max := x max;
+  v min := y min;  v max := y max
+END PROC get range;
+
+PROC clip (INT CONST from x, from y, to x, to y,
+           PROC (INT CONST, INT CONST) move,
+           PROC (INT CONST, INT CONST) draw):
+  INT VAR x, y;
+  calculate parts of line;
+  IF both points inside
+  THEN draw (to x, to y)
+  ELIF both points outside
+  THEN 
+  ELIF first point outside
+  THEN intersection (to x, to y, from x, from y, from part, x, y);
+       move (x, y);
+       draw (x, y);                                    (* Macke im SHARD *)
+       draw (to x, to y)
+  ELIF second point outside
+  THEN intersection (from x, from y, to x, to y, to part, x, y);
+       draw (x, y)
+  ELSE intersection (to x, to y, from x, from y, from part, x, y);
+       move (x, y);
+       draw (x, y);                                    (* Macke im SHARD *)
+       clip (x, y, to x, to y,  PROC (INT CONST, INT CONST) move,
+                                PROC (INT CONST, INT CONST) draw)
+  FI  .
+
+calculate parts of line:
+  INT CONST from part :: part (from x, from y),
+            to part   :: part (to x, to y)  .
+
+both points inside:
+  from part = 0 AND to part = 0  .
+
+both points outside:
+  (from part AND to part) <> 0  .
+
+first point outside:
+  from part <> 0 AND to part = 0  .
+
+second point outside:
+  to part <> 0 AND from part = 0  .
+
+END PROC clip;
+
+INT PROC part (INT CONST x, y):
+  INT VAR index :: 0;
+  IF x > x max
+  THEN set bit (index, 0)
+  ELIF x < x min
+  THEN set bit (index, 1) FI;
+
+  IF y > y max
+  THEN set bit (index, 2)
+  ELIF y < y min
+  THEN set bit (index, 3) FI;
+
+  index
+
+END PROC part;
+
+PROC intersection (INT CONST from x, from y, to x, to y, to part, INT VAR x, y):
+  SELECT to part OF
+  CASE  1: right side
+  CASE  2: left side 
+  CASE  4: up side 
+  CASE  5: upright side 
+  CASE  6: upleft side 
+  CASE  8: down side 
+  CASE  9: downright side 
+  CASE 10: downleft side
+  OTHERWISE errorstop ("wrong partno.:" + text (to part)) ENDSELECT  .
+
+right side:
+  y := from y + int (real (x max-from x)*(dy/dx));
+  x := x max  .
+
+left side:
+  y := from y + int (real (x min-from x)*(dy/dx));
+  x := x min  .
+
+up side:
+  x := from x + int (real (y max-from y)*(dx/dy));
+  y := y max  .
+
+down side:
+  x := from x + int (real (y min-from y)*(dx/dy));
+  y := y min  .
+
+upright side:
+  right side;
+  IF y > y max
+  THEN up side FI  .
+
+downright side:
+  right side;
+  IF y < y min
+  THEN down side FI  . 
+
+upleft side:
+  left side;
+  IF y > y max
+  THEN up side FI  .
+
+downleft side:
+  left side;
+  IF y < y min
+  THEN down side FI  .
+
+dx: real (to x-from x)  .
+dy: real (to y-from y)  .
+
+END PROC intersection;
+
+END PACKET clipping;
+
+PACKET thick line DEFINES thick:              (*Autor: Heiko Indenbirken *)
+                                              (*Stand:    02.07.85/15:07 *)
+                                              (*Änderung: 05.08.86/15:52 *)
+PROC thick (INT CONST x0, y0, x1, y1, thick,
+            PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  IF is point
+  THEN draw point
+  ELIF is horizontal line 
+  THEN horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+                        x0, y0, x1, y1, thick)
+  ELSE vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+                      x0, y0, x1, y1, thick)
+  FI  .
+
+is point:
+  x0 = x1 AND y0 = y1  .
+
+is horizontal line:
+  abs (x0-x1) >= abs (y0-y1)  .
+
+draw point:
+  INT VAR i;
+  FOR i FROM -thick UPTO thick
+  REP line (x0-thick, y0+i, x0+thick, y0+i) PER  .
+
+END PROC thick;
+
+PROC horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+                      INT CONST from x, from y, to x, to y, thick):
+  IF from x > to x
+  THEN horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line, 
+                        to x, to y, from x, from y, thick)
+  ELSE draw line FI  .
+
+draw line:
+  INT VAR i;
+  calculate increase;
+  calculate limit points;
+  FOR i FROM -thick UPTO thick
+  REP calculate delta x;
+      line (x start+delta x, y start+i, x end+delta x, y end+i)
+  PER  .
+
+calculate increase:
+  REAL VAR increase :: -dy / dx  .
+
+calculate limit points:
+  INT CONST x start :: from x - thick,
+            x end   :: to x   + thick,
+            y start :: from y + int (increase * real (thick)), 
+            y end   :: to y   - int (increase * real (thick))  .
+
+calculate delta x:
+  INT CONST delta x :: int (increase*real (i))  .
+
+dx: real (to x-from x)  .
+dy: real (to y-from y)  .
+
+END PROC horizontal line;
+
+PROC vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+                    INT CONST from x, from y, to x, to y, thick):
+  IF from y > to y
+  THEN vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+                      to x, to y, from x, from y, thick)
+  ELSE draw line FI  .
+
+draw line:
+  INT VAR i;
+  calculate increase;
+  calculate limit points;
+  FOR i FROM -thick UPTO thick
+  REP calculate delta y;
+      line (x start+i, y start+delta y, x end+i, y end+delta y)
+  PER  .
+
+calculate increase:
+  REAL VAR increase :: -dx / dy  .
+
+calculate limit points:
+  INT CONST x start :: from x + int (increase * real (thick)), 
+            x end   :: to x   - int (increase * real (thick)),
+            y start :: from y - thick,
+            y end   :: to y   + thick  .
+
+calculate delta y:
+  INT CONST delta y :: int (increase*real (i))  .
+
+dx: real (to x-from x)  .
+dy: real (to y-from y)  .
+
+END PROC vertical line;
+
+END PACKET thick line;
+
+PACKET graphik text DEFINES draw char,        (*Autor: Heiko Indenbirken *)
+                            zeichensatz:      (*Stand:    27.06.85/16:03 *)
+                                              (*Änderung: 28.06.85/19:06 *)
+                                              (*Änderung: 05.08.86/16:00 *)
+LET ZEICHENSATZ = ROW 255 TEXT;
+ZEICHENSATZ VAR zeichen;
+INT CONST char x :: 6, char y :: 10;
+
+zeichensatz ("ZEICHENSATZ");
+
+PROC zeichensatz (TEXT CONST name):
+  IF exists (name)
+  THEN BOUND ZEICHENSATZ VAR new zeichen :: old (name);
+       zeichen := new zeichen;
+  ELSE errorstop ("Der Zeichensatz """ + name + """ existiert nicht") FI
+END PROC zeichensatz;
+
+PROC draw char (INT CONST char no, INT CONST x, y, x size, y size, direction,
+                PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  TEXT CONST character :: zeichen [char no];
+  INT VAR n :: 1, x0, y0, x1, y1;
+  INT CONST len :: length (character);
+  WHILE n < len
+  REP value (character, n, x0, y0, x1, y1);
+      transform (x0, y0, x, y, x size, y size, direction);
+      transform (x1, y1, x, y, x size, y size, direction); 
+      line (x0, y0, x1, y1);
+      n INCR 4
+  PER  .
+
+END PROC draw char;
+
+PROC value (TEXT CONST char, INT CONST n, INT VAR x0, y0, x1, y1):
+  x0 := val (code (char SUB n));    y0 := val (code (char SUB n+1));
+  x1 := val (code (char SUB n+2));  y1 := val (code (char SUB n+3));
+END PROC value;
+
+INT PROC val (INT CONST n):
+  IF n > 127
+  THEN -256 OR n
+  ELSE n FI
+END PROC val;
+
+PROC transform (INT VAR x, y, INT CONST x0, y0, x size, y size, direction):
+  INT CONST old x :: x, old y :: y;
+  SELECT direction OF
+  CASE 0: x := x0 + x vektor;  y := y0 + y vektor
+  CASE 1: x := x0 - y vektor;  y := y0 + x vektor
+  CASE 2: x := x0 - x vektor;  y := y0 - y vektor
+  CASE 3: x := x0 + y vektor;  y := y0 - x vektor
+  ENDSELECT  .
+
+x vektor:
+  IF x size = 0
+  THEN old x
+  ELSE (old x*x size) DIV char x FI  .
+
+y vektor:
+  IF y size = 0
+  THEN old y
+  ELSE (old y*y size) DIV char y FI  .
+
+END PROC transform;
+
+END PACKET graphik text;
+
+PACKET graphik text DEFINES draw text:        (*Autor: Heiko Indenbirken *)
+                                              (*Stand:    03.07.85/11:55 *)
+                                              (*Änderung: 05.08.86/16:04 *)
+PROC draw text (INT CONST x pos, y pos,
+                TEXT CONST msg, REAL CONST angle, INT CONST height, width,
+                PROC (INT CONST, INT CONST,
+                INT CONST, INT CONST, INT CONST, INT CONST) draw char):
+  INT CONST dir :: int (((angle MOD 360.0)+45.0) / 90.0);
+  INT VAR i;
+  REAL VAR x :: real (x pos), y :: real (y pos),
+           x step :: cosd (angle)*real (width),
+           y step :: sind (angle)*real (width);
+  FOR i FROM 1 UPTO length (msg)
+  REP IF control char
+      THEN execute control char
+      ELSE execute normal char FI
+  PER  .
+
+control char:
+  akt char < ""32""  .
+
+execute control char:
+  SELECT code (akt char) OF
+  CASE  1: home
+  CASE  2: right
+  CASE  3: up
+  CASE  7: out (""7"")
+  CASE  8: left
+  CASE 10: down
+  CASE 13: return
+  ENDSELECT  .
+
+home:
+  x := real (x pos);
+  y := real (y pos)  .
+
+right:
+  x INCR x step;  y INCR y step  . 
+
+up:
+  x INCR y step;  y INCR x step  . 
+
+left:
+  x DECR x step;  y DECR y step  .
+
+down:
+  x DECR y step;  y DECR x step  . 
+
+return:
+  x := real (x pos)  .
+
+execute normal char:
+  draw char (code (akt char), dir, int (x+0.5), int (y+0.5), height, width);
+  x INCR x step;
+  y INCR y step  .
+
+akt char:
+  msg SUB i  .
+
+END PROC draw text;
+
+END PACKET graphik text;
+
+PACKET comercial plot DEFINES bar,            (*Autor: Heiko Indenbirken *)
+                              circle:         (*Stand:    03.04.1985     *)
+                                              (*Änderung: 03.07.85/15:37 *)
+PROC bar (INT CONST from x, from y, to x, to y, pattern,
+          PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  IF from x > to x
+  THEN bar (to x, from y, from x, to y, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  ELIF from y > to y
+  THEN bar (from x, to y, to x, from y, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  ELSE draw frame;
+       fill frame with pattern
+  FI  .
+
+draw frame:
+  line (from x, from y, from x, to y);
+  line (from x, to y, to x, to y);
+  line (to x, to y, to x, from y);
+  line (to x, from y, from x, from y)  .
+
+fill frame with pattern:
+  SELECT pattern OF
+  CASE 1: fill right (from x, to x, from y, to y, 2, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 2: fill hor   (from x, to x, from y, to y, 1, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 3: fill hor   (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 4: fill vert  (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 5: fill hor   (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line);
+          fill vert  (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 6: fill right (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 7: fill left  (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 8: fill right (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line);
+          fill left  (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  ENDSELECT  .
+
+END PROC bar;
+
+PROC fill hor (INT CONST from x, to x, from y, to y, step,
+               PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  INT VAR y :: from y;
+  REP line (from x, y, to x, y);
+      y INCR step
+  UNTIL y > to y PER  .
+
+END PROC fill hor;
+
+PROC fill vert (INT CONST from x, to x, from y, to y, step,
+                PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  INT VAR x :: from x;
+  REP line (x, from y, x, to y);
+      x INCR step
+  UNTIL x > to x PER  .
+
+END PROC fill vert;
+
+PROC fill right (INT CONST from x, to x, from y, to y, step,
+                 PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  INT CONST width  :: to x - from x,
+            height :: to y - from y,
+            length :: width + height,
+            height step :: height + step,
+            width step  :: width + step;
+
+  INT VAR t :: step, left  :: from x, right :: from x,
+                     lower :: from y, upper :: from y;
+(*               Ausfüllen von links unten nach rechts oben              *)
+  WHILE t < length
+  REP calc start point;
+      calc end point;
+      line (left, upper, right, lower);
+      t INCR step
+  PER  .
+
+calc start point:
+  IF t < height
+  THEN upper INCR step
+  ELIF t < height step
+  THEN left  := from x + t - height;
+       upper := to y
+  ELSE left INCR step FI  .
+
+calc end point:
+  IF t < width
+  THEN right INCR step
+  ELIF t < width step
+  THEN lower := from y + t - width;
+       right := to x
+  ELSE lower INCR step FI  .
+
+END PROC fill right;
+
+PROC fill left (INT CONST from x, to x, from y, to y, step,
+                PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  INT CONST width  :: to x - from x,
+            height :: to y - from y,
+            length :: width + height,
+            height step :: height + step,
+            width step  :: width + step;
+
+  INT VAR t :: step, left  :: to x,   right :: to x,
+                     lower :: from y, upper :: from y;
+(*               Ausfüllen von rechts unten nach links oben              *)
+  WHILE t < length
+  REP calc start point;
+      calc end point;
+      line (right, upper, left, lower);
+      t INCR step
+  PER  .
+
+calc start point:
+  IF t < height
+  THEN upper INCR step
+  ELIF t < height step
+  THEN right := to x - t + height;
+       upper := to y
+  ELSE right DECR step FI  .
+
+calc end point:
+  IF t < width
+  THEN left DECR step
+  ELIF t < width step
+  THEN lower := from y + t - width;
+       left  := from x
+  ELSE lower INCR step FI  .
+
+END PROC fill left;
+
+PROC circle (INT CONST x, y, REAL CONST rad, from, to, INT CONST pattern,
+             PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  REAL VAR t :: from;
+  INT VAR last x :: x, last y :: y;
+  WHILE t <= to
+  REP calc circle;
+      draw step;
+      t INCR 1.0
+  PER;
+  line (x rad, y rad, x, y)  .
+
+draw step:
+  IF pattern = 0
+  THEN line (last x, last y, x rad, y rad);
+       last x := x rad;
+       last y := y rad
+  ELSE line (x, y, x rad, y rad) FI  .
+
+calc circle:
+  INT CONST x rad :: int (cosd (t)*rad+0.5)+x,
+            y rad :: int (sind (t)*rad+0.5)+y  .
+
+END PROC circle;
+
+END PACKET comercial plot;
+
diff --git a/graphic/HP7475.plot b/graphic/HP7475.plot
new file mode 100644
index 0000000..860dd03
--- /dev/null
+++ b/graphic/HP7475.plot
@@ -0,0 +1,254 @@
+PACKET hp7475 plot DEFINES set range,         (*Autor: Heiko Indenbirken *)
+                           get range,         (*Stand:    03.09.86/15:09 *)
+                           drawing area,
+                           begin plot,
+                           end plot,
+                           clear,
+
+                           set pen, get pen, 
+                           move, 
+                           draw,
+                           marker,
+                           bar, circle,
+                           where:
+
+(*                                                                       *)
+(*                     Hardware Anschluß des HP7475A:                    *)
+(*                  9600 Baud, 8 Bit, no parity, RTS/CTS                 *)
+(*   Leitungen                  1  -----  1                              *)
+(*   gekreuzt:                  2  --x--  3                              *)
+(*                              3  --x--  2                              *)
+(*                                                                       *)
+
+
+LET POS = STRUCT (INT x, y);
+LET RANGE = STRUCT (POS min, max);
+LET PEN = STRUCT (INT back, fore, thick, line);
+
+LET width scale  = 0.002690217391304,
+    height scale = 0.002728921124206;
+
+LET term  = ";",
+    comma = ",",
+    point = ".",
+    zero  = "0",
+    nil   = "",
+    etx   = ""3"";
+
+ 
+POS VAR old :: POS:(0, 0);
+RANGE VAR area :: RANGE:(POS:(0,0), POS:(11040, 7721));
+PEN VAR pen :: PEN : (0, 1, 0, 1);
+TEXT VAR result;
+
+ROW 16 TEXT VAR mark := ROW 16 TEXT:
+("99,0,2,-2,0,0,-4,4,0,0,4,-2,0;",
+"99,0,2,-1,0,-1,-1,0,-2,1,-1,2,0,1,1,0,2,-1,1,-1,0;",
+"99,0,2,-2,-3,4,0,-2,3;",
+"-99,-2,0,99,4,0,-99,-2,2,99,0,-4;",
+"-99,-2,-2,99,4,4,-99,-4,0,99,4,-4;",
+"99,0,2,-2,-2,2,-2,2,2,-2,2;",
+"-99,0,-2,99,0,4,-2,-2,4,0,-2,2;",
+"-99,-2,0,99,4,0,-99,-2,2,99,0,-4,2,2,-2,2,-2,-2,2,-2;",
+"-99,-2,-2,99,4,4,-4,0,4,-4;",
+"-99,-2,2,99,4,0,-4,-4,4,0;",
+"99,0,-2,-99,-2,4,99,2,-2,2,2;",
+"99,1,1,-2,0,0,-2,2,0,0,2,1,1,-99,-4,0,99,1,-1,-99,0,-2,99,-1,-1,-99,4,0,99,-1,1;",
+"-99,-2,0,99,4,0,-99,-1,1,99,-2,-2,-99,1,-1,99,0,4,-99,-1,-1,99,2,-2;",
+"-99,-2,2,99,4,0,-4,-4,4,0,-4,4;",
+"-99,-2,0,99,4,0;",
+"-99,0,299,0,-4;");
+
+ROW 5 TEXT CONST line pattern := ROW 5 TEXT:("LT;", "LT1;", "LT2;", "LT3;", "LT4;");
+ROW 8 TEXT CONST fill pattern := ROW 8 TEXT:("FT4,25,45;", "FT1,0,0;", "FT3,50,0;",
+                                 "FT3,50,90;", "FT4,50,0;", "FT3,50,-45;",
+                                 "FT3,50,45;", "FT4,50,45;");
+
+PROC drawing area (REAL VAR x cm, y cm, INT VAR x pixel, y pixel) :
+   x cm    := 29.7;    y cm    := 21.07; 
+   x pixel := 11040;    y pixel :=  7721;
+END PROC drawing area;
+
+
+PROC set range (INT CONST h min, v min, h max, v max):
+  IF h min >= h max OR v min >= v max
+  THEN errorstop ("Incorrect Range") FI;
+  area := RANGE:(POS:(h min, v min), POS:(h max, v max))
+END PROC set range;
+
+PROC get range (INT VAR h min, v min, h max, v max):
+  h min := area.min.x;   v min := area.min.y;
+  h max := area.max.x;   v max := area.max.y
+END PROC get range;
+
+PROC begin plot: 
+  out ("IN;")
+ENDPROC begin plot;
+
+PROC end plot: 
+  TEXT VAR rec;
+  out ("IN;SP;PA22040,7721;DP;");
+  REP pause (10);
+      out ("OS;");
+      input (rec, ""13"", 600)
+  UNTIL enter pressed PER;
+  out ("IN;")  .
+
+enter pressed:
+  (int (rec) AND 4) > 0  .
+
+ENDPROC end plot;
+
+PROC clear:
+  new values (29.7, 21.07, 11040, 7721, area.min.x, area.max.x, area.min.y, area.max.y);
+  pen := PEN : (0, 1, 0, 1); 
+  old := area.min;
+  out ("DF;IP;");                                     (* Default     *)
+  out ("IW" + text (area.min.x, area.min.y) + ", " +  (* Clipping    *)
+               text (area.max.x, area.max.y) + term);
+  out ("SP1;");                                       (* Pen 1       *)
+  out ("LT;");                                        (* durchgehend *)
+  out ("PU;PA" + text (old.x, old.y));                (*  Startpunkt *)
+
+END PROC clear;
+
+PROC set pen (INT CONST back, fore, thick, type):
+  set colour;
+  set linetype  .
+
+set colour:
+  IF abs (fore) >= 1 AND abs (fore) <= 6
+  THEN out ("SP" + text (abs (fore)) + term);
+       pen.fore := abs (fore);
+  FI  .
+
+set linetype:
+  IF type >= 1 AND type <= 5
+  THEN out (line pattern [type]);
+       pen.line := type
+  ELSE out ("SP;");
+       pen.line := 0
+  FI  .
+
+END PROC set pen;
+
+PROC get pen (INT VAR back, fore, thick, line):
+  back  := pen.back;
+  fore  := pen.fore;
+  thick := pen.thick;
+  line  := pen.line
+END PROC get pen;
+
+PROC move (INT CONST x, y) :
+  out ("PU;PA" + text (x, y) + term);
+  old := POS : (x, y) 
+END PROC move;
+ 
+PROC draw (INT CONST x, y):
+  out ("PD;PA" + text (x, y) + term);
+  old := POS : (x, y)
+END PROC draw;
+
+PROC draw (TEXT CONST msg, REAL CONST angle, INT CONST height, width):
+  set angle;
+  set height and width;
+  plot msg  .
+
+set angle:
+  out ("DI " + text (cosd (angle), sind (angle)) + term)  .
+
+set height and width:
+  IF width = 0 AND height = 0
+  THEN out ("SR;")
+  ELSE out ("SI" + text (real (width) * width scale,
+                             real (height) * height scale) + term)
+  FI  .
+
+plot msg:
+  out ("LB" + msg + etx)  .
+
+END PROC draw;
+
+PROC bar (INT CONST from x, from y, to x, to y, pattern):
+  out ("PU;PA" + text (from x, from y) + term);
+  out ("LT;EA" + text (to x, to y) + term);
+  IF pattern > 0 AND pattern <= 8
+  THEN out (fill pattern [pattern]);
+       out ("RA" + text (to x, to y) + term);
+  FI;
+  out ("PU;PA" + text (old.x, old.y) + term);
+  out (line pattern [pen.line])  .
+
+END PROC bar;
+
+PROC circle (INT CONST x, y, rad, REAL CONST from, to, INT CONST pattern):
+  out ("LT;PU;PA" + text (x, y) + term);
+  IF (from MOD 360.0) = 0.0 AND (to MOD 360.0) = 0.0
+  THEN out ("CI" + text (rad) + term)
+  ELSE out ("EW" + text (rad) + comma + text (from, to-from) + term) FI;
+
+  IF pattern > 0 AND pattern <= 6
+  THEN out (fill pattern [pattern]);
+       out ("WG" + text (rad) + comma + text (from, to-from) + term)
+  FI;
+  out ("PU;PA" + text (old.x, old.y) + term);
+  out (line pattern [pen.line])  .
+
+END PROC circle;
+
+PROC marker (INT CONST x, y, no, size):
+  out ("LT;PU;PA" + text (x, y) + term);
+  out ("DI1,0;");
+  IF size = 0
+  THEN out ("SI0.25,0.5;")
+  ELSE out ("SI" + text (real (size)*0.001, real (size)*0.002) + term) FI;
+  out ("UC" + mark [mark no]);
+  out ("PU;PA" + text (old.x, old.y) + term);
+  out (line pattern [pen.line])  .
+
+mark no:
+  IF no >= 1 AND no <= 16
+  THEN no
+  ELSE 1 FI  .
+
+END PROC marker;
+
+PROC where (INT VAR x, y):
+  x := old.x;  y := old.y
+END PROC where;
+
+TEXT PROC text (INT CONST x, y):
+  text (x) + comma + text (y)
+END PROC text;
+
+TEXT PROC text (REAL CONST x, y):
+  text (x) + comma + text (y)
+END PROC text;
+
+TEXT PROC text (REAL CONST x):
+  result := compress (text (x, 9, 4));
+
+  IF (result SUB 1) = point
+  THEN insert char (result, zero, 1)
+  ELIF (result SUB LENGTH result) = point
+  THEN result CAT zero FI;
+  result
+END PROC text;
+
+PROC input (TEXT VAR rec, TEXT CONST del, INT CONST time):
+  enable stop;
+  rec := nil;
+  REP TEXT CONST char := incharety (time);
+
+      IF char = nil
+      THEN errorstop ("Timeout after " + text (time))
+      ELIF pos (del, char) > 0
+      THEN LEAVE input
+      ELSE rec CAT char FI
+
+  PER  .
+
+END PROC input;
+
+END PACKET hp7475 plot
+
diff --git a/graphic/PC.plot b/graphic/PC.plot
new file mode 100644
index 0000000..712f5ea
--- /dev/null
+++ b/graphic/PC.plot
@@ -0,0 +1,758 @@
+PACKET clipping DEFINES set range,            (*Autor: Heiko Indenbirken *)
+                        get range,            (*Stand:    27.06.85/12:39 *)
+                        clip:                 (*Änderung: 11.08.86/15:02 *)
+
+INT VAR x min :: 0, x max :: 1024, y min :: 0, y max :: 1024;
+
+PROC set range (INT CONST h min, v min, h max, v max):
+  IF h min >= h max OR v min >= v max
+  THEN errorstop ("Incorrect Range") FI;
+  x min := h min;  x max := h max;
+  y min := v min;  y max := v max
+END PROC set range;
+
+PROC get range (INT VAR h min, v min, h max, v max):
+  h min := x min;  h max := x max;
+  v min := y min;  v max := y max
+END PROC get range;
+
+PROC clip (INT CONST from x, from y, to x, to y,
+           PROC (INT CONST, INT CONST) move,
+           PROC (INT CONST, INT CONST) draw):
+  INT VAR x, y;
+  calculate parts of line;
+  IF both points inside
+  THEN draw (from x, from y);                          (* Macke im SHARD *)
+       draw (to x, to y)
+  ELIF both points outside
+  THEN 
+  ELIF first point outside
+  THEN intersection (to x, to y, from x, from y, from part, x, y);
+       move (x, y);
+       draw (x, y);                                    (* Macke im SHARD *)
+       draw (to x, to y)
+  ELIF second point outside
+  THEN intersection (from x, from y, to x, to y, to part, x, y);
+       draw (x, y)
+  ELSE intersection (to x, to y, from x, from y, from part, x, y);
+       move (x, y);
+       draw (x, y);                                    (* Macke im SHARD *)
+       clip (x, y, to x, to y,  PROC (INT CONST, INT CONST) move,
+                                PROC (INT CONST, INT CONST) draw)
+  FI  .
+
+calculate parts of line:
+  INT CONST from part :: part (from x, from y),
+            to part   :: part (to x, to y)  .
+
+both points inside:
+  from part = 0 AND to part = 0  .
+
+both points outside:
+  (from part AND to part) <> 0  .
+
+first point outside:
+  from part <> 0 AND to part = 0  .
+
+second point outside:
+  to part <> 0 AND from part = 0  .
+
+END PROC clip;
+
+INT PROC part (INT CONST x, y):
+  INT VAR index :: 0;
+  IF x > x max
+  THEN set bit (index, 0)
+  ELIF x < x min
+  THEN set bit (index, 1) FI;
+
+  IF y > y max
+  THEN set bit (index, 2)
+  ELIF y < y min
+  THEN set bit (index, 3) FI;
+
+  index
+
+END PROC part;
+
+PROC intersection (INT CONST from x, from y, to x, to y, to part, INT VAR x, y):
+  SELECT to part OF
+  CASE  1: right side
+  CASE  2: left side 
+  CASE  4: up side 
+  CASE  5: upright side 
+  CASE  6: upleft side 
+  CASE  8: down side 
+  CASE  9: downright side 
+  CASE 10: downleft side
+  OTHERWISE errorstop ("wrong partno.:" + text (to part)) ENDSELECT  .
+
+right side:
+  y := from y + int (real (x max-from x)*(dy/dx));
+  x := x max  .
+
+left side:
+  y := from y + int (real (x min-from x)*(dy/dx));
+  x := x min  .
+
+up side:
+  x := from x + int (real (y max-from y)*(dx/dy));
+  y := y max  .
+
+down side:
+  x := from x + int (real (y min-from y)*(dx/dy));
+  y := y min  .
+
+upright side:
+  right side;
+  IF y > y max
+  THEN up side FI  .
+
+downright side:
+  right side;
+  IF y < y min
+  THEN down side FI  . 
+
+upleft side:
+  left side;
+  IF y > y max
+  THEN up side FI  .
+
+downleft side:
+  left side;
+  IF y < y min
+  THEN down side FI  .
+
+dx: real (to x-from x)  .
+dy: real (to y-from y)  .
+
+END PROC intersection;
+
+END PACKET clipping;
+
+PACKET thick line DEFINES thick:              (*Autor: Heiko Indenbirken *)
+                                              (*Stand:    02.07.85/15:07 *)
+                                              (*Änderung: 05.08.86/15:52 *)
+PROC thick (INT CONST x0, y0, x1, y1, thick,
+            PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  IF is point
+  THEN draw point
+  ELIF is horizontal line 
+  THEN horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+                        x0, y0, x1, y1, thick)
+  ELSE vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+                      x0, y0, x1, y1, thick)
+  FI  .
+
+is point:
+  x0 = x1 AND y0 = y1  .
+
+is horizontal line:
+  abs (x0-x1) >= abs (y0-y1)  .
+
+draw point:
+  INT VAR i;
+  FOR i FROM -thick UPTO thick
+  REP line (x0-thick, y0+i, x0+thick, y0+i) PER  .
+
+END PROC thick;
+
+PROC horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+                      INT CONST from x, from y, to x, to y, thick):
+  IF from x > to x
+  THEN horizontal line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line, 
+                        to x, to y, from x, from y, thick)
+  ELSE draw line FI  .
+
+draw line:
+  INT VAR i;
+  calculate increase;
+  calculate limit points;
+  FOR i FROM -thick UPTO thick
+  REP calculate delta x;
+      line (x start+delta x, y start+i, x end+delta x, y end+i)
+  PER  .
+
+calculate increase:
+  REAL VAR increase :: -dy / dx  .
+
+calculate limit points:
+  INT CONST x start :: from x - thick,
+            x end   :: to x   + thick,
+            y start :: from y + int (increase * real (thick)), 
+            y end   :: to y   - int (increase * real (thick))  .
+
+calculate delta x:
+  INT CONST delta x :: int (increase*real (i))  .
+
+dx: real (to x-from x)  .
+dy: real (to y-from y)  .
+
+END PROC horizontal line;
+
+PROC vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+                    INT CONST from x, from y, to x, to y, thick):
+  IF from y > to y
+  THEN vertical line (PROC (INT CONST, INT CONST, INT CONST, INT CONST) line,
+                      to x, to y, from x, from y, thick)
+  ELSE draw line FI  .
+
+draw line:
+  INT VAR i;
+  calculate increase;
+  calculate limit points;
+  FOR i FROM -thick UPTO thick
+  REP calculate delta y;
+      line (x start+i, y start+delta y, x end+i, y end+delta y)
+  PER  .
+
+calculate increase:
+  REAL VAR increase :: -dx / dy  .
+
+calculate limit points:
+  INT CONST x start :: from x + int (increase * real (thick)), 
+            x end   :: to x   - int (increase * real (thick)),
+            y start :: from y - thick,
+            y end   :: to y   + thick  .
+
+calculate delta y:
+  INT CONST delta y :: int (increase*real (i))  .
+
+dx: real (to x-from x)  .
+dy: real (to y-from y)  .
+
+END PROC vertical line;
+
+END PACKET thick line;
+
+PACKET graphik text DEFINES draw char,        (*Autor: Heiko Indenbirken *)
+                            zeichensatz:      (*Stand:    27.06.85/16:03 *)
+                                              (*Änderung: 28.06.85/19:06 *)
+                                              (*Änderung: 05.08.86/16:00 *)
+LET ZEICHENSATZ = ROW 255 TEXT;
+ZEICHENSATZ VAR zeichen;
+INT CONST char x :: 6, char y :: 10;
+
+zeichensatz ("ZEICHENSATZ");
+
+PROC zeichensatz (TEXT CONST name):
+  IF exists (name)
+  THEN BOUND ZEICHENSATZ VAR new zeichen :: old (name);
+       zeichen := new zeichen;
+  ELSE errorstop ("Der Zeichensatz """ + name + """ existiert nicht") FI
+END PROC zeichensatz;
+
+PROC draw char (INT CONST char no, INT CONST x, y, x size, y size, direction,
+                PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  TEXT CONST character :: zeichen [char no];
+  INT VAR n :: 1, x0, y0, x1, y1;
+  INT CONST len :: length (character);
+  WHILE n < len
+  REP value (character, n, x0, y0, x1, y1);
+      transform (x0, y0, x, y, x size, y size, direction);
+      transform (x1, y1, x, y, x size, y size, direction); 
+      line (x0, y0, x1, y1);
+      n INCR 4
+  PER  .
+
+END PROC draw char;
+
+PROC value (TEXT CONST char, INT CONST n, INT VAR x0, y0, x1, y1):
+  x0 := val (code (char SUB n));    y0 := val (code (char SUB n+1));
+  x1 := val (code (char SUB n+2));  y1 := val (code (char SUB n+3));
+END PROC value;
+
+INT PROC val (INT CONST n):
+  IF n > 127
+  THEN -256 OR n
+  ELSE n FI
+END PROC val;
+
+PROC transform (INT VAR x, y, INT CONST x0, y0, x size, y size, direction):
+  INT CONST old x :: x, old y :: y;
+  SELECT direction OF
+  CASE 0: x := x0 + x vektor;  y := y0 + y vektor
+  CASE 1: x := x0 - y vektor;  y := y0 + x vektor
+  CASE 2: x := x0 - x vektor;  y := y0 - y vektor
+  CASE 3: x := x0 + y vektor;  y := y0 - x vektor
+  ENDSELECT  .
+
+x vektor:
+  IF x size = 0
+  THEN old x
+  ELSE (old x*x size) DIV char x FI  .
+
+y vektor:
+  IF y size = 0
+  THEN old y
+  ELSE (old y*y size) DIV char y FI  .
+
+END PROC transform;
+
+END PACKET graphik text;
+
+PACKET graphik text DEFINES draw text:        (*Autor: Heiko Indenbirken *)
+                                              (*Stand:    03.07.85/11:55 *)
+                                              (*Änderung: 05.08.86/16:04 *)
+PROC draw text (INT CONST x pos, y pos,
+                TEXT CONST msg, REAL CONST angle, INT CONST height, width,
+                PROC (INT CONST, INT CONST,
+                INT CONST, INT CONST, INT CONST, INT CONST) draw char):
+  INT CONST dir :: int (((angle MOD 360.0)+45.0) / 90.0);
+  INT VAR i;
+  REAL VAR x :: real (x pos), y :: real (y pos),
+           x step :: cosd (angle)*real (width),
+           y step :: sind (angle)*real (width);
+  FOR i FROM 1 UPTO length (msg)
+  REP IF control char
+      THEN execute control char
+      ELSE execute normal char FI
+  PER  .
+
+control char:
+  akt char < ""32""  .
+
+execute control char:
+  SELECT code (akt char) OF
+  CASE  1: home
+  CASE  2: right
+  CASE  3: up
+  CASE  7: out (""7"")
+  CASE  8: left
+  CASE 10: down
+  CASE 13: return
+  ENDSELECT  .
+
+home:
+  x := real (x pos);
+  y := real (y pos)  .
+
+right:
+  x INCR x step;  y INCR y step  . 
+
+up:
+  x INCR y step;  y INCR x step  . 
+
+left:
+  x DECR x step;  y DECR y step  .
+
+down:
+  x DECR y step;  y DECR x step  . 
+
+return:
+  x := real (x pos)  .
+
+execute normal char:
+  draw char (code (akt char), dir, int (x+0.5), int (y+0.5), height, width);
+  x INCR x step;
+  y INCR y step  .
+
+akt char:
+  msg SUB i  .
+
+END PROC draw text;
+
+END PACKET graphik text;
+
+PACKET comercial plot DEFINES bar,            (*Autor: Heiko Indenbirken *)
+                              circle:         (*Stand:    03.04.1985     *)
+                                              (*Änderung: 03.07.85/15:37 *)
+PROC bar (INT CONST from x, from y, to x, to y, pattern,
+          PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  IF from x > to x
+  THEN bar (to x, from y, from x, to y, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  ELIF from y > to y
+  THEN bar (from x, to y, to x, from y, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  ELSE draw frame;
+       fill frame with pattern
+  FI  .
+
+draw frame:
+  line (from x, from y, from x, to y);
+  line (from x, to y, to x, to y);
+  line (to x, to y, to x, from y);
+  line (to x, from y, from x, from y)  .
+
+fill frame with pattern:
+  SELECT pattern OF
+  CASE 1: fill right (from x, to x, from y, to y, 2, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 2: fill hor   (from x, to x, from y, to y, 1, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 3: fill hor   (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 4: fill vert  (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 5: fill hor   (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line);
+          fill vert  (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 6: fill right (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 7: fill left  (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  CASE 8: fill right (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line);
+          fill left  (from x, to x, from y, to y, 5, PROC (INT CONST, INT CONST, INT CONST, INT CONST) line)
+  ENDSELECT  .
+
+END PROC bar;
+
+PROC fill hor (INT CONST from x, to x, from y, to y, step,
+               PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  INT VAR y :: from y;
+  REP line (from x, y, to x, y);
+      y INCR step
+  UNTIL y > to y PER  .
+
+END PROC fill hor;
+
+PROC fill vert (INT CONST from x, to x, from y, to y, step,
+                PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  INT VAR x :: from x;
+  REP line (x, from y, x, to y);
+      x INCR step
+  UNTIL x > to x PER  .
+
+END PROC fill vert;
+
+PROC fill right (INT CONST from x, to x, from y, to y, step,
+                 PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  INT CONST width  :: to x - from x,
+            height :: to y - from y,
+            length :: width + height,
+            height step :: height + step,
+            width step  :: width + step;
+
+  INT VAR t :: step, left  :: from x, right :: from x,
+                     lower :: from y, upper :: from y;
+(*               Ausfüllen von links unten nach rechts oben              *)
+  WHILE t < length
+  REP calc start point;
+      calc end point;
+      line (left, upper, right, lower);
+      t INCR step
+  PER  .
+
+calc start point:
+  IF t < height
+  THEN upper INCR step
+  ELIF t < height step
+  THEN left  := from x + t - height;
+       upper := to y
+  ELSE left INCR step FI  .
+
+calc end point:
+  IF t < width
+  THEN right INCR step
+  ELIF t < width step
+  THEN lower := from y + t - width;
+       right := to x
+  ELSE lower INCR step FI  .
+
+END PROC fill right;
+
+PROC fill left (INT CONST from x, to x, from y, to y, step,
+                PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  INT CONST width  :: to x - from x,
+            height :: to y - from y,
+            length :: width + height,
+            height step :: height + step,
+            width step  :: width + step;
+
+  INT VAR t :: step, left  :: to x,   right :: to x,
+                     lower :: from y, upper :: from y;
+(*               Ausfüllen von rechts unten nach links oben              *)
+  WHILE t < length
+  REP calc start point;
+      calc end point;
+      line (right, upper, left, lower);
+      t INCR step
+  PER  .
+
+calc start point:
+  IF t < height
+  THEN upper INCR step
+  ELIF t < height step
+  THEN right := to x - t + height;
+       upper := to y
+  ELSE right DECR step FI  .
+
+calc end point:
+  IF t < width
+  THEN left DECR step
+  ELIF t < width step
+  THEN lower := from y + t - width;
+       left  := from x
+  ELSE lower INCR step FI  .
+
+END PROC fill left;
+
+PROC circle (INT CONST x, y, rad, REAL CONST  from, to, INT CONST pattern,
+             PROC (INT CONST, INT CONST, INT CONST, INT CONST) line):
+  REAL VAR t :: from;
+  INT VAR last x :: x, last y :: y;
+  WHILE t <= to
+  REP calc circle;
+      draw step;
+      t INCR 5.0
+  PER;
+  line (x rad, y rad, x, y)  .
+
+draw step:
+  IF pattern = 0
+  THEN line (last x, last y, x rad, y rad);
+       last x := x rad;
+       last y := y rad
+  ELSE line (x, y, x rad, y rad) FI  .
+
+calc circle:
+  INT CONST x rad :: int (cosd (t)*real (rad)+0.5)+x,
+            y rad :: int (sind (t)*real (rad)+0.5)+y  .
+
+END PROC circle;
+
+END PACKET comercial plot;
+
+PACKET pc plot DEFINES drawing area,          (*Autor: Heiko Indenbirken *)
+                       begin plot,            (*Stand:    20.05.85       *)
+                       end plot,              (*Änderung: 27.06.85/16:17 *)
+                       clear,                 (*Änderung: 03.07.85/15:59 *)
+                                              (*Änderung: 06.08.86/10:03 *)
+                       graphik,
+                       set pen, get pen, 
+
+                       move, 
+                       draw,
+                       draw line,
+                       marker,
+                       bar, circle,
+                       where:
+
+ 
+LET POS = STRUCT (INT x, y);
+LET PEN = STRUCT (INT back, fore, thick, line);
+INT CONST back code  :: -4,
+          modus code :: -5,
+          draw code  :: -6,
+          move code  :: -7,
+          pen code   :: -8,
+          full line  :: -1;
+ 
+INT VAR d, y, pause time :: 10,
+        resolution :: 4, max x :: 319, max y :: 199; 
+BOOL VAR is clear := FALSE;
+POS VAR old :: POS : (0, 0);
+PEN VAR pen :: PEN : (0, 1, 0, full line);
+
+PROC drawing area (REAL VAR x cm, y cm, INT VAR x pixel, y pixel) : 
+   x cm    := 22.0;    y cm    := 13.7; 
+   x pixel := max x;   y pixel := max y;
+END PROC drawing area;
+
+PROC graphik (INT CONST modus, pause):
+  pause time := pause;
+  SELECT modus OF
+  CASE 0: resolution := 3;
+  CASE 1: resolution := 72;
+          max x := 639;
+          max y := 399 
+  CASE 2: resolution := 64;
+          max x := 639;
+          max y := 399 
+  CASE 3: resolution := 6;
+          max x := 639;
+          max y := 199 
+  CASE 4: resolution := 4;
+          max x := 319;
+          max y := 199
+  OTHERWISE errorstop ("Nur Modi 0-4") ENDSELECT;
+
+  set range (0, 0, max x, max y);
+END PROC graphik;
+ 
+PROC begin plot : 
+  control (modus code, resolution, 0, d);
+  is clear := TRUE;
+ENDPROC begin plot ;
+
+PROC end plot : 
+  IF pause time > 0
+  THEN indicate end plot FI;
+  control (modus code, 3, 0, d)  .
+
+indicate end plot:
+  control (pen code, full line, full line, d);
+  REP set indicator;
+  UNTIL incharety (pause time) <> "" PER  .
+
+set indicator:
+  control (move code, 0, max y, d);
+  control (draw code, max x, max y, d)  .
+
+ENDPROC end plot ;
+
+PROC clear:
+  INT VAR x0, x1, y0, y1;
+  new values (22.0, 13.7, max x, max y, x0, x1, y0, y1);
+  set range (x0, y0, x1, y1);
+  clear screen;
+  clear pen;
+  clear pos;
+  is clear := FALSE  .
+
+clear screen:
+  IF is clear OR full screen
+  THEN control (modus code, resolution, 0, d)
+  ELSE draw frame;
+       clear frame
+  FI  .
+
+full screen:
+  x0 < 10 AND x1 > (max x-10) AND
+  y0 < 10 AND y1 > (max y-10)  .
+
+draw frame:
+   control (move code, x0, y0, d);
+   control (draw code, x1, y0, d);
+   control (draw code, x1, y1, d);
+   control (draw code, x0, y1, d);
+   control (draw code, x0, y0, d)  .
+
+clear frame:
+  control (pen code, full line, 0, d);
+  FOR y FROM max y-y1 UPTO max y-y0
+  REP control (move code, x0, y, d); 
+      control (draw code, x1, y, d); 
+  PER  .
+
+clear pen:
+  pen := PEN : (0, 1, 0, full line); 
+  control (pen code, full line, 1, d)  .
+
+clear pos:
+  old := POS : (x0, y0);
+  control (move code, x0, max y-y0, d)  .
+
+END PROC clear;
+
+PROC set pen (INT CONST back, fore, thick, type):
+  set background;
+  set foreground and linetype;
+  set thickness  .
+
+set background:
+  pen.back := back;                    (*Hintergrund über niederwertiges *)
+  control (back code, 0, back no, d)  .(*Byte von colour code            *)
+                                       (*Höherwetiges Byte regelt die    *)
+back no:                               (*Farbpalette                     *)
+  IF back = 0
+  THEN std background
+  ELSE back FI  .
+
+std background:
+  IF resolution = 4
+  THEN 16
+  ELSE 15 FI  .
+
+set foreground and linetype:               (*0, 1, 2, 3 Farben: löschend,*)
+  pen.fore := possible colour;             (*ändernd oder überschreibend *)
+  pen.line := type;                        (* in allen Linientypen.      *)
+  control (pen code, line (type), pen.fore, d)  .
+
+possible colour:
+  IF fore <= full line
+  THEN full line
+  ELIF fore > 3 OR  (fore > 1 AND resolution <> 4)
+  THEN 1
+  ELSE fore FI  .
+
+set thickness:
+  pen.thick := thick DIV 10  .
+
+END PROC set pen;
+
+PROC get pen (INT VAR back, fore, thick, line):
+  back  := pen.back;
+  fore  := pen.fore;
+  thick := pen.thick;
+  line  := pen.line
+END PROC get pen;
+
+INT PROC line (INT CONST type):
+  SELECT type OF
+  CASE 0: 0
+  CASE 1: full line
+  CASE 2: 21845
+  CASE 3: 3855
+  CASE 4: 255
+  CASE 5: 4351
+  OTHERWISE type END SELECT
+END PROC line;
+
+PROC int move (INT CONST x, y):
+  control (move code, x,  max y-y, d);
+END PROC int move;
+
+PROC int draw (INT CONST x, y):
+  control (draw code, x, max y-y, d);
+END PROC int draw;
+
+PROC draw line (INT CONST from x, from y, to x, to y):
+  control (move code, from x, max y-from y, d);
+  clip (from x, from y, to x, to y, PROC int move, PROC int draw)
+END PROC draw line;
+
+PROC move (INT CONST x, y) :
+  control (move code, x, max y-y, d);
+  old := POS  : (x, y) 
+END PROC move;
+ 
+PROC draw (INT CONST x, y):
+  IF std thickness
+  THEN clip (old.x, old.y, x, y, PROC int move, PROC int draw)
+  ELSE thick (old.x, old.y, x, y, pen.thick, PROC (INT CONST, INT CONST, INT CONST, INT CONST) draw line) FI;
+  old := POS  : (x, y)   .
+
+std thickness:  pen.thick = 0  .
+END PROC draw;
+
+PROC draw (TEXT CONST msg, REAL CONST angle, INT CONST height, width):
+  control (pen code, full line, pen.fore, d);
+  draw text (old.x, old.y, msg, angle, y size, x size,
+  PROC (INT CONST, INT CONST, INT CONST, INT CONST, INT CONST, INT CONST) draw char);
+  control (move code, old.x, max y-old.y, d);
+  control (pen code, line (pen.line), pen.fore, d)  .
+
+x size: IF width = 0
+        THEN 6
+        ELSE width FI  .
+y size: IF height = 0
+        THEN 10
+        ELSE height FI .
+
+END PROC draw;
+
+PROC draw char (INT CONST char, direction, x, y, INT CONST height, width):
+  draw char (char, x, y, width, height, direction,
+             PROC (INT CONST, INT CONST, INT CONST, INT CONST) draw line)
+END PROC draw char;
+
+PROC bar (INT CONST from x, from y, to x, to y, pattern):
+  control (pen code, full line, pen.fore, d);
+  bar (from x, from y, to x, to y, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) draw line);
+  control (move code, old.x, max y-old.y, d);
+  control (pen code, line (pen.line), pen.fore, d)  .
+END PROC bar;
+
+PROC circle (INT CONST x, y, rad, REAL CONST from, to, INT CONST pattern):
+  control (pen code, full line, pen.fore, d);
+  circle (x, y, rad, from, to, pattern, PROC (INT CONST, INT CONST, INT CONST, INT CONST) draw line);
+  control (move code, old.x, max y-old.y, d);
+  control (pen code, line (pen.line), pen.fore, d)  .
+END PROC circle;
+
+PROC marker (INT CONST x, y, no, size):
+  control (pen code, full line, pen.fore, d);
+  draw char (no, 0, x, y, size, size);
+  control (move code, old.x, max y-old.y, d);
+  control (pen code, line (pen.line), pen.fore, d)  .
+END PROC marker;
+
+PROC where (INT VAR x, y):
+  x := old.x;  y := old.y
+END PROC where;
+
+END PACKET pc plot
+
diff --git a/graphic/ZEICHENSATZ b/graphic/ZEICHENSATZ
new file mode 100644
index 0000000..9866ec2
Binary files /dev/null and b/graphic/ZEICHENSATZ differ
diff --git a/graphic/gen Graphik b/graphic/gen Graphik
new file mode 100644
index 0000000..f70cc66
--- /dev/null
+++ b/graphic/gen Graphik	
@@ -0,0 +1,16 @@
+TEXT VAR geraet;
+page;
+out ("Bitte den Namen der Hardwareanpassung (z.B. 'PC.plot') eingeben: ");
+get line (geraet);
+IF NOT exists (geraet)
+THEN errorstop ("Endgerät nicht vorhanden") FI;
+
+insert ("GRAPHIK.Picfile");
+insert ("GRAPHIK.Transform");
+insert (geraet);
+insert ("GRAPHIK.Plot");
+
+
+
+
+
diff --git a/graphic/gen Plotter b/graphic/gen Plotter
new file mode 100644
index 0000000..73d7b2f
--- /dev/null
+++ b/graphic/gen Plotter	
@@ -0,0 +1,16 @@
+TEXT VAR geraet;
+page;
+out ("Bitte den Namen der Hardwareanpassung (z.B. 'PC.plot') eingeben: ");
+get line (geraet);
+IF NOT exists (geraet)
+THEN errorstop ("Endgerät nicht vorhanden") FI;
+
+insert ("GRAPHIK.Picfile");
+insert ("GRAPHIK.Transform");
+insert (geraet);
+insert ("GRAPHIK.Plotter");
+insert ("GRAPHIK.Server")
+
+
+
+
diff --git a/graphic/graphik editor b/graphic/graphik editor
new file mode 100644
index 0000000..7aa6e33
--- /dev/null
+++ b/graphic/graphik editor	
@@ -0,0 +1,324 @@
+PACKET graphic editor DEFINES  graphic,           (*Autor: H.Indenbirken *)
+                               picfile, picture,  (*Stand: 26.02.1985    *)
+
+                               neu zeichnen,
+ 
+                               UP, DOWN, T,
+
+                               pen, select pen, selected pen, background,
+                               extrema pic, extrema picfile:
+ 
+
+ 
+LET norm cmd = ""1""27""3""10""9"epb"16"",
+    hop cmd = ""2""10""12""1"",
+    bell    = ""7"",
+    esc     = ""27"";
+
+PICFILE VAR p;
+PICTURE VAR pic;
+TEXT VAR command :: "", old command :: "", char, headline :: "";
+BOOL VAR within edit :: FALSE, new plot :: FALSE;
+ROW 3 ROW 2 REAL VAR size;
+ROW 2 ROW 2 REAL VAR limits;
+ROW 4 REAL VAR angles;
+ROW 2 REAL VAR oblique;
+ROW 3 REAL VAR perspective;
+
+PROC open graphic (TEXT CONST name, DATASPACE CONST ds):
+  p := ds; 
+  get values (p, size, limits, angles, oblique, perspective); 
+  head line := ""1""15"LEN       ................................ DIM    PEN    .."14" Picture      "15""14"";
+  replace (head line, 32-LENGTH name DIV 2, name);
+  new plot := TRUE;
+  within edit := TRUE
+END PROC open graphic;
+
+PROC graphic:
+  graphic (last param)
+END PROC graphic;
+
+PROC graphic (TEXT CONST name) :
+  IF NOT exists (name) 
+  THEN IF yes ("Soll ein neuer Picfile eingerichtet werden")
+       THEN graphic (new (name), name) FI
+  ELSE graphic (old (name), name) FI
+
+END PROC graphic;
+
+PROC graphic (DATASPACE CONST f, TEXT CONST name) :
+  open graphic (name, f);
+  reset;
+  kommandos bearbeiten;
+  within edit := FALSE  .
+
+kommandos bearbeiten :
+  REP IF new plot
+      THEN plot (p);
+           new plot := FALSE
+      FI;
+      read picture (p, pic);
+      out head line;
+      inchar (command);
+      do command
+  PER  .
+ 
+out head line:
+  replace (headline,  7, text (length (pic), 5));
+  replace (headline, 50, text (dim (pic), 1));
+  replace (headline, 57, text (pen (pic), 2));
+  replace (headline, 72, text (picture no (p), 4));
+  out (head line)  .
+
+do command:
+  SELECT pos (norm cmd, command) OF 
+  CASE  1: hop commands
+  CASE  2: escape commands
+  CASE  3: position up
+  CASE  4: position down
+  CASE  5: position direct
+  CASE  6: extrema pic
+  CASE  7: selected pen (pen (pic));
+  CASE  8: out (1, 2, ""15""5"Hintergrundfarbe: " +
+           colour of (background (p)) + " "14"")
+  CASE  9: identify (pic);
+  OTHERWISE out (bell) ENDSELECT .
+
+position up :
+  IF is first picture (p)
+  THEN out (bell);
+  ELSE up (p) FI  .
+
+position down :
+  IF eof (p)
+  THEN out (bell)
+  ELSE down (p) FI  .
+ 
+position direct:
+   out (1, 68, "");
+   edit get (command, 4, 4);
+   to pic (p, int (command))  .
+
+hop commands :
+  inchar (command);
+  SELECT pos (hop cmd, command) OF 
+  CASE 1: to first pic (p)
+  CASE 2: to eof (p)
+  CASE 3: delete picture (p);
+          IF NOT new plot
+          THEN erase (pic) FI
+  CASE 4: new plot := TRUE
+  OTHERWISE out (bell) ENDSELECT  .
+
+escape commands :
+  inchar (command);
+  IF command = "q"
+  THEN LEAVE kommandos bearbeiten
+  ELIF command = "f"
+  THEN do (old command)
+  ELIF command = esc
+  THEN kommandomodus
+  ELSE do (kommando auf taste (command)) FI  .
+
+END PROC graphic;
+
+PROC kommandomodus:
+  command := "";
+  disable stop;
+  REP get command;
+      do (command)
+  UNTIL command executed PER;
+
+  IF new values
+  THEN get values (size, limits, angles, oblique, perspective); 
+       set values (p, size, limits, angles, oblique, perspective); 
+       new plot := new plot OR new values
+  FI  .
+
+get command:
+  REP out (1, 2, ""15"Gib Graphikkommando: ");
+      edit get (command, 0, 54, "", "k", char);
+      out (""14"");
+      out (1, 2, ""5"");
+
+      IF char = ""13""
+      THEN LEAVE get command
+      ELIF char = ""27"k"
+      THEN command := old command FI
+  PER  .
+
+command executed:
+  IF is error
+  THEN out (1, 1, error message);
+       clear error;
+       FALSE
+  ELSE old command := command;
+       TRUE
+  FI  .
+
+END PROC kommandomodus;
+
+PROC out (INT CONST x, y, TEXT CONST t):
+  cursor (x, y);
+  out (t)
+END PROC out;
+
+TEXT PROC colour of (INT CONST colour):
+  SELECT colour OF
+  CASE 0: "löschen"
+  CASE 1: "std"
+  CASE 2: "rot"
+  CASE 3: "blau"
+  CASE 4: "grün"
+  CASE 5: "schwarz"
+  CASE 6: "weiß"
+  OTHERWISE text (colour) ENDSELECT  .
+END PROC colour of;
+
+TEXT PROC linetype of (INT CONST linetype):
+  SELECT linetype OF
+  CASE 0: "unsichtbar"
+  CASE 1: "durchgehend"
+  CASE 2: "gepunktet"
+  CASE 3: "kurz gestrichelt"
+  CASE 4: "lang gestrichelt"
+  CASE 5: "strichpunkt"
+  OTHERWISE text (linetype) ENDSELECT  .
+END PROC linetype of;
+
+PICFILE PROC picfile :
+  IF NOT within edit
+  THEN errorstop ("Not within editmode") FI;
+  p
+END PROC picfile;
+
+PICTURE PROC picture :
+  IF NOT within edit
+  THEN errorstop ("Not within editmode") FI;
+  pic
+END PROC picture;
+
+PROC neu zeichnen:
+  new plot := TRUE
+END PROC neu zeichnen;
+
+OP UP (INT CONST distance):
+  up (p, distance);
+  read picture (p, pic) 
+END OP UP;
+
+OP DOWN (INT CONST distance):
+  down (p, distance);
+  read picture (p, pic) 
+END OP DOWN;
+
+OP T (INT CONST n):
+  to pic (p, n);
+  read picture (p, pic) 
+END OP T;
+ 
+PROC pen (INT CONST n):
+  IF NOT new plot
+  THEN erase (pic) FI;
+
+  pen (pic, n);
+  write picture (p, pic);
+
+  IF NOT new plot
+  THEN show (pic) FI
+END PROC pen;
+
+PROC select pen (INT CONST n, colour, thickness, linetype, BOOL CONST hidden):
+  select pen (p, n, colour, thickness, linetype, hidden);
+  new plot := TRUE
+END PROC select pen;
+
+PROC select pen (INT CONST n, colour, thickness, linetype):
+  select pen (p, n, colour, thickness, linetype, FALSE);
+  new plot := TRUE
+END PROC select pen;
+
+PROC selected pen (INT CONST n, INT VAR colour, thickness, linetype,
+                   BOOL VAR hidden):
+  selected pen (p, n, colour, thickness, linetype, hidden);
+END PROC selected pen;
+
+PROC selected pen (INT CONST n):
+  INT VAR colour, thickness, linetype;
+  BOOL VAR hidden;
+  selected pen (p, n, colour, thickness, linetype, hidden);
+  out (1, 2, ""5""15"PEN #" + text (n) + ":  Farbe: " + colour of (colour) +
+             ", Dicke " + text (thickness) + ", Linientyp " + linetype of (linetype) +
+             hidden text + " "14"")  .
+
+hidden text:
+  IF hidden
+  THEN ". "
+  ELSE ", nicht sichtbare Linien werden unterdrückt." FI  .
+
+END PROC selected pen;
+
+INT PROC background:
+  background (p)
+END PROC background;
+
+PROC background (INT CONST n):
+  new plot := n <> background (p);
+  background (p, n)
+END PROC background;
+
+PROC extrema pic:
+  REAL VAR x min, x max, y min, y max, z min, z max;
+  IF dim (pic) = 2
+  THEN extrema (pic, x min, x max, y min, y max);
+       out (1, 2, ""5""15"Extrema: [" + text (x min) + "," + text (x max) + 
+                  "]  [" + text (y min) + "," + text (y max) + "] "14"")
+  ELSE extrema (pic, x min, x max, y min, y max, z min, z max);
+       out (1, 2, ""5""15"Extrema: [" + text (x min) + "," + text (x max) + 
+                  "]  [" + text (y min) + "," + text (y max) + 
+                  "]  [" + text (z min) + "," + text (z max) +"] "14"") 
+  FI
+END PROC extrema pic;
+
+PROC extrema picfile:
+  REAL VAR x min, x max, y min, y max, z min, z max;
+  extrema (p, x min, x max, y min, y max, z min, z max);
+  out (1, 2, ""5""15"Extrema: [" + text (x min) + "," + text (x max) + 
+             "]  [" + text (y min) + "," + text (y max) + 
+             "]  [" + text (z min) + "," + text (z max) +"] "14"") 
+END PROC extrema picfile;
+
+PROC identify (PICTURE CONST pic):
+  begin plot;
+  hidden lines (TRUE);
+  pen (background (p), 1, 1, 2);
+  plot (pic);
+  end plot
+END PROC identify;
+
+PROC erase (PICTURE CONST pic):
+  INT VAR colour, thickness, linetype;
+  BOOL VAR hidden;
+
+  selected pen (p, pen (pic), colour, thickness, linetype, hidden); 
+  begin plot;
+  hidden lines (TRUE);
+  pen (background (p), 0, thickness, linetype);
+  plot (pic);
+  end plot
+END PROC erase;
+
+PROC show (PICTURE CONST pic):
+  INT VAR colour, thickness, linetype;
+  BOOL VAR hidden;
+
+  selected pen (p, pen (pic), colour, thickness, linetype, hidden); 
+  begin plot;
+  hidden lines (TRUE);
+  pen (background (p), colour, thickness, linetype);
+  plot (pic);
+  end plot
+END PROC show;
+
+END PACKET graphic editor;
+
diff --git a/hamster/ls-Herbert und Robbi 1 b/hamster/ls-Herbert und Robbi 1
new file mode 100644
index 0000000..ed19e98
--- /dev/null
+++ b/hamster/ls-Herbert und Robbi 1	
@@ -0,0 +1,84 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                ls-Herbert und Robbi 1               ** 
+          **                                                     ** 
+          **                     Version 1.1                     ** 
+          **                                                     ** 
+          **                  (Stand: 30.03.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET ls herbert und robbi 1  DEFINES{}       sei ein hamster, ist hamster,{}       sei ein roboter, ist roboter,{}       landschaft, arbeitsfeld,{}       vor, links um, nimm, gib,{}       korn da, werkstueck da,{}       backen leer, behaelter leer,{}       vorn frei, lauf,{}       hamsterinter, roboterinter,{}       geschwindigkeit, taste,{}       befehlssatz erweitern,{}       befehlssatz ist erweitert,{}       drucke landschaft,{}       hamster druckerstart einstellen,{}       hamster drucker xstart,{}
+       hamster drucker ystart,{}       hamster landschaftsschrifttyp einstellen,{}       hamster landschaftsschrifttyp,{}       druckereinstellung fuer flaechenausdruck,{}       landschaftsauskunftstext,{}       testauskunftstext 1, testauskunftstext 2,{}       befehlsauskunftstext, laufauskunftstext,{}       kommandomodus, hamstermodus,{}       zeige landschaft, lege landschaft ab:{}TYPE LOCATION          = STRUCT (INT x, y);{}LET  menukarte         =  "ls-MENUKARTE:Herbert und Robbi",{}     richtung          =  ""3""8""10""2"",{}
+     erscheinungsform  =           "A<V>",{}     praefix           =       "Flaeche:",{}     flaechentype      =             1007,{}     neutral           =                0,{}     erzeuge           =                1,{}     hamsterlauf       =                2,{}     interaktiv        =                3,{}     kommandostufe     =               99,{}     west              =            ""8"",{}     ost               =            ""2"",{}     cleol             =            ""5"",{}     piep              =            ""7"",{}
+     mark ein          =           ""15"",{}     mark aus          =           ""14"",{}     escape            =           ""27"",{}     blank             =              " ",{}     niltext           =               "",{}     hindernis         =              "#",{}     korn              =              "o",{}     hinderniskachel   =             "##",{}     blankkachel       =             " .",{}     kornkachel        =             " o",{}     protokollname     =      "PROTOKOLL";{}LET    max x           =               40,{}
+       max y           =               23;{}LET    FLAECHE         =  ROW max x ROW max y INT;{}LET    LANDSCHAFT      =  STRUCT (INT xpos, ypos, blickrichtung,{}                                      anzahl koerner, FLAECHE flaeche);{}LET    HAMSTER         =  STRUCT (LOCATION stelle, INT koerner, form);{}BOUND LANDSCHAFT VAR aktuelle landschaft;{}FLAECHE VAR land;{}HAMSTER VAR hamster;{}FILE VAR protokoll;{}INT  CONST besetzt                 ::             -1,{}           frei                    ::              0;{}
+TEXT CONST kornsymbole             ::{}  "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";{}INT CONST maxkornzahl              ::   LENGTH kornsymbole;{}BOOL VAR   hamster eingestellt     ::           TRUE,{}           befehlssatz erweitert   ::          FALSE;{}TEXT VAR   eingabezeichen          ::        niltext,{}           archivlandschaftsname   ::        niltext,{}           hinderniszeichen        ::           "\#\#",{}           schrifttyp              ::        niltext;{}INT  VAR   verzoegerungsfaktor     ::              5,{}
+           modus                   ::  kommandostufe,{}           a, b, c, d;{}REAL VAR   xstart                  ::            0.0,{}           ystart                  ::            0.0;{}WINDOW VAR fenster                 ::  window (1, 1, 79, 24);{}INITFLAG VAR in this task          ::  FALSE;{}OP := (LOCATION VAR l, LOCATION CONST r):{}   l.x := r.x; l.y := r.y{}END OP :=;{}PROC initialize hamstersystem:{}  IF NOT initialized (in this task){}     THEN install menu (menukarte);{}  FI{}END PROC initialize hamstersystem;{}
+PROC sei ein hamster:{}  hamster eingestellt := TRUE{}END PROC sei ein hamster;{}BOOL PROC ist hamster:{}   hamster eingestellt{}END PROC ist hamster;{}PROC sei ein roboter:{}  hamster eingestellt := FALSE{}END PROC sei ein roboter;{}BOOL PROC ist roboter:{}   NOT hamster eingestellt{}END PROC ist roboter;{}PROC hole landschaft (TEXT CONST name):{}   aktuelle landschaft := old (praefix + name);{}   land                := aktuelle landschaft.flaeche;{}   hamster.form        := aktuelle landschaft.blickrichtung;{}
+   hamster.stelle.x    := aktuelle landschaft.xpos;{}   hamster.stelle.y    := aktuelle landschaft.ypos;{}   hamster.koerner     := aktuelle landschaft.anzahl koerner{}END PROC hole landschaft;{}PROC lege landschaft ab (TEXT CONST name):{}   IF exists (praefix + name){}      THEN forget (praefix + name, quiet){}   FI;{}   aktuelle landschaft                := new (praefix + name);{}   aktuelle landschaft.flaeche        := land;{}   aktuelle landschaft.blickrichtung  := hamster.form;{}   aktuelle landschaft.xpos           := hamster.stelle.x;{}
+   aktuelle landschaft.ypos           := hamster.stelle.y;{}   aktuelle landschaft.anzahl koerner := hamster.koerner;{}   type( old(praefix + name), flaechentype){}END PROC lege landschaft ab;{}PROC hamstermodus:{}   modus := neutral{}END PROC hamstermodus;{}PROC kommandomodus:{}   modus := kommandostufe{}END PROC kommandomodus;{}PROC erzeugemodus:{}   modus := erzeuge{}END PROC erzeugemodus;{}PROC intermodus:{}   modus := interaktiv{}END PROC intermodus;{}PROC laufmodus:{}   modus := hamsterlauf{}
+END PROC laufmodus;{}BOOL PROC vorn frei:{}  kontrolliere modus;{}  LOCATION VAR hier :: hamster.stelle;{}  SELECT hamster.form OF{}    CASE 1: IF hamster.stelle.y < 2       THEN protestiere FI;{}            hier.y DECR 1{}    CASE 2: IF hamster.stelle.x < 2       THEN protestiere FI;{}            hier.x DECR 1{}    CASE 3: IF hamster.stelle.y >= max y  THEN protestiere FI;{}            hier.y INCR 1{}    CASE 4: IF hamster.stelle.x >= max x  THEN protestiere FI;{}            hier.x INCR 1{}    OTHERWISE modus := kommandostufe;{}
+              IF ist hamster{}                 THEN errorstop(nachricht( 7)){}                 ELSE errorstop(nachricht(14)){}              FI{}  END SELECT;{}  IF modus = erzeuge{}     THEN TRUE{}     ELSE land[hier.x] [hier.y] <> besetzt{}  FI{}END PROC vorn frei;{}BOOL PROC korn da:{}  kontrolliere modus;{}  kornzahl > 0{}END PROC korn da;{}INT PROC kornzahl:{}  land [hamster.stelle.x] [hamster.stelle.y]{}END PROC kornzahl;{}BOOL PROC werkstueck da:{}  korn da{}END PROC werkstueck da;{}BOOL PROC backen leer:{}
+  kontrolliere modus;{}  hamster.koerner <= 0 AND (modus = hamsterlauf OR modus = interaktiv){}END PROC backen leer;{}BOOL PROC behaelter leer:{}  backen leer{}END PROC behaelter leer;{}PROC protestiere:{}  IF modus = erzeuge{}     THEN out(piep); eins zurueck{}     ELSE verzoegere 10 mal; zeige("X"); verzoegere 10 mal;{}          kommandomodus;{}          IF ist hamster{}             THEN errorstop(nachricht( 6)){}             ELSE errorstop(nachricht(13)){}          FI;{}  FI.{}  eins zurueck:{}
+    SELECT hamster.form OF{}      CASE 1:   hamster.stelle.y INCR 1{}      CASE 2:   hamster.stelle.x INCR 1{}      CASE 3:   hamster.stelle.y DECR 1{}      CASE 4:   hamster.stelle.x DECR 1{}      OTHERWISE kommandomodus;{}                IF ist hamster{}                   THEN errorstop(nachricht( 7)){}                   ELSE errorstop(nachricht(14)){}                FI;{}     END SELECT.{}  verzoegere 10 mal:{}    INT VAR j;{}    FOR j FROM 1 UPTO 10 REP{}      verzoegere{}    PER{}END PROC protestiere;{}
+PROC verzoegere:{}  IF modus <> hamsterlauf{}     THEN LEAVE verzoegere{}  FI;{}  eingabezeichen := incharety (verzoegerungsfaktor);{}  IF   eingabezeichen = escape{}       THEN kommandomodus;{}            IF ist hamster{}               THEN errorstop(nachricht( 4)){}               ELSE errorstop(nachricht(11)){}            FI{}  ELIF eingabezeichen = "-" THEN verlangsame{}  ELIF eingabezeichen = "+" THEN beschleunige{}  ELIF eingabezeichen = "?" THEN boxinfo (fenster, laufauskunftstext,{}                                                   5, maxint, a, b, c, d);{}
+                                 cursor on; zeige landschaft{}  ELIF pos ("0123456789", eingabezeichen) > 0{}        THEN geschwindigkeit (int (eingabezeichen)){}  FI.{}  verlangsame:{}    IF   verzoegerungsfaktor > 31 THEN  (* lass es dabei *){}    ELIF verzoegerungsfaktor < 1{}         THEN verzoegerungsfaktor INCR 1{}         ELSE verzoegerungsfaktor INCR verzoegerungsfaktor{}    FI.{}  beschleunige:{}    IF verzoegerungsfaktor < 1{}       THEN verzoegerungsfaktor := -1{}       ELSE verzoegerungsfaktor := verzoegerungsfaktor DIV 2{}
+    FI{}END PROC verzoegere;{}PROC geschwindigkeit (INT CONST faktor):{}  SELECT faktor OF{}    CASE 0 :  verzoegerungsfaktor := 20000;{}    CASE 1 :  verzoegerungsfaktor :=    50;{}    CASE 2 :  verzoegerungsfaktor :=    20;{}    CASE 3 :  verzoegerungsfaktor :=    10;{}    CASE 4 :  verzoegerungsfaktor :=     8;{}    CASE 5 :  verzoegerungsfaktor :=     5;{}    CASE 6 :  verzoegerungsfaktor :=     2;{}    CASE 7 :  verzoegerungsfaktor :=     1;{}    CASE 8 :  verzoegerungsfaktor :=     0;{}    CASE 9 :  verzoegerungsfaktor :=    -1;{}
+    OTHERWISE (*belasse es dabei*){}  END SELECT{}END PROC geschwindigkeit;{}PROC vor:{}  kontrolliere modus;{}  IF vorn frei{}     THEN zeige(kachel);{}          bilde neue hamsterkoordinaten;{}          zeige(erscheinungsform SUB hamster.form);{}          verzoegere{}     ELSE modus := kommandostufe;{}          zeige("X");{}          IF ist hamster{}             THEN errorstop(nachricht(1)){}             ELSE errorstop(nachricht(8)){}          FI{}  FI.{}  kachel:{}    INT CONST z :: land [hamster.stelle.x] [hamster.stelle.y];{}
+    IF   z = besetzt THEN hinderniskachel{}    ELIF z = frei    THEN blankkachel{}                     ELSE kornkachel{}    FI.{}  bilde neue hamsterkoordinaten:{}    SELECT hamster.form OF{}      CASE 1    :hamster.stelle.y DECR 1{}      CASE 2    :hamster.stelle.x DECR 1{}      CASE 3    :hamster.stelle.y INCR 1{}      CASE 4    :hamster.stelle.x INCR 1{}      OTHERWISE  modus:=kommandostufe;{}                 IF ist hamster{}                    THEN errorstop(nachricht( 7)){}                    ELSE errorstop(nachricht(14)){}
+                 FI{}    END SELECT.{}END PROC vor;{}PROC nimm:{}  kontrolliere modus;{}  IF korn da{}     THEN variiere kornzahl (-1);{}          IF kornzahl < 1 THEN zeige (ost + blank) FI{}     ELSE modus := kommandostufe;{}          zeige("X");{}          IF ist hamster{}             THEN errorstop(nachricht(2)){}             ELSE errorstop(nachricht(9)){}          FI{}  FI;{}  verzoegere{}END PROC nimm;{}PROC gib:{}  kontrolliere modus;{}  IF backen leer{}     THEN modus := kommandostufe;{}          zeige ("X");{}
+          IF ist hamster{}             THEN errorstop(nachricht( 3)){}             ELSE errorstop(nachricht(10)){}          FI{}     ELSE variiere kornzahl (+1);{}          zeige(ost + korn){}  FI;{}  verzoegere{}END PROC gib;{}PROC links um:{}  kontrolliere modus;{}  hamster.form := hamster.form MOD 4 + 1;{}  (* da hamster.form der Werte 1,2,3,4 faehig ist und linksdreht *){}  zeige (subjekt);{}  verzoegere.{}  subjekt:{}    erscheinungsform SUB hamster.form.{}END PROC links um;{}PROC variiere kornzahl (INT CONST delta):{}
+  IF delta * delta <> 1{}     THEN LEAVE variiere kornzahl{}  FI;   (* als delta kommen nur +1 und -1 vor *){}  INT VAR k;{}  IF kornzahl = -1 AND delta = 1{}     THEN k := 1{}     ELSE k := kornzahl + delta{}  FI;{}  IF k <= 0{}     THEN land [hamster.stelle.x] [hamster.stelle.y] := frei{}     ELSE land [hamster.stelle.x] [hamster.stelle.y] := min (k,maxkornzahl){}  FI;{}  IF modus = hamsterlauf OR modus = interaktiv{}     THEN hamster.koerner DECR delta{}  FI{}END PROC variiere kornzahl;{}PROC kontrolliere modus:{}
+  initialize hamstersystem;{}  SELECT modus OF{}    CASE neutral    : erzeugemodus;{}                      landschaft;{}                      laufmodus{}    CASE erzeuge,{}         interaktiv,{}         hamsterlauf: (* nichts *){}    OTHERWISE         kommandomodus;{}                      line;{}                      IF ist hamster{}                         THEN sage(anwendungstext (21));pause(20);{}                              errorstop(nachricht( 5)){}                         ELSE sage(anwendungstext (22));pause(20);{}
+                              errorstop(nachricht(12)){}                      FI{}  END SELECT{}END PROC kontrolliere modus;{}PROC zeige (TEXT CONST was):{}   cursor (2 * hamster.stelle.x - 1, hamster.stelle.y);{}   IF hamster.stelle.x >= max x  AND hamster.stelle.y > max y{}      THEN out ((was SUB 1)); out(west){}      ELSE out(was); (LENGTH was) TIMESOUT west{}   FI.{}END PROC zeige;{}PROC sage (TEXT CONST aussage):{}   cursor(1,24); out(aussage + cleol){}END PROC sage;{}TEXT PROC nachricht (INT CONST nummer):{}
+   inv (text (anwendungstext (nummer), 65)) + piep{}END PROC nachricht;{}TEXT PROC inv (TEXT CONST text):{}  TEXT VAR aus :: mark ein + text + blank + mark aus;{}  aus{}END PROC inv;{}PROC zeige landschaft:{}  initialize hamstersystem;{}  INT VAR y;{}  FOR y FROM 1 UPTO max y REP{}     setze zeile zusammen;{}     cursor (1,y); out (zeile){}  PER;{}  cursor(1,24); out(cleol);{}  IF modus = interaktiv{}     THEN gib befehlszeile aus{}  FI;{}  zeige hamster; cursor on.{}  setze zeile zusammen:{}    TEXT VAR zeile :: niltext;{}
+    INT VAR x;{}    FOR x FROM 1 UPTO max x REP{}       zeile CAT kachel{}    PER.{}  kachel:{}    INT CONST z :: land [x] [y];{}    IF   z = besetzt THEN hinderniskachel{}    ELIF z = frei    THEN blankkachel{}                     ELSE kornkachel{}    FI.{}   gib befehlszeile aus:{}     cursor(1,1); write(cleol); write (anwendungstext (62)){}END PROC zeige landschaft;{}PROC zeige hamster:{}   zeige (erscheinungsform SUB hamster.form){}END PROC zeige hamster;{}PROC landschaft (TEXT CONST kandidat):{}
+  initialize hamstersystem;{}  archivlandschaftsname := kandidat;{}  IF   exists (praefix + kandidat){}         CAND type (old (praefix + kandidat)) = flaechentype{}       THEN behandle existierende landschaft{}  ELIF exists (praefix + kandidat){}       THEN forget (praefix + kandidat, quiet);{}            behandle neue landschaft{}  ELSE behandle neue landschaft{}  FI.{}  behandle existierende landschaft:{}    hole landschaft (kandidat);{}    SELECT modus OF{}      CASE hamsterlauf,{}           interaktiv,{}
+           neutral       : zeige landschaft;{}                           laufmodus{}      CASE erzeuge       : modifiziere eventuell{}      CASE kommandostufe : modifiziere landschaft{}      OTHERWISE            errorstop (anwendungstext (15)){}    END SELECT.{}  behandle neue landschaft:{}    SELECT modus OF{}      CASE hamsterlauf,{}           interaktiv,{}           neutral,{}           erzeuge       : erschaffe landschaft;{}                           modifiziere landschaft;{}                           zeige landschaft;{}
+                           laufmodus{}      CASE kommandostufe : erschaffe landschaft;{}                           modifiziere landschaft;{}      OTHERWISE            errorstop (anwendungstext (15)){}    END SELECT.{}  modifiziere eventuell:{}    IF ist hamster{}       THEN IF boxyes (fenster, anwendungstext (41), 5, a, b, c, d){}               THEN cursor on; modifiziere landschaft{}            FI{}       ELSE IF boxyes (fenster, anwendungstext (42), 5, a, b, c, d){}               THEN cursor on; modifiziere landschaft{}
+            FI{}    FI;{}    zeige landschaft.{}  erschaffe landschaft:{}    INT VAR j;{}    FOR j FROM 1 UPTO max y REP{}      INT VAR k;{}      FOR k FROM 1 UPTO max x REP{}        land [k] [j] := frei{}      PER{}    PER;{}    hamster.form     :=   4;{}    hamster.stelle.x :=  20;{}    hamster.stelle.y :=  12;{}    hamster.koerner  :=   0.{}END PROC landschaft;{}PROC landschaft:{}  initialize hamstersystem;{}  IF ist hamster{}     THEN landschaft (erfragter landschaftsname (anwendungstext (36))){}
+     ELSE landschaft (erfragter landschaftsname (anwendungstext (37))){}  FI{}END PROC landschaft;{}TEXT PROC erfragter landschaftsname (TEXT CONST satz):{}  TEXT VAR landschaftsname :: archivlandschaftsname;{}  REP{}    page; line (3); out (satz + cleol); line (2);{}    editget (landschaftsname);{}    landschaftsname := compress (landschaftsname);{}    IF landschaftsname = niltext{}       THEN line (2); out (anwendungstext (18) + piep);{}            line (2); out (anwendungstext (38)); pause{}    FI{}
+  UNTIL landschaftsname <> niltext PER;{}  landschaftsname{}END PROC erfragter landschaftsname;{}PROC arbeitsfeld (TEXT CONST kandidat):{}  landschaft (kandidat){}END PROC arbeitsfeld;{}PROC arbeitsfeld:{}  landschaft{}END PROC arbeitsfeld;{}PROC modifiziere landschaft:{}  INT CONST modalibi :: modus;{}  erzeugemodus;{}  zeige landschaft;{}  informiere;{}  zeige hamster;{}  nimm ein eingabezeichen;{}  WHILE nicht endewunsch REP{}    erfuelle fortschreibungswunsch;{}    nimm ein eingabezeichen{}  PER;{}
+  erfrage koernerzahl;{}  lege landschaft ab (archivlandschaftsname);{}  modus := modalibi.{}  nimm ein eingabezeichen:{}    inchar (eingabezeichen).{}  nicht endewunsch:{}    pos ("hH", eingabezeichen) = 0.{}  erfuelle fortschreibungswunsch:{}    INT CONST r :: pos (richtung, eingabezeichen){}    IF   r > 0{}         THEN IF hamster.form = r{}                 THEN vor{}                 ELSE hamster.form := r;{}                      zeige hamster{}              FI{}    ELIF eingabezeichen = "?" THEN boxinfo (fenster, landschaftsauskunftstext,{}
+                                                     5, maxint, a, b, c, d);{}                                   cursor on; zeige landschaft; informiere{}    ELIF eingabezeichen = "k" THEN kopiere landschaft;{}                                   zeige landschaft; informiere{}    ELIF eingabezeichen = "g" THEN gib{}    ELIF eingabezeichen = "n" THEN IF korn da THEN nimm ELSE out (piep) FI{}    ELIF eingabezeichen = "z" THEN zeige (text (kornzahl, 2)){}    ELIF eingabezeichen = hindernis{}         THEN  land [hamster.stelle.x] [hamster.stelle.y] := besetzt; vor{}
+    ELIF eingabezeichen = blank{}         THEN  land [hamster.stelle.x] [hamster.stelle.y] := frei;    vor{}    ELSE out (piep){}    FI.{}    kopiere landschaft:{}      TEXT VAR kopie;{}      IF NOT not empty (alle landschaften){}         THEN IF ist hamster{}                 THEN boxinfo (fenster, anwendungstext (196), 5, maxint){}                 ELSE boxinfo (fenster, anwendungstext (197), 5, maxint){}              FI{}         ELSE lasse original auswaehlen{}      FI.{}    lasse original auswaehlen:{}
+      IF ist hamster{}         THEN kopie := boxone (fenster, alle landschaften,{}                               anwendungstext (23), anwendungstext (24),{}                               FALSE){}         ELSE kopie := boxone (fenster, alle landschaften,{}                               anwendungstext (25), anwendungstext (26),{}                               FALSE){}      FI;{}      cursor on; hole landschaft (kopie).{}    alle landschaften:{}      ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix).{}
+    erfrage koernerzahl:{}      TEXT VAR eingabe; BOOL VAR ist ok; INT VAR zahl;{}      cursor (1,23); 79 TIMESOUT waagerecht;{}      REP{}        ist ok := TRUE;{}        IF ist hamster{}           THEN eingabe := boxanswer (fenster, anwendungstext (43),{}                                               text (hamster.koerner),{}                                               5, a, b, c, d){}           ELSE eingabe := boxanswer (fenster, anwendungstext (44),{}                                               text (hamster.koerner),{}
+                                               5, a, b, c, d){}        FI;{}        disable stop;{}        IF eingabe = "" THEN eingabe := "0" FI;{}        zahl := int (eingabe);{}        IF zahl < 0 OR zahl > maxint THEN ist ok := FALSE FI;{}        IF is error THEN ist ok := FALSE; clear error FI;{}        enable stop;{}      UNTIL last conversion ok AND ist ok PER;{}      cursor on;{}      hamster.koerner := zahl.{}    informiere:{}      cursor (1,1);{}      IF ist hamster{}         THEN out (anwendungstext (27)){}
+         ELSE out (anwendungstext (28)){}      FI{}END PROC modifiziere landschaft;{}PROC lauf (TEXT CONST dateiname):{}  initialize hamstersystem;{}  IF NOT exists (dateiname){}     THEN errorstop (anwendungstext (16) + dateiname + anwendungstext (17)){}  FI;{}  hamstermodus;{}  disable stop;{}  run (dateiname);{}  kommandomodus;{}  cursor (1, 24);{}  IF is error{}     THEN IF length (errormessage) > 1{}             THEN sage (errormessage); pause;{}          FI{}     ELSE sage (anwendungstext (29)); pause; konserviere landschaft{}
+  FI;{}  clear error;{}  enable stop{}END PROC lauf;{}PROC lauf:{}  lauf (last param){}END PROC lauf;{}PROC konserviere landschaft:{}  TEXT VAR neuer landschaftsname;{}  IF ist hamster{}     THEN stelle landschaftsfrage{}     ELSE stelle arbeitsfeldfrage{}  FI; cursor on.{}  stelle landschaftsfrage:{}    IF boxyes (fenster, anwendungstext (45), 5){}       THEN bewahre landschaft auf{}    FI.{}  stelle arbeitsfeldfrage:{}    IF boxyes (fenster, anwendungstext (46), 5){}       THEN bewahre landschaft auf{}
+    FI.{}  bewahre landschaft auf:{}    neuer landschaftsname := archivlandschaftsname + ".x";{}    lege landschaft ab (neuer landschaftsname);{}    gib hinweis auf neuen namen.{}  gib hinweis auf neuen namen:{}    IF ist hamster{}       THEN boxinfo (fenster, anwendungstext (30){}                     + inv (neuer landschaftsname), 5, maxint, a, b, c, d){}       ELSE boxinfo (fenster, anwendungstext (31){}                     + inv (neuer landschaftsname), 5, maxint, a, b, c, d){}    FI{}END PROC konserviere landschaft;{}
+PROC hamsterinter (TEXT CONST landschaftsname):{}  initialize hamstersystem;{}  sei ein hamster;{}  steuere interaktiv (landschaftsname);{}  cursor on{}END PROC hamsterinter;{}PROC hamsterinter:{}  initialize hamstersystem;{}  hamsterinter (erfragter landschaftsname (anwendungstext (39))){}END PROC hamsterinter;{}PROC roboterinter (TEXT CONST landschaftsname):{}  initialize hamstersystem;{}  sei ein roboter;{}  steuere interaktiv (landschaftsname);{}  cursor on{}END PROC roboterinter;{}PROC roboterinter:{}
+  initialize hamstersystem;{}  roboterinter (erfragter landschaftsname (anwendungstext (40))){}END PROC roboterinter;{}PROC steuere interaktiv (TEXT CONST landschaftsname):{}  forget (protokollname, quiet);{}  protokoll := sequential file (output, protokollname);{}  intermodus;{}  landschaft (landschaftsname);{}  TEXT VAR befehl :: niltext, letzter befehl :: niltext;{}  REP{}    arbeiten{}  PER.{}  arbeiten:{}    intermodus;{}    hole befehl;{}    fuehre befehl aus.{}  hole befehl:{}    TEXT VAR befehlszeichen;{}
+    TEXT CONST befehlskette :: "vlngpeVLNGPE";{}    INT VAR befehlsposition;{}    zeige (hamsterform);{}    cursor (1,24);{}    IF ist hamster{}       THEN out (cleol + anwendungstext (32) + letzter befehl){}       ELSE out (cleol + anwendungstext (33) + letzter befehl){}    FI;{}    cursor(24,24);{}    inchar (befehlszeichen);{}    befehlsposition := pos(befehlskette,befehlszeichen);{}    IF befehlsposition = 0{}       THEN out(piep);{}            LEAVE arbeiten{}    FI;{}    SELECT befehlsposition OF{}
+      CASE 1, 7: befehl := "vor";{}                           out("vor");{}                           letzter befehl := "vor"{}      CASE 2, 8: befehl := "links um";{}                           out("links um");{}                           letzter befehl := "links um"{}      CASE 3, 9: befehl := "nimm";{}                           out("nimm");{}                           letzter befehl := "nimm"{}      CASE 4,10: befehl := "gib";{}                           out("gib");{}                           letzter befehl := "gib"{}
+      CASE 5,11: out("protokoll");{}                 letzter befehl := "protokoll";{}                 FILE VAR p :: sequential file (modify,protokollname);{}                 headline(p, protokollname + "  (Verlassen: <ESC><q>)");{}                 cursor on; show(p); cursor off;{}                 zeige landschaft; befehl := "";{}                 output(protokoll);{}                 LEAVE arbeiten{}      CASE 6,12: out("ende"); kommandomodus; befehl := "";{}                 LEAVE steuere interaktiv{}
+    END SELECT.{}   hamsterform:{}     erscheinungsform SUB hamster.form.{}   fuehre befehl aus:{}     BOOL VAR korrekt;{}     disable stop;{}     do (befehl);{}     cursor (1,24);{}     korrekt := NOT is error;{}     IF is error{}        THEN IF errormessage > ""{}                THEN out (inv (text (errormessage, 65)) + piep);{}                     pause(30);{}             FI;{}             clear error{}     FI;{}     IF korrekt AND befehl <> ""{}        THEN protokolliere (befehl){}     FI;{}     enable stop;{}
+END PROC steuere interaktiv;{}PROC protokolliere (TEXT CONST befehl):{}  putline (protokoll, befehl + ";"){}END PROC protokolliere;{}PROC drucke landschaft (TEXT CONST landschaftsname):{}  initialize hamstersystem;{}  ROW max y TEXT VAR drucklandschaft;{}  BOUND LANDSCHAFT VAR al;{}  INT VAR i, hamsterx, hamstery;{}  TEXT VAR hamsterzeichen;{}  landschaftsdatei holen;{}  drucklandschaft erzeugen;{}  hamster in drucklandschaft einsetzen;{}  druckdatei erzeugen;{}  disable stop;{}  TEXT VAR datname := std;{}
+  do ("print (""druckdatei"")");{}  IF is error{}      THEN menuinfo (inv (errormessage));{}           clear error;{}  FI;{}  last param (datname);{}  enable stop;{}  druckdatei loeschen;{}  cursor on.{}  landschaftsdatei holen:{}    IF exists (praefix + landschaftsname) AND{}       (type (old (praefix + landschaftsname)) = flaechentype){}       THEN hole landschaft;{}       ELSE LEAVE drucke landschaft{}    FI.{}  hole landschaft:{}    al             := old (praefix + landschaftsname);{}    hamsterx       := al.xpos;{}
+    hamstery       := al.ypos;{}    hamsterzeichen := erscheinungsform SUB al.blickrichtung.{}  drucklandschaft erzeugen:{}    TEXT VAR zeile; INT VAR  x;{}    FOR i FROM 1 UPTO max y REP{}        zeile := "";{}        FOR x FROM 1 UPTO maxx REP{}            zeile erzeugen{}        PER;{}        drucklandschaft[i] :=  zeile{}    PER.{}  zeile erzeugen:{}    INT CONST zeichen :: al.flaeche [x] [i];{}    IF   zeichen = besetzt THEN zeile CAT hinderniszeichen{}    ELIF zeichen = frei    THEN zeile CAT " ."{}
+                           ELSE zeile CAT " o"{}    FI.{}  hamster in drucklandschaft einsetzen:{}    change (drucklandschaft [hamstery], hamsterx*2-1, hamsterx*2-1,{}            hamsterzeichen).{}  druckdatei erzeugen:{}    FILE VAR p::sequential file(output, "druckdatei");{}    INT VAR blankzahl;{}    line(p);{}    putline(p,"#type (""" + schrifttyp + """)#");{}    putline(p,"#start(" + text(xstart) + "," + text(ystart) + ")#");{}    putline(p,"#limit(20.8)#");{}    blankzahl := ( 80 - (8 + length (landschaftsname))) DIV 2;{}
+    putline(p, blankzahl * " " + praefix + landschaftsname + " ");{}    putline(p, "  ");{}    FOR i FROM 1 UPTO maxy REP{}      putline(p, drucklandschaft[i] + " "){}    PER.{}  druckdatei loeschen:{}    forget("druckdatei", quiet){}END PROC drucke landschaft;{}PROC drucke landschaft:{}  initialize hamstersystem;{}  IF ist hamster{}     THEN drucke landschaft (erfragter landschaftsname (anwendungstext (36))){}     ELSE drucke landschaft (erfragter landschaftsname (anwendungstext (37))){}  FI;{}  cursor on{}
+END PROC drucke landschaft;{}PROC druckereinstellung fuer flaechenausdruck:{}  initialize hamstersystem;{}  page;{}  IF ist hamster{}     THEN putline (center (invers (anwendungstext (71)))){}     ELSE putline (center (invers (anwendungstext (72)))){}  FI;{}  line (3);{}  put (anwendungstext (73));{}  editget (schrifttyp);{}  line (2);{}  schrifttyp := compress (schrifttyp);{}  putline (anwendungstext (74));{}  putline (anwendungstext (75)); line (2);{}  putline (anwendungstext (76) + text (xstart) + "," + text (ystart) +{}
+           anwendungstext (77)); line;{}  put (anwendungstext (78)); get (xstart); line;{}  put (anwendungstext (79)); get (ystart); line (2);{}  IF yes (anwendungstext (80) + hinderniszeichen + anwendungstext (81)){}     THEN line;{}          put (anwendungstext (82)); inchar (hinderniszeichen); line (2);{}          hinderniszeichen CAT hinderniszeichen;{}          IF hinderniszeichen = "##"{}             THEN hinderniszeichen := "\#\#"{}          FI{}  FI;{}  line;{}  put (anwendungstext (83)){}END PROC druckereinstellung fuer flaechenausdruck;{}
+PROC hamster druckerstart einstellen (REAL CONST xpos, ypos):{}  xstart := xpos; ystart := ypos{}END PROC hamster druckerstart einstellen;{}REAL PROC hamster drucker xstart:{}  xstart{}END PROC hamster drucker xstart;{}REAL PROC hamster drucker ystart:{}  ystart{}END PROC hamster drucker ystart;{}PROC hamster landschaftsschrifttyp einstellen (TEXT CONST typ):{}  schrifttyp := typ{}END PROC hamster landschaftsschrifttyp einstellen;{}TEXT PROC hamster landschaftsschrifttyp:{}  schrifttyp{}END PROC hamster landschaftsschrifttyp;{}
+PROC drucke arbeitsfeld (TEXT CONST arbeitsfeldname):{}  drucke landschaft (arbeitsfeldname){}END PROC drucke arbeitsfeld;{}PROC drucke arbeitsfeld:{}  drucke landschaft{}END PROC drucke arbeitsfeld;{}TEXT PROC taste:{}  eingabezeichen{}END PROC taste;{}TEXT PROC landschaftsauskunftstext:{}  initialize hamstersystem;{}  IF ist hamster{}     THEN anwendungstext (52){}     ELSE anwendungstext (53){}  FI{}END PROC landschaftsauskunftstext;{}TEXT PROC laufauskunftstext:{}  initialize hamstersystem;{}
+  anwendungstext (51){}END PROC  laufauskunftstext;{}TEXT PROC befehlsauskunftstext:{}  initialize hamstersystem;{}  IF ist hamster{}     THEN anwendungstext (54){}     ELSE anwendungstext (55){}  FI{}END PROC befehlsauskunftstext;{}TEXT PROC testauskunftstext 1:{}  initialize hamstersystem;{}  IF befehlssatz erweitert{}     THEN langer testauskunftstext{}     ELSE kurzer testauskunftstext{}  FI.{}  kurzer testauskunftstext:{}    IF ist hamster{}       THEN anwendungstext (56){}       ELSE anwendungstext (57){}
+    FI.{}  langer testauskunftstext:{}    IF ist hamster{}       THEN anwendungstext (58){}       ELSE anwendungstext (60){}    FI.{}END PROC testauskunftstext 1;{}TEXT PROC testauskunftstext 2:{}  initialize hamstersystem;{}  IF befehlssatz erweitert{}     THEN eintragung{}     ELSE niltext{}  FI.{}  eintragung:{}    IF ist hamster{}       THEN anwendungstext (59){}       ELSE anwendungstext (61){}    FI{}END PROC testauskunftstext 2;{}PROC befehlssatz erweitern (BOOL CONST status):{}  befehlssatz erweitert := status{}
+END PROC befehlssatz erweitern;{}BOOL PROC befehlssatz ist erweitert:{}  befehlssatz erweitert{}END PROC befehlssatz ist erweitert;{}END PACKET ls herbert und robbi 1;{}
+
diff --git a/hamster/ls-Herbert und Robbi 2 b/hamster/ls-Herbert und Robbi 2
new file mode 100644
index 0000000..7394932
--- /dev/null
+++ b/hamster/ls-Herbert und Robbi 2	
@@ -0,0 +1,31 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **               ls-Herbert und Robbi 2                ** 
+          **                                                     ** 
+          **                     Version 1.1                     ** 
+          **                                                     ** 
+          **                  (Stand: 30.03.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET ls herbert und robbi 2  DEFINES{}       rechts frei,{}       links frei,{}       hinten frei,{}       korn vorn,    werkstueck vorn,{}       korn links,   werkstueck links,{}       korn rechts,  werkstueck rechts,{}       korn hinten,  werkstueck hinten:{}BOOL PROC rechts frei:{}  rechts um;{}  IF vorn frei{}     THEN links um; TRUE{}     ELSE links um; FALSE{}  FI{}END PROC rechts frei;{}BOOL PROC links frei:{}  links um;{}  IF vorn frei{}     THEN rechts um; TRUE{}     ELSE rechts um; FALSE{}
+  FI{}END PROC links frei;{}BOOL PROC hinten frei:{}  kehrt;{}  IF vorn frei{}     THEN kehrt; TRUE{}     ELSE kehrt; FALSE{}  FI{}END PROC hinten frei;{}BOOL PROC korn vorn:{}  IF vorn frei{}     THEN untersuche feld vor dir{}     ELSE FALSE{}  FI.{}  untersuche feld vor dir:{}    vor;{}    IF korn da{}       THEN mache vorwaertsgehen rueckgaengig; TRUE{}       ELSE mache vorwaertsgehen rueckgaengig; FALSE{}    FI.{}  mache vorwaertsgehen rueckgaengig:{}    kehrt; vor; kehrt{}END PROC korn vorn;{}
+BOOL PROC korn links:{}  links um;{}  IF vorn frei{}     THEN untersuche feld links{}     ELSE rechts um; FALSE{}  FI.{}  untersuche feld links:{}    vor;{}    IF korn da{}       THEN mache linkswende rueckgaengig; TRUE{}       ELSE mache linkswende rueckgaengig; FALSE{}    FI.{}  mache linkswende rueckgaengig:{}    kehrt; vor; links um{}END PROC korn links;{}BOOL PROC korn rechts:{}  rechts um;{}  IF vorn frei{}     THEN untersuche feld rechts{}     ELSE links um; FALSE{}  FI.{}  untersuche feld rechts:{}
+    vor;{}    IF korn da{}       THEN mache rechtswende rueckgaengig; TRUE{}       ELSE mache rechtswende rueckgaengig; FALSE{}    FI.{}  mache rechtswende rueckgaengig:{}    kehrt; vor; rechts um{}END PROC korn rechts;{}BOOL PROC korn hinten:{}  kehrt;{}  IF vorn frei{}     THEN untersuche feld hinter dir{}     ELSE kehrt; FALSE{}  FI.{}  untersuche feld hinter dir:{}    vor;{}    IF korn da{}       THEN mache kehrtwende rueckgaengig; TRUE{}       ELSE mache kehrtwende rueckgaengig; FALSE{}    FI.{}
+  mache kehrtwende rueckgaengig:{}    kehrt; vor{}END PROC korn hinten;{}PROC kehrt:{}  links um; links um{}END PROC kehrt;{}PROC rechts um:{}  links um; links um; links um{}END PROC rechts um;{}BOOL PROC werkstueck vorn:{}  korn vorn{}END PROC werkstueck vorn;{}BOOL PROC werkstueck links:{}  korn links{}END PROC werkstueck links;{}BOOL PROC werkstueck rechts:{}  korn rechts{}END PROC werkstueck rechts;{}BOOL PROC werkstueck hinten:{}  korn hinten{}END PROC werkstueck hinten;{}END PACKET ls herbert und robbi 2;{}
+befehlssatz erweitern (TRUE){}
+
diff --git a/hamster/ls-Herbert und Robbi 3 b/hamster/ls-Herbert und Robbi 3
new file mode 100644
index 0000000..e5db408
--- /dev/null
+++ b/hamster/ls-Herbert und Robbi 3	
@@ -0,0 +1,84 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **               ls-Herbert und Robbi 3                ** 
+          **                                                     ** 
+          **                     Version 1.1                     ** 
+          **                                                     ** 
+          **                  (Stand: 30.03.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET ls herbert und robbi 3  DEFINES{}  hamsterbefehlsauskunft,{}  hamsterlaufauskunft,{}  hamsterlandschaftsauskunft,{}  hamsterlandschaft verzeichnis,{}  hamsterlandschaft neu erstellen,{}  hamsterlandschaft ansehen,{}  hamsterlandschaft drucken,{}  hamsterlandschaft kopieren,{}  hamsterlandschaft umbenennen,{}  hamsterlandschaft loeschen,{}  hamsterprogramm verzeichnis,{}  hamsterprogramm neu erstellen,{}  hamsterprogramm ansehen,{}  hamsterprogramm kopieren,{}  hamsterprogramm umbenennen,{}
+  hamsterprogramm loeschen,{}  hamsterprogramm drucken,{}  hamster laufen lassen,{}  hamsterinteraktiv laufen lassen,{}  hamster, roboter:{}LET  menukarte       = "ls-MENUKARTE:Herbert und Robbi",{}     praefix         = "Flaeche:",{}     flaechentype    =       1007,{}     niltext         =         "",{}     maxlaenge       =         60,{}     maxnamenslaenge =         50;{}TEXT VAR flaechenname :: "",{}         programmname :: "";{}INITFLAG VAR in this task :: FALSE;{}PROC initialize hamster:{}
+  IF NOT initialized (in this task){}     THEN flaechenname := "";{}          programmname := ""{}  FI{}END PROC initialize hamster;{}PROC hamster:{}  sei ein hamster;{}  initialize hamster;{}  install menu (menukarte);{}  handle  menu ("HAMSTER"){}END PROC hamster;{}PROC roboter:{}  sei ein roboter;{}  initialize  hamster;{}  install menu (menukarte);{}  handle  menu ("ROBOTER");{}END PROC roboter;{}PROC hamsterlaufauskunft:{}  menuinfo (laufauskunftstext){}END PROC hamsterlaufauskunft;{}PROC hamsterlandschaftsauskunft:{}
+  menuinfo (landschaftsauskunftstext){}END PROC hamsterlandschaftsauskunft;{}PROC hamsterbefehlsauskunft:{}  menuinfo (befehlsauskunftstext);{}  menuinfo (testauskunftstext 1);{}  IF testauskunftstext 2 <> ""{}     THEN menuinfo (testauskunftstext 2){}  FI{}END PROC hamsterbefehlsauskunft;{}PROC hamsterlandschaft verzeichnis:{}  THESAURUS VAR landschaften ::{}  ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{}  forget ("Interne Thesaurusdateiliste", quiet);{}  FILE VAR f :: sequential file (output, "Interne Thesaurusdateiliste");{}
+  f FILLBY landschaften;{}  headline (f, anwendungstext (204)); modify (f);{}  to line (f, 1); insert record (f); write record (f, kenntext);{}  to line (f, 2); insert record (f);{}  to line (f, 1); menuwindowshow (f);{}  forget ("Interne Thesaurusdateiliste", quiet);{}  regenerate menuscreen.{}  kenntext:{}    IF ist hamster THEN anwendungstext (121) ELSE anwendungstext (151) FI.{}END PROC hamsterlandschaft verzeichnis;{}PROC hamsterprogramm verzeichnis:{}  THESAURUS VAR programme :: ALL myself - infix namen (ALL myself, praefix, flaechentype);{}
+  forget ("Interne Thesaurusdateiliste", quiet);{}  FILE VAR f :: sequential file (output, "Interne Thesaurusdateiliste");{}  f FILLBY programme;{}  headline (f, anwendungstext (204)); modify (f);{}  to line (f, 1); insert record (f); write record (f, anwendungstext (181));{}  to line (f, 2); insert record (f);{}  to line (f, 1); menuwindowshow (f);{}  forget ("Interne Thesaurusdateiliste", quiet);{}  regenerate menuscreen{}END PROC hamsterprogramm verzeichnis;{}PROC hamsterlandschaft neu erstellen:{}
+  hole flaechenname;{}  kontrolliere den flaechennamen;{}  kommandomodus;{}  landschaft (flaechenname);{}  regenerate menuscreen.{}  hole flaechenname:{}    IF ist hamster{}       THEN flaechenname := menuanswer (anwendungstext (101) +{}                                        anwendungstext (102), "", 5){}       ELSE flaechenname := menuanswer (anwendungstext (131) +{}                                        anwendungstext (132), "", 5){}    FI.{}  kontrolliere den flaechennamen:{}    IF   flaechenname = niltext{}
+         THEN LEAVE hamsterlandschaft neu erstellen{}    ELIF length (flaechenname) > maxnamenslaenge{}         THEN meckere zu langen namen an;{}              flaechenname := niltext;{}              LEAVE hamsterlandschaft neu erstellen{}    ELIF exists (praefix + flaechenname){}         THEN meckere existierende flaeche an;{}              LEAVE hamsterlandschaft neu erstellen{}    FI{}END PROC hamsterlandschaft neu erstellen;{}PROC hamsterprogramm neu erstellen:{}  hole programmname;{}  kontrolliere den programmnamen;{}
+  command dialogue (FALSE);{}  cursor on;{}  stdinfoedit (programmname);{}  cursor off;{}  command dialogue (TRUE);{}  regenerate menuscreen.{}  hole programmname:{}    programmname := menuanswer (anwendungstext (161) +{}                                anwendungstext (162), "", 5).{}  kontrolliere den programmnamen:{}    IF   programmname = niltext{}         THEN LEAVE hamsterprogramm neu erstellen{}    ELIF length (programmname) > maxnamenslaenge{}         THEN meckere zu langen namen an;{}              programmname := niltext;{}
+              LEAVE hamsterprogramm neu erstellen{}    ELIF exists (programmname){}         THEN meckere existierendes programm an;{}              LEAVE hamsterprogramm neu erstellen{}    FI{}END PROC hamsterprogramm neu erstellen;{}PROC hamsterlandschaft ansehen:{}  IF flaechenname <> niltext CAND exists (praefix + flaechenname){}     THEN frage nach dieser flaeche{}     ELSE lasse flaeche auswaehlen{}  FI;{}  kommandomodus;{}  landschaft (flaechenname);{}  regenerate menuscreen.{}  frage nach dieser flaeche:{}
+    IF menuno (ueberschrift + text 1 + name + text 2, 5){}       THEN lasse flaeche auswaehlen{}    FI.{}  ueberschrift:{}    IF ist hamster{}       THEN center (maxlaenge, invers (anwendungstext (105))) + ""13""13""{}       ELSE center (maxlaenge, invers (anwendungstext (135))) + ""13""13""{}   FI.{}  text 1:{}    IF ist hamster THEN anwendungstext (103) ELSE anwendungstext (133) FI.{}  name:{}    ""13""13" " + invers (flaechenname) + ""13""13"".{}  text 2:{}    IF ist hamster THEN anwendungstext (104) ELSE anwendungstext (134) FI.{}
+  lasse flaeche auswaehlen:{}    THESAURUS VAR verfuegbare;{}    verfuegbare := ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{}    IF NOT not empty (verfuegbare){}       THEN noch keine flaeche;{}            LEAVE hamsterlandschaft ansehen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    IF ist hamster{}       THEN flaechenname := menuone (verfuegbare, anwendungstext (105),{}                                     anwendungstext (106), FALSE){}       ELSE flaechenname := menuone (verfuegbare, anwendungstext (135),{}
+                                     anwendungstext (136), FALSE){}    FI;{}    IF flaechenname = niltext{}       THEN regenerate menuscreen;{}            LEAVE hamsterlandschaft ansehen{}    FI.{}END PROC hamsterlandschaft ansehen;{}PROC hamsterprogramm ansehen:{}  IF programmname <> niltext CAND exists (programmname){}     THEN frage nach diesem programm{}     ELSE lasse programm auswaehlen{}  FI;{}  cursor on;{}  stdinfoedit (programmname);{}  cursor off;{}  regenerate menuscreen.{}  frage nach diesem programm:{}
+    IF menuno (ueberschrift + anwendungstext (163) + name{}                            + anwendungstext (164), 5){}       THEN lasse programm auswaehlen{}    FI.{}  ueberschrift:{}    center (maxlaenge, invers (anwendungstext (165))) + ""13""13"".{}  name:{}    ""13""13" " + invers (programmname) + ""13""13"".{}  lasse programm auswaehlen:{}    THESAURUS VAR verfuegbare;{}    verfuegbare  := ALL myself - infix namen (ALL myself, praefix, flaechentype);{}    IF NOT not empty (verfuegbare){}       THEN noch kein programm;{}
+            LEAVE hamsterprogramm ansehen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    programmname := menuone (verfuegbare, anwendungstext (165),{}                             anwendungstext (166), FALSE);{}    IF programmname = niltext{}       THEN regenerate menuscreen;{}            LEAVE hamsterprogramm ansehen{}    FI.{}END PROC hamsterprogramm ansehen;{}PROC hamsterlandschaft drucken:{}  lasse flaechen auswaehlen;{}  drucke flaechen;{}  regenerate menuscreen.{}  lasse flaechen auswaehlen:{}
+    THESAURUS VAR verfuegbare;{}    verfuegbare := ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{}    IF NOT not empty (verfuegbare){}       THEN noch keine flaeche;{}            LEAVE hamsterlandschaft drucken{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    IF ist hamster{}       THEN verfuegbare := menusome (verfuegbare, anwendungstext (107),{}                                     anwendungstext (108), FALSE){}       ELSE verfuegbare := menusome (verfuegbare, anwendungstext (137),{}
+                                     anwendungstext (138), FALSE){}    FI.{}  drucke flaechen:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers (bezeichnung)));{}    menuwindowline (2);{}    command dialogue (FALSE);{}    fuehre einzelne operationen aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (schlussbemerkung);{}    menuwindowstop.{}  bezeichnung:{}    IF ist hamster THEN anwendungstext (107) ELSE anwendungstext (137) FI.{}
+  schlussbemerkung:{}    IF ist hamster THEN anwendungstext (110) ELSE anwendungstext (140) FI.{}  fuehre einzelne operationen aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              menuwindowout ( " """ + name (verfuegbare, k) + """ "{}                                    + anwendungstext (201));{}              menuwindowline;{}              drucke landschaft (name (verfuegbare, k));{}              fehlerbehandlung{}
+      FI{}    PER.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}       THEN menuwindowline (2);{}            IF ist hamster{}               THEN menuwindowout (anwendungstext (109)){}               ELSE menuwindowout (anwendungstext (139)){}            FI;{}            menuwindowstop;{}            regenerate menuscreen;{}            LEAVE hamsterlandschaft drucken{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}
+       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            menuinfo  (invers (errormessage));{}            clear error; enable stop;{}            LEAVE hamsterlandschaft drucken{}    FI.{}END PROC hamsterlandschaft drucken;{}PROC hamsterprogramm drucken:{}  lasse programme auswaehlen;{}  drucke programme;{}  regenerate menuscreen.{}  lasse programme auswaehlen:{}    THESAURUS VAR verfuegbare;{}    verfuegbare := ALL myself - infix namen (ALL myself, praefix, flaechentype);{}
+    IF NOT not empty (verfuegbare){}       THEN noch kein programm;{}            LEAVE hamsterprogramm drucken{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    verfuegbare := menusome (verfuegbare, anwendungstext (167),{}                             anwendungstext (168), FALSE).{}  drucke programme:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers (anwendungstext (167))));{}    menuwindowline (2);{}    command dialogue (FALSE);{}
+    fuehre einzelne operationen aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (anwendungstext (170));{}    menuwindowstop.{}  fuehre einzelne operationen aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              menuwindowout ( " """ + name (verfuegbare, k) + """ "{}                                    + anwendungstext (201));{}              menuwindowline;{}
+              print (name (verfuegbare, k));{}              fehlerbehandlung{}      FI{}    PER.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}       THEN menuwindowline (2);{}            menuwindowout (anwendungstext (169));{}            menuwindowstop;{}            regenerate menuscreen;{}            LEAVE hamsterprogramm drucken{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}
+    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            menuinfo  (invers (errormessage));{}            clear error; enable stop;{}            LEAVE hamsterprogramm drucken{}    FI.{}END PROC hamsterprogramm drucken;{}PROC hamsterlandschaft kopieren:{}  ermittle alten flaechennamen;{}  erfrage neuen flaechennamen;{}  kopiere ggf die flaeche.{}  ermittle alten flaechennamen:{}    IF NOT not empty (bestand){}       THEN noch keine flaeche;{}            LEAVE hamsterlandschaft kopieren{}
+       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    TEXT VAR alter name := menuone ( bestand, text1, text2, TRUE);{}    IF alter name = niltext{}       THEN LEAVE hamsterlandschaft kopieren{}    FI.{}  bestand:{}    ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix).{}  text1:{}    IF ist hamster THEN anwendungstext (111) ELSE anwendungstext (141) FI.{}  text2:{}    IF ist hamster THEN anwendungstext (112) ELSE anwendungstext (142) FI.{}  erfrage neuen flaechennamen:{}
+    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}     ueberschrift + hinweis auf alt + bisheriger name + aufforderung.{}  ueberschrift:{}    IF ist hamster{}       THEN center (maxlaenge, invers (anwendungstext (111))) + ""13""13""{}       ELSE center (maxlaenge, invers (anwendungstext (141))) + ""13""13""{}    FI.{}  hinweis auf alt:{}    IF ist hamster THEN anwendungstext (113) ELSE anwendungstext (143) FI.{}  bisheriger name:{}    ""13""13" " + invers (alter name) + ""13""13"".{}
+  aufforderung:{}    anwendungstext (202).{}  kopiere ggf die flaeche:{}    IF   neuer name = niltext{}         THEN menuinfo (invers (anwendungstext (192)));{}              LEAVE hamsterlandschaft kopieren{}    ELIF exists (praefix + neuer name){}         THEN mache vorwurf;{}              LEAVE hamsterlandschaft kopieren{}       ELSE copy (praefix + alter name, praefix + neuer name){}    FI.{}  mache vorwurf:{}    IF ist hamster{}       THEN menuinfo (anwendungstext (193)){}       ELSE menuinfo (anwendungstext (194)){}
+    FI.{}END PROC hamsterlandschaft kopieren;{}PROC hamsterprogramm kopieren:{}  ermittle alten programmnamen;{}  erfrage neuen programmnamen;{}  kopiere ggf das programm.{}  ermittle alten programmnamen:{}    IF NOT not empty (bestand){}       THEN noch kein programm;{}            LEAVE hamsterprogramm kopieren{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    TEXT VAR alter name := menuone ( bestand, anwendungstext (171),{}                                     anwendungstext (172), TRUE);{}
+    IF alter name = niltext{}       THEN LEAVE hamsterprogramm kopieren{}    FI.{}  bestand:{}    ALL myself - infix namen (ALL myself, praefix, flaechentype).{}  erfrage neuen programmnamen:{}    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}     ueberschrift + anwendungstext (173) + bisheriger name{}                  + anwendungstext (202).{}  ueberschrift:{}    center (maxlaenge, invers (anwendungstext (171))) + ""13""13"".{}  bisheriger name:{}    ""13""13" " + invers (alter name) + ""13""13"".{}
+  kopiere ggf das programm:{}    IF   neuer name = niltext{}         THEN menuinfo (invers (anwendungstext (192)));{}              LEAVE hamsterprogramm kopieren{}    ELIF exists (neuer name){}         THEN mache vorwurf;{}              LEAVE hamsterprogramm kopieren{}       ELSE copy (alter name, neuer name){}    FI.{}  mache vorwurf:{}    menuinfo (anwendungstext (195)).{}END PROC hamsterprogramm kopieren;{}PROC hamsterlandschaft umbenennen:{}  ermittle alten flaechennamen;{}  erfrage neuen flaechennamen;{}
+  benenne ggf die flaeche um.{}  ermittle alten flaechennamen:{}    IF NOT not empty (bestand){}       THEN noch keine flaeche;{}            LEAVE hamsterlandschaft umbenennen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    TEXT VAR alter name := menuone ( bestand, text1, text2, TRUE);{}    IF alter name = niltext{}       THEN LEAVE hamsterlandschaft umbenennen{}    FI.{}  bestand:{}    ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix).{}  text1:{}    IF ist hamster THEN anwendungstext (114) ELSE anwendungstext (144) FI.{}
+  text2:{}    IF ist hamster THEN anwendungstext (115) ELSE anwendungstext (145) FI.{}  erfrage neuen flaechennamen:{}    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}     ueberschrift + hinweis auf alt + bisheriger name + aufforderung.{}  ueberschrift:{}    IF ist hamster{}       THEN center (maxlaenge, invers (anwendungstext (114))) + ""13""13""{}       ELSE center (maxlaenge, invers (anwendungstext (144))) + ""13""13""{}    FI.{}  hinweis auf alt:{}    IF ist hamster THEN anwendungstext (116) ELSE anwendungstext (146) FI.{}
+  bisheriger name:{}    ""13""13" " + invers (alter name) + ""13""13"".{}  aufforderung:{}    IF ist hamster THEN anwendungstext (117) ELSE anwendungstext (147) FI.{}  benenne ggf die flaeche um:{}    IF   neuer name = niltext{}         THEN menuinfo (invers (anwendungstext (192)));{}              LEAVE hamsterlandschaft umbenennen{}    ELIF exists (praefix + neuer name){}         THEN mache vorwurf;{}              LEAVE hamsterlandschaft umbenennen{}    ELSE rename (praefix + alter name, praefix + neuer name);{}
+         flaechenname := neuer name{}    FI.{}  mache vorwurf:{}    IF ist hamster{}       THEN menuinfo (anwendungstext (193)){}       ELSE menuinfo (anwendungstext (194)){}    FI.{}END PROC hamsterlandschaft umbenennen;{}PROC hamsterprogramm umbenennen:{}  ermittle alten programmnamen;{}  erfrage neuen programmnamen;{}  benenne ggf das programm um.{}  ermittle alten programmnamen:{}    IF NOT not empty (bestand){}       THEN noch kein programm;{}            LEAVE hamsterprogramm umbenennen{}       ELSE biete auswahl an{}
+    FI.{}  biete auswahl an:{}    TEXT VAR alter name := menuone ( bestand, anwendungstext (174),{}                                     anwendungstext (175), TRUE);{}    IF alter name = niltext{}       THEN LEAVE hamsterprogramm umbenennen{}    FI.{}  bestand:{}    ALL myself - infix namen (ALL myself, praefix, flaechentype).{}  erfrage neuen programmnamen:{}    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}     ueberschrift + anwendungstext (176) + bisheriger name{}                  + anwendungstext (177).{}
+  ueberschrift:{}    center (maxlaenge, invers (anwendungstext (174))) + ""13""13"".{}  bisheriger name:{}    ""13""13" " + invers (alter name) + ""13""13"".{}  benenne ggf das programm um:{}    IF   neuer name = niltext{}         THEN menuinfo (invers (anwendungstext (192)));{}              LEAVE hamsterprogramm umbenennen{}    ELIF exists (neuer name){}         THEN mache vorwurf;{}              LEAVE hamsterprogramm umbenennen{}       ELSE rename (alter name, neuer name);{}            programmname := neuer name{}
+    FI.{}  mache vorwurf:{}    menuinfo (anwendungstext (195)).{}END PROC hamsterprogramm umbenennen;{}PROC hamsterlandschaft loeschen:{}  lasse flaechen auswaehlen;{}  loesche flaechen;{}  regenerate menuscreen.{}  lasse flaechen auswaehlen:{}    THESAURUS VAR verfuegbare;{}    verfuegbare := ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{}    IF NOT not empty (verfuegbare){}       THEN noch keine flaeche;{}            LEAVE hamsterlandschaft loeschen{}       ELSE biete auswahl an{}
+    FI.{}  biete auswahl an:{}    IF ist hamster{}       THEN verfuegbare := menusome (verfuegbare, anwendungstext (118),{}                                     anwendungstext (119), FALSE){}       ELSE verfuegbare := menusome (verfuegbare, anwendungstext (148),{}                                     anwendungstext (149), FALSE){}    FI.{}  loesche flaechen:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers (bezeichnung)));{}    menuwindowline (2);{}
+    command dialogue (FALSE);{}    fuehre einzelne operationen aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (schlussbemerkung);{}    menuwindowstop.{}  bezeichnung:{}    IF ist hamster THEN anwendungstext (118) ELSE anwendungstext (148) FI.{}  schlussbemerkung:{}    IF ist hamster THEN anwendungstext (120) ELSE anwendungstext (150) FI.{}  fuehre einzelne operationen aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}      IF name (verfuegbare, k) <> ""{}
+         THEN disable stop;{}              IF menuwindowyes (" """ + name (verfuegbare, k) + """ "{}                                      + anwendungstext (203)){}                 THEN forget (praefix + name (verfuegbare, k), quiet){}              FI;{}              fehlerbehandlung{}      FI{}    PER;{}    flaechenname := "".{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}       THEN menuwindowline (2);{}            IF ist hamster{}               THEN menuwindowout (anwendungstext (109)){}
+               ELSE menuwindowout (anwendungstext (139)){}            FI;{}            menuwindowstop;{}            regenerate menuscreen;{}            LEAVE hamsterlandschaft loeschen{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            menuinfo  (invers (errormessage));{}            clear error; enable stop;{}
+            LEAVE hamsterlandschaft loeschen{}    FI.{}END PROC hamsterlandschaft loeschen;{}PROC hamsterprogramm loeschen:{}  lasse programme auswaehlen;{}  loesche programme;{}  regenerate menuscreen.{}  lasse programme auswaehlen:{}    THESAURUS VAR verfuegbare;{}    verfuegbare := ALL myself - infix namen (ALL myself, praefix, flaechentype);{}    IF NOT not empty (verfuegbare){}       THEN noch kein programm;{}            LEAVE hamsterprogramm loeschen{}       ELSE biete auswahl an{}    FI.{}
+  biete auswahl an:{}    verfuegbare := menusome (verfuegbare, anwendungstext (178),{}                             anwendungstext (179), FALSE).{}  loesche programme:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers (anwendungstext (178))));{}    menuwindowline (2);{}    command dialogue (FALSE);{}    fuehre einzelne operationen aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (anwendungstext (180));{}
+    menuwindowstop.{}  fuehre einzelne operationen aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              IF menuwindowyes (" """ + name (verfuegbare, k) + """ "{}                                      + anwendungstext (203)){}                 THEN forget (name (verfuegbare, k), quiet){}              FI;{}              fehlerbehandlung{}      FI{}    PER;{}    programmname := "".{}  steige ggf bei leerem thesaurus aus:{}
+    IF NOT not empty (verfuegbare){}       THEN menuwindowline (2);{}            menuwindowout (anwendungstext (169));{}            menuwindowstop;{}            regenerate menuscreen;{}            LEAVE hamsterprogramm loeschen{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            menuinfo  (invers (errormessage));{}
+            clear error; enable stop;{}            LEAVE hamsterprogramm loeschen{}    FI.{}END PROC hamsterprogramm loeschen;{}PROC hamsterinteraktiv laufen lassen:{}  frage nach neuer flaeche;{}  cursor on;{}  IF ist hamster{}     THEN hamsterinter (flaechenname){}     ELSE roboterinter (flaechenname){}  FI;{}  programmname := "PROTOKOLL";{}  cursor off;{}  regenerate menuscreen.{}  frage nach neuer flaeche:{}    IF menuyes (ueberschrift + fragetext, 5){}       THEN lasse flaeche auswaehlen{}       ELSE weise auf landschaftsgestaltung hin;{}
+            LEAVE hamsterinteraktiv laufen lassen{}    FI.{}  ueberschrift:{}    IF ist hamster{}       THEN center (laenge, invers (anwendungstext (122))) + ""13""13""{}       ELSE center (laenge, invers (anwendungstext (152))) + ""13""13""{}    FI.{}  fragetext:{}    IF ist hamster{}       THEN center (laenge, anwendungstext (123)){}       ELSE center (laenge, anwendungstext (153)){}    FI.{}  laenge:{}    IF ist hamster{}       THEN max (length (anwendungstext (122)),{}                 length (anwendungstext (123))) + 5{}
+       ELSE max (length (anwendungstext (152)),{}                 length (anwendungstext (153))) + 5{}    FI.{}  lasse flaeche auswaehlen:{}    THESAURUS VAR verfuegbare;{}    verfuegbare := ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{}    IF ist hamster{}       THEN flaechenname := menuone (verfuegbare, anwendungstext (122),{}                                     anwendungstext (106), FALSE){}       ELSE flaechenname := menuone (verfuegbare, anwendungstext (152),{}                                     anwendungstext (136), FALSE){}
+    FI;{}    IF flaechenname = niltext{}       THEN weise auf landschaftsgestaltung hin;{}            regenerate menuscreen;{}            LEAVE hamsterinteraktiv laufen lassen{}    FI.{}  weise auf landschaftsgestaltung hin:{}    WINDOW VAR mfenster := current menuwindow;{}    IF ist hamster{}       THEN boxinfo (mfenster, anwendungstext (124), 5, maxint){}       ELSE boxinfo (mfenster, anwendungstext (154), 5, maxint){}    FI.{}END PROC hamsterinteraktiv laufen lassen;{}PROC hamster laufen lassen:{}
+  programmname ermitteln;{}  BOOL VAR namen eingesetzt :: FALSE;{}  untersuche programmdatei auf flaechennamen;{}  page;{}  geschwindigkeit (5);{}  cursor on;{}  lauf (programmname);{}  cursor off;{}  IF namen eingesetzt{}     THEN entferne flaechennamen aus programmdatei{}  FI;{}  regenerate menuscreen.{}  programmname ermitteln:{}    IF programmname <> niltext CAND exists (programmname){}       THEN frage nach diesem programm{}       ELSE lasse programm auswaehlen{}    FI.{}  frage nach diesem programm:{}
+    IF menuno (ueberschrift + anwendungstext (163) + name + anwendungstext (164), 5){}       THEN lasse programm auswaehlen{}    FI.{}  ueberschrift:{}    IF ist hamster{}       THEN center (maxlaenge, invers (anwendungstext (125))) + ""13""13""{}       ELSE center (maxlaenge, invers (anwendungstext (155))) + ""13""13""{}    FI.{}  name:{}    ""13""13" " + invers (programmname) + ""13""13"".{}  lasse programm auswaehlen:{}    THESAURUS VAR verfuegbare;{}    verfuegbare  := ALL myself - infix namen (ALL myself, praefix, flaechentype);{}
+    IF ist hamster{}       THEN programmname := menuone (verfuegbare, anwendungstext (125),{}                                     anwendungstext (166), TRUE){}       ELSE programmname := menuone (verfuegbare, anwendungstext (155),{}                                     anwendungstext (166), TRUE){}    FI;{}    IF programmname = niltext{}       THEN LEAVE hamster laufen lassen{}    FI.{}  untersuche programmdatei auf flaechennamen:{}    FILE VAR a :: sequential file (modify, programmname);{}    TEXT VAR zeile;{}
+    to line (a, 1);{}    REP{}      read record (a, zeile);{}      zeile := compress (zeile);{}      IF NOT eof (a) THEN down (a) FI{}    UNTIL zeile <> "" OR eof (a) PER;{}    IF pos (zeile, "landschaft") = 0 AND pos (zeile, "arbeitsfeld") = 0{}       THEN ermittle flaechennamen;{}            setze flaechennamen in datei ein{}    FI.{}  ermittle flaechennamen:{}    IF flaechenname <> ""{}       THEN frage nach altem flaechennamen{}       ELSE lasse flaeche auswaehlen{}    FI.{}  frage nach altem flaechennamen:{}
+    IF ist hamster{}       THEN frage nach alter landschaft{}       ELSE frage nach altem arbeitsfeld{}    FI.{}  frage nach alter landschaft:{}    IF menuno (ueberschrift + anwendungstext (103){}                    + fname + anwendungstext (104), 5){}       THEN lasse flaeche auswaehlen{}    FI.{}  frage nach altem arbeitsfeld:{}    IF menuno (ueberschrift + anwendungstext (133){}                    + fname + anwendungstext (134), 5){}       THEN lasse flaeche auswaehlen{}    FI.{}  fname:{}    ""13""13" " + invers (flaechenname) + ""13""13"".{}
+  lasse flaeche auswaehlen:{}    verfuegbare := ohne praefix (infix namen (ALL myself, praefix, flaechentype), praefix);{}    IF ist hamster{}       THEN flaechenname := menuone (verfuegbare, anwendungstext (125),{}                                     anwendungstext (106), FALSE){}       ELSE flaechenname := menuone (verfuegbare, anwendungstext (155),{}                                     anwendungstext (136), FALSE){}    FI;{}    IF flaechenname = niltext{}       THEN regenerate menuscreen;{}            landschaftsfehler anzeigen;{}
+            LEAVE hamster laufen lassen{}    FI.{}  landschaftsfehler anzeigen:{}    IF ist hamster{}       THEN menuinfo (anwendungstext (124)){}       ELSE menuinfo (anwendungstext (154)){}    FI.{}  setze flaechennamen in datei ein:{}    to line (a, 1);{}    zeile := "landschaft (""" + flaechenname + """);";{}    insert record (a);{}    write record (a, zeile);{}    namen eingesetzt := TRUE.{}  entferne flaechennamen aus programmdatei:{}    FILE VAR b :: sequential file (modify, programmname);{}
+    to line (b, 1);{}    REP{}      read record (b, zeile);{}      IF pos (zeile, "landschaft") = 0 AND pos (zeile, "arbeitsfeld") = 0{}         THEN IF NOT eof (b) THEN down (b) FI{}      FI{}    UNTIL zeile <> "" OR eof (b) PER;{}    IF pos (zeile, "landschaft") > 0 OR pos (zeile, "arbeitsfeld") > 0{}       THEN delete record (b){}    FI{}END PROC hamster laufen lassen;{}PROC meckere zu langen namen an:{}  menuinfo (anwendungstext (191)){}END PROC meckere zu langen namen an;{}PROC meckere existierende flaeche an:{}
+  IF ist hamster{}     THEN menuinfo (anwendungstext (193)){}     ELSE menuinfo (anwendungstext (194)){}  FI{}END PROC meckere existierende flaeche an;{}PROC meckere existierendes programm an:{}  menuinfo (anwendungstext (195)){}END PROC meckere existierendes programm an;{}PROC noch keine flaeche:{}  IF ist hamster{}     THEN menuinfo (anwendungstext (196)){}     ELSE menuinfo (anwendungstext (197)){}  FI{}END PROC noch keine flaeche;{}PROC noch kein programm:{}  menuinfo (anwendungstext (198)){}
+END PROC noch kein programm;{}END PACKET ls herbert und robbi 3;{}
+
diff --git a/hamster/ls-Herbert und Robbi-gen b/hamster/ls-Herbert und Robbi-gen
new file mode 100644
index 0000000..ae21ddb
--- /dev/null
+++ b/hamster/ls-Herbert und Robbi-gen	
@@ -0,0 +1,33 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                 ls-Herbert und Robbi                ** 
+          **                  GENERATORPROGRAMM                  ** 
+          **                     Version 1.1                     ** 
+          **                                                     ** 
+          **                  (Stand: 30.03.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                          *) 
+ 
+LET mm taskname = "ls-MENUKARTEN",{}    datei1      = "ls-Herbert und Robbi 1",{}    datei2      = "ls-Herbert und Robbi 2",{}    datei3      = "ls-Herbert und Robbi 3",{}    menukarte   = "ls-MENUKARTE:Herbert und Robbi";{}PROC stelle existenz des mm sicher:{}  cursor (1, 5); out (""4"");{}  IF NOT exists (task (mm taskname)){}     THEN errorstop ("Unbedingt erst den 'MENUKARTEN MANAGER' generieren!");{}  FI{}END PROC stelle existenz des mm sicher;{}PROC vom archiv (TEXT CONST datei):{}  cursor (1,5); out (""4"");{}
+  out ("  """); out (datei); putline (""" wird geholt.");{}  fetch (datei, archive){}END PROC vom archiv;{}PROC hole (TEXT CONST datei):{}  IF NOT exists (datei) THEN vom archiv (datei) FI{}END PROC hole;{}PROC in (TEXT CONST datei):{}  hole (datei);{}  cursor (1, 5); out (""4"");{}  out ("  """); out (datei); out (""" wird übersetzt: ");{}  insert (datei);{}  forget (datei, quiet);{}END PROC in;{}PROC schicke (TEXT CONST datei):{}  cursor (1, 5); out (""4"");{}  out ("  """); out(datei);{}  out (""" wird zum MENUKARTEN-MANAGER geschickt!");{}
+  command dialogue (FALSE);{}  save (datei, task (mm taskname));{}  command dialogue (TRUE);{}  forget (datei, quiet){}END PROC schicke;{}INT VAR size, used;{}BOOL VAR einzeln, mit erweiterung :: FALSE;{}storage (size, used);{}einzeln := size - used < 500;{}forget ("ls-Herbert und Robbi/gen", quiet);{}wirf kopfzeile aus;{}stelle existenz des mm sicher;{}hole die dateien;{}insertiere die dateien;{}mache global manager aus der task.{}wirf kopfzeile aus:{}  page;{}  putline ("              "15"ls-Herbert und Robbi - Automatische Generierung "14"");{}
+  line (2);{}  putline ("  Bitte beantworten Sie noch die folgende Frage:");{}  line;{}  put("  Sollen neben den 'Standardtests' auch die folgenden 'Tests':");{}  line (2);{}  putline("          Für den Hamster:                   Für den Roboter:");{}  putline("           links frei                         links frei");{}  putline("           rechts frei                        rechts frei");{}  putline("           hinten frei                        hinten frei");{}  putline("           korn vorn                          werkstueck vorn");{}
+  putline("           korn links                         werkstueck links");{}  putline("           korn rechts                        werkstueck rechts");{}  putline("           korn hinten                        werkstueck hinten");{}  line;{}  IF yes("  zur Verfügung gestellt werden"){}     THEN mit erweiterung := TRUE{}  FI.{}hole die dateien:{}  IF     NOT exists (datei 1){}     COR NOT exists (datei 3){}     COR NOT exists (menukarte){}     THEN hole dateien vom archiv; LEAVE hole die dateien{}
+  FI;{}  IF mit erweiterung AND NOT exists (datei 2){}     THEN hole dateien vom archiv{}  FI.{}hole dateien vom archiv:{}  cursor (1,3); out (""4"");{}  IF yes ("Ist das Archiv angemeldet und die Diskette eingelegt"){}     THEN lese ein{}     ELSE line (2);{}          errorstop ("Ohne die Diskette kann ich das System nicht generieren!"){}  FI.{}lese ein:{}  cursor (1, 3); out (""4"");{}  out ("                   "15"Bitte die Diskette eingelegt lassen! "14"");{}  IF NOT einzeln{}     THEN  hole (datei 1);{}
+           hole (datei 3);{}           hole (menukarte);{}           IF mit erweiterung{}              THEN hole (datei 2){}           FI;{}           cursor (1, 3); out(""4"");{}           out ("                  "15"Die Diskette wird nicht mehr benötigt! "14"");{}           release (archive){}  FI.{}insertiere die dateien:{}  check off;{}  cursor (1, 3); out(""4"");{}  out ("                  "15"Die Diskette wird nicht mehr benötigt! "14"");{}  in (datei 1);{}  IF mit erweiterung{}     THEN in (datei 2){}
+  FI;{}  in (datei 3);{}  schicke (menukarte);{}  IF einzeln THEN release (archive) FI;{}  check on.{}mache global manager aus der task:{}  global manager.{}
+
diff --git a/hamster/ls-MENUKARTE:Herbert und Robbi b/hamster/ls-MENUKARTE:Herbert und Robbi
new file mode 100644
index 0000000..2e9629c
Binary files /dev/null and b/hamster/ls-MENUKARTE:Herbert und Robbi differ
diff --git a/lisp/lisp.1 b/lisp/lisp.1
new file mode 100644
index 0000000..32a9c27
--- /dev/null
+++ b/lisp/lisp.1
@@ -0,0 +1,1306 @@
+PACKET lisp heap and oblist management              (* Autor: J.Durchholz *) 
+                                                    (* Datum: 09.05.1984  *) 
+    DEFINES                                         (* Version 1.7.2      *) 
+                                                    (* hey 25.2.83 *) 
+  initialize lisp system, 
+  dump lisp heap, 
+  lisp storage, 
+  collect lisp heap garbage, 
+  SYM, 
+  :=, 
+  nil, 
+  pname, 
+  head, 
+  set head, 
+  tail, 
+  set tail, 
+  cons, 
+  eq, 
+  equal, 
+  null, 
+  atom, 
+  is named atom, 
+  begin oblist dump, 
+  next atom, 
+  new atom, 
+  create atom, 
+  delete atom, 
+  begin property list dump, 
+  next property, 
+  add property, 
+  alter property, 
+  property, 
+  delete property, 
+  property exists, 
+  add flag, 
+  flag, 
+  delete flag, 
+  text, 
+  is text, 
+  character, 
+  is character, 
+  sym character, 
+  int 1, 
+  int 2, 
+  is int pair, 
+  sym: 
+ 
+ 
+(* NOTE: All internal routines are prefixed by x *) 
+ 
+ 
+(***************************** heap management ****************************) 
+ 
+LET 
+    max size = 32767, 
+    NODE = STRUCT (INT status, 
+                       head, tail); 
+LET HEAP = STRUCT (INT size, 
+                   ROW max size NODE node); 
+ 
+ 
+BOUND HEAP VAR heap; 
+ 
+ 
+PROC initialize lisp system (DATASPACE CONST ds): 
+  IF type (ds) < 0 THEN 
+    heap := ds; 
+    x initialize oblist and heap size; 
+    create atom ("NIL"); 
+    create atom ("PNAME"); 
+  ELSE 
+    heap := ds 
+  FI 
+END PROC initialize lisp system; 
+ 
+ 
+PROC dump lisp heap (FILE VAR f): 
+  put line (f, "Groesse :" + text (CONCR (heap).size)); 
+  line (f); 
+  put (CONCR (heap).size); 
+  BOOL VAR is char := FALSE; 
+  INT VAR i; 
+  FOR i FROM 1 UPTO CONCR (heap).size REP 
+    cout (i); 
+    dump ith node 
+  PER. 
+ 
+dump ith node: 
+  put (f, text (i, 6)); 
+  put (f, status); 
+  put (f, head); 
+  put (f, tail); 
+  line (f). 
+ 
+status: 
+  SELECT ith node.status OF 
+    CASE atomic             : "ATOMIC............" 
+    CASE non atomic         : "NON ATOMIC........" 
+    CASE oblist bone        : "OBLIST BONE......." 
+    CASE property indicator : "PROPERTY INDICATOR" 
+    CASE property root      : "PROPERTY ROOT....." 
+    CASE flag indicator     : "FLAG INDICATOR...." 
+    CASE text data          : "TEXT DATA........." 
+    CASE character data     : is char := TRUE; "CHARACTER DATA...." 
+    CASE int data           : "INT DATA.........." 
+    OTHERWISE                 "????." + text (ith node.status, 6) + ".????" 
+  END SELECT. 
+ 
+head: 
+  maybe a code + text (ith node.head, 6). 
+ 
+maybe a code: 
+  IF is char THEN 
+    is char := FALSE; 
+    IF ith node.head > 31 AND 128 > ith node.head THEN 
+      " " + code (ith node.head) + " " 
+    ELSE 
+      "   " 
+    FI 
+  ELSE 
+    "   " 
+  FI. 
+ 
+tail: 
+  text (ith node.tail, 6). 
+ 
+ith node: 
+  CONCR (heap).node (i). 
+ 
+END PROC dump lisp heap; 
+ 
+ 
+PROC lisp storage (INT VAR size, used): 
+  size := max size; 
+  used := CONCR (heap).size 
+END PROC lisp storage; 
+ 
+ 
+PROC collect lisp heap garbage: 
+  mark all used nodes; 
+  transfer all used high address nodes to unused low address nodes; 
+  adjust all pointers to cleared high address area and unmark all nodes; 
+  adjust size. 
+ 
+mark all used nodes: 
+  INT VAR i; 
+  FOR i FROM 2 UPTO 28 REP 
+    x mark (i) 
+  PER. 
+ 
+transfer all used high address nodes to unused low address nodes: 
+  INT VAR high address :: CONCR (heap).size + 1, 
+          low address :: 0; 
+  REP 
+    find next lower used high address node; 
+    IF no used high address node found THEN 
+      LEAVE transfer all used high address nodes to unused low address nodes 
+    FI; 
+    find next higher unused low address node; 
+    IF no unused low address node found THEN 
+      LEAVE transfer all used high address nodes to unused low address nodes 
+    FI; 
+    transfer high address node to low address node 
+  PER. 
+ 
+find next lower used high address node: 
+  REP 
+    high address DECR 1 
+  UNTIL high address node marked PER. 
+ 
+high address node marked: 
+  high address node.status < 0. 
+ 
+no used high address node found: 
+  low address = high address. 
+ 
+find next higher unused low address node: 
+  REP 
+    low address INCR 1 
+  UNTIL low address node not marked OR low address = high address PER. 
+ 
+low address node not marked: 
+  low address node.status > 0. 
+ 
+no unused low address node found : 
+  low address = high address. 
+ 
+transfer high address node to low address node: 
+  low address node.status := high address node.status; 
+  low address node.head := high address node.head; 
+  low address node.tail := high address node.tail; 
+  high address node.head := low address. 
+ 
+adjust all pointers to cleared high address area and unmark all nodes: 
+  (* 'high address' should now point to the last node of the used area   *) 
+  FOR low address FROM 1 UPTO high address REP 
+    unmark low address node; 
+    SELECT low address node.status OF 
+      CASE oblist bone: adjust head
+      CASE atomic, 
+           non atomic, 
+           property indicator, 
+           property root, 
+           flag indicator: adjust head; adjust tail 
+      CASE text data, character data: adjust tail 
+      CASE int data: 
+      OTHERWISE x lisp error ("Status " + text (low address node.status) + 
+                              " gefunden bei pointer Justage") 
+    END SELECT 
+  PER. 
+ 
+unmark low address node: 
+  low address node.status := - low address node.status. 
+ 
+adjust head: 
+  IF low address node.head > high address THEN 
+    low address node.head := node (low address node.head).head 
+  FI. 
+ 
+adjust tail: 
+  IF low address node.tail > high address THEN 
+    low address node.tail := node (low address node.tail).head 
+  FI. 
+ 
+adjust size: 
+  CONCR (heap).size := high address. 
+ 
+low address node: 
+  node (low address). 
+ 
+high address node: 
+  node (high address). 
+ 
+node: 
+  CONCR (heap).node. 
+ 
+END PROC collect lisp heap garbage; 
+ 
+ 
+PROC x mark (INT CONST ptr): 
+  IF node not yet marked THEN 
+    mark node; 
+    SELECT - ptr node.status OF 
+      CASE oblist bone: x mark (ptr node.head) 
+      CASE atomic, 
+           non atomic, 
+           property indicator, 
+           property root, 
+           flag indicator: x mark (ptr node.head); x mark (ptr node.tail) 
+      CASE text data, character data: x mark (ptr node.tail) 
+      CASE int data: 
+      OTHERWISE error stop ("Status " + text (- ptr node.status) + 
+                            " gefunden beim Markieren") 
+    END SELECT 
+  FI. 
+ 
+ 
+node not yet marked: 
+  ptr node.status > 0. 
+ 
+mark node: 
+  ptr node.status := - ptr node.status. 
+ 
+ptr node: 
+  CONCR (heap).node (ptr) 
+ 
+END PROC x mark; 
+ 
+ 
+TYPE SYM = INT; 
+ 
+ 
+OP := (SYM VAR left, SYM CONST right): 
+  CONCR (left) := CONCR (right) 
+END OP :=; 
+ 
+ 
+LET atomic = 1, 
+    non atomic = 2, 
+    oblist bone = 3, 
+    property indicator = 4, 
+    property root = 5, 
+    flag indicator = 6, 
+    text data = 7, 
+    character data = 8, 
+    int data = 9; 
+ 
+SYM CONST nil :: SYM :(35),   (* 'x initialize oblist and heap size' will *) 
+          pname :: SYM :(44); (* place the atom NIL at node 35 and PNAME  *) 
+                              (* at node 44                               *) 
+ 
+ 
+(***************************** basic functions ****************************) 
+ 
+ 
+SYM PROC head (SYM CONST sym): 
+  SELECT status of sym OF 
+    CASE atomic: error stop ("Atome haben keinen head"); nil 
+    CASE non atomic: SYM :(head of sym) 
+    CASE oblist bone, 
+         property indicator, 
+         property root, 
+         flag indicator    : x lisp error ("Versteckter Knoten, Type:" + 
+                                         text (status of sym)); 
+                             nil 
+    CASE text data, 
+         character data, 
+         int data       : error stop ("Daten haben keinen head"); nil 
+    OTHERWISE x lisp error ("Illegaler Status " + text (status of sym));
+              nil 
+  END SELECT. 
+ 
+status of sym: 
+  sym node.status. 
+ 
+head of sym: 
+  sym node.head. 
+ 
+sym node: 
+  CONCR (heap).node (CONCR (sym)) 
+ 
+END PROC head; 
+ 
+ 
+SYM PROC x head (SYM CONST sym): 
+  SYM :(CONCR (heap).node (CONCR (sym)).head) 
+END PROC x head; 
+ 
+ 
+PROC set head (SYM CONST sym, new head): 
+  SELECT status of sym OF 
+    CASE atomic: errorstop ("Atome haben keinen head") 
+    CASE non atomic: head of sym := CONCR (new head) 
+    CASE oblist bone, 
+         property indicator, 
+         property root, 
+         flag indicator    : x lisp error ("Versteckter Knoten, Type:" + 
+                                         text (status of sym)) 
+    CASE text data, 
+         character data, 
+         int data        : error stop ("Daten haben keinen head") 
+    OTHERWISE x lisp error ("Illegaler Status " + text (status of sym))
+  END SELECT. 
+ 
+status of sym: 
+  sym node.status. 
+ 
+head of sym: 
+  sym node.head. 
+ 
+sym node: 
+  CONCR (heap).node (CONCR (sym)). 
+ 
+END PROC set head; 
+ 
+ 
+PROC x set head (SYM CONST sym, new head): 
+  CONCR (heap).node (CONCR (sym)).head := CONCR (new head) 
+END PROC x set head; 
+ 
+ 
+SYM PROC tail (SYM CONST sym): 
+  SELECT status of sym OF 
+    CASE atomic: error stop ("Atome haben keinen tail"); nil 
+    CASE non atomic: SYM :(tail of sym) 
+    CASE oblist bone, 
+         property indicator, 
+         flag indicator    : x lisp error ("Versteckter Knoten:" + 
+                                         text (status of sym)); 
+                             nil 
+    CASE text data, 
+         character data, 
+         int data        : error stop ("Daten haben keinen tail"); nil 
+    OTHERWISE x lisp error ("Illegaler Status: "+ text (status of sym)); 
+              nil 
+  END SELECT. 
+ 
+status of sym: 
+  sym node.status. 
+ 
+tail of sym: 
+  sym node.tail. 
+ 
+sym node: 
+  CONCR (heap).node (CONCR (sym)). 
+ 
+END PROC tail; 
+ 
+ 
+SYM PROC x tail (SYM CONST sym): 
+  SYM :(CONCR (heap).node (CONCR (sym)).tail) 
+END PROC x tail; 
+ 
+ 
+PROC set tail (SYM CONST sym, new tail): 
+  SELECT status of sym OF 
+    CASE atomic: error stop ("Atome haben keinen tail") 
+    CASE non atomic: tail of sym := CONCR (new tail) 
+    CASE oblist bone, 
+         property indicator, 
+         property root, 
+         flag indicator    : x lisp error ("Versteckter Knoten, Type: " + 
+                                         text (status of sym)) 
+    CASE text data, 
+         character data, 
+         int data       : error stop ("Daten tails sind unveraenderbar")
+    OTHERWISE x lisp error ("Illegaler Status: " + text (status of sym)) 
+  END SELECT. 
+ 
+status of sym: 
+  sym node.status. 
+ 
+tail of sym: 
+  sym node.tail. 
+ 
+sym node: 
+  CONCR (heap).node (CONCR (sym)). 
+ 
+END PROC set tail; 
+ 
+ 
+PROC x set tail (SYM CONST sym, new tail): 
+  CONCR (heap).node (CONCR (sym)).tail := CONCR (new tail) 
+END PROC x set tail; 
+ 
+ 
+SYM PROC cons (SYM CONST head, tail): 
+  SYM VAR result; 
+  search free node; 
+  result node.status := non atomic; 
+  result node.head := CONCR (head); 
+  result node.tail := CONCR (tail); 
+  result. 
+ 
+search free node: 
+  IF CONCR (heap).size = max size THEN 
+    error stop ("LISP Heap Ueberlauf"); 
+    LEAVE cons WITH nil 
+  ELSE 
+    CONCR (heap).size INCR 1; 
+    CONCR (result) := CONCR (heap).size; cout(CONCR(result))
+  FI. 
+ 
+result node: 
+  CONCR (heap).node (CONCR (result)). 
+ 
+END PROC cons; 
+ 
+ 
+BOOL PROC eq (SYM CONST sym 1, sym 2): 
+  CONCR (sym 1) = CONCR (sym 2) 
+END PROC eq; 
+ 
+ 
+BOOL PROC equal (SYM CONST sym 1, sym 2): 
+  eq (sym 1, sym 2) COR have same value. 
+ 
+have same value: 
+  IF sym 1 node.status <> sym 2 node.status THEN 
+    FALSE 
+  ELSE 
+    SELECT sym 1 node.status OF 
+      CASE atomic: FALSE 
+      CASE non atomic: equal (head (sym 1), head (sym 2)) CAND 
+                       equal (tail (sym 1), tail (sym 2)) 
+      CASE oblist bone, 
+           property indicator, 
+           property root, 
+           flag indicator: x lisp error ("Versteckter Knoten, Type: " + 
+                                         text (x status (sym 1))); FALSE 
+      CASE text data: equal texts 
+      CASE character data: sym 1 node.head = sym 2 node.head 
+      CASE int data: sym 1 node.head = sym 2 node.head AND 
+                     sym 1 node.tail = sym 2 node.tail 
+      OTHERWISE x lisp error ("Ilegaler Status " + text (x status (sym 1)));
+                              FALSE 
+    END SELECT 
+  FI. 
+ 
+equal texts: 
+  equal length CAND equal character sequence. 
+ 
+equal length: 
+  eq (x head (sym 1), x head (sym 2)). 
+ 
+equal character sequence: 
+  SYM VAR actual sym 1 character :: sym 1, 
+          actual sym 2 character :: sym 2; 
+  INT VAR i; 
+  FOR i FROM 1 UPTO sym 1 node. head REP 
+    actual sym 1 character := x tail (actual sym 1 character); 
+    actual sym 2 character := x tail (actual sym 2 character); 
+    IF eq (actual sym 1 character, actual sym 2 character) THEN 
+      LEAVE equal character sequence WITH TRUE 
+    FI; 
+    IF x status (actual sym 1 character) <> character data OR 
+       x status (actual sym 2 character) <> character data    THEN 
+      x lisp error ("Ungueltiges Zeichen im text"); 
+      LEAVE equal character sequence WITH FALSE 
+    FI; 
+    IF CONCR (x head (actual sym 1 character)) <> 
+       CONCR (x head (actual sym 2 character))    THEN 
+      LEAVE equal character sequence WITH FALSE 
+    FI 
+  PER; 
+  TRUE. 
+ 
+sym 1 node: 
+  CONCR (heap).node (CONCR (sym 1)). 
+ 
+sym 2 node: 
+  CONCR (heap).node (CONCR (sym 2)). 
+ 
+END PROC equal; 
+ 
+ 
+BOOL PROC null (SYM CONST sym): 
+  CONCR (sym) = CONCR (nil) 
+END PROC null; 
+ 
+ 
+BOOL PROC atom (SYM CONST sym): 
+  SELECT x status (sym) OF 
+    CASE atomic, 
+         text data, 
+         character data, 
+         int data:       TRUE 
+    CASE non atomic: FALSE 
+    CASE oblist bone, 
+         property indicator, 
+         property root, 
+         flag indicator    : x lisp error ("Versteckter Knoten, Type:" + 
+                                         text (x status (sym))); TRUE 
+    OTHERWISE x lisp error ("Illegaler Status " + 
+                             text (x status (sym))); TRUE
+  END SELECT 
+END PROC atom; 
+ 
+ 
+BOOL PROC is named atom (SYM CONST sym): 
+  x status (sym) = atomic 
+END PROC is named atom; 
+ 
+ 
+(*------------------- internal heap management routines ------------------*) 
+ 
+ 
+SYM PROC x new node (INT CONST status, head, tail): 
+  IF CONCR (heap).size = max size THEN 
+    error stop ("LISP Heap Ueberlauf"); nil 
+  ELSE 
+    CONCR (heap).size INCR 1; 
+    new node.status := status; 
+    new node.head := head; 
+    new node.tail := tail; 
+    SYM :(CONCR (heap).size) 
+  FI. 
+ 
+new node: 
+  node (CONCR (heap).size). 
+ 
+node: 
+  CONCR (heap).node. 
+ 
+END PROC x new node; 
+ 
+ 
+INT PROC x status (SYM CONST sym): 
+  CONCR (heap).node (CONCR (sym)).status 
+END PROC x status; 
+ 
+ 
+(**************************** oblist management ***************************) 
+ 
+ 
+(* Oblist organization: 
+ 
+(NOTE: 
+ 
+                                 +-----------------+ 
+                                 l     <status>    l 
+ All nodes are represented as    +--------+--------+    in all comments 
+                                 l <head> l <tail> l    of this packet. 
+                                 +--------+--------+ 
+ 
+END OF NOTE) 
+ 
+ 
+The 'oblist' (object list) is organized as follows: 
+ 
+  +-------------+ 
+  l oblist bone l 
+  +------+------+  +--> list of all atoms whose print names begin with "§" 
+  l   o  l XXXX l  l 
+  +---+--+------+  l 
+      +------------+ 
+  +-------------+ 
+  l oblist bone l 
+  +------+------+  +--> list of all atoms whose print names begin with "A" 
+  l   o  l XXXX l  l 
+  +---+--+------+  l 
+      +------------+ 
+            . 
+            . 
+            . 
+ 
+  +-------------+ 
+  l oblist bone l 
+  +------+------+  +--> list of all atoms whose print names begin with "Z" 
+  l   o  l XXXX l  l 
+  +---+--+------+  l 
+      +------------+ 
+ 
+ 
+These nodes with status 'oblist bone' form the oblist skeleton. As long as
+the lisp heap exists, they are stored contiguously in nodes 2 - 28; they
+cannot be changed directly by the user. This way of storing the oblist
+skeleton allows a hashing scheme to be applied when searching for an atom
+with a given name. The hash width of 27 is the smallest one thas distributes
+all atoms according to their character; with a smaller hash size, two or
+more lists would be merged, with the effect that some of the atom lists
+would contain atoms beginning with different characters.
+ 
+ 
+The list of all atoms whose print names begin with a certain character
+is organized as follows: 
+ 
+  +-------------+ 
+  l    atomic   l 
+  +------+------+ 
+  l   o  l  o---+--> property list of first atom 
+  +---+--+------+ 
+      l 
+      V 
+  +-------------+ 
+  l    atomic   l 
+  +------+------+ 
+  l   o  l  o---+--> property list of 2nd atom 
+  +---+--+------+ 
+      l 
+      V 
+      . 
+      . 
+      . 
+ 
+      l 
+      V 
+  +-------------+ 
+  l    atomic   l 
+  +------+------+ 
+  l   o  l  o---+--> property list of last atom 
+  +---+--+------+ 
+      l 
+      V 
+    oblist bone where the atom list began 
+ 
+ 
+These lists cannot be acessed directly by the user, too. 
+*) 
+ 
+ 
+ 
+PROC x initialize oblist and heap size: 
+  node (1).status := text data; 
+  node (1).head := 32 (* blank *); 
+  node (1).tail := 1; 
+  INT VAR i; 
+  FOR i FROM 2 UPTO 28 REP 
+    node (i).status := oblist bone; 
+    node (i).head := i 
+  PER; 
+  CONCR (heap).size := 28. 
+ 
+node: 
+  CONCR (heap).node. 
+ 
+END PROC x initialize oblist and heap size; 
+ 
+ 
+(*++++++++++++++++++++++++++++++ oblist dump +++++++++++++++++++++++++++++*) 
+ 
+ 
+SYM VAR actual oblist bone :: SYM :(0), 
+        actual atom :: SYM :(0); 
+ 
+ 
+PROC begin oblist dump: 
+  actual oblist bone := SYM :(2); 
+  actual atom := SYM :(2) 
+END PROC begin oblist dump; 
+ 
+ 
+SYM PROC next atom: 
+  actual atom := x head (actual atom); 
+  WHILE no more atoms in this atom list REP 
+    try next oblist bone 
+  PER; 
+  actual atom. 
+ 
+no more atoms in this atom list: 
+  (* NIL is given as last atom when 'next atom' is called repeatedly, so *) 
+  (* it can serve as a terminator. So NIL "does not count" if it is      *) 
+  (* encountered during one of the calls.                                *) 
+  IF null (actual atom) THEN 
+    actual atom := x head (actual atom) 
+  FI; 
+  eq (actual atom, actual oblist bone). 
+ 
+try next oblist bone: 
+  IF actual oblist bone is last oblist bone THEN 
+    actual atom := SYM :(2); 
+    LEAVE next atom WITH nil 
+  FI; 
+  CONCR (actual oblist bone) INCR 1; 
+  actual atom := x head (actual oblist bone). 
+ 
+actual oblist bone is last oblist bone: 
+  CONCR (actual oblist bone) = 28. 
+ 
+END PROC next atom; 
+ 
+ 
+(*+++++++++++++++++++++++ atom search and creation +++++++++++++++++++++++*) 
+ 
+ 
+SYM VAR predecessor, result; 
+  (* Variables used for communication between the internal search        *) 
+  (* procedures and the procedures calling them.                         *) 
+ 
+ 
+SYM PROC atom (TEXT CONST name): 
+  x search atom (name); 
+  IF atom not already existing THEN 
+    nil 
+  ELSE 
+    result 
+  FI. 
+ 
+atom not already existing: 
+  x status (result) = oblist bone. 
+ 
+END PROC atom; 
+ 
+ 
+SYM PROC new atom (TEXT CONST name): 
+  x search atom (name); 
+  IF atom not already existing THEN 
+    x create new atom (name); 
+  FI; 
+  result. 
+ 
+atom not already existing: 
+  x status (result) = oblist bone. 
+ 
+END PROC new atom; 
+ 
+ 
+PROC create atom (TEXT CONST name): 
+  x search atom (name); 
+  IF atom already existing THEN 
+    error stop ("Atom " + name + " existiert bereits") 
+  ELSE 
+    x create new atom (name) 
+  FI. 
+ 
+atom already existing: 
+  x status (result) <> oblist bone. 
+ 
+END PROC create atom; 
+ 
+ 
+PROC delete atom (SYM CONST atom): 
+  IF is named atom (atom) THEN 
+    IF null (atom) OR eq (atom, pname) THEN 
+      error stop ("Dies Atom darf nicht geloescht werden") 
+    ELSE 
+      search predecessor; 
+      delete atom from atom list 
+    FI 
+  ELSE 
+    error stop ("Nur benannte Atome können geloescht werden") 
+  FI. 
+ 
+search predecessor: 
+  predecessor := x head (atom); 
+  WHILE NOT eq (x head (predecessor), atom) REP 
+    predecessor := x head (predecessor) 
+  PER. 
+ 
+delete atom from atom list: 
+  x set head (predecessor, x head (atom)). 
+ 
+END PROC delete atom; 
+ 
+ 
+PROC x search atom (TEXT CONST name): 
+  CONCR (result) := (code (name SUB 1) + 17) MOD 27 + 2; 
+  (* This formula places the list of atoms beginning with "§" at the     *) 
+  (* first oblist bone, the list of atoms beginning with "A" at the      *) 
+  (* at the second one, and so on. (See also the big comment in lines    *) 
+  (* 600 - 700)                                                          *) 
+  REP 
+    predecessor := result; 
+    result := x head (predecessor); 
+  UNTIL end of atom list reached COR right atom found PER. 
+ 
+end of atom list reached: 
+  x status (result) = oblist bone. 
+ 
+right atom found: 
+  SYM VAR actual character node := property (result, pname); 
+  IF NOT is text (actual character node) THEN 
+    x lisp error ("Namen erwartet"); 
+    LEAVE right atom found WITH FALSE 
+  FI; 
+  IF CONCR (x head (actual character node)) <> length (name) THEN 
+    FALSE 
+  ELSE 
+    INT VAR i; 
+    FOR i FROM 1 UPTO length (name) REP 
+      to next character node; 
+      check wether is character data node; 
+      check wether character matches; 
+    PER; 
+    TRUE 
+  FI. 
+ 
+to next character node: 
+  actual character node := x tail (actual character node). 
+ 
+check wether is character data node: 
+  IF x status (actual character node) <> character data THEN 
+    x lisp error ("Zeichenkette erwartet"); 
+    LEAVE right atom found WITH FALSE 
+  FI. 
+ 
+check wether character matches: 
+  IF code (name SUB i) <> CONCR (x head (actual character node)) THEN 
+    LEAVE right atom found WITH FALSE 
+  FI. 
+ 
+END PROC x search atom; 
+ 
+ 
+PROC x create new atom (TEXT CONST name): 
+  (* It is necessary that 'x search atom' has been executed before        *) 
+  (* calling 'x create new atom' because this procedure relies on the     *) 
+  (* value of 'predecessor'.                                              *) 
+  enable stop; 
+  SYM CONST sym name :: sym (name); 
+  IF CONCR (heap).size + 3 > max size THEN 
+    error stop ("LISP Heap Ueberlauf") 
+  FI; 
+  result := newly created atom; 
+  x set head (predecessor, result). 
+ 
+newly created atom: 
+  x new node (atomic, CONCR (oblist bone node), CONCR (property list)). 
+ 
+oblist bone node: 
+  x head (predecessor). 
+ 
+property list: 
+  x new node (property indicator, CONCR (pname), property root node). 
+ 
+property root node: 
+  CONCR (x new node (property root, CONCR (sym name), CONCR (nil))). 
+ 
+END PROC x create new atom; 
+ 
+ 
+(************************* property list handling *************************) 
+ 
+(* 
+The property lists consist of chained units of the structure 
+ 
+  +--------------------+   +---------------+ 
+  l property indicator l   l property root l 
+  +----------+---------+   +-------+-------+ 
+  l    o     l    o----+-->l   o   l   o---+--> . . . 
+  +----+-----+---------+   +---+---+-------+ 
+       l                       l 
+       V                       V 
+  property id              property 
+ 
+ 
+or 
+ 
+  +----------------+ 
+  l flag indicator l 
+  +--------+-------+ 
+  l   o    l   o---+--> . . . 
+  +---+----+-------+ 
+      l 
+      V 
+   flag id 
+ 
+ 
+ 
+The property lists cannot be altered or read directly, too. 
+ 
+For property list handling there exist procedures that insert, change, read
+and delete properties resp. flags. Thus, the only thing that can be done
+with any property of an atom without using these special procedures, is
+comparing to or 'cons'ing with some other S-expression. 
+At any given time the property list of any atom (including 'NIL') contains
+the property 'PNAME' giving the print name of the atom, stored as a list of
+characters. This special property cannot be altered, overwritten by 'add
+property' or deleted.
+*) 
+ 
+ 
+(*++++++++++++++++++++++++++ property list dump ++++++++++++++++++++++++++*) 
+ 
+ 
+SYM VAR actual property list node :: nil; 
+ 
+ 
+PROC begin property list dump (SYM CONST atom): 
+  actual property list node := x tail (atom) 
+END PROC begin property list dump; 
+ 
+ 
+PROC next property (SYM VAR property id, property): 
+  IF null (actual property list node) THEN 
+    property id := nil; 
+    property := nil 
+  ELSE 
+    SELECT x status (actual property list node) OF 
+      CASE flag indicator: get flag id 
+      CASE property indicator: get property id and property 
+      OTHERWISE x lisp error ("Flagge oder Eigenschaft erwartet und nicht: " 
+                              + text (x status (actual property list node))) 
+    END SELECT 
+  FI. 
+ 
+get flag id: 
+  property id := x head (actual property list node); 
+  actual property list node := x tail (actual property list node); 
+  property := nil. 
+ 
+get property id and property: 
+  property id := x head (actual property list node); 
+  actual property list node := x tail (actual property list node); 
+  IF x status (actual property list node) = property root THEN 
+    property := x head (actual property list node); 
+    actual property list node := x tail (actual property list node) 
+  ELSE 
+    x lisp error ("Eigenschaftswurzel erwartet, nicht:" + 
+                text (x status (actual property list node))); 
+    property := nil 
+  FI. 
+ 
+END PROC next property; 
+ 
+ 
+(*+++++++++++++++++++++++++++++ properties +++++++++++++++++++++++++++++++*) 
+ 
+ 
+SYM VAR last atom :: SYM :(0), 
+        p list predecessor, 
+        p list result; 
+ 
+ 
+PROC add property (SYM CONST atom, property id, property): 
+  IF eq (property id, pname) THEN 
+    errorstop ("Der PNAME eines Atoms darf nicht versteckt sein") 
+  ELSE 
+    IF CONCR (heap).size + 2 > max size THEN 
+      error stop ("LISP Heap Ueberlauf"); 
+      LEAVE add property 
+    FI; 
+    x set tail (atom, new property plus old property list); 
+    IF eq (atom, last atom) AND 
+       eq (property id, x head (p list result)) THEN 
+      p list predecessor := atom; 
+      p list result := x tail (atom) 
+    FI 
+  FI. 
+ 
+new property plus old property list: 
+  x new node (property indicator, 
+        CONCR (property id), CONCR (property root plus old property list)). 
+ 
+property root plus old property list: 
+  x new node (property root, CONCR (property), CONCR (old property list)). 
+ 
+old property list: 
+  x tail (atom) 
+ 
+END PROC add property; 
+ 
+ 
+PROC alter property (SYM CONST atom, property id, new property): 
+  IF eq (property id, pname) THEN 
+    error stop ("Namen kann man nicht aendern") 
+  ELSE 
+    x search property id (atom, property id); 
+    IF null (p list result) THEN 
+      error stop ("Eigenschaft existiert nicht") 
+    ELSE 
+      x set head (x tail (p list result), new property) 
+    FI 
+  FI 
+END PROC alter property; 
+ 
+ 
+SYM PROC property (SYM CONST atom, property id): 
+  x search property id (atom, property id); 
+  IF null (p list result) THEN 
+    nil 
+  ELSE 
+    x head (x tail (p list result)) 
+  FI 
+END PROC property; 
+ 
+ 
+PROC delete property (SYM CONST atom, property id): 
+  IF eq (property id, pname) THEN 
+    errorstop ("Der Name eines Atoms darf nicht geloescht werden") 
+  ELSE 
+    x search property id (atom, property id); 
+    IF NOT null (p list result) THEN 
+      x set tail (p list predecessor, x tail (x tail (p list result))); 
+      last atom := SYM :(0) 
+    FI 
+  FI 
+END PROC delete property; 
+ 
+ 
+BOOL PROC property exists (SYM CONST atom, property id): 
+  x search property id (atom, property id); 
+  NOT null (p list result) 
+END PROC property exists; 
+ 
+ 
+PROC x search property id (SYM CONST atom, property id): 
+  IF eq (last atom, atom) AND eq (x head (p list result), property id) THEN 
+    LEAVE x search property id 
+  FI; 
+  last atom := atom; 
+  p list predecessor := atom; 
+  REP 
+    p list result := x tail (p list predecessor); 
+    IF end of property list THEN 
+      last atom := SYM :(0); 
+      LEAVE x search property id 
+    FI; 
+    SELECT x status (p list result) OF 
+      CASE flag indicator: p list predecessor := p list result 
+      CASE property indicator: check wether property root node follows; 
+                               IF correct property id found THEN 
+                                 LEAVE x search property id 
+                               ELSE 
+                                 p list predecessor := xtail (p list result) 
+                               FI 
+      CASE property root: xlisperror("Unordentliche Eigenschaftwurzel"); 
+                          p list result := nil; 
+                          last atom := SYM :(0); 
+                          LEAVE x search property id 
+      OTHERWISE x lisp error ("Eigenschaften erwartet und nicht: " + 
+                              text (x status (p list result))); 
+                p list result := nil; 
+                last atom := SYM :(0); 
+                LEAVE x search property id 
+    END SELECT 
+  PER. 
+ 
+end of property list: 
+  null (p list result). 
+ 
+check wether property root node follows: 
+  IF x status (x tail (p list result)) <> property root THEN 
+    x lisp error ("Eigenschaftswurzel erwartet"); 
+    p list result := nil; 
+    last atom := SYM :(0); 
+    LEAVE x search property id 
+  FI. 
+ 
+correct property id found: 
+  eq (x head (p list result), property id). 
+ 
+END PROC x search property id; 
+ 
+ 
+(*++++++++++++++++++++++++++++++++ flags +++++++++++++++++++++++++++++++++*) 
+ 
+ 
+PROC add flag (SYM CONST atom, flag id): 
+  enable stop; 
+  x set tail (atom, new flag plus old property list). 
+ 
+new flag plus old property list: 
+  x new node (flag indicator, CONCR (flag id), old property list). 
+ 
+old property list: 
+  CONCR (x tail (atom)) 
+ 
+END PROC add flag; 
+ 
+ 
+BOOL PROC flag (SYM CONST atom, flag id): 
+  x search flag id (atom, flag id); 
+  NOT null (result) 
+END PROC flag; 
+ 
+ 
+PROC delete flag (SYM CONST atom, flag id): 
+  x search flag id (atom, flag id); 
+  IF NOT (is error COR null (result)) THEN 
+    x set tail (predecessor, x tail (result)) 
+  FI 
+END PROC delete flag; 
+ 
+ 
+PROC x search flag id (SYM CONST atom, flag id): 
+  predecessor := atom; 
+  REP 
+    result := x tail (predecessor); 
+    IF end of property list THEN 
+      LEAVE x search flag id 
+    FI; 
+    SELECT x status (result) OF 
+      CASE property root, property indicator: predecessor := result 
+      CASE flag indicator: IF correct flag id found THEN 
+                             LEAVE x search flag id 
+                           ELSE 
+                             predecessor := result 
+                           FI 
+      OTHERWISE x lisp error ("Eigenschaften erwartet und nicht:" + 
+                              text (x status (result))); 
+                result := nil; 
+                LEAVE x search flag id 
+    END SELECT 
+  PER. 
+ 
+end of property list: 
+  null (result). 
+ 
+correct flag id found: 
+  eq (x head (result), flag id). 
+ 
+END PROC x search flag id; 
+ 
+ 
+(****** Conversion of non-LISP data to LISP structures and vice versa *****) 
+ 
+ 
+TEXT PROC text (SYM CONST sym): 
+  IF is text (sym) THEN 
+    TEXT VAR result := ""; 
+    SYM VAR actual node :: sym; 
+    INT VAR i; 
+    FOR i FROM 1 UPTO CONCR (x head (sym)) REP 
+      actual node := x tail (actual node); 
+      result CAT actual character 
+    PER; 
+    result 
+  ELSE 
+    error stop ("ist kein text"); 
+    "" 
+  FI. 
+ 
+actual character: 
+  IF x status (actual node) <> character data THEN 
+    x lisp error ("Zeichenfolge erwartet"); 
+    LEAVE text WITH result 
+  FI; 
+  code (CONCR (x head (actual node))). 
+ 
+END PROC text; 
+ 
+ 
+BOOL PROC is text (SYM CONST sym): 
+  x status (sym) = text data 
+END PROC is text; 
+ 
+ 
+SYM PROC sym (TEXT CONST text): 
+  SYM VAR result :: x new node (text data, 
+                                length (text), CONCR (nil)), 
+          actual character node :: result; 
+  INT VAR length of text; 
+  ignore blanks at end of text;
+  INT VAR i; 
+  FOR i FROM 1 UPTO length of text REP 
+    x set tail (actual character node, new next character node); 
+    actual character node := x tail (actual character node) 
+  PER; 
+  result. 
+ 
+ignore blanks at end of text: 
+  FOR length of text FROM length (text) DOWNTO 0 REP 
+    IF (text SUB length of text) <> " " THEN 
+      LEAVE ignore blanks at end of text 
+    FI 
+  PER; 
+  length of text := 0. 
+ 
+new next character node: 
+  x new node (character data, code (text SUB i), 1). 
+ 
+END PROC sym; 
+ 
+ 
+INT PROC character (SYM CONST sym): 
+  IF x status (sym) = character data THEN 
+    CONCR (x head (sym)) 
+  ELSE 
+    error stop ("ist kein Charakter"); 
+    -1 
+  FI 
+END PROC character; 
+ 
+ 
+BOOL PROC is character (SYM CONST sym): 
+  x status (sym) = character data 
+END PROC is character; 
+ 
+ 
+SYM PROC sym character (INT CONST char): 
+  x new node (character data, char MOD 256, 1) 
+END PROC sym character; 
+ 
+ 
+INT PROC int 1 (SYM CONST sym): 
+  IF x status (sym) = int data THEN 
+    CONCR (x head (sym)) 
+  ELSE 
+    error stop ("ist keine Zahl"); 
+    -1 
+  FI 
+END PROC int 1; 
+ 
+ 
+INT PROC int 2 (SYM CONST sym): 
+  IF x status (sym) = int data THEN 
+    CONCR (x tail (sym)) 
+  ELSE 
+    error stop ("ist keine Zahl"); 
+    -1 
+  FI 
+END PROC int 2; 
+ 
+ 
+BOOL PROC is int pair (SYM CONST sym): 
+  x status (sym) = int data 
+END PROC is int pair; 
+ 
+ 
+SYM PROC sym (INT CONST int 1, int 2): 
+  x new node (int data, int 1, int 2) 
+END PROC sym; 
+ 
+ 
+(********************* internal error routine *****************************) 
+ 
+ 
+PROC x lisp error (TEXT CONST error message): 
+  error stop (""13"LISP SYSTEM FEHLER: " + error message ) 
+END PROC x lisp error; 
+ 
+ 
+END PACKET lisp heap and oblist management; 
+ 
+ 
+ 
+PACKET name                                         (* Autor: J.Durchholz *) 
+                                                    (* Datum: 15.06.1982  *) 
+    DEFINES                                         (* Version 1.1.1      *) 
+ 
+  name: 
+ 
+TEXT PROC name (SYM CONST sym): 
+  IF is named atom (sym) THEN 
+    text (property (sym, pname)) 
+  ELSE 
+    ""15"IST_KEIN_ATOM"14"" 
+  FI 
+END PROC name; 
+ 
+ 
+END PACKET name; 
+ 
+ 
+ 
+PACKET lisp storage info                            (* Autor: J.Durchholz *) 
+                                                    (* Datum: 23.08.1982  *) 
+    DEFINES                                         (* Version 1.1.1      *) 
+ 
+  lisp storage info: 
+ 
+ 
+PROC lisp storage info: 
+  INT VAR size, used; 
+  lisp storage (size, used); 
+  out (""13""10"      "); 
+  put (used); 
+  put ("Knoten von"); 
+  put (size); 
+  put line ("Knoten des LISP-Heaps sind belegt!") 
+END PROC lisp storage info; 
+ 
+ 
+END PACKET lisp storage info; 
+
diff --git a/lisp/lisp.2 b/lisp/lisp.2
new file mode 100644
index 0000000..28e6924
--- /dev/null
+++ b/lisp/lisp.2
@@ -0,0 +1,584 @@
+PACKET character buffer                            (* Autor : J.Durchholz *) 
+                                                   (* Datum : 09.05.1984  *) 
+    DEFINES                                        (* Version 1.7.2       *) 
+                                      (* 21.2.83. hey 293, 450,97,361 *)
+  get char, 
+  line nr, 
+  init char buffer: 
+ 
+ 
+TEXT VAR buffer; 
+INT VAR pointer, 
+        line; 
+ 
+ 
+INT PROC line nr: 
+  line 
+END PROC line nr; 
+ 
+ 
+PROC init char buffer: 
+  buffer := ""; 
+  pointer := 1; 
+  line := 0; 
+END PROC init char buffer; 
+ 
+ 
+PROC get char (FILE VAR f, TEXT VAR char): 
+  IF buffer empty THEN 
+    try to find nonempty line and put it into buffer; 
+    char := " "; 
+    pointer := 1 
+  ELSE 
+    char := buffer SUB pointer; 
+    pointer INCR 1 
+  FI. 
+ 
+buffer empty: 
+  pointer > length (buffer). 
+ 
+try to find nonempty line and put it into buffer: 
+  REP 
+    IF eof (f) THEN 
+      char := ""; 
+      LEAVE get char 
+    FI; 
+    get line (f, buffer); 
+    line INCR 1 
+  UNTIL buffer <> "" PER. 
+ 
+END PROC get char; 
+ 
+ 
+END PACKET character buffer; 
+ 
+ 
+ 
+ 
+PACKET lisp io                                      (* Autor: J.Durchholz *) 
+                                                    (* Datum: 10.09.1982  *) 
+    DEFINES                                         (* Version 4.1.3      *) 
+                                                    (* Änderung: notebook *)
+  put,  note,                                       (*    13.3.86  I. Ley *)
+  verbose lisp output, 
+  get, 
+  get all: 
+ 
+ 
+BOOL VAR verbose :: FALSE; 
+ 
+ 
+PROC verbose lisp output (BOOL CONST b): 
+  verbose := b 
+END PROC verbose lisp output; 
+ 
+BOOL PROC verbose lisp output: 
+  verbose 
+END PROC verbose lisp output; 
+ 
+ 
+PROC put (SYM CONST sym): 
+  IF atom (sym) THEN 
+    put atom 
+  ELSE 
+    put structure 
+  FI. 
+ 
+put atom: 
+  IF is named atom (sym) THEN 
+    put (name (sym)) 
+  ELIF is int pair (sym) THEN 
+    put (int 1 (sym)) 
+  ELIF is text (sym) THEN 
+    IF verbose THEN 
+      TEXT VAR buffer :: text (sym); 
+      change all (buffer, """", """"""); 
+      buffer CAT """"; 
+      put ("""" + buffer) 
+    ELSE 
+      write (text (sym)) 
+    FI 
+  ELIF is character (sym) THEN 
+    IF verbose THEN 
+      buffer := "'"; 
+      buffer CAT code (character (sym)); 
+      buffer CAT "'"; 
+      put (buffer) 
+    ELSE 
+      out (code (character (sym))) 
+    FI 
+  ELSE 
+    put (""15"UNBEKANNTER_ATOM_TYP"14"") 
+  FI. 
+ 
+put structure: 
+  put ("("); 
+  SYM VAR actual node := sym; 
+  REP 
+    put (head (actual node)); 
+    actual node := tail (actual node) 
+  UNTIL atom (actual node) PER; 
+  IF NOT null (actual node) THEN 
+    put ("."); 
+    put (actual node) 
+  FI; 
+  put (")"). 
+ 
+END PROC put; 
+ 
+PROC put (FILE VAR f, SYM CONST sym): 
+  IF atom (sym) THEN 
+    put atom 
+  ELSE 
+    put structure 
+  FI. 
+ 
+put atom: 
+  IF is named atom (sym) THEN 
+    put (f, name (sym)) 
+  ELIF is int pair (sym) THEN 
+    put (f, int 1 (sym)) 
+  ELIF is text (sym) THEN 
+    IF verbose THEN 
+      TEXT VAR buffer :: text (sym); 
+      change all (buffer, """", """"""); 
+      buffer CAT """"; 
+      put (f, """" + buffer) 
+    ELSE 
+      put (f, text (sym)) 
+    FI 
+  ELIF is character (sym) THEN 
+    IF verbose THEN 
+      buffer := "'"; 
+      buffer CAT code (character (sym)); 
+      buffer CAT "'"; 
+      put (f,  buffer) 
+    ELSE 
+      put (f,  code (character (sym))) 
+    FI 
+  ELSE 
+    put ( f, ""15"UNBEKANNTER_ATOM_TYP"14"") 
+  FI. 
+ 
+put structure: 
+  put (f, "("); 
+  SYM VAR actual node := sym; 
+  REP 
+    put (f, head (actual node)); 
+    actual node := tail (actual node) 
+  UNTIL atom (actual node) PER; 
+  IF NOT null (actual node) THEN 
+    put (f, "."); 
+    put (f, actual node) 
+  FI; 
+  put (f, ")"). 
+ 
+END PROC put; 
+ 
+ PROC note (SYM CONST sym): 
+  IF atom (sym) THEN 
+    note atom 
+  ELSE 
+    note structure 
+  FI. 
+ 
+note atom: 
+  IF is named atom (sym) THEN 
+    note ( name (sym)) 
+  ELIF is int pair (sym) THEN 
+    note (int 1 (sym)) 
+  ELIF is text (sym) THEN 
+    IF verbose THEN 
+      TEXT VAR buffer :: text (sym); 
+      change all (buffer, """", """"""); 
+      buffer CAT """"; 
+      note ( """" + buffer) 
+    ELSE 
+      note ( text (sym)) 
+    FI 
+  ELIF is character (sym) THEN 
+    IF verbose THEN 
+      buffer := "'"; 
+      buffer CAT code (character (sym)); 
+      buffer CAT "'"; 
+      note ( buffer) 
+    ELSE 
+      note ( code (character (sym))) 
+    FI 
+  ELSE 
+    note ( ""15"UNBEKANNTER_ATOM_TYP"14"") 
+  FI. 
+ 
+note structure: 
+  note ( "("); 
+  SYM VAR actual node := sym; 
+  REP 
+    note ( head (actual node)); 
+    actual node := tail (actual node) 
+  UNTIL atom (actual node) PER; 
+  IF NOT null (actual node) THEN 
+    note ( "."); 
+    note ( actual node) 
+  FI; 
+  note ( ")"). 
+ 
+END PROC note; 
+ 
+PROC get (FILE VAR f, SYM VAR s): 
+  initialize scanner (f); 
+  IF NOT get s expression (s) THEN 
+    error ("LISP-Ausdruck erwartet") 
+  FI; 
+  scanner postprocessing (f) 
+END PROC get; 
+ 
+ 
+(**************************** parser for 'get' ****************************) 
+ 
+ 
+LET end of file type = 0, 
+    name type = 1, 
+    text type = 2, 
+    character type = 3, 
+    int type = 4, 
+    other char type = 5; 
+ 
+ 
+BOOL PROC get s expression (SYM VAR s): 
+  (* The boolean result indicates wether the error has not occurred that  *) 
+  (* 'get next symbol' was called, but then the symbol was not expected   *) 
+  (* and thus could not be processed.                                     *) 
+  get next symbol; 
+  SELECT symbol type OF 
+    CASE end of file type: FALSE 
+    CASE name type: s := new atom (symbol); TRUE 
+    CASE text type: s := sym (symbol); TRUE 
+    CASE character type: s := sym character (code (symbol)); TRUE 
+    CASE int type: s := sym (int (symbol), -1); TRUE 
+    CASE other char type: get structure 
+    OTHERWISE error ("EINLESEFEHLER: unbekannter Symboltyp: " + 
+                     text (symbol type)); TRUE 
+  END SELECT. 
+ 
+get structure: 
+  IF symbol <> "(" THEN 
+    FALSE 
+  ELSE 
+    get list; 
+    IF symbol type <> other char type OR symbol <> ")" THEN 
+      error (">> ) << erwartet"); 
+      FALSE 
+    ELSE 
+      TRUE 
+    FI 
+  FI. 
+ 
+get list: 
+  SYM VAR father, son; 
+  IF get s expression (son) THEN 
+    get list elements; 
+  ELSE 
+    s := nil 
+  FI. 
+ 
+get list elements: 
+  father := cons (son, nil); 
+  s := father; 
+  WHILE get s expression (son) REP 
+    set tail (father, cons (son, nil)); 
+    father := tail (father) 
+  PER; 
+  IF symbol type = other char type AND symbol = "." THEN 
+    IF get s expression (son) THEN 
+      set tail (father, son); 
+      get next symbol 
+    ELSE 
+      error ("LISP-Ausdruck nach dem Punkt erwartet") 
+    FI 
+  FI. 
+ 
+END PROC get s expression; 
+ 
+ 
+(********************* scanner for 'get x espression' *********************) 
+ 
+ 
+FILE VAR infile; 
+ 
+ 
+PROC initialize scanner (FILE CONST f): 
+  infile := f; 
+  no input errors := TRUE; 
+  init char buffer; 
+  get char (infile, actual char) 
+END PROC initialize scanner; 
+ 
+ 
+PROC scanner postprocessing (FILE VAR f): 
+  f := infile 
+END PROC scanner postprocessing; 
+ 
+ 
+TEXT VAR symbol; INT VAR symbol type; 
+ 
+ 
+PROC get next symbol: 
+  skip blanks; 
+  IF actual char = "" THEN 
+    symbol := "DATEIENDE"; 
+    symbol type := end of file type 
+  ELIF is letter THEN 
+    get name 
+  ELIF is digit or sign THEN 
+    get integer 
+  ELIF is double quote THEN 
+    get text 
+  ELIF is single quote THEN 
+    get character 
+  ELSE 
+    get other char 
+  FI .
+ 
+is letter: 
+  IF "a" <= actual char AND actual char <= "z" THEN 
+    actual char := code (code (actual char) - code ("a") + code ("A")); 
+    TRUE 
+  ELSE 
+    "§" <= actual char AND actual char <= "Z" 
+  FI. 
+ 
+get name: 
+  symbol type := name type; 
+  symbol := actual char; 
+  REP 
+    get char (infile, actual char); 
+    IF is neither letter nor digit THEN 
+      LEAVE get name 
+    FI; 
+    symbol CAT actual char 
+  PER. 
+ 
+is neither letter nor digit: 
+  NOT (is letter OR is digit OR is underscore). 
+ 
+is digit: 
+  "0" <= actual char AND actual char <= "9". 
+ 
+is underscore: 
+  actual char = "_". 
+ 
+is digit or sign: 
+  is digit OR actual char = "+" OR actual char = "-". 
+ 
+get integer: 
+  symbol type := int type; 
+  IF actual char = "+" THEN 
+    get char (infile, actual char); 
+    skip blanks; 
+    symbol := actual char 
+  ELIF actual char = "-" THEN 
+    symbol := "-"; 
+    get char (infile, actual char); 
+    skip blanks; 
+    symbol CAT actual char 
+  ELSE 
+    symbol := actual char 
+  FI; 
+  REP 
+    get char (infile, actual char); 
+    IF NOT is digit THEN 
+      LEAVE get integer 
+    FI; 
+    symbol CAT actual char 
+  PER. 
+ 
+is double quote: 
+  actual char = """". 
+ 
+get text: 
+  symbol := ""; 
+  symbol type := text type; 
+  REP 
+    get char (infile, actual char); 
+    IF is double quote THEN 
+      get char (infile, actual char); 
+      IF NOT is double quote THEN LEAVE get text 
+      FI 
+    ELIF actual char = ""    THEN LEAVE get text  (*hey*)
+    FI; 
+    symbol CAT actual char 
+  PER. 
+ 
+is single quote: 
+  actual char = "'". 
+ 
+get character: 
+  symbol type := character type; 
+  get char (infile, symbol); 
+  get char (infile, actual char); 
+  IF actual char <> "'" THEN 
+    error (">> ' << erwartet") 
+  ELSE 
+    get char (infile, actual char) 
+  FI. 
+ 
+get other char: 
+  symbol type := other char type; 
+  symbol := actual char; 
+  get char (infile, actual char). 
+ 
+END PROC get next symbol; 
+ 
+ 
+TEXT VAR actual char; 
+ 
+ 
+PROC skip blanks: 
+  INT VAR comment depth :: 0; 
+  WHILE is comment OR actual char = " " REP 
+    get char (infile, actual char) 
+  PER. 
+ 
+is comment: 
+  IF actual char = "{" THEN 
+    comment depth INCR 1; 
+    TRUE 
+  ELIF actual char = "}" THEN 
+    IF comment depth = 0 THEN 
+      error (">> { << fehlt") 
+    ELSE 
+      comment depth DECR 1 
+    FI; 
+    TRUE 
+  ELSE 
+    IF comment depth > 0 THEN 
+      IF actual char = "" THEN 
+        error ("DATEIENDE im Kommentar"); 
+        FALSE 
+      ELSE 
+        TRUE 
+      FI 
+    ELSE 
+      FALSE 
+    FI 
+  FI. 
+ 
+END PROC skip blanks; 
+ 
+ 
+BOOL VAR no input errors; 
+FILE VAR errors; 
+ 
+ 
+PROC error (TEXT CONST error message): 
+  out ("FEHLER in Zeile "); 
+  out (text (line nr)); 
+  out (" bei >> "); 
+  out (symbol); 
+  out (" << : "); 
+  out (error message); 
+  line; 
+  IF no input errors THEN 
+    no input errors := FALSE; 
+    errors := notefile; modify(errors);
+    headline (errors, "Einlesefehler"); output(errors)
+  FI; 
+  write (errors, "FEHLER in Zeile "); 
+  write (errors, text (line nr)); 
+  write (errors, " bei >> "); 
+  write (errors, symbol); 
+  write (errors, " << : "); 
+  write (errors, error message); 
+  line (errors) 
+END PROC error; 
+ 
+ 
+PROC get (SYM VAR sym):     (*hey*)
+  disable stop; 
+  FILE VAR in  :: sequential file (modify, "LISP INPUT"), 
+           out :: notefile; modify (out);
+  headline (out,"LISP OUTPUT");
+  headline (in, "LISP INPUT");
+  noteedit (in);
+  input (in); 
+  get (in, sym); 
+  WHILE NOT no input errors AND NOT is error REP 
+    modify (errors);
+    headline (errors, " LISP-Fehlermeldungen"); 
+    headline (in, " Bitte KORREKTEN LISP-Ausdruck"); 
+    noteedit (in); 
+    headline (errors, "notebook"); 
+    input (in); 
+    get (in, sym) 
+  PER; 
+END PROC get; 
+ 
+ 
+PROC get all (FILE VAR f, SYM VAR sym): 
+  get (f, sym); 
+  skip blanks; 
+  IF NOT eof (infile) THEN 
+    error ("Hinter dem letzten Symbol des LISP-Ausdruck stehen noch Zeichen") 
+  FI 
+END PROC get all; 
+ 
+ 
+END PACKET lisp io; 
+ 
+ 
+ 
+PACKET lisp integer                                 (* Autor: J.Durchholz *) 
+                                                    (* Datum: 30.08.1982  *) 
+    DEFINES                                         (* Version 1.1.2      *) 
+ 
+  sum, 
+  difference, 
+  product, 
+  quotient,
+  remainder:
+ 
+SYM PROC sum (SYM CONST summand list): 
+  INT VAR result := 0; 
+  SYM VAR list rest := summand list; 
+  WHILE NOT atom (list rest) REP 
+    result INCR int 1 (head (list rest)); 
+    list rest := tail (list rest) 
+  PER; 
+  IF NOT null (list rest) THEN 
+    error stop ("Summandenliste endet falsch") 
+  FI ;
+  sym (result, -1) 
+END PROC sum; 
+ 
+ 
+SYM PROC difference (SYM CONST minuend, subtrahend): 
+  sym (int 1 (minuend) - int 1 (subtrahend), -1) 
+END PROC difference; 
+ 
+ 
+SYM PROC product (SYM CONST factor list): 
+  INT VAR result := 1; 
+  SYM VAR list rest := factor list; 
+  WHILE NOT atom (list rest) REP 
+    result := result * int 1 (head (list rest)); 
+    list rest := tail (list rest) 
+  PER; 
+  IF NOT null (list rest) THEN 
+    error stop ("Faktorenliste endet falsch") 
+  FI; 
+  sym (result, -1) 
+END PROC product; 
+ 
+ 
+SYM PROC quotient (SYM CONST dividend, divisor): 
+  sym (int 1 (dividend) DIV int 1 (divisor), -1) 
+END PROC quotient; 
+ 
+ 
+SYM PROC remainder(SYM CONST dividend, divisor): 
+  sym (int 1 (dividend) MOD int 1 (divisor), -1) 
+END PROC remainder;
+ 
+ 
+END PACKET lisp integer; 
+
diff --git a/lisp/lisp.3 b/lisp/lisp.3
new file mode 100644
index 0000000..a93463c
--- /dev/null
+++ b/lisp/lisp.3
@@ -0,0 +1,767 @@
+PACKET lisp heap maintenance                        (* Autor: J.Durchholz *) 
+                                                    (* Datum: 09.05.1984  *) 
+    DEFINES                                         (* Version 1.7.2      *) 
+                                                    (* Testhilfe          *) 
+  create lisp system,                  (* hey, 02.3.83 : 121,334,542,732 *) 
+  dump oblist: 
+ 
+ 
+PROC create lisp system (FILE VAR f, DATASPACE CONST new heap): 
+  initialize lisp system (new heap); 
+  input (f); 
+  WHILE NOT eof (f) REP 
+    TEXT VAR name; 
+    get (f, name); 
+    SYM CONST s :: new atom (name); 
+    get (f, name); 
+    SYM CONST property name :: new atom (name); 
+    IF NOT null (property name) THEN 
+      SYM VAR property; 
+      get (f, property); 
+      add property (s, property name, property) 
+    FI 
+  PER 
+END PROC create lisp system; 
+ 
+ 
+PROC dump oblist (FILE VAR f): 
+  begin oblist dump; 
+  REP 
+    SYM CONST actual atom :: next atom; 
+    put line (f, name (actual atom)); 
+    dump property list 
+  UNTIL null (actual atom) PER. 
+ 
+dump property list: 
+  begin property list dump (actual atom); 
+  REP 
+    SYM VAR id, value; 
+    next property (id, value); 
+    write (f, "  "); 
+    write (f, name (id)); 
+    write (f, " "); 
+    write (f, name (value)); 
+    line (f) 
+  UNTIL null (id) AND null (value) PER. 
+ 
+END PROC dump oblist; 
+ 
+ 
+PROC dump oblist: 
+  begin oblist dump; 
+  REP 
+    SYM CONST actual atom :: next atom; 
+    put line (name (actual atom)); 
+    dump property list 
+  UNTIL null (actual atom) PER. 
+ 
+dump property list: 
+  begin property list dump (actual atom); 
+  REP 
+    SYM VAR id, value; 
+    next property (id, value); 
+    out ("  "); 
+    out (name (id)); 
+    out (" "); 
+    put line (name (value)); 
+  UNTIL null (id) AND null (value) PER. 
+ 
+END PROC dump oblist; 
+ 
+ 
+END PACKET lisp heap maintenance; 
+ 
+ 
+ 
+PACKET lisp interpreter                             (* Autor: J.Durchholz *) 
+                                                    (* Datum: 27.12.1982  *) 
+    DEFINES                                         (* Version 3.1.7      *) 
+  evalquote,
+  apply, 
+  eval, 
+  try: 
+ 
+ 
+(* SYM-objects used by the interpreter. They all point to constant structure
+ within the heap. As their address may change during garbage collection,
+ it must be possible to correct the references to them made by the
+ SYM-objects. That is the reason why they are declared VAR instead of CONST*)
+SYM VAR lambda constant, 
+        label constant, 
+        quote constant, 
+        function constant, 
+        indefinite constant, 
+        apval constant, 
+        true constant, 
+        false constant; 
+ 
+SYM VAR errors; 
+BOOL VAR trace :: FALSE; 
+ 
+PROC initialize constants: 
+  lambda constant := new atom ("LAMBDA"); 
+  label constant := new atom ("LABEL"); 
+  quote constant := new atom ("QUOTE"); 
+  function constant := new atom ("FUNCTION"); 
+  indefinite constant := new atom ("INDEFINITE"); 
+  apval constant := new atom ("APVAL"); 
+  true constant := new atom ("T"); 
+  false constant := new atom ("F"); 
+  errors := new atom ("ERRORS") 
+END PROC initialize constants; 
+ 
+ 
+SYM PROC evalquote (SYM CONST expr):     (*hey*)
+  enable stop; 
+  initialize constants; 
+  x apply ( head (expr), quote (tail (expr)), nil )
+END PROC evalquote;
+ 
+ 
+SYM PROC quote (SYM CONST x):
+  IF eq (x,nil) THEN nil
+  ELSE set head (x, new head); set tail (x, quote (tail(x))); x
+  FI .
+new head:
+  cons (quote constant, cons (head(x), nil) )
+END PROC quote;
+ 
+ 
+SYM PROC apply (SYM CONST function, argument list, alist): 
+  enable stop; 
+  initialize constants; 
+  x apply (function, argument list, alist) 
+END PROC apply; 
+ 
+ 
+SYM PROC x apply (SYM CONST function, argument list, alist): 
+  IF trace THEN line;
+    put ("a p p l y :"); put (function); line;
+    put ("arguments :"); put (argument list); line;
+  FI;
+  SYM VAR new alist; 
+  initialize for alist insertion; 
+  reduce actual fn to lambda expression; 
+  insert parameter evaluated argument pairs in reversed order in new alist; 
+  function body evaluation. 
+ 
+reduce actual fn to lambda expression: 
+  SYM VAR actual fn :: function; 
+  REP 
+    IF is named atom (actual fn) THEN 
+      get function from property list of actual fn 
+                                           or from functional alist entry 
+    ELIF atom (actual fn) THEN 
+      error stop ("Eine Funktion darf kein unbenanntes Atom sein") 
+    ELSE 
+      IF eq (head (actual fn), lambda constant) THEN 
+        LEAVE reduce actual fn to lambda expression 
+      ELIF eq (head (actual fn), label constant) THEN 
+        get function from label expression and update alist 
+      ELSE 
+        error stop ("Funktion ist weder Atom noch LAMBDA-/LABEL-Ausdruck") 
+      FI 
+    FI 
+  PER. 
+ 
+get function from property list of actual fn or from functional alist entry: 
+  IF property exists (actual fn, function constant) THEN 
+    get function from property list of actual fn 
+  ELSE 
+    get function from functional alist entry 
+  FI. 
+ 
+get function from property list of actual fn: 
+  actual fn := property (actual fn, function constant). 
+ 
+get function from functional alist entry: 
+  SYM VAR actual alist entry; 
+  begin alist retrieval; 
+  REP 
+    IF end of alist THEN 
+      error stop ("Die Funktion " + name (actual fn) + 
+                  " ist nicht definiert") 
+    FI; 
+    search for next functional alist entry; 
+  UNTIL eq (head (actual functional alist entry), actual fn) PER; 
+  actual fn := tail (actual functional alist entry). 
+ 
+get function from label expression and update alist: 
+  actual fn := tail (actual fn); 
+  IF atom (actual fn) COR 
+     (NOT atom (head (actual fn)) OR atom (tail (actual fn))) COR 
+     NOT null (tail (tail (actual fn)))                           THEN 
+    error stop ("Ungueltiger LABEL-Ausdruck") 
+  FI; 
+  SYM VAR new alist entry; 
+  prepare new functional alist entry; 
+  set head (new alist entry, head (actual fn)); 
+  actual fn := head (tail (actual fn)); 
+  set tail (new alist entry, actual fn). 
+ 
+insert parameter evaluated argument pairs in reversed order in new alist: 
+  actual fn := tail (actual fn); 
+  IF atom (actual fn) THEN 
+    error stop ("Ungueltiger LAMBDA-Ausdruck") 
+  FI; 
+  SYM VAR parameter list rest :: head (actual fn), 
+          argument list rest :: argument list; 
+  actual fn := tail (actual fn); 
+  WHILE NOT null (parameter list rest) REP 
+    add next parameter argument pair to alist 
+  PER; 
+  check wether no arguments are left over. 
+ 
+add next parameter argument pair to alist: 
+  IF atom (parameter list rest) THEN 
+    error stop ("Parameterliste endet falsch") 
+  FI; 
+  SYM VAR param pointer :: head (parameter list rest); 
+  parameter list rest := tail (parameter list rest); 
+  IF is named atom (param pointer) AND NOT null (param pointer) THEN 
+    add parameter evaluated argument pair to alist; 
+    advance argument list rest 
+  ELIF atom (param pointer) THEN 
+    error stop ("Unbenannte Atome und NIL koennen nicht Parameter sein") 
+  ELSE 
+    IF eq (head (param pointer), indefinite constant) THEN 
+      check wether is last param; 
+      advance param pointer; 
+      IF eq (head (param pointer), quote constant) THEN 
+        advance param pointer; 
+        move param pointer to parameter; 
+        add parameter indefinite quoted argument pair to alist 
+      ELSE 
+        move param pointer to parameter; 
+        add parameter indefinite evaluated argument pair to alist 
+      FI; 
+      argument list rest := nil 
+    ELIF eq (head (param pointer), quote constant) THEN 
+      advance param pointer; 
+      move param pointer to parameter; 
+      add parameter quoted argument pair to alist; 
+      advance argument list rest 
+    ELIF eq (head (param pointer), function constant) THEN 
+      advance param pointer; 
+      move param pointer to parameter; 
+      add parameter functional argument pair to alist; 
+      advance argument list rest 
+    ELSE 
+      error stop ("Ungueltiger Parameter") 
+    FI 
+  FI. 
+ 
+advance param pointer: 
+  param pointer := tail (param pointer); 
+  IF atom (param pointer) THEN 
+    error stop ("Ungueltiger Parameter") 
+  FI. 
+ 
+move param pointer to parameter: 
+  IF NOT null (tail (param pointer)) THEN 
+    error stop ("Ungueltiger Parameter") 
+  FI; 
+  param pointer := head (param pointer); 
+  IF NOT atom (param pointer) OR null (param pointer) THEN 
+    error stop ("Unbenannte Atome und NIL koennen nicht Parameter sein") 
+  FI. 
+ 
+advance argument list rest: 
+  argument list rest := tail (argument list rest). 
+ 
+add parameter evaluated argument pair to alist: 
+  prepare new alist entry; 
+  set head (new alist entry, param pointer); 
+  set tail (new alist entry, x eval (actual argument, alist)). 
+ 
+check wether is last param: 
+  IF NOT null (parameter list rest) THEN 
+    error stop ("Ein INDEFINITE-Parameter muss der letzte sein") 
+  FI. 
+ 
+add parameter indefinite quoted argument pair to alist: 
+  prepare new alist entry; 
+  set head (new alist entry, param pointer); 
+  set tail (new alist entry, argument list rest); 
+  WHILE NOT atom (argument list rest) REP 
+    argument list rest := tail (argument list rest) 
+  PER; 
+  IF NOT null (argument list rest) THEN 
+    error stop ("Argumentliste endet falsch") 
+  FI. 
+ 
+add parameter indefinite evaluated argument pair to alist: 
+  prepare new alist entry; 
+  set head (new alist entry, param pointer); 
+  last evaluated argument := new alist entry; 
+  WHILE NOT atom (argument list rest) REP 
+    set tail (last evaluated argument, 
+              cons (x eval (head (argument list rest), alist), nil)); 
+    last evaluated argument := tail (last evaluated argument); 
+    advance argument list rest 
+  PER; 
+  IF NOT null (argument list rest) THEN 
+    error stop ("Argumentliste endet falsch") 
+  FI. 
+ 
+last evaluated argument: 
+  param pointer. 
+(* The value of param pointer is not used further, so the *) 
+(* variable can be "reused" in this manner. *) 
+ 
+add parameter quoted argument pair to alist: 
+  prepare new alist entry; 
+  set head (new alist entry, param pointer); 
+  set tail (new alist entry, actual argument). 
+ 
+add parameter functional argument pair to alist: 
+  prepare new functional alist entry; 
+  set head (new alist entry, param pointer); 
+  set tail (new alist entry, actual argument). 
+ 
+actual argument: 
+  IF atom (argument list rest) THEN 
+    IF null (argument list rest) THEN 
+      error stop ("Zuwenig Argumente") 
+    ELSE 
+      error stop ("Argumentliste endet falsch") 
+    FI 
+  FI; 
+  head (argument list rest). 
+ 
+check wether no arguments are left over: 
+  IF NOT null (argument list rest) THEN 
+    error stop ("Zuviele Argumente") 
+  FI. 
+ 
+function body evaluation: 
+  IF is int pair (actual fn) THEN 
+    predefined function evaluation 
+  ELIF atom (actual fn) COR NOT null (tail (actual fn)) THEN 
+    error stop ("Ungueltiger LAMBDA-Ausdruck"); nil 
+  ELSE 
+    x eval (head (actual fn), new alist) 
+  FI. 
+ 
+predefined function evaluation: 
+  SELECT int 1 (actual fn) OF 
+    CASE 0: call eval cond 
+    CASE 1: call begin oblist dump 
+    CASE 2: call next atom 
+    CASE 3: call add property 
+    CASE 4: call alter property 
+    CASE 5: call delete property 
+    CASE 6: call property exists 
+    CASE 7: call property 
+    CASE 8: call add flag 
+    CASE 9: call flag 
+    CASE 10: call delete flag 
+    CASE 11: call begin property list dump 
+    CASE 12: call next property 
+    CASE 13: call apply 
+    CASE 14: call eval 
+    CASE 15: call try 
+    CASE 16: give association list 
+    CASE 17: call error stop 
+    CASE 18: call head 
+    CASE 19: call set head 
+    CASE 20: call tail 
+    CASE 21: call set tail 
+    CASE 22: call cons 
+    CASE 23: call eq 
+    CASE 24: call get sym 
+    CASE 25: call put sym 
+    CASE 26: call null 
+    CASE 27: call is atom 
+    CASE 28: call is named atom 
+    CASE 29: call get named atom 
+    CASE 30: call put named atom 
+    CASE 31: call is text 
+    CASE 32: call get text 
+    CASE 33: call put text 
+    CASE 34: call is character 
+    CASE 35: call get character 
+    CASE 36: call put character 
+    CASE 37: call is int 
+    CASE 38: call get int 
+    CASE 39: call put int 
+    CASE 40: call sum 
+    CASE 41: call difference 
+    CASE 42: call product 
+    CASE 43: call quotient 
+    CASE 44: call remainder
+    CASE 45: call equal 
+    CASE 46: call trace
+    CASE 47: call define
+    CASE 48: call set
+    OTHERWISE error stop("Es gibt (noch) keine LISP-Funktion mit der Nummer" 
+                          + text (int 1 (actual fn)) ); nil 
+  END SELECT. 
+ 
+call eval cond: 
+  x eval condition (arg 1, alist). 
+ 
+call begin oblist dump: 
+  begin oblist dump; nil. 
+ 
+call next atom: 
+  next atom. 
+ 
+call add property: 
+  add property (arg 3, arg 2, arg 1); arg 1. 
+ 
+call alter property: 
+  alter property (arg 3, arg 2, arg 1); arg 1. 
+ 
+call delete property: 
+  delete property (arg 2, arg 1); nil. 
+ 
+call property exists: 
+  IF property exists(arg 2,arg 1) THEN true constant ELSE false constant FI. 
+ 
+call property: 
+  property (arg 2, arg 1). 
+ 
+call add flag: 
+  add flag (arg 2, arg 1); nil. 
+ 
+call flag: 
+  IF flag (arg 2, arg 1) THEN true constant ELSE false constant FI. 
+ 
+call delete flag: 
+  delete flag (arg 2, arg 1); nil. 
+ 
+call begin property list dump: 
+  begin property list dump (arg 1); nil. 
+ 
+call next property: 
+  SYM VAR s1, s2; next property (s1, s2); cons (s1, s2). 
+ 
+call apply: 
+  x apply (arg 3, arg 2, arg 1). 
+ 
+call eval: 
+  x eval (arg 2, arg 1). 
+ 
+call try: 
+  x try (arg 4, arg 3, arg 2, arg 1). 
+ 
+give association list: 
+  alist. 
+ 
+call error stop: 
+  error stop (text (arg 1)); nil. 
+ 
+call head: 
+  head (arg 1). 
+ 
+call set head: 
+  set head (arg 2, arg 1); arg 2. 
+ 
+call tail: 
+  tail (arg 1). 
+ 
+call set tail: 
+  set tail (arg 2, arg 1); arg 2. 
+ 
+call cons: 
+  cons (arg 2, arg 1). 
+ 
+call eq: 
+  IF eq (arg 2, arg 1) THEN true constant ELSE false constant FI. 
+ 
+call get sym: 
+  get (s1); s1. 
+ 
+call put sym: 
+  put (arg 1); arg 1. 
+ 
+call null: 
+  IF null (arg 1) THEN true constant ELSE false constant FI. 
+ 
+call is atom: 
+  IF atom (arg 1) THEN true constant ELSE false constant FI. 
+ 
+call is named atom: 
+  IF is named atom (arg 1) THEN true constant ELSE false constant FI. 
+ 
+call get named atom: 
+  TEXT VAR t; get (t); new atom (t). 
+ 
+call put named atom: 
+  put (name (arg 1)); arg 1. 
+ 
+call is text: 
+  IF is text (arg 1) THEN true constant ELSE false constant FI. 
+ 
+call get text: 
+  get (t); sym (t). 
+ 
+call put text: 
+  put (text (arg 1)); arg 1. 
+ 
+call is character: 
+  IF is character (arg 1) THEN true constant ELSE false constant FI. 
+ 
+call get character: 
+  inchar (t); sym character (code (t)). 
+ 
+call put character: 
+  out (code (character (arg 1))); arg 1. 
+ 
+call is int: 
+  IF is int pair (arg 1) THEN true constant ELSE false constant FI. 
+ 
+call get int: 
+  INT VAR i; get (i); sym (i, -1). 
+ 
+call put int: 
+  put (int 1 (arg 1)); arg 1. 
+ 
+call sum: 
+  sum (arg 1). 
+ 
+call difference: 
+  difference (arg 2, arg 1). 
+ 
+call product: 
+  product (arg 1). 
+ 
+call quotient: 
+  quotient (arg 2, arg 1). 
+ 
+call remainder:
+  remainder(arg 2, arg 1). 
+ 
+call equal:
+  IF equal (arg 2, arg 1) THEN true constant ELSE false constant FI.
+ 
+call trace:
+  trace := NOT trace;
+  IF trace THEN true constant ELSE false constant FI . 
+ 
+call define:     (*hey*) 
+  define (arg 1) . 
+ 
+call set:         (*hey*) 
+  add property (new atom ( name (arg 2)), apval constant, arg 1); arg 1 . 
+ 
+arg 1: 
+  tail (head (new alist)). 
+ 
+arg 2: 
+  tail (head (tail (new alist))). 
+ 
+arg 3: 
+  tail (head (tail (tail (new alist)))). 
+ 
+arg 4: 
+  tail (head (tail (tail (tail (new alist))))). 
+ 
+END PROC x apply; 
+ 
+SYM PROC define (SYM CONST x):   (*hey*) 
+  IF   eq (x, nil) THEN nil 
+  ELSE add property (new atom (name (head (head (x)))), 
+                     function constant, tail (head (x)) ); 
+       cons (head (head (x)), define (tail (x)) ) 
+  FI . 
+END PROC define; 
+ 
+SYM VAR old alist :: nil;
+ 
+SYM PROC eval (SYM CONST expression, alist): 
+  enable stop; 
+  initialize constants; 
+  x eval (expression, alist) 
+END PROC eval; 
+ 
+ 
+SYM PROC x eval (SYM CONST expression, alist):   (*hey*)
+  IF trace THEN line;
+    put ("e v a l   :"); put (expression); line;
+    IF NOT equal (alist, old alist) THEN
+    put ("bindings  :"); old alist := alist; put (alist); line FI
+  FI;
+  IF atom (expression) THEN 
+    IF is named atom (expression) THEN 
+      value from property list of expression or from alist entry 
+    ELSE 
+      expression 
+    FI 
+  ELSE 
+    x apply (head (expression), tail (expression), alist) 
+  FI. 
+ 
+value from property list of expression or from alist entry: 
+  IF property exists (expression, apval constant) THEN 
+    value from property list of expression 
+  ELSE 
+    value from alist entry 
+  FI. 
+ 
+value from property list of expression: 
+  property (expression, apval constant). 
+ 
+value from alist entry: 
+  SYM VAR actual alist entry; 
+  begin alist retrieval; 
+  REP 
+    IF end of alist THEN 
+      error stop ("Das Atom " + name (expression) + " hat keinen Wert") 
+    FI; 
+    search for next alist entry 
+  UNTIL eq (head (actual alist entry), expression) PER; 
+  tail (actual alist entry). 
+ 
+END PROC x eval; 
+ 
+ 
+SYM PROC try (SYM CONST expression list, alist, 
+                        error output, break possible): 
+  enable stop; 
+  initialize constants; 
+  x try (expression list, alist, error output, break possible) 
+END PROC try; 
+ 
+ 
+SYM PROC x try (SYM CONST expression list, alist, 
+                          error output, break possible): 
+  BOOL CONST output :: bool (error output), 
+             halt enabled :: bool (break possible); 
+  SYM VAR expr list rest :: expression list; 
+  REP 
+    IF null (expr list rest) THEN 
+      LEAVE x try WITH nil 
+    ELIF atom (expr list rest) THEN 
+      error stop ("Ausdrucksliste fuer 'try' endet falsch") 
+    ELSE 
+      try evaluation of actual expression 
+    FI; 
+    expr list rest := tail (expr list rest) 
+  PER; 
+  nil. 
+ 
+try evaluation of actual expression: 
+  disable stop; 
+  SYM VAR result :: x eval (head (expr list rest), alist); 
+  IF is error THEN 
+    IF error message = "halt from terminal" AND halt enabled THEN 
+      enable stop 
+    ELIF output THEN 
+      put error 
+    FI; 
+    add property (errors, apval constant, sym (error message)); 
+    clear error 
+  ELSE 
+    LEAVE x try WITH result 
+  FI; 
+  enable stop. 
+ 
+END PROC x try; 
+ 
+ 
+SYM PROC x eval condition (SYM CONST pair list, alist): 
+  enable stop; 
+  SYM VAR cond pair list rest :: pair list; 
+  REP 
+    IF atom (cond pair list rest) THEN 
+      error stop ("Keine 'T'-Bedingung in bedingtem Ausdruck gefunden") 
+    FI; 
+    check wether is correct pair; 
+    IF true condition found THEN 
+      LEAVE x eval condition WITH x eval (head (tail (actual pair)), alist) 
+    FI; 
+    cond pair list rest := tail (cond pair list rest) 
+  PER; 
+  nil. 
+ 
+check wether is correct pair: 
+  IF atom (actual pair) COR 
+     atom (tail (actual pair)) COR 
+     NOT null (tail (tail (actual pair))) THEN 
+    error stop ("Ungueltiges Paar im bedingten Ausdruck") 
+  FI. 
+ 
+true condition found: 
+  bool (x eval (head (actual pair), alist)). 
+ 
+actual pair: 
+  head (cond pair list rest). 
+ 
+END PROC x eval condition; 
+ 
+ 
+BOOL PROC bool (SYM CONST sym): 
+  IF eq (sym, true constant) THEN 
+    TRUE 
+  ELIF eq (sym, false constant) THEN 
+    FALSE 
+  ELSE 
+    error stop ("'T' oder 'F' erwartet"); TRUE 
+  FI 
+END PROC bool; 
+ 
+ 
+(******* a-list handling refinements used in 'x apply' and 'x eval' *******) 
+ 
+(* declared within 'x apply' and 'x eval': 'actual alist entry'           *) 
+ 
+. 
+ 
+initialize for alist insertion: 
+  new alist := alist. 
+ 
+begin alist retrieval: 
+  SYM VAR actual alist pos :: alist. 
+ 
+search for next alist entry: 
+  WHILE NOT end of alist REP 
+    IF atom (actual alist pos) THEN 
+      error stop ("Bindeliste endet falsch") 
+    FI; 
+    actual alist entry := head (actual alist pos); 
+    actual alist pos := tail (actual alist pos); 
+  UNTIL is non functional alist entry PER. 
+ 
+is non functional alist entry: 
+  NOT is functional alist entry. 
+ 
+search for next functional alist entry: 
+  WHILE NOT end of alist REP 
+    IF atom (actual alist pos) THEN 
+      error stop ("Bindeliste endet falsch") 
+    FI; 
+    actual alist entry := head (actual alist pos); 
+    actual alist pos := tail (actual alist pos); 
+  UNTIL is functional alist entry PER; 
+  actual alist entry := tail (actual alist entry). 
+ 
+is functional alist entry: 
+  check wether is alist entry; 
+  null (head (actual alist entry)). 
+ 
+check wether is alist entry: 
+  IF atom (actual alist entry) THEN 
+    error stop ("Bindelisteneintrag ist kein Paar") 
+  FI. 
+ 
+end of alist: 
+  null (actual alist pos). 
+ 
+actual functional alist entry: 
+  actual alist entry. 
+ 
+prepare new alist entry: 
+  new alist := cons (cons (nil, nil), new alist); 
+  new alist entry := head (new alist). 
+ 
+prepare new functional alist entry: 
+  new alist := cons (cons (nil, cons (nil, nil)), new alist); 
+  new alist entry := tail (head (new alist)). 
+ 
+ 
+END PACKET lisp interpreter; 
+ 
+ 
+
diff --git a/lisp/lisp.4 b/lisp/lisp.4
new file mode 100644
index 0000000..0733dcd
--- /dev/null
+++ b/lisp/lisp.4
@@ -0,0 +1,143 @@
+PACKET lisp               (* Autor: J.Durchholz , P. Heyderhoff *)
+                          (* Datum: 09.05.1984  *)
+    DEFINES               (* Version 1.7.2      *)
+                          (* Änderung: notebook                       *)
+                          (*    13.3.86  I. Ley                       *)
+                          (* Änderung: start lisp system              *)
+                          (*    25.3.86  I. Ley                       *)
+                          (* Anpassung an ELAN-Compiler Version 1.7.5 *)
+                          (*     8.4.86  I. Ley                       *)
+  start lisp system,
+  lisp heap,
+  insert lisp,
+  run lisp,
+  run lisp again,
+  lisp,
+  break lisp:
+ 
+SYM VAR run again pointer :: nil;
+DATASPACE VAR insert heap :: nil space;
+ 
+PROC start lisp system (DATASPACE CONST heap):
+  enable stop;
+  initialize lisp system (heap);
+  forget (insert heap);
+  insert heap := heap
+END PROC start lisp system;
+ 
+ 
+PROC start lisp system (DATASPACE CONST heap, FILE VAR f):
+  enable stop;
+  create lisp system (f, heap);
+  forget (insert heap);
+  insert heap := heap
+END PROC start lisp system;
+ 
+ 
+PROC start lisp system (FILE VAR f):
+  create lisp system (f, insert heap)
+END PROC start lisp system;
+ 
+ 
+DATASPACE PROC lisp heap:
+  insert heap
+END PROC lisp heap;
+ 
+ 
+DATASPACE VAR run heap :: nil space;
+ 
+ 
+PROC insert lisp:
+  insert lisp (last param)
+END PROC insert lisp;
+ 
+ 
+PROC insert lisp (TEXT CONST file name):
+  interpret (insert heap, file name)
+END PROC insert lisp;
+ 
+ 
+PROC run lisp:
+  run lisp (last param)
+END PROC run lisp;
+ 
+ 
+PROC run lisp (TEXT CONST file name):
+  forget (run heap);
+  run heap := insert heap;
+  interpret (run heap, file name)
+END PROC run lisp;
+ 
+ 
+PROC interpret (DATASPACE CONST heap, TEXT CONST file name):
+  enable stop;
+  FILE VAR f :: sequential file (input, file name);
+  interpret (heap, f)
+END PROC interpret;
+ 
+ 
+PROC interpret (DATASPACE CONST heap, FILE VAR f):
+  initialize lisp system (heap);
+  get (f, run again pointer);
+  add property (new atom ("program"), new atom ("APVAL"), run again pointer);
+  put (evalquote (run again pointer))
+END PROC interpret;
+ 
+PROC run lisp again:
+  put (evalquote (run again pointer))
+END PROC run lisp again;
+ 
+ 
+PROC get ausdruck:
+  enable stop; get (ausdruck)
+END PROC get ausdruck;
+ 
+SYM VAR ausdruck; 
+ 
+PROC lisp:
+ 
+(* HAUPT TESTPROGRAMM FUER LISP      Heyderhoff    25.1.83   *)
+IF NOT exists ("LISP HEAP") THEN 
+  FILE VAR bootstrap :: sequential file (input, "lisp.bootstrap"); 
+  create lisp system (bootstrap, new ("LISP HEAP")); 
+  verbose lisp output (TRUE);
+FI; 
+SYM VAR work;
+command dialogue(FALSE); forget ("LISP INPUT"); command dialogue(TRUE);
+(* bildlaenge(23); *) (* EUMEL 1.65 *)
+disable stop; 
+REP 
+  get (ausdruck); 
+  IF is error THEN 
+    handle error 
+  ELSE 
+    work := evalquote (ausdruck);
+    IF is error THEN  handle error 
+    ELSE note (work)
+    FI 
+  FI 
+PER .
+ 
+handle error: 
+  IF text (error message, 18) = "halt from terminal" THEN 
+    enable stop 
+  ELSE 
+    note (error message);
+    put (     error message); pause(20);
+    clear error; 
+  FI .
+END PROC lisp;
+ 
+PROC break lisp:
+  break; 
+  page; 
+  quit;
+  FILE VAR in  :: sequential file (modify, "LISP INPUT"), 
+           out :: notefile; modify (out);
+  headline (out,"LISP OUTPUT");
+  headline (in, "LISP INPUT");
+  noteedit (in);
+END PROC break lisp
+ 
+END PACKET lisp;
+
diff --git a/lisp/lisp.bootstrap b/lisp/lisp.bootstrap
new file mode 100644
index 0000000..37efbde
--- /dev/null
+++ b/lisp/lisp.bootstrap
@@ -0,0 +1,118 @@
+NIL                      APVAL 
+NIL 
+T                        APVAL 
+T 
+F                        APVAL 
+F 
+COND                     FUNCTION 
+(LAMBDA ((INDEFINITE QUOTE X)) . 0) 
+BEGINOBLISTDUMP        FUNCTION 
+(LAMBDA () . 1) 
+NEXTATOM                FUNCTION 
+(LAMBDA () . 2) 
+ADDPROPERTY             FUNCTION 
+(LAMBDA (X X X) . 3) 
+ALTERPROPERTY           FUNCTION 
+(LAMBDA (X X X) . 4) 
+DELETEPROPERTY          FUNCTION 
+(LAMBDA (X X) . 5) 
+PROPERTYEXISTS          FUNCTION 
+(LAMBDA (X X) . 6) 
+PROPERTY                 FUNCTION 
+(LAMBDA (X X) . 7) 
+ADDFLAG                 FUNCTION 
+(LAMBDA (X X) . 8) 
+FLAG                     FUNCTION 
+(LAMBDA (X X) . 9) 
+DELETEFLAG              FUNCTION 
+(LAMBDA (X X) . 10) 
+BEGINPROPERTYLISTDUMP FUNCTION 
+(LAMBDA (X) . 11) 
+NEXTPROPERTY            FUNCTION 
+(LAMBDA () . 12) 
+APPLY                    FUNCTION 
+(LAMBDA (X X X) . 13) 
+EVAL                     FUNCTION 
+(LAMBDA (X X) . 14) 
+TRY                      FUNCTION 
+(LAMBDA (X X X X) . 15) 
+ASSOCIATIONLIST         FUNCTION 
+(LAMBDA () . 16) 
+ERRORSTOP               FUNCTION 
+(LAMBDA (X) . 17) 
+HEAD                     FUNCTION 
+(LAMBDA (X) . 18) 
+SETHEAD                 FUNCTION 
+(LAMBDA (X X) . 19) 
+TAIL                     FUNCTION 
+(LAMBDA (X) . 20) 
+SETTAIL                 FUNCTION 
+(LAMBDA (X X) . 21) 
+CONS                     FUNCTION 
+(LAMBDA (X X) . 22) 
+EQ                       FUNCTION 
+(LAMBDA (X X) . 23) 
+GET                      FUNCTION 
+(LAMBDA () . 24) 
+PUT                      FUNCTION 
+(LAMBDA (X) . 25) 
+NULL                     FUNCTION 
+(LAMBDA (X) . 26) 
+ATOM                     FUNCTION 
+(LAMBDA (X) . 27) 
+NAMEDATOM               FUNCTION 
+(LAMBDA (X) . 28) 
+GETATOM                 FUNCTION 
+(LAMBDA () . 29) 
+PUTATOM                 FUNCTION 
+(LAMBDA (X) . 30) 
+TEXT                     FUNCTION 
+(LAMBDA (X) . 31) 
+GETTEXT                 FUNCTION 
+(LAMBDA () . 32) 
+PUTTEXT                 FUNCTION 
+(LAMBDA (X) . 33) 
+CHARACTER                FUNCTION 
+(LAMBDA (X) . 34) 
+GETCHARACTER            FUNCTION 
+(LAMBDA () . 35) 
+PUTCHARACTER            FUNCTION 
+(LAMBDA (X) . 36) 
+INT                      FUNCTION 
+(LAMBDA (X). 37) 
+GETINT                  FUNCTION 
+(LAMBDA () . 38) 
+PUTINT                  FUNCTION 
+(LAMBDA (X) . 39) 
+SUM                      FUNCTION 
+(LAMBDA ((INDEFINITE X)) . 40) 
+DIFFERENCE               FUNCTION 
+(LAMBDA (X X). 41) 
+PRODUCT                  FUNCTION 
+(LAMBDA ((INDEFINITE X)). 42) 
+QUOTIENT                 FUNCTION 
+(LAMBDA (X X).43) 
+REMAINDER                FUNCTION 
+(LAMBDA (X X).44) 
+EQUAL                    FUNCTION 
+(LAMBDA (X X) . 45) 
+TRACE                    FUNCTION 
+(LAMBDA () . 46 ) 
+DEFINE                   FUNCTION 
+(LAMBDA ((INDEFINITE X)) . 47 ) 
+SET                      FUNCTION 
+(LAMBDA (X X) . 48 ) 
+QUOTE                    FUNCTION 
+(LAMBDA ((QUOTE X)) X) 
+LIST                     FUNCTION 
+(LAMBDA ((INDEFINITE X)) X) 
+DO                       FUNCTION 
+(LAMBDA ((INDEFINITE X)) NIL) 
+PUTLIST                 FUNCTION 
+(LAMBDA ((INDEFINITE X)) 
+  (COND 
+    ((NULL X) NIL) 
+    (T (DO (PUT (HEAD X)) (PUTLIST (TAIL X)))) 
+  ) 
+) 
+
diff --git a/menugenerator/Generatordatei: Archivmenu b/menugenerator/Generatordatei: Archivmenu
new file mode 100644
index 0000000..76393fc
--- /dev/null
+++ b/menugenerator/Generatordatei: Archivmenu	
@@ -0,0 +1,323 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                      ls-ARCHIV-                     ** 
+          **                 MENUTAFEL-GENERATOR                 ** 
+          **                     Version 1.0                     ** 
+          **                                                     ** 
+          **                  (Stand: 30.03.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+TEXT PROC dateiverzeichnistext: 
+   "      "15" Verzeichnis der vorhandenen Dateien "14""13""13"" 
+ + " Eine Liste  der vorhandenen Dateien wird  auf dem "13"" 
+ + " Bildschirm ausgegeben.                            "13""13"" 
+ + " Da die Liste selbst eine Datei ist,  kann man sie "13"" 
+ + " mit  der  Tastenfolge <ESC> <q> verlassen  -  das "13"" 
+ + " wird auch in der Kopfzeile angezeigt.             "13""13"" 
+ + " Innerhalb  der Liste kann man  sich wie  in einer "13"" 
+ + " Datei bewegen - nicht aber schreiben." 
+END PROC dateiverzeichnistext; 
+ 
+TEXT PROC dateiloeschentext: 
+   "                 "15" Dateien löschen "14"             "13""13"" 
+ + " Alle vorhandenen  Dateien werden zur  Auswahl angebo- "13"" 
+ + " ten.  Anschließend werden die angekreuzten Dateien in "13"" 
+ + " der Reihenfolge,  in der sie  angekreuzt wurden,  ge- "13"" 
+ + " löscht.                                               "13""13"" 
+ + " Zur Sicherheit muß noch einmal für jede  einzelne Da- "13"" 
+ + " tei  bestätigt werden,  daß sie auch  tatsächlich ge- "13"" 
+ + " löscht werden soll!" 
+END PROC dateiloeschentext; 
+ 
+TEXT PROC dateidruckentext: 
+   "                 "15" Dateien drucken "14"           "13""13"" 
+ + " Alle vorhandenen Dateien werden zur Auswahl angebo- "13"" 
+ + " ten.  Anschließend werden die  angekreuzten Dateien "13"" 
+ + " in  der Reihenfolge,  in der sie angekreuzt wurden, "13"" 
+ + " zum Drucker geschickt.                              "13""13"" 
+ + " Der Vorgang wird auf dem Bildschirm protokolliert." 
+END PROC dateidruckentext; 
+ 
+TEXT PROC dateikopierentext: 
+   "                      "15" Datei kopieren "14"               "13""13"" 
+ + " Der Dateiname der Datei, die kopiert werden soll,  wird er- "13"" 
+ + " fragt. Hier kann direkt ein Name eingegeben werden. Mit der "13"" 
+ + " Tastenfolge <ESC><z> kann man sich auch die vorhandenen Da- "13"" 
+ + " teien zur Auswahl anbieten lassen und hier einen  Namen an- "13"" 
+ + " kreuzen. Anschließend wird der Name für die Kopie erfragt.  "13""13"" 
+ + " Es muß ein Name eingetragen werden, der noch nicht für eine "13"" 
+ + " Datei vergeben wurde  -  ansonsten erfolgt ein  Hinweis da- "13"" 
+ + " rauf und es wird nicht kopiert!                             "13"" 
+ + " Da man aber oft für die Kopie einen ähnlichen Namen wie für "13"" 
+ + " das Original wählt, wird der 'alte' Name vorgeschlagen. Aus "13"" 
+ + " genannten Gründen muß er aber verändert werden." 
+END PROC dateikopierentext; 
+ 
+TEXT PROC dateiumbenennentext: 
+   "                      "15" Datei umbenennen "14"               "13""13"" 
+ + " Der Dateiname der Datei,  die umbenannt werden soll, wird er- "13"" 
+ + " fragt.  Hier kann direkt ein Name eingegeben werden.  Mit der "13"" 
+ + " Tastenfolge  <ESC><z>  kann man sich auch die vorhandenen Da- "13"" 
+ + " teien zur  Auswahl anbieten lassen  und dort einen  Namen an- "13"" 
+ + " kreuzen. Anschließend wird der zukünftige Dateiname erfragt.  "13""13"" 
+ + " Es muß ein Name eingetragen werden,  der noch  nicht für eine "13"" 
+ + " Datei vergeben wurde  -  ansonsten erfolgt ein Hinweis und es "13"" 
+ + " wird nicht umbenannt!                                         "13"" 
+ + " Da man aber oft den 'neuen' Namen in Anlehnung an den 'alten' "13"" 
+ + " Namen wählt, wird der 'alte' Name vorgeschlagen.  Aus genann- "13"" 
+ + " ten Gründen muß er aber verändert werden." 
+END PROC dateiumbenennentext; 
+ 
+TEXT PROC dateispeicherplatztext: 
+   "            "15" Datei-Speicherplatz ermitteln "14"     "13""13"" 
+ + " Der Dateiname der Datei, deren Speicherplatz ermittelt "13"" 
+ + " werden soll, wird erfragt.  Hier kann direkt ein  Name "13"" 
+ + " eingegeben werden.  Mit der Tastenfolge  <ESC><z> kann "13"" 
+ + " man sich auch die  vorhandenen Dateien zur Auswahl an- "13"" 
+ + " bieten lassen und dort Namen ankreuzen.                "13""13"" 
+ + " Der  belegte  Speicherplatz der ausgewählten Datei(en) "13"" 
+ + " wird ermittelt und auf dem Bildschirm angezeigt." 
+END PROC dateispeicherplatztext; 
+ 
+TEXT PROC dateiaufraeumtext: 
+   "           "15" Dateien aufräumen (reorganisieren) "14"   "13""13"" 
+ + " Der Dateiname der Datei,  die aufgeräumt (reorganisiert) "13"" 
+ + " werden soll,  wird erfragt.  Hier kann  direkt ein  Name "13"" 
+ + " eingegeben werden. Mit der Tastenfolge <ESC><z> kann man "13"" 
+ + " sich auch die  vorhandenen  Dateien zur Auswahl anbieten "13"" 
+ + " lassen und dort Namen ankreuzen.                         "13""13"" 
+ + " Anschließend werden die ausgewählten Dateien aufgeräumt, "13"" 
+ + " d.h. die  interne  Verwaltung  der Datei wird optimiert. "13"" 
+ + " Das führt zumeist dazu, daß die Datei anschließend weni- "13"" 
+ + " ger Speicherplatz belegt als zuvor.                      "13""13"" 
+ + " "15"Achtung! "14" Die Operation ist zeitaufwendig!!!" 
+END PROC dateiaufraeumtext; 
+ 
+ 
+(*------------------------------------------------------------------------*) 
+ 
+ 
+ 
+TEXT PROC archivreserviertext: 
+   "                 "15"Reservieren (des Archivlaufwerks) "14"    "13""13"" 
+ + " Das System versucht,  auf das Archiv zuzugreifen.  Ist das Archiv "13"" 
+ + " von keiner anderen Task benutzt, dann wird die Frage gestellt, ob "13"" 
+ + " die Diskette eingelegt ist.  Erst zu diesem Zeitpunkt ist sicher- "13"" 
+ + " gestellt, daß keine andere Task auf das Archiv zugreifen kann!"13""13"" 
+ + " Nach  Bejahen der gestellten Frage ermittelt das System selbstän- "13"" 
+ + " dig den Namen der  eingelegten Diskette,  zeigt den Namen auf dem "13"" 
+ + " Bildschirm an und aktiviert die anderen Menupunkte des Pull-Down- "13"" 
+ + " Menus.                                                        "13""13"" 
+ + " Beim Verlassen des Pull-Down-Menus oder wenn eine andere Zieltask "13"" 
+ + " eingestellt wird, wird die Reservierung automatisch aufgehoben!" 
+END PROC archivreserviertext; 
+ 
+TEXT PROC neuediskettetext: 
+   "                   "15"Neue Diskette (anmelden) "14"           "13""13"" 
+ + " Der Datenaustausch mit einer Diskette ist nur dann möglich,  wenn "13"" 
+ + " der  im System  eingestellte  Diskettenname  (auf dem  Bildschirm "13"" 
+ + " sichtbar) mit dem tatsächlichen Namen der Diskette übereinstimmt. "13""13"" 
+ + " Nach einem  Diskettenwechsel ist das aber  zumeist nicht mehr der "13"" 
+ + " Fall.  Nach Aktivieren  dieses Menupunktes wird der Name der ein- "13"" 
+ + " gelegten Diskette ermittelt, im System eingestellt und angezeigt. "13""13"" 
+ + " Im Gegensatz zum Menupunkt  'Reservieren'  greift das System ohne "13"" 
+ + " Anfrage  an den  Benutzer  auf  das Archiv zu  (die  Reservierung "13"" 
+ + " bleibt ja bestehen)." 
+END PROC neue diskettetext; 
+ 
+TEXT PROC archivschreibtext: 
+   "                       "15"Schreiben (Kopieren) "14"           "13""13"" 
+ + " Alle Dateien der  eigenen Task werden zur Auswahl angeboten.  An- "13"" 
+ + " schließend werden Kopien der angekreuzten  Dateien in der Reihen- "13"" 
+ + " folge  ihres Ankreuzens in die  eingestellte  Zieltask geschickt. "13"" 
+ + " Der Vorgang wird auf dem Bildschirm protokolliert.            "13""13"" 
+ + " Sind in der Zieltask schon Dateien mit  gleichem Namen vorhanden, "13"" 
+ + " so wird erfragt, ob diese dort gelöscht werden sollen.        "13""13"" 
+ + " Normalerweise ist als  Zieltask  das  Archiv der  eigenen Station "13"" 
+ + " eingestellt. Mit dem Menupunkt  'Zieltask einstellen'  kann diese "13"" 
+ + " Einstellung verändert werden." 
+END PROC archivschreibtext; 
+ 
+TEXT PROC archivchecktext: 
+   "                      "15"Checken (Prüfen) "14"          "13""13"" 
+ + " Alle Dateien der eingestellten  Zieltask (des Archivs) wer- "13"" 
+ + " den zur  Auswahl angeboten.  Anschließend werden  die ange- "13"" 
+ + " kreuzten  Dateien in der Reihenfolge ihres Ankreuzens  'ge- "13"" 
+ + " checkt', d.h. daraufhin untersucht,  ob sie ohne Fehler ge- "13"" 
+ + " lesen  werden können.  Der Vorgang wird auf dem  Bildschirm "13"" 
+ + " protokolliert.                                          "13""13"" 
+ + " Dieser Menupunkt kann  nur ausgeführt werden,  wenn der Da- "13"" 
+ + " teiaustausch mit einem Archiv(manager) erfolgt." 
+END PROC archivchecktext; 
+ 
+TEXT PROC archivkombinationstext: 
+   "                        "15"Kombination "14"                   "13""13"" 
+ + " Dieser  Menupunkt wirkt wie eine  Kombination  der Menupunkte "13"" 
+ + " 'Schreiben' und 'Checken' (Weitere Informationen dort).       "13""13"" 
+ + " Alle Dateien  der eigenen Task werden  zur Auswahl angeboten. "13"" 
+ + " Die angekreuzten Dateien werden in  der Reihenfolge ihres An- "13"" 
+ + " kreuzens in die eingestellte  Zieltask kopiert.  Anschließend "13"" 
+ + " werden alle Dateien, die gerade geschrieben wurden, gecheckt, "13"" 
+ + " d.h. auf Lesefehler hin untersucht. Beide Vorgänge werden auf "13"" 
+ + " dem Bildschirm protokolliert.                                 "13""13"" 
+ + " Dieser Menupunkt kann nur ausgeführt werden,  wenn der Datei- "13"" 
+ + " austausch mit einem Archiv(manager) erfolgt. " 
+END PROC archivkombinationstext; 
+ 
+ 
+TEXT PROC archivholtext: 
+   "                          "15"Holen / Lesen "14"               "13""13"" 
+ + " Alle Dateien der eingestellten  Zieltask werden zur Auswahl ange- "13"" 
+ + " boten. Anschließend werden Kopien der angekreuzten Dateien in der "13"" 
+ + " Reihenfolge  des Ankreuzens in die eigene Task kopiert.  Der Vor- "13"" 
+ + " gang wird auf dem Bildschirm protokolliert.                   "13""13"" 
+ + " Sind in der eigenen Task schon Dateien mit gleichem Namen vorhan- "13"" 
+ + " den, so wird gefragt,  ob die 'alten' Dateien  überschrieben (ge- "13"" 
+ + " löscht) werden dürfen.                                        "13""13"" 
+ + " Normalerweise werden  die Dateien vom  Archiv der eigenen Station "13"" 
+ + " geholt.  Mit dem Menupunkt  'Zieltask einstellen' kann diese Ein- "13"" 
+ + " stellung verändert werden." 
+END PROC archivholtext; 
+ 
+ 
+TEXT PROC archivloeschtext: 
+   "                         "15"Löschen "14"               "13""13"" 
+ + " Alle Dateien der eingestellten Zieltask werden zur Auswahl "13"" 
+ + " angeboten. Anschließend werden die angekreuzten Dateien in "13"" 
+ + " der Reihenfolge ihres Ankreuzens gelöscht.  Zur Sicherheit "13"" 
+ + " muß noch einmal für jede  einzelne Datei bestätigt werden, "13"" 
+ + " daß sie auch tatsächlich gelöscht werden soll.         "13""13"" 
+ + " Normalerweise ist als Zieltask das Archiv der eigenen Sta- "13"" 
+ + " tion eingestellt. Mit dem Menupunkt  'Zieltask einstellen' "13"" 
+ + " kann diese Einstellung verändert werden." 
+END PROC archivloeschtext; 
+ 
+TEXT PROC archivverzeichnistext: 
+   "                      "15"Verzeichnis "14"           "13""13"" 
+ + " Eine Liste aller Dateien, die in der Zieltask vorhanden "13"" 
+ + " sind, wird auf dem Bildschirm ausgegeben. Ist die Ziel- "13"" 
+ + " task ein Archiv (manager), so wird auch angezeigt, wie- "13"" 
+ + " viel Platz auf der Diskette belegt ist.             "13""13"" 
+ + " Da die Liste selbt eine Datei ist, kann man sie mit der "13"" 
+ + " Tastenfolge  <ESC> <q>  verlassen.  Innerhalb der Liste "13"" 
+ + " kann man sich wie im Editor bewegen." 
+END PROC archivverzeichnistext; 
+ 
+TEXT PROC archivdruckentext: 
+   "                     "15"Drucken "14"           "13""13"" 
+ + " Zur Sicherheit fragt das System an,  ob ein Datei- "13"" 
+ + " verzeichnis der Zieltask gedruckt werden soll. Be- "13"" 
+ + " jaht man diese Frage, so wird ein Dateiverzeichnis "13"" 
+ + " erstellt und zum Drucker geschickt." 
+END PROC archivdruckentext; 
+ 
+TEXT PROC archivinitialisiertext: 
+   "             "15"Initialisieren (Vollständiges Löschen) "14"   "13""13"" 
+ + " Zunächst erfragt das System, ob die Diskette auch formatiert wer- "13"" 
+ + " den soll.  Bejaht man  die Frage,  so werden  mehrere Formate zur "13"" 
+ + " Auswahl angeboten  -  anschließend wird die  Diskette  formatiert "13"" 
+ + " (wobei alle Inhalte "15"gelöscht "14" werden). Das Formatieren ist not-"13"" 
+ + " wendig, wenn man eine 'frische' Diskette verwendet.           "13""13"" 
+ + " In jedem Fall wird dann angefragt,  ob die Diskette initialisiert "13"" 
+ + " bzw. überschrieben werden soll (je nachdem, ob die Diskette schon "13"" 
+ + " benutzt wurde oder nicht). Nach Bejahen der gestellten Frage wird "13"" 
+ + " der Name der Diskette erfragt. Bei der Initialisierung erhält die "13"" 
+ + " Diskette einen (neuen) Namen und wird "15"vollständig gelöscht."14" "13"" 
+END PROC archivinitialisiertext; 
+ 
+TEXT PROC archivzieltasktext: 
+   "                      "15"Zieltask einstellen "14"             "13""13"" 
+ + " Das System bietet die Alternativen  'Archiv'-'Vatertask'-'PUBLIC' "13"" 
+ + " und 'Sonstige' zur Auswahl an. Bei der Wahl einer der ersten drei "13"" 
+ + " Möglichkeiten nimmt das System die vollständige  Einstellung vor, "13"" 
+ + " zeigt den Namen der eingestellten  Zieltask an und  aktiviert die "13"" 
+ + " zur Verfügung stehenden Menupunkte.                           "13""13"" 
+ + " Als Zieltask kann aber im Prinzip auch jede andere empfangsberei- "13"" 
+ + " te Task auf der Station oder irgendwo im Netz  (wenn installiert) "13"" 
+ + " gewählt werden.  Dazu wählt man die Alternative 'Sonstige'. Nach- "13"" 
+ + " einander werden der Name der Task und die Stationsnummer erfragt. "13"" 
+ + " Danach wird erfragt, ob die Zieltask ein Archiv(manager) ist. An- "13"" 
+ + " schließend verfährt das System wie oben beschrieben." 
+END PROC archivzieltasktext; 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+oeffne menukarte ("Archiv"); 
+ 
+oeffne menu   ("ARCHIV", "", "menu archiv reservierung aufgeben"); 
+ 
+oberbegriff   ("Dateien"); 
+                                            
+menufunktion  ("v", "Verzeichnis",          "menu dateien verzeichnis", 
+                                            dateiverzeichnistext); 
+trennlinie;                                 
+menufunktion  ("l", "Löschen",              "menu dateien loeschen", 
+                                            dateiloeschentext); 
+menufunktion  ("d", "Drucken",              "menu dateien drucken", 
+                                            dateidruckentext); 
+trennlinie;                                 
+menufunktion  ("k", "Kopieren",             "menu dateien kopieren", 
+                                            dateikopierentext); 
+menufunktion  ("u", "Umbenennen",           "menu dateien umbenennen", 
+                                            dateiumbenennentext); 
+trennlinie;                                 
+menufunktion  ("s", "Speicherplatz",        "menu dateien speicherplatz", 
+                                            dateispeicherplatztext); 
+menufunktion  ("a", "Aufräumen",            "menu dateien aufraeumen", 
+                                            dateiaufraeumtext); 
+ 
+ 
+ 
+oberbegriff   ("Archiv", "menu archiv grundeinstellung (4)", 
+                         "menu archiv reservierung aufgeben"); 
+ 
+menufunktion  ("r", "Reservieren",          "menu archiv reservieren", 
+                                            archivreserviertext); 
+menufunktion  ("n", "Neue Diskette",        "menu archiv neue diskette", 
+                                            neuediskettetext); 
+trennlinie; 
+menufunktion  ("s", "Schreiben",            "menu archiv schreiben", 
+                                            archivschreibtext); 
+menufunktion  ("c", "Checken",              "menu archiv checken", 
+                                            archivchecktext); 
+menufunktion  ("k", "Kombination",          "menu archiv schreibcheck", 
+                                            archivkombinationstext); 
+menufunktion  ("h", "Holen/Lesen",          "menu archiv holen", 
+                                            archivholtext); 
+menufunktion  ("l", "Löschen",              "menu archiv loeschen", 
+                                            archivloeschtext); 
+trennlinie;                            
+menufunktion  ("v", "Verzeichnis",          "menu archiv verzeichnis", 
+                                            archivverzeichnistext); 
+menufunktion  ("d", "Drucken",              "menu archiv verzeichnis drucken", 
+                                            archivdruckentext); 
+trennlinie;                                   
+menufunktion  ("i", "Initialisieren",       "menu archivinitialisieren", 
+                                            archivinitialisiertext); 
+menufunktion  ("z", "Zieltask einstellen",  "menu archiv zieltask einstellen", 
+                                            archivzieltasktext); 
+schliesse menu; 
+schliesse menukarte; 
+
+
diff --git a/menugenerator/fonttab.ls-Menu-Generator b/menugenerator/fonttab.ls-Menu-Generator
new file mode 100644
index 0000000..a5fd613
Binary files /dev/null and b/menugenerator/fonttab.ls-Menu-Generator differ
diff --git a/menugenerator/ls-MENUBASISTEXTE b/menugenerator/ls-MENUBASISTEXTE
new file mode 100644
index 0000000..48ef277
Binary files /dev/null and b/menugenerator/ls-MENUBASISTEXTE differ
diff --git a/menugenerator/ls-Menu-Generator 1 b/menugenerator/ls-Menu-Generator 1
new file mode 100644
index 0000000..b9dfd73
--- /dev/null
+++ b/menugenerator/ls-Menu-Generator 1	
@@ -0,0 +1,47 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                 ls-Menu-Generator 1                 ** 
+          **                                                     ** 
+          **                     Version 1.0                     ** 
+          **                                                     ** 
+          **                  (Stand: 30.03.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET ls menu generator 1 DEFINES{}       textprozedur,{}       textzeile:{}LET maxzeilenzahl     =   14,{}    maxzeichenzahl    =   65,{}    zentrierkennung   =  "%",{}    beginmarkkennung  =  "$",{}    endmarkkennung    =  "&",{}    unblockkennung    =  "�",{}    blank             =  " ",{}    dateikennung      = ".a";{}LET dateieintrag      = "#type (""10"")##limit (16.5)#",{}    stdfonttabelle    = "fonttab.ls-Menu-Generator";{}ROW 3 TEXT CONST fehlermeldung :: ROW 3 TEXT : ({}"existiert nicht!",{}
+""15"Text ist zu lang - bitte kürzen! "14"",{}""15"Zeilenformatierung mit <ESC> abgebrochen! "14""{});{}ROW 6 TEXT CONST hinweis :: ROW 6 TEXT : ({}"Bitte warten ...",{}"Zulässige    Zeilenzahl: ",{}"Tatsächliche Zeilenzahl: ",{}"Textlänge ist in Ordnung!",{}"Textprozedur ist erstellt!",{}"Textzeile ist erstellt!"{});{}PROC textprozedur (TEXT CONST dateiname, prozedurname):{}  BOOL VAR mit fehler;{}  formatiere (dateiname, mit fehler);{}  IF mit fehler{}     THEN errorstop (fehlermeldung [3]){}  FI;{}
+  bereite den text auf (dateiname);{}  erzeuge textprozedur (dateiname, prozedurname);{}  out (""7""); out (hinweis [5]);{}  last param (dateiname + dateikennung){}END PROC textprozedur;{}PROC textzeile (TEXT CONST dateiname):{}  BOOL VAR mit fehler;{}  formatiere (dateiname, mit fehler);{}  IF mit fehler{}     THEN errorstop (fehlermeldung [3]){}  FI;{}  bereite den text auf (dateiname);{}  erzeuge textzeile    (dateiname);{}  out (""7""); out (hinweis [6]);{}  last param (dateiname + dateikennung){}
+END PROC textzeile;{}PROC gib wartehinweis:{}  page;{}  out (hinweis [1]){}END PROC gib wartehinweis;{}PROC formatiere (TEXT CONST dateiname, BOOL VAR mit fehler):{}  TEXT VAR fonttabelle, zeileninhalt;{}  kontrolliere existenz;{}  stelle fonttabelle ein;{}  schreibe font in die datei;{}  zeilenformatierung;{}  entferne ggf font aus der datei;{}  stelle fonttabelle zurueck;{}  streiche restleerzeilen weg;{}  untersuche ggf datei auf korrektheit.{}  kontrolliere existenz:{}    IF NOT exists (dateiname){}
+       THEN page; errorstop ("'" + dateiname + "' " + fehlermeldung [1]){}    FI.{}  stelle fonttabelle ein:{}    gib wartehinweis;{}    fonttabelle := fonttable;{}    fonttable (stdfonttabelle).{}  schreibe font in die datei:{}    FILE VAR datei :: sequential file (modify, dateiname);{}    to line (datei, 1);{}    insert record (datei);{}    write record (datei, dateieintrag + blank).{}  zeilenformatierung:{}    disable stop;{}    lineform (dateiname);{}    IF is error{}       THEN clear error;{}
+            mit fehler := TRUE{}       ELSE mit fehler := FALSE{}    FI;{}    enable stop.{}  entferne ggf font aus der datei:{}    to line (datei, 1);{}    read record (datei, zeileninhalt);{}    IF pos (zeileninhalt, dateieintrag) > 0{}       THEN delete record (datei){}    FI.{}  stelle fonttabelle zurueck:{}    fonttable (fonttabelle).{}  streiche restleerzeilen weg:{}    REP{}      streiche ggf letzte zeile{}    UNTIL zeile ist nicht leer PER.{}  streiche ggf letzte zeile:{}    to line (datei, lines (datei));{}
+    read record (datei, zeileninhalt);{}    IF compress (zeileninhalt) = ""{}       THEN delete record (datei){}    FI.{}  zeile ist nicht leer:{}    compress (zeileninhalt) <> "".{}  untersuche ggf datei auf korrektheit:{}    IF NOT mit fehler{}       THEN untersuche zeilenzahl{}    FI.{}  untersuche zeilenzahl:{}    IF lines (datei) > maxzeilenzahl{}       THEN page;{}            out (hinweis [2] + text (maxzeilenzahl)); line;{}            out (hinweis [3] + text (lines (datei))); line (2);{}            errorstop (fehlermeldung [2]){}
+       ELSE page;{}            out (hinweis [4]){}    FI.{}END PROC formatiere;{}PROC bereite den text auf (TEXT CONST dateiname):{}  INT  VAR zaehler;{}  TEXT VAR zeileninhalt;{}  FILE VAR f :: sequential file (modify, dateiname);{}  gib wartehinweis;{}  vernichte ggf aufbereitete datei;{}  richte datei neu ein;{}  uebertrage die zeilen.{}  vernichte ggf aufbereitete datei:{}    IF exists (dateiname + dateikennung){}       THEN forget (dateiname + dateikennung, quiet){}    FI.{}  richte datei neu ein:{}
+    FILE VAR aus :: sequential file (output, dateiname + dateikennung).{}  uebertrage die zeilen:{}    FOR zaehler FROM 1 UPTO lines (f) REP{}      bereite eine zeile auf{}    PER.{}  bereite eine zeile auf:{}    to line (f, zaehler);{}    read record (f, zeileninhalt);{}    ersetze alle gaensefuesschen;{}    haenge ggf absatzmarke an;{}    behandle zeile;{}    putline (aus, zeileninhalt).{}  ersetze alle gaensefuesschen:{}    change all (zeileninhalt, """", "'").{}  haenge ggf absatzmarke an:{}    IF (zeileninhalt SUB (length (zeileninhalt))) = blank{}
+       THEN IF (zeileninhalt SUB 1) <> zentrierkennung{}               THEN zeileninhalt CAT unblockkennung{}            FI{}    FI.{}  behandle zeile:{}    IF   zeile soll zentriert werden{}         THEN zentriere zeile{}    ELIF zeile ist leerzeile{}         THEN kennzeichne leerzeile{}    ELSE blocke zeile auf stdlaenge{}    FI.{}  zeile soll zentriert werden:{}    (zeileninhalt SUB 1) = zentrierkennung.{}  zeile ist leerzeile:{}    compress (zeileninhalt) = "".{}  zentriere zeile:{}    zeileninhalt := subtext (zeileninhalt, 2);{}
+    zeileninhalt := anfangsblanks + zeileninhalt;{}    zeilenabschluss.{}  anfangsblanks:{}    ((maxzeichenzahl - length (zeileninhalt)) DIV 2) * blank.{}  zeilenabschluss:{}    ersetze markierungszeichen;{}    setze 13.{}  ersetze markierungszeichen:{}    change all (zeileninhalt, beginmarkkennung, """15""");{}    change all (zeileninhalt, endmarkkennung,    """14""").{}  setze 13:{}    zeileninhalt CAT " ""13""".{}  kennzeichne leerzeile:{}    zeileninhalt := """13""".{}  blocke zeile auf stdlaenge:{}
+    IF zeile darf nicht geblockt werden{}       THEN ersetze endezeichen{}       ELSE fuehre blockung aus{}    FI.{}  zeile darf nicht geblockt werden:{}    (zeileninhalt SUB length (zeileninhalt)) = unblockkennung.{}  ersetze endezeichen:{}    zeileninhalt := subtext (zeileninhalt, 1, length (zeileninhalt) - 1);{}    ersetze markierungszeichen;{}    setze 13.{}  fuehre blockung aus:{}    ROW maxzeichenzahl INT VAR leerzeichen;{}    INT VAR gezaehlte blanks, zu verteilende blanks;{}    ordne anfangswerte zu;{}
+    verteile blanks gleichmaessig;{}    verteile blanks zufaellig;{}    baue zeile zusammen;{}    ersetze markierungszeichen;{}    setze 13.{}  ordne anfangswerte zu:{}    bestimme blankanzahl in der zeile;{}    bestimme zu verteilende blanks;{}    initialisiere die reihung.{}  bestimme blankanzahl in der zeile:{}    gezaehlte blanks := 0;{}    INT VAR zeiger;{}    FOR zeiger FROM 1 UPTO length (zeileninhalt) REP{}      IF (zeileninhalt SUB zeiger) = blank{}         THEN gezaehlte blanks INCR 1{}
+      FI{}    PER.{}  bestimme zu verteilende blanks:{}    zu verteilende blanks := maxzeichenzahl - length (zeileninhalt).{}  initialisiere die reihung:{}    FOR zeiger FROM 1 UPTO gezaehlte blanks REP{}      leerzeichen [zeiger] := 1{}    PER.{}  verteile blanks gleichmaessig:{}    WHILE (zu verteilende blanks DIV gezaehlte blanks) > 0 REP{}      schlag je ein blank auf;{}      zu verteilende blanks DECR gezaehlte blanks{}    PER.{}  schlag je ein blank auf:{}    FOR zeiger FROM 1 UPTO gezaehlte blanks REP{}
+      leerzeichen [zeiger] INCR 1{}    PER.{}  verteile blanks zufaellig:{}    FOR zeiger FROM 1 UPTO zu verteilende blanks REP{}      leerzeichen [random (1, gezaehlte blanks)] INCR 1{}    PER.{}  baue zeile zusammen:{}    TEXT VAR zwischen        := zeileninhalt;{}    INT  VAR aktuelles blank := 0;{}    zeileninhalt             := "";{}    FOR zeiger FROM 1 UPTO length (zwischen) REP{}      TEXT VAR aktuelles zeichen :: (zwischen SUB zeiger);{}      IF aktuelles zeichen = blank{}         THEN aktuelles blank INCR 1;{}
+              zeileninhalt CAT (leerzeichen [aktuelles blank] * blank){}         ELSE zeileninhalt CAT aktuelles zeichen{}      FI{}    PER{}END PROC bereite den text auf;{}PROC erzeuge textprozedur (TEXT CONST dateiname, prozedurname):{}  mache aus den zeilen einzeltexte;{}  entferne ueberfluessige restzeilen;{}  erstelle eine textprozedur.{}  mache aus den zeilen einzeltexte:{}    INT  VAR zeiger;{}    FILE VAR ausdatei :: sequential file (modify, dateiname + dateikennung);{}    FOR zeiger FROM 1 UPTO lines (ausdatei) REP{}
+      bearbeite eine zeile{}    PER.{}  bearbeite eine zeile:{}    TEXT VAR zeileninhalt;{}    to line (ausdatei, zeiger);{}    read record (ausdatei, zeileninhalt);{}    zeileninhalt := """ " + zeileninhalt + """ +";{}    change all (zeileninhalt, "­", "-");{}    write record (ausdatei, zeileninhalt).{}  entferne ueberfluessige restzeilen:{}    REP{}      entferne ggf eine zeile{}    UNTIL zeileninhalt <> """   ""13"""" +" PER;{}    entferne return aus letzter zeile.{}  entferne ggf eine zeile:{}
+    IF compress (zeileninhalt) = """   ""13"""" +"{}       THEN delete record (ausdatei){}    FI.{}  entferne return aus letzter zeile:{}    to line (ausdatei, lines (ausdatei));{}    read record (ausdatei, zeileninhalt);{}    zeileninhalt := subtext (zeileninhalt, 1, length (zeileninhalt) - 6);{}    write record (ausdatei, zeileninhalt).{}  erstelle eine textprozedur:{}    schreibe procanfang;{}    schreibe procende.{}  schreibe procanfang:{}    to line (ausdatei, 1);{}    insert record (ausdatei);{}
+    write record (ausdatei, "TEXT PROC " + prozedurname + ":").{}  schreibe procende:{}    to line (ausdatei, lines (ausdatei) + 1);{}    insert record (ausdatei);{}    write record (ausdatei, "END PROC " + prozedurname + ";").{}END PROC erzeuge textprozedur;{}PROC erzeuge textzeile (TEXT CONST dateiname):{}  entferne ueberfluessige restzeilen;{}  entferne return aus letzter zeile;{}  erstelle eine textzeile.{}  entferne ueberfluessige restzeilen:{}    TEXT VAR zeileninhalt;{}    INT VAR zeiger;{}
+    FILE VAR ausdatei :: sequential file (modify, dateiname + dateikennung);{}    REP{}      entferne ggf eine zeile{}    UNTIL compress (zeileninhalt) <> """13""" PER.{}  entferne ggf eine zeile:{}    to line (ausdatei, lines (ausdatei));{}    read record (ausdatei, zeileninhalt);{}    IF compress (zeileninhalt) = """13"""{}       THEN delete record (ausdatei){}    FI.{}  entferne return aus letzter zeile:{}    to line (ausdatei, lines (ausdatei));{}    read record (ausdatei, zeileninhalt);{}    change all (zeileninhalt, """13""", "");{}
+    write record (ausdatei, zeileninhalt).{}  erstelle eine textzeile:{}    haenge die zeilen aneinander;{}    fasse zeile in gaensefuesschen;{}    schreibe einzelzeile in ausgabedatei.{}  haenge die zeilen aneinander:{}    TEXT VAR zeile :: "";{}    FOR zeiger FROM 1 UPTO lines (ausdatei) REP{}      to line (ausdatei, zeiger);{}      read record (ausdatei, zeileninhalt);{}      zeile CAT (" " + zeileninhalt){}    PER.{}  fasse zeile in gaensefuesschen:{}    zeile := """" + zeile + """";{}    change all (zeile, "­","-").{}
+  schreibe einzelzeile in ausgabedatei:{}    forget (dateiname + dateikennung, quiet);{}    FILE VAR fertig :: sequential file (modify, dateiname + dateikennung);{}    to line (fertig, 1);{}    insert record (fertig);{}    write record (fertig, zeile){}END PROC erzeuge textzeile;{}END PACKET ls menu generator 1;{}
+
diff --git a/menugenerator/ls-Menu-Generator 2 b/menugenerator/ls-Menu-Generator 2
new file mode 100644
index 0000000..608f680
--- /dev/null
+++ b/menugenerator/ls-Menu-Generator 2	
@@ -0,0 +1,72 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                 ls-Menu-Generator 2                 ** 
+          **                                                     ** 
+          **                     Version 1.0                     ** 
+          **                                                     ** 
+          **                  (Stand: 30.03.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+PACKET ls menu generator 2 DEFINES{}            oeffne menukarte,{}            oeffne menu,{}            oberbegriff,{}            menufunktion,{}            trennlinie,{}            schliesse menu,{}            schliesse menukarte,{}            testinstallation:{}LET menutafeltype         = 1954,{}    kennung               = "ls - Menu - Generator",{}    mm taskname           = "ls-MENUKARTEN",{}    menutafelpraefix      = "ls-MENUKARTE:",{}    menu grundtext        = "ls-MENUBASISTEXTE",{}    zwischenablagename    = "MENU-ZWISCHENABLAGEDATEI INTERN";{}
+LET maxmenus              =    6,{}    maxmenutexte          =  300,{}    maxinfotexte          = 2000,{}    maxhauptmenupunkte    =   10,{}    maxuntermenupunkte    =   15,{}    maxmenubreite         =   71;   (* Breite der Hauptmenüzeile - 2 *){}LET blank                 =    " ",{}    cleop                 =  ""4"",{}    piep                  =  ""7"",{}    trennzeilensymbol     =  "###",{}    bleibt leer symbol    =  "***",{}    hauptmenuluecke       =  "  ";{}LET dummyname             =  "Dummy für Anwendertexte",{}
+    install finished      =  "Installation abgeschlossen!",{}    card finished         =  "Menukartengenerierung abgeschlossen!",{}    filetype              =  1003;{}TYPE MENUPUNKT   = STRUCT (TEXT punktkuerzel,{}                                punktname,{}                                procname,{}                                boxtext,{}                           BOOL aktiv,{}                                angewaehlt),{}     EINZELMENU  = STRUCT (INT  belegt,{}                           TEXT ueberschrift,{}
+                           INT  anfangsposition,{}                                maxlaenge,{}                           ROW  maxuntermenupunkte MENUPUNKT menupunkt,{}                           INT  aktueller untermenupunkt,{}                           TEXT startprozedurname,{}                                leaveprozedurname),{}     MENU        = STRUCT (TEXT menuname,{}                           INT  anzahl hauptmenupunkte,{}                           ROW  maxhauptmenupunkte EINZELMENU einzelmenu,{}
+                           TEXT menueingangsprozedur,{}                                menuausgangsprozedur,{}                                menuinfo,{}                                lizenznummer,{}                                versionsnummer,{}                           INT  hauptmenuzeiger,{}                                untermenuanfang,{}                                untermenuzeiger),{}     INFOTEXT    = STRUCT (INT anzahl infotexte,{}                           ROW maxinfotexte TEXT stelle),{}
+     MENUTEXT    = STRUCT (INT anzahl menutexte,{}                           ROW maxmenutexte TEXT platz),{}     MENULEISTE  = STRUCT (INT belegt, zeigeraktuell, zeigerhintergrund,{}                           ROW maxmenus MENU menu,{}                           MENUTEXT   menutext,{}                           INFOTEXT   infotext);{}ROW 14 TEXT CONST aussage :: ROW 14 TEXT : ({}"ACHTUNG - Eine Menukarte mit diesem Namen existiert bereits - ACHTUNG",{}"Kann die bereits existierende Menukarte gelöscht werden",{}
+"Dann kann keine neue Menukarte mit diesem Namen erstellt werden!",{}"Zum Weitermachen bitte irgendeine Taste tippen!",{}"Sollen auch Anwendungstexte in die Menukarte aufgenommen werden",{}"Auswahl der Datei, in der die Anwendungstexte stehen.",{}"Bitte die gewünschte Datei ankreuzen!",{}"Durchgang 1 von 2 Durchgängen - in Arbeit ist Zeile: ",{}"Durchgang 2 von 2 Durchgängen - in Arbeit ist Zeile: ",{}"",{}"Einlesen von Texten aus Datei : ",{}"Bearbeitet  wird Menu         : ",{}"Eingetragen wird Oberbegriff  : ",{}
+"Eingetragen wird Menufunktion : "{});{}ROW 22 TEXT CONST fehlermeldung :: ROW 22 TEXT : ({}"Ohne die Datei '",{}"' "13""10""10"         ist die Menuerstellung "15"unmöglich "14"!!",{}"Hier muß unbedingt eine Datei angekreuzt werden!",{}"Ausgewählte Datei hat falschen Typ (<> 1003) )",{}"Zu viele Anwendungstexte in der Datei ",{}"Anführungszeichen fehlt am Anfang oder Ende der Zeile ",{}"Anführungszeichen fehlt irgendwo in Zeile ",{}"Die angegebene Datei existiert nicht!",{}"Menukarte noch nicht geöffnet ('oeffne menukarte' fehlt)! ",{}
+"Vorausgehendes Menu nicht geschlossen! ",{}"Zu viele Menus in der Menukarte (> " + text (maxmenus) + ")!",{}"Menuname ist mehrfach vorhanden!",{}"Menu noch nicht geoeffnet ('oeffne menu' fehlt)!",{}"Zu viele Oberbegriffe in einem Menu (> " + text (maxhauptmenupunkte) + ")!",{}"Die Kopfzeile ist zu lang (> " + text (maxmenubreite)  + ")!",{}"Menupunkt-Kürzel ist länger als ein Zeichen!",{}"Menupunkt-Kürzel kommt mehrfach vor (nicht eindeutig)!",{}"Menupunkt-Bezeichnung ist zu lang!",{}"Zu viele (> " + text (maxuntermenupunkte) + ") Menupunkte in einem Pull-Down-Menu!",{}
+"Menukarte '",{}"' gibt es nicht in dieser Task!",{}"' hat falsche(n) Typ/Bezeichnung"{});{}TEXT VAR menuinfotextdateiname,{}         aktueller menudateiname;{}BOOL VAR menuleiste ist bereit :: FALSE,{}         menu ist geoeffnet    :: FALSE;{}BOUND MENULEISTE VAR menuleiste;{}BOUND MENUTEXT   VAR basistexte;{}BOUND MENU       VAR aktuelles menu;{}DATASPACE VAR ds;{}OP := (MENUTEXT VAR ziel, MENUTEXT VAR quelle):{}  INT VAR z;{}  ziel.anzahl menutexte := quelle.anzahl menutexte;{}  FOR z FROM 1 UPTO quelle.anzahl menutexte REP{}
+    ziel.platz [z] := quelle.platz [z]{}  PER{}END OP :=;{}OP := (MENU VAR ziel, MENU CONST quelle):{}  CONCR (ziel) := CONCR (quelle){}END OP :=;{}OP := (EINZELMENU VAR ziel, EINZELMENU CONST quelle):{}  CONCR (ziel) := CONCR (quelle){}END OP :=;{}OP := (MENUPUNKT VAR ziel, MENUPUNKT CONST quelle):{}  CONCR (ziel) := CONCR (quelle){}END OP :=;{}PROC oeffne menukarte (TEXT CONST menukartenname):{}  gib bildschirmhinweis aus;{}  ueberpruefe voraussetzungen;{}  erfrage den namen der datei mit den anwendertexten;{}
+  erstelle neue menuleiste.{}  gib bildschirmhinweis aus:{}    page; out (center (invers (kennung))).{}  ueberpruefe voraussetzungen:{}    ueberpruefe ob basistexte vorhanden sind;{}    ueberpruefe ob menukarte schon vorhanden ist.{}  ueberpruefe ob basistexte vorhanden sind:{}    IF NOT exists (menu grundtext){}       THEN gib hinweis und brich ab{}    FI.{}  gib hinweis und brich ab:{}    disable stop;{}    fetch (menu grundtext, /mm taskname);{}    IF is error{}       THEN clear error;{}            enable stop;{}
+            cursor (1, 4); out (cleop);{}            errorstop (fehlermeldung [1] + menu grundtext + fehlermeldung [2]){}       ELSE clear error;{}            enable stop{}    FI.{}  ueberpruefe ob menukarte schon vorhanden ist:{}    IF exists (menukarte){}       THEN gib hinweis auf vorhandene menukarte;{}            frage ob die alte karte geloescht werden darf{}    FI.{}  menukarte:{}    menutafelpraefix + menukartenname.{}  gib hinweis auf vorhandene menukarte:{}    cursor (1, 4); out (cleop);{}
+    cursor (1, 4); out (center (menukarte));{}    cursor (1, 6); out (center (invers (aussage [1]))).{}  frage ob die alte karte geloescht werden darf:{}    cursor (2, 9);{}    IF yes (aussage [2]){}       THEN forget (menukarte, quiet){}       ELSE weiterarbeit ist unmoeglich{}    FI.{}  weiterarbeit ist unmoeglich:{}    cursor (1, 12); out (center (invers (aussage [3])));{}    cursor (2, 15); out (aussage [4]);{}    cursor (2, 16); pause; page;{}    errorstop ("").{}  erfrage den namen der datei mit den anwendertexten:{}
+    cursor (1, 4); out (cleop);{}    IF yes (aussage [5]){}       THEN biete dateiauswahl an{}       ELSE erzeuge dateidummy{}    FI.{}  biete dateiauswahl an:{}    menuinfotextdateiname := one (2, 6, 77, 19, ALL myself,{}                                  aussage [6], aussage [7]);{}    ueberpruefe den dateinamen;{}    ueberpruefe den dateityp.{}  ueberpruefe den dateinamen:{}    IF compress (menuinfotextdateiname) = ""{}       THEN page; errorstop (fehlermeldung [3]){}    FI.{}  ueberpruefe den dateityp:{}
+    IF datei hat falschen typ{}       THEN page; errorstop (fehlermeldung [4]){}    FI.{}  datei hat falschen typ:{}    ds := old (menuinfotextdateiname);{}    IF type (ds) <> filetype{}       THEN forget (ds); TRUE{}       ELSE forget (ds); FALSE{}    FI.{}  erzeuge dateidummy:{}    forget (dummyname, quiet);{}    FILE VAR datei :: sequential file (modify, dummyname);{}    to line (datei, 1);{}    menuinfotextdateiname := dummyname.{}  erstelle neue menuleiste:{}    INT  VAR zeiger;{}    TEXT VAR zeileninhalt;{}
+    initialisiere werte;{}    aktueller menudateiname  := menukarte;{}    menuleiste               := new (aktueller menudateiname);{}    type (old (aktueller menudateiname), menutafeltype);{}    menuleiste.belegt        := 0;{}    menuleiste ist bereit    := TRUE;{}    trage menubasistexte ein;{}    trage anwendungstexte ein.{}  initialisiere werte:{}    menuleiste ist bereit  := FALSE;{}    menu ist geoeffnet     := FALSE.{}  trage menubasistexte ein:{}    basistexte             := old (menu grundtext);{}
+    menuleiste.menutext    := basistexte.{}  trage anwendungstexte ein:{}    konvertiere (menuinfotextdateiname, zwischenablagename,{}                 menuleiste.infotext.anzahl infotexte);{}    ueberpruefe anwendungstextanzahl;{}    trage anwendungstexte in die menuleiste.{}  ueberpruefe anwendungstextanzahl:{}    IF menuleiste.infotext.anzahl infotexte > maxinfotexte{}       THEN forget (zwischenablagename,      quiet);{}            forget (aktueller menudateiname, quiet);{}            errorstop (fehlermeldung [5] + "'" + menuinfotextdateiname + "'"){}
+    FI.{}  trage anwendungstexte in die menuleiste:{}    gib hinweis auf anwendungstexteintrag;{}    FILE VAR ein :: sequential file (input, zwischenablagename);{}    FOR zeiger FROM 1 UPTO menuleiste.infotext.anzahl infotexte REP{}      getline (ein, zeileninhalt);{}      menuleiste.infotext.stelle [zeiger] := zeileninhalt;{}      cout (zeiger){}    PER;{}    forget (zwischenablagename, quiet);{}    forget (dummyname         , quiet).{}  gib hinweis auf anwendungstexteintrag:{}    cursor (1, 7); out (aussage [9]).{}
+END PROC oeffne menukarte;{}PROC konvertiere (TEXT CONST eingabedatei, ausgabedatei,{}                  INT  VAR   anzahl konvertierter saetze):{}  loesche ausgabedatei;{}  untersuche eingabedatei;{}  konvertiere saetze.{}  loesche ausgabedatei:{}    IF exists (ausgabedatei){}       THEN forget (ausgabedatei, quiet){}    FI.{}  untersuche eingabedatei:{}    IF NOT exists (eingabedatei){}       THEN errorstop (fehlermeldung [8]){}    FI.{}  konvertiere saetze:{}    gib hinweis;{}    konvertiere satzweise.{}
+  gib hinweis:{}    cursor (1, 4); out (cleop);{}    cursor (1, 4); out (aussage [11] + "'" + eingabedatei + "'");{}    cursor (1, 6); out (aussage [ 8]);{}    anzahl konvertierter saetze := 0.{}  konvertiere satzweise:{}    TEXT VAR zeileninhalt :: "";{}    FILE VAR eingabe :: sequential file (input, eingabedatei);{}    WHILE NOT eof (eingabe) REP{}      behandle eine dateizeile{}    PER;{}    optimiere ausgabedatei.{}  behandle eine dateizeile:{}    getline (eingabe, zeileninhalt);{}    anzahl konvertierter saetze INCR 1;{}
+    cout (anzahl konvertierter saetze);{}    untersuche zeile;{}    wandle die zeile um;{}    FILE VAR aus :: sequential file (output, ausgabedatei);{}    write (aus, textausgabe).{}  untersuche zeile:{}    zeileninhalt := compress (zeileninhalt);{}    IF zeileninhalt = ""{}       THEN zeileninhalt := """"""{}    FI;{}    IF    (zeileninhalt SUB 1)                     <> """"{}       OR (zeileninhalt SUB length (zeileninhalt)) <> """"{}       THEN bereite abgang vor;{}            errorstop (fehlermeldung [6] + text (anzahl konvertierter saetze)){}
+    FI.{}  wandle die zeile um:{}    TEXT VAR textausgabe :: "", codekette;{}    zeileninhalt := subtext (zeileninhalt, 2, length (zeileninhalt) - 1);{}    WHILE gaensefuesschenposition > 0 REP{}        textausgabe CAT subtext (zeileninhalt, 1, gaensefuesschenposition - 1);{}        zeileninhalt := subtext (zeileninhalt, gaensefuesschenposition);{}        codekette    := subtext (zeileninhalt, 1, pos (zeileninhalt, """", 2));{}        IF   codekette =  """7"""{}             THEN textausgabe CAT  ""7""{}
+        ELIF codekette =  """5"""{}             THEN textausgabe CAT  ""5""{}        ELIF codekette =  """4"""{}             THEN textausgabe CAT  ""4""{}        ELIF codekette =  """10"""{}             THEN textausgabe CAT ""10""{}        ELIF codekette = """13"""{}             THEN textausgabe CAT ""13""{}        ELIF codekette = """14"""{}             THEN textausgabe CAT ""14""{}        ELIF codekette = """15"""{}             THEN textausgabe CAT ""15""{}        ELIF codekette = """"""{}             THEN textausgabe CAT """"{}
+        ELSE errorstop (fehlermeldung [7] +{}                        text (anzahl konvertierter saetze)){}        FI;{}        zeileninhalt := subtext (zeileninhalt, 1 + length (codekette)){}      PER;{}      textausgabe CAT zeileninhalt.{}    gaensefuesschenposition:{}      pos (zeileninhalt, """").{}    bereite abgang vor:{}      forget (ausgabedatei, quiet);{}      line (2).{}  optimiere ausgabedatei:{}    FILE VAR ausgabe :: sequential file (modify, ausgabedatei);{}    WHILE lines (ausgabe) > 0 CAND letzter satz ist leer REP{}
+      to line (ausgabe, lines (ausgabe));{}      delete record (ausgabe);{}      anzahl konvertierter saetze DECR 1;{}      cout (anzahl konvertierter saetze ){}    PER.{}  letzter satz ist leer:{}   TEXT VAR satz;{}   to line (ausgabe,lines (ausgabe));{}   read record (ausgabe, satz);{}   IF compress (satz) = "" OR compress (satz) = ""13""{}      THEN TRUE{}      ELSE FALSE{}   FI.{}END PROC konvertiere;{}PROC oeffne menu (TEXT CONST name, einstiegsproc, ausstiegsproc,{}                             itext, ltext, vtext):{}
+  gib hinweis auf geoeffnetes menu;{}  ueberpruefe auf ungereimtheiten;{}  nimm eintragungen in datenraum vor.{}  gib hinweis auf geoeffnetes menu:{}    cursor (1, 4); out (cleop);{}    out (aussage [12]); out (invers (name));{}    cursor (1, 6).{}  ueberpruefe auf ungereimtheiten:{}    pruefe auf bereits geoeffnete menuliste;{}    pruefe auf noch geoeffnetes menu;{}    pruefe auf noch freie menuplaetze;{}    pruefe auf schon vorhandenen menunamen.{}  pruefe auf bereits geoeffnete menuliste:{}    IF NOT menuleiste ist bereit{}
+       THEN bereinige eintragungen (9){}    FI.{}  pruefe auf noch geoeffnetes menu:{}    IF menu ist geoeffnet{}       THEN bereinige eintragungen (10){}    FI.{}  pruefe auf noch freie menuplaetze:{}    IF menuleiste.belegt = maxmenus{}       THEN bereinige eintragungen (11){}    FI.{}  pruefe auf schon vorhandenen menunamen:{}    IF menuname schon vorhanden{}       THEN bereinige eintragungen (12){}    FI.{}  menuname schon vorhanden:{}    INT VAR i;{}    FOR i FROM 1 UPTO menuleiste.belegt REP{}
+      untersuche einzelnen menunamen{}    PER;{}    FALSE.{}  untersuche einzelnen menunamen:{}    IF menuleiste.menu [i].menuname = compress (name){}       THEN LEAVE menuname schon vorhanden WITH TRUE{}    FI.{}  nimm eintragungen in datenraum vor:{}    forget (ds);{}    ds                                  := nilspace;{}    aktuelles menu                      := ds;{}    init (aktuelles menu);{}    aktuelles menu.menuname             := compress (name);{}    aktuelles menu.menueingangsprozedur := compress (einstiegsproc);{}
+    aktuelles menu.menuausgangsprozedur := compress (ausstiegsproc);{}    IF itext <> ""{}        THEN aktuelles menu.menuinfo          := itext;{}             aktuelles menu.lizenznummer      := ltext;{}             aktuelles menu.versionsnummer    := vtext{}        ELSE aktuelles menu.menuinfo          := bleibt leer symbol;{}             aktuelles menu.lizenznummer      := "";{}             aktuelles menu.versionsnummer    := ""{}    FI;{}    menu ist geoeffnet      := TRUE.{}END PROC oeffne menu;{}
+PROC oeffne menu (TEXT CONST name, einstiegsproc, ausstiegsproc):{}  oeffne menu (name, einstiegsproc, ausstiegsproc, "", "", ""){}END PROC oeffne menu;{}PROC oeffne menu (TEXT CONST name):{}  oeffne menu (name, "", "", "", "", ""){}END PROC oeffne menu;{}PROC bereinige eintragungen (INT CONST nummer):{}  forget (ds);{}  forget (aktueller menudateiname, quiet);{}  menuleiste ist bereit := FALSE;{}  menu ist geoeffnet    := FALSE;{}  errorstop (fehlermeldung [nummer]){}END PROC bereinige eintragungen;{}
+PROC init (MENU VAR m):{}  m.menuname                         := "";{}  m.hauptmenuzeiger                  := 1;{}  m.untermenuanfang                  := 0;{}  m.untermenuzeiger                  := 0;{}  m.menueingangsprozedur             := "";{}  m.menuausgangsprozedur             := "";{}  m.menuinfo                         := "";{}  m.versionsnummer                   := "";{}  m.anzahl hauptmenupunkte           := 0;{}  belege hauptmenupunkte.{}  belege hauptmenupunkte:{}    INT VAR i;{}    FOR i FROM 1 UPTO maxhauptmenupunkte REP{}
+      aktuelles einzelmenu.belegt                     :=   0;{}      aktuelles einzelmenu.ueberschrift               :=  "";{}      aktuelles einzelmenu.anfangsposition            :=   0;{}      aktuelles einzelmenu.maxlaenge                  :=   0;{}      aktuelles einzelmenu.aktueller untermenupunkt   :=   1;{}      aktuelles einzelmenu.startprozedurname          :=  "";{}      aktuelles einzelmenu.leaveprozedurname          :=  "";{}      belege untermenuepunkte{}    PER.{}   belege untermenuepunkte:{}
+     INT VAR j;{}     FOR j FROM 1 UPTO maxuntermenupunkte REP{}       aktueller menupunkt.punktkuerzel := "";{}       aktueller menupunkt.punktname    := "";{}       aktueller menupunkt.procname     := "";{}       aktueller menupunkt.boxtext      := "";{}       aktueller menupunkt.aktiv        := TRUE;{}       aktueller menupunkt.angewaehlt   := FALSE{}     PER.{}   aktuelles einzelmenu: m.einzelmenu [i].{}   aktueller menupunkt: aktuelles einzelmenu.menupunkt [j].{}END PROC init;{}PROC oberbegriff (TEXT CONST punktname, startprocname, leaveprocname):{}
+  gib hinweis auf oberbegriff;{}  untersuche ob menu geoeffnet und bereit ist;{}  untersuche oberbegriffe;{}  trage neuen oberbegriff ein;{}  notiere die anfangsposition;{}  notiere start und leaveprozedur;{}  erhoehe die anzahl der oberbegriffe.{}  gib hinweis auf oberbegriff:{}    cursor (1, 6); out (cleop);{}    cursor (1, 6); out (aussage [13]); out (invers (punktname)); line.{}  untersuche ob menu geoeffnet und bereit ist:{}    IF NOT menuleiste ist bereit{}       THEN bereinige eintragungen ( 9){}
+    FI;{}    IF NOT menu ist geoeffnet{}       THEN bereinige eintragungen (13){}    FI.{}  untersuche oberbegriffe:{}    IF zu viele oberbegriffe{}       THEN bereinige eintragungen (14){}    FI;{}    IF gesamtlaenge > maxmenubreite{}       THEN bereinige eintragungen (15){}    FI.{}  zu viele oberbegriffe:{}    aktuelles menu.anzahl hauptmenupunkte = maxhauptmenupunkte.{}  gesamtlaenge:{}    gesamtlaenge ohne letzten punkt + length (compress (punktname)).{}  gesamtlaenge ohne letzten punkt:{}    length (hauptmenuzeile).{}
+  hauptmenuzeile:{}    INT VAR zaehler;{}    TEXT VAR zeile :: "";{}    schreibe menunamen;{}    schreibe oberbegriffe;{}    zeile.{}  schreibe menunamen:{}    IF aktuelles menu. menuname <> ""{}       THEN zeile CAT aktuelles menu.menuname;{}            zeile CAT ":"{}    FI.{}  schreibe oberbegriffe:{}    FOR zaehler FROM 1 UPTO aktuelles menu.anzahl hauptmenupunkte REP{}      zeile CAT hauptmenuluecke;{}      zeile CAT aktuelles menu. einzelmenu [zaehler].ueberschrift{}    PER;{}    zeile CAT hauptmenuluecke.{}
+  trage neuen oberbegriff ein:{}    neuer menupunkt.ueberschrift     := compress (punktname).{}  notiere die anfangsposition:{}    neuer menupunkt.anfangsposition  := gesamtlaenge ohne letzten punkt + 1.{}  notiere start und leaveprozedur:{}    neuer menupunkt.startprozedurname := compress (startprocname);{}    neuer menupunkt.leaveprozedurname := compress (leaveprocname).{}  neuer menupunkt:{}    aktuelles menu.einzelmenu [aktuelles menu.anzahl hauptmenupunkte + 1].{}  erhoehe die anzahl der oberbegriffe:{}
+    aktuelles menu.anzahl hauptmenupunkte INCR 1.{}END PROC oberbegriff;{}PROC oberbegriff (TEXT CONST punktname):{}  oberbegriff (punktname, "", ""){}END PROC oberbegriff;{}PROC menufunktionseintrag (TEXT CONST kuerzel,{}                                      punktbezeichnung,{}                                      prozedurname,{}                                      infotext,{}                           BOOL CONST ist aktiv):{}  gib hinweis auf menufunktionseintrag;{}  trage menupunkt ein;{}  organisiere menu neu.{}
+  gib hinweis auf menufunktionseintrag:{}    line;{}    out (aussage [14]);{}    out ("'" + kuerzelzeichen  + "' - " + punktname).{}  kuerzelzeichen:{}    IF kuerzel = "" THEN " " ELSE kuerzel FI.{}  punktname:{}    IF punktbezeichnung = trennzeilensymbol{}       THEN "----------"{}       ELSE punktbezeichnung{}    FI.{}  trage menupunkt ein:{}    ueberpruefe das kuerzel;{}    ueberpruefe die punktbreite;{}    ueberpruefe die eintragsnummer;{}    aktuelles menu.einzelmenu [stelle].belegt INCR 1;{}
+    aktueller menupunkt.punktkuerzel  := compress (kuerzel);{}    aktueller menupunkt.punktname     := normierter menupunkt;{}    aktueller menupunkt.procname      := compress (prozedurname);{}    aktueller menupunkt.boxtext       := infotext;{}    aktueller menupunkt.aktiv         := ist aktiv;{}    aktueller menupunkt.angewaehlt    := FALSE.{}  aktueller menupunkt:{}    aktuelles untermenu.menupunkt [aktuelles untermenu.belegt].{}  aktuelles untermenu:{}    aktuelles menu.einzelmenu [stelle].{}
+  stelle:{}    aktuelles menu.anzahl hauptmenupunkte.{}  normierter menupunkt:{}    blank + compress (punktbezeichnung).{}  ueberpruefe das kuerzel:{}    TEXT VAR kurz :: compress (kuerzel);{}    IF   kuerzel ist zu lang{}         THEN bereinige eintragungen (16){}    ELIF kuerzel ist schon vorhanden{}         THEN bereinige eintragungen (17){}    FI.{}  kuerzel ist zu lang:{}    length (kurz) > 1.{}  kuerzel ist schon vorhanden:{}    (length (kurz) = 1) AND (pos (vorhandene kuerzel, kurz) > 0).{}
+  vorhandene kuerzel:{}    TEXT VAR liste :: "";{}    INT VAR zeiger;{}    FOR zeiger FROM 1 UPTO aktuelles untermenu.belegt REP{}      liste CAT aktuelles untermenu.menupunkt [zeiger].punktkuerzel{}    PER;{}    liste.{}  ueberpruefe die punktbreite:{}    IF length (compress (punktbezeichnung)) > maxmenubreite - 10{}       THEN bereinige eintragungen (18){}    FI.{}  ueberpruefe die eintragsnummer:{}    IF aktuelles untermenu.belegt = maxuntermenupunkte{}       THEN bereinige eintragungen (19){}
+    FI.{}  organisiere menu neu:{}    IF neue punktlaenge > aktuelles untermenu.maxlaenge{}       THEN aktuelles untermenu.maxlaenge := neue punktlaenge{}    FI.{}  neue punktlaenge:{}    length (aktueller menupunkt.punktname).{}END PROC menufunktionseintrag;{}PROC menufunktion (TEXT CONST kuerzel, punktbezeichnung,{}                              prozedurname, infotext):{}  menufunktionseintrag (kuerzel, punktbezeichnung, prozedurname, infotext,{}                        TRUE){}END PROC menufunktion;{}
+PROC trennlinie:{}  menufunktionseintrag ("", trennzeilensymbol, "", "", FALSE){}END PROC trennlinie;{}PROC schliesse menu:{}  menuleiste. belegt INCR 1;{}  menuleiste.menu [menuleiste.belegt] := aktuelles menu;{}  menu ist geoeffnet                  := FALSE{}END PROC schliesse menu;{}PROC schliesse menukarte:{}  forget (ds);{}  page; out (piep); put (card finished){}END PROC schliesse menukarte;{}PROC testinstallation (TEXT CONST kartenname):{}  ueberpruefe menukarte;{}  nimm installation vor.{}
+  ueberpruefe menukarte:{}    IF   NOT exists (kartenname){}         THEN errorstop (fehlermeldung [20] + kartenname + fehlermeldung [21]){}    ELIF    (pos (kartenname, menutafelpraefix) <> 1){}         OR (type (old (kartenname)) <> menutafeltype){}         THEN errorstop (fehlermeldung [20] + kartenname + fehlermeldung [22]){}    FI.{}  nimm installation vor:{}    TEXT CONST neuer kartenname{}                    :: kartenname + "  von Task '" + name (myself) + "'";{}    command dialogue (FALSE);{}
+    rename (kartenname, neuer kartenname);{}    save (neuer kartenname,task (mmtaskname));{}    forget (neuer kartenname, quiet);{}    reset dialog;{}    install menu (neuer kartenname, FALSE);{}    fetch (neuer kartenname, task (mmtaskname));{}    rename (neuer kartenname, kartenname);{}    command dialogue (TRUE);{}    page; out (piep); put (install finished){}END PROC testinstallation;{}END PACKET ls menu generator 2;{}
+
diff --git a/menugenerator/ls-Menu-Generator-gen b/menugenerator/ls-Menu-Generator-gen
new file mode 100644
index 0000000..9a4c3fc
--- /dev/null
+++ b/menugenerator/ls-Menu-Generator-gen
@@ -0,0 +1,30 @@
+(* 
+        
+          ********************************************************* 
+          ********************************************************* 
+          **                                                     ** 
+          **                  ls-Menu-Generator                  ** 
+          **                  GENERATORPROGRAMM                  ** 
+          **                     Version 1.0                     ** 
+          **                                                     ** 
+          **                  (Stand: 30.03.88)                  ** 
+          **                                                     ** 
+          **                                                     ** 
+          **         Autor: Wolfgang Weber, Bielefeld            ** 
+          **                                                     ** 
+          **                                                     ** 
+          ** Copyright (C) 1987, 1988 Eva Latta-Weber, Bielefeld ** 
+          **                                                     ** 
+          ** Copyright (C) 1988 ERGOS GmbH, Siegburg             ** 
+          **                                                     ** 
+          ********************************************************* 
+          ********************************************************* 
+ 
+                                                                           *) 
+ 
+LET mm taskname =  "ls-MENUKARTEN",{}    datei 1     =  "Generatordatei: Archivmenu",{}    datei 2     =  "ls-MENUBASISTEXTE",{}    datei 3     =  "ls-Menu-Generator 1",{}    datei 4     =  "ls-Menu-Generator 2";{}PROC stelle existenz des mm sicher:{}  cursor (1, 5); out (""4"");{}  IF NOT exists (task (mm taskname)){}     THEN errorstop ("Unbedingt erst den 'MENUKARTEN-MANAGER' generieren!");{}  FI{}END PROC stelle existenz des mm sicher;{}PROC vom archiv (TEXT CONST datei):{}  cursor (1,5); out (""4"");{}
+  out ("  """); out (datei); putline (""" wird geholt.");{}  fetch (datei, archive){}END PROC vom archiv;{}PROC hole (TEXT CONST datei):{}  IF NOT exists (datei) THEN vom archiv (datei) FI{}END PROC hole;{}PROC in (TEXT CONST datei):{}  hole (datei);{}  cursor (1, 5); out (""4"");{}  out ("  """); out (datei); out (""" wird übersetzt: ");{}  insert (datei);{}  forget (datei, quiet);{}END PROC in;{}PROC schicke (TEXT CONST datei):{}  cursor (1, 5); out (""4"");{}  out ("  """); out(datei);{}  out (""" wird zum MENUKARTEN-MANAGER geschickt!");{}
+  command dialogue (FALSE);{}  save (datei, task (mm taskname));{}  command dialogue (TRUE);{}  forget (datei, quiet){}END PROC schicke;{}INT VAR size, used;{}BOOL VAR einzeln;{}storage (size, used);{}einzeln := size - used < 500;{}forget ("ls-Menu-Generator/gen", quiet);{}wirf kopfzeile aus;{}stelle existenz des mm sicher;{}hole die dateien;{}insertiere die dateien;{}mache global manager aus der task.{}wirf kopfzeile aus:{}  page;{}  putline ("                  "15"ls-Menu-Generator - Automatische Generierung "14"").{}
+hole die dateien:{}  IF     NOT exists (datei 1) COR NOT exists (datei 2){}     COR NOT exists (datei 3) COR NOT exists (datei 4){}     THEN hole dateien vom archiv{}  FI.{}hole dateien vom archiv:{}  cursor (1,3);{}  say ("Ist das Archiv angemeldet und die "); line;{}  IF yes ("'ls-Menu-Generator'-Diskette eingelegt"){}     THEN lese ein{}     ELSE line (2);{}          errorstop ("Ohne die Diskette kann ich das System nicht generieren!"){}  FI.{}lese ein:{}  cursor (1, 3); out (""4"");{}  out ("                      "15"Bitte die Diskette eingelegt lassen! "14"");{}
+  IF NOT einzeln{}     THEN hole (datei 1);{}          hole (datei 2);{}          hole (datei 3);{}          hole (datei 4);{}          cursor (1, 3); out(""4"");{}          out ("                     "15"Die Diskette wird nicht mehr benötigt! "14"");{}          release (archive){}  FI.{}insertiere die dateien:{}  check off;{}  schicke (datei 2);{}  in (datei 3);{}  in (datei 4);{}  IF einzeln THEN release (archive) FI;{}  check on.{}mache global manager aus der task:{}  global manager.{}
+
diff --git a/mp-bap/ls-MENUKARTE:MP-BAP b/mp-bap/ls-MENUKARTE:MP-BAP
new file mode 100644
index 0000000..564b07c
Binary files /dev/null and b/mp-bap/ls-MENUKARTE:MP-BAP differ
diff --git a/mp-bap/ls-MP BAP 1 b/mp-bap/ls-MP BAP 1
new file mode 100644
index 0000000..be7e3d2
--- /dev/null
+++ b/mp-bap/ls-MP BAP 1	
@@ -0,0 +1,119 @@
+PACKET ls mp bap 1  DEFINES                (*******************************) 
+                                           (*                             *) 
+       stdvoreinstellung der parameter,    (*         ls-MP BAP 1         *) 
+       werkstueckdefinition,               (*         Version 1.1         *) 
+       tastendefinition,                   (*                             *) 
+       phasendefinition,                   (*   (c) 1987, 1988            *) 
+       bewertungsschluessel,               (*       by Eva Latta-Weber    *) 
+       werkstueckaufhaenger,               (*          Bielefeld          *) 
+       tastenbezeichnung,                  (*                             *) 
+       piepse,                             (*******************************) 
+                                            
+       mp bap einstellung anzeigen,         
+       mp bap standardwerte,                
+       mp bap breite des werkstuecks, 
+       mp bap hoehe  des werkstuecks, 
+       mp bap invers normal, 
+       mp bap zeichensatz, 
+       mp bap fehlerzeichen, 
+       mp bap tastenbelegung, 
+       mp bap anzahl arbeitsphasen, 
+       mp bap dauer einer arbeitsphase, 
+       mp bap pausendauer, 
+       mp bap wertungsschluessel: 
+ 
+LET maxspalten         =            70,{}    maxzeilen          =            14,{}    kleinster wert     =             1,{}    oben unten return  = ""3""10""13"",{}    punkt              =           "+",{}    punkt und zurueck  =        "+"8"",{}    piep               =         ""7"",{}    blank              =           " ";{}INT  VAR aktuelle werkstueckbreite,{}         aktuelle werkstueckhoehe,{}         kleinster aktueller zeichencode,{}         groesster aktueller zeichencode,{}         aktuelle anzahl der arbeitsphasen,{}
+         aktuelle arbeitsphasendauer in minuten,{}         aktuelle pausendauer in minuten;{}TEXT VAR aktuelles fehlerzeichen,{}         nach rechts,{}         nach links,{}         nach oben,{}         nach unten,{}         ausbesserung,{}         naechstes;{}BOOL VAR inversdarstellung;{}ROW 11 REAL VAR bewertung;{}WINDOW VAR w1, w2, w3, w4;{}PROC stdvoreinstellung der parameter:{}  aktuelle werkstueckbreite               :=     15;{}  aktuelle werkstueckhoehe                :=     12;{}  kleinster aktueller zeichencode         :=     65;{}
+  groesster aktueller zeichencode         :=     90;{}  aktuelle anzahl der arbeitsphasen       :=      3;{}  aktuelle arbeitsphasendauer in minuten  :=     10;{}  aktuelle pausendauer in minuten         :=      2;{}  aktuelles fehlerzeichen                 :=    "F";{}  nach rechts                             :=  ""2"";{}  nach links                              :=  ""8"";{}  nach oben                               :=  ""3"";{}  nach unten                              := ""10"";{}  ausbesserung                            :=  ""1"";{}
+  naechstes                               := ""27"";{}  inversdarstellung                       :=  FALSE;{}  bewertung := ROW 11 REAL : (0.0, 0.1, 0.2, 0.3, 0.4, 0.5,{}                                   0.6, 0.7, 0.8, 0.9, 1.0){}END PROC stdvoreinstellung der parameter;{}PROC werkstueckdefinition (INT VAR breite, hoehe, kleinster, groesster,{}                           TEXT VAR fzeichen, BOOL VAR invers):{}  breite        := aktuelle werkstueckbreite;{}  hoehe         := aktuelle werkstueckhoehe;{}
+  kleinster     := kleinster aktueller zeichencode;{}  groesster     := groesster aktueller zeichencode;{}  fzeichen      := aktuelles fehlerzeichen;{}  invers        := inversdarstellung{}END PROC werkstueckdefinition;{}PROC tastendefinition (TEXT VAR rechts, links, hoch, runter, aus, nach):{}  rechts        := nach rechts;{}  links         := nach links;{}  hoch          := nach oben;{}  runter        := nach unten;{}  aus           := ausbesserung;{}  nach          := naechstes{}END PROC tastendefinition;{}
+PROC phasendefinition (INT VAR aphasenzahl, aphasendauer, pausendauer):{}  aphasenzahl   := aktuelle anzahl der arbeitsphasen;{}  aphasendauer  := aktuelle arbeitsphasendauer in minuten;{}  pausendauer   := aktuelle pausendauer in minuten{}END PROC phasendefinition;{}PROC bewertungsschluessel (ROW 11 REAL VAR schluessel):{}  INT VAR zeiger;{}  FOR zeiger FROM 1 UPTO 11 REP{}    schluessel [zeiger] := bewertung [zeiger]{}  PER{}END PROC bewertungsschluessel;{}PROC mp bap einstellung anzeigen:{}  aktuellen parameterzustand anzeigen;{}
+  regenerate menuscreen{}END PROC mp bap einstellung anzeigen;{}PROC mp bap standardwerte:{}  standardwerte einstellen;{}  regenerate menuscreen{}END PROC mp bap standardwerte;{}PROC mp bap breite des werkstuecks:{}  breite des werkstuecks einstellen;{}  regenerate menuscreen{}END PROC mp bap breite des werkstuecks;{}PROC mp bap hoehe des werkstuecks:{}  hoehe des werkstuecks einstellen;{}  regenerate menuscreen{}END PROC mp bap hoehe des werkstuecks;{}PROC mp bap invers normal:{}  werkstueckdarstellung einstellen;{}
+  regenerate menuscreen{}END PROC mp bap invers normal;{}PROC mp bap zeichensatz:{}  zeichensatz einstellen;{}  regenerate menuscreen{}END PROC mp bap zeichensatz;{}PROC mp bap fehlerzeichen:{}  fehlerzeichen veraendern;{}  regenerate menuscreen{}END PROC mp bap fehlerzeichen;{}PROC mp bap tastenbelegung:{}  tastaturbelegung einstellen;{}  regenerate menuscreen{}END PROC mp bap tastenbelegung;{}PROC mp bap anzahl arbeitsphasen:{}  anzahl der arbeitsphasen festlegen;{}  regenerate menuscreen{}END PROC mp bap anzahl arbeitsphasen;{}
+PROC mp bap dauer einer arbeitsphase:{}  dauer einer arbeitsphase festlegen;{}  regenerate menuscreen{}END PROC mp bap dauer einer arbeitsphase;{}PROC mp bap pausendauer:{}  pausendauer festlegen;{}  regenerate menuscreen{}END PROC mp bap pausendauer;{}PROC mp bap wertungsschluessel:{}  wertungsschluessel veraendern;{}  regenerate menuscreen{}END PROC mp bap wertungsschluessel;{}PROC aktuellen parameterzustand anzeigen:{}  zeige die fenster;{}  fuelle die fenster mit inhalt;{}  gib hinweis aus.{}
+  zeige die fenster:{}    w1 := window ( 2,  2, 37, 20);{}    w2 := window (41,  2, 38, 20);{}    w3 := window ( 1,  1, 79, 24);{}    page; show (w1); show (w2).{}  fuelle die fenster mit inhalt:{}    zeige inhalt fenster 1;{}    zeige inhalt fenster 2.{}  zeige inhalt fenster 1:{}    zeige eingestellte parameter an (w1).{}  zeige inhalt fenster 2:{}    gib bewertungsschluessel aus (w2).{}  gib hinweis aus:{}    out footnote (w3, anwendungstext (2)); pause.{}END PROC aktuellen parameterzustand anzeigen;{}
+PROC zeige eingestellte parameter an (WINDOW VAR w):{}  zeige ueberschrift;{}  zeige werkstueckdefinition;{}  zeige tastenbelegung;{}  zeige simulationszeiten.{}  zeige ueberschrift:{}    cursor (w, 1,  1); out (w, center (w, invers (anwendungstext ( 1)))).{}  zeige werkstueckdefinition:{}    cursor (w, 2,  3); out (w, anwendungstext ( 6));{}                       out (w, text (aktuelle werkstueckbreite, 3));{}                       out (w, anwendungstext (28));{}    cursor (w, 2,  4); out (w, anwendungstext ( 7));{}
+                       out (w, text (aktuelle werkstueckhoehe,  3));{}                       out (w, anwendungstext (28));{}    cursor (w, 2,  5); out (w, anwendungstext ( 8));{}                        IF inversdarstellung{}                           THEN out (w, anwendungstext (29)){}                           ELSE out (w, anwendungstext (30)){}                        FI;{}    cursor (w, 2,  6); out (w, anwendungstext ( 9));{}                       out (w, zeichensatz);{}    cursor (w, 2,  7); out (w, anwendungstext (10));{}
+                       out (blank + aktuelles fehlerzeichen).{}  zeige tastenbelegung:{}    cursor (w, 2,  9); out (w, anwendungstext (11));{}                       out (w, tastenbezeichnung (nach rechts));{}    cursor (w, 2, 10); out (w, anwendungstext (12));{}                       out (w, tastenbezeichnung (nach links));{}    cursor (w, 2, 11); out (w, anwendungstext (13));{}                       out (w, tastenbezeichnung (nach oben));{}    cursor (w, 2, 12); out (w, anwendungstext (14));{}                       out (w, tastenbezeichnung (nach unten));{}
+    cursor (w, 2, 13); out (w, anwendungstext (15));{}                       out (w, tastenbezeichnung (ausbesserung));{}    cursor (w, 2, 14); out (w, anwendungstext (16));{}                       out (w, tastenbezeichnung (naechstes)).{}  zeige simulationszeiten:{}    cursor (w, 2, 16); out (w, anwendungstext (17));{}                       out (w, text (aktuelle anzahl der arbeitsphasen, 4));{}    cursor (w, 2, 17); out (w, anwendungstext (18));{}                       out (w, text (aktuelle arbeitsphasendauer in minuten, 4));{}
+                       out (w, anwendungstext (51));{}    cursor (w, 2, 18); out (w, anwendungstext (19));{}                       out (w, text (aktuelle pausendauer in minuten, 4));{}                       out (w, anwendungstext (51));{}    cursor (w, 2, 20); out (w, anwendungstext ( 5));{}                       out (w, gesamtdauerangabe).{}  zeichensatz:{}    blank + code (kleinster aktueller zeichencode) + "..." +{}            code (groesster aktueller zeichencode) + " ("  +{}            text (groesster aktueller zeichencode{}
+                   - kleinster aktueller zeichencode + 1, 2) +{}            anwendungstext (28) + ")".{}  gesamtdauerangabe:{}    text ( arbeitsdauer + pausendauer, 4) + anwendungstext (51).{}  arbeitsdauer:{}      aktuelle anzahl der arbeitsphasen{}    * aktuelle arbeitsphasendauer in minuten.{}  pausendauer:{}      (aktuelle anzahl der arbeitsphasen - 1){}    * aktuelle pausendauer in minuten.{}END PROC zeige eingestellte parameter an;{}PROC gib bewertungsschluessel aus (WINDOW VAR w):{}  zeichne koordinatenkreuz;{}
+  trage messwerte ein.{}  zeichne koordinatenkreuz:{}    cursor (w, 1,  1); out (w, center (w, invers (anwendungstext ( 4))));{}    cursor (w, 2,  3); out (w, anwendungstext (20));{}    cursor (w, 2,  4); out (w, anwendungstext (21));{}    cursor (w, 2,  6); out (w, anwendungstext (23));{}    cursor (w, 2,  7); out (w, anwendungstext (22));{}    cursor (w, 2,  8); out (w, anwendungstext (22));{}    cursor (w, 2,  9); out (w, anwendungstext (22));{}    cursor (w, 2, 10); out (w, anwendungstext (22));{}
+    cursor (w, 2, 11); out (w, anwendungstext (24));{}    cursor (w, 2, 12); out (w, anwendungstext (22));{}    cursor (w, 2, 13); out (w, anwendungstext (22));{}    cursor (w, 2, 14); out (w, anwendungstext (22));{}    cursor (w, 2, 15); out (w, anwendungstext (22));{}    cursor (w, 2, 16); out (w, anwendungstext (25));{}    cursor (w, 2, 17); out (w, anwendungstext (26));{}    cursor (w, 2, 19); out (w, anwendungstext (27)).{}  trage messwerte ein:{}    INT CONST abszisse :: 16, ordinate :: 2;{}
+    INT VAR nr;{}    FOR nr FROM 1 UPTO 11 REP{}      zeichne einen punkt{}    PER.{}  zeichne einen punkt:{}    cursor (w, ordinate + 3 * nr, abszisse - nachkommastelle); out (punkt).{}  nachkommastelle:{}    int(bewertung [nr] * 10.0).{}END PROC gib bewertungsschluessel aus;{}PROC standardwerte einstellen:{}  zeige fenster;{}  zeige eingestellte parameter an (w1);{}  gib information aus;{}  hole bestaetigung ein.{}  zeige fenster:{}    w1 := window ( 2,  2, 37, 20);{}    w2 := window (41, 10, 37, 12);{}
+    w3 := window (41,  2, 37,  6);{}    page; show (w1); show (w2); show (w3).{}  gib information aus:{}    cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (52))));{}    cursor (w2, 2, 3); out (w2, anwendungstext (67));{}    cursor (w2, 2, 4); out (w2, anwendungstext (68));{}    cursor (w2, 2, 7); out (w2, anwendungstext (69));{}    cursor (w2, 2, 9); out (w2, anwendungstext (70));{}    cursor (w2, 2,10); out (w2, anwendungstext (71));{}    cursor (w2, 2,11); out (w2, anwendungstext (72));{}
+    cursor (w2, 2,12); out (w2, anwendungstext (73)).{}  hole bestaetigung ein:{}    cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (66))));{}    cursor (w3, 2, 3);{}    IF yes (w3, anwendungstext (66)){}       THEN stdvoreinstellung der parameter;{}            gib positive rueckmeldung{}    FI.{}  gib positive rueckmeldung:{}    page (w1);{}    zeige eingestellte parameter an (w1);{}    cleop  (w3, 2, 3); out (anwendungstext (221));{}    cursor (w3, 2, 5); out (anwendungstext (  3));{}
+    pause.{}END PROC standardwerte einstellen;{}PROC breite des werkstuecks einstellen:{}  zeige die fenster;{}  hinweise an den benutzer ausgeben;{}  werkstueck zeigen (w3);{}  erfrage veraenderung;{}  REP{}    neuen wert vom bildschirm holen{}  UNTIL benutzer ist einverstanden PER.{}  zeige die fenster:{}    w1 := window ( 2, 2, 26, 6);{}    w2 := window (30, 2, 48, 6);{}    w3 := window (2, 9, 77, 16);{}    page; show (w1); show (w2).{}  hinweise an den benutzer ausgeben:{}    cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{}
+    cursor (w1, 2, 3); out (w1, anwendungstext (53));{}                       out (w1, text (kleinster wert, 3));{}    cursor (w1, 2, 4); out (w1, anwendungstext (54));{}                       out (w1, text (maxspalten,     3));{}    cursor (w1, 2, 6); out (w1, anwendungstext (55));{}                       out (w1, text (aktuelle werkstueckbreite, 3)).{}  erfrage veraenderung:{}    cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (57))));{}    cursor (w2, 2, 3);{}    IF no (anwendungstext (216)){}
+       THEN LEAVE breite des werkstuecks einstellen{}    FI.{}  neuen wert vom bildschirm holen:{}    cleop  (w2, 2, 3); out (w2, anwendungstext (58));{}    cursor (w2, 2, 4); out (w2, anwendungstext (59));{}    cursor (w2, 2, 6); out (w2, anwendungstext (60));{}    aktuelle werkstueckbreite := ermittelter wert (1, maxspalten,{}                                                aktuelle werkstueckbreite).{}  benutzer ist einverstanden :{}    gib aktuelle infos aus;{}    hole bestaetigung.{}  gib aktuelle infos aus:{}
+    hinweise an den benutzer ausgeben;{}    werkstueck zeigen (w3);{}    cleop (w2, 1, 3).{}  hole bestaetigung:{}    cursor (w2, 2, 3);{}    IF yes (w2, anwendungstext (62)){}       THEN TRUE{}       ELSE FALSE{}    FI.{}END PROC breite des werkstuecks einstellen;{}PROC hoehe des werkstuecks einstellen:{}  fenster zeigen;{}  hinweise an den benutzer ausgeben;{}  werkstueck zeigen (w3);{}  erfrage veraenderung;{}  REP{}    neuen wert vom bildschirm holen{}  UNTIL benutzer ist einverstanden PER.{}
+  fenster zeigen:{}    w1 := window ( 2, 2, 26, 6);{}    w2 := window (30, 2, 48, 6);{}    w3 := window (2, 9, 77, 16);{}    page; show (w1); show (w2).{}  hinweise an den benutzer ausgeben:{}    cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{}    cursor (w1, 2, 3); out (w1, anwendungstext (53));{}                       out (w1, text (kleinster wert, 3));{}    cursor (w1, 2, 4); out (w1, anwendungstext (54));{}                       out (w1, text (maxzeilen,      3));{}    cursor (w1, 2, 6); out (w1, anwendungstext (55));{}
+                       out (w1, text (aktuelle werkstueckhoehe, 3)).{}  erfrage veraenderung:{}    cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (63))));{}    cursor (w2, 2, 3);{}    IF no (anwendungstext (217)){}       THEN LEAVE hoehe des werkstuecks einstellen{}    FI.{}  neuen wert vom bildschirm holen:{}    cleop  (w2, 2, 3); out (w2, anwendungstext (58));{}    cursor (w2, 2, 4); out (w2, anwendungstext (59));{}    cursor (w2, 2, 6); out (w2, anwendungstext (64));{}    aktuelle werkstueckhoehe := ermittelter wert (1, maxzeilen,{}
+                                                  aktuelle werkstueckhoehe).{}  benutzer ist einverstanden :{}    gib aktuelle infos aus;{}    hole bestaetigung.{}  gib aktuelle infos aus:{}    hinweise an den benutzer ausgeben;{}    werkstueck zeigen (w3);{}    cleop (w2, 1, 3).{}  hole bestaetigung:{}    cursor (w2, 2, 3);{}    IF yes (w2, anwendungstext (65)){}       THEN TRUE{}       ELSE FALSE{}    FI.{}END PROC hoehe des werkstuecks einstellen;{}PROC werkstueckdarstellung einstellen:{}  fenster zeigen;{}
+  hinweise an den benutzer ausgeben;{}  werkstueck zeigen (w3);{}  REP{}    bestaetigung einholen;{}    hinweise an den benutzer ausgeben;{}    werkstueck zeigen (w3){}  UNTIL benutzer ist einverstanden PER.{}  fenster zeigen:{}    w1 := window ( 2,  2, 28,  6);{}    w2 := window (32,  2, 46,  6);{}    w3 := window ( 2,  9, 77, 16);{}    page; show (w1); show (w2).{}  hinweise an den benutzer ausgeben:{}    cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{}    cursor (w1, 2, 3); out (w1, anwendungstext (74));{}
+                       out (w1, anwendungstext (76));{}    cursor (w1, 2, 4); out (w1, anwendungstext (74));{}                       out (w1, anwendungstext (77));{}    cursor (w1, 2, 6); out (w1, anwendungstext (75));{}                       IF inversdarstellung{}                          THEN out (w1, anwendungstext (77)){}                          ELSE out (w1, anwendungstext (76)){}                       FI.{}  bestaetigung einholen:{}    page (w2);{}    cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (89))));{}
+    cursor (w2, 2, 3);{}    IF yes (w2, anwendungstext (78)){}       THEN veraendere darstellungsart{}       ELSE LEAVE werkstueckdarstellung einstellen{}    FI.{}  veraendere darstellungsart:{}    IF inversdarstellung{}       THEN inversdarstellung := FALSE{}       ELSE inversdarstellung := TRUE{}    FI.{}  benutzer ist einverstanden:{}    cleop (w2, 1, 3);{}    cursor (w2, 2, 3);{}    IF yes (w2, anwendungstext (99)){}       THEN TRUE{}       ELSE FALSE{}    FI.{}END PROC werkstueckdarstellung einstellen;{}
+PROC zeichensatz einstellen:{}  zeige fenster;{}  gib eingestellten zeichensatz an;{}  gib bedienhinweise aus;{}  erfrage neueinstellung;{}  REP{}    erfrage das neue fehlerzeichen;{}    ermittle das kleinste zeichen;{}    ermittle das groesste zeichen;{}    page (w1);{}    gib eingestellten zeichensatz an{}  UNTIL benutzer ist einverstanden PER.{}  zeige fenster:{}    w1 := window ( 2,  2, 28, 22);{}    w2 := window (32, 10, 46, 14);{}    w3 := window (32,  2, 46,  6);{}    page; show (w1); show (w2); show (w3).{}
+  gib eingestellten zeichensatz an:{}    cursor (w1, 1, 1);{}    out (w1, center (w1, invers (anwendungstext (79))));{}    gib zeichenkette aus (w1, kleinster aktueller zeichencode,{}                              groesster aktueller zeichencode,{}                              code (aktuelles fehlerzeichen)).{}  gib bedienhinweise aus:{}    cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (52))));{}    cursor (w2, 2, 3); out (w2, anwendungstext (80));{}    cursor (w2, 2, 4); out (w2, anwendungstext (81));{}
+    cursor (w2, 2, 5); out (w2, anwendungstext (82));{}    cursor (w2, 2, 6); out (w2, anwendungstext (83));{}    cursor (w2, 2, 8); out (w2, anwendungstext (84));{}    cursor (w2, 2, 9); out (w2, anwendungstext (85));{}    cursor (w2, 2,10); out (w2, anwendungstext (86));{}    cursor (w2, 2,12); out (w2, anwendungstext (87));{}    cursor (w2, 2,13); out (w2, anwendungstext (88)).{}  erfrage neueinstellung:{}    cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (90))));{}    cursor (w3, 2, 3);{}
+    IF no (w3, anwendungstext (91)){}       THEN LEAVE zeichensatz einstellen{}    FI.{}  erfrage das neue fehlerzeichen:{}    gib vollstaendigen zeichensatz aus;{}    gib fehlerzeicheninformationen aus;{}    REP{}      lasse fehlerzeichen eingeben{}    UNTIL fehlerzeichen ist ok PER.{}  gib vollstaendigen zeichensatz aus:{}    page (w1); page (w2); page (w3);{}    cursor (w1, 1, 1);{}    out (w1, center (w1, invers (anwendungstext (92))));{}    gib zeichenkette aus (w1, 33, 126, 0).{}  gib fehlerzeicheninformationen aus:{}
+    cursor (w2, 1, 1);{}    out (w2, center (w2, invers (anwendungstext (52))));{}    cursor (w2, 2, 3);  out (w2, anwendungstext (95));{}    cursor (w2, 2, 4);  out (w2, anwendungstext (96));{}    cursor (w2, 2, 6);  out (w2, anwendungstext (97)).{}  lasse fehlerzeichen eingeben:{}    cursor (w3, 1, 1);{}    out (w3, center (w3, invers (anwendungstext (100))));{}    cursor (w3, 2, 3);{}    out (w3, anwendungstext (101));{}    cursor on; inchar (aktuelles fehlerzeichen); cursor off;{}    IF fehlerzeichen ist ok{}
+       THEN out (w3, aktuelles fehlerzeichen);{}            markiere das fehlerzeichen im ersten fenster;{}       ELSE lege beschwerde ein{}    FI.{}  fehlerzeichen ist ok:{}        code (aktuelles fehlerzeichen) >=  33{}    AND code (aktuelles fehlerzeichen) <= 126.{}  markiere das fehlerzeichen im ersten fenster:{}    positioniere cursor in zeichenkette (w1, 33, code (aktuelles fehlerzeichen));{}    out (w1, invers (aktuelles fehlerzeichen)).{}  lege beschwerde ein:{}    piepse;{}    cursor (w2, 2, 8); out (w2, anwendungstext (102));{}
+    cursor (w2, 2,10); out (w2, anwendungstext (103));{}    cursor (w2, 2,11); out (w2, anwendungstext (104));{}    cursor (w2, 2,12); out (w2, anwendungstext (105));{}    cursor (w2, 2,13); out (w2, anwendungstext (106));{}    cursor (w2, 2,14); out (w2, anwendungstext (107)).{}  ermittle das kleinste zeichen:{}    page (w2); page (w3);{}    gib kleinste zeichencode informationen aus;{}    lasse den vorbereich festlegen.{}  ermittle das groesste zeichen:{}    lasse den nachbereich festlegen.{}  gib kleinste zeichencode informationen aus:{}
+    cursor (w2, 1, 1);{}    out (w2, center (w2, invers (anwendungstext (52))));{}    cursor (w2, 2, 3); out (w2, anwendungstext (111));{}    cursor (w2, 2, 4); out (w2, anwendungstext (112));{}    cursor (w2, 2, 5); out (w2, anwendungstext (113));{}    cursor (w2, 2, 6); out (w2, anwendungstext (114));{}    cursor (w2, 2, 8); out (w2, anwendungstext (115));{}    cursor (w2, 2, 9); out (w2, anwendungstext (116));{}    cursor (w2, 2,10); out (w2, anwendungstext (117));{}    cursor (w2, 2,11); out (w2, anwendungstext (118));{}
+    cursor (w2, 2,13); out (w2, anwendungstext (119));{}    cursor (w2, 2,14); out (w2, anwendungstext (120)).{}  lasse den vorbereich festlegen:{}    INT VAR s, z; page (w3); cursor (w3, 1, 1);{}    out (w3, center (w3, invers (anwendungstext (121))));{}    cursor (w3, 2, 3); out (w3, anwendungstext (122));{}    cursor (w3, 2, 4); out (w3, anwendungstext (123));{}    cursor (w3, 2, 5); out (w3, anwendungstext (125));{}    get cursor (s, z); cursor on;{}    kleinster aktueller zeichencode := code (aktuelles fehlerzeichen);{}
+    groesster aktueller zeichencode := code (aktuelles fehlerzeichen);{}    kleinster aktueller zeichencode := eingabe mit intervallanzeige ( w1, 33,{}                                       code (aktuelles fehlerzeichen),{}                                       kleinster aktueller zeichencode, s, z);{}    cursor off.{}  lasse den nachbereich festlegen:{}    cursor (w3, 1, 1);{}    out (w3, center (w3, invers (anwendungstext (121))));{}    cursor (w3, 2, 3); out (w3, anwendungstext (122));{}    cursor (w3, 2, 4); out (w3, anwendungstext (124));{}
+    cursor (w3, 2, 5); out (w3, anwendungstext (125));{}    get cursor (s, z); cursor on;{}    groesster aktueller zeichencode := eingabe mit intervallanzeige ( w1,{}                                       code (aktuelles fehlerzeichen), 126,{}                                       groesster aktueller zeichencode, s, z);{}    cursor off.{}  benutzer ist einverstanden:{}    page (w3); cursor (w3, 1, 1);{}    out (w3, center (w3, invers (anwendungstext (90))));{}    cursor (w3, 2, 3);{}    IF yes (w3, anwendungstext (126)){}
+       THEN TRUE{}       ELSE FALSE{}    FI.{}END PROC zeichensatz einstellen;{}PROC fehlerzeichen veraendern:{}  fenster zeigen;{}  gib eingestellten zeichensatz an;{}  gib bedienhinweise aus;{}  erfrage neueinstellung;{}  REP{}    lasse fehlerzeichen einstellen{}  UNTIL benutzer ist einverstanden PER.{}  fenster zeigen:{}    w1 := window ( 2,  2, 28, 22);{}    w2 := window (32, 10, 46, 14);{}    w3 := window (32,  2, 46,  6);{}    page; show (w1); show (w2); show (w3).{}  gib eingestellten zeichensatz an:{}
+    cursor (w1, 1, 1);{}    out (w1, center (w1, invers (anwendungstext (79))));{}    gib zeichenkette aus (w1, kleinster aktueller zeichencode,{}                              groesster aktueller zeichencode,{}                              code (aktuelles fehlerzeichen)).{}  gib bedienhinweise aus:{}    cursor (w2, 1, 1);{}    out (w2, center (w2, invers (anwendungstext (52))));{}    cursor (w2, 2, 3); out (w2, anwendungstext (131));{}    cursor (w2, 2, 4); out (w2, anwendungstext (132));{}    cursor (w2, 2, 5); out (w2, anwendungstext (133));{}
+    cursor (w2, 2, 7); out (w2, anwendungstext (134));{}    cursor (w2, 2, 8); out (w2, anwendungstext (135));{}    cursor (w2, 2, 9); out (w2, anwendungstext (136)).{}  erfrage neueinstellung:{}    cursor (w3, 1, 1);{}    out (w3, center (w3, invers (anwendungstext (130))));{}    cursor (w3, 2, 3);{}    IF no (w3, anwendungstext (137)){}       THEN LEAVE fehlerzeichen veraendern{}    FI.{}  lasse fehlerzeichen einstellen:{}    INT VAR s, z, fehlercode :: code (aktuelles fehlerzeichen);{}    page (w3); cursor (w3, 1, 1);{}
+    out (w3, center (w3, invers (anwendungstext (138))));{}    cursor (w3, 2, 3); out (w3, anwendungstext (139));{}    cursor (w3, 2, 4); out (w3, anwendungstext (140));{}    cursor (w3, 2, 5); out (w3, anwendungstext (141));{}    get cursor (s, z); cursor on;{}    fehlercode := eingabe mit elementanzeige (w1,{}                                              kleinster aktueller zeichencode,{}                                              groesster aktueller zeichencode,{}                                              fehlercode, s, z);{}
+    cursor off;{}    aktuelles fehlerzeichen := code (fehlercode).{}  benutzer ist einverstanden:{}    page (w3); cursor (w3, 1, 1);{}    out (w3, center (w3, invers (anwendungstext (130))));{}    cursor (w3, 2, 3);{}    IF yes (w3, anwendungstext (142)){}       THEN TRUE{}       ELSE FALSE{}    FI.{}END PROC fehlerzeichen veraendern;{}PROC tastaturbelegung einstellen:{}  ROW 6 TEXT VAR tastenname, taste;{}  fenster zeigen;{}  REP{}    tastaturneubelegung vornehmen{}  UNTIL benutzer ist einverstanden PER.{}
+  fenster zeigen:{}    w1 := window ( 2,  2, 28, 10);{}    w2 := window ( 2, 14, 28, 10);{}    w3 := window (32, 10, 46, 14);{}    w4 := window (32,  2, 46,  6);{}    page; show (w1); show (w2); show (w3); show (w4).{}  tastaturneubelegung vornehmen:{}    alte tastenbelegung einlesen;{}    tastenbelegung anzeigen;{}    bedienhinweise ausgeben;{}    veraenderung erfragen;{}    neue tastenbelegung erfragen;{}    hinweis zur bewertung und stand ausgeben.{}  alte tastenbelegung einlesen:{}    INT VAR z1;{}
+    FOR z1 FROM 1 UPTO 6 REP{}      tastenname [z1] := anwendungstext (z1 + 10){}    PER;{}    taste [1] := nach rechts;{}    taste [2] := nach links;{}    taste [3] := nach oben;{}    taste [4] := nach unten;{}    taste [5] := ausbesserung;{}    taste [6] := naechstes;{}    cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (151)))).{}  tastenbelegung anzeigen:{}    INT VAR cspa, czei;{}    cursor (w1, 2, 3); out (w1, tastenname [1]);{}                       out (w1, tastenbezeichnung (taste [1]));{}
+                       get cursor (w1, cspa, czei); cleol (w1, cspa, czei);{}    cursor (w1, 2, 4); out (w1, tastenname [2]);{}                       out (w1, tastenbezeichnung (taste [2]));{}                       get cursor (w1, cspa, czei); cleol (w1, cspa, czei);{}    cursor (w1, 2, 5); out (w1, tastenname [3]);{}                       out (w1, tastenbezeichnung (taste [3]));{}                       get cursor (w1, cspa, czei); cleol (w1, cspa, czei);{}    cursor (w1, 2, 6); out (w1, tastenname [4]);{}
+                       out (w1, tastenbezeichnung (taste [4]));{}                       get cursor (w1, cspa, czei); cleol (w1, cspa, czei);{}    cursor (w1, 2, 8); out (w1, tastenname [5]);{}                       out (w1, tastenbezeichnung (taste [5]));{}                       get cursor (w1, cspa, czei); cleol (w1, cspa, czei);{}    cursor (w1, 2,10); out (w1, tastenname [6]);{}                       out (w1, tastenbezeichnung (taste [6]));{}                       get cursor (w1, cspa, czei); cleol (w1, cspa, czei).{}
+  bedienhinweise ausgeben:{}    cursor (w2, 1, 1); out (center (w2, invers (anwendungstext (152))));{}    cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (52))));{}    cursor (w3, 2, 3); out (w3, anwendungstext (153));{}    cursor (w3, 2, 4); out (w3, anwendungstext (154));{}    cursor (w3, 2, 6); out (w3, anwendungstext (155));{}    cursor (w3, 2, 7); out (w3, anwendungstext (156));{}    cursor (w3, 2, 8); out (w3, anwendungstext (157));{}    cursor (w3, 2, 9); out (w3, anwendungstext (158));{}
+    cursor (w3, 2,11); out (w3, anwendungstext (159));{}    cursor (w3, 2,12); out (w3, anwendungstext (160));{}    cursor (w3, 2,13); out (w3, anwendungstext (161));{}    cursor (w3, 2,14); out (w3, anwendungstext (162)).{}  veraenderung erfragen:{}    cursor (w4, 1, 1); out (w4, center (w4, invers (anwendungstext (163))));{}    cursor (w4, 2, 3);{}    IF no (w4, anwendungstext (164)){}       THEN LEAVE tastaturbelegung einstellen{}    FI.{}  neue tastenbelegung erfragen:{}    INT VAR z2; page (w4);{}
+    cursor (w4, 1, 1); out (w4, center (w4, invers (anwendungstext (163))));{}    cursor (w4, 2, 3); out (w4, anwendungstext (165));{}    FOR z2 FROM 1 UPTO 6 REP{}      gib tastenhinweis;{}      hole tastatureingabe;{}      tastenbelegung anzeigen{}    PER.{}  gib tastenhinweis:{}    cleol (w4, 2, 5); out (w4, tastenname [z2]).{}  hole tastatureingabe:{}    INT VAR s, z; get cursor (w4, s, z);{}    cursor on; inchar (taste [z2]); cursor off;{}    cursor (w4, s, z); out (w4, tastenbezeichnung (taste [z2])).{}
+  hinweis zur bewertung und stand ausgeben:{}    IF neue tastenbelegung ist ok{}       THEN akzeptiere{}       ELSE akzeptiere nicht{}    FI.{}  neue tastenbelegung ist ok:{}    INT VAR zeiger; TEXT VAR tastenkette :: "";{}    FOR zeiger FROM 1 UPTO 6 REP{}      IF pos (tastenkette, taste [zeiger]) > 0{}         THEN LEAVE neue tastenbelegung ist ok WITH FALSE{}         ELSE tastenkette CAT taste [zeiger]{}      FI{}    PER;{}    TRUE.{}  akzeptiere:{}    cursor (w2, 3, 4);{}    out (w2, anwendungstext (166));{}
+    cursor (w2, 7, 6);{}    out (w2, anwendungstext (167)).{}  akzeptiere nicht:{}    cursor (w2, 3, 3); out (w2, anwendungstext (168));{}    cursor (w2, 3, 4); out (w2, anwendungstext (169));{}    cursor (w2, 3, 6); out (w2, anwendungstext (170));{}    cursor (w2, 3, 7); out (w2, anwendungstext (171));{}    cursor (w2, 3, 9); out (w2, anwendungstext (172));{}    cursor (w2, 5,10); out (w2, anwendungstext (173)).{}  benutzer ist einverstanden:{}    page (w4);{}    cursor (w4, 1, 1); out (w4, center (w4, invers (anwendungstext (163))));{}
+    IF neue tastenbelegung ist ok{}       THEN gib hinweis auf abspeicherung{}       ELSE frage nach neueingabe{}    FI.{}  gib hinweis auf abspeicherung:{}    cursor (w4, 3, 3); out (w4, anwendungstext (174));{}    neue tastenbelegung festschreiben;{}    cursor (w4, 3, 5); out (w4, anwendungstext (  2));{}    cursor on; pause; cursor off;{}    TRUE.{}  neue tastenbelegung festschreiben:{}    nach rechts   := taste [1];{}    nach links    := taste [2];{}    nach oben     := taste [3];{}    nach unten    := taste [4];{}
+    ausbesserung  := taste [5];{}    naechstes     := taste [6].{}  frage nach neueingabe:{}    cursor (w4, 2, 3);{}    IF yes (w4, anwendungstext (175)){}       THEN cleop (w2, 1, 3); FALSE{}       ELSE alte tastenbelegung einlesen;{}            tastenbelegung anzeigen;{}            cleop  (w4, 2, 3); out (w4, anwendungstext (176));{}            cursor (w4, 3, 5); out (w4, anwendungstext (  2));{}            cursor on; pause; cursor off;{}            TRUE{}    FI.{}END PROC tastaturbelegung einstellen;{}
+PROC simulationszeiten anzeigen (WINDOW VAR w):{}  cursor (w, 1, 1); out (w, center (w, invers (anwendungstext (181))));{}  cursor (w, 2, 3); out (w, anwendungstext (17));{}                    out (w, text (aktuelle anzahl der arbeitsphasen, 4));{}  cursor (w, 2, 4); out (w, anwendungstext (18));{}                    out (w, text (aktuelle arbeitsphasendauer in minuten, 4));{}                    out (w, anwendungstext (51));{}  cursor (w, 2, 5); out (w, anwendungstext (19));{}                    out (w, text (aktuelle pausendauer in minuten, 4));{}
+                    out (w, anwendungstext (51));{}  cursor (w, 2, 7); out (w, anwendungstext ( 5));{}                       out (w, gesamtdauerangabe).{}  gesamtdauerangabe:{}    text ( arbeitsdauer + pausendauer, 4) + anwendungstext (51).{}  arbeitsdauer:{}      aktuelle anzahl der arbeitsphasen{}    * aktuelle arbeitsphasendauer in minuten.{}  pausendauer:{}      (aktuelle anzahl der arbeitsphasen - 1){}    * aktuelle pausendauer in minuten.{}END PROC simulationszeiten anzeigen;{}PROC anzahl der arbeitsphasen festlegen:{}
+  INT CONST minwert :: 2, maxwert :: 20;{}  zeige fenster;{}    hinweise an den benutzer ausgeben;{}    simulationszeiten anzeigen (w2);{}    erfrage veraenderung;{}  REP{}    neuen wert vom bildschirm holen{}  UNTIL benutzer ist einverstanden PER.{}  zeige fenster:{}    w1 := window ( 2,  2, 28,  6);{}    w2 := window (22, 12, 37,  7);{}    w3 := window (32,  2, 47,  6);{}    page; show (w1); show (w2); show (w3).{}  hinweise an den benutzer ausgeben:{}    cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{}
+    cursor (w1, 2, 3); out (w1, anwendungstext (53));{}                       out (w1, text (minwert, 2));{}    cursor (w1, 2, 4); out (w1, anwendungstext (54));{}                       out (w1, text (maxwert, 2));{}    cursor (w1, 2, 6); out (w1, anwendungstext (55));{}                       out (w1, text (aktuelle anzahl der arbeitsphasen, 2)).{}  erfrage veraenderung:{}    cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (182))));{}    cursor (w3, 2, 3);{}    IF no (anwendungstext (218)){}
+       THEN LEAVE anzahl der arbeitsphasen festlegen{}    FI.{}  neuen wert vom bildschirm holen:{}    cleop  (w3, 2, 3); out (w3, anwendungstext ( 58));{}    cursor (w3, 2, 4); out (w3, anwendungstext ( 59));{}    cursor (w3, 2, 6); out (w3, anwendungstext (183));{}    aktuelle anzahl der arbeitsphasen := ermittelter wert (minwert, maxwert,{}                                         aktuelle anzahl der arbeitsphasen).{}  benutzer ist einverstanden:{}    hinweise an den benutzer ausgeben;{}    simulationszeiten anzeigen (w2);{}
+    cleop (w3, 2, 3);{}    IF yes (w3, anwendungstext (184)){}       THEN TRUE{}       ELSE FALSE{}    FI.{}END PROC anzahl der arbeitsphasen festlegen;{}PROC dauer einer arbeitsphase festlegen:{}  INT CONST minwert :: 1, maxwert :: 60;{}  zeige fenster;{}  hinweise an den benutzer ausgeben;{}  simulationszeiten anzeigen (w2);{}  erfrage veraenderung;{}  REP{}    neuen wert vom bildschirm holen{}  UNTIL benutzer ist einverstanden PER.{}  zeige fenster:{}    w1 := window ( 2,  2, 28,  6);{}    w2 := window (22, 12, 37,  7);{}
+    w3 := window (32,  2, 47,  6);{}    page; show (w1); show (w2); show (w3).{}  hinweise an den benutzer ausgeben:{}    cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{}    cursor (w1, 2, 3); out (w1, anwendungstext (53));{}                       out (w1, text (minwert, 2));{}                       out (w1, anwendungstext (51));{}    cursor (w1, 2, 4); out (w1, anwendungstext (54));{}                       out (w1, text (maxwert, 2));{}                       out (w1, anwendungstext (51));{}
+    cursor (w1, 2, 6); out (w1, anwendungstext (55));{}                       out (w1, text (aktuelle arbeitsphasendauer in minuten, 2));{}                       out (w1, anwendungstext (51)).{}  erfrage veraenderung:{}    cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (187))));{}    cursor (w3, 2, 3);{}    IF no (anwendungstext (219)){}       THEN LEAVE dauer einer arbeitsphase festlegen{}    FI.{}  neuen wert vom bildschirm holen:{}    INT VAR spa, zei;{}    cleop  (w3, 2, 3); out (w3, anwendungstext ( 58));{}
+    cursor (w3, 2, 3); out (w3, anwendungstext ( 58));{}    cursor (w3, 2, 4); out (w3, anwendungstext ( 59));{}    cursor (w3, 2, 6); out (w3, anwendungstext (188));{}    get cursor (w3, spa, zei);{}    cursor (w3, spa + 3, zei); out (w3, anwendungstext (51));{}    cursor (w3, spa, zei);{}    aktuelle arbeitsphasendauer in minuten{}                               := ermittelter wert (minwert, maxwert,{}                                  aktuelle arbeitsphasendauer in minuten).{}  benutzer ist einverstanden:{}
+    hinweise an den benutzer ausgeben;{}    simulationszeiten anzeigen (w2);{}    cleop (w3, 2, 3);{}    IF yes (w3, anwendungstext (189)){}       THEN TRUE{}       ELSE FALSE{}    FI.{}END PROC dauer einer arbeitsphase festlegen;{}PROC pausendauer festlegen:{}  INT CONST minwert :: 1, maxwert :: 30;{}  zeige fenster;{}  hinweise an den benutzer ausgeben;{}  simulationszeiten anzeigen (w2);{}  erfrage veraenderung;{}  REP{}    neuen wert vom bildschirm holen{}  UNTIL benutzer ist einverstanden PER.{}
+  zeige fenster:{}    w1 := window ( 2,  2, 28,  6);{}    w2 := window (22, 12, 37,  7);{}    w3 := window (32,  2, 47,  6);{}    page; show (w1); show (w2); show (w3).{}  hinweise an den benutzer ausgeben:{}    cursor (w1, 1, 1); out (w1, center (w1, invers (anwendungstext (52))));{}    cursor (w1, 2, 3); out (w1, anwendungstext (53));{}                       out (w1, text (minwert, 2));{}                       out (w1, anwendungstext (51));{}    cursor (w1, 2, 4); out (w1, anwendungstext (54));{}
+                       out (w1, text (maxwert, 2));{}                       out (w1, anwendungstext (51));{}    cursor (w1, 2, 6); out (w1, anwendungstext (55));{}                       out (w1, text (aktuelle pausendauer in minuten, 2));{}                       out (w1, anwendungstext (51)).{}  erfrage veraenderung:{}    cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (191))));{}    cursor (w3, 2, 3);{}    IF no (anwendungstext (220)){}       THEN LEAVE pausendauer festlegen{}    FI.{}
+  neuen wert vom bildschirm holen:{}    INT VAR spa, zei;{}    cleop  (w3, 2, 3); out (w3, anwendungstext ( 58));{}    cursor (w3, 2, 4); out (w3, anwendungstext ( 59));{}    cursor (w3, 2, 6); out (w3, anwendungstext (192));{}    get cursor (w3, spa, zei);{}    cursor (w3, spa + 3, zei); out (w3, anwendungstext (51));{}    cursor (w3, spa, zei);{}    aktuelle pausendauer in minuten{}                               := ermittelter wert (minwert, maxwert,{}                                          aktuelle pausendauer in minuten).{}
+  benutzer ist einverstanden:{}    hinweise an den benutzer ausgeben;{}    simulationszeiten anzeigen (w2);{}    cleop (w3, 2, 3);{}    IF yes (w3, anwendungstext (193)){}       THEN TRUE{}       ELSE FALSE{}    FI.{}END PROC pausendauer festlegen;{}PROC wertungsschluessel veraendern:{}  INT CONST abszisse :: 16, ordinate :: 2;{}  zeige fenster;{}  gib bewertungsschluessel aus (w1);{}  gib informationen aus;{}  stelle frage nach veraenderung;{}  REP{}    neueinstellung{}  UNTIL benutzer ist einverstanden PER.{}
+  zeige fenster:{}    w1 := window ( 2,  2, 38, 22);{}    w2 := window (42, 10, 37, 14);{}    w3 := window (42,  2, 37,  6);{}    page; show (w1); show (w2); show (w3).{}  gib informationen aus:{}    cursor (w2, 1, 1); out (w2, center (w2, invers (anwendungstext (52))));{}    cursor (w2, 2, 3); out (w2, anwendungstext (195));{}    cursor (w2, 2, 4); out (w2, anwendungstext (196));{}    cursor (w2, 2, 6); out (w2, anwendungstext (197));{}    cursor (w2, 2, 7); out (w2, anwendungstext (198));{}    cursor (w2, 2, 8); out (w2, anwendungstext (199));{}
+    cursor (w2, 2,11); out (w2, anwendungstext (200));{}    cursor (w2, 2,12); out (w2, anwendungstext (201));{}    cursor (w2, 2,13); out (w2, anwendungstext (202)).{}  stelle frage nach veraenderung:{}    cursor (w3, 1, 1); out (w3, center (w3, invers (anwendungstext (205))));{}    cursor (w3, 2, 3);{}    IF no (anwendungstext (206)){}       THEN LEAVE wertungsschluessel veraendern{}       ELSE gib hinweis auf linkes fenster{}    FI.{}  gib hinweis auf linkes fenster:{}    cleop  (w3, 2, 3); out (w3, anwendungstext (211));{}
+    cursor (w3, 2, 4); out (w3, anwendungstext (212));{}    cursor (w3, 2, 5); out (w3, anwendungstext (213)).{}  neueinstellung:{}    INT VAR zeiger;{}    cursor an;{}    FOR zeiger FROM 1 UPTO 11 REP{}      gehe auf aktuelle punktposition;{}      lasse verschieben{}    PER;{}    cursor aus.{}  gehe auf aktuelle punktposition:{}    cursor (w1, ordinate + 3 * zeiger, abszisse - nachkommastelle).{}  nachkommastelle:{}    int (bewertung [zeiger] * 10.0).{}  lasse verschieben:{}    TEXT VAR eingabezeichen; INT VAR position;{}
+    REP{}      inchar (eingabezeichen);{}      position := pos (oben unten return, eingabezeichen);{}      fuehre angemessene reaktion aus{}    UNTIL position = 3 PER.{}  fuehre angemessene reaktion aus:{}    SELECT position OF{}      CASE 1: steige auf{}      CASE 2: steige ab{}      CASE 3: (* tue nichts *){}      OTHERWISE piepse{}    END SELECT.{}  steige auf:{}    IF bewertung [zeiger] < 1.0{}       THEN loesche alten punkt;{}            bewertung [zeiger] INCR 0.1;{}            schreibe neuen punkt{}
+       ELSE piepse{}    FI.{}  steige ab:{}    IF bewertung [zeiger] > 0.0{}       THEN loesche alten punkt;{}            bewertung [zeiger] DECR 0.1;{}            schreibe neuen punkt{}       ELSE piepse{}    FI.{}  loesche alten punkt:{}    INT VAR tabspalte, tabzeile;{}    gehe auf aktuelle punktposition;{}    get cursor (w1, tabspalte, tabzeile);{}    IF tabspalte = ordinate + 3 OR tabzeile = abszisse{}       THEN out (w1, "|"){}       ELSE out (w1, blank){}    FI.{}  schreibe neuen punkt:{}    gehe auf aktuelle punktposition;{}
+    out (w1, punkt und zurueck).{}  benutzer ist einverstanden:{}    cleop (w3, 2, 3);{}    IF yes (w3, anwendungstext (207)){}       THEN TRUE{}       ELSE gib hinweis auf linkes fenster;{}            FALSE{}    FI.{}END PROC wertungsschluessel veraendern;{}PROC cleol (WINDOW VAR w, INT CONST cursorspalte, cursorzeile):{}  cursor (w, cursorspalte, cursorzeile);{}  IF remaining lines (w) > 1{}     THEN out (w, (areaxsize (w) - cursorspalte + 1) * blank){}     ELSE out (w, (areaxsize (w) - cursorspalte) * blank){}
+  FI;{}  cursor (w, cursorspalte, cursorzeile){}END PROC cleol;{}PROC cleop (WINDOW VAR w, INT CONST cursorspalte, cursorzeile):{}  cleol (w, cursorspalte, cursorzeile);{}  INT VAR i;{}  FOR i FROM 1 UPTO remaining lines (w) REP{}    cleol (w, 1, cursorzeile + i){}  PER;{}  cursor  (w, cursorspalte, cursorzeile){}END PROC cleop;{}PROC cursor an:{}  INT VAR spalte, zeile;{}  get cursor (spalte, zeile); cursor on; cursor (spalte, zeile){}END PROC cursor an;{}PROC cursor aus:{}  INT VAR spalte, zeile;{}
+  get cursor (spalte, zeile); cursor off; cursor (spalte, zeile){}END PROC cursor aus;{}INT PROC eingabe mit intervallanzeige (WINDOW VAR w, INT CONST minwert,{}                                       maxwert, anfangswert, cursorspalte,{}                                       cursorzeile):{}  BOOL VAR ist aufsteigend :: minwert = anfangswert;{}  INT  VAR aktueller wert  :: anfangswert, alter wert, eingelesener wert;{}  REP{}    hole position aus vorgabe (oben unten return, eingelesener wert);{}    SELECT eingelesener wert OF{}
+      CASE 1: erniedrige aktuellen wert wenn moeglich{}      CASE 2: erhoehe aktuellen wert wenn moeglich{}    END SELECT{}  UNTIL eingelesener wert = 3 PER;{}  aktueller wert.{}  erniedrige aktuellen wert wenn moeglich:{}    IF aktueller wert > minwert{}       THEN alter wert := aktueller wert;{}            aktueller wert DECR 1;{}            IF ist aufsteigend{}               THEN loesche alte markierung{}               ELSE markiere neues zeichen{}            FI{}       ELSE piepse{}    FI.{}  erhoehe aktuellen wert wenn moeglich:{}
+    IF aktueller wert < maxwert{}       THEN alter wert := aktueller wert;{}            aktueller wert INCR 1;{}            IF ist aufsteigend{}               THEN markiere neues zeichen{}               ELSE loesche alte markierung{}            FI{}       ELSE piepse{}    FI.{}  loesche alte markierung:{}    positioniere cursor in zeichenkette (w, 33, alter wert);{}    out (w, code (alter wert) + "  ");{}    cursor (cursorspalte, cursorzeile).{}  markiere neues zeichen:{}    positioniere cursor in zeichenkette (w, 33, aktueller wert);{}
+    out (w, invers (code (aktueller wert)));{}    cursor (cursorspalte, cursorzeile).{}END PROC eingabe mit intervallanzeige;{}INT PROC eingabe mit elementanzeige (WINDOW VAR w, INT CONST minwert,{}                                     maxwert, anfangswert,{}                                     cursorspalte, cursorzeile):{}  INT VAR aktueller wert :: anfangswert, alter wert, eingelesener wert;{}  REP{}    hole position aus vorgabe (oben unten return, eingelesener wert);{}    SELECT eingelesener wert OF{}
+      CASE 1: erniedrige aktuellen wert wenn moeglich{}      CASE 2: erhoehe aktuellen wert wenn moeglich{}    END SELECT{}  UNTIL eingelesener wert = 3 PER;{}  aktueller wert.{}  erniedrige aktuellen wert wenn moeglich:{}    IF aktueller wert > minwert{}       THEN alter wert := aktueller wert;{}            aktueller wert DECR 1;{}            loesche alte markierung;{}            markiere neues zeichen{}       ELSE piepse{}    FI.{}  erhoehe aktuellen wert wenn moeglich:{}    IF aktueller wert < maxwert{}
+       THEN alter wert := aktueller wert;{}            aktueller wert INCR 1;{}            loesche alte markierung;{}            markiere neues zeichen{}       ELSE piepse{}    FI.{}  loesche alte markierung:{}    positioniere cursor in zeichenkette (w, minwert, alter wert);{}    out (w, code (alter wert) + "  ");{}    cursor (cursorspalte, cursorzeile).{}  markiere neues zeichen:{}    positioniere cursor in zeichenkette (w, minwert, aktueller wert);{}    out (w, invers (code (aktueller wert)));{}
+    cursor (cursorspalte, cursorzeile).{}END PROC eingabe mit elementanzeige;{}PROC werkstueck zeigen (WINDOW VAR w):{}  INT VAR zaehler, spalte, zeile;{}  page (w);{}  werkstueckaufhaenger (spalte, zeile);{}  schreibe werkstueck zeilenweise.{}  schreibe werkstueck zeilenweise:{}    FOR zaehler FROM 1 UPTO aktuelle werkstueckhoehe REP{}      positioniere den cursor;{}      bastle eine zeile;{}      gib eine zeile aus{}    PER.{}  positioniere den cursor:{}    cursor (w, spalte,  zeile + zaehler - 1).{}
+  bastle eine zeile:{}    TEXT VAR zeileninhalt := "";{}    INT VAR z;{}    FOR z FROM 1 UPTO aktuelle werkstueckbreite REP{}      zeileninhalt CAT code (random (kleinster aktueller zeichencode,{}                                     groesster aktueller zeichencode)){}    PER.{}  gib eine zeile aus:{}    IF inversdarstellung{}       THEN out (w, invers (zeileninhalt)){}       ELSE out (w, zeileninhalt){}    FI.{}END PROC werkstueck zeigen;{}PROC werkstueckaufhaenger (INT VAR spalte, zeile):{}  spalte := ((maxspalten - aktuelle werkstueckbreite) DIV 2) + 3;{}
+  zeile  := ((maxzeilen  - aktuelle werkstueckhoehe ) DIV 2) + 2;{}  IF inversdarstellung THEN spalte DECR 1 FI{}END PROC werkstueckaufhaenger;{}PROC gib zeichenkette aus (WINDOW VAR w,{}                           INT CONST kleinster, groesster, markiertes):{}  INT VAR zaehler;{}  FOR zaehler FROM kleinster UPTO groesster REP{}    positioniere cursor in zeichenkette (w, kleinster, zaehler);{}    IF zaehler = markiertes{}       THEN out (w, invers (code (zaehler))){}       ELSE out (w, code (zaehler)){}
+    FI{}  PER{}END PROC gib zeichenkette aus;{}PROC positioniere cursor in zeichenkette (WINDOW VAR w,{}                                          INT CONST mincode, position):{}  cursor (w, 4 + ((position - mincode) DIV 19) * 5,{}             3 + ((position - mincode) MOD 19)){}END PROC positioniere cursor in zeichenkette;{}TEXT PROC tastenbezeichnung (TEXT CONST zeichen):{}  IF code (zeichen) >= 33 AND code (zeichen) <= 126{}     THEN "<" + zeichen + ">"{}     ELSE umgesetzter code{}  FI.{}  umgesetzter code:{}
+    SELECT code (zeichen) OF{}      CASE   1: anwendungstext (31){}      CASE   2: anwendungstext (32){}      CASE   3: anwendungstext (33){}      CASE   8: anwendungstext (34){}      CASE   9: anwendungstext (35){}      CASE  10: anwendungstext (36){}      CASE  11: anwendungstext (37){}      CASE  12: anwendungstext (38){}      CASE  13: anwendungstext (39){}      CASE  16: anwendungstext (40){}      CASE  27: anwendungstext (41){}      CASE  32: anwendungstext (42){}      CASE 214: anwendungstext (43){}
+      CASE 215: anwendungstext (44){}      CASE 216: anwendungstext (45){}      CASE 217: anwendungstext (46){}      CASE 218: anwendungstext (47){}      CASE 219: anwendungstext (48){}      CASE 251: anwendungstext (49){}      OTHERWISE anwendungstext (50){}  END SELECT{}END PROC tastenbezeichnung;{}INT PROC ermittelter wert (INT CONST minimum, maximum, startwert):{}  INT VAR aktueller wert, eingelesener wert;{}  cursor an;{}  aktueller wert := startwert;{}  REP{}    gib dreistellig aus und positioniere zurueck (aktueller wert, FALSE);{}
+    hole position aus vorgabe (oben unten return, eingelesener wert);{}    SELECT eingelesener wert OF{}      CASE 1: erhoehe aktuellen wert wenn moeglich{}      CASE 2: erniedrige aktuellen wert wenn moeglich{}    END SELECT{}  UNTIL eingelesener wert = 3 PER;{}  cursor aus;{}  aktueller wert.{}  erhoehe aktuellen wert wenn moeglich:{}    IF aktueller wert < maximum{}       THEN aktueller wert INCR 1{}       ELSE piepse{}    FI.{}  erniedrige aktuellen wert wenn moeglich:{}    IF aktueller wert > minimum{}
+       THEN aktueller wert DECR 1{}       ELSE piepse{}    FI.{}END PROC ermittelter wert;{}PROC gib dreistellig aus und positioniere zurueck (INT CONST wert,{}                                                   BOOL CONST mit wertwandel):{}  INT VAR spalte, zeile; get cursor (spalte, zeile);{}  IF mit wertwandel{}     THEN out ("'" + code (wert) + "'"){}     ELSE out (text (wert, 3)){}  FI;{}  cursor (spalte, zeile);{}END PROC gib dreistellig aus und positioniere zurueck;{}PROC hole position aus vorgabe (TEXT CONST vorgabe, INT VAR position):{}
+  TEXT VAR eingabezeichen; INT VAR spa, zei;{}  REP{}    get cursor (spa, zei); inchar (eingabezeichen); cursor (spa, zei);{}    position := pos (vorgabe, eingabezeichen);{}    IF position = 0 THEN piepse; cursor (spa, zei) FI{}  UNTIL position > 0 PER{}END PROC hole position aus vorgabe;{}PROC piepse:{}  INT VAR spa, zei; get cursor (spa, zei); out (piep); cursor (spa, zei){}END PROC piepse;{}END PACKET ls mp bap 1;{}stdvoreinstellung der parameter{}
+
diff --git a/mp-bap/ls-MP BAP 2 b/mp-bap/ls-MP BAP 2
new file mode 100644
index 0000000..0cd66ff
--- /dev/null
+++ b/mp-bap/ls-MP BAP 2	
@@ -0,0 +1,126 @@
+PACKET ls mp bap 2  DEFINES                (*******************************) 
+                                           (*                             *) 
+  materialpruefung, mp,                    (*         ls-MP BAP 2         *) 
+  bildschirmarbeitsplatz, bap,             (*         Version 1.1         *) 
+                                           (*                             *) 
+  mp bap simulation ausfuehren,            (*   (c) 1987, 1988            *) 
+  mp bap auswertung auf bildschirm,        (*       by Eva Latta-Weber    *) 
+  mp bap drucken von auswertungen,         (*          Bielefeld          *) 
+                                           (*                             *) 
+  mp bap protokollumfang festlegen,        (*******************************) 
+  mp bap kurzauswertung, 
+ 
+  druckereinstellung fuer protokolldatei, 
+  stddruckereinstellung fuer protokolldatei: 
+ 
+ 
+ 
+LET maxeintraege             =                    800, 
+    protokolldateipraefix    =       "ls-Protokoll: ", 
+    menukarte                =  "ls-MENUKARTE:MP-BAP", 
+    menubezeichnung          =                  "BAP", 
+    auswertdateipostfix      =        " - Auswertung", 
+    protokolldateityp        =                   1955, 
+    maxspalten               =                     70, 
+    maxzeilen                =                     14,{}    blank                    =                    " ",{}    trenn                    =                    "|",{}    werkstueckendekennung    =                      1,{}    pausenendekennung        =                      2,{}    simulationsendekennung   =                      3,{}    markierung ein           =                 ""15"",{}    markierung aus           =                " "14"",{}    stdschrifttyp            =                     "",{}
+    stdxstart                =                    0.0,{}    stdystart                =                    0.0,{}    stdfeldbreite            =                   21.0,{}    stdfeldlaenge            =                   29.5;{}LET  KONTROLLTABELLE = STRUCT (INT  letzter eintrag,{}                                    breite, hoehe,{}                                    kleinster code, groesster code,{}                                    anzahl aphasen, aphasendauer,{}                                    pausendauer,{}
+                               TEXT datum, uhrzeit, fehlerzeichen,{}                                    nach rechts, nach links,{}                                    nach oben, nach unten,{}                                    ausbesserung, naechstes,{}                               BOOL inversdarstellung,{}                               ROW  11 REAL bewertung,{}                               ROW maxeintraege KONTROLLE tabelle),{}     KONTROLLE       = STRUCT (INT  eintragskennung,{}                                    produktionsfehler,{}
+                                    anzahl korrekturen,{}                                    anzahl bedienfehler,{}                               REAL anfang, ende, differenz),{}     WERKSTUECK      = ROW maxspalten ROW maxzeilen INT;{}INT  VAR breite, hoehe, kleinster code, groesster code,{}         anzahl aphasen, aphasendauer, pausendauer,{}         eckspalte, eckzeile, x, y, xsize, ysize;{}TEXT VAR fehlerzeichen, nach rechts, nach links, nach oben, nach unten,{}         ausbesserung, naechstes, datum, uhrzeit;{}
+TEXT VAR protokollschrifttyp :: stdschrifttyp;{}REAL VAR xstart              :: stdxstart,{}         ystart              :: stdystart,{}         schreibfeldbreite   :: stdfeldbreite,{}         schreibfeldlaenge   :: stdfeldlaenge;{}ROW 11 REAL VAR bewertung;{}BOOL VAR inversdarstellung,{}         kontrolldatei zur vatertask ::  TRUE,{}         mit kurzprotokoll           ::  TRUE,{}         mit anmerkungen             ::  TRUE,{}         auswertung geht zum drucker :: FALSE;{}WERKSTUECK VAR werkstueck;{}
+PROC bildschirmarbeitsplatz:{}  kontrolldatei zur vatertask := FALSE;{}  install menu (menukarte);{}  handle menu  (menubezeichnung);{}END PROC bildschirmarbeitsplatz;{}PROC bap:{}  bildschirmarbeitsplatz{}END PROC bap;{}PROC materialpruefung:{}  TEXT VAR benutzerkennung :: "", protokollname, alter dateiname :: std;{}  install menu (menukarte, FALSE);{}  kontrolldatei zur vatertask := TRUE;{}  ermittle eingestellte parameter;{}  bereite den bildschirm vor;{}  ermittle die benutzerkennung;{}  gib benutzerhinweise aus;{}
+  arbeitsplatzsimulation ausfuehren (benutzerkennung, protokollname);{}  forget (protokollname, quiet);{}  last param (alter dateiname).{}  bereite den bildschirm vor:{}    WINDOW VAR w :: window ( 2, 10, 77, 14);{}    page;{}    show (w);{}    out (w, center (w, anwendungstext (400))).{}  ermittle die benutzerkennung:{}    benutzerkennung := compress (boxanswer (w, anwendungstext (401), "", 5));{}    IF benutzerkennung = ""{}       THEN cursor on; page;{}            LEAVE materialpruefung{}    FI.{}
+  gib benutzerhinweise aus:{}    boxinfo (w, anwendungstext (402));{}    boxinfo (w, anwendungstext (403));{}    boxinfo (w, anwendungstext (404));{}    gib bedieninformationen aus (2);{}    boxinfo (w, anwendungstext (405));{}    boxinfo (w, anwendungstext (406));{}    boxinfo (w, anwendungstext (407));{}    boxinfo (w, anwendungstext (408)).{}END PROC materialpruefung;{}PROC mp:{}  materialpruefung{}END PROC mp;{}PROC mp bap simulation ausfuehren:{}  TEXT VAR benutzerkennung :: "", dateiname;{}
+  kontrolldatei zur vatertask := FALSE;{}  ermittle eingestellte parameter;{}  bereite den bildschirm vor;{}  ermittle die benutzerkennung;{}  arbeitsplatzsimulation ausfuehren (benutzerkennung, dateiname);{}  regenerate menuscreen.{}  bereite den bildschirm vor:{}    WINDOW VAR w :: window (2,2,77,22);{}    page;{}    out (w, center (w, anwendungstext (399))).{}  ermittle die benutzerkennung:{}    benutzerkennung := compress (boxanswer (w, anwendungstext (401), "", 5));{}    IF benutzerkennung = ""{}
+       THEN regenerate menuscreen;{}            LEAVE mp bap simulation ausfuehren{}    FI.{}END PROC mp bap simulation ausfuehren;{}PROC mp bap auswertung auf bildschirm:{}  auswertung geht zum drucker := FALSE;{}  lasse protokolldateien auswaehlen;{}  werte protokolldateien aus;{}  regenerate menuscreen.{}  lasse protokolldateien auswaehlen:{}    THESAURUS VAR verfuegbare;{}    verfuegbare := infix namen (ALL myself, protokolldateipraefix,{}                                            protokolldateityp);{}
+    IF NOT not empty (verfuegbare){}       THEN noch kein protokoll{}       ELSE biete auswahl an{}    FI.{}  noch kein protokoll:{}    regenerate menuscreen;{}    menuinfo (anwendungstext (424));{}    LEAVE mp bap auswertung auf bildschirm.{}  biete auswahl an:{}    verfuegbare := menusome (verfuegbare, anwendungstext (421),{}                             anwendungstext (422), FALSE).{}  werte protokolldateien aus:{}    INT VAR k;{}    steige ggf bei leerem thesaurus aus;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}
+      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              gib hinweis auf auswertung;{}              simulationsauswertung (name (verfuegbare, k), TRUE);{}              forget (name (verfuegbare, k) + auswertdateipostfix, quiet);{}              fehlerbehandlung{}      FI{}    PER.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}       THEN regenerate menuscreen;{}            menuinfo (anwendungstext (423));{}            LEAVE mp bap auswertung auf bildschirm{}
+    FI.{}  gib hinweis auf auswertung:{}    page;{}    WINDOW VAR fenster :: window ( 2, 2, 77, 22);{}    show (fenster);{}    cursor (fenster, 1,  9); out (fenster, center (fenster, name (verfuegbare, k)));{}    cursor (fenster, 1, 12); out (fenster, center (anwendungstext (274))).{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            menuinfo (invers (errormessage));{}            clear error; enable stop;{}            LEAVE mp bap auswertung auf bildschirm{}    FI.{}
+END PROC mp bap auswertung auf bildschirm;{}PROC mp bap drucken von auswertungen:{}  auswertung geht zum drucker := TRUE;{}  lasse protokolldateien auswaehlen;{}  werte protokolldateien aus;{}  regenerate menuscreen.{}  lasse protokolldateien auswaehlen:{}    THESAURUS VAR verfuegbare;{}    verfuegbare := infix namen (ALL myself, protokolldateipraefix,{}                                            protokolldateityp);{}    IF NOT not empty (verfuegbare){}       THEN noch kein protokoll{}       ELSE biete auswahl an{}
+    FI.{}  noch kein protokoll:{}    regenerate menuscreen;{}    menuinfo (anwendungstext (424));{}    LEAVE mp bap drucken von auswertungen.{}  biete auswahl an:{}    verfuegbare := menusome (verfuegbare, anwendungstext (425),{}                             anwendungstext (422), FALSE).{}  werte protokolldateien aus:{}    INT VAR k;{}    steige ggf bei leerem thesaurus aus;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              gib hinweis auf auswertung;{}
+              simulationsauswertung (name (verfuegbare, k), FALSE);{}              print (name (verfuegbare, k) + auswertdateipostfix);{}              forget (name (verfuegbare, k) + auswertdateipostfix, quiet);{}              fehlerbehandlung{}      FI{}    PER.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}       THEN regenerate menuscreen;{}            menuinfo (anwendungstext (423));{}            LEAVE mp bap drucken von auswertungen{}    FI.{}  gib hinweis auf auswertung:{}
+    page;{}    WINDOW VAR fenster :: window ( 2, 2, 77, 22);{}    show (fenster);{}    cursor (fenster, 1,  9); out (fenster, center (fenster, name (verfuegbare, k)));{}    cursor (fenster, 1, 12); out (fenster, center (anwendungstext (270))).{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            menuinfo (invers (errormessage));{}            clear error; enable stop;{}            LEAVE mp bap drucken von auswertungen{}    FI.{}END PROC mp bap drucken von auswertungen;{}
+PROC mp bap protokollumfang festlegen:{}  page;{}  zeige aktuellen protokollumfang an;{}  gib erlaeuterungen zum protokollumfang;{}  frage nach umfangsaenderung;{}  regenerate menuscreen{}END PROC mp bap protokollumfang festlegen;{}PROC mp bap kurzauswertung:{}  page;{}  zeige aktuelle kurzauswertungseinstellung an;{}  gib erlaeuterungen zur kurzauswertung;{}  frage nach kurzauswertungsaenderung;{}  regenerate menuscreen{}END PROC mp bap kurzauswertung;{}PROC druckereinstellung fuer protokolldatei (TEXT CONST schrifttyp,{}
+                                             REAL CONST linker rand,{}                                                        oberer rand,{}                                                        feldbreite,{}                                                        feldlaenge):{}  protokollschrifttyp := schrifttyp;{}  xstart              := linker rand;{}  ystart              := oberer rand;{}  schreibfeldbreite   := feldbreite;{}  schreibfeldlaenge   := feldlaenge;{}END PROC druckereinstellung fuer protokolldatei;{}
+PROC stddruckereinstellung fuer protokolldatei:{}  protokollschrifttyp := stdschrifttyp;{}  xstart              := stdxstart;{}  ystart              := stdystart;{}  schreibfeldbreite   := stdfeldbreite;{}  schreibfeldlaenge   := stdfeldlaenge{}END PROC stddruckereinstellung fuer protokolldatei;{}                 (********************************){}PROC arbeitsplatzsimulation ausfuehren (TEXT CONST kennung,{}                                        TEXT VAR   dateiname):{}  ermittle eingestellte parameter;{}
+  lege datei mit kennung an (kennung, dateiname);{}  cursor on;{}  fuehre simulation durch (dateiname);{}  schicke ggf protokolldatei zur vatertask;{}  gib ggf kurzprotokoll aus.{}  schicke ggf protokolldatei zur vatertask:{}    IF kontrolldatei zur vatertask{}       THEN command dialogue (FALSE);{}            save (dateiname);{}            command dialogue (TRUE){}    FI.{}  gib ggf kurzprotokoll aus:{}    IF mit kurzprotokoll{}       THEN kurzauswertung auf bildschirm (dateiname){}       ELSE page; put (anwendungstext (271)){}
+    FI.{}END PROC arbeitsplatzsimulation ausfuehren;{}PROC ermittle eingestellte parameter:{}  werkstueckdefinition (breite, hoehe, kleinster code, groesster code,{}                        fehlerzeichen, inversdarstellung);{}  tastendefinition     (nach rechts, nach links, nach oben, nach unten,{}                        ausbesserung, naechstes);{}  phasendefinition     (anzahl aphasen, aphasendauer, pausendauer);{}  bewertungsschluessel (bewertung);{}END PROC ermittle eingestellte parameter;{}PROC lege datei mit kennung an (TEXT CONST kennung, TEXT VAR datname):{}
+  BOUND KONTROLLTABELLE VAR tab;{}  TEXT VAR interner name :: protokolldateipraefix;{}  interner name CAT kennung;{}  lege neue datei an;{}  type (old (datname), protokolldateityp).{}  lege neue datei an:{}    INT VAR i :: 0; TEXT VAR bezeichnung;{}    REP{}      i INCR 1;{}      bezeichnung := interner name + " /" + text (i){}    UNTIL NOT exists (bezeichnung) PER;{}    tab := new (bezeichnung);{}    initialisiere tabelle;{}    datname := bezeichnung.{}  initialisiere tabelle:{}    tab.letzter eintrag := 0.{}
+END PROC lege datei mit kennung an;{}PROC fuehre simulation durch (TEXT CONST dateiname):{}  BOUND KONTROLLTABELLE VAR tab :: old (dateiname);{}  TEXT CONST moegliche eingabezeichen :: nach rechts  + nach links +{}                                         nach oben    + nach unten +{}                                         ausbesserung + naechstes;{}  treffe vorbereitungen;{}  trage grunddaten in tabelle;{}  simuliere.{}  treffe vorbereitungen:{}     initialisierungen;{}     WINDOW VAR fenster :: window (  1,  9, 79, 16);{}
+     page;{}     gib bedieninformationen aus (2);{}     werkstueckaufhaenger (eckspalte, eckzeile);{}     weise auf arbeitsbeginn hin;{}     beginn der arbeitsphase      :=               clock (1);{}     beginn der bearbeitung       := beginn der arbeitsphase;{}     arbeitsphasenlaenge          := real (aphasendauer * 60).{}  initialisierungen:{}    INT  VAR eintragzaehler        :: 0,{}             arbeitsphasenzaehler  :: 1,{}             werkstueckzaehler     :: 0,{}             bedienfehlerzaehler   :: 0,{}
+             korrekturzaehler      :: 0,{}             produktionsfehler,{}             cursorspalte relativ,{}             cursorzeile  relativ;{}    REAL VAR beginn der arbeitsphase,{}             beginn der bearbeitung,{}             arbeitsphasenlaenge,{}             arbeitsphasenueberziehung,{}             pausenueberziehung.{}  weise auf arbeitsbeginn hin:{}    page (fenster);{}    boxinfo (fenster, anwendungstext (252), 5, maxint);{}    clear buffer.{}  trage grunddaten in tabelle:{}    tab.datum               := date;{}
+    tab.uhrzeit             := time of day;{}    tab.breite              := breite;{}    tab.hoehe               := hoehe;{}    tab.kleinster code      := kleinster code;{}    tab.groesster code      := groesster code;{}    tab.anzahl aphasen      := anzahl aphasen;{}    tab.aphasendauer        := aphasendauer;{}    tab.pausendauer         := pausendauer;{}    tab.fehlerzeichen       := fehlerzeichen;{}    tab.nach rechts         := nach rechts;{}    tab.nach links          := nach links;{}    tab.nach oben           := nach oben;{}
+    tab.nach unten          := nach unten;{}    tab.ausbesserung        := ausbesserung;{}    tab.naechstes           := naechstes;{}    tab.inversdarstellung   := inversdarstellung;{}    tab.bewertung           := bewertung;{}    eintragzaehler          := 1.{}  simuliere:{}    REP{}      gib holehinweis;{}      hole werkstueck  (werkstueck, produktionsfehler);{}      zeige werkstueck (werkstueck, fenster);{}      lasse werkstueck bearbeiten{}    UNTIL simulationsende erreicht PER.{}  gib holehinweis:{}
+    page (fenster);{}    cursor (fenster, 2, 3); out (fenster, anwendungstext (253)).{}  lasse werkstueck bearbeiten:{}    initialisiere den relativcursor;{}    setze cursor;{}    clear buffer;{}    bearbeite das werkstueck.{}  initialisiere den relativcursor:{}    cursorspalte relativ := 1;{}    cursorzeile relativ  := 1.{}  setze cursor:{}    IF inversdarstellung{}       THEN cursor (fenster, eckspalte + cursorspalte relativ,{}                             eckzeile  + cursorzeile  relativ - 1);{}
+       ELSE cursor (fenster, eckspalte + cursorspalte relativ - 1,{}                             eckzeile  + cursorzeile  relativ - 1);{}    FI.{}  bearbeite das werkstueck:{}    BOOL VAR werkstueck voll bearbeitet :: FALSE;{}    REP{}      hole eingabe und werte aus{}    UNTIL werkstueck voll bearbeitet PER.{}  hole eingabe und werte aus:{}    TEXT VAR eingabezeichen := incharety (100);{}    SELECT eingabezeichenposition OF{}      CASE 1: wenn moeglich nach rechts{}      CASE 2: wenn moeglich nach links{}
+      CASE 3: wenn moeglich nach oben{}      CASE 4: wenn moeglich nach unten{}      CASE 5: wenn moeglich ausbessern{}      CASE 6: beende werkstueckbearbeitung{}      OTHERWISE entscheide ob gepiepst wird{}    END SELECT.{}  eingabezeichenposition:{}    pos (moegliche eingabezeichen, eingabezeichen).{}  wenn moeglich nach rechts:{}    IF cursorspalte relativ < breite{}       THEN cursorspalte relativ INCR 1;{}            setze cursor{}       ELSE registriere bedienfehler{}    FI.{}  wenn moeglich nach links:{}
+    IF cursorspalte relativ > 1{}       THEN cursorspalte relativ DECR 1;{}            setze cursor{}       ELSE registriere bedienfehler{}    FI.{}  wenn moeglich nach oben:{}    IF cursorzeile relativ > 1{}       THEN cursorzeile relativ DECR 1;{}            setze cursor{}       ELSE registriere bedienfehler{}    FI.{}  wenn moeglich nach unten:{}    IF cursorzeile relativ < hoehe{}       THEN cursorzeile relativ INCR 1;{}            setze cursor{}       ELSE registriere bedienfehler{}    FI.{}
+  wenn moeglich ausbessern:{}    IF werkstueck [cursorspalte relativ][cursorzeile relativ] = code (fehlerzeichen){}       THEN werkstueck [cursorspalte relativ][cursorzeile relativ] := code (blank);{}            korrekturzaehler INCR 1;{}            get cursor (fenster, x, y);{}            out (fenster, blank);{}            cursor (fenster, x, y);{}       ELSE registriere bedienfehler{}    FI.{}  registriere bedienfehler:{}    piepse; bedienfehlerzaehler INCR 1.{}  entscheide ob gepiepst wird:{}    IF eingabezeichen <> "" THEN piepse FI.{}
+  beende werkstueckbearbeitung:{}    IF   simulationsende erreicht{}         THEN trage simulationsende in tabelle ein{}    ELIF arbeitsphasenende erreicht{}         THEN trage werkstueckdaten in tabelle ein;{}              ermittle ueberziehung der arbeitsphase;{}              lege eine pause ein{}    ELSE trage werkstueckdaten in tabelle ein{}    FI;{}    werkstueck voll bearbeitet := TRUE.{}  lege eine pause ein:{}    nimm pausendaten;{}    weise auf pausenanfang hin;{}    pausiere;{}    weise auf pausenende hin;{}
+    registriere pausenueberziehung.{}  nimm pausendaten:{}    REAL VAR pausenanfang :: clock (1),{}             pausenende   :: pausenanfang + real (pausendauer * 60);.{}  weise auf pausenanfang hin:{}    page (fenster);{}    boxnotice (fenster, anwendungstext (255), 5, x, y, xsize, ysize).{}  pausiere:{}    REP{}      pause (int ((pausenende - clock (1)) * 10.0)){}    UNTIL clock (1) >= pausenende PER.{}  weise auf pausenende hin:{}    page (fenster);{}    pausenanfang := clock (1);{}    piepse;{}
+    clear buffer;{}    boxinfo (fenster, anwendungstext (256), 5, maxint);{}    pausenende   := clock (1).{}  registriere pausenueberziehung:{}    pausenueberziehung := pausenende - pausenanfang;{}    trage pausenueberziehung in tabelle ein.{}  trage werkstueckdaten in tabelle ein:{}    REAL VAR bearbeitungsende :: clock (1);{}    tab.tabelle [eintragzaehler].eintragskennung    := werkstueckendekennung;{}    tab.tabelle [eintragzaehler].produktionsfehler  := produktionsfehler;{}    tab.tabelle [eintragzaehler].anzahl korrekturen := korrekturzaehler;{}
+    tab.tabelle [eintragzaehler].anzahl bedienfehler:= bedienfehlerzaehler;{}    tab.tabelle [eintragzaehler].anfang             := beginn der bearbeitung;{}    tab.tabelle [eintragzaehler].ende               := bearbeitungsende;{}    tab.tabelle [eintragzaehler].differenz          := bearbeitungszeit;{}    erhoehe eintragzaehler;{}    beginn der bearbeitung := clock (1);{}    werkstueckzaehler INCR 1;{}    bedienfehlerzaehler := 0;{}    korrekturzaehler    := 0.{}  trage pausenueberziehung in tabelle ein:{}
+    tab.tabelle [eintragzaehler].eintragskennung    := pausenendekennung;{}    tab.tabelle [eintragzaehler].produktionsfehler  := 0;{}    tab.tabelle [eintragzaehler].anzahl korrekturen := 0;{}    tab.tabelle [eintragzaehler].anzahl bedienfehler:= 0;{}    tab.tabelle [eintragzaehler].anfang             := pausenanfang;{}    tab.tabelle [eintragzaehler].ende               := pausenende;{}    tab.tabelle [eintragzaehler].differenz          := pausenueberziehung;{}    erhoehe eintragzaehler;{}    arbeitsphasenzaehler    INCR 1;{}
+    beginn der bearbeitung  := clock (1);{}    beginn der arbeitsphase := clock (1);{}    bearbeitungslaenge bestimmen.{}  trage simulationsende in tabelle ein:{}    bearbeitungsende := clock (1);{}    tab.tabelle [eintragzaehler].eintragskennung    := simulationsendekennung;{}    tab.tabelle [eintragzaehler].produktionsfehler  := produktionsfehler;{}    tab.tabelle [eintragzaehler].anzahl korrekturen := korrekturzaehler;{}    tab.tabelle [eintragzaehler].anzahl bedienfehler:= bedienfehlerzaehler;{}
+    tab.tabelle [eintragzaehler].anfang             := beginn der bearbeitung;{}    tab.tabelle [eintragzaehler].ende               := bearbeitungsende;{}    tab.tabelle [eintragzaehler].differenz          := bearbeitungszeit;{}    tab.letzter eintrag                             := eintragzaehler.{}  bearbeitungszeit:{}    bearbeitungsende - beginn der bearbeitung.{}  erhoehe eintragzaehler:{}    IF eintragzaehler < maxeintraege{}       THEN eintragzaehler INCR 1{}       ELSE trage simulationsende in tabelle ein;{}
+            errorstop (anwendungstext (254)){}    FI.{}  ermittle ueberziehung der arbeitsphase:{}    arbeitsphasenueberziehung := clock (1) - beginn der arbeitsphase{}                                           - arbeitsphasenlaenge.{}  bearbeitungslaenge bestimmen:{}    arbeitsphasenlaenge := real (aphasendauer * 60){}                                - arbeitsphasenueberziehung{}                                - pausenueberziehung.{}  arbeitsphasenende erreicht:{}    clock (1) - beginn der arbeitsphase >= arbeitsphasenlaenge.{}
+  simulationsende erreicht:{}    arbeitsphasenzaehler = anzahl aphasen AND arbeitsphasenende erreicht.{}END PROC fuehre simulation durch;{}PROC gib bedieninformationen aus (INT CONST zeile):{}  WINDOW VAR f1 :: window ( 2, zeile, 35, 6),{}             f2 :: window (40, zeile, 39, 6);{}  show (f1); show (f2);{}  cursor (f1, 2, 1); out (f1, anwendungstext (11));{}                     out (f1, tastenbezeichnung ( nach rechts));{}  cursor (f1, 2, 2); out (f1, anwendungstext (12));{}                     out (f1, tastenbezeichnung ( nach links));{}
+  cursor (f1, 2, 3); out (f1, anwendungstext (13));{}                     out (f1, tastenbezeichnung ( nach oben));{}  cursor (f1, 2, 4); out (f1, anwendungstext (14));{}                     out (f1, tastenbezeichnung ( nach unten));{}  cursor (f1, 2, 5); out (f1, anwendungstext (15));{}                     out (f1, tastenbezeichnung ( ausbesserung));{}  cursor (f1, 2, 6); out (f1, anwendungstext (16));{}                     out (f1, tastenbezeichnung ( naechstes));{}  cursor (f2, 2, 1); out (f2, anwendungstext (17));{}
+                     out (f2, text (anzahl aphasen, 4));{}  cursor (f2, 2, 2); out (f2, anwendungstext (18));{}                     out (f2, text (aphasendauer,   4));{}                     out (f2, anwendungstext (51));{}  cursor (f2, 2, 3); out (f2, anwendungstext (19));{}                     out (f2, text (pausendauer,    4));{}                     out (f2, anwendungstext (51));{}  cursor (f2, 2, 4); out (f2, anwendungstext ( 5));{}                     out (f2, text (gesamtzeit,      4));{}                     out (f2, anwendungstext (51));{}
+  cursor (f2, 2, 6); out (f2, anwendungstext (251));{}                     out (f2, 3 * blank);{}                     out (f2, fehlerzeichen).{}END PROC gib bedieninformationen aus;{}INT PROC gesamtzeit:{}  anzahl aphasen * aphasendauer + (anzahl aphasen - 1) * pausendauer{}END PROC gesamtzeit;{}PROC hole werkstueck (WERKSTUECK VAR w, INT VAR anzahl fehler):{}  INT VAR spaltenzaehler, zeilenzaehler;{}  anzahl fehler := 0;{}  FOR zeilenzaehler FROM 1 UPTO hoehe REP{}    ermittle eine zeile{}  PER.{}
+  ermittle eine zeile:{}    FOR spaltenzaehler FROM 1 UPTO breite REP{}      ermittle eine position;{}      ggf fehler registrieren{}    PER.{}  ermittle eine position:{}    w [spaltenzaehler][zeilenzaehler] := zufallscode.{}  zufallscode:{}    random (kleinster code, groesster code).{}  ggf fehler registrieren:{}    IF w [spaltenzaehler][zeilenzaehler] = code (fehlerzeichen){}       THEN anzahl fehler INCR 1{}    FI.{}END PROC hole werkstueck;{}PROC zeige werkstueck (WERKSTUECK CONST w, WINDOW VAR f):{}
+  INT VAR spaltenzaehler, zeilenzaehler;{}  page (f);{}  FOR zeilenzaehler FROM 1 UPTO hoehe REP{}    zeige eine zeile{}  PER.{}  zeige eine zeile:{}    cursor (f, eckspalte, eckzeile + zeilenzaehler - 1);{}    ggf invers einschalten;{}    FOR spaltenzaehler FROM 1 UPTO breite REP{}      out (f, code (w [spaltenzaehler][zeilenzaehler])){}    PER;{}    ggf invers ausschalten.{}  ggf invers einschalten:{}    IF inversdarstellung THEN out (f, markierung ein) FI.{}  ggf invers ausschalten:{}    IF inversdarstellung THEN out (f, markierung aus) FI.{}
+END PROC zeige werkstueck;{}PROC kurzauswertung auf bildschirm (TEXT CONST dateiname):{}  WINDOW VAR fenster :: window (  2, 10, 77, 13);{}  show (fenster);{}  clear buffer;{}  notiere ueberschrift;{}  notiere ergebnis.{}  notiere ueberschrift:{}    cursor (fenster, 1, 1);{}    out (fenster, center (fenster, anwendungstext (275)));{}    cursor (fenster, 1, 2);{}    out (fenster, center (fenster, anwendungstext (276))).{}  notiere ergebnis:{}    BOUND KONTROLLTABELLE CONST k := old (dateiname);{}    ermittle die simulationsdaten;{}
+    notiere gesamtzahl werkstuecke;{}    notiere zeichengesamtzahl;{}    notiere bedienfehler;{}    notiere benoetigte zeit;{}    notiere gesamtausbesserungsrate;{}    notiere gesamtbewertungsfaktor;{}    notiere gesamtbewertungszahl mit pausenueberziehung;{}    cursor (1, 24); out (anwendungstext (2));{}    pause.{}  ermittle die simulationsdaten:{}    INT  VAR z, anzahl zeichen pro werkstueck,{}             anzahl werkstuecke        ::   0,{}             anzahl bedienfehler       ::   0,{}             anzahl produktionsfehler  ::   0,{}
+             anzahl korrekturen        ::   0;{}    REAL VAR gesamtzahl zeichen, anteil korrekturen,{}             gesamtzeit                :: 0.0,{}             pausenueberzug            :: 0.0;{}    FOR z FROM 1 UPTO k.letzter eintrag REP{}      IF   k.tabelle [z].eintragskennung = werkstueckendekennung{}           THEN anzahl werkstuecke       INCR 1;{}                anzahl bedienfehler      INCR k.tabelle [z].anzahl bedienfehler;{}                anzahl produktionsfehler INCR k.tabelle [z].produktionsfehler;{}
+                anzahl korrekturen       INCR k.tabelle [z].anzahl korrekturen;{}                gesamtzeit               INCR k.tabelle [z].differenz;{}      ELIF k.tabelle [z].eintragskennung = pausenendekennung{}           THEN pausenueberzug           INCR k.tabelle [z].differenz;{}      FI{}    PER;{}    anzahl zeichen pro werkstueck := k.breite * k.hoehe;{}    gesamtzahl zeichen            :=   real (anzahl werkstuecke){}                                     * real (anzahl zeichen pro werkstueck);{}
+    IF anzahl produktionsfehler = 0{}       THEN anteil korrekturen    := 1.0{}       ELSE anteil korrekturen    :=   real (anzahl korrekturen){}                                     / real (anzahl produktionsfehler){}    FI.{}  notiere gesamtzahl werkstuecke:{}    cursor (fenster, 12, 4); out (fenster, anwendungstext (277));{}                             out (fenster, text (anzahl werkstuecke, 8)).{}  notiere zeichengesamtzahl:{}    cursor (fenster, 12, 5); out (fenster, anwendungstext (278));{}                             out (fenster, zahl aus zeichenkette).{}
+  zahl aus zeichenkette:{}    subtext (text (gesamtzahl zeichen, 9, 0), 1, 8).{}  notiere bedienfehler:{}    cursor (fenster, 12, 6); out (fenster, anwendungstext (279));{}                             out (fenster, text (anzahl bedienfehler, 8)).{}  notiere benoetigte zeit:{}    cursor (fenster, 12, 7); out (fenster, anwendungstext (280));{}                             out (fenster, text (gesamtzeit,         8, 2)).{}  notiere gesamtausbesserungsrate:{}    cursor (fenster, 12, 9); out (fenster, anwendungstext (281));{}
+                             out (fenster, text (anteil korrekturen, 8, 2)).{}  notiere gesamtbewertungsfaktor:{}    cursor (fenster, 12,10); out (fenster, anwendungstext (282));{}                             out (fenster, text (bewertungsfaktor, 8, 2)).{}  bewertungsfaktor:{}    bewertungsmasszahl (anteil korrekturen).{}  notiere gesamtbewertungszahl mit pausenueberziehung:{}    cursor (fenster, 12, 12); out (fenster, (anwendungstext (283)));{}                              out (fenster, text (gesamtwertung,   8, 2));{}
+    cursor (fenster, 12, 13); out (fenster, (anwendungstext (284)));{}                              out (fenster, 8 * "=").{}  gesamtwertung:{}    IF gesamtzeit = 0.0{}       THEN 0.0{}       ELSE gesamtzahl zeichen / (gesamtzeit + pausenueberzug){}                               * bewertungsfaktor{}    FI.{}END PROC kurzauswertung auf bildschirm;{}PROC simulationsauswertung (TEXT CONST dateiname, BOOL CONST mit zeigen):{}  TEXT CONST auswertdatei :: dateiname + auswertdateipostfix;{}  ermittle die kenndaten aus der protokolldatei (dateiname);{}
+  notiere ueberschrift 1               (auswertdatei);{}  notiere die kenndaten der simulation (auswertdatei);{}  notiere die werkstueckkenndaten      (auswertdatei);{}  notiere ein beispielwerkstueck       (auswertdatei);{}  notiere ueberschrift 2               (auswertdatei);{}  notiere gesamtergebnisse             (auswertdatei, dateiname);{}  notiere ueberschrift 3               (auswertdatei);{}  notiere tabellenkopf                 (auswertdatei);{}  notiere einzelne werkstueckdaten     (auswertdatei, dateiname);{}
+  notiere ggf die anmerkungen;{}  zeige ggf auswertung auf bildschirm.{}  notiere ggf die anmerkungen:{}    IF mit anmerkungen{}       THEN notiere anmerkungen        (auswertdatei);{}    FI.{}  zeige ggf auswertung auf bildschirm:{}    IF mit zeigen{}       THEN cursor on; show (auswertdatei); cursor off{}    FI.{}END PROC simulationsauswertung;{}PROC ermittle die kenndaten aus der protokolldatei (TEXT CONST dateiname):{}  BOUND KONTROLLTABELLE CONST k := old (dateiname);{}  breite                    := k.breite;{}
+  hoehe                     := k.hoehe;{}  kleinster code            := k.kleinster code;{}  groesster code            := k.groesster code;{}  fehlerzeichen             := k.fehlerzeichen;{}  inversdarstellung         := k.inversdarstellung;{}  nach rechts               := k.nach rechts;{}  nach links                := k.nach links;{}  nach oben                 := k.nach oben;{}  nach unten                := k.nach unten;{}  ausbesserung              := k.ausbesserung;{}  naechstes                 := k.naechstes;{}
+  anzahl aphasen            := k.anzahl aphasen;{}  aphasendauer              := k.aphasendauer;{}  pausendauer               := k.pausendauer;{}  datum                     := k.datum;{}  uhrzeit                   := k.uhrzeit;{}  bewertung                 := k.bewertung;{}END PROC ermittle die kenndaten aus der protokolldatei;{}PROC notiere ueberschrift 1 (TEXT CONST auswertdatei):{}  IF exists (auswertdatei){}     THEN forget (auswertdatei, quiet){}  FI;{}  FILE VAR f :: sequential file (output, auswertdatei);{}
+  IF auswertung geht zum drucker{}     THEN schreibe druckeranweisungen{}  FI;{}  putline (f, center (auswertdatei));{}  putline (f, center (length (auswertdatei) * "="));{}  put (f, anwendungstext (272)); put (f, datum); put (f, 26 * blank);{}  put (f, anwendungstext (273)); putline (f, uhrzeit);{}  line (f);{}  putline (f, center (anwendungstext (291)));{}  putline (f, center (length (anwendungstext (291)) * "=")).{}  schreibe druckeranweisungen:{}    write (f, "#type (""");{}    write (f, protokollschrifttyp);{}
+    write (f, """)##limit (");{}    write (f, text (schreibfeldbreite));{}    write (f, ")##pagelength (");{}    write (f, text (schreibfeldlaenge));{}    write (f, ")##start (");{}    write (f, text (xstart));{}    write (f, ",");{}    write (f, text (ystart));{}    write (f, ")#"); line (f).{}END PROC notiere ueberschrift 1;{}PROC notiere ueberschrift 2 (TEXT CONST auswertdatei):{}  FILE VAR f :: sequential file (output, auswertdatei);{}  putline (f, center (anwendungstext (285)));{}  putline (f, center (length (anwendungstext (285)) * "=")){}
+END PROC notiere ueberschrift 2;{}PROC notiere ueberschrift 3 (TEXT CONST auswertdatei):{}  FILE VAR f :: sequential file (output, auswertdatei);{}  line (f, 2);{}  putline (f, center (anwendungstext (311)));{}  putline (f, center (length (anwendungstext (311)) * "="));{}  line (f){}END PROC notiere ueberschrift 3;{}PROC notiere die kenndaten der simulation (TEXT CONST auswertdatei):{}  FILE VAR f :: sequential file (output, auswertdatei);{}  ROW 6 TEXT VAR ausgabe;{}  bestuecke ausgabezeilen;{}  schreibe ausgabezeilen.{}
+  bestuecke ausgabezeilen:{}    ausgabe [1] :=   anwendungstext (11){}                   + gleichlang (tastenbezeichnung (nach rechts ), 23){}                   + anwendungstext (17){}                   + text (anzahl aphasen,   4);{}    ausgabe [2] :=   anwendungstext (12){}                   + gleichlang (tastenbezeichnung (nach links  ), 23){}                   + anwendungstext (18){}                   + text (aphasendauer,     4) + anwendungstext (51);{}    ausgabe [3] :=   anwendungstext (13){}
+                   + gleichlang (tastenbezeichnung (nach oben   ), 23){}                   + anwendungstext (19){}                   + text (pausendauer,      4) + anwendungstext (51);{}    ausgabe [4] :=   anwendungstext (14){}                   + gleichlang (tastenbezeichnung (nach unten  ), 23){}                   + anwendungstext ( 5){}                   + text (simulationsdauer, 4) + anwendungstext (51);{}    ausgabe [5] :=   anwendungstext (15){}                   + gleichlang (tastenbezeichnung (ausbesserung), 23);{}
+    ausgabe [6] :=   anwendungstext (16){}                   + gleichlang (tastenbezeichnung (naechstes   ), 23){}                   + anwendungstext (251){}                   + (3 * blank) + fehlerzeichen.{}  simulationsdauer:{}    anzahl aphasen * aphasendauer + (anzahl aphasen - 1) * pausendauer.{}  schreibe ausgabezeilen:{}    INT VAR i;{}    FOR i FROM 1 UPTO 6 REP{}      putline (f, ausgabe [i]){}    PER;{}    line (f).{}END PROC notiere die kenndaten der simulation;{}PROC notiere die werkstueckkenndaten (TEXT CONST auswertdatei):{}
+  FILE VAR f :: sequential file (output, auswertdatei);{}  ROW 4 TEXT VAR ausgabe;{}  bestuecke ausgabezeilen;{}  schreibe ausgabezeilen.{}  bestuecke ausgabezeilen:{}    ausgabe [1] :=  anwendungstext (292) + text (breite,        4) +{}                    anwendungstext (296);{}    ausgabe [2] :=  anwendungstext (293) + text (hoehe,          4) +{}                    anwendungstext (296);{}    ausgabe [3] :=  anwendungstext (294) + text (breite * hoehe, 4) +{}                    anwendungstext (296);{}
+    ausgabe [4] :=  anwendungstext (295) + zeichenumfang.{}  zeichenumfang:{}    " " + code (kleinster code) + " ... " + code (groesster code) +{}    " (" + text (groesster code - kleinster code + 1, 3) +{}    anwendungstext (296) + ")".{}  schreibe ausgabezeilen:{}    INT VAR i;{}    FOR i FROM 1 UPTO 4 REP putline (f, ausgabe [i]) PER;{}    line (f).{}END PROC notiere die werkstueckkenndaten;{}PROC notiere ein beispielwerkstueck (TEXT CONST auswertdatei):{}  FILE VAR f :: sequential file (output, auswertdatei);{}
+  WERKSTUECK VAR beispiel;{}  INT VAR beispielfehler;{}  hole werkstueck (beispiel, beispielfehler);{}  notiere ueberschrift;{}  notiere werkstueckzeilen;{}  notiere werkstueckleerzeilen.{}  notiere ueberschrift:{}    putline (f, center (anwendungstext (297)));{}    putline (f, center (length (anwendungstext (297)) * "-")).{}  notiere werkstueckzeilen:{}    INT VAR bs, bz;{}    FOR bz FROM 1 UPTO hoehe REP{}      notiere eine zeile{}    PER.{}  notiere eine zeile:{}    TEXT VAR beispielzeile :: "";{}
+    konstruiere beispielzeile;{}    gib beispielzeile aus.{}  konstruiere beispielzeile:{}    beispielzeile CAT (((80 - breite) DIV 2) * blank);{}    FOR bs FROM 1 UPTO breite REP{}      beispielzeile CAT code (beispiel [bs][bz]){}    PER.{}  gib beispielzeile aus:{}    putline (f, beispielzeile).{}  notiere werkstueckleerzeilen:{}    line (f, maxzeilen - hoehe + 1).{}END PROC notiere ein beispielwerkstueck;{}PROC notiere gesamtergebnisse (TEXT CONST auswertdatei, protokolldatei):{}  FILE VAR f :: sequential file (output, auswertdatei);{}
+  BOUND KONTROLLTABELLE CONST k :: old (protokolldatei);{}  ermittle die simulationsdaten;{}    notiere gesamtzahl werkstuecke;{}    notiere anzahl zeichen pro werkstueck;{}    notiere zeichengesamtzahl;{}    notiere bedienfehler;{}    notiere produktionsfehlerzahl;{}    notiere fehlerkorrekturen;{}    notiere gesamtzeit mit pausenueberziehung;{}    notiere zeichenzahl pro sekunde mit;{}    notiere gesamtausbesserungsrate;{}    notiere gesamtbewertungsfaktor  mit;{}    notiere gesamtbewertungszahl    mit;{}
+    notiere gesamtzeit ohne pausenueberziehung;{}    notiere zeichenzahl pro sekunde ohne;{}    notiere gesamtbewertungszahl    ohne.{}  ermittle die simulationsdaten:{}    INT  VAR z, anzahl zeichen pro werkstueck,{}             anzahl werkstuecke        ::   0,{}             anzahl bedienfehler       ::   0,{}             anzahl produktionsfehler  ::   0,{}             anzahl korrekturen        ::   0;{}    REAL VAR gesamtzahl zeichen, anteil korrekturen,{}             gesamtzeit                :: 0.0,{}
+             pausenueberzug            :: 0.0;{}    FOR z FROM 1 UPTO k.letzter eintrag REP{}      IF   k.tabelle [z].eintragskennung = werkstueckendekennung{}           THEN anzahl werkstuecke       INCR 1;{}                anzahl bedienfehler      INCR k.tabelle [z].anzahl bedienfehler;{}                anzahl produktionsfehler INCR k.tabelle [z].produktionsfehler;{}                anzahl korrekturen       INCR k.tabelle [z].anzahl korrekturen;{}                gesamtzeit               INCR k.tabelle [z].differenz;{}
+      ELIF k.tabelle [z].eintragskennung = pausenendekennung{}           THEN pausenueberzug           INCR k.tabelle [z].differenz;{}      FI{}    PER;{}    anzahl zeichen pro werkstueck := k.breite * k.hoehe;{}    gesamtzahl zeichen            :=   real (anzahl werkstuecke){}                                     * real (anzahl zeichen pro werkstueck);{}    IF anzahl produktionsfehler = 0{}       THEN anteil korrekturen    := 1.0{}       ELSE anteil korrekturen    :=   real (anzahl korrekturen){}
+                                     / real (anzahl produktionsfehler){}    FI.{}  notiere gesamtzahl werkstuecke:{}    put (f, anwendungstext (277)); putline (f, text (anzahl werkstuecke, 8)).{}  notiere anzahl zeichen pro werkstueck:{}    put (f, anwendungstext (286)); putline (f, text (breite * hoehe,     8)).{}  notiere zeichengesamtzahl:{}    put (f, anwendungstext (278)); putline (f, zahl aus zeichenkette);{}    line (f).{}  zahl aus zeichenkette:{}    subtext (text (gesamtzahl zeichen, 9, 0), 1, 8).{}
+  notiere produktionsfehlerzahl:{}    put (f, anwendungstext (287)); putline (f, text (anzahl produktionsfehler, 8)).{}  notiere fehlerkorrekturen:{}    put (f, anwendungstext (288)); putline (f, text (anzahl korrekturen, 8)).{}  notiere bedienfehler:{}    put (f, anwendungstext (279)); putline (f, text (anzahl bedienfehler,8));{}    line (f).{}  notiere gesamtzeit mit pausenueberziehung:{}    put (f, anwendungstext (301)); put (f, text (gesamtzeit mit, 8, 1));{}    putline (f, anwendungstext (300)).{}
+  gesamtzeit mit:{}    gesamtzeit + pausenueberzug.{}  notiere zeichenzahl pro sekunde mit:{}    put (f, anwendungstext (302));{}    putline (f, text (zeichenpro sec mit, 8, 1));{}    line (f).{}  zeichen pro sec mit:{}    IF gesamtzeit + pausenueberzug > 0.0{}       THEN gesamtzahl zeichen / (gesamtzeit + pausenueberzug){}       ELSE 0.0{}    FI.{}  notiere gesamtausbesserungsrate:{}    put (f, anwendungstext (281)); putline (f, text (anteil korrekturen, 8, 1)).{}  notiere gesamtbewertungsfaktor mit:{}
+    put (f, anwendungstext (282)); putline (f, text (bewertungsfaktor, 8, 1));{}    line (f).{}  bewertungsfaktor:{}    bewertungsmasszahl (anteil korrekturen).{}  notiere gesamtbewertungszahl mit:{}    put (f, (anwendungstext (283))); putline (f, text (gesamtwertung mit,   8, 1));{}    put (f, (anwendungstext (284))); putline (f, 8 * "=").{}  gesamtwertung mit:{}    IF gesamtzeit = 0.0{}       THEN 0.0{}       ELSE gesamtzahl zeichen / (gesamtzeit + pausenueberzug){}                               * bewertungsfaktor{}
+    FI.{}  notiere gesamtzeit ohne pausenueberziehung:{}    put (f, anwendungstext (303)); put (f, text (gesamtzeit, 8, 1));{}    putline (f, anwendungstext (300)).{}  notiere zeichenzahl pro sekunde ohne:{}    put (f, anwendungstext (302));{}    putline (f, text (zeichenpro sec ohne, 8, 1)).{}  zeichen pro sec ohne:{}    IF gesamtzeit > 0.0{}       THEN gesamtzahl zeichen / gesamtzeit{}       ELSE 0.0{}    FI.{}  notiere gesamtbewertungszahl ohne:{}    put (f, (anwendungstext (304))); putline (f, text (gesamtwertung ohne,   8, 1));{}
+    put (f, (anwendungstext (284))); putline (f, 8 * "=").{}  gesamtwertung ohne:{}    IF gesamtzeit = 0.0{}       THEN 0.0{}       ELSE gesamtzahl zeichen / gesamtzeit * bewertungsfaktor{}    FI.{}END PROC notiere gesamtergebnisse;{}PROC notiere tabellenkopf (TEXT CONST auswertdatei):{}  FILE VAR f :: sequential file (output, auswertdatei);{}  putline (f, anwendungstext (312));{}  putline (f, anwendungstext (313));{}  putline (f, anwendungstext (314));{}  putline (f, anwendungstext (315));{}  putline (f, anwendungstext (316));{}
+  putline (f, anwendungstext (317));{}  putline (f, anwendungstext (318));{}END PROC notiere tabellenkopf;{}PROC notiere einzelne werkstueckdaten (TEXT CONST auswertdatei, dateiname):{}  BOUND KONTROLLTABELLE CONST k :: old (dateiname);{}  FILE VAR f :: sequential file (output, auswertdatei);{}  INT  VAR zeiger, werkstuecknummer :: 0;{}  TEXT VAR ausgabezeile :: "";{}  FOR zeiger FROM 1 UPTO k.letzter eintrag REP{}   notiere bearbeitungszeile{}  PER.{}  notiere bearbeitungszeile:{}    IF   k.tabelle [zeiger].eintragskennung = werkstueckendekennung{}
+         THEN werkstuecknummer INCR 1;{}              schreibe werkstueckzeile{}    ELIF k.tabelle [zeiger].eintragskennung = pausenendekennung{}         THEN schreibe pausenzeile{}    ELIF k.tabelle [zeiger].eintragskennung = simulationsendekennung{}         THEN werkstuecknummer INCR 1;{}              schreibe abschluss{}    ELSE putline (f, 75 * "?"){}    FI.{}  schreibe werkstueckzeile:{}    konstruiere ausgabezeile;{}    putline (f, ausgabezeile).{}  konstruiere ausgabezeile:{}    ausgabezeile := "";{}
+    ausgabezeile CAT text (werkstuecknummer, 5);{}    ausgabezeile CAT 2 * blank;{}    ausgabezeile CAT trenn;{}    ausgabezeile CAT text (k.tabelle [zeiger].anzahl bedienfehler, 5);{}    ausgabezeile CAT 3 * blank;{}    ausgabezeile CAT trenn;{}    ausgabezeile CAT text (k.tabelle [zeiger].produktionsfehler,   6);{}    ausgabezeile CAT 2 * blank;{}    ausgabezeile CAT trenn;{}    ausgabezeile CAT text (k.tabelle [zeiger].anzahl korrekturen,  6);{}    ausgabezeile CAT 2 * blank;{}    ausgabezeile CAT trenn;{}
+    ausgabezeile CAT text (k.tabelle [zeiger].differenz,  6, 1);{}    ausgabezeile CAT blank;{}    ausgabezeile CAT trenn;{}    ausgabezeile CAT text (zeichen pro zeiteinheit,  6, 1);{}    ausgabezeile CAT blank;{}    ausgabezeile CAT trenn;{}    ausgabezeile CAT text (einzelausbesserungsrate,  6, 1);{}    ausgabezeile CAT blank;{}    ausgabezeile CAT trenn;{}    ausgabezeile CAT text (bewertungsmasszahl (einzelausbesserungsrate), 6, 1);{}    ausgabezeile CAT blank;{}    ausgabezeile CAT trenn;{}
+    ausgabezeile CAT text (endbewertungszahl, 6, 1);{}    ausgabezeile CAT blank.{}  zeichen pro zeiteinheit:{}    real (breite * hoehe) / k.tabelle [zeiger].differenz.{}  einzelausbesserungsrate:{}    IF k.tabelle [zeiger].produktionsfehler = 0{}       THEN 0.0{}       ELSE   real (k.tabelle [zeiger].anzahl korrekturen){}            / real (k.tabelle [zeiger].produktionsfehler ){}    FI.{}  endbewertungszahl:{}    real (breite * hoehe) / k.tabelle [zeiger].differenz{}                          * bewertungsmasszahl (einzelausbesserungsrate).{}
+  schreibe pausenzeile:{}    line (f);{}    put     (f, anwendungstext (320));{}    put     (f, text (k.tabelle [zeiger].differenz, 6, 1));{}    putline (f, anwendungstext (300));{}    line (f).{}  schreibe abschluss:{}    putline (f, anwendungstext (318));{}    putline (f, anwendungstext (319));{}    line (f);{}    konstruiere ausgabezeile;{}    ausgabezeile := "(" +{}                    subtext (ausgabezeile, 2, length (ausgabezeile) - 1) +{}                    ")";{}    putline (f, ausgabezeile).{}
+END PROC notiere einzelne werkstueckdaten;{}PROC notiere anmerkungen (TEXT CONST auswertdatei):{}  FILE VAR f :: sequential file (output, auswertdatei);{}  line (f);{}  schreibe kopf;{}  schreibe hinweis auf letztes werkstueck;{}  schreibe hinweis auf bedienfehler;{}  erlaeutere bewertungsschluessel;{}  stelle bewertungsschluessel graphisch dar;{}  schreibe rest.{}  schreibe kopf:{}    putline (f, center (anwendungstext (325)));{}    putline (f, center (length (anwendungstext (325)) * "="));{}    line (f).{}
+  schreibe hinweis auf letztes werkstueck:{}    INT VAR i;{}    FOR i FROM 326 UPTO 337 REP{}      putline (f, anwendungstext (i)){}    PER;{}    line (f).{}  schreibe hinweis auf bedienfehler:{}    FOR i FROM 339 UPTO 341 REP{}      putline (f, anwendungstext (i)){}    PER;{}    line (f).{}  erlaeutere bewertungsschluessel:{}    FOR i FROM 343 UPTO 372 REP{}      putline (f, anwendungstext (i)){}    PER.{}  stelle bewertungsschluessel graphisch dar:{}    putline (f, anwendungstext (374));{}    putline (f, anwendungstext (375));{}
+    ermittle die startposition;{}    zeichne diagramm;{}    trage werte ein.{}  ermittle die startposition:{}    modify (f);{}    INT VAR zeilenpos :: lines (f) + 2, spaltenpos :: 18.{}  zeichne diagramm:{}    cursor (f, spaltenpos, zeilenpos     , anwendungstext (20));{}    cursor (f, spaltenpos, zeilenpos +  1, anwendungstext (21));{}    cursor (f, spaltenpos, zeilenpos +  3, anwendungstext (23));{}    cursor (f, spaltenpos, zeilenpos +  4, anwendungstext (22));{}    cursor (f, spaltenpos, zeilenpos +  5, anwendungstext (22));{}
+    cursor (f, spaltenpos, zeilenpos +  6, anwendungstext (22));{}    cursor (f, spaltenpos, zeilenpos +  7, anwendungstext (22));{}    cursor (f, spaltenpos, zeilenpos +  8, anwendungstext (24));{}    cursor (f, spaltenpos, zeilenpos +  9, anwendungstext (22));{}    cursor (f, spaltenpos, zeilenpos + 10, anwendungstext (22));{}    cursor (f, spaltenpos, zeilenpos + 11, anwendungstext (22));{}    cursor (f, spaltenpos, zeilenpos + 12, anwendungstext (22));{}    cursor (f, spaltenpos, zeilenpos + 13, anwendungstext (25));{}
+    cursor (f, spaltenpos, zeilenpos + 14, anwendungstext (26));{}    cursor (f, spaltenpos, zeilenpos + 15, anwendungstext (27)).{}  trage werte ein:{}    zeilenpos INCR 13;{}    INT VAR bwzeiger;{}    FOR bwzeiger FROM 1 UPTO 11 REP{}      cursor (f, spaltenpos + 3 * bwzeiger, zeilenpos - konkreter wert, "+"){}    PER.{}  konkreter wert:{}    int (bewertung [bwzeiger] * 10.0).{}  schreibe rest:{}    output (f);{}    line (f, 2);{}    FOR i FROM 377 UPTO 387 REP{}      putline (f, anwendungstext (i)){}
+    PER;{}    haenge an jede zeile ein blank an.{}  haenge an jede zeile ein blank an:{}    TEXT VAR inhalt;{}    INT  VAR zeilenzeiger;{}    modify (f);{}    FOR zeilenzeiger FROM 1 UPTO lines (f) REP{}      to line (f, zeilenzeiger);{}      read record (f, inhalt);{}      inhalt CAT blank;{}      write record (f, inhalt){}    PER;{}    to line (f,1).{}END PROC notiere anmerkungen;{}PROC cursor (FILE VAR f, INT CONST spa, zei, TEXT CONST text):{}  positioniere an zeile;{}  positioniere an spalte;{}
+  gib text an position aus.{}  positioniere an zeile:{}    IF zeile noch nicht vorhanden{}       THEN schaffe zeile und gehe dorthin{}       ELSE to line (f,zei){}    FI.{}  zeile noch nicht vorhanden:{}    zei > lines (f).{}  schaffe zeile und gehe dorthin:{}    INT VAR zaehler 1;{}    IF lines (f) = 0{}       THEN to line (f,lines (f));{}            insert record (f);{}    FI;{}    FOR zaehler 1 FROM lines (f)  UPTO zei REP{}      to line (f,lines (f));{}      down (f);insert record (f){}    PER;{}
+    to line(f,zei).{}  positioniere an spalte:{}    TEXT VAR alter satz :: "", neuer satz :: "", restsatz ::"";{}    INT VAR satzlaenge;{}    read record (f,alter satz);{}    satzlaenge := length (alter satz);{}    IF satzlaenge = 0{}       THEN neuer satz CAT (spa -1) * " "{}    ELIF satzlaenge >= spa{}       THEN neuer satz := subtext(alter satz,1,spa-1);{}            restsatz   := subtext(alter satz, spa + length (text));{}       ELSE neuer satz := alter satz;{}            neuer satz CAT (spa - satzlaenge - 1) * " "{}
+    FI.{}  gib text an position aus:{}   neuer satz CAT text;{}   IF restsatz <> ""{}      THEN neuer satz CAT restsatz{}   FI;{}   write record(f,neuer satz).{} END PROC cursor;{}TEXT PROC gleichlang (TEXT CONST text, INT CONST laenge):{}  TEXT VAR intern :: compress (text);{}  INT  VAR anzahl :: laenge - length (intern);{}  IF anzahl < 0{}     THEN subtext (intern, 1, laenge){}     ELSE intern + (anzahl * blank){}  FI{}END PROC gleichlang;{}REAL PROC bewertungsmasszahl (REAL CONST wert):{}  REAL VAR interner wert := round (wert, 1);{}
+  IF interner wert > wert{}     THEN interner wert DECR 0.1{}  FI;{}  interpoliere.{}  interpoliere:{}    REAL VAR unterer wert, oberer wert;{}    unterer wert := interner wert;{}    IF unterer wert = 1.0{}       THEN oberer wert := 1.0{}       ELSE oberer  wert := unterer wert + 0.1{}    FI;{}    unterer wert := bewertung (int (unterer wert * 10.0) + 1);{}    oberer  wert := bewertung (int (oberer  wert * 10.0) + 1);{}    unterer wert + (oberer wert - unterer wert) * faktor.{}  faktor:{}    frac (wert * 10.0).{}
+END PROC bewertungsmasszahl;{}PROC zeige aktuellen protokollumfang an:{}  WINDOW VAR w :: window (2, 2, 34,  5);{}  show (w);{}  cursor (w, 1, 1); out (w, center (w, invers (anwendungstext (431))));{}  IF mit anmerkungen{}     THEN cursor (w, 2, 4); out (w, anwendungstext (432)){}     ELSE cursor (w, 2, 4); out (w, anwendungstext (433));{}  FI.{}END PROC zeige aktuellen protokollumfang an;{}PROC gib erlaeuterungen zum protokollumfang:{}  WINDOW VAR f :: window ( 2, 9, 77, 15);{}  show (f);{}  cursor (f, 1, 1); out (f, center (f, invers (anwendungstext (434))));{}
+  cursor (f, 5, 3); out (f, anwendungstext (435));{}  cursor (f, 5, 4); out (f, anwendungstext (436));{}  cursor (f, 5, 5); out (f, anwendungstext (437));{}  cursor (f, 5, 6); out (f, anwendungstext (438));{}  cursor (f, 5, 8); out (f, anwendungstext (439));{}  cursor (f, 5, 9); out (f, anwendungstext (440));{}  cursor (f, 5,10); out (f, anwendungstext (441));{}  cursor (f, 5,11); out (f, anwendungstext (442));{}  cursor (f, 5,13); out (f, anwendungstext (443));{}  cursor (f, 5,14); out (f, anwendungstext (444));{}
+END PROC gib erlaeuterungen zum protokollumfang;{}PROC frage nach umfangsaenderung:{}  WINDOW VAR fenster :: window (38, 2, 41, 5);{}  show (fenster);{}  cursor (fenster, 1, 1); out (fenster, center (fenster, invers (anwendungstext (451))));{}  cursor (fenster, 4, 3); out (fenster, anwendungstext (452));{}  cursor (fenster, 4, 4);{}  IF yes (fenster, anwendungstext (453)){}     THEN  mit anmerkungen := NOT mit anmerkungen{}  FI.{}END PROC frage nach umfangsaenderung;{}PROC zeige aktuelle kurzauswertungseinstellung an:{}
+  WINDOW VAR w :: window ( 2, 2, 34,  5);{}  show (w);{}  cursor (w, 1, 1); out (w, center (w, invers (anwendungstext (431))));{}  IF mit kurzprotokoll{}     THEN cursor (w, 7, 4); out (w, anwendungstext (461));{}     ELSE cursor (w, 7, 4); out (w, anwendungstext (462));{}  FI.{}END PROC zeige aktuelle kurzauswertungseinstellung an;{}PROC gib erlaeuterungen zur kurzauswertung:{}  WINDOW VAR f :: window ( 2, 9, 77, 15);{}  show (f);{}  cursor (f, 1, 1); out (f, center (f, invers (anwendungstext (463))));{}
+  cursor (f, 5, 3); out (f, anwendungstext (464));{}  cursor (f, 5, 4); out (f, anwendungstext (465));{}  cursor (f, 5, 5); out (f, anwendungstext (466));{}  cursor (f, 5, 6); out (f, anwendungstext (467));{}  cursor (f, 5, 8); out (f, anwendungstext (468));{}  cursor (f, 5, 9); out (f, anwendungstext (469));{}  cursor (f, 5,10); out (f, anwendungstext (470));{}  cursor (f, 5,11); out (f, anwendungstext (471));{}  cursor (f, 5,13); out (f, anwendungstext (472));{}  cursor (f, 5,14); out (f, anwendungstext (473));{}
+END PROC gib erlaeuterungen zur kurzauswertung;{}PROC frage nach kurzauswertungsaenderung:{}  WINDOW VAR fenster :: window (38, 2, 41, 5);{}  show (fenster);{}  cursor (fenster, 1, 1); out (fenster, center (fenster, invers (anwendungstext (481))));{}  cursor (fenster, 5, 3); out (fenster, anwendungstext (482));{}  cursor (fenster, 5, 4);{}  IF yes (fenster, anwendungstext (483)){}     THEN  mit kurzprotokoll := NOT mit kurzprotokoll{}  FI.{}END PROC frage nach kurzauswertungsaenderung;{}END PACKET ls mp bap 2;{}
+
diff --git a/mp-bap/ls-MP BAP-gen b/mp-bap/ls-MP BAP-gen
new file mode 100644
index 0000000..26a84c3
--- /dev/null
+++ b/mp-bap/ls-MP BAP-gen	
@@ -0,0 +1,30 @@
+                                             (*****************************) 
+                                             (*                           *) 
+                                             (*         ls-MP BAP         *) 
+                                             (*     GENERATORPROGRAMM     *) 
+                                             (*                           *) 
+                                             (* (c) 1987  (01.09.87)      *) 
+                                             (*     by Eva Latta          *) 
+                                             (*        Bielefeld          *) 
+                                             (*****************************) 
+LET mm taskname   = "ls-MENUKARTEN", 
+    eigener name  = "ls-MP BAP/gen", 
+    datei1        = "ls-MP BAP 1", 
+    datei2        = "ls-MP BAP 2", 
+    menukarte     = "ls-MENUKARTE:MP-BAP"; 
+ 
+PROC stelle existenz des mm sicher: 
+  cursor (1, 5); out (""4""); 
+  IF NOT exists (task (mm taskname)) 
+     THEN errorstop ("Unbedingt erst den 'MENUKARTEN MANAGER' generieren!"); 
+  FI 
+END PROC stelle existenz des mm sicher; 
+ 
+PROC vom archiv (TEXT CONST datei): 
+  cursor (1,5); out (""4""); 
+  out ("  """); out (datei); putline (""" wird geholt.");{}  fetch (datei, archive){}END PROC vom archiv;{}PROC hole (TEXT CONST datei):{}  IF NOT exists (datei) THEN vom archiv (datei) FI{}END PROC hole;{}PROC in (TEXT CONST datei):{}  hole (datei);{}  cursor (1, 5); out (""4"");{}  out ("  """); out (datei); out (""" wird übersetzt: ");{}  insert (datei);{}  forget (datei, quiet);{}END PROC in;{}PROC schicke (TEXT CONST datei):{}  cursor (1, 5); out (""4"");{}  out ("  """); out(datei);{}  out (""" wird zum MENUKARTEN-MANAGER geschickt!");{}
+  command dialogue (FALSE);{}  save (datei, task (mm taskname));{}  command dialogue (TRUE);{}  forget (datei, quiet){}END PROC schicke;{}INT VAR size, used;{}BOOL VAR einzeln;{}storage (size, used);{}einzeln := size - used < 500;{}forget (eigener name, quiet);{}wirf kopfzeile aus;{}stelle existenz des mm sicher;{}hole die dateien;{}insertiere die dateien;{}mache global manager aus der task.{}wirf kopfzeile aus:{}  page;{}  putline ("                  "15"ls-MP BAP  -  Automatische Generierung "14"").{}
+hole die dateien:{}  IF     NOT exists (datei 1){}     COR NOT exists (datei 2){}     COR NOT exists (menukarte){}     THEN hole dateien vom archiv; LEAVE hole die dateien{}  FI.{}hole dateien vom archiv:{}  cursor (1,3); out (""4"");{}  IF yes ("Ist das Archiv angemeldet und die Diskette eingelegt"){}     THEN lese ein{}     ELSE line (2);{}          errorstop ("Ohne die Diskette kann ich das System nicht generieren!"){}  FI.{}lese ein:{}  cursor (1, 3); out (""4"");{}  out ("                   "15"Bitte die Diskette eingelegt lassen! "14"");{}
+  IF NOT einzeln{}     THEN  hole (datei 1);{}           hole (datei 2);{}           hole (menukarte);{}           cursor (1, 3); out(""4"");{}           out ("                  "15"Die Diskette wird nicht mehr benötigt! "14"");{}           release (archive){}  FI.{}insertiere die dateien:{}  check off;{}  cursor (1, 3); out(""4"");{}  out ("                  "15"Die Diskette wird nicht mehr benötigt! "14"");{}  in (datei 1);{}  in (datei 2);{}  schicke (menukarte);{}  IF einzeln THEN release (archive) FI;{}
+  check on.{}mache global manager aus der task:{}  global manager.{}
+
diff --git a/net/basic net b/net/basic net
new file mode 100644
index 0000000..c5e9278
--- /dev/null
+++ b/net/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/net/net files-M b/net/net files-M
new file mode 100644
index 0000000..ae6f9f3
--- /dev/null
+++ b/net/net files-M	
@@ -0,0 +1,5 @@
+net report
+net hardware interface
+basic net
+net manager
+
diff --git a/net/net hardware interface b/net/net hardware interface
new file mode 100644
index 0000000..4e3466a
--- /dev/null
+++ b/net/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/net/net inserter b/net/net inserter
new file mode 100644
index 0000000..c89d0f0
--- /dev/null
+++ b/net/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/net/net manager b/net/net manager
new file mode 100644
index 0000000..05f530e
--- /dev/null
+++ b/net/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/net/net report b/net/net report
new file mode 100644
index 0000000..ddc19d2
--- /dev/null
+++ b/net/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/net/netz b/net/netz
new file mode 100644
index 0000000..c237ba2
--- /dev/null
+++ b/net/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/net/netzhandbuch b/net/netzhandbuch
new file mode 100644
index 0000000..7083462
--- /dev/null
+++ b/net/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/net/netzhandbuch.anhang b/net/netzhandbuch.anhang
new file mode 100644
index 0000000..17d1ece
--- /dev/null
+++ b/net/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/net/netzhandbuch.index b/net/netzhandbuch.index
new file mode 100644
index 0000000..01d8a0f
--- /dev/null
+++ b/net/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/net/port server b/net/port server
new file mode 100644
index 0000000..46c647f
--- /dev/null
+++ b/net/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/net/printer server b/net/printer server
new file mode 100644
index 0000000..b1a30bc
--- /dev/null
+++ b/net/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/net/spool cmd b/net/spool cmd
new file mode 100644
index 0000000..b44e799
--- /dev/null
+++ b/net/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/net/spool manager b/net/spool manager
new file mode 100644
index 0000000..e711ab4
--- /dev/null
+++ b/net/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/printer/dotmatrix24/beschreibungen24 b/printer/dotmatrix24/beschreibungen24
new file mode 100644
index 0000000..e3d2fa9
--- /dev/null
+++ b/printer/dotmatrix24/beschreibungen24
@@ -0,0 +1,62 @@
+ 
+(*************************************************************************)
+(*                                            Stand   :  3. 1.89         *)
+(*  Beschreibungen-Datei für 24-Nadel-Drucker Version : 0.9              *)
+(*                                            Autor   : hjh              *)
+(*************************************************************************)
+ 
+$necp5p7$ 
+begin;headnecp5p7;declarations;feed; 
+open;opendoch;opendocp5p7;openpagep5-7;close;closepage; 
+execute;cmdp5-7;crs;move;movep5-7;onoff;typep5-7;end
+
+$necp6$ 
+begin;headnecp6;declarations;feed; 
+open;opendoch;opendocp6;openpagep5-7;close;closepage; 
+execute;cmdp5-7;crs;move;movep5-7;onoff;typep5-7;end
+ 
+$necp6+$
+begin;headnecp6+;declarations;speed;topmargin;typefacep6+;feed; 
+open;opendoch;initspeed;opendocp6+;openpage;close;closepage; 
+execute;cmdp6+;crs;move;stdmove;onoff;typep6+;end
+
+$epsonlq850$
+begin;headlq850;declarations;speed;topmargin;typefacelq850;feed; 
+open;opendoch;initspeed;opendoclq850;openpage;close;closepage; 
+execute;cmdlq850;crs;move;stdmove;onoff;typeplq850;end
+
+$epsonlq1500$
+printerlq1500;end
+ 
+$oki390/391$
+begin;headoki390/391;declarations;speed;topmargin;typefaceoki;feedschacht; 
+open;opendoch;initspeed;opendocokieps;openpage;close;closepage; 
+execute;cmdoki;crs;move;stdmove;onoff;typeokieps;end
+
+$oki393/393Ceps$
+begin;headoki393/393Ceps;declarations;speed;topmargin;typefaceoki;feedschacht; 
+open;opendoch;initspeed;opendocokieps;openpage;close;closepage; 
+execute;cmdoki;crs;move;stdmove;onoff;typeokieps;end 
+ 
+$oki393/393Cibm$
+begin;headoki393/393Cibm;declarations;speed;topmargin;typefaceoki;feedschacht; 
+open;opendoch;initspeed;opendocokiibm;openpage;close;closepage; 
+execute;cmdoki;crs;move;stdmove;onoff;typeokiibm;end 
+ 
+$toshp321$ 
+begin;headtoshp321;declarations;speed;feed; 
+open;opendochtosh;initspeed;opendoctosh;openpagetosh;close;closepagetosh; 
+execute;cmdtosh;crs;move;stdmove;onoff;typetosh;end 
+ 
+$starnb24$ 
+begin;headstarnb24;declarations;speed;topmargin;typefacestar;feedschacht; 
+open;opendoch;initspeed;opendocstar;openpage;close;closepage; 
+execute;cmdstar;crs;move;stdmove;onoff;typestar;end 
+ 
+$brotherm1724l$ 
+begin;headbrotherm1724l;declarations;speed;topmargin;feed; 
+open;opendoch;initspeed;opendocbrother;openpage;close;closepage; 
+execute;cmdtosh;crs;move;stdmove;onoff;typebrother;end 
+ 
+
+
diff --git a/printer/dotmatrix24/fonttab.brother b/printer/dotmatrix24/fonttab.brother
new file mode 100644
index 0000000..2251e18
Binary files /dev/null and b/printer/dotmatrix24/fonttab.brother differ
diff --git a/printer/dotmatrix24/fonttab.epson.lq1500 b/printer/dotmatrix24/fonttab.epson.lq1500
new file mode 100644
index 0000000..1b4c6a6
Binary files /dev/null and b/printer/dotmatrix24/fonttab.epson.lq1500 differ
diff --git a/printer/dotmatrix24/fonttab.epson.lq850 b/printer/dotmatrix24/fonttab.epson.lq850
new file mode 100644
index 0000000..7a6d2f0
Binary files /dev/null and b/printer/dotmatrix24/fonttab.epson.lq850 differ
diff --git a/printer/dotmatrix24/fonttab.nec.p5 b/printer/dotmatrix24/fonttab.nec.p5
new file mode 100644
index 0000000..9910da6
Binary files /dev/null and b/printer/dotmatrix24/fonttab.nec.p5 differ
diff --git a/printer/dotmatrix24/fonttab.nec.p5.new b/printer/dotmatrix24/fonttab.nec.p5.new
new file mode 100644
index 0000000..9804bd5
Binary files /dev/null and b/printer/dotmatrix24/fonttab.nec.p5.new differ
diff --git a/printer/dotmatrix24/fonttab.nec.p6+ b/printer/dotmatrix24/fonttab.nec.p6+
new file mode 100644
index 0000000..b209e81
Binary files /dev/null and b/printer/dotmatrix24/fonttab.nec.p6+ differ
diff --git a/printer/dotmatrix24/fonttab.oki b/printer/dotmatrix24/fonttab.oki
new file mode 100644
index 0000000..2251e18
Binary files /dev/null and b/printer/dotmatrix24/fonttab.oki differ
diff --git a/printer/dotmatrix24/fonttab.toshiba.p321 b/printer/dotmatrix24/fonttab.toshiba.p321
new file mode 100644
index 0000000..452afca
Binary files /dev/null and b/printer/dotmatrix24/fonttab.toshiba.p321 differ
diff --git a/printer/dotmatrix24/inserter b/printer/dotmatrix24/inserter
new file mode 100644
index 0000000..442075d
--- /dev/null
+++ b/printer/dotmatrix24/inserter
@@ -0,0 +1,793 @@
+ 
+(*************************************************************************) 
+(*   Installationsprogramm für                Stand   :  3. 1.89         *) 
+(*      24-Nadel Drucker                      Version : 0.9              *) 
+(*                                            Autor   : hjh              *) 
+(*************************************************************************) 
+ 
+PACKET driver inst 24 
+ 
+ 
+       DEFINES treiber einrichten: 
+ 
+ 
+LET up = ""3""13""5"", 
+ 
+    generator name = "printer.24.nadel", 
+ 
+    description file name = "beschreibungen24", 
+    module file name = "module24"; 
+ 
+ 
+INT VAR pr channel, 
+        quality,
+        paper format number,
+        service option; 
+TEXT VAR fonttab name :: "", 
+         driver name :: ""; 
+TEXT VAR inp; 
+BOOL VAR was esc; 
+ 
+treiber einrichten 
+ 
+PROC treiber einrichten:
+
+  treiber einrichten (0)
+END PROC treiber einrichten;
+
+PROC treiber einrichten (INT CONST service opt): 
+ 
+  ask for print channel; 
+  main menu; 
+  IF installed 
+    THEN generate printer spool 
+    ELSE inform about restart 
+  FI. 
+ 
+  ask for printchannel: 
+    inits; 
+    page; 
+    headline ("Druckerkanal - Einstellung"); 
+    cursor (1, 15); 
+    putline ("Hinweis: Die Druckerkanalnummer kann auch nachträglich mit"); 
+    putline ("         'serverchannel (Kanalnummer)' in der Task """ + 
+             name (myself) + """"); 
+    putline ("         verändert werden."); 
+    REP 
+      cursor (1, 10);
+      put (""5"EUMEL-Kanalnummer des Druckerkanals:");
+      get (pr channel);
+      disable stop; 
+      serverchannel (pr channel);
+      BOOL VAR no error :: NOT is error; 
+      clear error; 
+      no error := no error CAND
+                  (pr channel <> channel (myself)) CAND  
+                  (pr channel > 1)                 CAND  
+                  (pr channel < 17); 
+      
+      IF NOT no error
+        THEN cursor (1, 7); 
+             put error;
+             putline ("Eingabe korrigiert wiederholen!") 
+      FI; 
+      enable stop 
+    UNTIL no error PER; 
+    IF exists task ("canal " + text (pr channel)) 
+      THEN end (/ ("canal " + text (pr channel))); 
+    FI; 
+ 
+. inits: 
+    line; 
+    IF single task 
+      THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL") 
+    FI; 
+    command dialogue (TRUE);
+    IF name (myself) <> "PRINTER" 
+      THEN putline ("Diese Task heißt nicht ""PRINTER"", sondern """ + 
+                    name (myself) + """ !"); 
+           IF yes ("Soll die Task in ""PRINTER"" umbenannt werden ?") 
+             THEN rename myself ("PRINTER") 
+           FI 
+    FI; 
+    INT VAR choice;
+    service option := service opt.
+ 
+  single task:  (pcb (9) AND 255) = 1.
+ 
+  main menu: 
+    BOOL VAR installed :: FALSE; 
+    REP 
+      show main menu; 
+      get choice; 
+      treat choice 
+    UNTIL was esc OR installed PER. 
+ 
+  show main menu: 
+    page; 
+    headline("Hauptmenü 24-Nadel-Drucker"); 
+    putline (" 1. Brother");
+    putline (" 2. Epson");
+    putline (" 3. NEC"); 
+    putline (" 4. OKI");
+    putline (" 5. Toshiba").
+
+  get choice: 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Installation abbrechen"); 
+    ask user (5).
+ 
+  treat choice: 
+    SELECT int (inp) OF 
+      CASE 1: brother menu 
+      CASE 2: epson menu 
+      CASE 3: nec menu 
+      CASE 4: oki menu 
+      CASE 5: toshiba menu 
+    END SELECT. 
+ 
+  
+  brother menu: 
+    page;
+    headline ("brother - Menü"); 
+    putline (" 1. M-1724 L"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (1); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           brother m1724l inst
+    FI. 
+  
+    brother m1724l inst: 
+      putline ("brother M-1724 L"); 
+      line; 
+      putline ("Wählen Sie folgende DIP-Schalter Optionen:"); 
+      putline ("Emulationsmodus                IBM Proprinter XL ");
+      putline ("Automatischer Zeilenvorschub       Nein       ");
+      show control options ("paperfeed, std speed, top margin"); 
+      show material options ("slow, fast, draft, nlq"); 
+      show command options ("draft, nlq"); 
+      ask for papersize; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.brother"); 
+             generate ("brotherm1724l"); 
+             adjust papersize; 
+             adjust quality; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+ 
+  toshiba menu:
+    page;
+    headline ("TOSHIBA - Menü"); 
+    putline (" 1. P 321"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (1); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           toshiba p321 inst
+    FI. 
+  
+    toshiba p321 inst: 
+       putline ("TOSHIBA P 321"); 
+       putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+       putline ("S3-8  S3-7  S3-5  übrige Schalter"); 
+       putline ("OFF   OFF   *)    egal           "); 
+       putline ("*) ON: Einzelblatteinzug, OFF: kein Einzug"); 
+       show control options ("std speed, paper feed"); 
+       show material options("slow, fast"); 
+       show command options ("nlq, draft"); 
+       ask for quality; 
+       ask for papersize; 
+       IF all right 
+         THEN get fonttable ("fonttab.toshiba.p321"); 
+              generate ("toshp321"); 
+              adjust papersize; 
+              adjust quality; 
+              do ("papersize(21.0,30.48)"); 
+              installed := TRUE; 
+        FI. 
+ 
+  
+  epson menu: 
+    page; 
+    headline ("Epson - Menü"); 
+    putline (" 1. LQ 850"); 
+    putline (" 2. LQ 1050"); 
+    putline (" 3. LQ 1500"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (3); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           SELECT choice OF 
+             CASE 1 : lq850 inst
+             CASE 2 : lq850 inst
+             CASE 3 : lq1500 inst
+           END SELECT
+    FI. 
+
+    lq850 inst:
+      IF choice = 1 
+         THEN putline ("Epson LQ 850")
+         ELSE putline ("Epson LQ 1050")
+      FI; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8");
+      putline ("egal  egal  egal  egal  egal  egal  *1)    OFF ");
+      putline ("*1) ON: Einzelblatteinzug, OFF: kein Einzug"); line;
+      putline ("SW2-1 SW2-2 SW2-3 SW2-4 SW2-5 SW2-6 SW2-7 SW2-8"); 
+      putline ("egal  egal  *2)                     OFF   OFF");
+      putline ("*2) SW2-2 bis SW2-6 müssen je nach Art der Schnittstelle "); 
+      putline ("    gesetzt werden (Druckerhandbuch)");
+      show control options ("std speed, top margin, std typeface, paperfeed");
+      show material options ("slow, fast, draft, nlq, roman, sansserif"); 
+      show command options ("draft, nlq, roman, sansserif"); 
+      ask for quality; 
+      ask for papersize; 
+      IF all right 
+        THEN get fonttable ("fonttab.epson.lq850"); 
+             generate ("epsonlq850"); 
+             adjust quality; 
+             adjust papersize; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI. 
+ 
+  lq1500 inst:
+      putline ("EPSON LQ-1500");
+      show control options ("");
+      show material options ("draft, nlq"); 
+      show command options ("draft, nlq"); 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.epson.lq1500"); 
+             generate ("epsonlq1500"); 
+             adjust quality; 
+             installed := TRUE 
+      FI. 
+ 
+  nec menu: 
+    page;
+    headline ("NEC - Menü"); 
+    putline (" 1. PINWRITER P5 "); 
+    putline (" 2. PINWRITER P6 "); 
+    putline (" 3. PINWRITER P7 "); 
+    putline (" 4. PINWRITER P6 PLUS"); 
+    putline (" 5. PINWRITER P7 PLUS"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (5); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           SELECT choice OF 
+             CASE 1   : necp5p7 inst
+             CASE 2   : necp6 inst
+             CASE 3   : necp5p7 inst 
+             CASE 4   : necp6plus inst
+             CASE 5   : necp6plus inst
+           END SELECT
+    FI. 
+  
+     necp5p7 inst: 
+      IF choice = 1 
+         THEN putline ("NEC PINWRITER P5") 
+         ELSE putline ("NEC PINWRITER P7") 
+      FI; 
+      show control options ("paper feed"); 
+      show material options ("draft, nlq"); 
+      show command options ("draft, nlq"); 
+      ask for quality; 
+      ask for papersize; 
+      IF all right 
+        THEN get fonttable ("fonttab.nec.p5.new"); 
+             generate ("necp5p7"); 
+             adjust papersize; 
+             adjust quality; 
+             installed := TRUE 
+      FI. 
+ 
+     necp6 inst: 
+      putline ("NEC PINWRITER P6 "); 
+      show control options ("paper feed"); 
+      show material options ("draft, nlq"); 
+      show command options ("draft, nlq"); 
+      ask for quality; 
+      ask for papersize; 
+      IF all right 
+        THEN get fonttable ("fonttab.nec.p5.new"); 
+             generate ("necp6"); 
+             adjust papersize; 
+             adjust quality; 
+             installed := TRUE 
+      FI. 
+ 
+     necp6plus inst: 
+      IF choice = 4 
+         THEN putline ("NEC PINWRITER P6 PLUS") 
+         ELSE putline ("NEC PINWRITER P7 PLUS") 
+      FI; 
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:"); 
+      putline ("CR FUNCTION             CR ONLY ");
+      show control options ("std speed, top margin, std typeface, paperfeed");
+      show material options ("slow, fast, draft, nlq, courier, souvenir"); 
+      show command options ("draft, nlq, courier, souvenir"); 
+      ask for papersize; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.nec.p6+"); 
+             generate ("necp6+"); 
+             adjust papersize; 
+             adjust quality; 
+             installed := TRUE;
+             IF choice = 5 THEN do ("papersize (34.544, 30.48)") FI; 
+      FI. 
+ 
+  oki menu: 
+    page; 
+    headline ("OKI - Menü"); 
+    putline (" 1. MICROLINE 390 IBM-/EPSON-kompatibel"); 
+    putline (" 2. MICROLINE 391 IBM-/EPSON-kompatibel"); 
+    putline (" 3. MICROLINE 393/393C EPSON-kompatibel");                   
+    putline (" 4. MICROLINE 393/393C IBM-kompatibel");                     
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (4); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           SELECT choice OF 
+             CASE 1   : oki ml390 inst                                 
+             CASE 2   : oki ml390 inst                                 
+             CASE 3   : oki ml393eps inst 
+             CASE 4   : oki ml393ibm inst 
+           END SELECT
+    FI. 
+ 
+    oki ml390 inst:
+      IF choice = 1
+        THEN putline ("OKI Microline 390") ;
+        ELSE putline ("OKI Microline 391") ;
+      FI;
+      line; 
+      putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:"); 
+      putline ("EMULATION MODE           EPSON LQ ");
+      putline ("AUTO LF                  NO       ");
+      show control options ("paperfeed, std speed, top margin"); 
+      show material options ("slow, fast, draft, nlq"); 
+      show command options ("draft, nlq, courier, kassette"); 
+      ask for papersize; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.oki"); 
+             generate ("oki390/391"); 
+             adjust papersize; 
+             adjust quality; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+ 
+    oki ml393eps inst:
+      putline ("OKI Microline 393 EPSON-kompatibel");
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:"); 
+      putline ("AUTO LF                  NO    ");
+      show control options ("paperfeed, std speed, top margin, std typeface"); 
+      show material options ("slow, fast, draft, nlq"); 
+      show command options ("draft, nlq, courier, kassette, schwarz, rot, blau, violett, gelb, orange, grün"); 
+      ask for papersize; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.oki"); 
+             generate ("oki393/393Ceps"); 
+             adjust papersize; 
+             adjust quality;
+             installed := TRUE 
+      FI.
+ 
+    oki ml393ibm inst:
+      putline ("OKI Microline 393 IBM-kompatibel");
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:"); 
+      putline ("EMULATION MODE           ASCII ");
+      putline ("AUTO LF                  NO    ");
+      show control options ("paperfeed, std speed, top margin, std typeface"); 
+      show material options ("slow, fast, draft, nlq"); 
+      show command options ("draft, nlq, courier, kassette, schwarz, rot, blau, violett, gelb, orange, grün"); 
+      ask for papersize; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.oki");
+             generate ("oki393/393Cibm"); 
+             adjust papersize; 
+             adjust quality;
+             installed := TRUE 
+      FI.
+ 
+ 
+ 
+generate printer spool: 
+   IF service opt = 0 
+      THEN forget (generator name, quiet); 
+           forget (driver name, quiet) 
+    FI;
+    eumel must advertise;
+    cursor (1, 10);
+(*  putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+    putline ("die Fonttabelle mit dem Kommando");
+    line;
+    putline ("      font table (""" + font tab name + """)");
+    line;
+    putline ("eingestellt werden!!!");
+    line (2);
+    putline ("Hinweis: Dieses Installationsprogramm kann in der Task """ + name (myself) + """"); 
+    putline ("         mit 'treiber einrichten' aufgerufen werden, wenn ein anderer"); 
+    putline ("         Drucker eingesetzt werden soll."); 
+    line (2); 
+*) 
+(*  put ("Generierung beendet, weiter mit 'SV'");
+    break (quiet);
+*) 
+    putline ("  Generierung beendet."); 
+    putline ("  Weiter: Bitte Taste drücken"); 
+    WHILE incharety <> "" REP ENDREP; 
+    REP UNTIL incharety <> "" ENDREP; 
+    break; 
+    do ("spool manager (PROC printer)").
+ 
+  inform about restart: 
+    page; 
+    putline ("Es ist kein Druckertreiber installiert worden!"); 
+    line; 
+    putline ("Dieses Installationsprogramm kann in der Task """ + name (myself) + """"); 
+    putline ("mit 'treiber einrichten' erneut aufgerufen werden."); 
+    line; 
+    pause(50); 
+    break. 
+ 
+END PROC treiber einrichten; 
+ 
+PROC headline (TEXT CONST header): 
+ 
+  cursor (13,1); 
+  putline ("E U M E L - Druckertreiber - Installations - Programm"); 
+  cursor (40 - LENGTH header DIV 2, 2); 
+  put (header); 
+  line (2) 
+END PROC headline; 
+ 
+PROC ask user (INT CONST max choice): 
+ 
+  TEXT VAR exit; 
+  inp := "";
+  REP 
+    cursor (1,23); 
+    IF inp = "" 
+      THEN put ("Ihre Wahl (Nummer eingeben):")  
+      ELSE put ("FEHLER! Eingabe korrigieren:")
+    FI; 
+    editget (inp, ""27"", "", exit); 
+    was esc :=  exit = ""27"";
+  UNTIL was esc OR ok PER. 
+ 
+  ok: 
+    int (inp) > 0 AND int (inp) <= max choice AND last conversion ok. 
+END PROC ask user;
+
+PROC show control options (TEXT CONST options): 
+ 
+  line; 
+  putline ("Steuerprozeduren in der Task """ + name (myself) + """:"); 
+  write ("papersize, std quality");
+  IF options <> "" 
+    THEN put (","); 
+         putline (options) 
+  FI
+END PROC show control options; 
+
+PROC show material options (TEXT CONST options): 
+ 
+  line; 
+  putline ("Mögliche Materialwerte (#material(""..."")#):"); 
+  putline (options) 
+END PROC show material options; 
+ 
+PROC show command options (TEXT CONST options): 
+ 
+  line; 
+  putline ("Mögliche direkte Druckeranweisungen (#""...""#):"); 
+  putline (options) 
+END PROC show command options; 
+ 
+PROC ask for quality: 
+ 
+  line (1); 
+  putline ("Standard - Druckqualität:"); 
+  line; 
+  REP out (up); 
+    IF yes ("Draft Quality (schneller, aber nicht so schön)") 
+      THEN quality := 1; LEAVE ask for quality 
+    FI;
+    out (up);
+    IF yes ("Near Letter Quality (schöner, aber langsamer)")
+      THEN quality := 2; LEAVE ask for quality 
+    FI;
+  PER 
+END PROC ask for quality; 
+ 
+PROC adjust quality: 
+ 
+  IF quality = 1 
+    THEN do ("std quality (""draft"")") 
+    ELSE do ("std quality (""nlq"")") 
+  FI 
+END PROC adjust quality; 
+ 
+PROC ask for papersize : 
+LET up           = ""3""13""5"";
+ 
+  paper format number := paper format ; 
+ 
+    . paper format :
+        line (1); 
+        putline ("Papierformat:"); 
+        line;
+        REP out (up);
+            IF yes ("Endlospapier, 8 Zoll breit")
+               THEN LEAVE paper format WITH 1 FI;
+            out (up);
+            IF yes ("Endlospapier, 13.2 Zoll breit")
+               THEN LEAVE paper format WITH 2 FI;
+            out (up);
+            IF yes ("Einzelblatteinzug, DINA 4")
+               THEN LEAVE paper format WITH 3 FI;
+        PER;
+        0
+END PROC ask for papersize;
+ 
+ 
+PROC adjust papersize: 
+ 
+    SELECT paper format number OF 
+      CASE 1 : do("papersize ( 8.0 * 2.54, 12.0 * 2.54)");
+               do ("paper feed (""tractor"")") 
+      CASE 2 : do("papersize (13.2 * 2.54, 12.0 * 2.54)");
+               do ("paper feed (""tractor"")") 
+      CASE 3 : do("papersize (21.0, 29.7)");
+               do ("paper feed (""sheet"")") 
+    END SELECT
+ 
+END PROC adjust papersize; 
+ 
+BOOL PROC all right: 
+ 
+  line (3);
+  cursor (1,23); 
+  yes ("Soll der ausgewählte Druckertreiber installiert werden") 
+END PROC all right; 
+ 
+PROC get fonttable (TEXT CONST name): 
+ 
+  fonttab name := name; 
+  from archive ((description file name & module file name & fonttab name) 
+                                                                    - all); 
+  fonttable (fonttab name); 
+  command dialogue (FALSE); 
+  save (fonttab name, /"configurator"); 
+  IF service option = 0 
+    THEN forget (fonttab name) 
+  FI; 
+  command dialogue (TRUE); 
+END PROC get fonttable; 
+ 
+PROC from archive (THESAURUS CONST files):
+ 
+  IF highest entry (files) > 0 
+    THEN fetch from archive; 
+         release (archive);
+         putline ("Archiv abgemeldet !")
+  FI.
+ 
+  fetch from archive: 
+    THESAURUS VAR thes :: files; 
+    REP 
+      ask for archive;
+      reserve archive;
+      fetch (thes / ALL archive, archive);
+      thes := thes - all 
+    UNTIL highest entry (thes) = 0 PER.
+
+ask for archive:
+  TEXT VAR buffer;
+(*line;
+  putline ("Bitte Archiv mit den Dateien"); 
+  INT VAR index :: 0; 
+  REP 
+    get (thes, buffer, index); 
+    putline ("    " + buffer) 
+  UNTIL index = 0 PER; 
+  putline ("einlegen !"); 
+  line; 
+  putline ("Wenn eingelegt: Taste drücken !"); 
+  inchar (buffer)*). 
+ 
+reserve archive :
+  INT VAR p1, p2;
+  archive (" "31" ");
+  disable stop;
+  list (archive);
+  IF is error
+     THEN buffer := errormessage;
+          p1 := pos (buffer, """", 1 ) + 1;
+          p2 := pos (buffer, """", p1) - 1;
+          IF p1 > 0 AND p2 > 0
+             THEN clear error;
+                  buffer := subtext (buffer, p1, p2);
+                  archive (buffer);
+          FI;
+  FI;
+  enable stop.
+
+END PROC from archive;
+
+THESAURUS OP & (TEXT CONST left, right):
+  THESAURUS VAR result := empty thesaurus;
+  insert (result, left);
+  insert (result, right);
+  result
+END OP &;
+
+THESAURUS OP & (THESAURUS CONST left, TEXT CONST right):
+  THESAURUS VAR result := left;
+  insert (result, right);
+  result
+END OP &;
+ 
+PROC generate (TEXT CONST name): 
+ 
+  open files; 
+  read description; 
+  build programme; 
+  insert programme; 
+  forget files. 
+ 
+  open files: 
+    line (5); 
+    cursor (1, 20); 
+    putline (""4"Bitte warten !"); 
+    putline ("    - Der Treiber wird generiert."); 
+    driver name := "printer." + name + "(generiert)"; 
+    IF exists (driver name) 
+      THEN forget (driver name, quiet) 
+    FI; 
+    FILE VAR des file :: sequential file (modify, description file name), 
+             mod file :: sequential file (modify, module file name), 
+             driver file :: sequential file (output, driver name). 
+ 
+  read description: 
+    to line (des file, 1); 
+    col (des file, 1);
+    downety (des file, "$" + name + "$"); 
+    IF eof (des file) 
+      THEN errorstop ("Beschreibung von """ + name + """ nicht im"13""10"" + 
+                      "Descriptions-File enthalten")
+    FI; 
+    TEXT VAR description :: "", 
+             record; 
+    BOOL VAR done :: FALSE; 
+    read record (des file, record); 
+    record := subtext (record, col (des file) + LENGTH name + 2);
+    WHILE NOT eof (des file) AND NOT done REP 
+      treat record
+    PER. 
+ 
+  treat record: 
+    INT VAR dollar pos :: pos (record, "$"); 
+    IF dollar pos = 0
+      THEN description CAT compress (record); 
+           down (des file); 
+           read record (des file, record)  
+      ELSE description CAT compress (subtext (record, 1, dollar pos - 1));
+           col (des file, dollar pos); 
+           done := TRUE; 
+    FI. 
+ 
+  build programme: 
+    get module name; 
+    WHILE still modules REP 
+      find module; 
+      transfer module; 
+      get module name 
+    PER. 
+ 
+  get module name: 
+    INT VAR semicol pos :: pos (description, ";"); 
+    TEXT VAR module name; 
+    IF semicol pos > 0 
+      THEN module name := subtext (description, 1, semicol pos - 1); 
+           description := subtext (description, semicol pos + 1) 
+      ELSE module name := description; 
+           description := "" 
+    FI.
+ 
+  still modules: 
+    module name <> "" OR description <> "". 
+ 
+  find module: 
+    to line (mod file, 1); 
+    col (mod file, 1); 
+    downety (mod file, "$" + module name + "$"); 
+    IF eof (mod file) 
+      THEN errorstop ("Modul """ + module name + """ nicht im"13""10"" + 
+                      "Modul-File enthalten")
+    FI. 
+ 
+  transfer module: 
+    done := FALSE; 
+    read record (mod file, record); 
+    record := subtext (record, col (mod file) + LENGTH module name + 2);
+    WHILE NOT eof (mod file) AND NOT done REP 
+      transfer record
+    PER. 
+ 
+  transfer record: 
+    dollar pos := pos (record, "$"); 
+    IF dollar pos = 0
+      THEN write (driver file, compress (record)); 
+           line (driver file);
+           down (mod file); 
+           read record (mod file, record)  
+      ELSE write (driver file, compress (subtext (record, 1, 
+                                            dollar pos - 1)));
+           col (mod file, dollar pos); 
+           done := TRUE; 
+           cout (line no (mod file)) 
+    FI. 
+ 
+  insert programme: 
+    IF online 
+      THEN putline ("    - Der Treiber wird insertiert.") 
+    FI;
+    check off; 
+    insert (driver name). 
+ 
+  forget files: 
+    IF service option = 0 
+      THEN forget (description file name, quiet); 
+           forget (module file name, quiet)
+    FI  .
+END PROC generate; 
+ 
+END PACKET driver inst 24
+
diff --git a/printer/dotmatrix24/module24 b/printer/dotmatrix24/module24
new file mode 100644
index 0000000..a4957c2
--- /dev/null
+++ b/printer/dotmatrix24/module24
@@ -0,0 +1,1554 @@
+
+(*************************************************************************) 
+(*                                            Stand   : 03. 1.89         *) 
+(*   Module-Datei für 24-Nadel-Drucker        Version : 0.9              *) 
+(*                                            Autor   : hjh              *) 
+(*************************************************************************) 
+ 
+$begin$ 
+PACKET printer driver 
+ 
+       DEFINES printer,
+               open,
+               close,
+               execute,
+               paper size,
+               std quality,
+
+$headnecp6$    paper feed:
+(* Treiber fuer NEC P6, automatisch generiert *)
+LET underline linetype = 1; 
+INT VAR factor 1, factor 2, draft factor 1, draft factor 2;
+
+$headnecp5p7$  paper feed:
+(* Treiber fuer NEC P5, P7 , automatisch generiert *)
+LET underline linetype = 1; 
+INT VAR factor 1, factor 2, draft factor 1, draft factor 2;
+
+$headnecp6+$   std speed, 
+               top margin, 
+               paper feed, 
+               std typeface:
+(* Treiber für NEC P6 plus/P7 plus ,automatisch generiert *) 
+ 
+
+$headlq850$    std speed, 
+               top margin, 
+               paper feed, 
+               std typeface:
+(* Treiber für EPSON LQ-850/1050 ,automatisch generiert *) 
+ 
+$headbrotherm1724l$ 
+               std speed, 
+               top margin, 
+               paper feed: 
+INT VAR vertical factor := 1; 
+(* Treiber für BROTHER M-1724L in IBM-Emulation, automatisch generiert *) 
+ 
+$headoki390/391$ 
+               std speed, 
+               top margin, 
+               paper feed, 
+               std typeface:
+INT VAR vertical factor := 1; 
+(* Treiber für OKI MIKROLINE 390/391  ,automatisch generiert *) 
+ 
+$headoki393/393Ceps$ 
+               std speed, 
+               top margin, 
+               paper feed, 
+               std typeface:
+INT VAR vertical factor := 1; 
+(* Treiber für OKI MIKROLINE 393/393C EPSON-kompatibel, automatisch generiert *) 
+ 
+$headoki393/393Cibm$ 
+               std speed, 
+               top margin, 
+               paper feed, 
+               std typeface:
+INT VAR vertical factor := 1; 
+(* Treiber für OKI MIKROLINE 393/393C IBM-kompatibel, automatisch generiert *) 
+ 
+$headtoshp321$   std speed, 
+                 paper feed: 
+(* Treiber für TOSHIBA P321, automatisch generiert *) 
+ 
+$headstarnb24$ 
+               std speed, 
+               top margin, 
+               paper feed, 
+               std typeface:
+(* Treiber für STAR NB 24-10/15 in Standard Betriebsart automatisch generiert *) 
+ 
+$declarations$
+INT VAR font nr, font bits, modification bits, 
+        blankbreite, x rest, high, low, steps;
+REAL VAR x size, y size;
+TEXT VAR buffer :: "";
+BOOL VAR is nlq ;
+TEXT VAR font text :: "";
+TEXT VAR std quality name :: "draft";
+ 
+. is pica  : font bits = 0
+. is elite : font bits = 1
+.;
+
+ 
+PROC paper size (REAL CONST x, y) :
+ 
+  x size := x;
+  y size := y;
+END PROC paper size;
+ 
+papersize (20.32, 30.48); 
+ 
+PROC paper size : 
+ 
+  line;
+  putline ("Papierbreite  =  " + text (x size, 5, 2) + " cm  =  " + text (x size / 2.54, 5, 2) + " Zoll");
+  putline ("Papierlaenge  =  " + text (y size, 5, 2) + " cm  =  " + text (y size / 2.54, 5, 2) + " Zoll");
+END PROC paper size;
+ 
+ 
+ 
+PROC std quality (TEXT CONST quality) :
+ 
+  IF quality = "nlq" OR quality = "draft"
+     THEN std quality name := quality
+     ELSE errorstop ("unzulässige Qualitätsbezeichnung")
+  FI
+END PROC std quality;
+ 
+TEXT PROC std quality : 
+ 
+  std quality name 
+END PROC std quality;
+                        
+ 
+$topmargin$ 
+REAL VAR  y margin := 0.0 ;
+ 
+PROC top margin (REAL CONST margin): 
+ 
+  y margin := margin 
+END PROC top margin; 
+ 
+REAL PROC top margin: 
+ 
+  y margin 
+END PROC top margin;
+ 
+ 
+$speed$
+BOOL VAR is slow :: TRUE; 
+TEXT VAR std speed name :: "slow";
+ 
+PROC std speed (TEXT CONST speed) :
+ 
+  IF speed = "fast" OR speed = "slow"
+     THEN std speed name := speed
+     ELSE errorstop ("unzulässige Geschwindigkeit")
+  FI
+END PROC std speed;
+ 
+TEXT PROC std speed : 
+ 
+std speed name 
+END PROC std speed;
+ 
+ 
+$typefacelq850$ 
+TEXT VAR act typeface name :: "";
+TEXT VAR std typeface name :: "";
+ 
+. is roman: 
+  act typeface name = "roman". 
+. is sansserif: 
+  act typeface name = "sansserif"
+.; 
+ 
+PROC std typeface (TEXT CONST typeface) :
+ 
+  IF typeface = "" OR typeface = "roman" OR typeface = "sansserif"
+     THEN std typeface name := typeface
+     ELSE errorstop ("unzulässige Schriftart")
+  FI
+END PROC std typeface;
+ 
+TEXT PROC std typeface : 
+ 
+  std typeface name 
+END PROC std typeface;
+ 
+ 
+ 
+$typefacep6+$ 
+BOOL VAR is courier :: TRUE; 
+TEXT VAR std typeface name :: "courier";
+ 
+PROC std typeface (TEXT CONST typeface) :
+ 
+  IF typeface = "courier" OR typeface = "souvenir" 
+     THEN std typeface name := typeface
+     ELSE errorstop ("unzulässige Schriftart")
+  FI
+END PROC std typeface;
+ 
+TEXT PROC std typeface : 
+ 
+  std typeface name 
+END PROC std typeface;
+ 
+$typefaceoki$ 
+BOOL VAR is courier ; 
+TEXT VAR std typeface name :: "";
+ 
+PROC std typeface (TEXT CONST typeface) :
+ 
+  IF typeface = "" OR typeface = "courier" OR typeface = "kassette" 
+     THEN std typeface name := typeface
+     ELSE errorstop ("unzulässige Schriftart")
+  FI
+END PROC std typeface;
+ 
+TEXT PROC std typeface : 
+ 
+  std typeface name 
+END PROC std typeface;
+ 
+$typefacestar$ 
+BOOL VAR is roman ; 
+TEXT VAR std typeface name :: "";
+ 
+PROC std typeface (TEXT CONST typeface) :
+ 
+  IF typeface = "" OR typeface = "roman" OR typeface = "font1" 
+     THEN std typeface name := typeface
+     ELSE errorstop ("unzulässige Schriftart")
+  FI
+END PROC std typeface;
+ 
+TEXT PROC std typeface : 
+ 
+  std typeface name 
+END PROC std typeface;
+ 
+$feed$ 
+BOOL VAR is sheet feed :: FALSE;
+ 
+PROC paper feed (TEXT CONST feeder) :
+ 
+  IF feeder = "sheet"
+    THEN is sheet feed := TRUE 
+  ELIF feeder = "tractor" 
+    THEN is sheet feed := FALSE 
+    ELSE errorstop ("unzulässige Einzugsart")
+  FI
+END PROC paper feed;
+ 
+TEXT PROC paper feed: 
+  IF is sheet feed
+    THEN "sheet" 
+    ELSE "tractor" 
+  FI 
+END PROC paper feed;
+ 
+$feedschacht$
+BOOL VAR is sheet feed :: FALSE;
+TEXT VAR feeder name :: "tractor";
+ 
+PROC paper feed (TEXT CONST feeder) :
+ 
+  IF feeder = "tractor" 
+     THEN feeder name := "tractor"; 
+          is sheet feed := FALSE
+  ELIF feeder = "sheet" OR feeder = "schacht1" 
+     THEN feeder name := "schacht1" ; 
+          is sheet feed := TRUE
+  ELIF feeder = "schacht2" 
+     THEN feeder name := "schacht2" ; 
+          is sheet feed := TRUE 
+     ELSE errorstop ("unzulässige Einzugsart")
+  FI
+END PROC paper feed;
+ 
+TEXT PROC paper feed: feeder name END PROC paper feed;
+ 
+$open$
+PROC open (INT CONST op code, INT VAR param1, param2):
+ 
+  SELECT op code OF
+    CASE 1: open document(param1,param2)
+    CASE 2: open page    (param1,param2)
+  END SELECT. 
+END PROC open ; 
+ 
+ 
+$opendoch$
+PROC open document (INT VAR x steps,y steps): 
+    modification bits := 0; 
+    x steps := x step conversion ( x size );
+    y steps := y step conversion ( y size );
+    y steps := (y steps DIV 30) * 30;
+ 
+$opendochtosh$
+PROC open document (INT VAR x steps,y steps): 
+    modification bits := 0; 
+    x steps := x step conversion ( x size );
+    y steps := y step conversion ( y size );
+    y steps := (y steps DIV 36) * 36;
+ 
+$initspeed$ 
+    IF pos (material, "slow") <> 0 
+         THEN is slow := TRUE;
+    ELIF pos (material, "fast") <> 0 
+         THEN is slow := FALSE;
+         ELSE is slow := std speed name = "slow"
+    FI;
+ 
+$opendocp6+$ 
+    out (""24""27""64"");                  (* Reset des Druckers *) 
+    out (""27"t"1""27"6"27"R"0"");         (* Zeichentabelle 4 (Grafik) *) 
+    out (""27"O"); 
+    out (""27"2" + ""27"C" + code (y steps DIV 30));   (* Formularlaenge   *) 
+    out (""27"x"0"");                                  (* Entwurfsqualität *) 
+    IF is sheet feed
+       THEN out (""27""25"4");             (* Sheetmode ein             *)
+    FI;
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+    IF pos (material, "courier") <> 0 
+      THEN is courier := TRUE ; 
+    ELIF pos (material, "souvenir") <> 0 
+      THEN is courier := FALSE ; 
+      ELSE is courier := std typeface name = "courier" 
+    FI; 
+END PROC open document ;
+ 
+$opendocp5p7$ 
+    out (""24""27""64"");                  (* Reset des Druckers         *)
+    out (""27"R"0"");                      (* Amerikanischer Zeichensatz *)
+    out (""27"C" + code (y steps DIV 30)); (* Formularlaenge             *)
+    out (""27"x"0"");                      (* Entwurfsqualität           *) 
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+    IF is sheet feed
+       THEN out (""27""25"4");             (* Sheetmode ein             *)
+            center paper ;
+    FI;
+ 
+    . center paper :
+        INT CONST x steps in chars := x steps DIV x step conversion (2.54 / 10.0),
+                  left margin      := (136 - x steps in chars) DIV 2;
+        out (""27"P");
+        out (""27"l"); out (code (left margin + 1));
+END PROC open document ;
+
+$opendocp6$ 
+    out (""24""27""64"");                  (* Reset des Druckers         *)
+    out (""27"R"0"");                      (* Amerikanischer Zeichensatz *)
+    out (""27"C" + code (y steps DIV 30)); (* Formularlaenge             *)
+    out (""27"x"0"");                      (* Entwurfsqualität           *) 
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+    IF is sheet feed
+       THEN out (""27""25"4");             (* Sheetmode ein              *)
+    FI;
+END PROC open document ;
+
+$opendoclq850$ 
+    out (""24""27""64"");                  (* Reset des Druckers *) 
+    out (""27"t"1""27"6"27"R"0"");         (* Zeichentabelle 4 (Grafik) *) 
+    out (""27"O"); 
+    out (""27"2" + ""27"C" + code (y steps DIV 30));   (* Formularlaenge   *) 
+    out (""27"x"0"");                                  (* Entwurfsqualität *) 
+    IF is sheet feed
+         THEN out (""27""25"4");                       (* Sheetmode ein    *)
+    FI;
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+    IF pos (material, "roman") <> 0 
+      THEN act typeface name := "roman" 
+    ELIF pos (material, "sansserif") <> 0 
+      THEN act typeface name := "sansserif" 
+      ELSE act typeface name := std typeface name  
+    FI; 
+END PROC open document ; 
+ 
+$opendocokieps$ 
+    out (""24""27""64"");                  (* Reset des Druckers *) 
+    out (""27"t"1""27"6"27"R"0"");         (* Zeichentabelle 4 (Grafik) *) 
+    out (""27"O"); 
+    out (""27"2" + ""27"C" + code (y steps DIV 30));   (* Formularlaenge   *) 
+    out (""27"x"0"");                                  (* Entwurfsqualität *) 
+    IF is sheet feed
+         THEN IF feeder name = "schacht2"
+                 THEN out (""27""25"2")  
+                 ELSE out (""27""25"1")
+              FI 
+    FI;                                                (* Sheetmode ein    *) 
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+    IF pos (material, "courier") <> 0 
+      THEN is courier := TRUE ; 
+    ELIF pos (material, "kassette") <> 0 
+      THEN is courier := FALSE ; 
+      ELSE is courier := std typeface name = "courier" 
+    FI; 
+END PROC open document ; 
+ 
+$opendoctosh$ 
+    out (""24""27"5"0""27"4"27"O");             (* Reset des Druckers *) 
+    out (""27"6");                              (* Zeichensatz *) 
+    out (""27"A"12""27"2") ;
+    out (""27"C" + code (y steps DIV 36));      (* Formularlaenge   *) 
+    out (""27"x"0"");                                  (* Entwurfsqualität *) 
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+END PROC open document ; 
+ 
+$opendocbrother$ 
+    out (""24""27"5"0""27"4"27"O");             (* Reset des Druckers *) 
+    out (""27"6" + ""27"R"0"");                (* Zeichensatz II ascii *) 
+    out (""27"A"10""27"2") ;                    (* Zeilenabstand *)
+    out (""27"C" + code (y steps DIV 36));      (* Formularlaenge   *) 
+    IF is sheet feed
+       THEN out (""27""25"4")  
+    FI;                                                (* Sheetmode ein    *) 
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+END PROC open document ; 
+ 
+$opendocokiibm$ 
+    out (""24""27"5"0""27"4"27"O");             (* Reset des Druckers *) 
+    out (""27"6" + ""27"!"64"");                (* Zeichensatz II ascii *) 
+    out (""27""91""92""4""0""0""0""180"");      (* 1/180 *)
+    out (""27"A"12""27"2") ;                    (* Zeilenabstand *)
+    out (""27"C" + code (y steps DIV 36));      (* Formularlaenge   *) 
+    IF is sheet feed
+         THEN IF feeder name = "schacht2"
+                 THEN out (""27""25"2")  
+                 ELSE out (""27""25"1")
+              FI 
+    FI;                                                (* Sheetmode ein    *) 
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+    IF pos (material, "courier") <> 0 
+      THEN is courier := TRUE ; 
+    ELIF pos (material, "kassette") <> 0 
+      THEN is courier := FALSE ; 
+      ELSE is courier := std typeface name = "courier" 
+    FI; 
+END PROC open document ; 
+ 
+$opendocstar$ 
+    out (""24""27""64"");                  (* Reset des Druckers *) 
+    out (""27"R"0"");                  (* amerikanischer Zeichensatz *) 
+    out (""27"O"); 
+    out (""27"2" + ""27"C" + code (y steps DIV 30));   (* Formularlaenge   *) 
+    out (""27"x"0"");                                  (* Entwurfsqualität *) 
+    IF is sheet feed
+         THEN IF feeder name = "schacht2"
+                 THEN out (""27""25"2")  
+                 ELSE out (""27""25"1")
+              FI 
+    FI;                                                (* Sheetmode ein    *) 
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+    IF pos (material, "roman") <> 0 
+      THEN is roman := TRUE ; 
+    ELIF pos (material, "font1") <> 0 
+      THEN is roman := FALSE ; 
+      ELSE is roman := std typeface name = "roman" 
+    FI; 
+END PROC open document ; 
+ 
+$openpagetosh$ 
+PROC open page (INT VAR x start , y start): 
+ 
+    x start := 0;
+    IF is sheet feed
+       THEN y start := y step conversion (2.54)    (* 1 Inch *)
+       ELSE y start := 0;
+    FI;
+    x rest  := 0;
+    out (""13"");
+END PROC open page; 
+ 
+$openpage$ 
+PROC open page (INT VAR x start , y start): 
+ 
+    x start := 0 ; 
+    y start := y step conversion (y margin) ; 
+    x rest := 0; 
+    out (""13""). 
+END PROC open page; 
+ 
+$openpagep5-7$ 
+PROC open page (INT VAR x start , y start): 
+ 
+    x start := 0;
+    IF is sheet feed
+       THEN y start := y step conversion (8.466667e-1)    (* 2/6 Inch *)
+       ELSE y start := 0;
+    FI;
+    x rest  := 0;
+    out (""13"");
+END PROC open page; 
+ 
+$close$
+ 
+PROC close (INT CONST op code, INT CONST param1) :
+ 
+  SELECT op code OF
+    CASE 1: close document 
+    CASE 2: close page (param1)
+  END SELECT.
+ 
+close document : 
+. 
+END PROC close ; 
+ 
+$closepage$ 
+PROC close page (INT CONST remaining y steps) : 
+    IF remaining y steps > 0
+       THEN out (""12"")
+    ELIF is sheet feed
+       THEN out (""27""25"R")
+    FI;
+END PROC close page;
+
+$closepagetosh$ 
+PROC close page (INT CONST remaining y steps) : 
+    IF   is sheet feed
+         THEN out (""12"")
+    ELIF remaining y steps > 0
+         THEN out (""12"")
+    FI;
+END PROC close page;
+
+$execute$
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+ 
+SELECT op code OF
+  CASE 1:  write text
+  CASE 2:  write cmd
+  CASE 3:  carriage return
+  CASE 4:  move
+  CASE 5:  draw
+  CASE 6:  on
+  CASE 7:  off
+  CASE 8:  type
+END SELECT.
+
+from : param1. 
+to   : param2. 
+ 
+  write text :
+    out subtext (string, from, to).
+ 
+$cmdp6+$ 
+  write cmd :
+    buffer := subtext (string, from, to); 
+    IF   buffer = "nlq"
+      THEN IF NOT is nlq THEN is nlq := TRUE; switch to nlq FI;
+    ELIF buffer = "draft"
+      THEN IF is nlq THEN is nlq := FALSE; switch to draft FI;
+    ELIF   buffer = "courier"
+      THEN IF NOT is courier THEN is courier := TRUE; switch to courier FI;
+    ELIF buffer = "souvenir"
+      THEN IF is courier THEN is courier := FALSE; switch to souvenir FI;
+    ELIF buffer = "schwarz" 
+      THEN out (""27"r0")
+    ELIF buffer = "rot" 
+      THEN out (""27"r1")
+    ELIF buffer = "blau" 
+      THEN out (""27"r2")
+    ELIF buffer = "violett" 
+      THEN out (""27"r3")
+    ELIF buffer = "gelb" 
+      THEN out (""27"r4")
+    ELIF buffer = "orange" 
+      THEN out (""27"r5")
+    ELIF buffer = "grün" 
+      THEN out (""27"r6")
+      ELSE out (buffer) 
+    FI. 
+ 
+$cmdp5-7$ 
+  write cmd :
+    buffer := subtext (string, from, to);
+    IF   buffer = "nlq"
+         THEN IF NOT is nlq THEN switch to nlq FI;
+              is nlq := TRUE;
+    ELIF buffer = "draft"
+         THEN IF     is nlq THEN switch to draft FI;
+              is nlq := FALSE;
+         ELSE out (buffer);
+    FI;.
+ 
+$cmdlq850$ 
+  write cmd :
+    buffer := subtext (string, from, to); 
+    IF   buffer = "nlq"
+      THEN IF NOT is nlq THEN is nlq := TRUE; switch to nlq FI;
+    ELIF buffer = "draft"
+      THEN IF is nlq THEN is nlq := FALSE; switch to draft FI;
+    ELIF   buffer = "roman"
+      THEN IF NOT is roman THEN act typeface name := "roman" ; 
+                                switch to roman FI;
+    ELIF buffer = "sansserif"
+      THEN IF NOT is sansserif THEN act typeface name := "sansserif"; 
+                                    switch to sansserif FI;
+      ELSE out (buffer) 
+    FI. 
+ 
+$cmdoki$ 
+  write cmd :
+    buffer := subtext (string, from, to); 
+    IF   buffer = "nlq"
+      THEN IF NOT is nlq THEN is nlq := TRUE; switch to nlq FI;
+    ELIF buffer = "draft"
+      THEN IF is nlq THEN is nlq := FALSE; switch to draft FI;
+    ELIF   buffer = "courier"
+      THEN IF NOT is courier THEN is courier := TRUE; switch to courier FI;
+    ELIF buffer = "kassette"
+      THEN IF is courier THEN is courier := FALSE; switch to kassette FI;
+    ELIF buffer = "schwarz" 
+      THEN out (""27"r0")
+    ELIF buffer = "rot" 
+      THEN out (""27"r1")
+    ELIF buffer = "blau" 
+      THEN out (""27"r2")
+    ELIF buffer = "violett" 
+      THEN out (""27"r3")
+    ELIF buffer = "gelb" 
+      THEN out (""27"r4")
+    ELIF buffer = "orange" 
+      THEN out (""27"r5")
+    ELIF buffer = "grün" 
+      THEN out (""27"r6")
+      ELSE out (buffer) 
+    FI. 
+ 
+$cmdtosh$ 
+  write cmd :
+    buffer := subtext (string, from, to);
+    IF   buffer = "nlq"
+      THEN IF NOT is nlq THEN is nlq := TRUE; switch to nlq FI;
+    ELIF buffer = "draft"
+      THEN IF is nlq THEN is nlq := FALSE;  switch to draft FI;
+      ELSE out (buffer);
+    FI;.
+ 
+$cmdstar$ 
+  write cmd :
+    buffer := subtext (string, from, to); 
+    IF   buffer = "nlq"
+      THEN IF NOT is nlq THEN is nlq := TRUE; switch to nlq FI;
+    ELIF buffer = "draft"
+      THEN IF is nlq THEN is nlq := FALSE; switch to draft FI;
+    ELIF   buffer = "roman"
+      THEN IF NOT is roman THEN is roman := TRUE; switch to roman FI;
+    ELIF buffer = "font1"
+      THEN IF is roman THEN is roman := FALSE; switch to font1 FI;
+    FI. 
+ 
+$crs$
+  carriage return :
+    x rest := 0;
+    out (""13"").
+ 
+$move$ 
+x steps : param1.
+y steps : param2.
+
+move :
+  IF x steps < 0 OR y steps < 0 THEN stop FI; 
+  IF x steps > 0 THEN x move FI; 
+  IF y steps > 0 THEN y move FI. 
+
+$stdmove$ 
+x move : 
+  x rest INCR x steps;
+  high   := (x rest) DIV blankbreite;
+  x rest := (x rest) MOD blankbreite; 
+  steps := x rest DIV 3;
+  IF high   > 0 THEN high TIMESOUT " " FI;
+  IF steps > 0 AND is slow
+     THEN IF is underline THEN out (" "8"") FI;
+          out (""27"Y" + code (steps) + ""0"");  (* 1/360 *)
+          steps TIMESOUT ""0"";
+          x rest := x rest MOD 3
+  FI. 
+ 
+is underline: 
+  bit (modification bits,7). 
+ 
+y move : 
+  IF y steps > 0
+     THEN high := y steps DIV 255;
+          low  := y steps MOD 255;
+          IF high > 0 THEN high TIMESOUT ""27"J"255"" FI;   (* 1/180 *)
+          IF low  > 0 THEN out (""27"J" + code (low)) FI;
+  FI. 
+ 
+draw :
+  IF x steps < 0 OR y steps <> 0 OR linetype <> 1 
+    THEN stop
+  ELIF x steps > 0
+    THEN x draw
+  FI. 
+ 
+x draw : 
+  x rest INCR x steps ; 
+  steps := x steps DIV 3 ; 
+  IF steps > 0 THEN 
+    x rest := x steps MOD 3 ; 
+    out (""27"Y");
+    out (code (steps MOD 256));
+    out (code (steps DIV 256));
+    steps TIMESOUT ""1""; 
+  FI.
+ 
+$movep5-7$ 
+      x move :
+        x rest INCR x steps; 
+        IF not is underline
+           THEN simple x move
+           ELSE underline x move
+        FI;
+
+        . not is underline :
+            NOT bit (modification bits, 7)
+ 
+        . simple x move :
+            high   := x rest DIV factor 1;
+            x rest := x rest MOD factor 1;
+            out (""27"\");
+            out (code (high MOD 256));
+            out (code (high DIV 256));
+ 
+        . underline x move :
+            high   := x rest DIV factor 2;
+            x rest := x rest MOD factor 2;
+            IF high < blankbreite
+               THEN stop
+               ELSE low  := high MOD 127;
+                    high := high DIV 127;
+                    IF low >= blankbreite
+                       THEN low  DECR blankbreite;
+                       ELSE high DECR 1;
+                            low  DECR (blankbreite - 127);
+                    FI;
+                    IF high > 0 
+                       THEN out (""27" ");
+                            out (code (127 - blankbreite));
+                            high TIMESOUT " ";
+                    FI;
+                    out (""27" ");
+                    out (code (low)); 
+                    out (" "27" "0"");
+            FI;
+. y move:
+
+  low  := y steps MOD 255;
+  high := y steps DIV 255;
+  IF high > 0 THEN high TIMESOUT (""27"J"255"") FI;
+  IF low  > 0 THEN out (""27"J" + code (low))   FI;
+ 
+. draw :
+    IF   x steps < 0 OR y steps <> 0 
+         THEN stop
+    ELIF x steps > 0
+         THEN x draw
+    FI;
+ 
+    . x draw :
+        x rest INCR x steps;
+        steps  := x rest DIV 4;
+        x rest := x rest MOD 4;
+        IF steps > 0
+           THEN low  := steps MOD 256;
+                high := steps DIV 256;
+                out (""27"*"39"");
+                out (code (low));
+                out (code (high));
+                steps TIMESOUT dot;
+        FI;
+
+        . dot :
+            IF linetype = underline linetype
+               THEN ""000""000""001""
+               ELSE ""000""000""048""
+            FI. 
+ 
+ 
+$onoff$ 
+  modification : param1
+.
+  on :
+    buffer := on string (modification);
+    IF buffer <> ""
+       THEN modification bits := modification bits OR code (buffer);
+            switch to font;
+       ELSE stop
+    FI
+ 
+.
+  off :
+    buffer := off string (modification);
+    IF buffer <> ""
+       THEN modification bits := modification bits XOR code (buffer);
+            switch to font;
+       ELSE stop
+    FI.
+ 
+$typep6+$ 
+   type : 
+    font nr := param1 ; 
+    buffer := font string (font nr);
+    font bits   := code (buffer SUB 3);
+    font text   := subtext (buffer, 4);
+    blankbreite := char pitch (font nr, " ") ; 
+    IF is courier 
+      THEN switch to courier 
+      ELSE switch to souvenir 
+    FI ; 
+    switch to font;
+    IF is nlq 
+      THEN switch to nlq 
+      ELSE switch to draft 
+    FI;
+ 
+. switch to font :
+    out (""27"!");
+    out (code (font bits OR modification bits));
+    out (font text);
+ 
+. switch to nlq :
+    out (""27"x"1"");
+ 
+. switch to draft :
+    out (""27"x"0"");
+ 
+. switch to courier : 
+    out (""27"k"0"") ; 
+
+. switch to souvenir : 
+    out (""27"k"15"") ; 
+END PROC execute;
+ 
+$typeplq850$ 
+   type : 
+    font nr := param1 ; 
+    buffer := font string (font nr);
+    font bits   := code (buffer SUB 3);
+    font text   := subtext (buffer, 4);
+    blankbreite := char pitch (font nr, " ") ; 
+    IF is roman 
+      THEN switch to roman 
+      ELSE switch to sansserif 
+    FI ; 
+    switch to font;
+    IF is nlq 
+      THEN switch to nlq 
+      ELSE switch to draft 
+    FI;
+ 
+. switch to font :
+    out (""27"!");
+    out (code (font bits OR modification bits));
+    out (font text);
+ 
+. switch to nlq :
+    out (""27"x"1"");
+ 
+. switch to draft :
+    out (""27"x"0"");
+ 
+. switch to roman : 
+    out (""27"k"0"") ; 
+
+. switch to sansserif : 
+    out (""27"k"1"") ; 
+END PROC execute;
+ 
+$typeokieps$ 
+   type : 
+    font nr := param1 ; 
+    buffer := font string (font nr);
+    font bits   := code (buffer SUB 3);
+    vertical factor := code (buffer SUB 1); 
+    font text   := subtext (buffer, 4);
+    blankbreite := char pitch (font nr, " ") ; 
+    IF is courier 
+      THEN switch to courier 
+      ELSE switch to kassette 
+    FI ; 
+    switch to font;
+    IF is nlq 
+      THEN switch to nlq 
+      ELSE switch to draft 
+    FI;
+ 
+. switch to font :
+    out (""27"!");
+    out (code (font bits OR modification bits));
+    IF vertical factor = 2 
+      THEN out (""27"w"1"") 
+      ELSE out (""27"w"0"") 
+    FI; 
+    out (font text);
+ 
+. switch to nlq :
+    out (""27"x"1"");
+ 
+. switch to draft :
+    out (""27"x"0"");
+ 
+. switch to courier : 
+    out (""27"k"0"") ; 
+
+. switch to kassette : 
+    out (""27"k"127"") ; 
+END PROC execute;
+ 
+$typep5-7$ 
+  type :
+    font nr     := param1;
+    buffer      := font string (font nr);
+    factor 1    := code (buffer SUB 1);  (* 720 / Mikroschritte pro Inch mit ESC \ *)
+    factor 2    := code (buffer SUB 2);  (* 720 / Mikroschritte pro Inch mit ESC Blank *)
+    font bits   := code (buffer SUB 3);
+    font text   := subtext (buffer, 4);
+    blankbreite := char pitch (font nr, " ") DIV factor 2; 
+    switch to font;
+    IF is nlq THEN switch to nlq FI;
+ 
+END PROC execute;
+ 
+ 
+PROC switch to font :
+ 
+  out (""27"!");
+  out (code (font bits OR modification bits));
+  out (font text);
+ 
+END PROC switch to font;
+ 
+ 
+PROC switch to nlq :
+ 
+  IF is pica OR is elite
+     THEN draft factor 1 := factor 1;
+          factor 1       := 4;
+          draft factor 2 := factor 2; 
+          IF is pica
+             THEN factor 2    := 4 * factor 2 DIV 6;
+                  blankbreite := char pitch (font nr, " ") DIV factor 2;
+          FI;
+          out (""27"x"1"");
+     ELSE out (""27"x"0"");
+  FI;
+ 
+END PROC switch to nlq;
+ 
+ 
+PROC switch to draft :
+ 
+  IF is pica OR is elite
+     THEN factor 1 := draft factor 1;
+          factor 2 := draft factor 2;
+          out (""27"x"0"");
+  FI;
+ 
+END PROC switch to draft;
+
+$typetosh$ 
+   type : 
+    font nr := param1 ; 
+    buffer := font string (font nr);
+    font bits   := code (buffer SUB 3);
+    font text   := subtext (buffer, 4);
+    blankbreite := char pitch (font nr, " ") ; 
+    IF is nlq 
+      THEN switch to nlq
+      ELSE switch to draft 
+    FI;
+    switch to font;
+ 
+. switch to font :
+    INT VAR master select bits := font bits OR modification bits ; 
+    IF bit (master select bits,0) 
+       THEN out (""27":")
+       ELSE out (""18"") 
+    FI;
+    IF bit (master select bits,1) 
+       THEN out (""27"I"2""27"P"1"")
+       ELSE out (""27"P"0"") 
+    FI;
+    IF bit (master select bits,2) 
+       THEN out (""27""15"")
+    FI;
+    IF bit (master select bits,3) 
+       THEN out (""27"E")
+       ELSE out (""27"F") 
+    FI;
+    IF bit (master select bits,4) 
+       THEN out (""27"G")
+       ELSE out (""27"H") 
+    FI;
+    IF bit (master select bits,5) 
+       THEN out (""27"W"1"")
+       ELSE out (""27"W"0"") 
+    FI;
+    IF bit (master select bits,6) 
+       THEN
+       ELSE
+    FI;
+    IF bit (master select bits,7) 
+       THEN out (""27"-"1"")
+       ELSE out (""27"-"0"") 
+    FI;
+    out (font text);
+ 
+ 
+. switch to nlq :
+    out (""27"I"2"");
+ 
+. switch to draft :
+    out (""27"I"1"");
+ 
+END PROC execute;
+ 
+$typeokiibm$ 
+   type : 
+    font nr := param1 ; 
+    buffer := font string (font nr);
+    vertical factor := code (buffer SUB 1); 
+    font bits   := code (buffer SUB 3);
+    font text   := subtext (buffer, 4);
+    blankbreite := char pitch (font nr, " ") ; 
+    IF is courier 
+      THEN switch to courier 
+      ELSE switch to kassette 
+    FI ; 
+    IF is nlq 
+      THEN switch to nlq
+      ELSE switch to draft 
+    FI;
+    switch to font;
+ 
+. switch to font :
+    INT VAR master select bits := font bits OR modification bits ; 
+    IF bit (master select bits,0) 
+       THEN out (""27":")
+       ELSE out (""18"") 
+    FI;
+    IF bit (master select bits,1) 
+       THEN out (""27"I"2""27"P"1"")
+       ELSE out (""27"P"0"") 
+    FI;
+    IF bit (master select bits,2) 
+       THEN out (""27""15"")
+    FI;
+    IF bit (master select bits,3) 
+       THEN out (""27"E")
+       ELSE out (""27"F") 
+    FI;
+    IF bit (master select bits,4) 
+       THEN out (""27"G")
+       ELSE out (""27"H") 
+    FI;
+    IF bit (master select bits,5) 
+       THEN out (""27"W"1"")
+       ELSE out (""27"W"0"") 
+    FI;
+    IF bit (master select bits,6) 
+       THEN  out(""27"%G")
+       ELSE  out(""27"%H")
+    FI;
+    IF bit (master select bits,7) 
+       THEN out (""27"-"1"")
+       ELSE out (""27"-"0"") 
+    FI;
+    IF vertical factor = 2 
+      THEN out (""27""91""64""4""0""0""0""2""0"") 
+      ELSE out (""27""91""64""4""0""0""0""1""0"") 
+    FI; 
+    out (font text);
+ 
+ 
+. switch to nlq :
+    out (""27"I"2"");
+ 
+. switch to draft :
+    out (""27"I"0"");
+ 
+. switch to courier : 
+    out (""27"k"0"") ; 
+
+. switch to kassette : 
+    out (""27"k"127"") ; 
+END PROC execute;
+ 
+$typebrother$ 
+   type : 
+    font nr := param1 ; 
+    buffer := font string (font nr);
+    vertical factor := code (buffer SUB 1); 
+    font bits   := code (buffer SUB 3);
+    font text   := subtext (buffer, 4);
+    blankbreite := char pitch (font nr, " ") ; 
+    IF is nlq 
+      THEN switch to nlq
+      ELSE switch to draft 
+    FI;
+    switch to font;
+ 
+. switch to font :
+    INT VAR master select bits := font bits OR modification bits ; 
+    IF bit (master select bits,0) 
+       THEN out (""27":")
+       ELSE out (""18"") 
+    FI;
+    IF bit (master select bits,1) 
+       THEN out (""27"I"2""27"P"1"")
+       ELSE out (""27"P"0"") 
+    FI;
+    IF bit (master select bits,2) 
+       THEN out (""27""15"")
+    FI;
+    IF bit (master select bits,3) 
+       THEN out (""27"E")
+       ELSE out (""27"F") 
+    FI;
+    IF bit (master select bits,4) 
+       THEN out (""27"G")
+       ELSE out (""27"H") 
+    FI;
+    IF bit (master select bits,5) 
+       THEN out (""27"W"1"")
+       ELSE out (""27"W"0"") 
+    FI;
+    IF bit (master select bits,6) 
+       THEN
+       ELSE
+    FI;
+    IF bit (master select bits,7) 
+       THEN out (""27"-"1"")
+       ELSE out (""27"-"0"") 
+    FI;
+    IF vertical factor = 2 
+      THEN out (""27""91""64""4""0""0""0""2""0"") 
+      ELSE out (""27""91""64""4""0""0""0""1""0"") 
+    FI; 
+    out (font text);
+ 
+. switch to nlq :
+    out (""27"I"2"");
+ 
+. switch to draft :
+    out (""27"I"0"");
+ 
+END PROC execute;
+ 
+$typestar$ 
+   type : 
+    font nr := param1 ; 
+    buffer := font string (font nr);
+    font bits   := code (buffer SUB 3);
+    font text   := subtext (buffer, 4);
+    blankbreite := char pitch (font nr, " ") ; 
+    IF is roman 
+      THEN switch to roman 
+      ELSE switch to font1 
+    FI ; 
+    switch to font;
+    IF is nlq 
+      THEN switch to nlq 
+      ELSE switch to draft 
+    FI;
+ 
+. switch to font :
+    out (""27"!");
+    out (code (font bits OR modification bits));
+    out (font text);
+ 
+. switch to nlq :
+    out (""27"x"1"");
+ 
+. switch to draft :
+    out (""27"x"0"");
+ 
+. switch to roman : 
+    out (""27"k"0"") ; 
+
+. switch to font1 : 
+    out (""27"k"1"") ; 
+END PROC execute;
+ 
+ 
+
+$printerlq1500$ 
+PACKET printer driver
+ 
+(**************************************************************************)
+(*                                                Stand   : 29.07.86      *)
+(*   EPSON   LQ-1500                              Version : 4             *)
+(*                                                Autor   : Rudolf Ruland *)
+(*   geändert am 15.12.88 hjh                                             *)
+(**************************************************************************)
+ 
+       DEFINES printer,
+               open,
+               close,
+               execute,
+ 
+               paper size,
+               std quality:
+ 
+LET
+(*  underline           =  1,
+    bold                =  2,
+    italics             =  4,
+    reverse             =  8, *)
+ 
+    underline linetype  =  1,
+ 
+    c document          =  1,
+    c page              =  2,
+ 
+    c write text        =  1,
+    c write cmd         =  2,
+    c carriage return   =  3, 
+    c move              =  4,
+    c draw              =  5,
+    c on                =  6, 
+    c off               =  7,
+    c type              =  8;
+ 
+INT VAR rest, high, low, factor;
+BOOL VAR is nlq, factor was 6, condensed;
+REAL VAR x size, y size;
+TEXT VAR std quality name, buffer;
+ 
+(*********************************************************************)
+ 
+paper size  (13.6 * 2.54, 12.0 * 2.54);
+std quality ("draft");
+ 
+PROC paper size (REAL CONST x, y) :
+ 
+  x size := x;
+  y size := y;
+ 
+END PROC paper size;
+ 
+PROC paper size : 
+ 
+  line;
+  putline ("Papierbreite  =  " + text (x size, 5, 2) + " cm  =  " + text (x size / 2.54, 5, 2) + " Zoll");
+  putline ("Papierlaenge  =  " + text (y size, 5, 2) + " cm  =  " + text (y size / 2.54, 5, 2) + " Zoll");
+ 
+END PROC paper size;
+ 
+ 
+PROC std quality (TEXT CONST quality) :
+ 
+  IF quality = "nlq" OR quality = "draft"
+     THEN std quality name := quality;
+     ELSE errorstop ("unzulaessige Betriebsart")
+  FI;
+ 
+END PROC std quality;
+ 
+TEXT PROC std quality : std quality name END PROC std quality;
+ 
+(*********************************************************************)
+ 
+PROC open (INT CONST op code, INT VAR param1, param2) :
+ 
+SELECT op code OF
+  CASE c document : open document 
+  CASE c page     : open page
+END SELECT; 
+ 
+ 
+. x steps : param1
+. y steps : param2
+. 
+  open document :
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+    factor       := 0;
+    factor was 6 := FALSE;
+    condensed    := FALSE; 
+    x steps := x step conversion ( x size );
+    y steps := y step conversion ( y size );
+    y steps := (y steps DIV 30) * 30;
+    out (""27""64"");                      (* Reset des Druckers             *)
+    out (""27"R"0"");                      (* Amerikanischer Zeichensatz     *)
+    out (""27"C" + code (y steps DIV 30)); (* Formularlaenge                 *)
+    out (""27"x"0"");                      (* Entwurfsqualität               *) 
+ 
+ 
+. x start : param1
+. y start : param2
+. 
+  open page :
+    x start := 0;
+    y start := 0;
+    rest    := 0;
+    out (""13"");
+ 
+END PROC open;
+ 
+ 
+PROC close (INT CONST op code, INT CONST param1) :
+ 
+SELECT op code OF
+  CASE c document : close document 
+  CASE c page     : close page
+END SELECT; 
+ 
+. 
+  close document :
+ 
+ 
+. remaining y steps : param1
+.
+  close page :
+    IF remaining y steps > 0 THEN out (""12"") FI
+ 
+END PROC close;
+ 
+ 
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+ 
+SELECT op code OF
+  CASE c write text       :  write text
+  CASE c write cmd        :  write cmd
+  CASE c carriage return  :  carriage return
+  CASE c move             :  move
+  CASE c draw             :  draw
+  CASE c on               :  on
+  CASE c off              :  off
+  CASE c type             :  type
+END SELECT
+
+ 
+. from : param1
+. to   : param2
+.
+  write text :
+    out subtext (string, from, to)
+ 
+.
+  write cmd :
+    buffer := subtext (string, from, to);
+    IF   buffer = "nlq"
+         THEN is nlq := TRUE;
+              near letter quality;
+    ELIF buffer = "draft"
+         THEN is nlq := FALSE;
+              draft quality;
+         ELSE out (buffer);
+    FI;
+ 
+    . near letter quality :
+        IF factor = 6
+           THEN factor was 6 := TRUE;
+                factor       := 4; 
+           ELSE factor was 6 := FALSE;
+        FI;
+        IF condensed
+           THEN out (""27"x"0"")
+           ELSE out (""27"x"1"") 
+        FI;
+ 
+    . draft quality :
+        IF factor was 6
+           THEN factor was 6 := FALSE;
+                factor       := 6; 
+        FI;
+        out (""27"x"0"");
+ 
+ 
+(*. x steps to left margin : param1*)
+.
+  carriage return :
+    rest := 0;
+    out (""13"");
+ 
+ 
+. x steps : param1
+. y steps : param2
+.
+  move :
+    IF   x steps < 0 OR y steps < 0
+         THEN stop
+    ELIF x steps > 0
+         THEN x move
+    ELIF y steps > 0
+         THEN y move
+    FI;
+ 
+    . x move :
+        high := (x steps + rest) DIV factor;
+        rest := (x steps + rest) MOD factor;
+        out (""27"\");
+        out (code (high MOD 256));
+        out (code (high DIV 256));
+ 
+    . y move :
+        high := y steps DIV 255;
+        low  := y steps MOD 255;
+        IF high > 0 THEN high TIMESOUT ""27"J"255""      FI;
+        IF low  > 0 THEN out (""27"J"); out (code (low)) FI;
+ 
+. 
+  draw :
+    IF   x steps < 0 OR y steps <> 0 OR linetype <> underline linetype
+         THEN stop
+    ELIF x steps > 0
+         THEN x draw
+    FI;
+ 
+    . x draw :
+        high := (x steps + rest) DIV 6;
+        rest := (x steps + rest) MOD 6;
+        IF high > 0
+           THEN low  := high MOD 255;
+                high := high DIV 255;
+                out (""27"V");
+                out (code (low));
+                out (""27"*"1""1""0""1""27"V"0"");
+                FOR low FROM 1 UPTO high
+                    REP out (""27"V"255""27"*"1""1""0""1""27"V"0"") PER; 
+        FI;
+ 
+ 
+. modification : param1
+.
+  on :
+    IF on string (modification) <> "" 
+       THEN out (on string (modification))
+       ELSE stop
+    FI
+ 
+.
+  off :
+    IF off string (modification) <> ""
+       THEN out (off string (modification))
+       ELSE stop
+    FI
+ 
+ 
+. font nr : param1
+.
+  type :
+    buffer := font string (font nr);
+    out (buffer);
+    factor := pitch factor;
+    IF is nlq THEN near letter quality FI;
+ 
+    . pitch factor :                           (*             Mikroschritt *)
+        INT CONST font bits := code (buffer SUB 3);
+        IF   bit (font bits, 1) 
+             THEN condensed := FALSE;       2  (* proportional  1/360 Inch *)
+        ELIF pos (buffer, ""27"x"1"") <> 0
+             THEN condensed := FALSE;       4  (* near letter   1/180 Inch *)
+        ELIF bit (font bits, 2) 
+             THEN condensed := TRUE;        3  (* condensed     1/240 Inch *)
+        ELIF bit (font bits, 0) 
+             THEN condensed := FALSE;       4  (* elite         1/180 Inch *)
+             ELSE condensed := FALSE;       6  (* pica          1/120 Inch *)
+        FI
+ 
+END PROC execute;
+
+
+$end$
+INT VAR reply; DATASPACE VAR ds; FILE VAR file;
+ 
+PROC printer:
+ 
+  disable stop;
+  continue (server channel);
+  check error (error message);
+  ds := nilspace;
+  REP forget (ds);
+      execute print;
+      IF is error AND online THEN put error; clear error; FI;
+  PER;
+END PROC printer;
+ 
+PROC execute print:
+ 
+  LET ack = 0, fetch code = 11, file type = 1003;
+  enable stop;
+  ds := nilspace;
+  call (father, fetch code, ds, reply);
+  IF reply = ack CAND type (ds) = file type
+     THEN file := sequential file (input, 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);
+  FI;
+END PROC execute print;
+ 
+PROC check error(TEXT CONST message):
+ 
+  IF is error
+     THEN clear error; rename myself (message);
+          IF is error THEN end(myself) FI;
+          pause (9000); end(myself);
+  FI;
+END PROC check error;
+ 
+END PACKET printerdriver
+
+
diff --git a/printer/dotmatrix24/printer.24.nadel b/printer/dotmatrix24/printer.24.nadel
new file mode 100644
index 0000000..579f67f
--- /dev/null
+++ b/printer/dotmatrix24/printer.24.nadel
@@ -0,0 +1,776 @@
+ 
+(*************************************************************************) 
+(*   Installationsprogramm für                Stand   :  3. 1.89         *) 
+(*      24-Nadel Drucker                      Version : 0.9              *) 
+(*                                            Autor   : hjh              *) 
+(*************************************************************************) 
+ 
+PACKET driver inst 24 
+ 
+ 
+       DEFINES treiber einrichten: 
+ 
+ 
+LET up = ""3""13""5"", 
+ 
+    generator name = "printer.24.nadel", 
+ 
+    description file name = "beschreibungen24", 
+    module file name = "module24"; 
+ 
+ 
+INT VAR pr channel, 
+        quality,
+        paper format number,
+        service option; 
+TEXT VAR fonttab name :: "", 
+         driver name :: ""; 
+TEXT VAR inp; 
+BOOL VAR was esc; 
+ 
+treiber einrichten 
+ 
+PROC treiber einrichten:
+
+  treiber einrichten (0)
+END PROC treiber einrichten;
+
+PROC treiber einrichten (INT CONST service opt): 
+ 
+  ask for print channel; 
+  main menu; 
+  IF installed 
+    THEN generate printer spool 
+    ELSE inform about restart 
+  FI. 
+ 
+  ask for printchannel: 
+    inits; 
+    page; 
+    headline ("Druckerkanal - Einstellung"); 
+    cursor (1, 15); 
+    putline ("Hinweis: Die Druckerkanalnummer kann auch nachträglich mit"); 
+    putline ("         'serverchannel (Kanalnummer)' in der Task """ + 
+             name (myself) + """"); 
+    putline ("         verändert werden."); 
+    REP 
+      cursor (1, 10);
+      put (""5"EUMEL-Kanalnummer des Druckerkanals:");
+      get (pr channel);
+      disable stop; 
+      serverchannel (pr channel);
+      BOOL VAR no error :: NOT is error; 
+      IF is error 
+        THEN cursor (1, 7); 
+             put error;
+             putline ("Eingabe korrigiert wiederholen!") 
+      FI; 
+      clear error; 
+      enable stop 
+    UNTIL no error PER. 
+ 
+  inits: 
+    line; 
+    IF single task 
+      THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL") 
+    FI; 
+    command dialogue (TRUE);
+    IF name (myself) <> "PRINTER" 
+      THEN putline ("Diese Task heißt nicht ""PRINTER"", sondern """ + 
+                    name (myself) + """ !"); 
+           IF yes ("Soll die Task in ""PRINTER"" umbenannt werden ?") 
+             THEN rename myself ("PRINTER") 
+           FI 
+    FI; 
+    INT VAR choice;
+    service option := service opt.
+ 
+  single task:  (pcb (9) AND 255) = 1.
+ 
+  main menu: 
+    BOOL VAR installed :: FALSE; 
+    REP 
+      show main menu; 
+      get choice; 
+      treat choice 
+    UNTIL was esc OR installed PER. 
+ 
+  show main menu: 
+    page; 
+    headline("Hauptmenü 24-Nadel-Drucker"); 
+    putline (" 1. Brother");
+    putline (" 2. Epson");
+    putline (" 3. NEC"); 
+    putline (" 4. OKI");
+    putline (" 5. Toshiba").
+
+  get choice: 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Installation abbrechen"); 
+    ask user (5).
+ 
+  treat choice: 
+    SELECT int (inp) OF 
+      CASE 1: brother menu 
+      CASE 2: epson menu 
+      CASE 3: nec menu 
+      CASE 4: oki menu 
+      CASE 5: toshiba menu 
+    END SELECT. 
+ 
+  
+  brother menu: 
+    page;
+    headline ("brother - Menü"); 
+    putline (" 1. M-1724 L"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (1); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           brother m1724l inst
+    FI. 
+  
+    brother m1724l inst: 
+      putline ("brother M-1724 L"); 
+      line; 
+      putline ("Wählen Sie folgende DIP-Schalter Optionen:"); 
+      putline ("Emulationsmodus                IBM Proprinter XL ");
+      putline ("Automatischer Zeilenvorschub       Nein       ");
+      show control options ("paperfeed, std speed, top margin"); 
+      show material options ("slow, fast, draft, nlq"); 
+      show command options ("draft, nlq"); 
+      ask for papersize; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.brother"); 
+             generate ("brotherm1724l"); 
+             adjust papersize; 
+             adjust quality; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+ 
+  toshiba menu:
+    page;
+    headline ("TOSHIBA - Menü"); 
+    putline (" 1. P 321"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (1); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           toshiba p321 inst
+    FI. 
+  
+    toshiba p321 inst: 
+       putline ("TOSHIBA P 321"); 
+       putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+       putline ("S3-8  S3-7  S3-5  übrige Schalter"); 
+       putline ("OFF   OFF   *)    egal           "); 
+       putline ("*) ON: Einzelblatteinzug, OFF: kein Einzug"); 
+       show control options ("std speed, paper feed"); 
+       show material options("slow, fast"); 
+       show command options ("nlq, draft"); 
+       ask for quality; 
+       ask for papersize; 
+       IF all right 
+         THEN get fonttable ("fonttab.toshiba.p321"); 
+              generate ("toshp321"); 
+              adjust papersize; 
+              adjust quality; 
+              do ("papersize(21.0,30.48)"); 
+              installed := TRUE; 
+        FI. 
+ 
+  
+  epson menu: 
+    page; 
+    headline ("Epson - Menü"); 
+    putline (" 1. LQ 850"); 
+    putline (" 2. LQ 1050"); 
+    putline (" 3. LQ 1500"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (3); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           SELECT choice OF 
+             CASE 1 : lq850 inst
+             CASE 2 : lq850 inst
+             CASE 3 : lq1500 inst
+           END SELECT
+    FI. 
+
+    lq850 inst:
+      IF choice = 1 
+         THEN putline ("Epson LQ 850")
+         ELSE putline ("Epson LQ 1050")
+      FI; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8");
+      putline ("egal  egal  egal  egal  egal  egal  *1)    OFF ");
+      putline ("*1) ON: Einzelblatteinzug, OFF: kein Einzug"); line;
+      putline ("SW2-1 SW2-2 SW2-3 SW2-4 SW2-5 SW2-6 SW2-7 SW2-8"); 
+      putline ("egal  egal  *2)                     OFF   OFF");
+      putline ("*2) SW2-2 bis SW2-6 müssen je nach Art der Schnittstelle "); 
+      putline ("    gesetzt werden (Druckerhandbuch)");
+      show control options ("std speed, top margin, std typeface, paperfeed");
+      show material options ("slow, fast, draft, nlq, roman, sansserif"); 
+      show command options ("draft, nlq, roman, sansserif"); 
+      ask for quality; 
+      ask for papersize; 
+      IF all right 
+        THEN get fonttable ("fonttab.epson.lq850"); 
+             generate ("epsonlq850"); 
+             adjust quality; 
+             adjust papersize; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI. 
+ 
+  lq1500 inst:
+      putline ("EPSON LQ-1500");
+      show control options ("");
+      show material options ("draft, nlq"); 
+      show command options ("draft, nlq"); 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.epson.lq1500"); 
+             generate ("epsonlq1500"); 
+             adjust quality; 
+             installed := TRUE 
+      FI. 
+ 
+  nec menu: 
+    page;
+    headline ("NEC - Menü"); 
+    putline (" 1. PINWRITER P5 "); 
+    putline (" 2. PINWRITER P6 "); 
+    putline (" 3. PINWRITER P7 "); 
+    putline (" 4. PINWRITER P6 PLUS"); 
+    putline (" 5. PINWRITER P7 PLUS"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (5); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           SELECT choice OF 
+             CASE 1   : necp5p7 inst
+             CASE 2   : necp6 inst
+             CASE 3   : necp5p7 inst 
+             CASE 4   : necp6plus inst
+             CASE 5   : necp6plus inst
+           END SELECT
+    FI. 
+  
+     necp5p7 inst: 
+      IF choice = 1 
+         THEN putline ("NEC PINWRITER P5") 
+         ELSE putline ("NEC PINWRITER P7") 
+      FI; 
+      show control options ("paper feed"); 
+      show material options ("draft, nlq"); 
+      show command options ("draft, nlq"); 
+      ask for quality; 
+      ask for papersize; 
+      IF all right 
+        THEN get fonttable ("fonttab.nec.p5.new"); 
+             generate ("necp5p7"); 
+             adjust papersize; 
+             adjust quality; 
+             installed := TRUE 
+      FI. 
+ 
+     necp6 inst: 
+      putline ("NEC PINWRITER P6 "); 
+      show control options ("paper feed"); 
+      show material options ("draft, nlq"); 
+      show command options ("draft, nlq"); 
+      ask for quality; 
+      ask for papersize; 
+      IF all right 
+        THEN get fonttable ("fonttab.nec.p5.new"); 
+             generate ("necp6"); 
+             adjust papersize; 
+             adjust quality; 
+             installed := TRUE 
+      FI. 
+ 
+     necp6plus inst: 
+      IF choice = 4 
+         THEN putline ("NEC PINWRITER P6 PLUS") 
+         ELSE putline ("NEC PINWRITER P7 PLUS") 
+      FI; 
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:"); 
+      putline ("CR FUNCTION             CR ONLY ");
+      show control options ("std speed, top margin, std typeface, paperfeed");
+      show material options ("slow, fast, draft, nlq, courier, souvenir"); 
+      show command options ("draft, nlq, courier, souvenir"); 
+      ask for papersize; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.nec.p6+"); 
+             generate ("necp6+"); 
+             adjust papersize; 
+             adjust quality; 
+             installed := TRUE;
+             IF choice = 5 THEN do ("papersize (34.544, 30.48)") FI; 
+      FI. 
+ 
+  oki menu: 
+    page; 
+    headline ("OKI - Menü"); 
+    putline (" 1. MICROLINE 390 IBM-/EPSON-kompatibel"); 
+    putline (" 2. MICROLINE 391 IBM-/EPSON-kompatibel"); 
+    putline (" 3. MICROLINE 393/393C EPSON-kompatibel");                   
+    putline (" 4. MICROLINE 393/393C IBM-kompatibel");                     
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (4); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           SELECT choice OF 
+             CASE 1   : oki ml390 inst                                 
+             CASE 2   : oki ml390 inst                                 
+             CASE 3   : oki ml393eps inst 
+             CASE 4   : oki ml393ibm inst 
+           END SELECT
+    FI. 
+ 
+    oki ml390 inst:
+      IF choice = 1
+        THEN putline ("OKI Microline 390") ;
+        ELSE putline ("OKI Microline 391") ;
+      FI;
+      line; 
+      putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:"); 
+      putline ("EMULATION MODE           EPSON LQ ");
+      putline ("AUTO LF                  NO       ");
+      show control options ("paperfeed, std speed, top margin"); 
+      show material options ("slow, fast, draft, nlq"); 
+      show command options ("draft, nlq, courier, kassette"); 
+      ask for papersize; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.oki"); 
+             generate ("oki390/391"); 
+             adjust papersize; 
+             adjust quality; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+ 
+    oki ml393eps inst:
+      putline ("OKI Microline 393 EPSON-kompatibel");
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:"); 
+      putline ("AUTO LF                  NO    ");
+      show control options ("paperfeed, std speed, top margin, std typeface"); 
+      show material options ("slow, fast, draft, nlq"); 
+      show command options ("draft, nlq, courier, kassette, schwarz, rot, blau, violett, gelb, orange, grün"); 
+      ask for papersize; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.oki"); 
+             generate ("oki393/393Ceps"); 
+             adjust papersize; 
+             adjust quality;
+             installed := TRUE 
+      FI.
+ 
+    oki ml393ibm inst:
+      putline ("OKI Microline 393 IBM-kompatibel");
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Wählen Sie folgende Optionen im Druckmenü des Druckers:"); 
+      putline ("EMULATION MODE           ASCII ");
+      putline ("AUTO LF                  NO    ");
+      show control options ("paperfeed, std speed, top margin, std typeface"); 
+      show material options ("slow, fast, draft, nlq"); 
+      show command options ("draft, nlq, courier, kassette, schwarz, rot, blau, violett, gelb, orange, grün"); 
+      ask for papersize; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.oki");
+             generate ("oki393/393Cibm"); 
+             adjust papersize; 
+             adjust quality;
+             installed := TRUE 
+      FI.
+ 
+ 
+ 
+generate printer spool: 
+   IF service opt = 0 
+      THEN forget (generator name, quiet); 
+           forget (driver name, quiet) 
+    FI;
+    eumel must advertise;
+    cursor (1, 10);
+    putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+    putline ("die Fonttabelle mit dem Kommando");
+    line;
+    putline ("      font table (""" + font tab name + """)");
+    line;
+    putline ("eingestellt werden!!!");
+    line (2);
+    putline ("Hinweis: Dieses Installationsprogramm kann in der Task """ + name (myself) + """"); 
+    putline ("         mit 'treiber einrichten' aufgerufen werden, wenn ein anderer"); 
+    putline ("         Drucker eingesetzt werden soll."); 
+    line (2); 
+    put ("Generierung beendet, weiter mit 'SV'");
+    break (quiet);
+    do ("spool manager (PROC printer)").
+ 
+  inform about restart: 
+    page; 
+    putline ("Es ist kein Druckertreiber installiert worden!"); 
+    line; 
+    putline ("Dieses Installationsprogramm kann in der Task """ + name (myself) + """"); 
+    putline ("mit 'treiber einrichten' erneut aufgerufen werden."); 
+    line. 
+ 
+END PROC treiber einrichten; 
+ 
+PROC headline (TEXT CONST header): 
+ 
+  cursor (13,1); 
+  putline ("E U M E L - Druckertreiber - Installations - Programm"); 
+  cursor (40 - LENGTH header DIV 2, 2); 
+  put (header); 
+  line (2) 
+END PROC headline; 
+ 
+PROC ask user (INT CONST max choice): 
+ 
+  TEXT VAR exit; 
+  inp := "";
+  REP 
+    cursor (1,23); 
+    IF inp = "" 
+      THEN put ("Ihre Wahl (Nummer eingeben):")  
+      ELSE put ("FEHLER! Eingabe korrigieren:")
+    FI; 
+    editget (inp, ""27"", "", exit); 
+    was esc :=  exit = ""27"";
+  UNTIL was esc OR ok PER. 
+ 
+  ok: 
+    int (inp) > 0 AND int (inp) <= max choice AND last conversion ok. 
+END PROC ask user;
+
+PROC show control options (TEXT CONST options): 
+ 
+  line; 
+  putline ("Steuerprozeduren in der Task """ + name (myself) + """:"); 
+  write ("papersize, std quality");
+  IF options <> "" 
+    THEN put (","); 
+         putline (options) 
+  FI
+END PROC show control options; 
+
+PROC show material options (TEXT CONST options): 
+ 
+  line; 
+  putline ("Mögliche Materialwerte (#material(""..."")#):"); 
+  putline (options) 
+END PROC show material options; 
+ 
+PROC show command options (TEXT CONST options): 
+ 
+  line; 
+  putline ("Mögliche direkte Druckeranweisungen (#""...""#):"); 
+  putline (options) 
+END PROC show command options; 
+ 
+PROC ask for quality: 
+ 
+  line (1); 
+  putline ("Standard - Druckqualität:"); 
+  line; 
+  REP out (up); 
+    IF yes ("Draft Quality (schneller, aber nicht so schön)") 
+      THEN quality := 1; LEAVE ask for quality 
+    FI;
+    out (up);
+    IF yes ("Near Letter Quality (schöner, aber langsamer)")
+      THEN quality := 2; LEAVE ask for quality 
+    FI;
+  PER 
+END PROC ask for quality; 
+ 
+PROC adjust quality: 
+ 
+  IF quality = 1 
+    THEN do ("std quality (""draft"")") 
+    ELSE do ("std quality (""nlq"")") 
+  FI 
+END PROC adjust quality; 
+ 
+PROC ask for papersize : 
+LET up           = ""3""13""5"";
+ 
+  paper format number := paper format ; 
+ 
+    . paper format :
+        line (1); 
+        putline ("Papierformat:"); 
+        line;
+        REP out (up);
+            IF yes ("Endlospapier, 8 Zoll breit")
+               THEN LEAVE paper format WITH 1 FI;
+            out (up);
+            IF yes ("Endlospapier, 13.2 Zoll breit")
+               THEN LEAVE paper format WITH 2 FI;
+            out (up);
+            IF yes ("Einzelblatteinzug, DINA 4")
+               THEN LEAVE paper format WITH 3 FI;
+        PER;
+        0
+END PROC ask for papersize;
+ 
+ 
+PROC adjust papersize: 
+ 
+    SELECT paper format number OF 
+      CASE 1 : do("papersize ( 8.0 * 2.54, 12.0 * 2.54)");
+               do ("paper feed (""tractor"")") 
+      CASE 2 : do("papersize (13.2 * 2.54, 12.0 * 2.54)");
+               do ("paper feed (""tractor"")") 
+      CASE 3 : do("papersize (21.0, 29.7)");
+               do ("paper feed (""sheet"")") 
+    END SELECT
+ 
+END PROC adjust papersize; 
+ 
+BOOL PROC all right: 
+ 
+  line (3);
+  cursor (1,23); 
+  yes ("Soll der ausgewählte Druckertreiber installiert werden") 
+END PROC all right; 
+ 
+PROC get fonttable (TEXT CONST name): 
+ 
+  fonttab name := name; 
+  from archive ((description file name & module file name & fonttab name) 
+                                                                    - all); 
+  fonttable (fonttab name); 
+  command dialogue (FALSE); 
+  save (fonttab name, /"configurator"); 
+  IF service option = 0 
+    THEN forget (fonttab name) 
+  FI; 
+  command dialogue (TRUE); 
+END PROC get fonttable; 
+ 
+PROC from archive (THESAURUS CONST files):
+ 
+  IF highest entry (files) > 0 
+    THEN fetch from archive; 
+         release (archive);
+         putline ("Archiv abgemeldet !")
+  FI.
+ 
+  fetch from archive: 
+    THESAURUS VAR thes :: files; 
+    REP 
+      ask for archive;
+      reserve archive;
+      fetch (thes / ALL archive, archive);
+      thes := thes - all 
+    UNTIL highest entry (thes) = 0 PER.
+
+ask for archive:
+  line;
+  putline ("Bitte Archiv mit den Dateien"); 
+  TEXT VAR buffer;
+  INT VAR index :: 0; 
+  REP 
+    get (thes, buffer, index); 
+    putline ("    " + buffer) 
+  UNTIL index = 0 PER; 
+  putline ("einlegen !"); 
+  line; 
+  putline ("Wenn eingelegt: Taste drücken !"); 
+  inchar (buffer). 
+ 
+reserve archive :
+  INT VAR p1, p2;
+  archive (" "31" ");
+  disable stop;
+  list (archive);
+  IF is error
+     THEN buffer := errormessage;
+          p1 := pos (buffer, """", 1 ) + 1;
+          p2 := pos (buffer, """", p1) - 1;
+          IF p1 > 0 AND p2 > 0
+             THEN clear error;
+                  buffer := subtext (buffer, p1, p2);
+                  archive (buffer);
+          FI;
+  FI;
+  enable stop.
+
+END PROC from archive;
+
+THESAURUS OP & (TEXT CONST left, right):
+  THESAURUS VAR result := empty thesaurus;
+  insert (result, left);
+  insert (result, right);
+  result
+END OP &;
+
+THESAURUS OP & (THESAURUS CONST left, TEXT CONST right):
+  THESAURUS VAR result := left;
+  insert (result, right);
+  result
+END OP &;
+ 
+PROC generate (TEXT CONST name): 
+ 
+  open files; 
+  read description; 
+  build programme; 
+  insert programme; 
+  forget files. 
+ 
+  open files: 
+    line (5); 
+    cursor (1, 20); 
+    putline (""4"Bitte warten !"); 
+    putline ("    - Der Treiber wird generiert."); 
+    driver name := "printer." + name + "(generiert)"; 
+    IF exists (driver name) 
+      THEN forget (driver name, quiet) 
+    FI; 
+    FILE VAR des file :: sequential file (modify, description file name), 
+             mod file :: sequential file (modify, module file name), 
+             driver file :: sequential file (output, driver name). 
+ 
+  read description: 
+    to line (des file, 1); 
+    col (des file, 1);
+    downety (des file, "$" + name + "$"); 
+    IF eof (des file) 
+      THEN errorstop ("Beschreibung von """ + name + """ nicht im"13""10"" + 
+                      "Descriptions-File enthalten")
+    FI; 
+    TEXT VAR description :: "", 
+             record; 
+    BOOL VAR done :: FALSE; 
+    read record (des file, record); 
+    record := subtext (record, col (des file) + LENGTH name + 2);
+    WHILE NOT eof (des file) AND NOT done REP 
+      treat record
+    PER. 
+ 
+  treat record: 
+    INT VAR dollar pos :: pos (record, "$"); 
+    IF dollar pos = 0
+      THEN description CAT compress (record); 
+           down (des file); 
+           read record (des file, record)  
+      ELSE description CAT compress (subtext (record, 1, dollar pos - 1));
+           col (des file, dollar pos); 
+           done := TRUE; 
+    FI. 
+ 
+  build programme: 
+    get module name; 
+    WHILE still modules REP 
+      find module; 
+      transfer module; 
+      get module name 
+    PER. 
+ 
+  get module name: 
+    INT VAR semicol pos :: pos (description, ";"); 
+    TEXT VAR module name; 
+    IF semicol pos > 0 
+      THEN module name := subtext (description, 1, semicol pos - 1); 
+           description := subtext (description, semicol pos + 1) 
+      ELSE module name := description; 
+           description := "" 
+    FI.
+ 
+  still modules: 
+    module name <> "" OR description <> "". 
+ 
+  find module: 
+    to line (mod file, 1); 
+    col (mod file, 1); 
+    downety (mod file, "$" + module name + "$"); 
+    IF eof (mod file) 
+      THEN errorstop ("Modul """ + module name + """ nicht im"13""10"" + 
+                      "Modul-File enthalten")
+    FI. 
+ 
+  transfer module: 
+    done := FALSE; 
+    read record (mod file, record); 
+    record := subtext (record, col (mod file) + LENGTH module name + 2);
+    WHILE NOT eof (mod file) AND NOT done REP 
+      transfer record
+    PER. 
+ 
+  transfer record: 
+    dollar pos := pos (record, "$"); 
+    IF dollar pos = 0
+      THEN write (driver file, compress (record)); 
+           line (driver file);
+           down (mod file); 
+           read record (mod file, record)  
+      ELSE write (driver file, compress (subtext (record, 1, 
+                                            dollar pos - 1)));
+           col (mod file, dollar pos); 
+           done := TRUE; 
+           cout (line no (mod file)) 
+    FI. 
+ 
+  insert programme: 
+    IF online 
+      THEN putline ("    - Der Treiber wird insertiert.") 
+    FI;
+    check off; 
+    insert (driver name). 
+ 
+  forget files: 
+    IF service option = 0 
+      THEN forget (description file name, quiet); 
+           forget (module file name, quiet)
+    FI  .
+END PROC generate; 
+ 
+END PACKET driver inst 24
+
diff --git a/printer/dotmatrix24/readme b/printer/dotmatrix24/readme
new file mode 100644
index 0000000..d526aa3
--- /dev/null
+++ b/printer/dotmatrix24/readme
@@ -0,0 +1,320 @@
+#type("nlq10")##limit(18.0)##start(1.5,1.0)# 
+#head# 
+Treiber-Installations-Programm   #right#Seite % 
+für 24-Nadel-Matrixdrucker   #right#23.12.1988 
+ 
+ 
+#end# 
+#on("u")#Dokumentation zum Treiber-Installations-Programm für 24-Nadel-
+Matrixdrucker#off("u")# 
+ 
+#on("u")#Inhalt:#off("u")# 
+ 
+1. Installations- und Gebrauchsanleitung 
+2. Druckertreiber-Auswahl 
+3. Steuerungsmöglichkeiten und Spezialfeatures 
+4. Weitere Hinweise 
+ 
+ 
+#on("b")#1. Installations- und Gebrauchsanleitung#off("b")# 
+ 
+#on("u")#Einrichten#off("u")# 
+So wird das Treiber-Installationsprogramm eingerichtet: 
+ 
+       SV drücken 
+ 
+    nach 'gib supervisor kommando:' 
+ 
+       begin("PRINTER","SYSUR") 
+ 
+    in der Task "PRINTER" (nach 'gib kommando'): 
+ 
+       archive ("std.printer") 
+       fetch ("printer.24.nadel",archive) 
+       check off 
+       insert ("printer.24.nadel") 
+ 
+Das Programm wird dann insertiert. 
+ 
+#on("u")#Druckerkanal#off("u")# 
+Hiernach wird die Kanalnummer des Druckers erfragt. Wenn der Drucker
+über Parallelschnittstelle betrieben wird, ist die Kanalnummer
+meistens 15. 
+ 
+#on("u")#Menüsystem#off("u")# 
+Das Installationsprogramm zeigt nun eine Liste von Druckerherstellern.
+Wählen Sie den Hersteller Ihres Druckers aus! Hiernach wird eine Liste
+der unterstützten Drucker dieses Herstellers gezeigt. Wählen Sie hier
+den passenden Typ aus! 
+Das Installationsprogramm zeigt nun einige Informationen zu dem ange­
+wählten Drucker. Besonders zu beachten sind hierbei #on("u")#Angaben zur Konfi­
+guration des Druckers#off("u")# (z.B. DIP-Schalter). Der Drucker muß unbedingt
+wie angegeben konfiguriert werden, wenn er mit dem ausgewählten Trei­
+ber betrieben werden soll. 
+ 
+Hinweise zu Konfigurationsangaben: 
+1. Die Angabe 'egal' bedeutet, daß die Einstellung für die Funktion
+   des Treibers keine Bedeutung hat. Dennoch solte der Anwender darauf
+   achten, welche Funktion die Schalter haben (Druckerhandbuch!). So
+   ist es zum Beispiel immer empfehlenswert, den Papierende-Sensor zu
+   aktivieren, damit der Drucker nach Papierende nicht auf der Walze
+   weiterdruckt. 
+2. Die Konfigurationsangaben beziehen sich immer auf genau den ausge­
+   wählten Druckertyp. Wenn Sie den Treiber mit einem anderen Drucker
+   als den ausgewählten verwenden, dann beachten Sie folgende Regeln
+   für die Konfiguration: 
+   - Der Drucker muß auf eine passende Emulation konfiguriert werden. 
+   - Der Drucker darf bei einem Carriage Return (Code 13) keinen Zei­
+     lenvorschub durchführen. 
+   - Der Drucker darf die Perforation #on("u")#nicht#off("u")# automatisch überspringen. 
+ 
+   - Auf Seitenlängen und internationale Zeichensätze müssen Sie nicht
+     achten. 
+ 
+(Hinweise zur Auswahl des richtigen Treibers gibt Abschnitt 2) 
+ 
+Nach den Konfigurationsangaben werden Steuerungsmöglichkeiten des
+ausgewählten Treibers angezeigt. (Siehe hierzu Abschnitt 3) 
+ 
+Falls der Treiber bestimmte grundsätzliche Betriebsmöglichkeiten er­
+laubt (z.B. DRAFT/NLQ, Einzelblatteinzug), werden Sie danach gefragt,
+welche Möglichkeit standardmäßig gewählt werden soll. diese Vorein­
+stellungen können nachträglich in der Task "PRINTER" mit den entspre­
+chenden Steuerprozeduren neu gesetzt werden. Außerdem können bestimmte
+Einstellungen noch für jedes einzelne Dokument (d.h. für jede Druck­
+datei) gewählt ('material'-Anweisung) oder sogar innerhalb eines Doku­
+ments verändert werden (direkte Druckeranweisung \#"..."\#). 
+Über die Steuerungsmöglichkeiten informiert Abschnitt 3 ausführlicher. 
+ 
+ 
+#on("b")#2. Druckertreiber-Auswahl#off("b")# 
+ 
+#on("u")#Verwendung nicht im Menü enthaltener Drucker#off("u")# 
+Für den Fall, daß Sie genau Ihren Drucker im Menü nicht finden, soll­
+ten Sie zunächst versuchen, ob ein Treiber für einen anderen Drucker
+des gleichen Herstellers mit Ihrem Drucker korrekt arbeitet. 
+Falls dies nicht funktioniert oder der Hersteller überhaupt nicht im
+Menü erscheint, müssen Sie herausfinden (Druckerhandbuch, -händler!),
+welchen Drucker Ihr Drucker emuliert oder welchem er ähnlich ist.
+(Viele Drucker verfügen über EPSON LQ-1000 oder IBM Grafikdrucker bzw.
+Proprinter-Eumulationen.) 
+Eine der beiden Anpassungen 'EPSON LQ-1050' oder 'OKI ML-393
+IBM-kompatibel' müßte immer einen (Minimal-) Betrieb ermöglichen (wobei die
+Verwendung der Proportionalschrift bzw. der doppelt hohen Schriften u. U.
+nicht funktioniert). 
+ 
+ 
+#on("b")#3. Steuerungsmöglichkeiten und Spezialfeatures#off("b")# 
+ 
+Einige Treiber bieten bestimmte Einstellungsmöglichkeiten (z.B.
+DRAFT/NLQ) und/oder Spezialfeatures (z.B. Farbdruck). 
+Die Einstellungen können über 
+- Steuerprozeduren 
+- Materialanweisungen bzw. 
+- direkte Druckeranweisungen 
+vorgenommen werden. 
+ 
+#on("u")#Steuerprozeduren#off("u")# 
+setzen Einstellungen, die für alle Dokumente (Druckdateien) gelten
+sollen. Die Prozeduren müssen in der Druckspooltask (meist: "PRINTER")
+aufgerufen werden. #on("b")#Gültig werden die Änderungen erst, wenn danach in
+der Druckspooltask das Kommando 'start' gegeben wird!#off("b")# 
+ 
+PROC papersize (REAL CONST breite, länge) 
+    Dient zur Einstellung der Größe der physikalisch beschreibbaren
+    Fläche. 
+    Beispiel:  papersize (20.32, 30.48) 
+               (Standardeinstellung für Endlospapier 8 Zoll breit und
+               12 Zoll lang) 
+ 
+PROC papersize 
+    Informationsprozedur 
+ 
+PROC top margin (REAL CONST margin) 
+    Falls der Drucker es nicht erlaubt, direkt am Blattanfang zu druk­
+    ken (zum Beispiel wegen eines Einzelblatteinzugs), muß mit dieser
+    Prozedur die Länge des oberen Randes, den der Drucker nicht be­
+    drucken kann, in cm angegeben werden. 
+    Beispiel:  top margin (2.0) 
+               (Teilt dem Druckertreiber mit, daß die ersten 2 cm
+               nicht bedruckbar sind.) 
+ 
+REAL PROC top margin 
+    Informationsprozedur 
+ 
+PROC std speed (TEXT CONST speed) 
+    Parameter: slow, fast 
+    Wahl zwischen Positionierung in Mikroschritten (slow) oder in
+    Blanks (fast). 
+    Beispiel:  std speed ("slow") 
+ 
+TEXR PROC std speed 
+    Informationsprozedur 
+ 
+PROC std quality (TEXT CONST quality) 
+    übliche Parameter: draft, nlq 
+    Wahl zwischen Datenverarbeitungs-Qualität und Schönschrift-
+    Qualität 
+    Beispiel:  std quality ("draft") 
+ 
+TEXT PROC std quality 
+    Informationsprozedur 
+ 
+PROC std typeface (TEXT CONST typeface) 
+    übliche Parameter: roman, sansserif, courier 
+    Wahl zwischen verschiedenen NLQ-Schriftarten (nur sichtbar im
+    NLQ-Modus, das heißt 'std typeface' schaltet nicht auf NLQ). 
+    Beispiel: std typeface ("roman") 
+ 
+TEXT PROC std typeface 
+    Informationsprozedur 
+ 
+PROC paper feed (TEXT CONST name) 
+    übliche Parameter: tractor, sheet, schacht1, schacht2 
+    Wählt Endlospapier oder Einzelblatteinzug und ggf. Schachtnummer. 
+    Beispiel:  paper feed ("sheet") 
+ 
+TEXT PROC paper feed 
+    Informationsprozedur 
+ 
+ 
+#on("u")#Materialanweisungen \#material("...")\##off("u")# 
+müssen in der Druckdatei vor dem ersten druckbaren Zeichen stehen und
+setzen Einstellungen für eine ganze Datei. (Materialanweisungen haben
+für die jeweilige Datei Vorrang vor den durch Steuerprozeduren einge­
+stellten Standardwerten. Diese werden durch die Materialanweisung aber
+nicht geändert.) 
+ 
+Beispiel:  \#material("nlq")\# 
+           sorgt bei entsprechendem Treiber dafür, daß das gesamte
+           Dokument in Schönschrift-Qualität ausgedruckt wird, egal
+           wie 'std quality' eingestellt ist. 
+ 
+#on("b")#Es darf in einer Datei nur eine Materialanweisung stehen!#off("b")# Sollen meh­
+rere Einstellungen vorgenommen werden, müssen sie in einer Anweisung
+erscheinen. Beispiel:  \#material("sheet;draft")\# 
+ 
+ 
+#on("u")#direkte Druckeranweisungen \#"..."\##off("u")# 
+gelten ab der Position, an der sie in der Datei auftreten. Sie haben
+(sofern sie erlaubt sind,) Vorrang vor Standardeinstellungen und
+Materialeinstellungen. 
+ 
+Beispiel:  \#"draft"\# 
+           schaltet (bei entsprechendem Treiber) auf Datenverar­
+           beitungs-Qualität, egal welche Standardeinstellung vorliegt
+           und welche Materialanweisung gegeben wurde. 
+ 
+#on("b")#In einer Druckeranweisung darf nur eine Einstellung vorgenommen
+werden.#off("b")# Also:  \#"nlq"\#\#"sansserif"\# 
+ 
+ 
+#on("u")#Wichtig#off("u")# 
+- Achten Sie bei Materialanweisungen und direkten Druckeranweisungen
+  besonders auf korrekte Schreibweise! Es werden nur Kleinbuchstaben
+  berücksichtigt! Also:  \#"nlq"\# und keinesfalls \#"NLQ"\#!!! 
+- Direkte Druckeranweisungen werden vom EUMEL-Drucker ignoriert und
+  nur vom Druckertreiber in eine Kommando-Sequenz umgesetzt. Es kann
+  daher vorkommen, daß (z.B. bei Spaltendruck) unerwartete Ergebnisse
+  erscheinen, weil der EUMEL-Drucker dann den Text in einer anderen
+  Reihenfolge an den Drucker sendet, als er in der Datei steht, die
+  mit dem direkten Druckerkommando gesetzte Modifikation aber (z.B.
+  für beide Spalten) unerwünscht erhalten bleibt. 
+ 
+ 
+#on("u")#Tabelle#off("u")# 
+Die Tabelle soll einen Anhaltspunkt dafür geben, wie welche Einstel­
+lungen erfolgen können. 
+ 
+#type("17")# 
+                   Steuerprozeduren      Materialanweisungen     direkte Druckeranweisungen 
+ 
+#on("u")#                                                                                          #off("u")# 
+ 
+Positionierung     std speed             slow, fast              ------ 
+                     slow, fast 
+ 
+Qualität           std quality           z.B. draft, nlq         z.B. draft, nlq 
+                     z.B. draft, nlq 
+ 
+Schriftart         std typeface          z.B. roman,             z.B. roman, 
+(nur bei NLQ)        z.B. roman,         sansserif, courier      sansserif, courier 
+                     sansserif, courier 
+ 
+Einzelblatt-       paper feed            z.B. schacht1,          z.B. schacht1, 
+einzug               z.B. tractor,       schacht2                schacht2 
+                     sheet, 
+                     schacht1, schacht2 
+ 
+Farbdruck          ------                ------                  z.B. schwarz, 
+                                                                 rot, blau, 
+                                                                 violett, gelb 
+                                                                 orange, grün 
+ 
+ 
+ 
+#type("nlq10")##on("b")#4. Weitere Hinweise#off("b")# 
+ 
+#on("u")#Zeichensatzänderungen gegenüber früheren Versionen#off("u")# 
+In den Fonttabellen früherer Druckertreiber-Versionen wurden oberhalb
+des Codes 127 einige internationale Zeichen zur Verfügung gestellt
+(und zwar in Anlehnung an den Agfa-Laserdrucker-Zeichensatz). 
+Bei den Treibern der vorliegenden Version gilt folgendes: 
+- Wie bisher wird der volle im Benutzerhandbuch festgelegte EUMEL-
+  Zeichensatz (sofern möglich) unterstützt. 
+- Der Code 252 liefert das Paragraphzeichen. 
+- Alle übrigen (vom EUMEL-Zeichensatz nicht definierten) Zeichencodes
+  oberhalb 127 liefern, sofern möglich, die entsprechenden Zeichen des
+  IBM-Grafikzeichensatzes. 
+ 
+ 
+#on("u")#Hinweis zu Proportionalschriften#off("u")# 
+Bei Proportionalschriften kann die Modifikation \#on("i")\# zu Problemen
+führen (z.B. beim Blocksatz), wenn die kursiven Zeichen andere
+Proportionalbreiten haben.
+ 
+#on("u")#Hinweis zur Modifikation on/off("b") bzw. on/off("r")#off("u")# 
+Die meisten 24-Nadel Drucker verfügen sowohl über einen horizontalen als
+auch über einen vertikalen Schattendruck. Diese beiden Druckarten können
+mit der Modifikation on("b") (bold) bzw. on("r") (eigentlich für reverse
+gedacht) eingeschaltet werden.
+
+#on("u")#Hinweis zur Benutzung von Einzelblatteinzügen#off("u")# 
+Bei der Benutzung von Einzelblatteinzügen müssen folgende Einstel­
+lungen vorgenommen werden (vgl. auch Abschnitt 3!): 
+ 
+   Am Drucker: 
+1. Sie müssen Ihren Drucker auf die Option Einzelblatteinzug
+   schalten (siehe Druckerhandbuch!). 
+ 
+   In der Druckspooltask (meist 'PRINTER'): 
+2. Falls der Druckertreiber die Steuerprozedur 'paper feed' zur Verfü­
+   gung stellt, müssen Sie mit 'paperfeed ("sheet")' oder (für
+   2-Schacht-Einzüge) mit 'paperfeed ("schacht1")' bzw. 'paperfeed
+   ("schacht2")' den Druckertreiber auf Einzelblatteinzug umschalten. 
+3. Falls Sie eine andere Papierlänge als 12 Zoll (=30.48 cm) verwen­
+   den, müssen Sie die neuen Papiermaße mit 'papersize' in cm einstel­
+   len. 
+   Beispiel:  papersize (21.0, 29.7) 
+              (für DIN A4-Blätter) 
+4. Falls der Drucker mit dem Einzelblatteinzug nicht direkt am Blatt­
+   anfang drucken kann, sondern ein gewisser oberer Rand bleibt, muß
+   mit 'top margin' die Länge des nicht bedruckbaren Randes in cm dem
+   Druckertreiber mitgeteilt werden. 
+   Beispiel:  top margin (1.5) 
+   (Wie groß der obere Rand ist, kann festgestellt werden, indem eine
+   Datei mit \#start(0.0,0.0)\# ausgedruckt wird.) 
+ 
+   Wurde mit 'top margin' dem Treiber die Größe der nicht bedruckbaren
+   Fläche mitgeteilt, so ist darauf zu achten, daß in den Druckdateien
+   ein genügend großer y-Wert für die Startposition eingestellt wird
+   ('start'-Anweisung). Andernfalls kommt es bei der Ausgabe in der
+   ersten Zeile zu Überschreibungen. 
+ 
+ 
+#on("b")#5. Die Änderungen, die Sie in der Druckspooltask vorgenommen haben
+   werden erst wirksam, wenn das Spool-Kommando 'start' gegeben wird.#off("b")# 
+
+
+
+
diff --git a/printer/dotmatrix9/beschreibungen9 b/printer/dotmatrix9/beschreibungen9
new file mode 100644
index 0000000..6a74b88
--- /dev/null
+++ b/printer/dotmatrix9/beschreibungen9
@@ -0,0 +1,97 @@
+ 
+(*************************************************************************)
+(*                                            Stand   : 01.10.88         *)
+(*  Beschreibungen-Datei für 9-Nadel-Drucker  Version : 0.9              *)
+(*                                            Autoren : mov/hjh          *)
+(*************************************************************************)
+ 
+$fx85$ 
+head;hfx85;decl;speed;openh;opendoch;initspeed;opendocfx85;openpge;betwoc; 
+clpge;betwce;cmd;crs;moh;mofx85;ymodr;onoff;tyfx85;end 
+
+$fx800$ 
+head;hfx800;decl;quality;typeface;openh;opendoch;opendocfx800;openpge;betwoc; 
+clpge;betwce;cmdfx800;crs;moh;mofx800;ymodr;onoff;tyfx800;end 
+
+$mx$ 
+head;hmx;decl;speed;openh;opendoch;initspeed;opendocmx;openpge;betwoc;clpge; 
+betwce;cmd;crs;moh;modrmx;onoff;tymx;end 
+ 
+$lx800$ 
+head;hlx800;decl;speed;quality;typeface;openh;opendoch;initspeed; 
+opendocfx800;openpge;betwoc;clpge;betwce;cmdfx800;crs;moh;mofx85;ymodr;onoff; 
+tyfx800;end 
+
+$ibmgp$ 
+head;hgp;decl;speed;openh;opendoch;initspeed;opendocgp;openpge;betwoc; 
+clpge;betwce;cmd;crs;moh;mogp;ymodr;onoff;tyfx85;end 
+ 
+$ibmpp$ 
+head;hpp;decl;speed;quality;openh;opendoch;initspeed;opendocpp;openpge; 
+betwoc;clpge;betwce;cmdpp;crs;moh;mofx85;ymodr;onoffpp;tyfx85;end 
+ 
+$okiml182i$
+head;hml182i;decl;speed;quality;openh;opendoch;initspeed;opendocml182i; 
+opendocgp;openpge;betwoc;clpge;betwce;cmdml182i;crs;moh;mogp;ymodr;onoff; 
+tyohnesmall;end 
+ 
+$okiml192el$ 
+head;hml192el;decl;speed;feed;openh;opendoch;initspeed;opendocml192el; 
+openpgemlsf;betwoc;clmlsf;betwce;cmd;crs;moh;moml192el;ymodr;onoff;tyml192el; 
+end 
+ 
+$okiml292el$ 
+head;hml292el;decl;quality;typeface292;feed;openh;opendoch;opendocml292el; 
+openpgemlsf;betwoc;clmlsf;betwce;cmdml292el;crs;moh;mofx800;ymodr;onoff; 
+tyml292el;end 
+ 
+$okiml294i$ 
+head;hml294i;decl;speed;quality;feed;openh;opendoch;initspeed;opendocml294i; 
+openpgemlsf;betwoc;clmlsf;betwce;cmdml294i;crs;moh;mofx85;ymodr;ontyml294i;end 
+ 
+$okiml320$ 
+head;hml320;decl;speed;openh;opendoch;initspeed;opendocml320; 
+openpge;betwoc;clpge;betwce;cmd;crs;moh;moml192el;ymodr;onoff;tyml192el; 
+end 
+ 
+$starlc10$ 
+head;hlc10;decl;quality;typefacelc10;openh;opendoch;opendoclc10;openpge; 
+betwoc;clpge;betwce;cmdlc10;crs;moh;mofx800;ymodr;onoff;tyfx800;end 
+ 
+$dmp4000$ 
+head;hdmp4000;decl;speed;openh;opendoch;initspeed;opendocdmp4000;openpge; 
+betwoc;clpge;betwce;cmd;crs;moh;mofx85;ymodr;onoff;tyfx85;end 
+ 
+$starnx15$ 
+head;hnx15;decl;speed;openh;opendoch;initspeed;opendocnx15;openpge;betwoc; 
+clpge;betwce;cmd;crs;moh;mofx85;ymodr;onoff;tyfx85;end 
+ 
+$mt230$ 
+head;hmt230;decl;speed;feedschacht;openh;opendoch;initspeed;opendocmt; 
+openpgemtsf;betwoc;clmtsf;betwce;cmdmt230;crs;moh;mofx85;ymodr;onoff; 
+tyfx85;end 
+ 
+$mt340$ 
+head;hmt340;decl;speed;feedschacht;openh;opendoch;initspeed;opendocmt; 
+openpgemtsf;betwoc;clmtsf;betwce;cmdmt230;crs;moh;moml192el;ymodr;onoff; 
+tyml192el;end 
+ 
+$citi120d$ 
+head;h120d;decl;openh;opendoch;opendoc120d;openpge;betwoc; 
+clpge;betwce;cmd;crs;moh;mofx800;ymodr;onoff;tyfx85;end 
+ 
+$citohc310cxp$ 
+head;hc310;decl;speed;feedschacht;openh;opendoch;initspeed;opendocc310; 
+openpgec310sf;betwoc;clc310sf;betwce;cmdc310;crs;moh;mofx85;ymodr;onoff; 
+tyfx85;end 
+ 
+$citohci3500$ 
+head;hci3500;decl;speed;openh;opendoch;initspeed;opendocgp;openpge;betwoc; 
+clpge;betwce;cmd;crs;moh;mogp;ymodr;onoff;tyfx85;end 
+ 
+$fujdx2100$ 
+head;hdx2100;decl;speed;feed;openh;opendoch;initspeed;opendocdx2100; 
+openpge;betwoc;clpge;betwce;cmddx2100;crs;moh;moml192el;ymodr;onoff;tyml192el; 
+end 
+
+
diff --git a/printer/dotmatrix9/fonttab.1 b/printer/dotmatrix9/fonttab.1
new file mode 100644
index 0000000..b5d17e6
Binary files /dev/null and b/printer/dotmatrix9/fonttab.1 differ
diff --git a/printer/dotmatrix9/fonttab.10 b/printer/dotmatrix9/fonttab.10
new file mode 100644
index 0000000..6a13c49
Binary files /dev/null and b/printer/dotmatrix9/fonttab.10 differ
diff --git a/printer/dotmatrix9/fonttab.20 b/printer/dotmatrix9/fonttab.20
new file mode 100644
index 0000000..7cf0aaf
Binary files /dev/null and b/printer/dotmatrix9/fonttab.20 differ
diff --git a/printer/dotmatrix9/fonttab.20.lc b/printer/dotmatrix9/fonttab.20.lc
new file mode 100644
index 0000000..ddf4535
Binary files /dev/null and b/printer/dotmatrix9/fonttab.20.lc differ
diff --git a/printer/dotmatrix9/fonttab.20.lx b/printer/dotmatrix9/fonttab.20.lx
new file mode 100644
index 0000000..1ce0940
Binary files /dev/null and b/printer/dotmatrix9/fonttab.20.lx differ
diff --git a/printer/dotmatrix9/fonttab.7 b/printer/dotmatrix9/fonttab.7
new file mode 100644
index 0000000..676b9a0
Binary files /dev/null and b/printer/dotmatrix9/fonttab.7 differ
diff --git a/printer/dotmatrix9/fonttab.7.cxp b/printer/dotmatrix9/fonttab.7.cxp
new file mode 100644
index 0000000..0a996f3
Binary files /dev/null and b/printer/dotmatrix9/fonttab.7.cxp differ
diff --git a/printer/dotmatrix9/fonttab.7.fuj b/printer/dotmatrix9/fonttab.7.fuj
new file mode 100644
index 0000000..1ed83be
Binary files /dev/null and b/printer/dotmatrix9/fonttab.7.fuj differ
diff --git a/printer/dotmatrix9/fonttab.7.mt b/printer/dotmatrix9/fonttab.7.mt
new file mode 100644
index 0000000..c816646
Binary files /dev/null and b/printer/dotmatrix9/fonttab.7.mt differ
diff --git a/printer/dotmatrix9/module9 b/printer/dotmatrix9/module9
new file mode 100644
index 0000000..65de1ee
--- /dev/null
+++ b/printer/dotmatrix9/module9
@@ -0,0 +1,1099 @@
+ 
+(*************************************************************************)
+(*                                            Stand   : 01.10.88         *)
+(*   Module-Datei für 9-Nadel-Drucker         Version : 0.9              *)
+(*                                            Autoren : mov/hjh          *)
+(*************************************************************************)
+
+$head$ 
+PACKET printer driver 
+ 
+       DEFINES printer,
+               open,
+               close,
+               execute,
+               paper size,
+               top margin,
+
+$hfx85$        std speed:
+(* Treiber für EPSON FX85/105, automatisch generiert *)
+
+$hfx800$       std quality,
+               std typeface:
+(* Treiber für EPSON FX800/1000, automatisch generiert *) 
+BOOL VAR was tall font;
+ 
+$hmx$          std speed:
+(* Treiber für EPSON MX80/100, Typ III *) 
+(* Treiber automatisch generiert *)
+BOOL VAR is condensed, is small;
+
+$hlx800$       std speed, 
+               std quality,
+               std typeface:
+(* Treiber für EPSON LX800/1000, automatisch generiert *) 
+BOOL VAR was tall font;
+
+$hgp$          std speed: 
+(* Treiber für IBM-Grafikdrucker *) 
+(* Treiber automatisch generiert *) 
+
+$hpp$          std speed, 
+               std quality:
+(* Treiber für IBM-Proprinter *) 
+(* Treiber automatisch generiert *) 
+ 
+$hml182i$      std speed,
+               std quality:
+(* Treiber für OKI ML182/183 IBM-kompatibel *) 
+(* Treiber automatisch generiert *) 
+ 
+$hml192el$     paper feed,
+               std speed:
+(* Treiber für OKI ML192/193 Elite *) 
+(* Treiber automatisch generiert *) 
+BOOL VAR prop font;
+ 
+$hml292el$     std quality, 
+               std typeface, 
+               paper feed: 
+(* Treiber für OKI ML292/293 Elite *) 
+(* Treiber automatisch generiert *) 
+BOOL VAR was tall font;
+
+$hml294i$      std speed, 
+               paper feed,
+               std quality:
+(* Treiber für OKI ML294 IBM-kompatibel *)
+(* Treiber automatisch generiert *) 
+
+$hml320$       std speed:
+(* Treiber für OKI ML320 IBM/EPSON-kompatibel *) 
+(* Treiber automatisch generiert *) 
+BOOL VAR prop font;
+ 
+$hlc10$        std quality, 
+               std typeface:
+(* Treiber für Star LC-10 oder LC-10 Colour *) 
+(* Treiber automatisch generiert *) 
+BOOL VAR was tall font;
+ 
+$hdmp4000$     std speed:
+(* Treiber für Schneider DMP4000, automatisch generiert *)
+ 
+$hnx15$        std speed:
+(* Treiber für Star NX-15, ND-10, ND-15, NR-10 und NR-15 *)
+(* Treiber automatisch generiert *)
+ 
+$hmt230$       paper feed, 
+               std speed: 
+(* Treiber für Mannesmann-Tally MT 230 *) 
+(* Treiber automatisch generiert *) 
+ 
+$hmt340$       paper feed,
+               std speed:
+(* Treiber für Mannesmann-Tally MT 340 *) 
+(* Treiber automatisch generiert *) 
+BOOL VAR prop font := FALSE; 
+ 
+$h120d$        : 
+(* Treiber für Citizen 120-D *) 
+(* Treiber automatisch generiert *) 
+ 
+$hc310$        paper feed,
+               std speed:
+(* Treiber für C. Itoh C 310/315 CXP *) 
+(* Treiber automatisch generiert *) 
+
+$hci3500$      std speed: 
+(* Treiber für C. Itoh CI-3500 *) 
+(* Treiber automatisch generiert *) 
+ 
+$hdx2100$     paper feed,
+              std speed:
+(* Treiber für Fujitsu DX 2100 *)
+(* Treiber automatisch generiert *)
+BOOL VAR prop font := FALSE ;
+ 
+$decl$
+INT VAR blankbreite, x rest, y rest, high, low, small, modifikations;
+REAL VAR x size, y size, y margin;
+TEXT VAR buffer :: "";
+ 
+PROC paper size (REAL CONST x, y) :
+ 
+  x size := x;
+  y size := y;
+END PROC paper size;
+ 
+PROC paper size : 
+ 
+  line;
+  putline ("Papierbreite  =  " + text (x size, 5, 2) + " cm  =  " + text (x size / 2.54, 5, 2) + " Zoll");
+  putline ("Papierlaenge  =  " + text (y size, 5, 2) + " cm  =  " + text (y size / 2.54, 5, 2) + " Zoll");
+END PROC paper size;
+ 
+papersize (20.32, 30.48); 
+ 
+PROC top margin (REAL CONST margin): 
+ 
+  y margin := margin 
+END PROC top margin; 
+ 
+REAL PROC top margin:   y margin   END PROC top margin;
+ 
+top margin (0.0); 
+ 
+$speed$
+BOOL VAR is slow; 
+TEXT VAR std speed name :: "slow";
+ 
+PROC std speed (TEXT CONST speed) :
+ 
+  IF speed = "fast" OR speed = "slow"
+     THEN std speed name := speed
+     ELSE errorstop ("unzulässige Geschwindigkeit")
+  FI
+END PROC std speed;
+ 
+TEXT PROC std speed : std speed name END PROC std speed;
+ 
+$quality$ 
+TEXT VAR std quality name :: "draft";
+ 
+PROC std quality (TEXT CONST quality) :
+ 
+  IF quality = "nlq" OR quality = "draft"
+     THEN std quality name := quality
+     ELSE errorstop ("unzulässige Qualitätsbezeichnung")
+  FI
+END PROC std quality;
+ 
+TEXT PROC std quality : std quality name END PROC std quality;
+ 
+$typeface$ 
+TEXT VAR std typeface name :: "";
+ 
+PROC std typeface (TEXT CONST typeface) :
+ 
+  IF typeface = "" OR typeface = "roman" OR typeface = "sansserif"
+     THEN std typeface name := typeface
+     ELSE errorstop ("unzulässige Schriftart")
+  FI
+END PROC std typeface;
+ 
+TEXT PROC std typeface : std typeface name END PROC std typeface;
+ 
+$typeface292$ 
+TEXT VAR std typeface name :: "";
+ 
+PROC std typeface (TEXT CONST typeface) :
+ 
+  IF typeface = "" OR typeface = "courier" OR typeface = "sansserif"
+     THEN std typeface name := typeface
+     ELSE errorstop ("unzulässige Schriftart")
+  FI
+END PROC std typeface;
+ 
+TEXT PROC std typeface : std typeface name END PROC std typeface;
+ 
+$typefacelc10$ 
+TEXT VAR std typeface name :: "";
+ 
+PROC std typeface (TEXT CONST typeface) :
+ 
+  IF typeface = "" OR typeface = "courier" OR typeface = "sansserif" 
+                   OR typeface = "orator1" OR typeface = "orator2" 
+     THEN std typeface name := typeface
+     ELSE errorstop ("unzulässige Schriftart")
+  FI
+END PROC std typeface;
+ 
+TEXT PROC std typeface : std typeface name END PROC std typeface;
+ 
+$feed$ 
+TEXT VAR feeder name :: "tractor";
+ 
+PROC paper feed (TEXT CONST feeder) :
+ 
+  IF feeder = "sheet" OR feeder = "tractor"
+     THEN feeder name := feeder
+     ELSE errorstop ("unzulässige Einzugsart")
+  FI
+END PROC paper feed;
+ 
+TEXT PROC paper feed: feeder name END PROC paper feed;
+ 
+$feedschacht$
+TEXT VAR act feeder :: "", 
+         feeder name :: "tractor";
+ 
+PROC paper feed (TEXT CONST feeder) :
+ 
+  IF feeder = "tractor" OR feeder = "schacht1" OR feeder = "schacht2" 
+     THEN feeder name := feeder
+  ELIF feeder = "sheet" 
+     THEN feeder name := "schacht1" 
+     ELSE errorstop ("unzulässige Einzugsart")
+  FI
+END PROC paper feed;
+ 
+TEXT PROC paper feed: feeder name END PROC paper feed;
+ 
+$openh$
+PROC open (INT CONST op code, INT VAR param1, param2) :
+ 
+SELECT op code OF
+  CASE 1: open document 
+  CASE 2: open page
+END SELECT.
+ 
+$opendoch$
+  open document :
+    modifikations := 0; 
+    param 1 := x step conversion ( x size );
+    param 2 := y step conversion ( y size );
+$initspeed$ 
+    IF pos (material, "slow") <> 0 
+         THEN is slow := TRUE;
+    ELIF pos (material, "fast") <> 0 
+         THEN is slow := FALSE;
+         ELSE is slow := std speed name = "slow"
+    FI;
+$opendocfx85$ 
+    param 2 := (param 2 DIV 36) * 36;
+    out (""27""64""27""64"");              (* Reset des Druckers *)
+    out (""27"R"0""27"2"27"6");
+    out (""27"C" + code (param 2 DIV 36)). (* Formularlaenge *)
+ 
+$opendocfx800$ 
+    param 2 := (param 2 DIV 36) * 36;
+    was tall font := TRUE; 
+    out (""27""64""27""64"");              (* Reset des Druckers *)
+    out (""27"t"1""27"6");                 (* Zeichentabelle 4 (Grafik) *)
+    out (""27"R"0""27"9"27"O"27"2"); 
+    out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+    IF pos (material, "nlq") <> 0 
+      THEN out (""27"x"1"") 
+    ELIF pos (material, "draft") <> 0 
+      THEN out (""27"x"0"") 
+    ELIF std quality name = "nlq"
+      THEN out (""27"x"1"") 
+      ELSE out (""27"x"0"")
+    FI; 
+    IF pos (material, "roman") <> 0 
+         THEN out (""27"k"0"") 
+    ELIF pos (material, "sansserif") <> 0 
+         THEN out (""27"k"1"") 
+    ELIF std typeface name = "roman" 
+      THEN out (""27"k"0"") 
+    ELIF std typeface name = "sansserif" 
+      THEN out (""27"k"1"") 
+    FI. 
+ 
+$opendocmx$ 
+    param 2 := (param 2 DIV 36) * 36;
+    out (""27"R"0""27""64"");               (* Reset des Druckers *) 
+    out (""27"R"0""27"2");
+    out (""27"C" + code (param 2 DIV 36));  (* Formularlaenge *) 
+    out (""27"9"27"O").
+ 
+$opendocgp$ 
+    param 2 := (param 2 DIV 36) * 36;
+    out (""27"6");                               (* Zeichensatz 2 *)
+    out (""18""27"F"27"H"27"W"0""27"T"27"-"0""); (* Modifikationen rücksetzen *) 
+    out (""27"9"27"O"27"A"12""27"2"); 
+    out (""27"C" + code (param 2 DIV 36)).       (* Formularlaenge *)
+ 
+$opendocpp$ 
+    param 2 := (param 2 DIV 36) * 36;
+    out (""27"6");                               (* Zeichensatz 2 *)
+    out (""18""27"F"27"W"0""27"T"27"-"0"");      (* Modifikationen rücksetzen *) 
+    out (""27"9"27"O"27"A"12""27"2"); 
+    out (""27"C" + code (param 2 DIV 36));       (* Formularlaenge *)
+    IF pos (material, "nlq") <> 0 
+      THEN out (""27"G")
+    ELIF pos (material, "draft") <> 0 
+      THEN out (""27"H") 
+    ELIF std quality name = "nlq" 
+      THEN out (""27"G") 
+      ELSE out (""27"H") 
+    FI. 
+    
+$opendocml182i$ 
+    IF pos (material, "nlq") <> 0 
+      THEN out (""27"I3") 
+    ELIF pos (material, "draft") <> 0 
+      THEN out (""27"I1") 
+    ELIF std quality name = "nlq"
+      THEN out (""27"I3") 
+      ELSE out (""27"I1")
+    FI; 
+    out (""27"N"0"");           (* Kein Sprung über Perf. *)
+
+$opendocml192el$ 
+    param 2 := (param 2 DIV 36) * 36;
+    prop font := FALSE;
+    out (""27""64""27""64"");              (* Reset des Druckers *)
+    out (""27"R"0""27"2");
+    out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *) 
+    out (""27"6");                         (* Erweiterung des Zeichensatzes  *)
+    out (""27"9"27"O"27"x"0"").
+ 
+$opendocml292el$ 
+    param 2 := (param 2 DIV 36) * 36;
+    was tall font := TRUE; 
+    out (""27""64""27""64"");              (* Reset des Druckers *)
+    out (""27"t"1""27"6");                 (* Zeichentabelle 4 (Grafik) *)
+    out (""27"R"0""27"2");
+    out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+    out (""27"9"27"O"27"r0"); 
+    IF pos (material, "nlq") <> 0 
+      THEN out (""27"x"1"") 
+    ELIF pos (material, "draft") <> 0 
+      THEN out (""27"x"0"") 
+    ELIF std quality name = "nlq"
+      THEN out (""27"x"1"") 
+      ELSE out (""27"x"0"")
+    FI; 
+    IF pos (material, "courier") <> 0 
+         THEN out (""27"k"0"") 
+    ELIF pos (material, "sansserif") <> 0 
+         THEN out (""27"k"1"") 
+    ELIF std typeface name = "courier" 
+      THEN out (""27"k"0"") 
+    ELIF std typeface name = "sansserif" 
+      THEN out (""27"k"1"") 
+    FI. 
+ 
+$opendocml294i$ 
+    param 2 := (param 2 DIV 36) * 36;
+    out (""27"6");                               (* Zeichensatz 2 *)
+    out (""18""27"F"27"W0"27"T"27"-0"27"%H");    (* Modifikationen rücksetzen *) 
+    out (""27"9"27"O"27"A"12""27"2");
+    out (""27"C" + code (param 2 DIV 36));       (* Formularlaenge *)
+    IF pos (material, "nlq") <> 0 
+      THEN out (""27"G")
+    ELIF pos (material, "draft") <> 0 
+      THEN out (""27"H") 
+    ELIF std quality name = "nlq" 
+      THEN out (""27"G") 
+      ELSE out (""27"H") 
+    FI. 
+ 
+$opendocml320$ 
+    param 2 := (param 2 DIV 36) * 36;
+    prop font := FALSE;
+    out (""27"{"99""27"{"40"");            (* Umschaltung auf EPSON-Emulation *) 
+    out (""27""64""27""64"");              (* Reset des Druckers *)
+    out (""27"R"0""27"2");
+    out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *) 
+    out (""27"6");                         (* Erweiterung des Zeichensatzes  *)
+    out (""27"9"27"O"27"x"0"").
+ 
+$opendoclc10$ 
+    param 2 := (param 2 DIV 36) * 36;
+    was tall font := TRUE; 
+    out (""27""64""27""64"");              (* Reset des Druckers *)
+    out (""27"t"1""27"6");                 (* Zeichentabelle 4 (Grafik) *)
+    out (""27"R"0""27"2");
+    out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+    out (""27"9"27"r"0"");
+    IF pos (material, "nlq") <> 0 
+      THEN out (""27"x"1"") 
+    ELIF pos (material, "draft") <> 0 
+      THEN out (""27"x"0"") 
+    ELIF std quality name = "nlq"
+      THEN out (""27"x"1"") 
+      ELSE out (""27"x"0"")
+    FI; 
+    IF pos (material, "courier") <> 0 
+         THEN out (""27"k"0"") 
+    ELIF pos (material, "sansserif") <> 0 
+         THEN out (""27"k"1"") 
+    ELIF pos (material, "orator1") <> 0 
+         THEN out (""27"k"2"") 
+    ELIF pos (material, "orator2") <> 0 
+         THEN out (""27"k"3"") 
+    ELIF std typeface name = "courier" 
+      THEN out (""27"k"0"") 
+    ELIF std typeface name = "sansserif" 
+      THEN out (""27"k"1"") 
+    ELIF std typeface name = "orator1" 
+      THEN out (""27"k"2"") 
+    ELIF std typeface name = "orator2" 
+      THEN out (""27"k"3"") 
+    FI. 
+ 
+$opendocnx15$ 
+    param 2 := (param 2 DIV 36) * 36;
+    out (""27""64""27""64"");              (* Reset des Druckers *)
+    out (""27"R"0""27"2"); 
+    out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+    out (""27"6");                         (* Erweiterung des Zeichensatzes  *)
+    out (""27"9"27"x"0"").
+ 
+$opendocdmp4000$ 
+    param 2 := (param 2 DIV 36) * 36;
+    out (""27""64""27""64"");              (* Reset des Druckers *) 
+    out (""27"m"0""27"R"0""27"9"27"O"27"2"27"6");
+    out (""27"C" + code (param 2 DIV 36)). (* Formularlaenge *)
+ 
+$opendocmt$ 
+    param 2 := (param 2 DIV 36) * 36;
+    out (""27""64""27""64"");              (* Reset des Druckers *)
+    out (""27"R"0""27"2");
+    out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+    out (""27"O"27"x"0""27"r"0""27"6"); 
+    IF feeder name = "tractor" 
+      THEN act feeder := feeder name; 
+           out (""27"[5{") 
+      ELSE out (""27"[0{");
+           IF pos (material, "schacht1") <> 0 
+             THEN act feeder := "schacht1" 
+           ELIF pos (material, "schacht2") <> 0 
+             THEN act feeder := "schacht2" 
+             ELSE act feeder := feeder name 
+           FI 
+    FI.
+ 
+$opendocdx2100$
+param 2 := (param 2 DIV 36) * 36;
+out (""24""27""64"");                            (* Reset des Druckers *) 
+out (""27"R"0"");                                (* US-Zeichensatz *)
+out (""27"2" + ""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+out (""27"N"0"");                                (* skip perforation *)
+out (""27"x"0"" + ""27"r"0"").                   (* draft und black *)
+ 
+ 
+$opendoc120d$ 
+    param 2 := (param 2 DIV 36) * 36;
+    out (""27""64""27""64"");              (* Reset des Druckers *)
+    out (""27"R"0""27"9"27"O"27"x0"27"2");
+    out (""27"C" + code (param 2 DIV 36)). (* Formularlaenge *)
+
+$opendocc310$ 
+    param 2 := (param 2 DIV 36) * 36;
+    out (""27""64""27""64"");              (* Reset des Druckers *)
+    out (""27"R"0""27"2");
+    out (""27"C" + code (param 2 DIV 36)); (* Formularlaenge *)
+    out (""27"O"27"x"0""27"r"0""27"6"); 
+    IF feeder name = "tractor" 
+      THEN act feeder := feeder name; 
+      ELSE IF pos (material, "schacht1") <> 0 
+             THEN act feeder := "schacht1" 
+           ELIF pos (material, "schacht2") <> 0 
+             THEN act feeder := "schacht2" 
+             ELSE act feeder := feeder name 
+           FI 
+    FI.
+ 
+$openpge$
+  open page :
+    param 1 := 0;
+    param 2 := y step conversion (y margin);
+    x rest  := 0;
+    y rest  := 0;
+    small   := 0;
+    out (""13"").
+$openpgemlsf$ 
+  open page :
+    param 1 := 0;
+    param 2 := 0;
+    x rest  := 0;
+    y rest  := 0;
+    small   := 0;
+    IF feeder name = "sheet" THEN out (""12"") FI; 
+    out (""13"").
+$openpgemtsf$ 
+  open page :
+    param 1 := 0;
+    param 2 := 0;
+    x rest  := 0;
+    y rest  := 0;
+    small   := 0;
+    IF feeder name = "schacht1" 
+      THEN out (""27"[21{"12"") 
+    ELIF feeder name = "schacht2" 
+      THEN out (""27"[22{"12"") 
+    FI; 
+    out (""13"").
+  
+$openpgec310sf$ 
+  open page :
+    param 1 := 0;
+    param 2 := 0;
+    x rest  := 0;
+    y rest  := 0;
+    small   := 0;
+    IF feeder name = "schacht1" 
+      THEN out (""27""25"1"12"") 
+    ELIF feeder name = "schacht2" 
+      THEN out (""27""25"2"12"") 
+    FI; 
+    out (""13"").
+  
+$betwoc$
+END PROC open; 
+ 
+PROC close (INT CONST op code, INT CONST param1) :
+ 
+SELECT op code OF
+  CASE 1: close document 
+  CASE 2: close page
+END SELECT.
+close document : 
+$clpge$
+. close page :
+    IF param 1 > 0 THEN out (""12"") FI.
+$clmlsf$ 
+.close page :
+  IF feeder name = "sheet" 
+    THEN out (""27""25""3"") 
+  ELIF param 1 > 0 
+    THEN out (""12"") 
+  FI. 
+$clmtsf$ 
+.close page :
+  IF feeder name <> "tractor" 
+    THEN out (""27"[2J") 
+  ELIF param 1 > 0 
+    THEN out (""12"") 
+  FI.
+$clc310sf$ 
+.close page :
+  IF feeder name = "sheet" 
+    THEN out (""27""25"R") 
+  ELIF param 1 > 0 
+    THEN out (""12"") 
+  FI. 
+ 
+$betwce$
+END PROC close;
+ 
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+ 
+SELECT op code OF
+  CASE 1:  write text
+  CASE 2:  write cmd
+  CASE 3:  carriage return
+  CASE 4:  move
+  CASE 5:  draw
+  CASE 6:  on
+  CASE 7:  off
+  CASE 8:  type
+END SELECT.
+
+is underline: bit (modifikations, 0).
+is bold     : bit (modifikations, 1). 
+is italics  : bit (modifikations, 2). 
+ 
+  write text :
+    out subtext (string, param 1, param 2).
+$cmd$ 
+  write cmd :
+    out subtext (string, param 1, param 2). 
+$cmdfx800$ 
+  write cmd :
+    buffer := subtext (string, param 1, param 2); 
+    IF buffer = "draft" 
+      THEN out (""27"x"0"") 
+    ELIF buffer = "nlq"
+      THEN out (""27"x"1"") 
+    ELIF buffer = "roman" 
+      THEN out (""27"k"0"") 
+    ELIF buffer = "sansserif" 
+      THEN out (""27"k"1"") 
+      ELSE out (buffer) 
+    FI. 
+$cmdpp$ 
+  write cmd :
+    buffer := subtext (string, param 1, param 2); 
+    IF buffer = "draft" 
+      THEN out (""27"H")
+    ELIF buffer = "nlq"
+      THEN out (""27"G") 
+      ELSE out (buffer) 
+    FI. 
+$cmdml182i$ 
+  write cmd :
+    buffer := subtext (string, param 1, param 2); 
+    IF buffer = "draft" 
+      THEN out (""27"I1") 
+    ELIF buffer = "nlq"
+      THEN out (""27"I3") 
+      ELSE out (buffer) 
+    FI. 
+$cmdml292el$ 
+  write cmd :
+    buffer := subtext (string, param 1, param 2); 
+    IF buffer = "draft" 
+      THEN out (""27"x"0"") 
+    ELIF buffer = "nlq"
+      THEN out (""27"x"1"") 
+    ELIF buffer = "courier" 
+      THEN out (""27"k"0"") 
+    ELIF buffer = "sansserif" 
+      THEN out (""27"k"1"") 
+    ELIF buffer = "schwarz" 
+      THEN out (""27"r0")
+    ELIF buffer = "rot" 
+      THEN out (""27"r1")
+    ELIF buffer = "blau" 
+      THEN out (""27"r2")
+    ELIF buffer = "violett" 
+      THEN out (""27"r3")
+    ELIF buffer = "gelb" 
+      THEN out (""27"r4")
+    ELIF buffer = "orange" 
+      THEN out (""27"r5")
+    ELIF buffer = "grün" 
+      THEN out (""27"r6")
+      ELSE out (buffer) 
+    FI. 
+$cmdml294i$ 
+  write cmd :
+    buffer := subtext (string, param 1, param 2); 
+    IF buffer = "draft" 
+      THEN out (""27"H") 
+    ELIF buffer = "nlq"
+      THEN out (""27"G") 
+    ELIF buffer = "schwarz" 
+      THEN out (""27"r0")
+    ELIF buffer = "rot" 
+      THEN out (""27"r1")
+    ELIF buffer = "blau" 
+      THEN out (""27"r2")
+    ELIF buffer = "violett" 
+      THEN out (""27"r3")
+    ELIF buffer = "gelb" 
+      THEN out (""27"r4")
+    ELIF buffer = "orange" 
+      THEN out (""27"r5")
+    ELIF buffer = "grün" 
+      THEN out (""27"r6")
+      ELSE out (buffer) 
+    FI. 
+$cmdlc10$ 
+  write cmd :
+    buffer := subtext (string, param 1, param 2); 
+    IF buffer = "draft" 
+      THEN out (""27"x"0"") 
+    ELIF buffer = "nlq"
+      THEN out (""27"x"1"") 
+    ELIF buffer = "courier" 
+      THEN out (""27"k"0"") 
+    ELIF buffer = "sansserif" 
+      THEN out (""27"k"1"") 
+    ELIF buffer = "orator1" 
+      THEN out (""27"k"2"") 
+    ELIF buffer = "orator2" 
+      THEN out (""27"k"3"") 
+    ELIF buffer = "schwarz" 
+      THEN out (""27"r"0"")
+    ELIF buffer = "rot" 
+      THEN out (""27"r"1"")
+    ELIF buffer = "blau" 
+      THEN out (""27"r"2"")
+    ELIF buffer = "violett" 
+      THEN out (""27"r"3"")
+    ELIF buffer = "gelb" 
+      THEN out (""27"r"4"")
+    ELIF buffer = "orange" 
+      THEN out (""27"r"5"")
+    ELIF buffer = "grün" 
+      THEN out (""27"r"6"")
+      ELSE out (buffer) 
+    FI. 
+$cmdmt230$ 
+  write cmd :
+    buffer := subtext (string, param 1, param 2); 
+    IF feeder name <> "tractor" 
+      THEN IF buffer = "schacht1" OR buffer = "schacht2" 
+             THEN act feeder := buffer 
+           FI 
+    ELIF buffer = "schwarz" 
+      THEN out (""27"r"0"")
+    ELIF buffer = "magenta" 
+      THEN out (""27"r"1"")
+    ELIF buffer = "cyan" 
+      THEN out (""27"r"2"")
+    ELIF buffer = "blau" 
+      THEN out (""27"r"3"")
+    ELIF buffer = "gelb" 
+      THEN out (""27"r"4"")
+    ELIF buffer = "rot" 
+      THEN out (""27"r"5"")
+    ELIF buffer = "grün" 
+      THEN out (""27"r"6"")
+      ELSE out (buffer) 
+    FI. 
+ 
+$cmdc310$ 
+  write cmd :
+    buffer := subtext (string, param 1, param 2); 
+    IF feeder name <> "tractor" 
+      THEN IF buffer = "schacht1" OR buffer = "schacht2" 
+             THEN act feeder := buffer 
+           FI 
+    ELIF buffer = "schwarz" 
+      THEN out (""27"r"0"")
+    ELIF buffer = "rot" 
+      THEN out (""27"r"1"")
+    ELIF buffer = "blau" 
+      THEN out (""27"r"2"")
+    ELIF buffer = "violett" 
+      THEN out (""27"r"3"")
+    ELIF buffer = "gelb" 
+      THEN out (""27"r"4"")
+    ELIF buffer = "orange" 
+      THEN out (""27"r"5"")
+    ELIF buffer = "grün" 
+      THEN out (""27"r"6"")
+      ELSE out (buffer) 
+    FI. 
+ 
+$cmddx2100$ 
+   write cmd :
+     buffer := subtext (string, param 1, param 2); 
+     IF buffer = "schwarz"
+       THEN out (""27"r"0"")
+     ELIF buffer = "rot"
+       THEN out (""27"r"1"")
+     ELIF buffer = "blau"
+       THEN out (""27"r"2"")
+     ELIF buffer = "violett"
+       THEN out (""27"r"3"")
+     ELIF buffer = "gelb"
+       THEN out (""27"r"4"")
+     ELIF buffer = "orange"
+       THEN out (""27"r"5"")
+     ELIF buffer = "grün"
+       THEN out (""27"r"6"")
+     ELSE out (buffer)
+     FI.
+ 
+$crs$
+  carriage return :
+    y rest INCR small;
+    x rest := 0;
+    small  := 0;
+    out (""13"").
+$moh$ 
+x steps : param1.
+y steps : param2.
+
+move :
+  IF x steps < 0 OR y steps < 0 THEN stop FI; 
+  IF x steps > 0 THEN x move FI; 
+  IF y steps > 0 THEN y move FI. 
+
+$mofx85$ 
+x move :
+  high   := (x steps + x rest) DIV blankbreite;
+  x rest := (x steps + x rest) MOD blankbreite;
+  IF high   > 0 THEN high TIMESOUT " " FI;
+  IF x rest > 0 AND is slow
+     THEN IF is underline THEN out (" "8"") FI;
+          out (""27"Y"+ code (x rest) + ""0"");
+          x rest TIMESOUT ""0"";
+          x rest := 0
+  FI. 
+ 
+ 
+$mofx800$
+x move :
+  IF is underline
+    THEN underline x move
+    ELSE simple x move
+  FI. 
+ 
+underline x move: 
+  high   := (x steps + x rest) DIV blankbreite;
+  low    := (x steps + x rest) MOD blankbreite;
+  IF high > 0 THEN high TIMESOUT " " FI;
+  IF low > 0
+     THEN out (" "8""27"\"+ code (low) + ""0"")
+  FI. 
+ 
+simple x move:
+  out (""27"\");
+  out (code (x steps MOD 256));
+  out (code (x steps DIV 256)). 
+ 
+$modrmx$ 
+x move :
+  high := (x steps + x rest) DIV blankbreite;
+  low  := (x steps + x rest) MOD blankbreite;
+  IF high > 0 THEN high TIMESOUT " " FI;
+  IF low  > 0 AND is slow
+     THEN IF is underline THEN out ("_"8"") FI;
+          IF is condensed 
+             THEN high := low;
+                  low  := 0;
+                  out (""27"L"+ code (high) + ""0"");
+             ELSE high := low DIV 2;
+                  low  := low MOD 2;
+                  out (""27"K"+ code (high) + ""0"");
+          FI;
+          high TIMESOUT ""0"";
+          IF is small
+             THEN out (""27"S"1"");
+                  small DECR 1;
+          FI;
+  FI;
+  x rest := low. 
+ 
+y move : 
+  y rest INCR y steps;
+  IF y rest > 0
+     THEN high := y rest DIV 255;
+          low  := y rest MOD 255;
+          IF high > 0 THEN high TIMESOUT ""27"J"255""      FI;
+          IF low  > 0 THEN out (""27"J"); out (code (low)) FI;
+          y rest := 0
+  FI. 
+ 
+draw :
+  IF x steps < 0 OR y steps <> 0 OR linetype <> 1 
+    THEN stop
+  ELIF x steps > 0
+    THEN x draw
+  FI. 
+ 
+x draw :
+  out (""27"L");
+  out (code (x steps MOD 256));
+  out (code (x steps DIV 256));
+  x steps TIMESOUT ""1"";
+  IF is small THEN out (""27"S"1"") FI. 
+ 
+$mogp$ 
+x move :
+  high   := (x steps + x rest) DIV blankbreite;
+  x rest := (x steps + x rest) MOD blankbreite;
+  IF high   > 0 THEN high TIMESOUT " " FI;
+  IF x rest > 0 AND is slow
+     THEN IF is underline 
+            THEN out (" "13""27"Y"); 
+                 out (code (x pos MOD 256)); 
+                 out (code (x pos DIV 256)); 
+                 x pos TIMESOUT ""0"" 
+            ELSE out (""27"Y"+ code (x rest) + ""0"");
+                 x rest TIMESOUT ""0"" 
+          FI;
+          x rest := 0 
+  FI. 
+ 
+$moml192el$ 
+x move :
+  high   := (x steps + x rest) DIV blankbreite;
+  x rest := (x steps + x rest) MOD blankbreite;
+  IF high   > 0 THEN high TIMESOUT " " FI;
+  IF x rest > 0 AND is slow
+    THEN  IF is underline THEN 
+             IF prop font THEN 
+               out (""27"p"0"" + " "8"" + ""27"p"1"") 
+             ELSE 
+               out (" "8"") 
+             FI; 
+          FI;
+          out (""27"Y"+ code (x rest) + ""0"");
+          x rest TIMESOUT ""0"";
+          x rest := 0
+  FI.
+ 
+$ymodr$ 
+y move : 
+  y rest INCR y steps;
+  IF y rest > 0
+    THEN high := y rest DIV 255;
+         low  := y rest MOD 255;
+         IF high > 0 THEN high TIMESOUT ""27"J"255""      FI;
+         IF low  > 0 THEN out (""27"J"); out (code (low)) FI;
+         y rest := 0 
+  FI.
+ 
+draw :
+  IF x steps < 0 OR y steps <> 0 OR linetype <> 1 
+    THEN stop
+  ELIF x steps > 0
+    THEN x draw
+  FI. 
+ 
+x draw :
+  out (""27"Y");
+  out (code (x steps MOD 256));
+  out (code (x steps DIV 256));
+  x steps TIMESOUT ""1"".
+ 
+$onoff$              
+  on :
+    IF on string (param 1) <> ""
+       THEN out (on string (param 1));
+            modifikations := modifikations OR param 1
+       ELSE stop
+    FI. 
+ 
+  off :
+    IF off string (param 1) <> ""
+       THEN out (off string (param 1));
+            modifikations := modifikations AND (param 1 XOR -1) 
+       ELSE stop
+    FI.
+ 
+$onoffpp$              
+  on :
+    IF on string (param 1) <> "" AND param 1 <> 2
+       THEN out (on string (param 1));
+            modifikations := modifikations OR param 1
+       ELSE stop
+    FI. 
+ 
+  off :
+    IF off string (param 1) <> "" AND param 1 <> 2 
+       THEN out (off string (param 1));
+            modifikations := modifikations AND (param 1 XOR -1) 
+       ELSE stop
+    FI.
+ 
+$tyfx85$ 
+  type :
+    buffer := font string (param 1);
+    out (buffer);
+    restore modifikations; 
+    blankbreite  := char pitch (param 1, " ");
+    IF pos (buffer, ""27"S") <> 0 THEN small DECR 1 FI.  
+
+$tyfx800$ 
+ type :
+    buffer := font string (param 1);
+    IF was tall font 
+      THEN out (""27"w"0"") 
+    FI; 
+    out (buffer);
+    restore modifikations;
+    blankbreite  := char pitch (param 1, " "); 
+    was tall font := pos (buffer, ""27"w"1"") <> 0.
+
+$tymx$ 
+  type :
+    buffer := font string (param 1);
+    blankbreite  := char pitch (param 1, " ");
+    is condensed := pos (buffer, ""15"") <> 0;
+    IF pos (buffer, ""27"S") <> 0 
+       THEN small DECR 1;
+            is small := TRUE;
+       ELSE is small := FALSE;
+    FI;
+    out (buffer);
+    restore modifikations.
+
+$tyohnesmall$
+ type :
+    buffer := font string (param 1);
+    out (buffer);
+    restore modifikations;
+    blankbreite  := char pitch (param 1, " ").
+
+$tyml192el$ 
+  type :
+    buffer := font string (param 1);
+    out (buffer);
+    restore modifikations; 
+    blankbreite  := char pitch (param 1, " ");
+    prop font    := pos (buffer, ""27"p"1"") <> 0;
+    IF pos (buffer, ""27"S") <> 0 THEN small DECR 1 FI.
+
+$tyml292el$ 
+  type :
+    buffer := font string (param 1);
+    IF was tall font 
+      THEN out (""27""31"0"27"U0") 
+    FI; 
+    was tall font := pos (buffer, ""27"w"1"") <> 0;
+    change all (buffer, ""27"w"0"", ""27""31"0"27"U0"); 
+    change all (buffer, ""27"w"1"", ""27""31"1"27"U1"); 
+    out (buffer);
+    restore modifikations; 
+    blankbreite  := char pitch (param 1, " ").
+ 
+$ontyml294i$ 
+  on :
+    IF on string (param 1) <> "" AND param 1 <> 2 
+       THEN out (on string (param 1));
+            modifikations := modifikations OR param 1 
+    ELIF param 1 = 4
+       THEN out (""27"%G"); 
+            modifikations := modifikations OR param 1 
+       ELSE stop
+    FI. 
+ 
+  off :
+    IF off string (param 1) <> "" AND param 1 <> 2
+       THEN out (off string (param 1));
+            modifikations := modifikations AND (param 1 XOR -1) 
+    ELIF param 1 = 4 
+       THEN out (""27"%H"); 
+            modifikations := modifikations AND (param 1 XOR -1) 
+       ELSE stop
+    FI.
+ 
+  type :
+    buffer := font string (param 1);
+    out (buffer);
+    IF is underline THEN out (on string (1)) FI; 
+    IF is bold      THEN out (on string (2)) FI; 
+    IF is italics   THEN out (""27"%G") FI;
+    blankbreite  := char pitch (param 1, " ");
+    IF pos (buffer, ""27"S") <> 0 THEN small DECR 1 FI.
+
+$end$
+  restore modifikations: 
+    IF is underline THEN out (on string (1)) FI; 
+    IF is bold      THEN out (on string (2)) FI; 
+    IF is italics   THEN out (on string (4)) FI. 
+ 
+END PROC execute;
+
+INT VAR reply; DATASPACE VAR ds; FILE VAR file;
+ 
+PROC printer:
+ 
+  disable stop;
+  continue (server channel);
+  check error (error message);
+  ds := nilspace;
+  REP forget (ds);
+      execute print;
+      IF is error AND online THEN put error; clear error; FI;
+  PER;
+END PROC printer;
+ 
+PROC execute print:
+ 
+  LET ack = 0, fetch code = 11, file type = 1003;
+  enable stop;
+  ds := nilspace;
+  call (father, fetch code, ds, reply);
+  IF reply = ack CAND type (ds) = file type
+     THEN file := sequential file (input, 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);
+  FI;
+END PROC execute print;
+ 
+PROC check error(TEXT CONST message):
+ 
+  IF is error
+     THEN clear error; rename myself (message);
+          IF is error THEN end(myself) FI;
+          pause (9000); end(myself);
+  FI;
+END PROC check error;
+ 
+END PACKET printerdriver
+ 
+
diff --git a/printer/dotmatrix9/printer.neun.nadel b/printer/dotmatrix9/printer.neun.nadel
new file mode 100644
index 0000000..00f698b
--- /dev/null
+++ b/printer/dotmatrix9/printer.neun.nadel
@@ -0,0 +1,1129 @@
+PACKET driver inst 9                         (* Autoren : mov/hjh     *) 
+                                             (* Stand   : 01.10.88    *) 
+ 
+       DEFINES druckerkanal, 
+               treiber einrichten: 
+ 
+ 
+LET up = ""3""13""5"", 
+ 
+    generator name = "printer.neun.nadel", 
+ 
+    description file name = "beschreibungen9", 
+    module file name = "module9"; 
+ 
+ 
+INT VAR pr channel, 
+        positioning,
+        quality,
+        sheet feeder, 
+        service option; 
+TEXT VAR fonttab name :: "", 
+         driver name :: ""; 
+TEXT VAR inp; 
+BOOL VAR was esc; 
+ 
+ 
+PROC druckerkanal (INT CONST channel) :
+ 
+  serverchannel (channel)
+ 
+END PROC druckerkanal; 
+ 
+INT PROC druckerkanal : pr channel END PROC druckerkanal; 
+ 
+ 
+PROC treiber einrichten:
+
+  treiber einrichten (0)
+END PROC treiber einrichten;
+
+PROC treiber einrichten (INT CONST service opt): 
+ 
+  ask for print channel; 
+  main menu; 
+  IF installed 
+    THEN generate printer spool 
+    ELSE inform about restart 
+  FI. 
+ 
+  ask for printchannel: 
+    inits; 
+    page; 
+    headline ("Druckerkanal - Einstellung"); 
+    cursor (1, 15); 
+    putline ("Hinweis: Die Druckerkanalnummer kann auch nachträglich mit"); 
+    putline ("         'druckerkanal (Kanalnummer)' in der Task """ + 
+             name (myself) + """"); 
+    putline ("         verändert werden."); 
+    REP 
+      cursor (1, 10);
+      put (""5"EUMEL-Kanalnummer des Druckerkanals:");
+      get (pr channel);
+      disable stop; 
+      druckerkanal (pr channel);
+      BOOL VAR no error :: NOT is error; 
+      IF is error 
+        THEN cursor (1, 7); 
+             put error;
+             putline ("Eingabe korrigiert wiederholen!") 
+      FI; 
+      clear error; 
+      enable stop 
+    UNTIL no error PER. 
+ 
+  inits: 
+    line; 
+    IF single task 
+      THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL") 
+    FI; 
+    command dialogue (TRUE);
+    IF name (myself) <> "PRINTER" 
+      THEN putline ("Diese Task heißt nicht ""PRINTER"", sondern """ + 
+                    name (myself) + """ !"); 
+           IF yes ("Soll die Task in ""PRINTER"" umbenannt werden ?") 
+             THEN rename myself ("PRINTER") 
+           FI 
+    FI; 
+    INT VAR choice;
+    service option := service opt.
+ 
+  single task:  (pcb (9) AND 255) = 1.
+ 
+  main menu: 
+    BOOL VAR installed :: FALSE; 
+    REP 
+      show main menu; 
+      get choice; 
+      treat choice 
+    UNTIL was esc OR installed PER. 
+ 
+  show main menu: 
+    page; 
+    headline ("Hauptmenü 9-Nadel-Drucker"); 
+    putline (" 1. Brother");
+    putline (" 2. Citizen");
+    putline (" 3. C. Itoh");
+    putline (" 4. Epson");
+    putline (" 5. Fujitsu");
+    putline (" 6. IBM"); 
+    putline (" 7. Mannesmann - Tally");
+    putline (" 8. OKI");
+    putline (" 9. Schneider");
+    putline ("10. Star").
+
+  get choice: 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Installation abbrechen"); 
+    ask user (10).
+ 
+  treat choice: 
+    SELECT int (inp) OF 
+      CASE 1: brother menu 
+      CASE 2: citizen menu 
+      CASE 3: c itoh menu 
+      CASE 4: epson menu 
+      CASE 5: fujitsu menu 
+      CASE 6: ibm menu 
+      CASE 7: mannesmann menu 
+      CASE 8: oki menu 
+      CASE 9: schneider menu 
+      CASE 10: star menu 
+    END SELECT. 
+ 
+  
+  brother menu:. 
+
+  citizen menu: 
+    page; 
+    headline ("Citizen - Menü"); 
+    putline (" 1. 120-D"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (1); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           citi120d inst 
+    FI. 
+ 
+    citi120d inst: 
+      putline ("Citizen 120-D"); 
+      line; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("S1    S2    S3    S4    S5    S6    S7    S8");
+      putline ("egal  OFF   OFF   egal  egal  egal  egal  egal"); 
+      show control options (""); 
+      IF all right 
+        THEN get fonttable ("fonttab.7");
+             generate ("citi120d"); 
+             installed := TRUE 
+      FI.
+  
+  c itoh menu:
+    page; 
+    headline ("C. Itoh - Menü"); 
+    putline (" 1. C 310 CXP"); 
+    putline (" 2. C 315 CXP"); 
+    putline (" 3. CI-3500");
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (3); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           IF choice = 3 
+             THEN ci3500 inst 
+             ELSE c310 inst 
+           FI 
+    FI. 
+ 
+    c310 inst: 
+      IF choice = 1 
+        THEN putline ("C. Itoh C 310 CXP") 
+        ELSE putline ("C. Itoh C 315 CXP") 
+      FI; 
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):"); 
+      putline ("- 00: Epson-Modus (02)"); 
+      putline ("- 22: nur Wagenrücklauf (01)");
+      show control options ("std speed, paperfeed"); 
+      show material options ("slow, fast, schacht1, schacht2");
+      show command options ("schacht1, schacht2,  schwarz, rot, blau, violett, gelb, orange, grün"); 
+      ask for positioning;
+      ask for paper feed; 
+      IF all right 
+        THEN get fonttable ("fonttab.7.cxp"); 
+             generate ("citohc310cxp"); 
+             adjust positioning;
+             adjust paper feed; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI. 
+  
+    ci3500 inst: 
+      putline ("C. Itoh CI-3500"); 
+      line; 
+      putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):"); 
+      putline ("- 26: nur Wagenrücklauf (1)"); 
+      putline ("- 49: 17,1 Zeichen pro Zoll (17)");
+      show control options ("std speed"); 
+      show material options ("slow, fast"); 
+      ask for positioning; 
+      IF all right 
+        THEN get fonttable ("fonttab.10");
+             generate ("citohci3500"); 
+             adjust positioning; 
+             installed := TRUE 
+      FI.
+  
+  epson menu: 
+    page; 
+    headline ("Epson - Menü"); 
+    putline (" 1. MX 80 Typ III"); 
+    putline (" 2. MX 100 Typ III"); 
+    putline (" 3. LX 800"); 
+    putline (" 4. LX 1000"); 
+    putline (" 5. FX 85"); 
+    putline (" 6. FX 105"); 
+    putline (" 7. FX 800 oder FX 850"); 
+    putline (" 8. FX 1000 oder FX 1050"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (8); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           SELECT choice OF 
+             CASE 1, 2: mx80 inst
+             CASE 3, 4: lx800 inst
+             CASE 5, 6: fx85 inst
+             CASE 7, 8: fx800 inst 
+           END SELECT
+    FI. 
+ 
+    mx80 inst: 
+      IF choice = 1 
+        THEN putline ("Epson MX 80 Typ III") 
+        ELSE putline ("Epson MX 100 Typ III") 
+      FI; 
+      show control options ("std speed"); 
+      show material options ("slow, fast"); 
+      ask for positioning; 
+      IF all right 
+        THEN get fonttable ("fonttab.1");
+             generate ("mx"); 
+             adjust positioning; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+    lx800 inst:
+      IF choice = 3 
+        THEN putline ("Epson LX 800") 
+        ELSE putline ("Epson LX 1000") 
+      FI; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8   SW2-1 SW2-2 SW2-3 SW2-4"); 
+      putline ("egal  egal  egal  egal  egal  egal  egal  egal    egal  *)    OFF   OFF"); 
+      putline ("*) ON: Einzelblatteinzug, OFF: kein Einzug"); 
+      show control options ("std speed, std quality, std typeface"); 
+      show material options ("slow, fast, draft, nlq, roman, sansserif"); 
+      show command options ("draft, nlq, roman, sansserif"); 
+      ask for positioning; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.20.lx"); 
+             generate ("lx800"); 
+             adjust positioning; 
+             adjust quality; 
+             IF choice = 4 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI. 
+ 
+    fx85 inst: 
+      IF choice = 5 
+        THEN putline ("Epson FX 85") 
+        ELSE putline ("Epson FX 105") 
+      FI; 
+      line; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8   SW2-1 SW2-2 SW2-3 SW2-4"); 
+      putline ("egal  egal  egal  ON    egal  egal  egal  egal    egal  egal  OFF   OFF"); 
+      show control options ("std speed"); 
+      show material options ("slow, fast"); 
+      ask for positioning; 
+      IF all right 
+        THEN get fonttable ("fonttab.7"); 
+             generate ("fx85"); 
+             adjust positioning; 
+             IF choice = 6 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+    fx800 inst: 
+      IF choice = 7 
+        THEN putline ("Epson FX 800 oder FX 850") 
+        ELSE putline ("Epson FX 1000 oder FX 1050") 
+      FI; 
+      line; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8   SW2-1 SW2-2 SW2-3 SW2-4"); 
+      putline ("egal  egal  egal  ON    egal  egal  egal  egal    egal  *)    OFF   OFF"); 
+      putline ("*) ON: Einzelblatteinzug, OFF: kein Einzug"); 
+      show control options ("std quality, std typeface"); 
+      show material options ("draft, nlq, roman, sansserif"); 
+      show command options ("draft, nlq, roman, sansserif"); 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.20"); 
+             generate ("fx800"); 
+             adjust quality; 
+             IF choice = 8 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI. 
+ 
+  fujitsu menu: 
+    page; 
+    headline ("Fujitsu - Menü"); 
+    putline (" 1. DX 2100"); 
+    putline (" 2. DX 2200"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (2); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           SELECT choice OF 
+             CASE 1,2   : dx2100 inst
+           END SELECT
+    FI. 
+
+    dx2100 inst: 
+      IF choice = 1 
+        THEN putline ("Fujitsu DX 2100") 
+        ELSE putline ("Fujitsu DX 2200") 
+      FI; 
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("SW1-1 SW1-2 SW1-3 SW1-4 SW1-5 SW1-6 SW1-7 SW1-8   SW2-1 SW2-2 SW2-3 SW2-4"); 
+      putline ("egal  egal  egal  egal  egal  egal  egal  egal    egal  *)    OFF   OFF"); 
+      putline ("*) ON: Einzelblatteinzug, OFF: kein Einzug"); 
+      show control options ("std speed, paper feed"); 
+      show material options ("slow, fast"); 
+      show command options ("schwarz, rot, blau, violett, gelb, rot, grün"); 
+      ask for positioning; 
+      ask for paper feed; 
+      IF all right 
+        THEN get fonttable ("fonttab.7.fuj"); 
+             generate ("fujdx2100"); 
+             adjust positioning; 
+             adjust paper feed; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI. 
+ 
+ 
+ 
+  ibm menu: 
+    page; 
+    headline ("IBM - Menü"); 
+    putline (" 1. Grafikdrucker (""80 Zeichen breit"")"); 
+    putline (" 2. Grafikdrucker (""136 Zeichen breit"")"); 
+    putline (" 3. Proprinter/Grafikdrucker II (""80 Zeichen breit"")"); 
+    putline (" 4. Proprinter/Grafikdrucker II (""136 Zeichen breit"")"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (4); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           IF choice = 1 OR choice = 2
+             THEN ibmgp inst
+             ELSE ibmpp inst 
+           FI 
+    FI. 
+ 
+    ibmgp inst: 
+      IF choice = 1 
+        THEN putline ("IBM Grafikdrucker (""80 Zeichen breit"")") 
+        ELSE putline ("IBM Grafikdrucker (""136 Zeichen breit"")") 
+      FI; 
+      show control options ("std speed"); 
+      show material options ("slow, fast"); 
+      ask for positioning; 
+      IF all right 
+        THEN get fonttable ("fonttab.10");
+             generate ("ibmgp"); 
+             adjust positioning; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+
+    ibmpp inst:
+      IF choice = 3 
+        THEN putline ("IBM Proprinter/Grafikdrucker II (""80 Zeichen breit"")") 
+        ELSE putline ("IBM Proprinter/Grafikdrucker II (""136 Zeichen breit"")") 
+      FI; 
+      show control options ("std speed, std quality"); 
+      show material options ("slow, fast, draft, nlq"); 
+      show command options ("draft, nlq");
+      ask for positioning; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.10"); 
+             generate ("ibmpp"); 
+             adjust positioning; 
+             adjust quality;
+             IF choice = 4 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+  mannesmann menu: 
+    page; 
+    headline ("Mannesmann - Tally - Menü"); 
+    putline (" 1. MT 230"); 
+    putline (" 2. MT 340"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (2); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           IF choice = 1  
+             THEN mt230 inst
+             ELSE mt340 inst 
+           FI
+    FI. 
+ 
+    mt230 inst:
+      putline ("Mannesmann-Tally MT 230"); 
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Der Drucker muß auf den ANSI+EPSON - Modus eingestellt werden.");
+      putline ("(Siehe: MT 230 Anwenderhandbuch, S. 4-145)"); 
+      show control options ("std speed, paperfeed"); 
+      show material options ("slow, fast, schacht1, schacht2");
+      show command options ("schacht1, schacht2,  schwarz, magenta, cyan, blau, gelb, rot, grün"); 
+      ask for positioning;
+      ask for paper feed; 
+      IF all right 
+        THEN get fonttable ("fonttab.7"); 
+             generate ("mt230"); 
+             adjust positioning;
+             adjust paper feed; 
+             do ("papersize (39.37, 30.48)"); 
+             installed := TRUE 
+      FI. 
+  
+    mt340 inst:
+      putline ("Mannesmann-Tally MT 340"); 
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Der Drucker muß auf den ANSI+EPSON - Modus eingestellt werden.");
+      putline ("(Siehe: MT 340 Anwenderhandbuch, S. 4-104)"); 
+      show control options ("std speed, paperfeed"); 
+      show material options ("slow, fast, schacht1, schacht2");
+      show command options ("schacht1, schacht2,  schwarz, magenta, cyan, blau, gelb, rot, grün"); 
+      ask for positioning;
+      ask for paper feed; 
+      IF all right 
+        THEN get fonttable ("fonttab.7.mt"); 
+             generate ("mt340"); 
+             adjust positioning;
+             adjust paper feed; 
+             do ("papersize (39.37, 30.48)"); 
+             installed := TRUE 
+      FI. 
+
+  oki menu: 
+    page; 
+    headline ("OKI - Menü"); 
+    putline (" 1. MICROLINE 182 IBM-kompatibel"); 
+    putline (" 2. MICROLINE 183 IBM-kompatibel"); 
+    putline (" 3. MICROLINE 192 ELITE");
+    putline (" 4. MICROLINE 193 ELITE"); 
+    putline (" 5. MICROLINE 292 ELITE");
+    putline (" 6. MICROLINE 293 ELITE"); 
+    putline (" 7. MICROLINE 294 IBM-kompatibel"); 
+    putline (" 8. MICROLINE 320"); 
+    putline (" 9. MICROLINE 321"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (9); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           SELECT choice OF 
+             CASE 1, 2: ml182i inst
+             CASE 3, 4: ml192el inst 
+             CASE 5, 6: ml292el inst 
+             CASE 7   : ml294i inst 
+             CASE 8, 9: ml320 inst 
+           END SELECT
+    FI. 
+ 
+    ml182i inst:
+      IF choice = 1 
+        THEN putline ("OKI Microline 182 IBM-kompatibel")
+        ELSE putline ("OKI Microline 183 IBM-kompatibel") 
+      FI; 
+      line; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("S-1   S-2   S-3   S-4   S-5   S-6   S-7   S-8");
+      putline ("egal  egal  OFF   egal  egal  OFF   egal  OFF");
+      show control options ("std speed, std quality"); 
+      show material options ("slow, fast, draft, nlq"); 
+      show command options ("draft, nlq"); 
+      ask for positioning; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.10"); 
+             generate ("okiml182i"); 
+             adjust positioning; 
+             adjust quality; 
+             IF choice = 2 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+    ml192el inst:
+      IF choice = 3 
+        THEN putline ("OKI Microline 192 ELITE (IBM/EPSON-kompatibel)")
+        ELSE putline ("OKI Microline 193 ELITE (IBM/EPSON-kompatibel)") 
+      FI; 
+      line; 
+      putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):"); 
+      putline ("- 13: Automatic Line Feed: Nein"); 
+      putline ("- 18: Compatibility: EPSON FX"); 
+      putline ("(Außerdem: Jumper SP5 in Position 'B')"); 
+      show control options ("std speed, paperfeed"); 
+      show material options ("slow, fast"); 
+      ask for positioning;
+      ask for paper feed; 
+      IF all right 
+        THEN get fonttable ("fonttab.7"); 
+             generate ("okiml192el"); 
+             adjust positioning;
+             adjust paper feed; 
+             IF choice = 4 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+    ml292el inst:
+      IF choice = 5 
+        THEN putline ("OKI Microline 292 ELITE (IBM/EPSON-kompatibel)")
+        ELSE putline ("OKI Microline 293 ELITE (IBM/EPSON-kompatibel)") 
+      FI; 
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):"); 
+      putline ("- Automatic Line Feed: NO"); 
+      putline ("- Compatibility: EPSON EX"); 
+      putline ("(Außerdem: Jumper SP5 in Position 'B')"); 
+      show control options ("paperfeed, std quality, std typeface"); 
+      show material options ("draft, nlq, courier, sansserif"); 
+      show command options ("draft, nlq, courier, sansserif"); 
+      putline ("schwarz, rot, blau, violett, gelb, orange, grün"); 
+      ask for paper feed; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.20"); 
+             generate ("okiml292el"); 
+             adjust paper feed; 
+             adjust quality;
+             IF choice = 6 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+    ml294i inst:
+      putline ("OKI Microline 294 IBM-kompatibel");
+      putline ("Der Druckertreiber unterstützt auch den Farbdruck mit entsprechendem"); 
+      putline ("Farbband.");
+      line; 
+      putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):"); 
+      putline ("- Proportional Spacing: NO");
+      putline ("- Automatic Line Feed: NO"); 
+      putline ("- Compatibility: PROPRINTER XL"); 
+      show control options ("paperfeed, std quality"); 
+      show material options ("draft, nlq"); 
+      show command options ("draft, nlq,  schwarz, rot, blau, violett, gelb, orange, grün"); 
+      ask for paper feed; 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.10"); 
+             generate ("okiml294i"); 
+             adjust paper feed; 
+             adjust quality;
+             do ("papersize (34.544, 30.48)");
+             installed := TRUE 
+      FI.
+ 
+    ml320 inst:
+      IF choice = 8 
+        THEN putline ("OKI Microline 320 IBM/EPSON-kompatibel") 
+        ELSE putline ("OKI Microline 321 IBM/EPSON-kompatibel") 
+      FI; 
+      line; 
+      putline ("Der Drucker muß so konfiguriert sein (Druckmenü des Druckers):"); 
+      putline ("- Automatic Line Feed: Nein"); 
+      show control options ("std speed"); 
+      show material options ("slow, fast"); 
+      ask for positioning;
+      IF all right 
+        THEN get fonttable ("fonttab.7"); 
+             generate ("okiml320"); 
+             adjust positioning;
+             IF choice = 9 THEN do ("papersize (34.544, 30.48)") FI; 
+             installed := TRUE 
+      FI.
+ 
+  schneider menu: 
+    page; 
+    headline ("Schneider - Menü"); 
+    putline (" 1. DMP 4000"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (1); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           dmp4000 inst 
+    FI. 
+ 
+    dmp4000 inst:
+      putline ("Schneider DMP 4000"); 
+      line; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("DS1-4           übrige Schalter"); 
+      putline (" OFF                 egal");
+      show control options ("std speed"); 
+      show material options ("slow, fast");
+      ask for positioning; 
+      IF all right 
+        THEN get fonttable ("fonttab.7"); 
+             generate ("dmp4000"); 
+             adjust positioning; 
+             do ("papersize (39.37, 30.48)"); 
+             installed := TRUE 
+      FI. 
+ 
+  star menu: 
+    page; 
+    headline ("Star - Menü"); 
+    putline (" 1. LC-10 (auch LC-10 Colour)"); 
+    putline (" 2. NX-15"); 
+    putline (" 3. ND-10");
+    putline (" 4. ND-15"); 
+    putline (" 5. NR-10");
+    putline (" 6. NR-15"); 
+    cursor (1,24); 
+    put ("CR: Eingabe        ESC: Zurück zum Hauptmenü"); 
+    ask user (6); 
+    page; 
+    choice := int (inp);
+    IF was esc 
+      THEN was esc := FALSE 
+      ELSE headline ("");
+           putline ("Druckertyp:"); 
+           IF choice = 1  
+             THEN lc10 inst
+           ELIF choice = 2 
+             THEN nx15 inst 
+             ELSE nd10 inst 
+           FI
+    FI. 
+ 
+    lc10 inst:
+      putline ("Star LC-10 oder LC-10 Colour"); 
+      line; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("S1-1  S1-2  S1-3  S1-4  S1-5  S1-6  S1-7  S1-8     S2-1  S2-2  S2-3  S2-4");
+      putline ("egal  egal  egal  *)    egal  EIN   egal  EIN      egal  egal  egal  egal"); 
+      putline ("*) AUS: Einzelblatteinzug, EIN: kein Einzug"); 
+      show control options ("std quality, std typeface"); 
+      show material options ("draft, nlq, courier, sansserif, orator1, orator2");
+      show command options ("draft, nlq, courier, sansserif, orator1, orator2");
+      putline ("schwarz, rot, blau, violett, gelb, orange, grün"); 
+      ask for quality; 
+      IF all right 
+        THEN get fonttable ("fonttab.20.lc"); 
+             generate ("starlc10"); 
+             adjust quality; 
+             do ("papersize (21.0, 30.48)"); 
+             installed := TRUE 
+      FI. 
+ 
+    nx15 inst:
+      putline ("Star NX-15"); 
+      line; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("S1-4  S1-8  S2-5         übrige Schalter"); 
+      putline ("EIN   EIN   EIN               egal");
+      show control options ("std speed"); 
+      show material options ("slow, fast"); 
+      ask for positioning;
+      IF all right 
+        THEN get fonttable ("fonttab.7"); 
+             generate ("starnx15"); 
+             adjust positioning; 
+             do ("papersize (36.0, 30.48)"); 
+             installed := TRUE 
+      FI. 
+ 
+    nd10 inst:
+      IF choice = 3 
+        THEN putline ("Star ND-10"); 
+      ELIF choice = 4 
+        THEN putline ("Star ND-15"); 
+      ELIF choice = 5 
+        THEN putline ("Star NR-10"); 
+        ELSE putline ("Star NR-15"); 
+      FI; 
+      line; 
+      putline ("Die DIP-Schalter müssen so eingestellt sein:"); 
+      putline ("S1-5  S1-6  S2-2          übrige Schalter"); 
+      putline ("EIN   EIN   EIN                egal");
+      show control options ("std speed"); 
+      show material options ("slow, fast"); 
+      ask for positioning; 
+      IF all right 
+        THEN get fonttable ("fonttab.7"); 
+             generate ("starnx15"); 
+             adjust positioning;
+             IF choice = 3 OR choice = 5 
+               THEN do ("papersize (21.0, 30.48)") 
+               ELSE do ("papersize (36.0, 30.48)")
+             FI; 
+             installed := TRUE 
+      FI. 
+ 
+generate printer spool: 
+    IF service opt = 0 
+      THEN forget (generator name, quiet); 
+           forget (driver name, quiet) 
+    FI;
+    eumel must advertise;
+    cursor (1, 10);
+    putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+    putline ("die Fonttabelle mit dem Kommando");
+    line;
+    putline ("      font table (""" + font tab name + """)");
+    line;
+    putline ("eingestellt werden!!!");
+    line (2);
+    putline ("Hinweis: Dieses Installationsprogramm kann in der Task """ + name (myself) + """"); 
+    putline ("         mit 'treiber einrichten' aufgerufen werden, wenn ein anderer"); 
+    putline ("         Drucker eingesetzt werden soll."); 
+    line (2); 
+    put ("Generierung beendet, weiter mit 'SV'");
+    break (quiet);
+    do ("spool manager (PROC printer)").
+ 
+  inform about restart: 
+    page; 
+    putline ("Es ist kein Druckertreiber installiert worden!"); 
+    line; 
+    putline ("Dieses Installationsprogramm kann in der Task """ + name (myself) + """"); 
+    putline ("mit 'treiber einrichten' erneut aufgerufen werden."); 
+    line. 
+ 
+END PROC treiber einrichten; 
+ 
+PROC headline (TEXT CONST header): 
+ 
+  cursor (13,1); 
+  putline ("E U M E L - Druckertreiber - Installations - Programm"); 
+  cursor (40 - LENGTH header DIV 2, 2); 
+  put (header); 
+  line (2) 
+END PROC headline; 
+ 
+PROC ask user (INT CONST max choice): 
+ 
+  TEXT VAR exit; 
+  inp := "";
+  REP 
+    cursor (1,23); 
+    IF inp = "" 
+      THEN put ("Ihre Wahl (Nummer eingeben):")  
+      ELSE put ("FEHLER! Eingabe korrigieren:")
+    FI; 
+    editget (inp, ""27"", "", exit); 
+    was esc :=  exit = ""27"";
+  UNTIL was esc OR ok PER. 
+ 
+  ok: 
+    int (inp) > 0 AND int (inp) <= max choice AND last conversion ok. 
+END PROC ask user;
+
+PROC show control options (TEXT CONST options): 
+ 
+  line; 
+  putline ("Steuerprozeduren in der Task """ + name (myself) + """:"); 
+  write ("papersize, top margin");
+  IF options <> "" 
+    THEN put (","); 
+         putline (options) 
+  FI
+END PROC show control options; 
+
+PROC show material options (TEXT CONST options): 
+ 
+  line; 
+  putline ("Mögliche Materialwerte (#material(""..."")#):"); 
+  putline (options) 
+END PROC show material options; 
+ 
+PROC show command options (TEXT CONST options): 
+ 
+  line; 
+  putline ("Mögliche direkte Druckeranweisungen (#""...""#):"); 
+  putline (options) 
+END PROC show command options; 
+ 
+PROC ask for positioning: 
+ 
+  line (2); 
+  putline ("Positionierung in x-Richtung:"); 
+  line; 
+  REP out (up); 
+    IF yes ("in Mikroschritten (genauer, aber langsamer)")
+      THEN positioning := 1; LEAVE ask for positioning 
+    FI;
+    out (up);
+    IF yes ("in Blanks (schneller, aber ungenauer)")
+      THEN positioning := 2; LEAVE ask for positioning 
+    FI;
+  PER 
+END PROC ask for positioning; 
+ 
+PROC ask for quality: 
+ 
+  line (2); 
+  putline ("Standard - Druckqualität:"); 
+  line; 
+  REP out (up); 
+    IF yes ("Draft Quality (schneller, aber nicht so schön)") 
+      THEN quality := 1; LEAVE ask for quality 
+    FI;
+    out (up);
+    IF yes ("Near Letter Quality (schöner, aber langsamer)")
+      THEN quality := 2; LEAVE ask for quality 
+    FI;
+  PER 
+END PROC ask for quality; 
+ 
+PROC ask for paper feed: 
+ 
+  line (2); 
+  putline ("Einzelblatteinzug:"); 
+  line; 
+  REP out (up); 
+    IF yes ("kein Einzelblatteinzug vorhanden") 
+      THEN sheet feeder := 0; LEAVE ask for paper feed 
+    FI;
+    out (up);
+    IF yes ("Einzelblatteinzug vorhanden")
+      THEN sheet feeder := 1; LEAVE ask for paper feed 
+    FI;
+  PER 
+END PROC ask for paper feed; 
+ 
+BOOL PROC all right: 
+ 
+  line (3);
+  cursor (1,23); 
+  yes ("Soll der ausgewählte Druckertreiber installiert werden") 
+END PROC all right; 
+ 
+PROC get fonttable (TEXT CONST name): 
+ 
+  fonttab name := name; 
+  from archive ((description file name & module file name & fonttab name) 
+                                                                    - all); 
+  fonttable (fonttab name); 
+  command dialogue (FALSE); 
+  save (fonttab name, /"configurator"); 
+  IF service option = 0 
+    THEN forget (fonttab name) 
+  FI; 
+  command dialogue (TRUE); 
+END PROC get fonttable; 
+ 
+PROC from archive (THESAURUS CONST files):
+ 
+  IF highest entry (files) > 0 
+    THEN fetch from archive; 
+         release (archive);
+         putline ("Archiv abgemeldet !")
+  FI.
+ 
+  fetch from archive: 
+    THESAURUS VAR thes :: files; 
+    REP 
+      ask for archive;
+      reserve archive;
+      fetch (thes / ALL archive, archive);
+      thes := thes - all 
+    UNTIL highest entry (thes) = 0 PER.
+
+ask for archive:
+  line;
+  putline ("Bitte Archiv mit den Dateien"); 
+  TEXT VAR buffer;
+  INT VAR index :: 0; 
+  REP 
+    get (thes, buffer, index); 
+    putline ("    " + buffer) 
+  UNTIL index = 0 PER; 
+  putline ("einlegen !"); 
+  line; 
+  putline ("Wenn eingelegt: Taste drücken !"); 
+  inchar (buffer). 
+ 
+reserve archive :
+  INT VAR p1, p2;
+  archive (" "31" ");
+  disable stop;
+  list (archive);
+  IF is error
+     THEN buffer := errormessage;
+          p1 := pos (buffer, """", 1 ) + 1;
+          p2 := pos (buffer, """", p1) - 1;
+          IF p1 > 0 AND p2 > 0
+             THEN clear error;
+                  buffer := subtext (buffer, p1, p2);
+                  archive (buffer);
+          FI;
+  FI;
+  enable stop.
+
+END PROC from archive;
+
+THESAURUS OP & (TEXT CONST left, right):
+  THESAURUS VAR result := empty thesaurus;
+  insert (result, left);
+  insert (result, right);
+  result
+END OP &;
+
+THESAURUS OP & (THESAURUS CONST left, TEXT CONST right):
+  THESAURUS VAR result := left;
+  insert (result, right);
+  result
+END OP &;
+ 
+PROC generate (TEXT CONST name): 
+ 
+  open files; 
+  read description; 
+  build programme; 
+  insert programme; 
+  forget files. 
+ 
+  open files: 
+    line (5); 
+    cursor (1, 20); 
+    putline (""4"Bitte warten !"); 
+    putline ("    - Der Treiber wird generiert."); 
+    driver name := "printer." + name + "(generiert)"; 
+    IF exists (driver name) 
+      THEN forget (driver name, quiet) 
+    FI; 
+    FILE VAR des file :: sequential file (modify, description file name), 
+             mod file :: sequential file (modify, module file name), 
+             driver file :: sequential file (output, driver name). 
+ 
+  read description: 
+    to line (des file, 1); 
+    col (des file, 1);
+    downety (des file, "$" + name + "$"); 
+    IF eof (des file) 
+      THEN errorstop ("Beschreibung von """ + name + """ nicht im"13""10"" + 
+                      "Descriptions-File enthalten")
+    FI; 
+    TEXT VAR description :: "", 
+             record; 
+    BOOL VAR done :: FALSE; 
+    read record (des file, record); 
+    record := subtext (record, col (des file) + LENGTH name + 2);
+    WHILE NOT eof (des file) AND NOT done REP 
+      treat record
+    PER. 
+ 
+  treat record: 
+    INT VAR dollar pos :: pos (record, "$"); 
+    IF dollar pos = 0
+      THEN description CAT compress (record); 
+           down (des file); 
+           read record (des file, record)  
+      ELSE description CAT compress (subtext (record, 1, dollar pos - 1));
+           col (des file, dollar pos); 
+           done := TRUE; 
+    FI. 
+ 
+  build programme: 
+    get module name; 
+    WHILE still modules REP 
+      find module; 
+      transfer module; 
+      get module name 
+    PER. 
+ 
+  get module name: 
+    INT VAR semicol pos :: pos (description, ";"); 
+    TEXT VAR module name; 
+    IF semicol pos > 0 
+      THEN module name := subtext (description, 1, semicol pos - 1); 
+           description := subtext (description, semicol pos + 1) 
+      ELSE module name := description; 
+           description := "" 
+    FI.
+ 
+  still modules: 
+    module name <> "" OR description <> "". 
+ 
+  find module: 
+    to line (mod file, 1); 
+    col (mod file, 1); 
+    downety (mod file, "$" + module name + "$"); 
+    IF eof (mod file) 
+      THEN errorstop ("Modul """ + module name + """ nicht im"13""10"" + 
+                      "Modul-File enthalten")
+    FI. 
+ 
+  transfer module: 
+    done := FALSE; 
+    read record (mod file, record); 
+    record := subtext (record, col (mod file) + LENGTH module name + 2);
+    WHILE NOT eof (mod file) AND NOT done REP 
+      transfer record
+    PER. 
+ 
+  transfer record: 
+    dollar pos := pos (record, "$"); 
+    IF dollar pos = 0
+      THEN write (driver file, compress (record)); 
+           line (driver file);
+           down (mod file); 
+           read record (mod file, record)  
+      ELSE write (driver file, compress (subtext (record, 1, 
+                                            dollar pos - 1)));
+           col (mod file, dollar pos); 
+           done := TRUE; 
+           cout (line no (mod file)) 
+    FI. 
+ 
+  insert programme: 
+    IF online 
+      THEN putline ("    - Der Treiber wird insertiert.") 
+    FI;
+    check off; 
+    insert (driver name). 
+ 
+  forget files: 
+    IF service option = 0 
+      THEN forget (description file name, quiet); 
+           forget (module file name, quiet)
+    FI.
+END PROC generate; 
+ 
+PROC adjust positioning: 
+ 
+  IF positioning = 1 
+    THEN do ("std speed (""slow"")") 
+    ELSE do ("std speed (""fast"")") 
+  FI 
+END PROC adjust positioning; 
+ 
+PROC adjust quality: 
+ 
+  IF quality = 1 
+    THEN do ("std quality (""draft"")") 
+    ELSE do ("std quality (""nlq"")") 
+  FI 
+END PROC adjust quality; 
+ 
+PROC adjust paper feed: 
+ 
+  IF sheet feeder = 1 
+    THEN do ("paper feed (""sheet"")") 
+    ELSE do ("paper feed (""tractor"")") 
+  FI 
+END PROC adjust paperfeed; 
+ 
+treiber einrichten 
+ 
+END PACKET driver inst 9
+
diff --git a/printer/dotmatrix9/readme b/printer/dotmatrix9/readme
new file mode 100644
index 0000000..2047abe
--- /dev/null
+++ b/printer/dotmatrix9/readme
@@ -0,0 +1,324 @@
+#type("nlq10")##limit(18.0)##start(1.5,1.0)# 
+#head# 
+Treiber-Installations-Programm   #right#Seite % 
+für 9-Nadel-Matrixdrucker   #right#23.06.1988 
+ 
+ 
+#end# 
+#on("u")#Dokumentation zum Treiber-Installations-Programm für 9-Nadel-
+Matrixdrucker#off("u")# 
+ 
+#on("u")#Inhalt:#off("u")# 
+ 
+1. Installations- und Gebrauchsanleitung 
+2. Druckertreiber-Auswahl 
+3. Steuerungsmöglichkeiten und Spezialfeatures 
+4. Weitere Hinweise 
+ 
+ 
+#on("b")#1. Installations- und Gebrauchsanleitung#off("b")# 
+ 
+#on("u")#Einrichten#off("u")# 
+So wird das Treiber-Installationsprogramm eingerichtet: 
+ 
+       SV drücken 
+ 
+    nach 'gib supervisor kommando:' 
+ 
+       begin("PRINTER","SYSUR") 
+ 
+    in der Task "PRINTER" (nach 'gib kommando'): 
+ 
+       archive ("std.printer") 
+       fetch ("printer.neun.nadel",archive) 
+       check off 
+       insert ("printer.neun.nadel") 
+ 
+Das Programm wird dann insertiert. 
+ 
+#on("u")#Druckerkanal#off("u")# 
+Hiernach wird die Kanalnummer des Druckers erfragt. Wenn der Drucker
+über Parallelschnittstelle betrieben wird, ist die Kanalnummer
+meistens 15. 
+ 
+#on("u")#Menüsystem#off("u")# 
+Das Installationsprogramm zeigt nun eine Liste von Druckerherstellern.
+Wählen Sie den Hersteller Ihres Druckers aus! Hiernach wird eine Liste
+der unterstützten Drucker dieses Herstellers gezeigt. Wählen Sie hier
+den passenden Typ aus! 
+Das Installationsprogramm zeigt nun einige Informationen zu dem ange­
+wählten Drucker. Besonders zu beachten sind hierbei #on("u")#Angaben zur Konfi­
+guration des Druckers#off("u")# (z.B. DIP-Schalter). Der Drucker muß unbedingt
+wie angegeben konfiguriert werden, wenn er mit dem ausgewählten Trei­
+ber betrieben werden soll. 
+ 
+Hinweise zu Konfigurationsangaben: 
+1. Die Angabe 'egal' bedeutet, daß die Einstellung für die Funktion
+   des Treibers keine Bedeutung hat. Dennoch solte der Anwender darauf
+   achten, welche Funktion die Schalter haben (Druckerhandbuch!). So
+   ist es zum Beispiel immer empfehlenswert, den Papierende-Sensor zu
+   aktivieren, damit der Drucker nach Papierende nicht auf der Walze
+   weiterdruckt. 
+2. Die Konfigurationsangaben beziehen sich immer auf genau den ausge­
+   wählten Druckertyp. Wenn Sie den Treiber mit einem anderen Drucker
+   als den ausgewählten verwenden, dann beachten Sie folgende Regeln
+   für die Konfiguration: 
+   - Der Drucker muß auf eine passende Emulation konfiguriert werden. 
+   - Der Drucker darf bei einem Carriage Return (Code 13) keinen Zei­
+     lenvorschub durchführen. 
+   - Der Drucker darf die Perforation #on("u")#nicht#off("u")# automatisch überspringen. 
+ 
+   - Auf Seitenlängen und internationale Zeichensätze müssen Sie nicht
+     achten. 
+ 
+(Hinweise zur Auswahl des richtigen Treibers gibt Abschnitt 2) 
+ 
+Nach den Konfigurationsangaben werden Steuerungsmöglichkeiten des
+ausgewählten Treibers angezeigt. (Siehe hierzu Abschnitt 3) 
+ 
+Falls der Treiber bestimmte grundsätzliche Betriebsmöglichkeiten er­
+laubt (z.B. DRAFT/NLQ, Einzelblatteinzug), werden Sie danach gefragt,
+welche Möglichkeit standardmäßig gewählt werden soll. diese Vorein­
+stellungen können nachträglich in der Task "PRINTER" mit den entspre­
+chenden Steuerprozeduren neu gesetzt werden. Außerdem können bestimmte
+Einstellungen noch für jedes einzelne Dokument (d.h. für jede Druck­
+datei) gewählt ('material'-Anweisung) oder sogar innerhalb eines Doku­
+ments verändert werden (direkte Druckeranweisung \#"..."\#). 
+Über die Steuerungsmöglichkeiten informiert Abschnitt 3 ausführlicher. 
+ 
+ 
+#on("b")#2. Druckertreiber-Auswahl#off("b")# 
+ 
+#on("u")#Verwendung nicht im Menü enthaltener Drucker#off("u")# 
+Für den Fall, daß Sie genau Ihren Drucker im Menü nicht finden, soll­
+ten Sie zunächst versuchen, ob ein Treiber für einen anderen Drucker
+des gleichen Herstellers mit Ihrem Drucker korrekt arbeitet. 
+Falls dies nicht funktioniert oder der Hersteller überhaupt nicht im
+Menü erscheint, müssen Sie herausfinden (Druckerhandbuch, -händler!),
+welchen Drucker Ihr Drucker emuliert oder welchem er ähnlich ist.
+(Viele Drucker verfügen über EPSON FX-85 bzw. FX-800-Emulationen oder
+IBM Grafikdrucker bzw. Proprinter-Eumulationen.) 
+Eine der beiden Anpassungen 'EPSON MX' oder 'IBM-Grafikdrucker' müßte
+immer einen (Minimal-) Betrieb ermöglichen. 
+ 
+#on("u")#Hinweise zu den Treibern für FX-80/85-kompatilble Drucker#off("u")# 
+Die Treiber für FX-80-bzw. FX-85-kompatible Geräte, die oft auch IBM-
+kompatibel sind, basieren üblicherweise auf den Treibern für EPSON-
+Drucker, weil so einige Schrifttypen (z.B. Proportionalschrift) und
+Modifikationen leichter ausgenutzt werden können. Ein Nachteil liegt
+aber darin, daß beim FX-80 und FX-85 noch die alten EPSON-Zeichensätze
+benutzt werden, die nicht die IBM-üblichen Grafik- und Sonderzeichen
+enthalten. 
+Falls für Sie die Benutzung dieser Zeichen vordringlich ist, sollten
+Sie Ihren Drucker (nachdem er auf IBM-Emulation konfiguriert wurde)
+zusammen mit dem Treiber für IBM-Grafikdrucker bzw. -Proprinter ver­
+wenden. 
+ 
+ 
+#on("b")#3. Steuerungsmöglichkeiten und Spezialfeatures#off("b")# 
+ 
+Einige Treiber bieten bestimmte Einstellungsmöglichkeiten (z.B.
+DRAFT/NLQ) und/oder Spezialfeatures (z.B. Farbdruck). 
+Die Einstellungen können über 
+- Steuerprozeduren 
+- Materialanweisungen bzw. 
+- direkte Druckeranweisungen 
+vorgenommen werden. 
+ 
+#on("u")#Steuerprozeduren#off("u")# 
+setzen Einstellungen, die für alle Dokumente (Druckdateien) gelten
+sollen. Die Prozeduren müssen in der Druckspooltask (meist: "PRINTER")
+aufgerufen werden. #on("b")#Gültig werden die Änderungen erst, wenn danach in
+der Druckspooltask das Kommando 'start' gegeben wird!#off("b")# 
+ 
+PROC papersize (REAL CONST breite, länge) 
+    Dient zur Einstellung der Größe der physikalisch beschreibbaren
+    Fläche. 
+    Beispiel:  papersize (20.32, 30.48) 
+               (Standardeinstellung für Endlospapier 8 Zoll breit und
+               12 Zoll lang) 
+ 
+PROC papersize 
+    Informationsprozedur 
+ 
+PROC top margin (REAL CONST margin) 
+    Falls der Drucker es nicht erlaubt, direkt am Blattanfang zu druk­
+    ken (zum Beispiel wegen eines Einzelblatteinzugs), muß mit dieser
+    Prozedur die Länge des oberen Randes, den der Drucker nicht be­
+    drucken kann, in cm angegeben werden. 
+    Beispiel:  top margin (2.0) 
+               (Teilt dem Druckertreiber mit, daß die ersten 2 cm
+               nicht bedruckbar sind.) 
+ 
+REAL PROC top margin 
+    Informationsprozedur 
+ 
+PROC std speed (TEXT CONST speed) 
+    Parameter: slow, fast 
+    Wahl zwischen Positionierung in Mikroschritten (slow) oder in
+    Blanks (fast). 
+    Beispiel:  std speed ("slow") 
+ 
+TEXR PROC std speed 
+    Informationsprozedur 
+ 
+PROC std quality (TEXT CONST quality) 
+    übliche Parameter: draft, nlq 
+    Wahl zwischen Datenverarbeitungs-Qualität und Schönschrift-
+    Qualität 
+    Beispiel:  std quality ("draft") 
+ 
+TEXT PROC std quality 
+    Informationsprozedur 
+ 
+PROC std typeface (TEXT CONST typeface) 
+    übliche Parameter: roman, sansserif, courier 
+    Wahl zwischen verschiedenen NLQ-Schriftarten (nur sichtbar im
+    NLQ-Modus, das heißt 'std typeface' schaltet nicht auf NLQ). 
+    Beispiel: std typeface ("roman") 
+ 
+TEXT PROC std typeface 
+    Informationsprozedur 
+ 
+PROC paper feed (TEXT CONST name) 
+    übliche Parameter: tractor, sheet, schacht1, schacht2 
+    Wählt Endlospapier oder Einzelblatteinzug und ggf. Schachtnummer. 
+    Beispiel:  paper feed ("sheet") 
+ 
+TEXT PROC paper feed 
+    Informationsprozedur 
+ 
+ 
+#on("u")#Materialanweisungen \#material("...")\##off("u")# 
+müssen in der Druckdatei vor dem ersten druckbaren Zeichen stehen und
+setzen Einstellungen für eine ganze Datei. (Materialanweisungen haben
+für die jeweilige Datei Vorrang vor den durch Steuerprozeduren einge­
+stellten Standardwerten. Diese werden durch die Materialanweisung aber
+nicht geändert.) 
+ 
+Beispiel:  \#material("nlq")\# 
+           sorgt bei entsprechendem Treiber dafür, daß das gesamte
+           Dokument in Schönschrift-Qualität ausgedruckt wird, egal
+           wie 'std quality' eingestellt ist. 
+ 
+#on("b")#Es darf in einer Datei nur eine Materialanweisung stehen!#off("b")# Sollen meh­
+rere Einstellungen vorgenommen werden, müssen sie in einer Anweisung
+erscheinen. Beispiel:  \#material("sheet;draft")\# 
+ 
+ 
+#on("u")#direkte Druckeranweisungen \#"..."\##off("u")# 
+gelten ab der Position, an der sie in der Datei auftreten. Sie haben
+(sofern sie erlaubt sind,) Vorrang vor Standardeinstellungen und
+Materialeinstellungen. 
+ 
+Beispiel:  \#"draft"\# 
+           schaltet (bei entsprechendem Treiber) auf Datenverar­
+           beitungs-Qualität, egal welche Standardeinstellung vorliegt
+           und welche Materialanweisung gegeben wurde. 
+ 
+#on("b")#In einer Druckeranweisung darf nur eine Einstellung vorgenommen
+werden.#off("b")# Also:  \#"nlq"\#\#"sansserif"\# 
+ 
+ 
+#on("u")#Wichtig#off("u")# 
+- Achten Sie bei Materialanweisungen und direkten Druckeranweisungen
+  besonders auf korrekte Schreibweise! Es werden nur Kleinbuchstaben
+  berücksichtigt! Also:  \#"nlq"\# und keinesfalls \#"NLQ"\#!!! 
+- Direkte Druckeranweisungen werden vom EUMEL-Drucker ignoriert und
+  nur vom Druckertreiber in eine Kommando-Sequenz umgesetzt. Es kann
+  daher vorkommen, daß (z.B. bei Spaltendruck) unerwartete Ergebnisse
+  erscheinen, weil der EUMEL-Drucker dann den Text in einer anderen
+  Reihenfolge an den Drucker sendet, als er in der Datei steht, die
+  mit dem direkten Druckerkommando gesetzte Modifikation aber (z.B.
+  für beide Spalten) unerwünscht erhalten bleibt. 
+ 
+ 
+#on("u")#Tabelle#off("u")# 
+Die Tabelle soll einen Anhaltspunkt dafür geben, wie welche Einstel­
+lungen erfolgen können. 
+ 
+#type("17")# 
+                   Steuerprozeduren      Materialanweisungen     direkte Druckeranweisungen 
+ 
+#on("u")#                                                                                          #off("u")# 
+ 
+Positionierung     std speed             slow, fast              ------ 
+                     slow, fast 
+ 
+Qualität           std quality           z.B. draft, nlq         z.B. draft, nlq 
+                     z.B. draft, nlq 
+ 
+Schriftart         std typeface          z.B. roman,             z.B. roman, 
+(nur bei NLQ)        z.B. roman,         sansserif, courier      sansserif, courier 
+                     sansserif, courier 
+ 
+Einzelblatt-       paper feed            z.B. schacht1,          z.B. schacht1, 
+einzug               z.B. tractor,       schacht2                schacht2 
+                     sheet, 
+                     schacht1, schacht2 
+ 
+Farbdruck          ------                ------                  z.B. schwarz, 
+                                                                 rot, blau, 
+                                                                 violett, gelb 
+                                                                 orange, grün 
+ 
+ 
+ 
+#type("nlq10")##on("b")#4. Weitere Hinweise#off("b")# 
+ 
+#on("u")#Zeichensatzänderungen gegenüber früheren Versionen#off("u")# 
+In den Fonttabellen früherer Druckertreiber-Versionen wurden oberhalb
+des Codes 127 einige internationale Zeichen zur Verfügung gestellt
+(und zwar in Anlehnung an den Agfa-Laserdrucker-Zeichensatz). 
+Bei den Treibern der vorliegenden Version gilt folgendes: 
+- Wie bisher wird der volle im Benutzerhandbuch festgelegte EUMEL-
+  Zeichensatz (sofern möglich) unterstützt. 
+- Der Code 252 liefert das Paragraphzeichen. 
+- Alle übrigen (vom EUMEL-Zeichensatz nicht definierten) Zeichencodes
+  oberhalb 127 liefern, sofern möglich, die entsprechenden Zeichen des
+  IBM-Grafikzeichensatzes. 
+ 
+ 
+#on("u")#Hinweis zu Proportionalschriften#off("u")# 
+Bei Proportionalschriften sollte die Modifikation \#on("i")\# nicht
+benutzt werden, da die kursiven Zeichen andere Proportionalbreiten
+haben. Stattdessen sollte auf den schrägen Typ umgeschaltet werden
+(z.B. von "prop10" auf "prop10i"). 
+ 
+ 
+#on("u")#Hinweis zur Benutzung von Einzelblatteinzügen#off("u")# 
+Bei der Benutzung von Einzelblatteinzügen müssen folgende Einstel­
+lungen vorgenommen werden (vgl. auch Abschnitt 3!): 
+ 
+   Am Drucker: 
+1. Sie müssen Ihren Drucker auf die Option Einzelblatteinzug konfigu­
+   rieren (siehe Druckerhandbuch!). 
+ 
+   In der Druckspooltask (meist 'PRINTER'): 
+2. Falls der Druckertreiber die Steuerprozedur 'paper feed' zur Verfü­
+   gung stellt, müssen Sie mit 'paperfeed ("sheet")' oder (für
+   2-Schacht-Einzüge) mit 'paperfeed ("schacht1")' bzw. 'paperfeed
+   ("schacht2")' den Druckertreiber auf Einzelblatteinzug umschalten. 
+3. Falls Sie eine andere Papierlänge als 12 Zoll (=30.48 cm) verwen­
+   den, müssen Sie die neuen Papiermaße mit 'papersize' in cm einstel­
+   len. 
+   Beispiel:  papersize (21.0, 29.7) 
+              (für DIN A4-Blätter) 
+4. Falls der Drucker mit dem Einzelblatteinzug nicht direkt am Blatt­
+   anfang drucken kann, sondern ein gewisser oberer Rand bleibt, muß
+   mit 'top margin' die Länge des nicht bedruckbaren Randes in cm dem
+   Druckertreiber mitgeteilt werden. 
+   Beispiel:  top margin (1.5) 
+   (Wie groß der obere Rand ist, kann festgestellt werden, indem eine
+   Datei mit \#start(0.0,0.0)\# ausgedruckt wird.) 
+ 
+   Wurde mit 'top margin' dem Treiber die Größe der nicht bedruckbaren
+   Fläche mitgeteilt, so ist darauf zu achten, daß in den Druckdateien
+   ein genügend großer y-Wert für die Startposition eingestellt wird
+   ('start'-Anweisung). Andernfalls kommt es bei der Ausgabe in der
+   ersten Zeile zu Überschreibungen. 
+ 
+ 
+#on("b")#5. Die Änderungen, die Sie in der Druckspooltask vorgenommen haben
+   werden erst wirksam, wenn das Spool-Kommando 'start' gegeben wird.#off("b")# 
+
diff --git a/printer/laser/fonttab.apple.laserwriter b/printer/laser/fonttab.apple.laserwriter
new file mode 100644
index 0000000..bee2d6a
Binary files /dev/null and b/printer/laser/fonttab.apple.laserwriter differ
diff --git a/printer/laser/fonttab.canon.lbp-8 b/printer/laser/fonttab.canon.lbp-8
new file mode 100644
index 0000000..45314ac
Binary files /dev/null and b/printer/laser/fonttab.canon.lbp-8 differ
diff --git a/printer/laser/fonttab.epson.sq b/printer/laser/fonttab.epson.sq
new file mode 100644
index 0000000..a3f7af3
Binary files /dev/null and b/printer/laser/fonttab.epson.sq differ
diff --git a/printer/laser/fonttab.hp.laserjet b/printer/laser/fonttab.hp.laserjet
new file mode 100644
index 0000000..4082e46
Binary files /dev/null and b/printer/laser/fonttab.hp.laserjet differ
diff --git a/printer/laser/fonttab.kyocera.f-1010 b/printer/laser/fonttab.kyocera.f-1010
new file mode 100644
index 0000000..9c3fbda
Binary files /dev/null and b/printer/laser/fonttab.kyocera.f-1010 differ
diff --git a/printer/laser/fonttab.nec.lc-08 b/printer/laser/fonttab.nec.lc-08
new file mode 100644
index 0000000..f032953
Binary files /dev/null and b/printer/laser/fonttab.nec.lc-08 differ
diff --git a/printer/laser/genfont.kyocera.f-1010.dynamic1 b/printer/laser/genfont.kyocera.f-1010.dynamic1
new file mode 100644
index 0000000..fae8c09
--- /dev/null
+++ b/printer/laser/genfont.kyocera.f-1010.dynamic1
@@ -0,0 +1,30 @@
+#"!"82"! "# 
+#"CMNT 'dyn1.6   '; GENF 10220, 'DYNAMIC1',  22, 32, 126, 32, 0.94, 0.0, 0, 0, 0.0, 0.0; "# 
+#"CMNT 'dyn1.6.i '; GENF 10224, 'DYNAMIC1',  22, 32, 126, 32, 0.94, 0.3, 0, 0, 0.0, 0.0; "# 
+#"CMNT 'dyn1.8   '; GENF 10280, 'DYNAMIC1',  28, 32, 126, 32, 0.94, 0.0, 0, 0, 0.0, 0.0; "# 
+#"CMNT 'dyn1.8.i '; GENF 10284, 'DYNAMIC1',  28, 32, 126, 32, 0.94, 0.3, 0, 0, 0.0, 0.0; "# 
+#"CMNT 'dyn1.10  '; GENF 10340, 'DYNAMIC1',  34, 32, 126, 32, 0.94, 0.0, 0, 0, 0.0, 0.0; "# 
+#"CMNT 'dyn1.10.i'; GENF 10344, 'DYNAMIC1',  34, 32, 126, 32, 0.94, 0.3, 0, 0, 0.0, 0.0; "# 
+#"CMNT 'dyn1.12  '; GENF 10420, 'DYNAMIC1',  42, 32, 126, 32, 0.94, 0.0, 0, 0, 0.0, 0.0; "# 
+#"CMNT 'dyn1.12.i'; GENF 10424, 'DYNAMIC1',  42, 32, 126, 32, 0.94, 0.3, 0, 0, 0.0, 0.0; "# 
+#"CMNT 'dyn1.14  '; GENF 10500, 'DYNAMIC1',  50, 32, 126, 32, 0.94, 0.0, 0, 0, 0.0, 0.0; "# 
+#"CMNT 'dyn1.14.b'; GENF 10502, 'DYNAMIC1',  50, 32, 126, 32, 1.04, 0.0, 0, 0, 5.0, 3.0; "# 
+#"CMNT 'dyn1.18.b'; GENF 10682, 'DYNAMIC1',  68, 32, 126, 32, 1.04, 0.0, 0, 0, 5.0, 3.0; "# 
+#"CMNT 'dyn1.24.b'; GENF 10922, 'DYNAMIC1',  92, 32, 126, 32, 1.04, 0.0, 0, 0, 5.0, 3.0; "# 
+#"CMNT 'dyn1.36.b'; GENF 11322, 'DYNAMIC1', 132, 32, 126, 32, 1.04, 0.0, 0, 0, 5.0, 3.0; "# 
+#"MAP 0, 0; EXIT;"# 
+ 
+#type ("dyn1.6")   #\#type("dyn1.6")\# 
+#type ("dyn1.6.i") #\#type("dyn1.6.i")\# 
+#type ("dyn1.8")   #\#type("dyn1.8")\# 
+#type ("dyn1.8.i") #\#type("dyn1.8.i")\# 
+#type ("dyn1.10")  #\#type("dyn1.10")\# 
+#type ("dyn1.10.i")#\#type("dyn1.10.i")\# 
+#type ("dyn1.12")  #\#type("dyn1.12")\# 
+#type ("dyn1.12.i")#\#type("dyn1.12.i")\# 
+#type ("dyn1.14")  #\#type("dyn1.14")\# 
+#type ("dyn1.14.b")#\#type("dyn1.14.b")\# 
+#type ("dyn1.18.b")#\#type("dyn1.18.b")\# 
+#type ("dyn1.24.b")#\#type("dyn1.24.b")\# 
+#type ("dyn1.36.b")#\#type("dyn1.36.b")\# 
+
diff --git a/printer/laser/genfont.kyocera.f-1010.dynamic2 b/printer/laser/genfont.kyocera.f-1010.dynamic2
new file mode 100644
index 0000000..f425a7f
--- /dev/null
+++ b/printer/laser/genfont.kyocera.f-1010.dynamic2
@@ -0,0 +1,30 @@
+#"!"82"! "# 
+#"CMNT 'dyn2.6   '; GENF 20200, 'DYNAMIC2',  20, 32, 126, 32, 0.94, 0.0, 0, 0, 2.0, 0.0; "# 
+#"CMNT 'dyn2.6.i '; GENF 20204, 'DYNAMIC2',  20, 32, 126, 32, 0.94, 0.3, 0, 0, 2.0, 0.0; "# 
+#"CMNT 'dyn2.8   '; GENF 20260, 'DYNAMIC2',  26, 32, 126, 32, 0.94, 0.0, 0, 0, 2.0, 0.0; "# 
+#"CMNT 'dyn2.8.i '; GENF 20264, 'DYNAMIC2',  26, 32, 126, 32, 0.94, 0.3, 0, 0, 2.0, 0.0; "# 
+#"CMNT 'dyn2.10  '; GENF 20320, 'DYNAMIC2',  32, 32, 126, 32, 0.94, 0.0, 0, 0, 2.0, 0.0; "# 
+#"CMNT 'dyn2.10.i'; GENF 20324, 'DYNAMIC2',  32, 32, 126, 32, 0.94, 0.3, 0, 0, 2.0, 0.0; "# 
+#"CMNT 'dyn2.12  '; GENF 20400, 'DYNAMIC2',  40, 32, 126, 32, 0.94, 0.0, 0, 0, 2.0, 0.0; "# 
+#"CMNT 'dyn2.12.i'; GENF 20404, 'DYNAMIC2',  40, 32, 126, 32, 0.94, 0.3, 0, 0, 2.0, 0.0; "# 
+#"CMNT 'dyn2.14  '; GENF 20480, 'DYNAMIC2',  48, 32, 126, 32, 0.94, 0.0, 0, 0, 2.0, 0.0; "# 
+#"CMNT 'dyn2.14.b'; GENF 20482, 'DYNAMIC2',  48, 32, 126, 32, 0.99, 0.0, 0, 0, 5.0, 3.0; "# 
+#"CMNT 'dyn2.18.b'; GENF 20662, 'DYNAMIC2',  66, 32, 126, 32, 0.99, 0.0, 0, 0, 5.0, 3.0; "# 
+#"CMNT 'dyn2.24.b'; GENF 20902, 'DYNAMIC2',  90, 32, 126, 32, 0.99, 0.0, 0, 0, 5.0, 3.0; "# 
+#"CMNT 'dyn2.36.b'; GENF 21302, 'DYNAMIC2', 130, 32, 126, 32, 0.99, 0.0, 0, 0, 5.0, 3.0; "# 
+#"MAP 0, 0; EXIT;"# 
+ 
+#type ("dyn2.6")   #\#type("dyn2.6")\# 
+#type ("dyn2.6.i") #\#type("dyn2.6.i")\# 
+#type ("dyn2.8")   #\#type("dyn2.8")\# 
+#type ("dyn2.8.i") #\#type("dyn2.8.i")\# 
+#type ("dyn2.10")  #\#type("dyn2.10")\# 
+#type ("dyn2.10.i")#\#type("dyn2.10.i")\# 
+#type ("dyn2.12")  #\#type("dyn2.12")\# 
+#type ("dyn2.12.i")#\#type("dyn2.12.i")\# 
+#type ("dyn2.14")  #\#type("dyn2.14")\# 
+#type ("dyn2.14.b")#\#type("dyn2.14.b")\# 
+#type ("dyn2.18.b")#\#type("dyn2.18.b")\# 
+#type ("dyn2.24.b")#\#type("dyn2.24.b")\# 
+#type ("dyn2.36.b")#\#type("dyn2.36.b")\# 
+
diff --git a/printer/laser/laser.inserter b/printer/laser/laser.inserter
new file mode 100644
index 0000000..c28766f
--- /dev/null
+++ b/printer/laser/laser.inserter
@@ -0,0 +1,275 @@
+PACKET laserdrucker inserter DEFINES treiber einrichten : 
+ 
+(**************************************************************************)
+(*   Installationsprogramm                        Stand   : 12.12.88      *)
+(*   für Tintenstrahl-                            Version : 0.9           *)
+(*   und Laserdrucker                             Autor   : hjh           *)
+(**************************************************************************)
+ 
+LET anzahl firmen = 6 ; 
+LET apple = "APPLE" , 
+    canon = "CANON" , 
+    epson = "EPSON" , 
+    hp    = "HEWLETT PACKARD" , 
+    kyo   = "KYOCERA" , 
+    nec   = "NEC" ; 
+ 
+THESAURUS VAR firmen := empty thesaurus ; 
+ 
+INT VAR i ; 
+ROW anzahl firmen THESAURUS VAR drucker ; 
+FOR i FROM 1 UPTO anzahl firmen REP 
+  drucker (i) := empty thesaurus 
+PER ;
+ROW anzahl firmen THESAURUS VAR printer ; 
+FOR i FROM 1 UPTO anzahl firmen REP 
+  printer (i) := empty thesaurus 
+PER ;
+ROW anzahl firmen THESAURUS VAR fonttables ; 
+FOR i FROM 1 UPTO anzahl firmen REP 
+  fonttables (i) := empty thesaurus 
+PER ;
+ 
+liste (apple,"LASERWRITER","printer.apple.laserwriter","fonttab.apple.laserwriter"); 
+liste (canon , "LBP-8"    ,"printer.canon.lbp-8"      ,"fonttab.canon.lbp-8"); 
+liste (epson , "SQ 2500"  ,"printer.epson.sq"         ,"fonttab.epson.sq"); 
+liste (hp , "HP LASERJET" ,"printer.hp.laserjet"      ,"fonttab.hp.laserjet"); 
+liste (hp , "HP LASERJET+" ,"printer.hp.laserjet"      ,"fonttab.hp.laserjet"); 
+liste (kyo , "F-1010"     ,"printer.kyocera.f-1010"   ,"fonttab.kyocera.f-1010"); 
+liste (kyo , "F-2200"     ,"printer.kyocera.f-1010"   ,"fonttab.kyocera.f-1010"); 
+liste (nec , "SILENTWRITER LC-08"      ,"printer.nec.lc-08"
+,"fonttab.nec.lc-08"); 
+
+treiber einrichten;
+ 
+PROC liste (TEXT CONST firmenname, druckername , 
+                        printername, fonttabname ) : 
+  INT VAR firmnum ; 
+  IF firmen CONTAINS firmenname 
+    THEN firmnum := link (firmen,firmenname) 
+    ELSE insert (firmen,firmenname,firmnum) 
+  FI; 
+  insert (drucker(firmnum), druckername) ; 
+  insert (printer(firmnum), printername) ; 
+  insert (fonttables(firmnum), fonttabname) ; 
+END PROC liste ;
+ 
+PROC treiber einrichten : 
+  INT VAR menu phase := 1 ; 
+  BOOL VAR installed := FALSE ; 
+  BOOL VAR was esc ; 
+  INT VAR firmnum, druckernum ;
+  TEXT VAR firmenname, druckername, printername, fonttabname ;
+ 
+  pre menu ;
+  REP 
+    SELECT menu phase OF 
+      CASE 1 : menu ("Hauptmenü Tintenstrahl und Laserdrucker", firmen, 
+                     "CR: Eingabe        ESC : Installation abrechen", 
+                     firmnum, was esc ) ;
+               IF was esc 
+                 THEN menu phase := 0 
+                 ELSE menu phase := 2 ; 
+                      firmenname := name (firmen,firmnum) ;
+               FI ;
+  
+      CASE 2 : menu (firmenname + " - Menü", drucker(firmnum),
+                     "CR: Eingabe        ESC : Zurück zum Hauptmenü",      
+                     druckernum, was esc) ;
+               IF was esc 
+                 THEN menu phase := 1 
+                 ELSE menu phase := 3 ; 
+                      druckername := name (drucker(firmnum),druckernum);  
+                      printername := name (printer(firmnum),druckernum); 
+                      fonttabname := name (fonttables(firmnum),druckernum); 
+               FI;
+ 
+      CASE 3 : inst (druckername, printername, fonttabname, installed) ; 
+               IF NOT installed THEN menu phase := 1 FI;
+    END SELECT 
+  UNTIL installed OR abbruch PER ;
+  post menu. 
+ 
+  abbruch: 
+    menu phase < 1 .
+ 
+  pre menu: 
+    line; 
+    IF is single task system
+      THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL") 
+    FI; 
+    IF NOT is system task (myself)
+      THEN errorstop ("Die Druckertask muß im Systemzweig angelegt werden") 
+    FI; 
+    command dialogue (TRUE);
+    IF name (myself) <> "PRINTER" 
+      THEN putline ("Diese Task heißt nicht ""PRINTER"", sondern """ + 
+                    name (myself) + """ !"); 
+           IF yes ("Soll die Task in ""PRINTER"" umbenannt werden ?") 
+             THEN rename myself ("PRINTER") 
+           FI 
+    FI. 
+ 
+  is single task system:  (pcb (9) AND 255) = 1.
+ 
+  post menu: 
+   IF NOT installed 
+    THEN page; 
+         putline ("Es ist kein Druckertreiber installiert worden!"); 
+         line; 
+         putline ("Wenn dieses Installationsprogramm insertiert wurde,");
+         putline ("kann es in der Task """ + name (myself) + """ "); 
+         putline ("mit 'treiber einrichten' erneut aufgerufen werden."); 
+         line; 
+   FI. 
+ 
+END PROC treiber einrichten ;
+ 
+PROCEDURE menu (TEXT CONST header, THESAURUS CONST items, TEXT CONST bottom, 
+                INT VAR choice, BOOL VAR was esc) : 
+  INT VAR anzahl ; 
+  page; 
+  headline (header) ; 
+  show list (items,anzahl) ; 
+  bottomline (bottom) ;
+  ask user (anzahl,choice,was esc);  
+END PROC menu ;
+ 
+PROC headline (TEXT CONST header): 
+  cursor (13,1); 
+  putline ("E U M E L - Druckertreiber - Installations - Programm"); 
+  cursor (40 - LENGTH header DIV 2, 2); 
+  IF header <> "" THEN put (header) FI ;
+  line (2) 
+END PROC headline; 
+ 
+PROC bottomline (TEXT CONST bottom): 
+  cursor (1,24); 
+  IF bottom <> "" THEN put (""5"" + bottom) FI ;
+END PROC bottomline; 
+ 
+PROC show list (THESAURUS CONST items , INT VAR anzahl ) : 
+  INT VAR i ; 
+  anzahl := highest entry (items);
+  FOR i FROM 1 UPTO anzahl REP 
+    putline ( text(i) + ".  " + name (items,i) ) ; 
+  PER;
+END PROC show list ;
+ 
+PROC ask user (INT CONST max choice, INT VAR choice, BOOL VAR was esc): 
+  TEXT VAR exit; 
+  TEXT VAR inp := "";
+  REP 
+    cursor (1,23); 
+    IF inp = "" 
+      THEN put ("Ihre Wahl (Nummer eingeben):")
+      ELSE put ("FEHLER! Eingabe korrigieren:")
+    FI; 
+    editget (inp, ""27"", "", exit); 
+    was esc :=  exit = ""27"";
+  UNTIL was esc OR ok PER. 
+ 
+  ok: 
+    choice := int (inp) ; 
+    last conversion ok CAND ( choice > 0 AND choice <= max choice) . 
+END PROC ask user; 
+ 
+BOOL PROC is system task (TASK CONST task): 
+  TASK VAR tsk := task ; 
+  WHILE NOT (tsk = supervisor OR tsk = niltask) REP  
+    tsk := father (tsk) ; 
+  PER;
+  tsk = supervisor 
+END PROC is system task ;
+ 
+PROC inst (TEXT CONST druckername, printername, fonttabname, 
+           BOOL VAR success) : 
+   page ; 
+   headline (druckername) ; 
+   fetch from archive if necessary ((empty thesaurus 
+      + printer name + fonttab name) - all ,success); 
+   IF success  AND ok
+     THEN page ; 
+          putline ("Der Drucker wird insertiert"); 
+          insert (printer name) ; 
+     ELSE success := FALSE ; 
+   FI. 
+ 
+ok: 
+  bottomline (" "); 
+  yes ("Soll der ausgewählte Drucker insertiert werden"). 
+   
+END PROC inst ; 
+ 
+PROC fetch from archive if necessary (THESAURUS CONST files, 
+                                       BOOL VAR success ):
+  BOOL VAR was esc ; 
+  THESAURUS VAR thes :: files; 
+ 
+  WHILE highest entry (thes) > 0  REP
+    ask for archive;
+    IF NOT was esc 
+      THEN disable stop ; 
+           bottomline ("Bitte warten !  "); 
+           reserve archive;
+           IF NOT is error 
+             THEN IF highest entry (thes / ALL archive) > 0 
+                    THEN fetch (thes / ALL archive, archive);
+                    ELSE fehler ("Dateien nicht gefunden") 
+                  FI; 
+                  thes := thes - all;
+           FI; 
+           IF is error 
+             THEN fehler (errormessage);
+                  clear error 
+           FI; 
+           command dialogue (FALSE); 
+           release (archive);
+           command dialogue (TRUE); 
+           enable stop ; 
+    FI;
+  UNTIL was esc PER; 
+  success := highest entry (thes) = 0. 
+ 
+ask for archive:
+  headline ("") ;
+  putline ("Bitte Archiv mit den Dateien"); 
+  TEXT VAR buffer;
+  INT VAR index :: 0; 
+  REP 
+    get (thes, buffer, index); 
+    putline ("    " + buffer) 
+  UNTIL index = 0 PER; 
+  putline ("einlegen !"); 
+  bottomline ("CR: Wenn Archiv eingelegt        ESC : Zurück zum Hauptmenü"); 
+  cursor (1,24); 
+  REP 
+    inchar (buffer) ; 
+  UNTIL buffer = ""13"" OR buffer = ""27"" PER ; 
+  was esc := buffer = ""27"". 
+ 
+reserve archive :
+  INT VAR p1, p2;
+  archive (" "31" ");
+  list (archive);
+  IF is error
+     THEN buffer := errormessage;
+          p1 := pos (buffer, """", 1 ) + 1;
+          p2 := pos (buffer, """", p1) - 1;
+          IF p1 > 0 AND p2 > 0
+             THEN clear error;
+                  buffer := subtext (buffer, p1, p2);
+                  archive (buffer);
+          FI;
+  FI.
+
+END PROC fetch from archive if necessary ;
+
+PROC fehler (TEXT CONST fehlermeldung): 
+  bottomline (""7"" + fehlermeldung + "   Bitte eine Taste drücken") ; 
+  pause ; 
+  bottomline (" ") ; 
+END PROC fehler;
+ 
+END PACKET laserdrucker inserter;
+
diff --git a/printer/laser/printer.apple.laserwriter b/printer/laser/printer.apple.laserwriter
new file mode 100644
index 0000000..d4c6adf
--- /dev/null
+++ b/printer/laser/printer.apple.laserwriter
@@ -0,0 +1,770 @@
+PACKET apple laser writer printer
+ 
+(**************************************************************************)
+(*                                                Stand   : 24.02.88      *)
+(*  APPLE LaswerWriter (PostScript)               Verison : 4             *)
+(*                                                Autor   : Rudolf Ruland *)
+(**************************************************************************)
+ 
+       DEFINES open,
+               close,
+               execute,
+ 
+               paper size,
+               paper x size,
+               paper y size,
+
+               load positioning procs,
+               load underline procs,
+               load italics procs,
+               load encoding,
+
+               read ps input,
+
+               box commands,
+               insert box command,
+               delete box command,
+
+               print error,
+               :
+ 
+LET
+(*  underline           =  1,
+    bold                =  2,
+    italics             =  4,
+    reverse             =  8,
+*) 
+    underline linetype  =  1,
+ 
+    c document          =  1,
+    c page              =  2,
+ 
+    c write text        =  1,
+    c write cmd         =  2,
+    c carriage return   =  3, 
+    c move              =  4,
+    c draw              =  5,
+    c on                =  6, 
+    c off               =  7,
+    c type              =  8,
+ 
+    ps input name       =  "PostScript.input",
+    ps error            =  999,
+
+    tag type            =  1;
+
+INT VAR paper length, font no, underline no, symbol type;
+REAL VAR x size, y size;
+BOOL VAR is landscape;
+TEXT VAR record, char, command, symbol;
+FILE VAR ps input;
+THESAURUS VAR box cmds := empty thesaurus;
+
+(*********************************************************************)
+ 
+paper size (21.0, 29.7);
+ 
+PROC paper size (REAL CONST x, y) :
+ 
+  x size := x;
+  y size := y;
+ 
+END PROC paper size;
+ 
+PROC paper size : 
+ 
+  line;
+  putline ("Papierbreite  =  " + text (x size, 5, 2) + " cm  =  " + text (x size / 2.54, 5, 2) + " Zoll");
+  putline ("Papierlaenge  =  " + text (y size, 5, 2) + " cm  =  " + text (y size / 2.54, 5, 2) + " Zoll");
+ 
+END PROC paper size;
+ 
+REAL PROC paper x size : x size END PROC paper x size;
+
+REAL PROC paper y size : y size END PROC paper y size;
+
+
+THESAURUS PROC box commands : box cmds END PROC box commands;
+
+PROC insert box command (TEXT CONST new command) :
+
+  command := new command;
+  change all (command, " ", "");
+  insert (box cmds, command)
+
+END PROC insert box command;
+
+PROC delete box command (TEXT CONST old command) :
+
+  INT VAR dummy;
+  command := old command;
+  change all (command, " ", "");
+  delete (box cmds, command, dummy)
+
+END PROC delete box command;
+
+(*********************************************************************)
+ 
+PROC open (INT CONST op code, INT VAR param1, param2) :
+ 
+SELECT op code OF
+  CASE c document : open document 
+  CASE c page     : open page
+END SELECT; 
+ 
+ 
+. x steps : param1
+. y steps : param2
+. 
+  open document :
+    IF pos (material, "landscape") > 0 OR pos (material, "quer") > 0
+       THEN is landscape := TRUE;
+            x steps      := x step conversion ( y size );
+            y steps      := y step conversion ( x size );
+       ELSE is landscape := FALSE;
+            x steps      := x step conversion ( x size );
+            y steps      := y step conversion ( y size );
+    FI;
+    forget (ps input name, quiet);
+    ps input     := sequential file (output, ps input name);
+    paper length := y steps;
+    font no      := 0;
+    underline no := 0;
+    disable stop;
+    out (""4"");
+    read ps input (ps input, 18000, ""4"");
+    clear error;
+    enable stop;
+    out ("initgraphics erasepage statusdict /waittimeout 3000 put ");
+    load positioning procs;
+    load underline procs;
+    load italics procs;
+    load encoding;
+    read ps input (ps input, 0, "");
+ 
+. x start : param1
+. y start : param2
+. 
+  open page :
+    x start := 0;
+    y start := 0;
+    IF   pos (material, "tray") > 0
+         THEN out ("statusdict /manualfeed false put ");
+    ELIF pos (material, "manual") > 0
+         THEN out ("statusdict /manualfeed true put statusdict /manualfeedtimeout 3600 put ");
+    FI;
+    IF material contains a number
+       THEN out ("/#copies "); out (number); out ("def ");
+    FI;
+    IF is landscape
+       THEN out (paper length);
+            out ("ys 0 translate 90 rotate ");
+    FI;
+    read ps input (ps input, 0, "");
+ 
+    . material contains a number :
+        INT VAR number := pos (material, "0", "9", 1);
+        IF number = 0
+           THEN FALSE
+           ELSE number := max (1, int (subtext (material, number, number + 1)));
+                TRUE
+        FI
+ 
+END PROC open; 
+ 
+ 
+PROC close (INT CONST op code, INT CONST param1) :
+ 
+SELECT op code OF
+  CASE c document : close document 
+  CASE c page     : close page
+  OTHERWISE : put (param1)
+END SELECT; 
+ 
+. 
+  close document :
+    disable stop;
+    out (""4"");
+    read ps input (ps input, 18000, ""4"");
+
+ 
+(*. remaining y steps : param1*)
+.
+  close page :
+    outline ("showpage"); 
+    read ps input (ps input, 0, "");
+ 
+END PROC close;
+ 
+ 
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+ 
+SELECT op code OF
+  CASE c write text       :  write text
+  CASE c write cmd        :  write cmd
+  CASE c carriage return  :  carriage return
+  CASE c move             :  move
+  CASE c draw             :  draw
+  CASE c on               :  on
+  CASE c off              :  off
+  CASE c type             :  type
+END SELECT
+
+ 
+. from : param1
+. to   : param2
+.
+  write text :
+    out ("(");
+    out subtext (string, from, to);
+    out (") show ");
+.
+  write cmd :
+    command := subtext (string, from, to);
+    IF is box cmd
+       THEN disable stop;
+            do (command);
+            clear error;
+       ELSE out (command);
+            out (" ");
+    FI;
+ 
+    . is box cmd :
+        scan (command);
+        next symbol (symbol, symbol type);
+        (symbol type = tag type) CAND (box cmds CONTAINS symbol)
+ 
+ 
+(*. x steps to left margin : param1*)
+.
+  carriage return :
+    move to (0, y pos);
+    line;
+    read ps input (ps input, 0, "");
+ 
+
+. x steps : param1
+. y steps : param2
+
+.
+  move :
+    move to (x pos, y pos);
+ 
+. 
+  draw :
+    IF y steps <> 0 COR x steps < 0 COR linetype <> underline linetype
+       THEN stop
+       ELSE IF underline no <> font no THEN out ("lu ") FI;
+            out (x steps); 
+            out ("ul ");
+    FI;
+
+ 
+. modification : param1
+.
+  on :
+    IF on string (modification) <> ""
+       THEN out (on string (modification));
+            out (" ");
+       ELSE stop
+    FI
+ 
+.
+  off :
+    IF off string (modification) <> ""
+       THEN out (off string (modification));
+            out (" ");
+       ELSE stop
+    FI
+ 
+ 
+. font nr : param1
+.
+  type :
+    font no := font nr;
+    out (fontstring (font nr));
+    out (" /af exch def af setfont ");
+ 
+END PROC execute;
+ 
+ 
+PROC move to (INT CONST x, y) :
+
+  out (x);                out ("xs ");
+  out (paper length - y); out ("ys moveto ");
+
+END PROC move to;
+
+
+PROC line                        : out (""13""10"")               END PROC line;
+
+PROC outline (TEXT CONST string) : out (string); out (""13""10"") END PROC outline;
+
+PROC out     (INT  CONST value)  : out (text (value)); out (" ")  END PROC out;
+
+PROC out     (REAL CONST value)  : out (text (value)); out (" ")  END PROC out;
+
+
+PROC load positioning procs :
+
+  out ("/xs {"); out (72.0 / 2.54 * x step conversion (1)); out ("mul} def ");
+  out ("/ys {"); out (72.0 / 2.54 * y step conversion (1)); out ("mul} def ");
+
+END PROC load positioning procs;
+
+
+PROC load underline procs :
+
+  out ("/ul {xs ut setlinewidth 0 up rmoveto dup gsave 0 rlineto stroke grestore up neg rmoveto} def ");
+  out ("/lu {af /FontMatrix get 3 get af /FontInfo get 2 copy /up 3 1 roll /UnderlinePosition get mul 3 mul def /ut 3 1 roll /UnderlineThickness get mul def} def ");
+
+END PROC load underline procs;
+
+
+PROC load italics procs :
+
+  out ("/iton {/m matrix def m 2 12 sin 12 cos div put af m makefont setfont} def ");
+  out ("/itoff {af setfont} def ");
+
+END PROC load italics procs;
+
+
+PROC load encoding :
+
+  out ("/reencsmalldict 12 dict def ");
+  out ("/ReEncodeSmall {reencsmalldict begin ");
+  out ("/newcodesandnames exch def /newfontname exch def /basefontname exch def ");
+  out ("/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def ");
+  out ("basefontdict {exch dup /FID ne {dup /Encoding eq {exch dup length array copy newfont 3 1 roll put} {exch newfont 3 1 roll put} ifelse} {pop pop} ifelse} forall ");
+  out ("newfont /FontName newfontname put newcodesandnames aload pop newcodesandnames length 2 idiv {newfont /Encoding get 3 1 roll put} repeat ");
+  out ("newfontname newfont definefont pop ");
+  out ("end} def ");
+  out ("/eumelencoding[10#128 /Ccedilla 10#129 /udieresis 10#128 /Ccedilla 10#129 /udieresis ");
+  out ("10#130 /eacute 10#131 /acircumflex 10#132 /adieresis 10#133 /agrave 10#134 /aring 10#135 /ccedilla 10#136 /ecircumflex 10#137 /edieresis 10#138 /egrave 10#139 /idieresis ");
+  out ("10#140 /icircumflex 10#141 /igrave 10#142 /Adieresis 10#143 /Aring 10#144 /Eacute 10#145 /ae 10#146 /AE 10#147 /ocircumflex 10#148 /odieresis 10#149 /ograve ");
+  out ("10#150 /ucircumflex 10#151 /ugrave 10#152 /ydieresis 10#153 /Odieresis 10#154 /Udieresis 10#155 /cent 10#156 /sterling 10#157 /yen 10#158 /currency 10#159 /florin ");
+  out ("10#160 /aacute 10#161 /iacute 10#162 /oacute 10#163 /uacute 10#164 /ntilde 10#165 /Ntilde 10#166 /ordfeminine 10#167 /ordmasculine 10#168 /questiondown 10#169 /quotedblleft ");
+  out ("10#170 /quotedblright 10#171 /guilsinglleft 10#172 /guilsinglright 10#173 /exclamdown 10#174 /guillemotleft 10#175 /guillemotright 10#176 /atilde 10#177 /otilde 10#178 /Oslash 10#179 /oslash ");
+  out ("10#180 /oe 10#181 /OE 10#182 /Agrave 10#183 /Atilde 10#184 /Otilde 10#185 /section 10#186 /daggerdbl 10#187 /dagger 10#188 /paragraph 10#189 /space ");
+  out ("10#190 /space 10#191 /space 10#192 /quotedblbase 10#193 /ellipsis 10#194 /perthousand 10#195 /bullet 10#196 /endash 10#197 /emdash 10#198 /space 10#199 /Aacute ");
+  out ("10#200 /Acircumflex 10#201 /Egrave 10#202 /Ecircumflex 10#203 /Edieresis 10#204 /Igrave 10#205 /Iacute 10#206 /Icircumflex 10#207 /Idieresis 10#208 /Ograve 10#209 /Oacute ");
+  out ("10#210 /Ocircumflex 10#211 /Scaron 10#212 /scaron 10#213 /Ugrave 10#214 /Adieresis 10#215 /Odieresis 10#216 /Udieresis 10#217 /adieresis 10#218 /odieresis 10#219 /udieresis ");
+  out ("10#220 /k 10#221 /hyphen 10#222 /numbersign 10#223 /space 10#224 /grave 10#225 /acute 10#226 /circumflex 10#227 /tilde 10#228 /dieresis 10#229 /ring ");
+  out ("10#230 /cedilla 10#231 /caron 10#232 /Lslash 10#233 /Oslash 10#234 /OE 10#235 /ordmasculine 10#236 /Uacute 10#237 /Ucircumflex 10#238 /Ydieresis 10#239 /germandbls ");
+  out ("10#240 /Zcaron 10#241 /zcaron 10#242 /fraction 10#243 /ae ");
+  out ("10#251 /germandbls 10#252 /section] def ");
+  out ("/Helvetica /EHelvetica eumelencoding ReEncodeSmall ");
+  out ("/Helvetica-Bold /EHelvetica-Bold eumelencoding ReEncodeSmall ");
+  out ("/Helvetica-Oblique /EHelvetica-Oblique eumelencoding ReEncodeSmall ");
+  out ("/Helvetica-BoldOblique /EHelvetica-BoldOblique eumelencoding ReEncodeSmall ");
+  out ("/Times-Roman /ETimes-Roman eumelencoding ReEncodeSmall ");
+  out ("/Times-Bold /ETimes-Bold eumelencoding ReEncodeSmall ");
+  out ("/Times-Italic /ETimes-Italic eumelencoding ReEncodeSmall ");
+  out ("/Times-BoldItalic /ETimes-BoldItalic eumelencoding ReEncodeSmall ");
+  out ("/Courier /ECourier eumelencoding ReEncodeSmall ");
+  out ("/Courier-Oblique /ECourier-Oblique eumelencoding ReEncodeSmall ");
+  out ("/Courier-BoldOblique /ECourier-BoldOblique eumelencoding ReEncodeSmall ");
+  out ("/Courier-Bold /ECourier-Bold eumelencoding ReEncodeSmall ");
+  line;
+
+END PROC load encoding;
+
+
+PROC read ps input (FILE VAR input file, INT CONST timeout, TEXT CONST ok) :
+
+  BOOL VAR was cr;
+  record := "";
+  was cr := FALSE;
+  char   := incharety (timeout);
+  REP IF   char = ""10"" CAND was cr
+           THEN put record;
+                was cr := FALSE;
+      ELIF char = ""13"" CAND NOT was cr
+           THEN was cr := TRUE;
+           ELSE IF was cr
+                   THEN record CAT """13""";
+                        was cr := FALSE;
+                FI;
+                IF   char = ""4""
+                     THEN IF record <> "" THEN put record FI;
+                          putline (input file, "--  EOF  --");
+                          line (input file);
+                ELIF char >= " "
+                     THEN record CAT char
+                ELIF char >= ""0""
+                     THEN record CAT """";
+                          record CAT text (code (char));
+                          record CAT """";
+                     ELSE IF record <> "" THEN put record FI;
+                          LEAVE read ps input;
+                FI;
+      FI;
+      IF pos (ok, char) > 0
+         THEN IF record <> "" THEN put record FI;
+              LEAVE read ps input;
+      FI;
+      cat input (record, char);
+      IF char = "" THEN char := incharety (min (5, time out)) FI;
+  PER;
+
+  . put record :
+      putline (input file, record);
+      IF NOT is error CAND pos (record, "%%[ Error:") > 0
+         THEN errorstop (ps error, record) FI;
+      record := "";
+
+END PROC read ps input; 
+
+
+PROC print error (TEXT CONST error message, INT CONST error line) :
+
+  REAL CONST pl := y size * 72.0 / 2.54,
+             ys := 56.69291,
+             xs := 51.02362,
+             h  := 12.0;
+  REAL VAR x := xs, y := ys + h;
+  outline ("/Courier findfont 10 scalefont setfont");
+  move to x and y;
+  out     ("(FEHLER : ");
+  out     (error message);
+  IF error line > 0
+     THEN out (" in Zeile ");
+          out (error line);
+  FI;
+  outline (") show");
+  IF exists (ps input name)
+     THEN ps input := sequential file (input, ps input name);
+          y INCR 3.0 * h;
+          move to x and y;
+          outline ("(PostScript - Input :) show");
+          y INCR h;
+          WHILE NOT eof (ps input)
+          REP getline (ps input, record);
+              y INCR h;
+              move to x and y;
+              out     ("(");
+              out     (record);
+              outline (") show");
+          PER;
+          output (ps input);
+  FI;
+  outline ("showpage");
+  out (""4"");
+  read ps input (ps input, 18000, ""4"");
+
+  . move to x and y :
+      out (x); out (pl - y); out ("moveto ");
+
+END PROC print error;
+
+
+END PACKET apple laser writer printer;
+
+
+PACKET apple laserwriter box commands 
+
+(**************************************************************************)
+(*                                                                        *)
+(*      Kommandos zum Zeichen von Boxen, Linien und Schraffuren           *)
+(*                für den Apple LaserWriter                               *)
+(*                                                                        *)
+(*                                                Autor   : Rudolf Ruland *)
+(*                                                Stand   : 24.02.88      *)
+(**************************************************************************)
+
+       DEFINES line,
+               x line,
+               y line,
+
+               box,
+               box frame,
+               box shade,
+
+               cake,
+               cake frame,
+               cake shade,
+               :
+
+INT VAR x, y, h, w;
+
+WHILE highest entry (box commands) > 0
+  REP delete box command (name (box commands, highest entry (box commands))) PER;
+insert box command ("line");
+insert box command ("xline");
+insert box command ("yline");
+insert box command ("box");
+insert box command ("boxshade");
+insert box command ("boxframe");
+insert box command ("cake");
+insert box command ("cakeshade");
+insert box command ("cakeframe");
+
+
+PROC line (REAL CONST x offset, y offset, width, height, line width) :
+
+  IF line width > 0.0
+     THEN graph on (x offset, y offset, width, height);
+          out (text (line width / 300.0 * 72.0));
+          out (" setlinewidth ");
+          out (text (w));
+          out (" xs ");
+          out (text (-h));
+          out (" ys rlineto stroke ");
+          graph off;
+  FI;
+
+END PROC line;
+
+PROC x line (REAL CONST x offset, y offset, width, line width) :
+
+  line (x offset, y offset, width, 0.0, line width);
+
+END PROC x line;
+
+PROC y line (REAL CONST x offset, y offset, height, line width) :
+
+  line (x offset, y offset, 0.0, height, line width);
+
+END PROC y line;
+
+
+PROC box (REAL CONST x offset, y offset, width, height, line width, pattern):
+
+  box shade (x offset, y offset, width, height, pattern);
+  box frame (x offset, y offset, width, height, line width);
+
+END PROC box;
+
+
+PROC box shade (REAL CONST x offset, y offset, width, height, pattern) :
+
+  graph on (x offset, y offset, width, height);
+  box path;
+  out (text (pattern));
+  out (" setgray fill ");
+  graph off;
+
+END PROC box shade;
+
+
+PROC box frame (REAL CONST x offset, y offset, width, height, line width) :
+
+  IF line width <> 0.0
+     THEN graph on (x offset, y offset, width, height);
+          box path;
+          out (text (line width / 300.0 * 72.0));
+          out (" setlinewidth stroke ");
+          graph off;
+   FI;
+
+END PROC box frame;
+
+
+PROC box path :
+
+  out (text (w));
+  out (" xs 0 rlineto 0 ");
+  out (text (-h));
+  out (" ys rlineto ");
+  out (text (-w));
+  out (" xs 0 rlineto closepath ");
+
+END PROC box path;
+
+
+
+PROC cake (REAL CONST x offset, y offset, radius, start angle, sweep angle, line width, pattern) :
+
+  cake shade (x offset, y offset, radius, start angle, sweep angle, pattern);
+  cake frame (x offset, y offset, radius, start angle, sweep angle, line width);
+
+END PROC cake;
+
+
+PROC cake shade (REAL CONST x offset, y offset, radius, start angle, sweep angle, pattern) :
+
+  graph on (x offset, y offset, radius, 0.0);
+  cake path (start angle, sweep angle);
+  out (text (pattern));
+  out (" setgray fill ");
+  graph off;
+
+END PROC cake shade;
+
+
+PROC cake frame (REAL CONST x offset, y offset, radius, start angle, sweep angle, line width) :
+
+
+  IF line width <> 0.0
+     THEN graph on (x offset, y offset, radius, 0.0);
+          cake path (start angle, sweep angle);
+          out (text (line width / 300.0 * 72.0));
+          out (" setlinewidth stroke ");
+          graph off;
+   FI;
+
+END PROC cake frame;
+
+
+PROC cake path (REAL CONST start angle, sweep angle) :
+
+  out (text (start angle));
+  out (" rotate ");
+  out ("currentpoint ");
+  out (text (w));
+  out (" xs 0 ");
+  out (text (sweep angle));
+  out (" ");
+  IF sweep angle < 360.0
+     THEN out ("2 setlinejoin arc closepath ");
+     ELSE out (text (w));
+          out (" xs 0 rmoveto arc ");
+  FI;
+
+END PROC cake path;
+
+
+PROC graph on (REAL CONST x offset, y offset, width, height) :
+
+  x := x step conversion (x offset);
+  y := y step conversion (y offset);
+  w := x step conversion (width);
+  h := y step conversion (height);
+  out ("gsave ");
+  out (text (x));
+  out (" xs ");
+  out (text (-y));
+  out (" ys rmoveto ");
+
+END PROC graph on;
+
+PROC graph off :
+
+  out ("grestore ");
+
+END PROC graph off;
+
+
+END PACKET apple laserwriter box commands;
+
+
+ 
+#page# 
+(******************************************************************)
+(***                                                            ***)
+(***   Generierung des Printers                                 ***)
+(***                                                            ***)
+(******************************************************************)
+(* 
+LET up = ""3""13""5"";
+*) 
+LET      printer name  = "printer.apple.laserwriter";
+TEXT VAR fonttab name := "fonttab.apple.laserwriter";
+ 
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+ 
+INT VAR pr channel;
+TEXT VAR buffer;
+ 
+command dialogue (TRUE);
+IF NOT multi user 
+  THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL") 
+FI; 
+ask for print channel;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+command dialogue (TRUE);
+check on;
+.
+  ask for print channel : 
+    line;
+    put ("gib Druckerkanal:");
+    get (pr channel);
+    do ("serverchannel(" + text (pr channel) + ")" ) ;
+    line;
+.
+  load font table :
+    IF NOT exists (fonttab name)
+       THEN REP line (2); 
+                putline ("Bitte Archiv mit der Fonttabelle """ +
+                          fonttab name + """ einlegen!");
+                line;
+            UNTIL yes ("Archiv eingelegt") PER;
+            reserve archive;
+            fetch (fonttab name, archive);
+            release (archive);
+    FI;
+    font table (fonttab name);
+    IF multi user
+       THEN command dialogue (FALSE);
+            do ("save(""" + font tab name + """,task(""configurator""))")
+    FI;
+    forget (fonttab name, quiet);
+ 
+    . reserve archive :
+        INT VAR p1, p2;
+        archive (" "31" ");
+        disable stop;
+        list (archive);
+        IF is error
+           THEN buffer := errormessage;
+                p1 := pos (buffer, """", 1 ) + 1;
+                p2 := pos (buffer, """", p1) - 1;
+                IF p1 > 0 AND p2 > 0
+                   THEN clear error;
+                        buffer := subtext (buffer, p1, p2);
+                        archive (buffer);
+                FI;
+        FI;
+        enable stop;
+ 
+. generate printer spool :
+    eumel must advertise;
+    cursor (1, 12);
+    putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+    putline ("die Fonttabelle mit dem Kommando");
+    line;
+    putline ("      font table (""" + font tab name + """)");
+    line;
+    putline ("eingestellt werden!!!");
+    line (4);
+    putline ("Generierung beendet, weiter mit 'SV'");
+    generate printer server;
+    do (buffer);
+ 
+. generate printer server :
+    buffer :=  "break (quiet);";
+    buffer CAT "spool manager (PROC printer);";
+    buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+    buffer CAT "PROC printer:";
+    buffer CAT "  disable stop;";
+    buffer CAT "  continue (server channel);";
+    buffer CAT "  check error (error message);";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  REP forget (ds);";
+    buffer CAT "      execute print;";
+    buffer CAT "      IF is error AND online THEN clear error; print error (error message, 0); clear error FI;";
+    buffer CAT "  PER;";
+    buffer CAT "END PROC printer;";
+    buffer CAT "PROC execute print:";
+    buffer CAT "  LET ack = 0, fetch code = 11, file type = 1003;";
+    buffer CAT "  enable stop;";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  call (father, fetch code, ds, reply);";
+    buffer CAT "  IF reply = ack CAND type (ds) = file type";
+    buffer CAT "     THEN file := sequential file (input, ds);";
+    buffer CAT "          print (file,";
+    buffer CAT "            PROC (INT CONST, INT VAR, INT VAR) open,";
+    buffer CAT "            PROC (INT CONST, INT CONST) close,";
+    buffer CAT "            PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC execute print;";
+    buffer CAT "PROC check error(TEXT CONST message):";
+    buffer CAT "  IF is error";
+    buffer CAT "     THEN clear error; rename myself (message);";
+    buffer CAT "          IF is error THEN end(myself) FI;";
+    buffer CAT "          pause (9000); end(myself);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC check error;";
+
diff --git a/printer/laser/printer.canon.lbp-8 b/printer/laser/printer.canon.lbp-8
new file mode 100644
index 0000000..4dfe9f8
--- /dev/null
+++ b/printer/laser/printer.canon.lbp-8
@@ -0,0 +1,327 @@
+PACKET canon lbp 8 printer
+ 
+(*************************************************************************)
+(*                                               Stand   : 29.07.86      *)
+(*   CANON  LBP-8  A1/A2                         Version : 4             *)
+(*                                               Autor   : Rudolf Ruland *)
+(*************************************************************************)
+ 
+ 
+       DEFINES open,
+               close,
+               execute,
+ 
+               paper size :
+ 
+LET underline           =  1,
+(*  bold                =  2,
+    italics             =  4,
+    reverse             =  8,
+ 
+    underline linetype  =  1, *)
+
+    csi                 =  ""155"",
+ 
+    c document          =  1,
+    c page              =  2,
+ 
+    c write text        =  1,
+    c write cmd         =  2,
+    c carriage return   =  3, 
+    c move              =  4,
+    c draw              =  5,
+    c on                =  6, 
+    c off               =  7,
+    c type              =  8;
+ 
+REAL VAR x size, y size;
+BOOL VAR is underline;
+ 
+(*********************************************************************)
+ 
+paper size (21.0, 29.7);
+ 
+PROC paper size (REAL CONST x, y) :
+ 
+  x size := x;
+  y size := y;
+ 
+END PROC paper size;
+ 
+PROC paper size : 
+ 
+  line;
+  putline ("Papierbreite  =  " + text (x size, 5, 2) + " cm  =  " + text (x size / 2.54, 5, 2) + " Zoll");
+  putline ("Papierlaenge  =  " + text (y size, 5, 2) + " cm  =  " + text (y size / 2.54, 5, 2) + " Zoll");
+ 
+END PROC paper size;
+ 
+(*********************************************************************)
+
+PROC open (INT CONST op code, INT VAR param1, param2) :
+ 
+SELECT op code OF
+  CASE c document : open document 
+  CASE c page     : open page
+END SELECT; 
+ 
+ 
+. x steps : param1
+. y steps : param2
+. 
+  open document :
+    is underline := FALSE;
+    x steps := x step conversion ( x size - 0.8043333 );
+    y steps := y step conversion ( y size - 0.508);
+    out (""27":"27"P"13"");             (* Enable - Prop.Type *)
+    out (""27";"27"<"155"11h");         (* Reset des Druckers *)
+    out (""27"(B");                     (* ACSII-Zeichensatz  *)
+    out (""155"1;4 D");                 (* Char.Satz 1 = PICA *)
+ 
+. x start : param1
+. y start : param2
+. 
+  open page :
+    x start := x step conversion (0.4064 );
+    y start := y step conversion (0.508  + 0.6345);
+    out (""13"");
+ 
+END PROC open; 
+ 
+ 
+PROC close (INT CONST op code, INT CONST param1) :
+ 
+SELECT op code OF
+  CASE c document : close document 
+  CASE c page     : close page
+  OTHERWISE : put (param1)
+END SELECT; 
+ 
+. 
+  close document :
+   (*  out(""155"0q")    von Standard-Cassette Papier holen *)
+ 
+(*. remaining y steps : param1*)
+.
+  close page :
+    out (""13""12"");
+ 
+END PROC close;
+ 
+ 
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+ 
+SELECT op code OF
+  CASE c write text       :  write text
+  CASE c write cmd        :  write cmd
+  CASE c carriage return  :  carriage return
+  CASE c move             :  move
+  CASE c draw             :  draw
+  CASE c on               :  on
+  CASE c off              :  off
+  CASE c type             :  type
+END SELECT
+
+ 
+. from : param1
+. to   : param2
+.
+  write text :
+    INT VAR new from, new to;
+    IF is underline
+       THEN IF pos (string, " ", from, from) <> 0
+               THEN out ("_");
+                    new from := from + 1;
+               ELSE new from := from;
+            FI;
+            IF from < to AND pos (string, " ", to, to) <> 0
+               THEN new to := to - 1;
+               ELSE new to := to;
+            FI;
+            out subtext (string, new from, new to);
+            IF to <> new to THEN out ("_") FI;
+       ELSE out subtext (string, from, to)
+    FI;
+ 
+.
+  write cmd :
+    out subtext (string, from, to)
+ 
+ 
+(*. x steps to left margin : param1*)
+.
+  carriage return :
+    out (""13"")
+ 
+ 
+. x steps : param1
+. y steps : param2
+.
+  move :
+    IF   x steps > 0
+         THEN out (csi); out (text (  x steps)); out ("a")
+    ELIF x steps < 0
+         THEN out (csi); out (text (- x steps)); out ("j")
+    FI;
+    IF   y steps > 0
+         THEN out (csi); out (text (  y steps)); out ("e")
+    ELIF y steps < 0
+         THEN out (csi); out (text (- y steps)); out ("k")
+    FI;
+ 
+. 
+  draw :
+    stop
+ 
+ 
+. modification : param1
+.
+  on :
+    IF on string (modification) <> ""
+       THEN out (on string (modification));
+            IF modification = underline THEN is underline := TRUE FI; 
+       ELSE stop
+    FI
+ 
+.
+  off :
+    IF off string (modification) <> ""
+       THEN out (off string (modification));
+            IF modification = underline THEN is underline := FALSE FI; 
+       ELSE stop
+    FI
+ 
+ 
+. font nr : param1
+.
+  type :
+    out (font string (font nr));
+ 
+END PROC execute;
+ 
+ 
+END PACKET canon lbp 8 printer;
+ 
+ 
+ 
+#page# 
+(******************************************************************)
+(***                                                            ***)
+(***   Generierung des Printers                                 ***)
+(***                                                            ***)
+(******************************************************************)
+ 
+LET printer name = "printer.canon.lbp-8";
+ 
+TEXT VAR fonttab name := "fonttab.canon.lbp-8";
+ 
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+ 
+INT VAR pr channel;
+TEXT VAR buffer;
+ 
+command dialogue (TRUE);
+IF NOT multi user 
+  THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL") 
+FI; 
+ask for print channel;
+ask for font cartridge;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+check on;
+.
+  ask for print channel :
+    line;
+    put ("gib Druckerkanal:");
+    get (pr channel);
+    do ("serverchannel(" + text (pr channel) + ")" ) ;
+    line;
+. 
+  ask for font cartridge :
+.
+  load font table :
+    IF NOT exists (fonttab name)
+       THEN command dialogue (TRUE); 
+            REP line (2); 
+                putline ("Bitte Archiv mit der Fonttabelle """ +
+                          fonttab name + """ einlegen!");
+                line;
+            UNTIL yes ("Archiv eingelegt") PER;
+            reserve archive;
+            fetch (fonttab name, archive);
+            release (archive);
+    FI;
+    font table (fonttab name);
+    IF multi user
+       THEN command dialogue (FALSE); 
+            do ("save(""" + font tab name + """,task(""configurator""))") 
+    FI;
+    forget (fonttab name, quiet);
+ 
+    . reserve archive :
+        INT VAR p1, p2;
+        archive (" "31" ");
+        disable stop;
+        list (archive);
+        IF is error
+           THEN buffer := errormessage;
+                p1 := pos (buffer, """", 1 ) + 1;
+                p2 := pos (buffer, """", p1) - 1;
+                IF p1 > 0 AND p2 > 0
+                   THEN clear error;
+                        buffer := subtext (buffer, p1, p2);
+                        archive (buffer);
+                FI;
+        FI;
+        enable stop;
+ 
+. generate printer spool :
+    eumel must advertise;
+    cursor (1, 12);
+    putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+    putline ("die Fonttabelle mit dem Kommando");
+    line;
+    putline ("      font table (""" + font tab name + """)");
+    line;
+    putline ("eingestellt werden!!!");
+    line (4);
+    putline ("Generierung beendet, weiter mit 'SV'");
+    generate printer server;
+    do (buffer);
+ 
+. generate printer server :
+    buffer :=  "break (quiet);";
+    buffer CAT "spool manager (PROC printer);";
+    buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+    buffer CAT "PROC printer:";
+    buffer CAT "  disable stop;";
+    buffer CAT "  continue (server channel);";
+    buffer CAT "  check error (error message);";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  REP forget (ds);";
+    buffer CAT "      execute print;";
+    buffer CAT "      IF is error AND online THEN put error; clear error; FI;";
+    buffer CAT "  PER;";
+    buffer CAT "END PROC printer;";
+    buffer CAT "PROC execute print:";
+    buffer CAT "  LET ack = 0, fetch code = 11, file type = 1003;";
+    buffer CAT "  enable stop;";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  call (father, fetch code, ds, reply);";
+    buffer CAT "  IF reply = ack CAND type (ds) = file type";
+    buffer CAT "     THEN file := sequential file (input, ds);";
+    buffer CAT "          print (file,";
+    buffer CAT "            PROC (INT CONST, INT VAR, INT VAR) open,";
+    buffer CAT "            PROC (INT CONST, INT CONST) close,";
+    buffer CAT "            PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC execute print;"; 
+    buffer CAT "PROC check error(TEXT CONST message):";
+    buffer CAT "  IF is error";
+    buffer CAT "     THEN clear error; rename myself (message);";
+    buffer CAT "          IF is error THEN end(myself) FI;"; 
+    buffer CAT "          pause (9000); end(myself);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC check error;"; 
+
diff --git a/printer/laser/printer.epson.sq b/printer/laser/printer.epson.sq
new file mode 100644
index 0000000..63e474f
--- /dev/null
+++ b/printer/laser/printer.epson.sq
@@ -0,0 +1,585 @@
+PACKET epson sq printer
+ 
+(**************************************************************************)
+(*                                                Stand   : 03.12.86      *)
+(*   EPSON  SQ-2500                               Version : 4             *)
+(*                                                Autor   : Rudolf Ruland *)
+(**************************************************************************)
+ 
+       DEFINES open,
+               close,
+               execute,
+ 
+               paper size,
+           (*  paper feed,    *)  (* <-- nicht getestet *)
+               std typeface,
+               std quality:
+ 
+LET
+(*  underline           =  1,
+    bold                =  2,
+    italics             =  4,
+    reverse             =  8, *)
+ 
+    underline linetype  =  1,
+ 
+    c document          =  1,
+    c page              =  2,
+ 
+    c write text        =  1,           cmd draft      =  1,
+    c write cmd         =  2,           cmd nlq        =  2,
+    c carriage return   =  3,           cmd roman      =  3,
+    c move              =  4,           cmd sansserif  =  4,
+    c draw              =  5,           cmd courier    =  5,
+    c on                =  6,           cmd prestige   =  6,
+    c off               =  7,           cmd script     =  7,
+    c type              =  8;
+ 
+INT VAR font nr, x rest, high, low, font bits, modification bits, blank pitch,
+        factor 1, factor 2, steps;
+BOOL VAR is nlq, sheet feed;
+REAL VAR x size, y size;
+TEXT VAR std quality name, std typeface name, buffer, symbol, font text;
+THESAURUS VAR commands := empty thesaurus;
+
+insert (commands, "draft");
+insert (commands, "nlq");
+insert (commands, "roman");
+insert (commands, "sansserif");
+insert (commands, "courier");
+insert (commands, "prestige");
+insert (commands, "script");
+
+. is prop        : bit (font bits, 1)
+. is double      : bit (font bits, 5)
+.;
+ 
+(*********************************************************************)
+ 
+paper size  (13.6 * 2.54, 12.0 * 2.54);
+paper size  ( 8.0 * 2.54, 12.0 * 2.54);
+paper feed ("tractor");
+std typeface ("roman");
+std quality ("draft");
+ 
+PROC paper size (REAL CONST x, y) :
+ 
+  x size := x;
+  y size := y;
+ 
+END PROC paper size;
+ 
+PROC paper size : 
+ 
+  line;
+  putline ("Papierbreite  =  " + text (x size, 5, 2) + " cm  =  " + text (x size / 2.54, 5, 2) + " Zoll");
+  putline ("Papierlaenge  =  " + text (y size, 5, 2) + " cm  =  " + text (y size / 2.54, 5, 2) + " Zoll");
+ 
+END PROC paper size;
+ 
+ 
+PROC paper feed (TEXT CONST paper) :
+ 
+  IF   pos (paper, "sheet") <> 0
+       THEN sheet feed := TRUE;
+  ELIF pos (paper, "tractor") <> 0
+       THEN sheet feed := FALSE;
+       ELSE errorstop ("unzulaessige Papiereinfuehrung")
+  FI;
+ 
+END PROC paper feed;
+ 
+TEXT PROC paper feed :
+ 
+  IF sheet feed
+     THEN "sheet"
+     ELSE "tractor"
+  FI
+
+END PROC paper feed;
+ 
+ 
+PROC std typeface (TEXT CONST typeface) :
+ 
+  buffer := typeface;
+  changeall (buffer, " ", "");
+  IF link (commands, buffer) >= cmd roman
+     THEN std typeface name := buffer
+     ELSE errorstop ("unzulaessige Schriftart")
+  FI;
+ 
+END PROC std typeface;
+ 
+TEXT PROC std typeface : std typeface name END PROC std typeface;
+ 
+ 
+PROC std quality (TEXT CONST quality) :
+ 
+  IF quality = "nlq" OR quality = "draft"
+     THEN std quality name := quality;
+     ELSE errorstop ("unzulaessige Betriebsart")
+  FI;
+ 
+END PROC std quality;
+ 
+TEXT PROC std quality : std quality name END PROC std quality;
+ 
+(*********************************************************************)
+ 
+PROC open (INT CONST op code, INT VAR param1, param2) :
+ 
+SELECT op code OF
+  CASE c document : open document 
+  CASE c page     : open page
+END SELECT; 
+ 
+ 
+. x steps : param1
+. y steps : param2
+. 
+  open document :
+    x steps := x step conversion ( x size );
+    y steps := y step conversion ( y size );
+    y steps := (y steps DIV 30) * 30;
+    modification bits := 0;
+    out (""24""27""64"");                  (* Reset des Druckers            *)
+    out (""27"C" + code (y steps DIV 30)); (* Formularlaenge                *)
+    out (""27"x"0"");                      (* Entwurfsqualität              *) 
+    out (""27"R"0"");                      (* Amerikanischer Zeichensatz    *)
+    out (""27"t"1""27"6");                 (* Erweiterung des Zeichensatzes *)
+    IF sheet feed THEN out (""27""25"4") FI; (* Sheetmode ein               *)
+    IF   pos (material, "roman") <> 0
+         THEN out (""27"k"0"")
+    ELIF pos (material, "sansserif") <> 0
+         THEN out (""27"k"1"")
+    ELIF pos (material, "courier") <> 0
+         THEN out (""27"k"2"")
+    ELIF pos (material, "prestige") <> 0
+         THEN out (""27"k"3"")
+    ELIF pos (material, "script") <> 0
+         THEN out (""27"k"4"")
+         ELSE out (""27"k" + code (link (commands, std typeface) - cmd roman));
+    FI;
+    IF   pos (material, "nlq") <> 0 
+         THEN is nlq := TRUE;
+    ELIF pos (material, "draft") <> 0 
+         THEN is nlq := FALSE;
+         ELSE is nlq := std quality = "nlq"
+    FI;
+ 
+ 
+. x start : param1
+. y start : param2
+. 
+  open page :
+    x start := 0;
+    IF sheet feed
+       THEN y start := y step conversion (8.466667e-1)    (* 2/6 Inch *)
+       ELSE y start := 0;
+    FI;
+    x rest  := 0;
+    out (""13"");
+ 
+END PROC open;
+ 
+ 
+PROC close (INT CONST op code, INT CONST param1) :
+ 
+SELECT op code OF
+  CASE c document : close document 
+  CASE c page     : close page
+END SELECT; 
+ 
+. 
+  close document :
+ 
+ 
+. remaining y steps : param1
+.
+  close page :
+    IF   sheet feed
+         THEN out (""27""25"R")
+    ELIF remaining y steps > 0
+         THEN out (""12"")
+    FI;
+ 
+END PROC close;
+ 
+ 
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+ 
+SELECT op code OF
+  CASE c write text       :  write text
+  CASE c write cmd        :  write cmd
+  CASE c carriage return  :  carriage return
+  CASE c move             :  move
+  CASE c draw             :  draw
+  CASE c on               :  on
+  CASE c off              :  off
+  CASE c type             :  type
+END SELECT
+
+ 
+. from : param1
+. to   : param2
+.
+  write text :
+    out subtext (string, from, to)
+ 
+.
+  write cmd :
+    buffer := subtext (string, from, to);
+    scan (buffer);
+    next symbol (symbol);
+    SELECT link (commands, symbol) OF
+      CASE cmd draft     : IF     is nlq THEN switch to draft FI; is nlq := FALSE;
+      CASE cmd nlq       : IF NOT is nlq THEN switch to nlq   FI; is nlq := TRUE;
+      CASE cmd roman     : out (""27"k"0"")
+      CASE cmd sansserif : out (""27"k"1"")
+      CASE cmd courier   : out (""27"k"2"")
+      CASE cmd prestige  : out (""27"k"3"")
+      CASE cmd script    : out (""27"k"4"")
+      OTHERWISE : out (buffer);
+    END SELECT;
+ 
+ 
+(*. x steps to left margin : param1*)
+.
+  carriage return :
+    x rest := 0;
+    out (""13"");
+ 
+ 
+. x steps : param1
+. y steps : param2
+.
+  move :
+    IF x steps < 0 OR y steps < 0
+       THEN stop
+       ELSE IF x steps > 0 THEN x move FI;
+            IF y steps > 0 THEN y move FI;
+    FI;
+ 
+    . x move :
+        x rest INCR x steps; 
+        IF not is underline
+           THEN simple x move
+           ELSE underline x move
+        FI;
+
+        . not is underline :
+            NOT bit (modification bits, 7)
+ 
+        . simple x move :
+            high   := x rest DIV factor 1;
+            x rest := x rest MOD factor 1;
+            out (""27"\");
+            out (code (high MOD 256));
+            out (code (high DIV 256));
+ 
+        . underline x move :
+            high   := x rest DIV factor 2;
+            x rest := x rest MOD factor 2;
+            IF high < blank pitch
+               THEN stop
+               ELSE low  := high MOD 127;
+                    high := high DIV 127;
+                    IF low >= blank pitch
+                       THEN low  DECR blankpitch;
+                       ELSE high DECR 1;
+                            low  DECR (blankpitch - 127);
+                    FI;
+                    IF high > 0 
+                       THEN out (""27" ");
+                            out (code (127 - blankpitch));
+                            high TIMESOUT " ";
+                    FI;
+                    out (""27" ");
+                    out (code (low)); 
+                    out (" "27" "0"");
+            FI;
+ 
+     . y move :
+         low  := y steps MOD 255;
+         high := y steps DIV 255;
+         IF high > 0 THEN high TIMESOUT (""27"J"255"")    FI;
+         IF low  > 0 THEN out (""27"J"); out (code (low)) FI;
+. 
+  draw :
+    IF   x steps < 0 OR y steps <> 0 OR linetype <> underline linetype
+         THEN stop
+    ELIF x steps > 0
+         THEN x draw
+    FI;
+ 
+    . x draw :
+        x rest INCR x steps;
+        steps  := x rest DIV 6;
+        x rest := x rest MOD 6;
+        IF steps > 0
+           THEN low  := steps MOD 256;
+                high := steps DIV 256;
+                out (""27"L");
+                out (code (low));
+                out (code (high));
+                steps TIMESOUT ""1"";
+        FI;
+ 
+ 
+. modification : param1
+.
+  on :
+    buffer := on string (modification);
+    IF buffer <> ""
+       THEN modification bits := modification bits OR code (buffer);
+            switch to font;
+       ELSE stop
+    FI
+ 
+.
+  off :
+    buffer := off string (modification);
+    IF buffer <> ""
+       THEN modification bits := modification bits XOR code (buffer);
+            switch to font;
+       ELSE stop
+    FI
+ 
+.
+  type :
+    font nr   := param1;
+    buffer    := font string (font nr);
+    font bits := code (buffer SUB 1);
+    font text := subtext (buffer, 2);
+    IF is prop
+       THEN factor 1 := 4;
+            factor 2 := 4;
+       ELSE factor 1 := 6;
+            factor 2 := 6;
+    FI;
+    IF is double THEN factor 2 INCR factor 2 FI;
+    blank pitch := char pitch (font nr, " ") DIV factor 2; 
+    switch to font;
+    IF is nlq THEN switch to nlq FI;
+ 
+END PROC execute;
+ 
+ 
+PROC switch to font :
+ 
+  out (""27"!");
+  out (code (font bits OR modification bits));
+  out (font text);
+ 
+END PROC switch to font;
+ 
+ 
+PROC switch to nlq :
+ 
+  IF NOT is prop
+     THEN factor 1   := 4;
+          factor 2   := (4 * factor 2) DIV 6;
+          blankpitch := (6 * blankpitch) DIV 4;
+          out (""27"x"1"");
+     ELSE out (""27"x"0"");
+  FI;
+ 
+END PROC switch to nlq;
+ 
+ 
+PROC switch to draft :
+ 
+  IF NOT is prop
+     THEN factor 1   := 6;
+          factor 2   := (6 * factor 2) DIV 4;
+          blankpitch := (4 * blankpitch) DIV 6;
+          out (""27"x"0"");
+  FI;
+ 
+END PROC switch to draft;
+
+ 
+END PACKET epson sq printer;
+ 
+ 
+ 
+#page# 
+(******************************************************************)
+(***                                                            ***)
+(***   Generierung des Printers                                 ***)
+(***                                                            ***)
+(******************************************************************)
+ 
+LET printer name = "printer.epson.sq",
+    up           = ""3""13""5"";
+ 
+TEXT VAR fonttab name := "fonttab.epson.sq";
+ 
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+ 
+INT VAR pr channel;
+TEXT VAR buffer;
+ 
+command dialogue (TRUE);
+IF NOT multi user 
+  THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL") 
+FI; 
+ask for print channel;
+ask for paper format;
+ask for typeface;
+ask for print quality;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+check on;
+.
+  ask for print channel : 
+    line;
+    put ("gib Druckerkanal:");
+    get (pr channel);
+    do ("serverchannel(" + text (pr channel) + ")" ) ;
+    line;
+. 
+  ask for paper format :
+    SELECT paper format OF
+      CASE 1 : papersize ( 8.0 * 2.54, 12.0 * 2.54)
+      CASE 2 : papersize (13.6 * 2.54, 12.0 * 2.54)
+      CASE 3 : papersize (21.0, 29.7)
+    END SELECT
+
+    . paper format :
+        line;
+        REP out (up);
+            IF yes ("Papierformat : endlos, 8 Zoll breit")
+               THEN LEAVE paper format WITH 1 FI;
+            out (up);
+            IF yes ("Papierformat : endlos, 13.6 Zoll breit")
+               THEN LEAVE paper format WITH 2 FI;
+            out (up);
+            IF yes ("Papierformat : DINA 4")
+               THEN LEAVE paper format WITH 3 FI;
+        PER;
+        0
+.
+  ask for typeface :
+    line;
+    std typeface (typeface)
+ 
+    . typeface :
+        REP out (up);
+            IF yes ("standardmäßige Schriftart : roman")
+               THEN LEAVE typeface WITH "roman" FI;
+            out (up);
+            IF yes ("standardmäßige Schriftart : sansserif")
+               THEN LEAVE typeface WITH "sansserif" FI;
+            out (up);
+            IF yes ("standardmäßige Schriftart : courier")
+               THEN LEAVE typeface WITH "courier" FI;
+            out (up);
+            IF yes ("standardmäßige Schriftart : prestige")
+               THEN LEAVE typeface WITH "prestige" FI;
+            out (up);
+            IF yes ("standardmäßige Schriftart : script")
+               THEN LEAVE typeface WITH "script" FI;
+        PER;
+        ""
+.
+  ask for print quality :
+    line;
+    std quality (quality);
+ 
+    . quality :
+        REP out (up);
+            IF yes ("standardmäßige Druckqualität : draft quality")
+               THEN LEAVE quality WITH "draft" FI;
+            out (up);
+            IF yes ("standardmäßige Druckqualität : near letter quality")
+               THEN LEAVE quality WITH "nlq" FI;
+        PER;
+        ""
+.
+  load font table :
+    IF NOT exists (fonttab name)
+       THEN command dialogue (TRUE); 
+            REP line (2); 
+                putline ("Bitte Archiv mit der Fonttabelle """ +
+                          fonttab name + """ einlegen!");
+                line;
+            UNTIL yes ("Archiv eingelegt") PER;
+            reserve archive;
+            fetch (fonttab name, archive);
+            release (archive);
+    FI;
+    font table (fonttab name);
+    IF multi user
+       THEN command dialogue (FALSE); 
+            do ("save(""" + font tab name + """,task(""configurator""))") 
+    FI;
+    forget (fonttab name, quiet);
+ 
+    . reserve archive :
+        INT VAR p1, p2;
+        archive (" "31" ");
+        disable stop;
+        list (archive);
+        IF is error
+           THEN buffer := errormessage;
+                p1 := pos (buffer, """", 1 ) + 1;
+                p2 := pos (buffer, """", p1) - 1;
+                IF p1 > 0 AND p2 > 0
+                   THEN clear error;
+                        buffer := subtext (buffer, p1, p2);
+                        archive (buffer);
+                FI;
+        FI;
+        enable stop;
+ 
+. generate printer spool :
+    eumel must advertise;
+    cursor (1, 12);
+    putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+    putline ("die Fonttabelle mit dem Kommando");
+    line;
+    putline ("      font table (""" + font tab name + """)");
+    line;
+    putline ("eingestellt werden!!!");
+    line (4);
+    putline ("Generierung beendet, weiter mit 'SV'");
+    generate printer server;
+    do (buffer);
+ 
+. generate printer server :
+    buffer :=  "break (quiet);";
+    buffer CAT "spool manager (PROC printer);";
+    buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+    buffer CAT "PROC printer:";
+    buffer CAT "  disable stop;";
+    buffer CAT "  continue (server channel);";
+    buffer CAT "  check error (error message);";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  REP forget (ds);";
+    buffer CAT "      execute print;";
+    buffer CAT "      IF is error AND online THEN put error; clear error; FI;";
+    buffer CAT "  PER;";
+    buffer CAT "END PROC printer;";
+    buffer CAT "PROC execute print:";
+    buffer CAT "  LET ack = 0, fetch code = 11, file type = 1003;";
+    buffer CAT "  enable stop;";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  call (father, fetch code, ds, reply);";
+    buffer CAT "  IF reply = ack CAND type (ds) = file type";
+    buffer CAT "     THEN file := sequential file (input, ds);";
+    buffer CAT "          print (file,";
+    buffer CAT "            PROC (INT CONST, INT VAR, INT VAR) open,";
+    buffer CAT "            PROC (INT CONST, INT CONST) close,";
+    buffer CAT "            PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC execute print;"; 
+    buffer CAT "PROC check error(TEXT CONST message):";
+    buffer CAT "  IF is error";
+    buffer CAT "     THEN clear error; rename myself (message);";
+    buffer CAT "          IF is error THEN end(myself) FI;"; 
+    buffer CAT "          pause (9000); end(myself);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC check error;"; 
+
diff --git a/printer/laser/printer.hp.laserjet b/printer/laser/printer.hp.laserjet
new file mode 100644
index 0000000..152ee8e
--- /dev/null
+++ b/printer/laser/printer.hp.laserjet
@@ -0,0 +1,417 @@
+PACKET hp laserjet printer
+ 
+(**************************************************************************)
+(*                                                Stand   : 03.02.88      *)
+(*  HP 2686A LaserJet / LaserJet+                 Verison : 4             *)
+(*                                                Autor   : Rudolf Ruland *)
+(**************************************************************************)
+ 
+       DEFINES open,
+               close,
+               execute,
+ 
+               paper size,
+               printer type :
+ 
+LET
+(*  underline           =  1,
+    bold                =  2,
+    italics             =  4,
+    reverse             =  8,
+ 
+    underline linetype  =  1, *)
+ 
+    c document          =  1,
+    c page              =  2,
+ 
+    c write text        =  1,
+    c write cmd         =  2,
+    c carriage return   =  3, 
+    c move              =  4,
+    c draw              =  5,
+    c on                =  6, 
+    c off               =  7,
+    c type              =  8;
+ 
+INT VAR abs x pos
+REAL VAR x size, y size;
+BOOL VAR is laser jet plus, is landscape;
+
+(*********************************************************************)
+ 
+paper size (21.0, 29.7);
+printer type ("LaserJet");
+ 
+PROC paper size (REAL CONST x, y) :
+ 
+  x size := x;
+  y size := y;
+ 
+END PROC paper size;
+ 
+PROC paper size : 
+ 
+  line;
+  putline ("Papierbreite  =  " + text (x size, 5, 2) + " cm  =  " + text (x size / 2.54, 5, 2) + " Zoll");
+  putline ("Papierlaenge  =  " + text (y size, 5, 2) + " cm  =  " + text (y size / 2.54, 5, 2) + " Zoll");
+ 
+END PROC paper size;
+ 
+PROC printer type (TEXT CONST type) :
+
+  is laser jet plus := pos (type, "+") <> 0
+
+END PROC printer type;
+ 
+TEXT PROC printer type :
+
+  IF is laser jet plus
+     THEN "LaserJet+"
+     ELSE "LaserJet"
+  FI
+
+END PROC printer type;
+
+(*********************************************************************)
+ 
+PROC open (INT CONST op code, INT VAR param1, param2) :
+ 
+SELECT op code OF
+  CASE c document : open document 
+  CASE c page     : open page
+END SELECT; 
+ 
+ 
+. x steps : param1
+. y steps : param2
+. 
+  open document :
+    out (""27"E");      (* Reset des Druckers *)
+    out (""27"&s1C");   (* 'end of line wrap' aus *)
+    out (""27"&l0L");   (* 'perforation skip' aus *)
+    out (""27"&l1X");   (* eine Kopie             *)
+    out (""27"&l1H");   (* upper tray             *)
+    IF pos (material, "landscape") > 0 OR pos (material, "quer") > 0
+       THEN is landscape := TRUE;
+            x steps      := x step conversion ( y size );
+            y steps      := y step conversion ( x size );
+            out (""27"&l1O");
+       ELSE is landscape := FALSE;
+            x steps      := x step conversion ( x size );
+            y steps      := y step conversion ( y size );
+    FI;
+ 
+. x start : param1
+. y start : param2
+. 
+  open page :
+    IF is landscape
+       THEN x start  := x step conversion (0.508);     (* 0.200*2.54 *)
+            y start  := y step conversion (1.693333);  (* 0.500*2.54 + 2.54/6.0 *)
+       ELSE x start  := x step conversion (0.39878);   (* 0.157*2.54 *)
+            y start  := y step conversion (1.693333);  (* 0.500*2.54 + 2.54/6.0 *)
+    FI;
+    IF   pos (material, "lower tray") > 0 COR pos (material, "lowertray") > 0
+         THEN out (""27"&l4H");
+    ELIF pos (material, "tray") > 0 COR pos (material, "upper tray") > 0 COR pos (material, "uppertray") > 0
+         THEN out (""27"&l1H");
+    ELIF pos (material, "manual") > 0
+         THEN out (""27"&l2H");
+    ELIF pos (material, "envelope") > 0
+         THEN out (""27"&l3H");
+    FI;
+    IF material contains a number
+       THEN out (""27"&l" + text (number) + "X");
+    FI;
+    out (""13"");
+ 
+    . material contains a number :
+        INT VAR number := pos (material, "0", "9", 1);
+        IF number = 0
+           THEN FALSE
+           ELSE number := max (1, int (subtext (material, number, number + 1)));
+                TRUE
+        FI
+ 
+END PROC open; 
+ 
+ 
+PROC close (INT CONST op code, INT CONST param1) :
+ 
+SELECT op code OF
+  CASE c document : close document 
+  CASE c page     : close page
+  OTHERWISE : put (param1)
+END SELECT; 
+ 
+. 
+  close document :
+ 
+ 
+(*. remaining y steps : param1*)
+.
+  close page :
+    out (""12"") 
+ 
+END PROC close;
+ 
+ 
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+ 
+SELECT op code OF
+  CASE c write text       :  write text
+  CASE c write cmd        :  write cmd
+  CASE c carriage return  :  carriage return
+  CASE c move             :  move
+  CASE c draw             :  draw
+  CASE c on               :  on
+  CASE c off              :  off
+  CASE c type             :  type
+END SELECT
+
+ 
+. from : param1
+. to   : param2
+.
+  write text :
+    out subtext (string, from, to)
+ 
+.
+  write cmd :
+    out subtext (string, from, to)
+ 
+ 
+(*. x steps to left margin : param1*)
+.
+  carriage return :
+    out (""13"")
+ 
+ 
+. x steps : param1
+. y steps : param2
+.
+  move :
+    IF   x steps <> 0
+         THEN x move
+    ELIF y steps > 0
+         THEN out (""27"&a+" + text (y steps) + "V");
+    ELIF y steps < 0
+         THEN out (""27"&a"  + text (y steps) + "V");
+    FI;
+ 
+    . x move :
+        IF is laser jet plus
+           THEN laser jet plus x move
+           ELSE laser jet x move
+        FI;
+
+    . laser jet plus x move :
+        IF x steps >= 0
+           THEN out (""27"*p+" + text (x steps) + "X");
+           ELSE out (""27"*p"  + text (x steps) + "X");
+        FI;
+
+    . laser jet x move :
+        abs x pos := x pos;
+        IF abs x pos >= 0
+           THEN out (""27"&a");
+                out (text ((abs x pos DIV 5) * 12 + ((abs x pos MOD 5) * 12 + 4) DIV 5));
+                out ("H");
+           ELSE stop
+        FI;
+
+. 
+  draw :
+    stop
+ 
+ 
+. modification : param1
+.
+  on :
+    IF on string (modification) <> ""
+       THEN out (on string (modification))
+       ELSE stop
+    FI
+ 
+.
+  off :
+    IF off string (modification) <> ""
+       THEN out (off string (modification))
+       ELSE stop
+    FI
+ 
+ 
+. font nr : param1
+.
+  type :
+    out (font string (font nr));
+ 
+END PROC execute;
+ 
+ 
+END PACKET hp laserjet printer;
+ 
+ 
+#page# 
+(******************************************************************)
+(***                                                            ***)
+(***   Generierung des Printers                                 ***)
+(***                                                            ***)
+(******************************************************************)
+ 
+LET printer name = "printer.hp.laserjet",
+    up           = ""3""13""5"";
+ 
+TEXT VAR fonttab name := "fonttab.hp.laserjet";
+ 
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+ 
+INT VAR pr channel;
+TEXT VAR buffer;
+ 
+command dialogue (TRUE);
+IF NOT multi user 
+  THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL") 
+FI; 
+ask for print channel;
+ask for printer type;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+check on;
+.
+  ask for print channel :
+    line;
+    put ("gib Druckerkanal:");
+    get (pr channel);
+    do ("serverchannel(" + text (pr channel) + ")" ) ;
+    line;
+. 
+  ask for printer type :
+    printer type (laser jet);
+ 
+    . laser jet :
+        line;
+        REP out (up); 
+            IF yes ("Druckertyp : HP LaserJet")
+               THEN LEAVE laser jet WITH "LaserJet" FI;
+            out (up);
+            IF yes ("Druckertyp : HP LaserJet+")
+               THEN LEAVE laser jet WITH "LaserJet+" FI;
+        PER;
+        ""
+.
+  load font table :
+    line (2);
+    write (""13""4"");
+    putline ("Die Fonttabelle """ + fonttab name +
+             """ enthält die Schrifttypen der");
+    putline ("Font Cartriges:");
+    putline ("                  92286A  Courier 1");
+    putline ("                  92286C  International 1");
+    putline ("                  92286D  Prestige Elite");
+    putline ("                  92286E  Letter Gothic");
+    putline ("                  92286F  TMS Proportional 2");
+    putline ("                  92286L  Courier P&L");
+    putline ("                  92286M  Prestige Elite P&L");
+    putline ("                  92286N  Letter Gothic P&L");
+    putline ("                  92286P  TMS RMN P&L");
+    putline ("                  92286Q  Memo 1");
+    line;
+    putline ("Für ein korrektes Druckbild dürfen immer nur die Schrifttypen angesprochen");
+    putline ("werden, deren Cartrige eingeschoben ist!");
+    IF printer type = "LaserJet"
+       THEN line;
+            putline ("ELAN-Listings können nur gedruckt werden, wenn ein Cartrige mit dem");
+            putline ("Schrifttyp 'LINE PRINTER' eingeschoben ist!");
+    FI;
+    line (2);
+    putline ("Weiter nach Eingabe einer Taste");
+    pause;
+    IF NOT exists (fonttab name)
+       THEN command dialogue (TRUE); 
+            REP line (2); 
+                putline ("Bitte Archiv mit der Fonttabelle """ +
+                          fonttab name + """ einlegen!");
+                line;
+            UNTIL yes ("Archiv eingelegt") PER;
+            reserve archive;
+            fetch (fonttab name, archive);
+            release (archive);
+    FI;
+    font table (fonttab name);
+    IF multi user
+       THEN command dialogue (FALSE); 
+            do ("save(""" + font tab name + """,task(""configurator""))") 
+    FI;
+    forget (fonttab name, quiet);
+ 
+    . reserve archive :
+        INT VAR p1, p2;
+        archive (" "31" ");
+        disable stop;
+        list (archive);
+        IF is error
+           THEN buffer := errormessage;
+                p1 := pos (buffer, """", 1 ) + 1;
+                p2 := pos (buffer, """", p1) - 1;
+                IF p1 > 0 AND p2 > 0
+                   THEN clear error;
+                        buffer := subtext (buffer, p1, p2);
+                        archive (buffer);
+                FI;
+        FI;
+        enable stop;
+ 
+. generate printer spool :
+    eumel must advertise;
+    cursor (1, 12);
+    putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+    putline ("die Fonttabelle mit dem Kommando");
+    line;
+    putline ("      font table (""" + font tab name + """)");
+    line;
+    putline ("eingestellt werden!!!");
+    line (4);
+    putline ("Generierung beendet, weiter mit 'SV'");
+    generate printer server;
+    do (buffer);
+ 
+. generate printer server :
+    buffer :=  "break (quiet);";
+    buffer CAT "spool manager (PROC printer);";
+    buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+    buffer CAT "PROC printer:";
+    buffer CAT "  disable stop;";
+    buffer CAT "  continue (server channel);";
+    buffer CAT "  check error (error message);";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  REP forget (ds);";
+    buffer CAT "      execute print;";
+    buffer CAT "      IF is error AND online";
+    buffer CAT "         THEN out (""""27""(8U""27""(s0p10h12v0s0b3T"");";
+    buffer CAT "              put error; clear error; out (""""12"""");";
+    buffer CAT "      FI;";
+    buffer CAT "  PER;";
+    buffer CAT "END PROC printer;";
+    buffer CAT "PROC execute print:";
+    buffer CAT "  LET ack = 0, fetch code = 11, file type = 1003;";
+    buffer CAT "  enable stop;";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  call (father, fetch code, ds, reply);";
+    buffer CAT "  IF reply = ack CAND type (ds) = file type";
+    buffer CAT "     THEN file := sequential file (input, ds);";
+    buffer CAT "          print (file,";
+    buffer CAT "            PROC (INT CONST, INT VAR, INT VAR) open,";
+    buffer CAT "            PROC (INT CONST, INT CONST) close,";
+    buffer CAT "            PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC execute print;"; 
+    buffer CAT "PROC check error(TEXT CONST message):";
+    buffer CAT "  IF is error";
+    buffer CAT "     THEN clear error; rename myself (message);";
+    buffer CAT "          IF is error THEN end(myself) FI;"; 
+    buffer CAT "          pause (9000); end(myself);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC check error;"; 
+
diff --git a/printer/laser/printer.kyocera.f-1010 b/printer/laser/printer.kyocera.f-1010
new file mode 100644
index 0000000..a46f7b3
--- /dev/null
+++ b/printer/laser/printer.kyocera.f-1010
@@ -0,0 +1,373 @@
+PACKET kyocera f 1010 printer
+ 
+(**************************************************************************)
+(*                                                Stand   : 03.12.86      *)
+(*  KYOCERA   F - 1010                            Verison : 4             *)
+(*                                                Autor   : Rudolf Ruland *)
+(**************************************************************************)
+
+(**************************************************************************)
+(*  Hinweis : Die 'time-out' Zeit, nach der der Eingabepuffer ausgegeben  *)
+(*            wird, wenn keine Eingabe mehr erfolgt, sollte moeglichst    *)
+(*            gross gewaehlt werden,                                      *)
+(*            z.B.  mit   FRPO H9, 60;   wird sie auf 5 Min. gesetzt      *)
+(**************************************************************************)
+
+ 
+       DEFINES open,
+               close,
+               execute,
+ 
+               paper size :
+ 
+LET underline           =  1,
+(*  bold                =  2,
+    italics             =  4,
+    reverse             =  8,
+ 
+    underline linetype  =  1, *)
+ 
+    c document          =  1,
+    c page              =  2,
+ 
+    c write text        =  1,
+    c write cmd         =  2,
+    c carriage return   =  3, 
+    c move              =  4,
+    c draw              =  5,
+    c on                =  6, 
+    c off               =  7,
+    c type              =  8;
+ 
+INT VAR blankpitch, high, low;
+REAL VAR x size, y size;
+BOOL VAR is landscape, is underline;
+
+(*********************************************************************)
+ 
+paper size (21.0, 29.7);
+ 
+PROC paper size (REAL CONST x, y) :
+ 
+  x size := x;
+  y size := y;
+ 
+END PROC paper size;
+ 
+PROC paper size : 
+ 
+  line;
+  putline ("Papierbreite  =  " + text (x size, 5, 2) + " cm  =  " + text (x size / 2.54, 5, 2) + " Zoll");
+  putline ("Papierlaenge  =  " + text (y size, 5, 2) + " cm  =  " + text (y size / 2.54, 5, 2) + " Zoll");
+ 
+END PROC paper size;
+ 
+(*********************************************************************)
+ 
+PROC open (INT CONST op code, INT VAR param1, param2) :
+ 
+SELECT op code OF
+  CASE c document : open document 
+  CASE c page     : open page
+END SELECT; 
+ 
+ 
+. x steps : param1
+. y steps : param2
+. 
+  open document :
+    out ("!"82"! RES; UNIT D; EXIT;");         (* Reset des Druckers *)
+    IF pos (material, "landscape") > 0 OR pos (material, "quer") > 0
+       THEN is landscape := TRUE;
+            x steps      := x step conversion ( y size );
+            y steps      := y step conversion ( x size );
+            out (""27"&l1O");
+       ELSE is landscape := FALSE;
+            x steps      := x step conversion ( x size );
+            y steps      := y step conversion ( y size );
+    FI;
+    is underline := FALSE;
+    IF y size < 29.7 OR x size < 21.0
+       THEN out ("!"82"! SLM ");
+            IF is landscape
+               THEN out (text (x step conversion (29.7 - y size)));
+                    out ("; STM ");
+                    out (text (y step conversion ((21.0 - x size) * 0.5)));
+               ELSE out (text (x step conversion ((21.0 - x size) * 0.5)));
+            FI;
+            out ("; EXIT;");
+     FI;
+
+. x start : param1
+. y start : param2
+. 
+  open page :
+    out ("!"82"! MZP 0, 0; EXIT;");       (* Positionierung zum Nullpunkt *)
+    IF is landscape
+       THEN x start  := x step conversion (0.19);
+            y start  := y step conversion (0.70);
+       ELSE x start  := x step conversion (0.56);
+            y start  := y step conversion (0.60);
+    FI;
+    IF   pos (material, "tray") > 0
+         THEN out (""27"&l1H");
+    ELIF pos (material, "manual") > 0
+         THEN out (""27"&l2H");
+    FI;
+    out (""13"");
+ 
+END PROC open; 
+ 
+ 
+PROC close (INT CONST op code, INT CONST param1) :
+ 
+SELECT op code OF
+  CASE c document : close document 
+  CASE c page     : close page
+  OTHERWISE : put (param1)
+END SELECT; 
+ 
+. 
+  close document :
+ 
+ 
+(*. remaining y steps : param1*)
+.
+  close page :
+    out (""12"");
+
+END PROC close;
+ 
+ 
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+ 
+SELECT op code OF
+  CASE c write text       :  write text
+  CASE c write cmd        :  write cmd
+  CASE c carriage return  :  carriage return
+  CASE c move             :  move
+  CASE c draw             :  draw
+  CASE c on               :  on
+  CASE c off              :  off
+  CASE c type             :  type
+END SELECT
+
+ 
+. from : param1
+. to   : param2
+.
+  write text :
+    out subtext (string, from, to)
+ 
+.
+  write cmd :
+    out subtext (string, from, to)
+ 
+ 
+(*. x steps to left margin : param1*)
+.
+  carriage return :
+    out (""13"")
+ 
+ 
+. x steps : param1
+. y steps : param2
+.
+  move :
+    IF   x steps > 0
+         THEN IF is underline
+                 THEN underline x move
+                 ELSE out (""27"*p+" + text (x steps) + "X");
+              FI;
+    ELIF x steps < 0
+         THEN out (""27"*p"  + text (x steps) + "X");
+    ELIF y steps > 0
+         THEN out (""27"*p+" + text (y steps) + "Y");
+    ELIF y steps < 0
+         THEN out (""27"*p"  + text (y steps) + "Y");
+    FI;
+
+    . underline x move :
+        high := x steps DIV blankpitch;
+        low  := x steps MOD blankpitch;
+        IF high > 0 THEN high TIMESOUT " " FI;
+        IF low  > 0 THEN out (" "27"*p" + text (low - blank pitch) + "X") FI;
+ 
+. 
+  draw :
+    stop
+ 
+ 
+. modification : param1
+.
+  on :
+    IF on string (modification) <> ""
+       THEN out (on string (modification));
+            IF modification = underline THEN is underline := TRUE FI;
+       ELSE stop
+    FI
+ 
+.
+  off :
+    IF off string (modification) <> ""
+       THEN out (off string (modification));
+            IF modification = underline THEN is underline := FALSE FI;
+       ELSE stop
+    FI
+ 
+ 
+. font nr : param1
+.
+  type :
+    out (font string (font nr));
+    blankpitch := char pitch (font nr, " ");
+ 
+END PROC execute;
+ 
+ 
+END PACKET kyocera f 1010 printer;
+ 
+ 
+ 
+#page# 
+(******************************************************************)
+(***                                                            ***)
+(***   Generierung des Printers                                 ***)
+(***                                                            ***)
+(******************************************************************)
+ 
+LET printer name = "printer.kyocera.f-1010";
+ 
+TEXT VAR fonttab name := "fonttab.kyocera.f-1010";
+ 
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+ 
+INT VAR pr channel;
+TEXT VAR buffer;
+ 
+command dialogue (TRUE);
+IF NOT multi user 
+  THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL") 
+FI; 
+ask for print channel;
+dynamic font hint;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+check on;
+command dialogue (TRUE);
+.
+  ask for print channel : 
+    line;
+    put ("gib Druckerkanal:");
+    get (pr channel);
+    do ("serverchannel(" + text (pr channel) + ")" ) ;
+    line;
+.
+  dynamic font hint :
+    line (3);
+    putline (""4"Hinweis zur Benutzung der dynamischen Schrifttypen:");
+    line;
+    putline ("    In der Fonttabelle """ + fonttab name + """ sind einige dynamische");
+    putline ("    Schrifttypen angepaßt. Diese müssen nach jedem Einschalten des");
+    putline ("    Druckers neu generiert werden.");
+    putline ("    Zur Generierung dieser Schrifttypen befinden sich auf dem Standard-");
+    putline ("    archive die folgenden Dateien:");
+    line;
+    putline ("               ""genfont.kyocera.f-1010.dynamic1""");
+    putline ("               ""genfont.kyocera.f-1010.dynamic2""");
+    line;
+    putline ("    Nach Einschalten des Druckers müssen diese Dateien zuerst ausgedruckt");
+    putline ("    werden.");
+    putline ("    Die Generierung benötigt pro Schriftart etwa 15 Minuten.");
+    line (2);
+    putline ("Weiter nach Eingabe einer Taste");
+    pause;
+.
+  load font table :
+    IF NOT exists (fonttab name)
+       THEN REP line (2); 
+                putline ("Bitte Archiv mit der Fonttabelle """ +
+                          fonttab name + """ einlegen!");
+                line;
+            UNTIL yes ("Archiv eingelegt") PER;
+            reserve archive;
+            fetch (fonttab name, archive);
+            release (archive);
+    FI;
+    font table (fonttab name);
+    IF multi user
+       THEN command dialogue (FALSE);
+            do ("save(""" + font tab name + """,task(""configurator""))")
+    FI;
+    forget (fonttab name, quiet);
+ 
+    . reserve archive :
+        INT VAR p1, p2;
+        archive (" "31" ");
+        disable stop;
+        list (archive);
+        IF is error
+           THEN buffer := errormessage;
+                p1 := pos (buffer, """", 1 ) + 1;
+                p2 := pos (buffer, """", p1) - 1;
+                IF p1 > 0 AND p2 > 0
+                   THEN clear error;
+                        buffer := subtext (buffer, p1, p2);
+                        archive (buffer);
+                FI;
+        FI;
+        enable stop;
+ 
+. generate printer spool :
+    eumel must advertise;
+    cursor (1, 12);
+    putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+    putline ("die Fonttabelle mit dem Kommando");
+    line;
+    putline ("      font table (""" + font tab name + """)");
+    line;
+    putline ("eingestellt werden!!!");
+    line (4);
+    putline ("Generierung beendet, weiter mit 'SV'");
+    generate printer server;
+    do (buffer);
+ 
+. generate printer server :
+    buffer :=  "break (quiet);";
+    buffer CAT "spool manager (PROC printer);";
+    buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+    buffer CAT "PROC printer:";
+    buffer CAT "  disable stop;";
+    buffer CAT "  continue (server channel);";
+    buffer CAT "  check error (error message);";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  REP forget (ds);";
+    buffer CAT "      execute print;";
+    buffer CAT "      IF is error AND online";
+    buffer CAT "         THEN out (""""27""(8U""27""(s0p10h12v0s0b3T"");";
+    buffer CAT "              put error; clear error; out (""""12"""");";
+    buffer CAT "      FI;";
+    buffer CAT "  PER;";
+    buffer CAT "END PROC printer;";
+    buffer CAT "PROC execute print:";
+    buffer CAT "  LET ack = 0, fetch code = 11, file type = 1003;";
+    buffer CAT "  enable stop;";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  call (father, fetch code, ds, reply);";
+    buffer CAT "  IF reply = ack CAND type (ds) = file type";
+    buffer CAT "     THEN file := sequential file (input, ds);";
+    buffer CAT "          print (file,";
+    buffer CAT "            PROC (INT CONST, INT VAR, INT VAR) open,";
+    buffer CAT "            PROC (INT CONST, INT CONST) close,";
+    buffer CAT "            PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC execute print;";
+    buffer CAT "PROC check error(TEXT CONST message):";
+    buffer CAT "  IF is error";
+    buffer CAT "     THEN clear error; rename myself (message);";
+    buffer CAT "          IF is error THEN end(myself) FI;";
+    buffer CAT "          pause (9000); end(myself);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC check error;";
+
diff --git a/printer/laser/printer.nec.lc-08 b/printer/laser/printer.nec.lc-08
new file mode 100644
index 0000000..9ee2837
--- /dev/null
+++ b/printer/laser/printer.nec.lc-08
@@ -0,0 +1,626 @@
+PACKET nec lc 08 printer
+ 
+(**************************************************************************)
+(*                                                Stand   : 29.01.88      *)
+(*  NEC Silentwriter LC-08                        Verison : 4             *)
+(*                                                Autor   : Rudolf Ruland *)
+(**************************************************************************)
+ 
+       DEFINES open,
+               close,
+               execute,
+ 
+               box commands,
+               insert box command,
+               delete box command,
+
+               paper size,
+               paper x size,
+               paper y size:
+ 
+LET
+(*  underline           =  1,
+    bold                =  2,
+    italics             =  4,
+    reverse             =  8,
+ 
+    underline linetype  =  1, *)
+ 
+    c document          =  1,
+    c page              =  2,
+ 
+    c write text        =  1,
+    c write cmd         =  2,
+    c carriage return   =  3, 
+    c move              =  4,
+    c draw              =  5,
+    c on                =  6, 
+    c off               =  7,
+    c type              =  8,
+
+    tag type            =  1;
+ 
+INT VAR symbol type;
+REAL VAR x size, y size;
+BOOL VAR is landscape, was cr;
+TEXT VAR bold buffer, mod string, command, symbol;
+THESAURUS VAR box cmds := empty thesaurus;
+
+(*********************************************************************)
+ 
+paper size (21.0, 29.7);
+ 
+PROC paper size (REAL CONST x, y) :
+ 
+  x size := x;
+  y size := y;
+ 
+END PROC paper size;
+ 
+PROC paper size : 
+ 
+  line;
+  putline ("Papierbreite  =  " + text (x size, 5, 2) + " cm  =  " + text (x size / 2.54, 5, 2) + " Zoll");
+  putline ("Papierlaenge  =  " + text (y size, 5, 2) + " cm  =  " + text (y size / 2.54, 5, 2) + " Zoll");
+ 
+END PROC paper size;
+ 
+REAL PROC paper x size : x size END PROC paper x size;
+REAL PROC paper y size : y size END PROC paper y size;
+
+
+THESAURUS PROC box commands : box cmds END PROC box commands;
+
+PROC insert box command (TEXT CONST new command) :
+
+  command := new command;
+  change all (command, " ", "");
+  insert (box cmds, command)
+
+END PROC insert box command;
+
+PROC delete box command (TEXT CONST old command) :
+
+  INT VAR dummy;
+  command := old command;
+  change all (command, " ", "");
+  delete (box cmds, command, dummy)
+
+END PROC delete box command;
+
+(*********************************************************************)
+ 
+PROC open (INT CONST op code, INT VAR param1, param2) :
+ 
+SELECT op code OF
+  CASE c document : open document 
+  CASE c page     : open page
+END SELECT; 
+ 
+ 
+. x steps : param1
+. y steps : param2
+. 
+  open document :
+    out (""28"Cz");                      (* Diablo 630 Emulation    *)
+    out (""27""13"P");                   (* Reset                   *)
+    out (""28"$");                       (* Formatlaenge loeschen   *)
+    out (""28"Ca"27"6"28"Cz");           (* Zeichensatz 2           *)
+    out (""28"Ra");                      (* USA-Zeichensatz         *)
+    out (""27""25"1");                   (* Sheet 1                 *)
+    is landscape := pos (material, "landscape") > 0;
+    IF is landscape
+       THEN x steps := x step conversion ( y size );
+            y steps := y step conversion ( x size );
+            out (""28")"128""0"");       (* Landscape-Mode          *)
+       ELSE x steps := x step conversion ( x size );
+            y steps := y step conversion ( y size );
+            out (""28")"001""0"");       (* Portait  -Mode          *)
+    FI;
+    was cr      := FALSE;
+    bold buffer := "";
+
+. x start : param1
+. y start : param2
+. 
+  open page :
+    IF is landscape
+       THEN x start := x step conversion (0.45);
+            y start := y step conversion (0.9);
+       ELSE x start := x step conversion (0.7);
+            y start := y step conversion (0.9);
+    FI;
+    IF   pos (material, "sheet1") > 0
+         THEN out (""27""25"1")
+    ELIF pos (material, "sheet2") > 0
+         THEN out (""27""25"2")
+    ELIF pos (material, "manual") > 0
+         THEN out (""27""25"E")
+    FI;
+    out (""28"'a"0""0""28"&a"0""0"");  (* Positionierung auf den Nullpunkt *)
+ 
+END PROC open; 
+ 
+ 
+PROC close (INT CONST op code, INT CONST param1) :
+ 
+SELECT op code OF
+  CASE c document : close document 
+  CASE c page     : close page
+  OTHERWISE : put (param1)
+END SELECT; 
+ 
+. 
+  close document :
+ 
+ 
+(*. remaining y steps : param1*)
+.
+  close page :
+    out (""12"") 
+ 
+END PROC close;
+ 
+ 
+PROC execute (INT CONST op code, TEXT CONST string, INT CONST param1, param2) :
+ 
+SELECT op code OF
+  CASE c write text       :  write text
+  CASE c write cmd        :  write cmd
+  CASE c carriage return  :  carriage return
+  CASE c move             :  move
+  CASE c draw             :  draw
+  CASE c on               :  on
+  CASE c off              :  off
+  CASE c type             :  type
+END SELECT
+
+ 
+. from : param1
+. to   : param2
+.
+  write text :
+    IF was cr
+       THEN was cr := FALSE;
+            out (bold buffer);
+    FI;
+    out subtext (string, from, to)
+ 
+.
+  write cmd :
+    IF was cr
+       THEN was cr := FALSE;
+            out (bold buffer);
+    FI;
+    command := subtext (string, from, to);
+    IF is box cmd
+       THEN disable stop;
+            do (command);
+            clear error;
+       ELSE out (command);
+    FI;
+ 
+    . is box cmd :
+        scan (command);
+        next symbol (symbol, symbol type);
+        (symbol type = tag type) CAND (box cmds CONTAINS symbol)
+
+
+(*. x steps to left margin : param1*)
+.
+  carriage return :
+    out (""13"");
+    was cr := TRUE;
+ 
+ 
+. x steps : param1
+. y steps : param2
+.
+  move :
+    IF x steps <> 0 THEN x move FI;
+    IF y steps <> 0 THEN y move FI;
+
+    . x move :
+        IF x steps > 0  THEN out (""28"&c") ELSE out (""28"&d") FI;
+        out (x steps low);
+        out (x steps high);
+
+        . x steps low  : code (abs (x steps) MOD 256)
+        . x steps high : code (abs (x steps) DIV 256)
+
+    . y move :
+        IF y steps > 0  THEN out (""28"'c") ELSE out (""28"'d") FI;
+        out (y steps low);
+        out (y steps high);
+
+        . y steps low  : code (abs (y steps) MOD 256)
+        . y steps high : code (abs (y steps) DIV 256)
+. 
+  draw :
+    stop
+ 
+ 
+. modification : param1
+.
+  on :
+    mod string := on string (modification);
+    IF mod string <> ""
+       THEN out (mod string);
+            IF pos (""27"W"27"O", mod string) > 0
+               THEN bold buffer CAT mod string;
+            FI;
+       ELSE stop
+    FI
+ 
+.
+  off :
+    mod string := off string (modification);
+    IF mod string <> ""
+       THEN out (mod string);
+            IF pos (""27"&", mod string) > 0
+               THEN bold buffer := subtext (bold buffer, 1, LENGTH bold buffer - 2);
+                    out (bold buffer);
+            FI;
+       ELSE stop
+    FI
+ 
+ 
+. font nr : param1
+.
+  type :
+    out (""28")");                            (* Font Identifikation *)
+    command := font string (font nr);
+    IF is landscape
+       THEN out subtext (command, 3, 4);
+       ELSE out subtext (command, 1, 2);
+    FI;
+    out (""28"E");                            (* Zeilenvorschub (VMI) *)
+    out (code (font height (font nr) + font depth (font nr) + font lead (font nr)));
+    out (""28"F");                            (* Zeichenabstand (HMI) *)
+    out (code (char pitch (font nr, " ")));
+    out (""27"P");                            (* proportional ein     *)
+    out subtext (command, 5);
+
+END PROC execute;
+ 
+END PACKET nec lc 08 printer;
+ 
+ 
+PACKET nec lc 08 box commands 
+
+(**************************************************************************)
+(*                                                                        *)
+(*      Kommandos zum Zeichen von Boxen, Linien und Schraffuren           *)
+(*                für den NEC Laserdrucker LC-08                          *)
+(*                                                                        *)
+(*                                                Autor   : Rudolf Ruland *)
+(*                                                Stand   : 29.01.88      *)
+(**************************************************************************)
+
+       DEFINES line,
+               x line,
+               y line,
+
+               box,
+               box frame,
+               box shade,
+
+               cake,
+               cake frame,
+               cake shade,
+               :
+
+INT VAR x, y, h, w;
+
+WHILE highest entry (box commands) > 0
+  REP delete box command (name (box commands, highest entry (box commands))) PER;
+insert box command ("line");
+insert box command ("xline");
+insert box command ("yline");
+insert box command ("box");
+insert box command ("boxshade");
+insert box command ("boxframe");
+insert box command ("cake");
+insert box command ("cakeshade");
+insert box command ("cakeframe");
+
+
+PROC line (REAL CONST x offset, y offset, width, height, INT CONST line width) :
+
+  IF line width > 0
+     THEN graph on (x offset, y offset, width, height);
+          out ("LW" + text (line width) + ";");
+          out ("PR;");
+          out ("PD" + text (+w) + "," + text (-h) + ";");
+          graph off;
+  FI;
+
+END PROC line;
+
+PROC x line (REAL CONST x offset, y offset, width, INT CONST line width) :
+
+  IF line width > 0
+     THEN graph on (x offset, y offset, width, 0.0);
+          out ("LW" + text (line width) + ";");
+          out ("PR;");
+          out ("PD" + text (+w) + "," + "0;");
+          graph off;
+  FI;
+
+END PROC x line;
+
+PROC y line (REAL CONST x offset, y offset, height, INT CONST line width) :
+
+  IF line width > 0
+     THEN graph on (x offset, y offset, 0.0, height);
+          out ("LW" + text (line width) + ";");
+          out ("PR;");
+          out ("PD0," + text (-h) + ";");
+          graph off;
+  FI;
+
+END PROC y line;
+
+
+PROC box (REAL CONST x offset, y offset, width, height,
+          INT CONST pattern type, line width) :
+
+  IF   pattern type = 0
+       THEN box frame (x offset, y offset, width, height, line width)
+  ELIF line width   = 0
+       THEN box shade (x offset, y offset, width, height, pattern type)
+       ELSE graph on (x offset, y offset, width, height);
+            out ("LW" + text (line width) + ";");
+            set pattern (pattern type);
+            out ("ER" + text (+w) + "," + text (-h) + ";");
+            graph off;
+  FI;
+
+END PROC box;
+
+
+PROC box shade (REAL CONST x offset, y offset, width, height,
+                INT CONST pattern type) :
+
+  IF pattern type <> 0
+     THEN graph on (x offset, y offset, width, height);
+          set pattern (pattern type);
+          out ("RR" + text (+w) + "," + text (-h) + ";");
+          graph off;
+  FI;
+
+END PROC box shade;
+
+
+PROC box frame (REAL CONST x offset, y offset, width, height,
+                INT CONST line width) :
+
+  IF line width <> 0
+     THEN graph on (x offset, y offset, width, height);
+          out ("LW" + text (line width) + ";");
+          out ("PR;");
+          out ("PD");
+          out (text (+w) + "," +            "0,");
+          out (           "0," + text (-h) + ",");
+          out (text (-w) + "," +            "0,");
+          out (           "0," + text (+h) + ";");
+          graph off;
+   FI;
+
+END PROC box frame;
+
+
+PROC cake (REAL CONST x offset, y offset, radius, start angle, sweep angle,
+          INT CONST pattern type, line width) :
+
+  IF   pattern type = 0
+       THEN cake frame (x offset, y offset, radius, start angle, sweep angle, line width)
+  ELIF line width   = 0
+       THEN cake shade (x offset, y offset, radius, start angle, sweep angle, pattern type)
+       ELSE graph on (x offset, y offset, radius, 0.0);
+            out ("LW" + text (line width) + ";");
+            set pattern (pattern type);
+            out ("EW" + text (+w) + "," + text (start angle) + "," + text (sweep angle) + ";");
+            graph off;
+  FI;
+
+END PROC cake;
+
+
+PROC cake shade (REAL CONST x offset, y offset, radius, start angle, sweep angle,
+                INT CONST pattern type) :
+
+  IF pattern type > 0 CAND w > 0
+     THEN graph on (x offset, y offset, radius, 0.0);
+          set pattern (pattern type);
+          out ("WG" + text (+w) + "," + text (start angle) + "," + text (sweep angle) + ";");
+          graph off;
+  FI;
+
+END PROC cake shade;
+
+
+PROC cake frame (REAL CONST x offset, y offset, radius, start angle, sweep angle,
+                 INT CONST line width) :
+
+
+  IF line width <> 0
+     THEN REAL CONST xs := real (x) + cos (start angle*pi/180.0) * real (w),
+                     ys := real (y) + sin (start angle*pi/180.0) * real (w);
+          graph on (x offset, y offset, radius, 0.0);
+          out ("LW" + text (line width) + ";");
+          out ("MA"+ text (xs) + "," + text (ys) + ";");
+          out ("FA"+ text ( x) + "," + text ( y) + "," + text (sweep angle) + ";");
+          out ("MA"+ text ( x) + "," + text ( y) + ";");
+          graph off;
+   FI;
+
+END PROC cake frame;
+
+
+PROC graph on (REAL CONST x offset, y offset, width, height) :
+
+  x := x pos + x step conversion (x offset);
+  y := plot y size - (y pos + y step conversion (y offset));
+  w := x step conversion (width);
+  h := y step conversion (height);
+  out (""28"Aa");
+  out ("DF;");
+  out ("MA"+ text (x) + "," + text (y) + ";");
+
+  . plot y size : 3389 - y step conversion (1.0)
+
+END PROC graph on;
+
+PROC graph off :
+
+  out (""28"Az");
+
+END PROC graph off;
+
+
+PROC set pattern (INT CONST pattern type) :
+
+  out ("XX1;");
+  out (pattern);
+
+  . pattern :
+      SELECT pattern type OF
+        CASE  1 : "FT2,1,0;"
+        CASE  2 : "FT2,1,90;"
+        CASE  3 : "FT2,1,45;"
+        CASE  4 : "FT3,1,0;"
+        CASE  5 : "FT3,1,45;"
+        CASE  6 : "FT2,100,0;"
+        CASE  7 : "FT2,100,90;"
+        CASE  8 : "FT2,100,45;"
+        CASE  9 : "FT3,100,0;"
+        CASE 10 : "FT3,100,45;"
+        OTHERWISE : "FT1;"
+      END SELECT
+
+END PROC set pattern;
+
+
+END PACKET nec lc 08 box commands;
+
+
+ 
+#page# 
+(******************************************************************)
+(***                                                            ***)
+(***   Generierung des Printers                                 ***)
+(***                                                            ***)
+(******************************************************************)
+ 
+LET printer name = "printer.nec.lc-08";
+ 
+TEXT VAR fonttab name := "fonttab.nec.lc-08";
+ 
+BOOL CONST multi user := (pcb (9) AND 255) <> 1;
+ 
+INT VAR pr channel;
+TEXT VAR buffer;
+ 
+command dialogue (TRUE);
+IF NOT multi user 
+  THEN errorstop ("Dieser Treiber arbeitet nur mit Multi-Tasking-EUMEL") 
+FI; 
+ask for print channel;
+load font table;
+forget (printer name, quiet);
+IF multi user THEN generate printer spool FI;
+command dialogue (TRUE);
+check on;
+.
+  ask for print channel : 
+    line;
+    put ("gib Druckerkanal:");
+    get (pr channel);
+    do ("serverchannel(" + text (pr channel) + ")" ) ;
+    line;
+.
+  load font table :
+    IF NOT exists (fonttab name)
+       THEN REP line (2); 
+                putline ("Bitte Archiv mit der Fonttabelle """ +
+                          fonttab name + """ einlegen!");
+                line;
+            UNTIL yes ("Archiv eingelegt") PER;
+            reserve archive;
+            fetch (fonttab name, archive);
+            release (archive);
+    FI;
+    font table (fonttab name);
+    IF multi user
+       THEN command dialogue (FALSE);
+            do ("save(""" + font tab name + """,task(""configurator""))")
+    FI;
+    forget (fonttab name, quiet);
+ 
+    . reserve archive :
+        INT VAR p1, p2;
+        archive (" "31" ");
+        disable stop;
+        list (archive);
+        IF is error
+           THEN buffer := errormessage;
+                p1 := pos (buffer, """", 1 ) + 1;
+                p2 := pos (buffer, """", p1) - 1;
+                IF p1 > 0 AND p2 > 0
+                   THEN clear error;
+                        buffer := subtext (buffer, p1, p2);
+                        archive (buffer);
+                FI;
+        FI;
+        enable stop;
+ 
+. generate printer spool :
+    eumel must advertise;
+    cursor (1, 12);
+    putline ("In allen bestehenden Tasks - insbesondere in der Task ""PUBLIC"" - muß");
+    putline ("die Fonttabelle mit dem Kommando");
+    line;
+    putline ("      font table (""" + font tab name + """)");
+    line;
+    putline ("eingestellt werden!!!");
+    line (4);
+    putline ("Generierung beendet, weiter mit 'SV'");
+    generate printer server;
+    do (buffer);
+ 
+. generate printer server :
+    buffer :=  "break (quiet);";
+    buffer CAT "spool manager (PROC printer);";
+    buffer CAT "INT VAR reply; DATASPACE VAR ds; FILE VAR file;";
+    buffer CAT "PROC printer:";
+    buffer CAT "  disable stop;";
+    buffer CAT "  continue (server channel);";
+    buffer CAT "  check error (error message);";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  REP forget (ds);";
+    buffer CAT "      execute print;";
+    buffer CAT "      IF is error AND online THEN put error; clear error; FI;";
+    buffer CAT "  PER;";
+    buffer CAT "END PROC printer;";
+    buffer CAT "PROC execute print:";
+    buffer CAT "  LET ack = 0, fetch code = 11, file type = 1003;";
+    buffer CAT "  enable stop;";
+    buffer CAT "  ds := nilspace;";
+    buffer CAT "  call (father, fetch code, ds, reply);";
+    buffer CAT "  IF reply = ack CAND type (ds) = file type";
+    buffer CAT "     THEN file := sequential file (input, ds);";
+    buffer CAT "          print (file,";
+    buffer CAT "            PROC (INT CONST, INT VAR, INT VAR) open,";
+    buffer CAT "            PROC (INT CONST, INT CONST) close,";
+    buffer CAT "            PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC execute print;";
+    buffer CAT "PROC check error(TEXT CONST message):";
+    buffer CAT "  IF is error";
+    buffer CAT "     THEN clear error; rename myself (message);";
+    buffer CAT "          IF is error THEN end(myself) FI;";
+    buffer CAT "          pause (9000); end(myself);";
+    buffer CAT "  FI;";
+    buffer CAT "END PROC check error;";
+
diff --git a/printer/laser/readme b/printer/laser/readme
new file mode 100644
index 0000000..019d75c
--- /dev/null
+++ b/printer/laser/readme
@@ -0,0 +1,155 @@
+Treiber-Installations-Programm für Laserdrucker   21. 2.1989 
+ 
+ 
+1. Installations- und Gebrauchsanleitung 
+ 
+Einrichten 
+So wird das Treiber-Installationsprogramm eingerichtet: 
+ 
+    Richten Sie die Task PRINTER als Sohn von SYSUR ein : 
+ 
+           begin ("PRINTER", "SYSUR") 
+            
+    Geben Sie in der Task PRINTER nacheinander folgende Kommandos
+    ein, die Sie jeweils mit der ENTER-Taste bestätigen: 
+ 
+       archive ("std.printer") 
+       fetch("laser.inserter",archive) 
+       insert ("laser.inserter") 
+ 
+Das Programm wird dann insertiert. 
+ 
+ 
+Menüsystem 
+Das Installationsprogramm zeigt nun eine Liste von Druckerherstellern.
+Wählen Sie den Hersteller Ihres Druckers aus! Hiernach wird eine Liste
+der unterstützten Drucker dieses Herstellers gezeigt. Wählen Sie hier
+den passenden Typ aus! 
+Das Installationsprogramm fragt nun nach der Art der Druckerschnittstelle.
+Die Druckerhardware muß wie hier angegeben konfiguriert sein, wenn sie
+mit dem ausgewählten Treiber betrieben werden soll. 
+ 
+Das Installationsprogramm kann mit 'treiber einrichten' erneut aufgerufen
+werden. Die Druckerschnittstelle kann mit 'printer setup' nachträglich
+umkonfiguriert werden. 
+ 
+2. Druckertreiber-Auswahl 
+ 
+Verwendung nicht im Menü enthaltener Drucker 
+Für den Fall, daß Sie genau Ihren Drucker im Menü nicht finden,
+müssen Sie herausfinden (Druckerhandbuch, -händler!),
+welchen Drucker Ihr Drucker emuliert oder welchem er ähnlich ist.
+(Die meisten Laserdrucker verfügen über eine HP-Laserjet Emulation).
+ 
+ 
+3. Steuerungsmöglichkeiten und Spezialfeatures 
+ 
+Einige Treiber bieten bestimmte Einstellungsmöglichkeiten.
+Die Einstellungen können über 
+- Steuerprozeduren 
+- Materialanweisungen bzw. 
+- direkte Druckeranweisungen 
+vorgenommen werden. 
+ 
+Steuerprozeduren 
+setzen Einstellungen, die für alle Dokumente (Druckdateien) gelten
+sollen. Die Prozeduren müssen in der Druckspooltask (meist: "PRINTER")
+aufgerufen werden. Vor Aufruf der Prozeduren muß das Spoolkommando 
+'stop spool' gegeben werden!
+ 
+ 
+ 
+PROC papersize (REAL CONST breite, länge) 
+    Dient zur Einstellung der Größe der physikalisch beschreibbaren
+    Fläche. 
+    Beispiel:  papersize (21.0, 29.7) 
+               (Standardeinstellung für DIN A4 Format)
+ 
+PROC papersize 
+    Informationsprozedur 
+ 
+Die Änderungen, die Sie in der Druckspooltask vorgenommen haben
+werden erst wirksam, nachdem das Spool-Kommando 'start spool' ge­
+geben und die Druckspooltask verlassen wurde. 
+ 
+ 
+ 
+Materialanweisungen \#material("...")\# 
+müssen in der Druckdatei vor dem ersten druckbaren Zeichen stehen und
+setzen Einstellungen für eine ganze Datei. (Materialanweisungen haben
+für die jeweilige Datei Vorrang vor den durch Steuerprozeduren einge­
+stellten Standardwerten. Diese werden durch die Materialanweisung aber
+nicht geändert.) 
+ 
+Beispiel:  \#material("landscape")\#  oder \#material("quer")\#
+           Der Druckertreiber stellt sich auf Querdruck ein. Für das 
+           Papierformat werden die
+           durch papersize eingestellten Werte vertauscht angenommen.
+           Es sollten nur Schrifttypen verwendet werden, die auch im 
+           Landscape-Modus vorhanden sind.
+
+ 
+- Es darf in einer Datei nur eine Materialanweisung stehen! Sollen meh­
+  rere Einstellungen vorgenommen werden, müssen sie in einer Anweisung
+  erscheinen. Beispiel:  \#material("quer;2")\# 
+ 
+- Achten Sie bei Materialanweisungen
+  besonders auf korrekte Schreibweise! Es werden nur Kleinbuchstaben
+  berücksichtigt! Also:  \#"quer"\# und keinesfalls \#"QUER"\#!!! 
+ 
+- Bei Laserdruckern gebräuchliche Materialanweisungen sind: 
+    - landscape (quer) 
+    - manual 
+    - tray 
+ 
+direkte Druckeranweisungen \#"..."\# 
+gelten ab der Position, an der sie in der Datei auftreten. Sie haben
+(sofern sie erlaubt sind,) Vorrang vor Standardeinstellungen und
+Materialeinstellungen. 
+ 
+ 
+- Direkte Druckeranweisungen werden vom EUMEL-Drucker ignoriert und
+  nur vom Druckertreiber in eine Kommando-Sequenz umgesetzt. Es kann
+  daher vorkommen, daß (z.B. bei Spaltendruck) unerwartete Ergebnisse
+  erscheinen, weil der EUMEL-Drucker dann den Text in einer anderen
+  Reihenfolge an den Drucker sendet, als er in der Datei steht, die
+  mit dem direkten Druckerkommando gesetzte Modifikation aber (z.B.
+  für beide Spalten) unerwünscht erhalten bleibt. Direkte
+  Druckeranweisungen, die das Schriftformat verändern,
+  sollten grundsätzlich nicht gegeben werden. 
+ 
+ 
+4. Spezialfeatures: 
+ 
+Die Druckertreiber für die Drucker APPLE-Laserwriter und NEC LC-08
+verfügen über Anweisungen zum Zeichnen einer Linie, Box oder eines Kuchen- 
+stücks, die als direkte Druckeranweisungen in ELAN-Syntax gegeben werden
+müssen. 
+Folgende Anweisungen stehen zur Verfügung: 
+ 
+PROC line (REAL CONST x offset, y offset, width, height, line width) :
+
+PROC x line (REAL CONST x offset, y offset, width, line width) :
+
+PROC y line (REAL CONST x offset, y offset, height, line width) :
+ 
+PROC box (REAL CONST x offset, y offset, width, height, line width, pattern):
+
+PROC box shade (REAL CONST x offset, y offset, width, height, pattern) :
+
+PROC box frame (REAL CONST x offset, y offset, width, height, line width) :
+
+PROC cake (REAL CONST x offset, y offset, radius, start angle, sweep angle, 
+                      line width, pattern) :
+
+PROC cake shade (REAL CONST x offset, y offset, radius, start angle, 
+                            sweep angle, pattern) :
+
+PROC cake frame (REAL CONST x offset, y offset, radius, start angle, 
+                            sweep angle, line width) :
+
+
+
+
+
+
diff --git a/prolog/calc b/prolog/calc
new file mode 100644
index 0000000..0ed11af
--- /dev/null
+++ b/prolog/calc
@@ -0,0 +1,32 @@
+{ CALC evaluates arithmetic expressions with store } 
+ 
+calc:- eval ([], RS), write (result store), write (RS), nl. 
+ 
+eval (SI, SO):- 
+   read (CALC), nonvar (CALC), eval member (CALC, SI, SO). 
+ 
+eval member (CALC, SI, SO):- 
+   member (CALC, [stop,end,bye,eof]), SO=SI; 
+   eval (CALC,I,SI,ST), write (I), eval (ST,SO); 
+   write (error in), write (CALC), nl, eval (SI, SO). 
+ 
+eval (I, I, S, S):- integer (I). 
+eval (N, I, S, S):- atom (N), eval atom (N, I, S). 
+ 
+eval atom (N, I, S):- 
+  member (N=I, S); 
+  write ("error:  Cell"), write (N), 
+    write("not found in store. 0 substituted."), nl, I=0. 
+ 
+eval ( L+R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J+K. 
+eval ( L-R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J-K. 
+eval ( L*R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J*K. 
+eval ( L/R,I,SI,SO):- eval (L,J,SI,ST), eval (R,K,ST,SO), I IS J/K. 
+ 
+eval (N=O, I, SI, SO):- 
+  atom (N), eval (O,I,SI,ST), eval repl (N,I,ST,SO). 
+ 
+eval repl (N, I, [], [=(N,I)]). 
+eval repl (N, I, [=(N,_)|S], [=(N,I)|S]). 
+eval repl (N, I, [=(M,J)|SI], [=(M,J)|SO]):- eval repl (N, I, SI, SO). 
+
diff --git a/prolog/family b/prolog/family
new file mode 100644
index 0000000..8419cc6
--- /dev/null
+++ b/prolog/family
@@ -0,0 +1,29 @@
+ 
+mann(jürgen). mann(detlef). mann (frank). mann (peter). mann(jochen). 
+frau(gaby). frau(yvonne). frau(sinha). frau(rita). frau(viktoria). 
+frau(adelheid). 
+vater(gaby, peter). vater(yvonne, peter). vater(frank, peter). 
+mutter(gaby, rita). mutter(yvonne, rita). mutter(frank, rita). 
+mutter(rita,viktoria). 
+vater(jürgen, heinz). mutter(jürgen, natalie). 
+vater(kalle, heinz). mutter(kalle, natalie). 
+mann(gaby, jürgen). mann(yvonne, detlef). mann(sinha,frank). 
+mann(rita, peter). mann(adelheid, jochen). 
+frau(X,Y) :- mann (Y,X). 
+großmutter(X,Y):- mutter(X,H), mutter(H,Y); vater(X,H), mutter(H,Y). 
+sohn(X,Y):- vater(Y,X), mann(Y); mutter(Y,X), mann(Y) . 
+tochter(X,Y):-  vater(Y,X), frau(Y); mutter(Y,X), frau(Y). 
+geschwister(X,Y):-vater(X,A),vater(Y,A),mutter(X,B),mutter(Y,B),<>(X,Y). 
+bruder(X,Y):- geschwister(X,Y), mann(Y). 
+schwester(X,Y):- geschwister(X,Y), frau(Y). 
+schwager(X,Y):- mann(X,Z), bruder(Z,Y); frau(X,Z), bruder(Z,Y). 
+schwägerin(X,Y):-mann(X,Z),schwester(Z,Y);frau(X,Y),schwester(Z,Y). 
+freund (X,Y):-    mann(Y),    mann(X),    <>(X,Y); 
+                  mann(Y),    frau(X),    mann(Z,Y), <>(X,Z); 
+                  mann(Y),    frau(X), !, mann(Z,Y), []; 
+                  mann(Y),    frau(X). 
+freundin (X,Y):-  frau(Y),    frau(X),    <>(X,Y); 
+                  frau(Y),    mann(X),    mann(Y,Z), <>(X,Z); 
+                  frau(Y),    mann(X), !, mann(Y,Z), []; 
+                  frau(Y),    mann(X). 
+
diff --git a/prolog/permute b/prolog/permute
new file mode 100644
index 0000000..54f8fee
--- /dev/null
+++ b/prolog/permute
@@ -0,0 +1,15 @@
+permute ([], []). 
+permute ([E|X], Z):- 
+        permute (X, Y), insert (E, Y, Z). 
+insert  (E, X, [E|X]). 
+insert  (E, [F|X], [F|Y]):- 
+        insert (E, X, Y). 
+marquise(RESULT):- 
+  permute (["beautiful marquise", 
+                "your beautiful eyes", 
+                  "make me", 
+                    "die", 
+                      "of love" 
+                        ], 
+                          RESULT). 
+
diff --git a/prolog/prieks b/prolog/prieks
new file mode 100644
index 0000000..372ec9d
--- /dev/null
+++ b/prolog/prieks
@@ -0,0 +1,58 @@
+ 
+ist priek (bo priek). 
+ist priek (ki priek). 
+ist priek (bla priek). 
+ 
+WER GNASELT WEN :- population (B), 
+                   member ([WEN, WER, _], B), 
+                   bedingungen (B). 
+ 
+WER KNAUDERT WEN:- population (B), 
+                   member ([WER, _, WEN], B), 
+                   bedingungen (B). 
+ 
+population (B):-   sind prieks (U, V, W), 
+                   sind knauderarten (R, S, T), 
+                   B = [ [drausla puemfe, U, R], 
+                         [glessla puemfe, V, S], 
+                         [hapla puemfe, W, T]    ]. 
+ 
+sind prieks (X,Y,Z):- ist priek (G), 
+                      ist priek (H), H<>G, 
+                      ist priek (I), I<>G, I<>H, !, 
+                          permute ([G,H,I], [X,Y,Z]). 
+ 
+sind knauderarten (X,Y,Z):- ist knauderart (G), 
+                            ist knauderart (H), H<>G, 
+                            ist knauderart (I), I<>G, I<>H, !, 
+                                permute ([G,H,I],[X,Y,Z]). 
+ 
+ist knauderart (an). 
+ist knauderart (ab). 
+ist knauderart (ueber). 
+ 
+bedingungen (B):-  not member ([hapla puemfe,ki priek,_],B) , 
+                   not member ([hapla puemfe,_,ueber],B) , 
+                   not member ([drausla puemfe,bo priek,_],B) , 
+                   not member ([_,bo priek,ab],B) , 
+                   noch ne bedingung (B) , 
+                   weitere bedingungen (B) , !. 
+ 
+weitere bedingungen (B):-  not member([_,ki priek,ueber],B), 
+                           not member([_,bo priek,ueber],B) 
+                           ; 
+                           member([drausla puemfe,_,an],B). 
+ 
+noch ne bedingung (B):-    not member ([drausla puemfe,ki priek,_],B) 
+                           ; 
+                           not member ([glessla puemfe,_,ueber],B). 
+ 
+permute ([], []). 
+permute (X, [Y|Z]):- delete (Y ,X, E), permute (E, Z). 
+delete (X, [X|Z], Z). 
+delete (X, [Y|Z], [Y|E]):- delete (X, Z, E). 
+member (X, [X|Z]).        
+member (X, [Y|Z]):-  member (X, Z). 
+not member (X, []). 
+not member (X, [Y|Z]):- X <> Y, not member (X,Z). 
+
diff --git a/prolog/prolog b/prolog/prolog
new file mode 100644
index 0000000..7ac2e6a
--- /dev/null
+++ b/prolog/prolog
@@ -0,0 +1,2488 @@
+PACKET  prolog                                   (* Autor: P.Heyderhoff *) 
+DEFINES                                          (* Date:  03.07.1987   *) 
+        prolog, prolog again: 
+ 
+{ GLOBALS } 
+ 
+LET { Stacksize parameter } 
+    limit = 800; 
+ 
+LET { nil-POINTER } 
+    nil = 0; 
+ 
+LET { bootstrap rules } 
+    boot = """|"".""!"".""MOD"".""-"".""+"".""*"".""/"".bye.listing. 
+call(X).write(X).writeq(X).read(X).get(X).get0(X).put(X).incr(X). 
+assertz(X).asserta(X).retract(X).var(X). 
+X IS Y.X=X.X<>Y.X<=Y.X==Y.X=..Y.clause(X,_).name(X,Y). 
+arg(X,Y,Z).functor(X,Y,Z).elan(X).elan(X,Y)"; 
+ 
+LET { bootstrap symbols, see: boot } 
+    cons=1, cut=2, mod=3, {TOKEN: minus=4, plus=5, times=6, slash=7} 
+    bye=8, list=9, call=10, xpar=11, 
+    writ=12, wriq=13, read=14, get=15, get0=16, put0=17, 
+    incr=18, ass=19, assa=20, retr=21, vari=22, 
+    is=23, ypar=24, dif=26, leq=27, eq=28, univ=29, clau=30, claupar=31, 
+    nam=32, argi=33, zpar=34, func=35, 
+    elan=36, build ins=33; 
+ 
+LET { TOKENS } 
+    stroke=1, exclamation=2, colon=3, minus=4, plus=5, times=6, slash=7, 
+    underscore=8, less=9, equal=10, uneq=11, grt=12, eqeq=13, 
+    eqdotdot=14, period=15, comma=17, semicolon=18, 
+    open paren=19, close paren=20, open bracket=21, close bracket=22, 
+    end of input=23, boldvar=24, number=25, identifier=26; 
+ 
+LET { SYMBOLTYPES } 
+    tag=1, bold=2, num=3, tex=4, operator=5, delimiter=6, end of file=7, 
+    within com=8, within tex=9; 
+ 
+INT CONST integer:= -1, var:= -2; 
+ 
+LET TOKEN = INT; 
+ 
+LET SYMBOLTYPE = INT; 
+ 
+LET SYMBOL = INT; 
+LET SYMBOLTABLE = THESAURUS; 
+ 
+LET TERMS = INT; 
+{ LET TERMSCELL = STRUCT (TERM first, 
+                          TERMS rest); } 
+LET TERM = STRUCT (SYMBOL symbol, 
+                   TERMS arguments, 
+                   INT arity); 
+ 
+LET CLAUSES = INT; 
+{ LET CLAUSESCELL = STRUCT (TERMS first, 
+                            CLAUSES rest); } 
+LET FRAME = INT; 
+LET FRAMECELL = STRUCT (TERM call, 
+                        FRAME father, 
+                        TERMS subgoals, { remaining } 
+                        ENVIRONMENT environment, 
+                        EXPRESSIONS reset, 
+                        CLAUSES rest { potential rules }, 
+                        FRAME level ); 
+ 
+LET ENVIRONMENT = INT; 
+LET ENVIRONMENTCELL = STRUCT (SUBSTITUTION first, 
+                              ENVIRONMENT rest); 
+LET SUBSTITUTION = STRUCT (TERM variable, 
+                           TERM substitute, 
+                           FRAME others); 
+ 
+LET FRAMESTACK = STRUCT (FRAME frame, goalframe, removed goal, 
+                         INT last tp, last kp, last fp, last np); 
+ 
+LET EXPRESSIONS = INT; 
+ 
+LET EXPRESSION = STRUCT (TERM term, 
+                         FRAME index); 
+ 
+TEXT VAR tcsymbol, tcarguments, tcarity, tcrest; INT VAR tp; 
+ 
+TEXT VAR kcfirst, kcrest; INT VAR kp; 
+ 
+ROW limit FRAMECELL VAR fc; INT VAR fp; 
+ 
+ROW limit ENVIRONMENTCELL VAR nc; INT VAR np; 
+ 
+ROW limit FRAMESTACK VAR fsc; INT VAR fsp; 
+ 
+ROW limit EXPRESSION VAR ec; INT VAR ep; 
+ 
+ROW limit CLAUSES VAR freec; INT VAR freep; 
+ 
+SYMBOL VAR look ahead value; 
+TEXT   VAR look ahead symbol, ahead symbol; 
+BOOL   VAR look ahead empty,  ahead empty; 
+INT    VAR look ahead token,  ahead symboltype; 
+ 
+SYMBOL VAR pattern; 
+ 
+TERMS VAR ts; 
+ 
+TERM VAR t, t2, t3; 
+ 
+CLAUSES VAR k, kl, knowledge base, candidates; 
+ 
+FRAME VAR root, cut level, res frame; 
+ 
+SYMBOLTABLE VAR symboltable, reset symboltable; 
+ 
+FILE VAR file; 
+ 
+BOOL VAR from file, tracing, testing, found, quoting, free of errors, finish; 
+ 
+INT  VAR i, j, reset tp, reset kp, reset freep, anonym value, 
+         inference level, inference count, rule count; 
+ 
+TEXT VAR command; 
+ 
+REAL VAR start time:= 0.0; 
+ 
+PROC init globals: 
+   tp := nil; kp:= nil; 
+   tracing:= FALSE; 
+   testing:= FALSE; 
+   symboltable:= empty thesaurus; 
+   reset symboltable:= symboltable; 
+   reset tp:= nil; 
+   reset kp:= nil; 
+   reset freep:= nil; 
+   knowledge base:= nil; 
+   from file:= FALSE; 
+   inference count:= 0; 
+   tcsymbol:=""; 
+   tcarguments:=""; 
+   tcarity:=""; 
+   tcrest:=""; 
+   kcfirst:=""; 
+   kcrest:=""; 
+   quoting:= TRUE 
+ENDPROC init globals; 
+ 
+PROC init prooftree: 
+   root := nil; 
+   freep:= reset freep; 
+   fp:= nil; fsp:= nil; np:= nil; ep:= nil; tp:= reset tp; kp:= reset kp; 
+   symboltable:= reset symboltable; 
+   free of errors:= TRUE; 
+   candidates:= nil; 
+   new (fp, root); 
+   fc(root):= FRAMECELL:(t, nil, nil, nil, nil, nil, 0); 
+   anonym value:= 0; 
+   collect heap garbage; 
+   finish:= FALSE 
+ENDPROC init proof tree; 
+  
+PROC prolog (TEXT CONST knowledge): 
+   line; 
+   last param (knowledge); 
+   init globals; 
+   bootstrap; 
+   IF   exists (knowledge) THEN consult (knowledge) FI; 
+   IF   free of errors 
+   THEN prolog again 
+   FI; 
+   last param (knowledge). 
+ 
+ bootstrap: 
+   TERMS VAR clauses:= nil; 
+   init proof tree; 
+   look ahead empty:= TRUE; ahead empty:= TRUE; 
+   scan (boot); 
+   WHILE look ahead <> end of input 
+   REP read clause; 
+       assertz (clauses); 
+       clauses:= nil 
+   PER; 
+   reset tp:= tp; 
+   reset kp:= kp; 
+   reset symboltable:= symboltable. 
+ 
+ read clause: 
+   TERM VAR term; 
+   read term (term); 
+   IF   look ahead = period 
+   THEN remove token 
+   FI; 
+   insert term in clauses. 
+ 
+ insert term in clauses: 
+   TERMS VAR tmp; 
+   new tp (tmp); 
+   replace(tcsymbol,tmp,term.symbol); 
+   replace(tcarguments,tmp,term.arguments); 
+   replace(tcarity,tmp,term.arity); 
+   replace(tcrest,tmp, clauses); 
+   clauses:= tmp. 
+ 
+ remove token: 
+   look ahead empty:= TRUE. 
+ 
+ENDPROC prolog; 
+ 
+BOOL PROC prolog (TEXT CONST query, TEXT VAR answer): 
+   disable stop; 
+   init prooftree; 
+   read goals; 
+   BOOL VAR result:= NOT prove; 
+   answer is value of last variable; 
+   result . 
+ 
+ read goals: 
+   scan (query); 
+   look ahead empty:= TRUE; ahead empty:= TRUE; 
+   from file:= FALSE; 
+   fc(root).subgoals:= nil; 
+   read terms (fc(root).subgoals); 
+   IF   look ahead = period 
+   THEN remove token 
+   FI; 
+   IF   look ahead <> end of input 
+   THEN syntax error ("unexpected characters after last goal") 
+   FI. 
+ 
+ answer is value of last variable: 
+   IF fc(root).environment <> nil 
+   THEN 
+        value (nc(fc(root).environment).first.variable, t, root); 
+        file:= sequential file (output, "$$"); 
+        sysout ("$$"); 
+        write term backward (t); 
+        sysout (""); 
+        input (file); 
+        getline (file, answer); 
+        forget ("$$", quiet) 
+   ELSE answer:= "" 
+   FI . 
+ 
+ remove token: 
+   look ahead empty:= TRUE. 
+ 
+ENDPROC prolog; 
+ 
+PROC prolog again: 
+   disable stop; 
+   lernsequenz auf taste legen ("q","bye"13""); 
+   write (""13""10""5"?- "); 
+   REP 
+         init proof tree; 
+         initiate read terms (fc(root).subgoals, "-"); 
+         read goals; 
+         prove goals; 
+   UNTIL finish 
+   PER; 
+   lernsequenz auf taste legen ("q","break"13""). 
+   
+ read goals: 
+   IF   is error 
+   THEN c:= "?" 
+   ELIF look ahead = open bracket 
+   THEN remove token; 
+        read consult list 
+   ELSE read terms (fc(root).subgoals); 
+        IF   look ahead = period 
+        THEN remove token 
+        FI; 
+        IF   look ahead <> end of input 
+        THEN syntax error ("unexpected characters after last goal") 
+        FI 
+   FI. 
+ 
+ prove goals: 
+   IF  tracing THEN inference level:= 0; line FI; 
+   inference count:= 0; 
+   start time:= clock (0); 
+   REP 
+        IF   c <> "?" CAND prove 
+        THEN IF tracing THEN line FI; 
+             write ("   no"13""10""5"?- "); 
+             LEAVE prove goals 
+        ELSE IF tracing THEN inference level:= 0 FI; 
+             get cursor (i,j); IF i > 1 THEN line FI; 
+             IF   is error 
+             THEN put error; clear error; putline (""4""{cleop}); 
+                  free of errors:= FALSE; 
+                  sysout (""); sysin (""); 
+                  putline ("type '?' to get explanations"); 
+                  putline ("type ';' to try next alternative"); 
+                  putline ("type any other key to stop") 
+             ELSE write answers 
+             FI; 
+             get cursor (i, j); 
+             write (""10""10""13""5"?- "); 
+             getchar (c); 
+             TEXT VAR c; 
+             SELECT pos ("?;",c) OF 
+             CASE 1:    write ("?"); 
+                        inform 
+             CASE 2:    write (""13""5""3""3""); 
+                        get cursor (j, k); 
+                        cursor (i, k); 
+                        putline (";"); 
+             OTHERWISE  IF c >= " " COR c = ""27"" THEN push (c) FI; 
+                        LEAVE prove goals 
+             END SELECT; 
+             IF tracing THEN line FI; 
+             IF   is error 
+             THEN put error; clear error; putline (""4""{cleop}) 
+             FI 
+        FI 
+   PER. 
+ 
+ write answers: 
+   write ("   "); 
+   IF   fc(root).environment = nil 
+   THEN IF free of errors THEN put ("yes") ELSE put ("no") FI 
+   ELSE write environment list (root) 
+   FI. 
+ 
+ remove token: 
+   look ahead empty:= TRUE. 
+ 
+ENDPROC prolog again; 
+ 
+PROC prolog: prolog (last param) ENDPROC prolog; 
+  
+BOOL PROC prove: 
+   enable stop; 
+   initialize prove; 
+   find potential candidates. 
+ 
+ handle remaining subgoals: 
+   { all subgoals to the left are solved } 
+   IF   subgoals remain 
+   THEN get candidates 
+   ELSE LEAVE prove WITH FALSE 
+   FI. 
+ 
+ find potential candidates: 
+   REP  try one candidate PER; TRUE. 
+ 
+ try one candidate: 
+   { all candidates tried do not unify with the current goal } 
+   IF   head of one candidate unifies with the current goal 
+   THEN push frame; 
+        handle remaining subgoals 
+   ELSE backtrack to the parent of the current goal 
+   FI. 
+ 
+ backtrack to the parent of the current goal: 
+   { none of the candidates unify with the current goal } 
+   IF   prooftree exhausted 
+   THEN LEAVE prove WITH TRUE 
+   ELSE pop frame 
+   FI. 
+ 
+ prooftree exhausted: fsp = 1. 
+ 
+ initialize prove: 
+   TERM VAR curr call; 
+   FRAME VAR curr frame, top frame; 
+   EXPRESSIONS VAR last ep; 
+   IF   fsp = nil 
+   THEN curr frame:= root; 
+        push frame; 
+        handle remaining subgoals 
+   ELSE IF tracing THEN line FI; 
+        backtrack to the parent of the current goal 
+   FI. 
+ 
+ head of one candidate unifies with the current goal: 
+   son  { curr frame is the resulting next son }. 
+  
+ subgoals remain: 
+   select frame {(curr frame, curr call)}. 
+ 
+ push frame: 
+   fsp INCR 1; 
+   fsc(fsp).frame:= curr frame; 
+   fsc(fsp).goalframe:= nil; 
+   fsc(fsp).last tp:= tp; 
+   fsc(fsp).last kp:= kp; 
+   fsc(fsp).last fp:= fp; 
+   fsc(fsp).last np:= np. 
+ 
+ pop frame: 
+   { fsp <> nil } 
+   top frame:= fsc(fsp).frame; 
+   curr frame:= fc(top frame).father; 
+   reinsert current call as subgoal; 
+   curr call:= fc(top frame).call; 
+   candidates:= fc(top frame).rest; 
+   cut level:= fc(top frame).level; 
+   tp:= fsc(fsp).last tp; 
+   kp:= fsc(fsp).last kp; 
+   fp:= fsc(fsp).last fp; 
+   np:= fsc(fsp).last np; 
+   fsp DECR 1; 
+   IF   tracing CAND inference level > 0 CAND NOT testing 
+   THEN write (""13""5""3""5""); inference level DECR 1 
+   FI; 
+   undo bindings (fc(top frame).reset). 
+ 
+ reinsert current call as subgoal:  
+   IF   fsc(fsp).goalframe <> nil 
+   THEN fc(fsc(fsp).goalframe).subgoals:= fsc(fsp).removed goal 
+   FI. 
+  
+ select frame: 
+   REP 
+       IF   next call 
+       THEN LEAVE select frame WITH TRUE 
+       FI; 
+       curr frame:= fc(curr frame).father 
+   UNTIL curr frame = nil PER; 
+   FALSE. 
+ 
+ next call: 
+   ts:= fc(curr frame).subgoals; 
+   IF   ts = nil 
+   THEN FALSE 
+   ELSE remove subgoals; TRUE 
+   FI. 
+ 
+ remove subgoals: 
+   curr call:= TERM:(tcsymbolISUBts, tcargumentsISUBts, tcarityISUBts); 
+   fc(curr frame).subgoals:= (tcrestISUB(ts)) ; 
+   fsc(fsp).goalframe:= curr frame; 
+   fsc(fsp).removed goal:= ts. 
+ 
+ get candidates: 
+   initialize clauses; 
+   WHILE more knowledge 
+   REP  find next clause candidate in knowledge base PER 
+   { candidates = a list of clauses which may be unifiable with curr call } . 
+ 
+ initialize clauses: 
+   fc(curr frame).level:= cut level; 
+   cut level:= curr frame; 
+   IF   curr call.arity = var 
+   THEN IF   bound (curr call, curr frame, curr call, ts) THEN FI; 
+        IF   curr call.arity = var 
+        THEN take goal itself as candidate; LEAVE get candidates 
+        FI 
+   FI; 
+   k:= knowledge base; 
+   found:= FALSE; 
+   candidates:= nil. 
+ 
+ take goal itself as candidate: 
+   new kp (candidates); 
+   replace (kcfirst, candidates, goal itself); 
+   replace (kcrest, candidates, nil). 
+ 
+ goal itself: 
+   new tp (ts); 
+   replace(tcsymbol,ts,curr call.symbol); 
+   replace(tcarguments,ts, curr call.arguments); 
+   replace(tcarity,ts, curr call.arity); 
+   replace(tcrest,ts, nil); 
+   ts. 
+ 
+ find next clause candidate in knowledge base: 
+   IF   (tcsymbolISUB((kcfirstISUB(k)) )) = curr call.symbol 
+   THEN found:= TRUE; 
+        IF   (tcarityISUB((kcfirstISUB(k)) ))  = curr call.arity 
+        THEN insert clause in candidates 
+        FI 
+   ELIF found 
+   THEN LEAVE get candidates 
+   FI; 
+   k:= (kcrestISUB(k)) . 
+ 
+ more knowledge: k <> nil. 
+ 
+ insert clause in candidates: 
+   kl:= candidates; 
+   new kp (candidates); 
+   replace(kcfirst,candidates,kcfirstISUBk); 
+   replace(kcrest, candidates, kl). 
+ 
+ son: 
+   { If rules has n sons, then this refinement will return TRUE the first 
+     n times, it is called and FALSE forever after. 
+     IF son then curr frame has become a frame for the next son. 
+     So this refinement helps to construct the prooftree. 
+   } 
+ 
+   IF   candidates = nil 
+   THEN FALSE 
+   ELSE create next son 
+   FI. 
+ 
+ create next son: 
+   initialize son; 
+   REP try to unify curr call with candidates 
+   UNTIL candidates exhausted PER; 
+   { not unified } 
+   forget son. 
+  
+ initialize son: 
+   last ep:= ep; 
+   new (fp, res frame); 
+   fc(res frame).environment:= nil. 
+ 
+ try to unify curr call with candidates: 
+   k:= (kcfirstISUB(candidates)) ; 
+   IF 
+   unify (curr call, 
+          curr frame, 
+          TERM:(tcsymbolISUBk, tcargumentsISUBk, tcarityISUBk), 
+          res frame) 
+   THEN 
+        IF tracing THEN trace unification results FI; 
+        apply rule; 
+        fill result frame 
+   ELSE remove curr call from candidates 
+   FI. 
+ 
+ candidates exhausted: candidates = nil. 
+ 
+ forget son: 
+   fp DECR 1; FALSE. 
+ 
+ fill result frame: 
+   ts:= (kcfirstISUB(candidates)) ; 
+   fc(res frame):= FRAMECELL:(curr call, 
+                              curr frame, 
+                              tcrestISUBts, 
+                              fc(res frame).environment, 
+                              last ep, 
+                              (kcrestISUB(candidates)) , 
+                              cut level); 
+   curr frame:= res frame; 
+   LEAVE son WITH TRUE. 
+ 
+ remove curr call from candidates: 
+   candidates:= (kcrestISUB(candidates)) ; 
+   LEAVE try to unify curr call with candidates. 
+  
+ apply rule: 
+   SELECT   curr call.symbol OF 
+   CASE cons: {cons, to construct lists, see PROC unify} 
+   CASE cut:  fc(res frame):= FRAMECELL:(curr call, curr frame, nil, 
+                fc(res frame).environment, last ep, nil, cut level); 
+              curr frame:= res frame; 
+              FOR ts FROM fp DOWNTO cut level 
+              REP fc(ts).rest:= nil PER; 
+              LEAVE son WITH TRUE 
+   CASE bye:  IF   curr call.arity = 0 
+              THEN push (""13""); 
+                   finish:= TRUE 
+              FI 
+   CASE list: IF   curr call.arity = 0 COR curr call.arity = 1 
+              THEN found:= TRUE; 
+                   IF   curr call.arity = 0 
+                   THEN pattern:= cut 
+                   ELSE value (argfirst, t, curr frame); 
+                        pattern:= t.symbol 
+                   FI; 
+                   write knowledgebase (knowledge base) 
+              FI 
+   CASE call: undo bindings (last ep); 
+              new tp (ts); 
+              replace(tcrest,ts, fc(curr frame).subgoals); 
+              fc(curr frame).subgoals:= ts; 
+              value (argfirst, t, curr frame); 
+              t.arguments:= revers (t.arguments); 
+              replace(tcsymbol,ts, t.symbol); 
+              replace(tcarguments,ts, t.arguments); 
+              replace(tcarity,ts, t.arity); 
+              LEAVE son WITH TRUE 
+   CASE xpar: {X parameter of call} 
+   CASE writ: IF   curr call.arity = 1 
+              THEN value (argfirst, t, curr frame); 
+                   quoting:= FALSE; 
+                   write term backward (t); write (" "); 
+                   quoting:= TRUE 
+              FI 
+   CASE wriq: IF   curr call.arity = 1 
+              THEN value (argfirst, t, curr frame); 
+                   write term backward (t); write (" ") 
+              FI 
+   CASE read: IF   curr call.arity <> 1 
+              THEN 
+              ELIF argfirst.arity = var 
+              THEN initiate read terms (ts, 
+                      name (symboltable,argfirst.symbol)); 
+                   read term (t); 
+                   nc(fc(curr frame).environment).first.substitute:= t 
+              ELSE syntax error ("read parameter must be variable") 
+              FI 
+   CASE get0, get: 
+              IF   curr call.arity <> 1 
+              THEN 
+              ELIF argfirst.arity = var 
+              THEN getchar (command); 
+                   WHILE curr call.symbol = get 
+                   CAND code(command) < 32 
+                   REP getchar (command) PER; 
+                   t.arity:= integer; 
+                   t.arguments:= nil; 
+                   t.symbol:= code (command); 
+                   nc(fc(curr frame).environment).first.substitute:= t 
+              ELSE syntax error ("get parameter must be variable") 
+              FI 
+   CASE put0: value (argfirst, t, curr frame); 
+              IF   curr call.arity = 1 CAND t.arity = integer 
+              THEN write (code (t.symbol)) 
+              FI 
+   CASE incr: IF   curr call.arity = 1 
+              THEN 
+                   value(argfirst, t, curr frame); 
+                   t.symbol INCR 1; 
+                   IF   t.arity = integer 
+                  CAND argfirst.arity = var 
+                   THEN k:= fc(curr frame).environment; 
+                        nc(k).first.substitute:= t; 
+                   ELSE syntax error ("integer variable expected") 
+              FI   FI 
+   CASE ass:  IF   curr call.arity = 1 
+              THEN value (argfirst,t,currframe); 
+                   IF   t.symbol = nil 
+                   CAND t.arguments > nil 
+                   THEN assertz (t.arguments); 
+                        IF   free of errors 
+                        THEN reset tp:= tp; 
+                             reset kp:= kp; 
+                             reset symboltable:= symboltable 
+                        FI 
+                   ELSE syntax error ("parameter must be a list") 
+              FI   FI 
+   CASE assa: IF   curr call.arity = 1 
+              THEN value (argfirst,t,currframe); 
+                   IF   t.symbol = nil 
+                   CAND t.arguments > nil 
+                   THEN asserta (t.arguments); 
+                        IF   free of errors 
+                        THEN reset tp:= tp; 
+                             reset kp:= kp; 
+                             reset symboltable:= symboltable 
+                        FI 
+                   ELSE syntax error ("parameter must be a list") 
+              FI   FI 
+   CASE retr: IF   curr call.arity = 1 
+              THEN value (argfirst,t,currframe); 
+                   IF   t.symbol = nil 
+                   CAND t.arguments > nil 
+                   THEN i:= rule count; 
+                        retract (t.arguments); 
+                        IF   i <> rule count 
+                        THEN remove curr call from candidates 
+                        FI 
+                   ELSE syntax error ("parameter must be a list") 
+              FI   FI 
+   CASE vari: IF   curr call.arity = 1 
+              THEN value (argfirst, t, curr frame); 
+                   IF   t.arity <> var 
+                   THEN remove curr call from candidates 
+                   FI 
+              FI 
+   CASE is:   IF   curr call.arity = 2 
+              THEN disable stop; 
+                   t.symbol:= arith (TERM:(tcsymbolISUBargrest, 
+                                           tcargumentsISUBargrest, 
+                                           tcarityISUBargrest), 
+                                     curr frame); 
+                   IF is error THEN put error; clear error FI; 
+                   enable stop; 
+                   t.arity := integer; 
+                   t.arguments:= nil; 
+                   IF   unify (argfirst, curr frame, t, curr frame) 
+                   THEN LEAVE apply rule 
+              FI   FI; 
+              remove curr call from candidates 
+   CASE ypar: {Y parameter of is} 
+   CASE dif:  IF   curr call.arity = 2 CAND 
+              unify (argfirst, 
+                     curr frame, 
+                     TERM:(tcsymbolISUBargrest, 
+                           tcargumentsISUBargrest, 
+                           tcarityISUBargrest), 
+                     curr frame) 
+              THEN remove curr call from candidates 
+              FI 
+   CASE leq:  IF   curr call.arity = 2 
+              THEN get operands; 
+                   IF   t.arity = integer 
+                   THEN IF   t.symbol <= t2.symbol 
+                        THEN LEAVE apply rule 
+                        FI 
+                   ELIF name (symboltable,  t.symbol)  <= 
+                        name (symboltable, t2.symbol) 
+                   THEN LEAVE apply rule 
+              FI   FI; 
+              remove curr call from candidates 
+   CASE eq:   IF   curr call.arity = 2 
+              THEN get operands; 
+                   IF   NOT ( t = t2 ) 
+                   THEN remove curr call from candidates 
+              FI   FI 
+   CASE univ: IF   curr call.arity = 2 
+              CAND np > fsc(fsp).last np 
+              THEN 
+                   get operands; 
+                   IF   t2.arity = var CAND t.arity >= 0 
+                   THEN new tp (ts); 
+                        replace (tcsymbol,ts,t.symbol); 
+                        replace (tcarguments, ts, nil); 
+                        replace (tcarity,ts,0); 
+                        replace (tcrest,ts,revers(t.arguments)); 
+                        nc(np).first.substitute.arguments:= ts; 
+                        nc(np).first.substitute.symbol:= nil; 
+                        nc(np).first.substitute.arity:= t.arity + 1 
+                   ELIF t.arity = var CAND t2.arity > 0 
+                   CAND t2.symbol <= cons 
+                   THEN np DECR 1; 
+                        t2. arguments:= revers(t2.arguments); 
+                        nc(np).first.substitute.symbol:= 
+                          tcsymbol ISUB t2.arguments; 
+                        nc(np).first.substitute.arguments:= 
+                          tcrest ISUB t2.arguments; 
+                        nc(np).first.substitute.arity:= t2.arity - 1; 
+                        np INCR 1 
+                   ELSE syntax error ("wrong parameter after =..") 
+              FI   FI 
+   CASE clau: get operands; 
+              IF   curr call.arity = 2 
+              THEN 
+                   IF   t.arity < 0 
+                   THEN syntax error ("clause with wrong parameter") 
+                   ELSE find clause; 
+                        k:= tcrest ISUB (kcfirstISUBk); 
+                        t3.symbol:= nil; 
+                        t3.arguments:= k; 
+                        t3.arity:= no of terms (k); 
+                        IF   NOT unify (t2, res frame, 
+                                        t3, curr frame) 
+                        THEN remove curr call from candidates 
+                        FI 
+                   FI 
+              FI 
+   CASE claupar: { anonymous parameter of clause } 
+   CASE nam:  IF   curr call.arity = 2 
+              THEN get operands; 
+                   IF   t.arity = var 
+                   CAND t2.symbol = nil 
+                   THEN command:= ""; 
+                        k:= t2.arguments; 
+                        REP command:= code (tcsymbolISUBk) + command; 
+                            k:= tcrestISUBk 
+                        UNTIL k <= nil PER; 
+                        t.symbol:= link (symboltable, command); 
+                        IF   t.symbol = 0 
+                        THEN insert (symboltable, command, t.symbol); 
+                        FI; 
+                        t.arity:= 0; 
+                        t.arguments:= nil; 
+                        nc(fc(curr frame).environment).first.substitute:= t 
+                   ELIF t2.arity = var 
+                   CAND t.arity = 0 
+                   THEN command:= name (symboltable, t.symbol); 
+                        ts:= nil; 
+                        FOR k FROM 1 UPTO length(command) 
+                        REP new tp (i); 
+                            IF   ts = nil 
+                            THEN ts:= i 
+                            ELSE replace (tcrest, j, i) 
+                            FI; 
+                            j:= i; 
+                            replace (tcrest, i, nil); 
+                            replace (tcarity, i, integer); 
+                            replace (tcarguments, i, nil); 
+                            replace (tcsymbol, i, code (command SUB k)) 
+                        PER; 
+                        t3.arity:= length(command); 
+                        t3.arguments:= ts; 
+                        t3.symbol:= nil; 
+                        IF unify (t2, res frame, t3, curr frame) THEN FI 
+                   ELSE syntax error ("name insufficient parameters") 
+              FI   FI 
+   CASE argi: get operands; 
+              IF   curr call.arity = 3 
+              THEN k:= argrest; 
+                   value (TERM:(tcsymbolISUB(tcrestISUB(k)), 
+                                tcargumentsISUB(tcrestISUB(k)), 
+                                tcarityISUB(tcrestISUB(k))), 
+                          t3, 
+                          curr frame); 
+                   IF   t.arity <> integer COR t2.arity <= 0 
+                   COR  t.symbol <= 0 COR t.symbol > t2.arity 
+                   THEN syntax error ("arg with wrong parameter") 
+                   ELSE 
+                        FOR k FROM t2.arity DOWNTO ( t.symbol + 1) 
+                        REP  IF   t2.arguments <= nil 
+                             THEN syntax error ("out of range"); 
+                                  LEAVE apply rule 
+                             FI; 
+                             t2.arguments:= tcrestISUB(t2.arguments) 
+                        PER; 
+                        IF   t3.arity = var 
+                        THEN nc(fc(curr frame).environment).first.substitute 
+                             := TERM:(tcsymbolISUBt2.arguments, 
+                                      tcargumentsISUBt2.arguments, 
+                                      tcarityISUBt2.arguments) 
+                        ELIF NOT unify (TERM:(tcsymbolISUBt2.arguments, 
+                                              tcargumentsISUBt2.arguments, 
+                                              tcarityISUBt2.arguments), 
+                                        curr frame, 
+                                        t3, 
+                                        curr frame) 
+                        THEN remove curr call from candidates 
+                        FI 
+                   FI 
+              FI 
+   CASE zpar: {z parameter of arg} 
+   CASE func: IF   curr call.arity = 3 
+              THEN 
+                   get operands; 
+                   k:= argrest; 
+                   value (TERM:(tcsymbolISUB(tcrestISUB(k)), 
+                                tcargumentsISUB(tcrestISUB(k)), 
+                                tcarityISUB(tcrestISUB(k))), 
+                          t3, 
+                          curr frame); 
+                   IF   t2.arity = var 
+                   THEN IF   t3.arity = var 
+                        THEN 
+                             t2.symbol:= argfirst.symbol; 
+                             t2.arity := 0; 
+                             nc(nc(fc(curr frame).environment).rest).first. 
+                               substitute:= t2; 
+                             k:= tcrestISUB(k); 
+                             t3.symbol:= argfirst.arity; 
+                             t3.arity := integer; 
+                             nc(fc(curr frame).environment).first. 
+                               substitute:= t3 
+                        ELIF t3.arity = integer 
+                        CAND t.arity = t3.symbol 
+                        THEN t.arity:= 0; 
+                             t.arguments:= nil; 
+                             nc(fc(curr frame).environment).first. 
+                               substitute:= t 
+                        ELSE remove curr call from candidates 
+                        FI 
+                   ELIF ( t.arity = var)  
+                   CAND (t2.arity = 0) 
+                   CAND (t3.arity = integer) 
+                   THEN  t2.arity:= t3.symbol; 
+                        FOR k FROM 1 UPTO t3.symbol 
+                        REP new tp (ts); 
+                            replace (tcarity, ts, var); 
+                            anonym value DECR 1; 
+                            replace (tcsymbol, ts, anonym value); 
+                            replace (tcarguments, ts, nil); 
+                            replace (tcrest, ts, t2.arguments); 
+                            t2.arguments:= ts 
+                        PER; 
+                        nc(fc(curr frame).environment).first. 
+                          substitute:= t2 
+                   ELIF t2.arity <= 0 
+                   THEN IF   t.symbol = t2.symbol 
+                        THEN IF   t.arity  = t3.symbol 
+                             CAND t3.arity = integer 
+                             THEN 
+                             ELIF t3.arity = var 
+                             THEN t3.arity := integer; 
+                                  t3.symbol:= t.arity; 
+                                  nc(fc(curr frame).environment).first. 
+                                    substitute:= t3 
+                             ELSE remove curr call from candidates 
+                             FI 
+                        ELSE remove curr call from candidates 
+                        FI 
+                   ELSE syntax error ("wrong functor parameters") 
+              FI   FI 
+   CASE elan: disable stop; 
+              lernsequenz auf taste legen ("q","break"13""); 
+              SELECT 
+              pos("consult,reconsult,sysout,sysin,forget,trace,line,abolish," 
+                  ,name (symboltable, argfirst.symbol) + ",") OF 
+              CASE 01: consult (arg1) 
+              CASE 09: reconsult (arg1) 
+              CASE 19: sysout (arg1) 
+              CASE 26: sysin (arg1) 
+              CASE 32: forget (arg1, quiet) 
+              CASE 39: trace (arg1) 
+              CASE 45: line 
+              CASE 50: value (TERM:(tcsymbolISUBargrest, 
+                                    tcargumentsISUBargrest, 
+                                    tcarityISUBargrest), 
+                                    t, 
+                                    curr frame); 
+                       abolish (t.symbol) 
+              OTHERWISE do (elan command) 
+              ENDSELECT; 
+              lernsequenz auf taste legen ("q","bye"13""); 
+              IF is error THEN put error; clear error FI; 
+              enable stop 
+   END SELECT. 
+ 
+ get operands: 
+   value (argfirst, t, curr frame); 
+   value (TERM:(tcsymbolISUBargrest, 
+                tcargumentsISUBargrest, 
+                tcarityISUBargrest), 
+          t2, 
+          curr frame). 
+ 
+ argfirst:TERM:(tcsymbolISUBcurr call.arguments, 
+                tcargumentsISUBcurr call.arguments, 
+                tcarityISUBcurr call.arguments). 
+ 
+ argrest:       tcrestISUBcurr call.arguments. 
+ 
+ arg1: value (TERM:(tcsymbolISUBargrest, 
+                    tcargumentsISUBargrest, 
+                    tcarityISUBargrest), 
+              t, 
+              curr frame); 
+       name(symboltable, t.symbol). 
+ 
+find clause: 
+   k:= knowledgebase; 
+   WHILE k <> nil 
+   REP 
+       ts:= kcfirstISUBk; 
+       IF   TERM:(tcsymbolISUBts,tcargumentsISUBts,tcarityISUBts) = t 
+       THEN LEAVE find clause 
+       FI; 
+       k:= kcrestISUBk 
+   PER; 
+   remove curr call from candidates; 
+   LEAVE apply rule. 
+ 
+ elan command: 
+   command:= ""; 
+   ts:= curr call.arguments; 
+   WHILE ts <> nil 
+   REP value (TERM:(tcsymbolISUBts, 
+                    tcargumentsISUBts, 
+                    tcarityISUBts), 
+              t, 
+              curr frame); 
+       command CAT name (symboltable, t.symbol); 
+       found:= ts = curr call.arguments; 
+       ts:= tcrestISUB(ts); 
+       IF   found 
+       THEN IF ts > nil THEN command CAT "(""" FI 
+       ELIF ts = nil 
+       THEN command CAT """)" 
+       ELSE command CAT """,""" 
+       FI 
+   PER; 
+   command. 
+ 
+ trace unification results: 
+   inference level INCR 1; 
+   write term (curr call); write ("="); 
+   value (TERM:(tcsymbolISUB(kcfirstISUB(candidates)) , 
+                tcargumentsISUB(kcfirstISUB(candidates)) , 
+                tcarityISUB(kcfirstISUB(candidates)) ), t, res frame); 
+   write term backward (t); 
+   IF   testing 
+   THEN ts:= ep; 
+        IF ts > last ep THEN write (" with ") FI; 
+        list expressions 
+   FI; 
+   line. 
+ 
+ list expressions: 
+   WHILE ts > last ep 
+   REP  k:= fc(ec(ts).index).environment; 
+        WHILE nc(k).first.variable.symbol <> ec(ts).term.symbol 
+        REP k:= nc(k).rest PER; 
+        write term (ec(ts).term); write ("="); 
+        write term (nc(k).first.substitute); write (" "); 
+        ts DECR 1 
+   PER. 
+ 
+ENDPROC prove; 
+  
+BOOL PROC unify (TERM CONST t1, FRAME CONST f1, 
+                 TERM CONST t2, FRAME CONST f2): 
+ 
+   { Unifies the expressions <t1,f1^.environment> and <t2,f2^.environment>, 
+     If unification succeeds, both environments are updated. } 
+ 
+{}{inference count INCR 1;} 
+   IF   f1 = f2 CAND t1 = t2 
+   THEN TRUE 
+   ELIF t1.arity = var 
+   THEN TERM  VAR t; 
+        FRAME VAR f; 
+        IF   bound (t1, f1, t,  f) 
+        THEN unify (t,  f,  t2, f2) 
+     {  ELIF occurs (t1, f1, t2, f2) THEN FALSE } 
+        ELSE bind expression 1; 
+             push expression 1; 
+             TRUE 
+        FI 
+   ELIF t2.arity = var 
+   THEN IF   bound (t2, f2, t,  f) 
+        THEN unify (t,  f,  t1, f1) 
+     {  ELIF occurs (t2, f2, t1, f1) THEN FALSE } 
+        ELSE bind expression 2; 
+             push expression 2; 
+             TRUE 
+        FI 
+   ELIF t1.symbol = t2.symbol 
+   CAND t1.arity  = t2.arity 
+   THEN constant or compound term 
+   ELIF t1.symbol = cons CAND t2.symbol = nil 
+   CAND t1.arity  = 2    CAND t2.arguments > nil 
+   CAND unify (TERM:(tcsymbolISUBt1.arguments, 
+                     tcargumentsISUBt1.arguments, 
+                     tcarityISUBt1.arguments), 
+               f1, 
+               TERM:(tcsymbolISUBt2.arguments, 
+               tcargumentsISUBt2.arguments, 
+               tcarityISUBt2.arguments), 
+               f2) 
+   THEN construct list 1 
+   ELIF t2.symbol = cons CAND t1.symbol = nil 
+   CAND t2.arity  = 2    CAND t1.arguments > nil 
+   CAND unify (TERM:(tcsymbolISUBt2.arguments, 
+                     tcargumentsISUBt2.arguments, 
+                     tcarityISUBt2.arguments), 
+               f2, 
+               TERM:(tcsymbolISUBt1.arguments, 
+                     tcargumentsISUBt1.arguments, 
+                     tcarityISUBt1.arguments), 
+               f1) 
+   THEN construct list 2 
+   ELSE FALSE 
+   FI. 
+ 
+constant or compound term: 
+   { arguments of t1 and t2 are properly instantiated by the parser } 
+   EXPRESSIONS VAR last ep:= ep; 
+   TERMS VAR x:= t1.arguments, y:= t2.arguments; 
+   WHILE x <> nil 
+   REP IF   unify (TERM:(tcsymbolISUBx, tcargumentsISUBx, tcarityISUBx), 
+                   f1, 
+                   TERM:(tcsymbolISUBy, tcargumentsISUBy, tcarityISUBy), 
+                   f2) 
+       THEN x:= tcrestISUB(x); 
+            y:= tcrestISUB(y) 
+       ELSE undo bindings (last ep); 
+            LEAVE unify WITH FALSE 
+       FI 
+   PER; 
+   TRUE. 
+ 
+ construct list 1: 
+   last ep:= ep; 
+   IF   t2.symbol = cons 
+   THEN TERM VAR tail:= TERM:(tcsymbolISUB(tcrestISUB(t2.arguments)), 
+                              tcargumentsISUB(tcrestISUB(t2.arguments)), 
+                              tcarityISUB(tcrestISUB(t2.arguments))); 
+   ELSE tail:= TERM: (nil, (tcrestISUB(t2.arguments)) , 
+                      no of terms (t2.arguments) - 1); 
+   FI; 
+   IF   bound (TERM:(tcsymbolISUB(tcrestISUB(t1.arguments)) , 
+                     tcargumentsISUB(tcrestISUB(t1.arguments)) , 
+                     tcarityISUB(tcrestISUB(t1.arguments)) ), 
+               f1, 
+               t, 
+               f) 
+   THEN IF   unify (t, f, tail, f2) 
+        THEN TRUE 
+        ELSE undo bindings (last ep); FALSE 
+        FI 
+   ELSE bind tail 1; 
+        push tail 1; 
+        TRUE 
+   FI. 
+ 
+ construct list 2: 
+   last ep:= ep; 
+   IF   t1.symbol = cons 
+   THEN tail:= TERM:(tcsymbolISUB(tcrestISUB(t1.arguments)) , 
+                     tcargumentsISUB(tcrestISUB(t1.arguments)) , 
+                     tcarityISUB(tcrestISUB(t1.arguments)) ); 
+   ELSE tail:= TERM: (nil, tcrestISUB(t1.arguments), 
+                      no of terms (t1.arguments) - 1); 
+   FI; 
+   IF   bound (TERM:(tcsymbolISUB(tcrestISUB(t2.arguments)) , 
+                     tcargumentsISUB(tcrestISUB(t2.arguments)) , 
+                     tcarityISUB(tcrestISUB(t2.arguments)) ), 
+               f2, 
+               t, 
+               f) 
+   THEN IF   unify (t, f, tail, f1) 
+        THEN TRUE 
+        ELSE undo bindings (last ep); FALSE 
+        FI 
+   ELSE bind tail 2; 
+        push tail 2; 
+        TRUE 
+   FI. 
+  
+ bind expression 1: 
+   { bind the expression <t1, f1> to <t2, f2> in the environment <f1> } 
+   new environment n; 
+   nc(n).first:= SUBSTITUTION:(t1, t2, f2); 
+   nc(n).rest :=fc(f1).environment; 
+   fc(f1).environment:= n. 
+ 
+ bind expression 2: 
+   new environment n; 
+   nc(n).first:= SUBSTITUTION:(t2, t1, f1); 
+   nc(n).rest :=fc(f2).environment; 
+   fc(f2).environment:= n. 
+ 
+ bind tail 1: 
+   new environment n; 
+   nc(n).first:= SUBSTITUTION:( 
+                    TERM:(tcsymbolISUB(tcrestISUB(t1.arguments)), 
+                          tcargumentsISUB(tcrestISUB(t1.arguments)) , 
+                          tcarityISUB(tcrestISUB(t1.arguments)) ), 
+                    tail, 
+                    f2); 
+   nc(n).rest :=fc(f1).environment; 
+   fc(f1).environment:= n. 
+ 
+ bind tail 2: 
+   new environment n; 
+   nc(n).first:= SUBSTITUTION:( 
+                    TERM:(tcsymbolISUB(tcrestISUB(t2.arguments)) , 
+                    tcargumentsISUB(tcrestISUB(t2.arguments)) , 
+                    tcarityISUB(tcrestISUB(t2.arguments)) ), 
+                    tail, 
+                    f1); 
+   nc(n).rest :=fc(f2).environment; 
+   fc(f2).environment:= n. 
+ 
+ push expression 1: 
+   ep INCR 1; 
+   ec(ep):= EXPRESSION:(t1, f1). 
+ 
+ push expression 2: 
+   ep INCR 1; 
+   ec(ep):= EXPRESSION:(t2, f2). 
+ 
+ push tail 1: 
+   ep INCR 1; 
+   ec(ep):= EXPRESSION:(TERM:(tcsymbolISUB(tcrestISUB(t1.arguments)) , 
+                              tcargumentsISUB(tcrestISUB(t1.arguments)) , 
+                              tcarityISUB(tcrestISUB(t1.arguments)) ), 
+                        f1). 
+ 
+ push tail 2: 
+   ep INCR 1; 
+   ec(ep):= EXPRESSION:(TERM:(tcsymbolISUB(tcrestISUB(t2.arguments)) , 
+                              tcargumentsISUB(tcrestISUB(t2.arguments)) , 
+                              tcarityISUB(tcrestISUB(t2.arguments)) ), 
+                        f2). 
+ 
+ new environment n: 
+   ENVIRONMENT VAR n; 
+   IF np = limit THEN pegeloverflow ELSE np INCR 1; n:= np FI 
+ENDPROC unify; 
+ 
+BOOL OP = (TERM CONST t1, t2): { INLINE; } 
+   { Two terms are equal iff their printed representations are 
+     indistinguishable. Don't confuse with equal expressions. } 
+ 
+   IF   ( t1.symbol = t2.symbol ) 
+   CAND ( t1.arity  = t2.arity  ) 
+   THEN IF   t1.arguments = 0 
+        THEN terms are variables or constants 
+        ELSE terms are compound 
+        FI 
+   ELSE FALSE 
+   FI. 
+ 
+ terms are variables or constants: TRUE. 
+ 
+ terms are compound: 
+   TERMS VAR x:= t1.arguments, 
+             y:= t2.arguments; 
+   WHILE x <> nil 
+   REP   IF   recursive equal (TERM:(tcsymbolISUBx, 
+                                     tcargumentsISUBx, 
+                                     tcarityISUBx), 
+                               TERM:(tcsymbolISUBy, 
+                                     tcargumentsISUBy, 
+                                     tcarityISUBy)) 
+         THEN x:= tcrestISUB(x); 
+              y:= tcrestISUB(y) 
+         ELSE LEAVE = WITH FALSE 
+         FI 
+   PER;  TRUE. 
+ENDOP =; 
+ 
+BOOL PROC recursive equal (TERM CONST t1, t2): t1=t2 
+ENDPROC recursive equal; 
+  
+PROC undo bindings (EXPRESSIONS CONST last ep): 
+   { Remove the binding for each of the expressions } 
+   WHILE ep > last ep 
+   REP remove matching substitutions; 
+       remove expression 
+   PER. 
+ 
+ remove matching substitutions: 
+   { with variable equal to term t from environment env } 
+   TERM VAR t:= ec(ep).term; 
+   ENVIRONMENT VAR n:= env, last:= nil; 
+   WHILE n <> nil 
+   REP IF   nc(n).first.variable.symbol = t.symbol 
+       THEN forget n 
+       ELSE last:= n 
+       FI; 
+       n:= nc(n).rest 
+   PER. 
+ 
+ forget n: 
+   IF   last = nil 
+   THEN env := nc(n).rest 
+   ELSE nc(last).rest:= nc(n).rest 
+   FI; 
+   IF n = np THEN np DECR 1 FI. 
+ 
+ env: fc(ec(ep).index).environment.  
+ 
+ remove expression: 
+   { Removes the first expression from e recovering the space used } 
+   ep DECR 1. 
+ 
+END PROC undo bindings; 
+ 
+PROC consult (TEXT CONST knowledge): 
+   { asserts the clauses from the file into knowledge base } 
+{} enable stop; 
+   IF   NOT exists (knowledge) 
+   THEN syntax error ("consulting file not existing"); LEAVE consult 
+   FI; 
+   last param (knowledge); 
+   TERMS VAR clauses; 
+   BOOL VAR single:= TRUE; 
+   rule count:= 0; 
+   initiate read terms (knowledge, clauses); 
+   WHILE look ahead <> end of input 
+   REP rule count INCR 1; 
+       cout (rule count); 
+       read clause; 
+       assertz (clauses); 
+       clauses:= nil 
+   PER; 
+   remove token; 
+   IF   anything noted 
+   THEN modify (file); 
+        note edit (file) 
+   FI; 
+   IF   free of errors 
+   THEN reset tp:= tp; 
+        reset kp:= kp; 
+        reset symboltable:= symboltable; 
+        put (rule count) 
+   ELSE put (0); from file:= FALSE 
+   FI; 
+   putline ("rules inserted."); 
+   line . 
+ 
+ read clause: 
+   TERM VAR term; 
+   IF   single 
+   THEN read term (term); 
+        IF   term.arity = var 
+        THEN syntax error ("clause starts with variable") 
+        ELIF name (symboltable, term.symbol) = ":-" 
+        THEN read terms (clauses); 
+             call terms (clauses); 
+             LEAVE consult 
+        FI; 
+        IF   look ahead = colon 
+        THEN remove token; 
+             read terms (clauses) 
+        FI 
+   ELIF look ahead = semicolon 
+   THEN remove token; 
+        read terms (clauses) 
+   FI; 
+   IF   look ahead = semicolon 
+   THEN single:= FALSE 
+   ELIF look ahead = period 
+   THEN single:= TRUE; 
+        remove token 
+   ELSE syntax error ("period or semicolon expected") 
+   FI; 
+   insert term in clauses. 
+ 
+ insert term in clauses: 
+   TERMS VAR tmp; 
+   new tp (tmp); 
+   replace(tcsymbol,tmp,term.symbol); 
+   replace(tcarguments,tmp,term.arguments); 
+   replace(tcarity,tmp,term.arity); 
+   replace(tcrest,tmp, clauses); 
+   clauses:= tmp. 
+ 
+ remove token: 
+   look ahead empty:= TRUE. 
+ 
+END PROC consult; 
+ 
+PROC reconsult (TEXT CONST knowledge): 
+   { asserts the clauses from the file into knowledge base } 
+{} enable stop; 
+   IF   NOT exists (knowledge) 
+   THEN syntax error ("reconsulting file not existing"); LEAVE reconsult 
+   FI; 
+   last param (knowledge); 
+   TERMS VAR clauses; 
+   BOOL VAR single:= TRUE; 
+   rule count:= 0; 
+   initiate read terms (knowledge, clauses); 
+   WHILE look ahead <> end of input 
+   REP rule count INCR 1; 
+       cout (rule count); 
+       read clause; 
+       abolish (tcsymbol ISUB clauses); 
+       clauses:= nil 
+   PER; 
+   remove token; 
+   consult (knowledge). 
+ 
+ read clause: 
+   TERM VAR term; 
+   IF   single 
+   THEN read term (term); 
+        IF   term.arity = var 
+        THEN syntax error ("clause starts with variable") 
+        ELIF name (symboltable, term.symbol) = ":-" 
+        THEN read terms (clauses); 
+             call terms (clauses); 
+             LEAVE reconsult 
+        FI; 
+        IF   look ahead = colon 
+        THEN remove token; 
+             read terms (clauses) 
+        FI 
+   ELIF look ahead = semicolon 
+   THEN remove token; 
+        read terms (clauses) 
+   FI; 
+   IF   look ahead = semicolon 
+   THEN single:= FALSE 
+   ELIF look ahead = period 
+   THEN single:= TRUE; 
+        remove token 
+   ELSE syntax error ("period or semicolon expected") 
+   FI; 
+   insert term in clauses. 
+ 
+ insert term in clauses: 
+   TERMS VAR tmp; 
+   new tp (tmp); 
+   replace(tcsymbol,tmp,term.symbol); 
+   replace(tcarguments,tmp,term.arguments); 
+   replace(tcarity,tmp,term.arity); 
+   replace(tcrest,tmp, clauses); 
+   clauses:= tmp. 
+ 
+ remove token: 
+   look ahead empty:= TRUE. 
+ 
+END PROC reconsult; 
+ 
+PROC assertz (TERMS CONST clause): 
+   { Inserts the clause into the knowledge base before the first clause 
+     beginning with the same functor. 
+     Clauses beginning with the same functor are assumed to be listed 
+     consecutively. 
+   } 
+   CLAUSES VAR c1, c2, c3; 
+   IF   free of errors 
+   THEN IF   freep > nil 
+        THEN c3:= freec(freep); 
+             freep DECR 1; 
+             IF reset freep > freep THEN reset freep:= freep FI 
+        ELSE new kp (c3) 
+        FI; 
+        replace(kcfirst,c3, clause); 
+        IF   knowledge base = nil 
+        COR  (tcsymbolISUB((kcfirstISUB(knowledgebase)) )) = 
+             (tcsymbolISUB(clause)) 
+        THEN insert on top 
+        ELSE c1:= knowledge base; 
+             REP find and insert clause PER 
+        FI 
+   FI. 
+ 
+ find and insert clause: 
+   c2:= (kcrestISUB(c1)) ; 
+   IF   c2 = nil 
+   THEN insert on top 
+   ELIF (tcsymbolISUB((kcfirstISUB(c2)) )) = (tcsymbolISUB(clause)) 
+   THEN insert before 
+   FI; 
+   c1:= c2. 
+ 
+ insert on top: 
+   replace(kcrest,c3, knowledge base); 
+   knowledge base:= c3; 
+   LEAVE assertz. 
+ 
+ insert before: 
+   replace(kcrest,c3, c2); 
+   replace(kcrest,c1, c3); 
+   LEAVE assertz. 
+ 
+ENDPROC assertz; 
+  
+PROC asserta (TERMS CONST clause): 
+   { Inserts the clause into the knowledge base after the last clause 
+     beginning with the same functor. 
+     Clauses beginning with the same functor are assumed to be listed 
+     consecutively. 
+   } 
+   CLAUSES VAR c1, c2, c3; 
+   IF   free of errors 
+   THEN IF   freep > nil 
+        THEN c3:= freec(freep); 
+             freep DECR 1; 
+             IF reset freep > freep THEN reset freep:= freep FI 
+        ELSE new kp (c3) 
+        FI; 
+        replace(kcfirst,c3, clause); 
+        IF   knowledge base = nil 
+        THEN replace(kcrest,c3, knowledge base); 
+             knowledge base:= c3 
+        ELSE c1:= knowledge base; 
+             REP find and insert clause PER 
+        FI 
+   FI. 
+ 
+ find and insert clause: 
+   c2:= (kcrestISUB(c1)) ; 
+   IF   c2 = nil 
+   THEN append after c1 
+   ELIF (tcsymbolISUB((kcfirstISUB(c2)) )) = (tcsymbolISUB(clause)) 
+   THEN insert behind 
+   FI; 
+   c1:= c2. 
+ 
+ append after c1: 
+   replace(kcrest,c1, clause); 
+   LEAVE asserta. 
+ 
+ insert behind: 
+   REP  c1:= c2; 
+        c2:= (kcrestISUB(c1)) ; 
+   UNTIL (tcsymbolISUB((kcfirstISUB(c2)) )) <> (tcsymbolISUB(clause)) 
+   PER; 
+   replace(kcrest,c3, c2); 
+   replace(kcrest,c1, c3); 
+   LEAVE asserta. 
+ 
+ENDPROC asserta; 
+  
+PROC retract (TERMS CONST clause): 
+   { Retracts the clause from the knowledge base. } 
+   CLAUSES VAR c1:= knowledge base, c2; 
+   IF   free of errors 
+   THEN IF   c1 = nil 
+        THEN rule count DECR 1 
+        ELIF c1 > build ins CAND terms eq ((kcfirstISUB(c1)) , clause) 
+        THEN retract top 
+        ELSE REP find and retract clause PER 
+        FI 
+   FI. 
+ 
+ find and retract clause: 
+   c2:= (kcrestISUB(c1)) ; 
+   IF   c2 = nil 
+   THEN rule count DECR 1; 
+        LEAVE retract 
+   ELIF c2 > build ins CAND terms eq ((kcfirstISUB(c2)) , clause)  
+   THEN retract c2 
+   FI; 
+   c1:= c2. 
+ 
+ retract top: 
+   freep INCR 1; 
+   reset freep:= freep; 
+   freec(freep):= knowledge base; 
+   knowledge base:= (kcrestISUB(knowledge base)) ; 
+   LEAVE retract. 
+ 
+ retract c2: 
+   replace(kcrest,c1, (kcrestISUB(c2)) ); 
+   freep INCR 1; 
+   reset freep:= freep; 
+   freec(freep):= c2; 
+   LEAVE retract. 
+ 
+ENDPROC retract; 
+  
+PROC abolish (SYMBOL CONST clause): 
+   { Retracts all the clauses with this name from the knowledge base. } 
+{} enable stop; 
+   CLAUSES VAR c1:= knowledge base, c2; 
+   IF   free of errors 
+   THEN REP 
+          IF   c1 = nil 
+          THEN rule count DECR 1; 
+               LEAVE abolish 
+          ELIF c1 = knowledgebase CAND c1 > build ins 
+          CAND (tcsymbol ISUB(kcfirstISUBc1)) = clause 
+          THEN retract top; 
+               c1:= knowledgebase 
+          ELSE find and retract clause 
+          FI 
+        PER 
+   FI. 
+ 
+ find and retract clause: 
+   c2:= kcrestISUBc1 ; 
+   IF   c2 = nil 
+   THEN rule count DECR 1; 
+        LEAVE abolish 
+   ELIF c2 > build ins 
+   CAND (tcsymbol ISUB(kcfirstISUBc2)) = clause  
+   THEN retract c2 
+   ELSE c1:= c2 
+   FI. 
+ 
+ retract top: 
+   freep INCR 1; 
+   reset freep:= freep; 
+   freec(freep):= knowledge base; 
+   knowledge base:= (kcrestISUB(knowledge base)). 
+ 
+ retract c2: 
+   replace(kcrest,c1, (kcrestISUB(c2)) ); 
+   freep INCR 1; 
+   reset freep:= freep; 
+   freec(freep):= c2. 
+ 
+ENDPROC abolish; 
+  
+BOOL PROC terms eq (TERMS CONST a, b): 
+   IF   a = b 
+   THEN TRUE 
+   ELIF a = 0 COR b = 0 
+   THEN FALSE 
+   ELIF TERM:(tcsymbolISUBa, 
+              tcargumentsISUBa, 
+              tcarityISUBa) = 
+        TERM:(tcsymbolISUBb, 
+              tcargumentsISUBb, 
+              tcarityISUBb) 
+   THEN terms eq ((tcrestISUB(a)) , (tcrestISUB(b)) ) 
+   ELSE FALSE 
+   FI 
+ENDPROC terms eq; 
+ 
+PROC value (TERM CONST t, TERM VAR r, FRAME CONST f): 
+   { sets r to the value of t in f^.environment } 
+{} enable stop; 
+   IF   t.arguments = 0 
+   THEN IF   t.arity = var 
+        THEN variable term 
+        ELSE constant term 
+        FI 
+   ELSE compound term 
+   FI. 
+ 
+ constant term: r:= t. 
+ 
+ variable term: 
+   TERM VAR t1, t2; 
+   FRAME VAR f1; 
+   IF   bound (t, f, t1, f1) 
+   THEN value (t1, r, f1) 
+   ELSE r:= t 
+   FI. 
+ 
+ compound term: 
+   INT VAR step:= 3; 
+   TERMS VAR ts:= t.arguments; 
+   r.arguments:= nil; 
+   WHILE ts <> nil 
+   REP  value (TERM:(tcsymbolISUBts, 
+                     tcargumentsISUBts, 
+                     tcarityISUBts), 
+               t1, 
+               f); 
+        IF   stepping 
+        CAND step = 1 CAND t.symbol = cons CAND t1.symbol = nil 
+        THEN step:= 0; 
+             value (t1, t2, f); 
+             ts:= t2.arguments 
+        ELSE ts:= tcrestISUB(ts); 
+             push term in arguments 
+        FI; 
+   PER; 
+   IF   step = 0 
+   THEN r.symbol:= nil 
+   ELSE r.symbol:= t.symbol 
+   FI; 
+   r.arity:= no of terms (r.arguments). 
+ 
+ stepping: 
+   IF step > 1 THEN step DECR 1; TRUE ELSE FALSE FI. 
+ 
+ push term in arguments: 
+   TERMS VAR term; 
+   new tp (term); 
+   replace(tcsymbol,term, t1.symbol); 
+   replace(tcarguments,term, t1.arguments); 
+   replace(tcarity,term, t1.arity); 
+   replace(tcrest,term, r.arguments); 
+   r.arguments:= term. 
+ENDPROC value; 
+ 
+BOOL PROC bound (TERM CONST t1, FRAME CONST f1, 
+                 TERM VAR   t2, FRAME VAR   f2): 
+   { returns TRUE iff the expression <t1, f1^.environment> is bound and 
+     assigns <t2, f2^.environment> the expression to which it is bound. } 
+   ENVIRONMENT VAR n:= fc(f1).environment; 
+   SUBSTITUTION VAR sub; 
+   WHILE n <> nil 
+   REP sub:= nc(n).first; 
+       IF   t1.symbol = sub.variable.symbol 
+       THEN t2:= sub.substitute; 
+            f2:= sub.others; 
+            LEAVE bound WITH TRUE 
+       ELSE n:= nc(n).rest 
+       FI 
+   PER; 
+   FALSE 
+ENDPROC bound; 
+  
+PROC append term (TERM CONST appendix, TERMS VAR list): 
+   TERMS VAR term, last term; 
+   IF   list = nil 
+   THEN new tp (term); 
+        list:= term 
+   ELSE term:= list; 
+        REP  last term:= term; 
+             term:= tcrestISUB(term) 
+        UNTILterm = nil PER; 
+        new tp (term); 
+        replace(tcrest,last term, term); 
+   FI; 
+   replace(tcsymbol,term,appendix.symbol); 
+   replace(tcarguments,term,appendix.arguments); 
+   replace(tcarity,term,appendix.arity); 
+   replace(tcrest,term, nil) 
+END PROC append term; 
+ 
+TERMS PROC revers (TERMS CONST ts): 
+   IF   ts <= nil 
+   THEN ts 
+   ELSE TERMS VAR reverted:= revers ((tcrestISUB(ts)) ); 
+        append term (TERM:(tcsymbolISUBts, 
+                           revers (tcargumentsISUBts), 
+                           tcarityISUBts), 
+                     reverted); 
+        reverted 
+   FI 
+ENDPROC revers; 
+ 
+PROC call terms (TERMS VAR ts): 
+  TEXT VAR old:= sysout; 
+  forget ("$sysin$",quiet); 
+  sysout ("$sysin$"); 
+  WHILE ts > nil 
+  REP write term (TERM:(tcsymbolISUBts, 
+                        tcargumentsISUBts, 
+                        tcarityISUBts)); 
+      line; 
+      ts:= tcrestISUB(ts) 
+  PER; 
+  write ("elan(sysin,())."); 
+  sysout (old); 
+  sysin  ("$sysin$") 
+ENDPROC call terms; 
+ 
+PROC write environment list (FRAME CONST frame): 
+   write environment list (frame, fc(frame).environment); 
+ENDPROC write environment list; 
+ 
+PROC write environment list (FRAME CONST frame, ENVIRONMENT CONST en): 
+   IF en <> nil 
+   THEN write environment list (frame, nc(en).rest); 
+        write term (nc(en).first.variable);   write (" = "); 
+        value (nc(en).first.variable, t, frame); 
+        write term backward (t); 
+        IF en <> fc(frame).environment THEN write (", ") FI 
+   FI 
+ENDPROC write environment list; 
+ 
+PROC write knowledge base (CLAUSES CONST k): 
+   TERMS VAR t:= (kcfirstISUB(k)) ; 
+   IF   t > nil CAND k <= reset kp CAND k > build ins 
+   CAND (pattern = cut COR pattern = (tcsymbolISUB(t)) 
+        ) 
+   THEN found:= FALSE; 
+        IF   (kcrestISUB(k))  > nil 
+        THEN write knowledge base ((kcrestISUB(k)) ) 
+        FI; 
+        write term (TERM:(tcsymbolISUBt, tcargumentsISUBt, tcarityISUBt)); 
+        t:= (tcrestISUB(t)) ; 
+        IF   t > nil 
+        THEN write (":- "); 
+             write terms 
+        FI; 
+        write ("."); 
+        line 
+   ELIF (found COR k <= build ins) CAND (kcrestISUB(k))  > nil 
+   THEN write knowledge base ((kcrestISUB(k)) ) 
+   FI. 
+ 
+ write terms: 
+   BOOL VAR once:= FALSE; 
+   WHILE t <> nil 
+   REP  IF once THEN write (", ") ELSE once:= TRUE FI; 
+        write term (TERM:(tcsymbolISUBt, tcargumentsISUBt, tcarityISUBt)); 
+        t:= (tcrestISUB(t)) ; 
+   PER. 
+ENDPROC write knowledge base; 
+ 
+PROC write symbol (TERM CONST t): 
+   TEXT VAR w1, w2:= name (symboltable, t.symbol); 
+   IF   quoting 
+   THEN scan (w2); 
+        next symbol (w1, i); INT VAR i; 
+        IF   w1 = w2 CAND i <> num 
+        THEN write (w2) 
+        ELSE write (""""); write (w2); write ("""") 
+        FI 
+   ELSE write (w2) 
+   FI 
+ENDPROC write symbol; 
+ 
+PROC write term backward (TERM CONST t): 
+   IF   t.arity = integer 
+   THEN write (text (t.symbol)) 
+   ELIF t.symbol <= cons 
+   THEN IF   t.symbol < 0 
+        THEN write ("_"+text(-t.symbol)) 
+        ELSE write ("["); 
+             write subterms backward (t, t.arguments); write ("]") 
+        FI 
+   ELSE 
+        write symbol (t); 
+        IF   t.arguments <> nil 
+        THEN compound term 
+        FI 
+   FI. 
+ 
+ compound term: 
+   write ("("); write subterms backward (t, t.arguments); write (")"). 
+ 
+ENDPROC write term backward;  
+ 
+PROC write subterms backward (TERM CONST t, TERMS CONST ts): 
+   IF   ts = nil 
+   THEN 
+   ELSE write subterms backward (t, (tcrestISUB(ts)) ); 
+        write term backward ( 
+              TERM:(tcsymbolISUBts, tcargumentsISUBts, tcarityISUBts)); 
+        IF   ts <> t.arguments 
+        THEN IF t.symbol = cons THEN write ("|") ELSE write (",") FI 
+        FI 
+   FI 
+ENDPROC write subterms backward; 
+ 
+PROC write term (TERM CONST t): 
+   IF   t.arity = integer 
+   THEN write (text (t.symbol)) 
+   ELIF t.symbol <= cons 
+   THEN IF   t.symbol < 0 
+        THEN write ("_"+text(-t.symbol)) 
+        ELSE write ("["); write terms; write ("]") 
+        FI 
+   ELSE 
+        write symbol (t); 
+        IF   t.arguments <> nil 
+        THEN compound term 
+        FI 
+   FI. 
+ 
+ compound term: 
+   write ("("); write terms; write (")"). 
+ 
+ write terms: 
+   TERMS VAR ts:= t.arguments; 
+   WHILE ts <> nil 
+   REP  write term ( 
+              TERM:(tcsymbolISUBts, tcargumentsISUBts, tcarityISUBts)); 
+        ts:= tcrestISUB(ts); 
+        IF   ts <> nil 
+        THEN IF t.symbol = cons THEN write ("|") ELSE write (",") FI 
+        FI 
+   PER. 
+ 
+ENDPROC write term;  
+ 
+PROC read consult list: 
+   TERM VAR t; 
+   TERMS CONST old tp:= tp; 
+   WHILE filename read REP PER; 
+   IF   look ahead <> close bracket 
+   THEN syntax error ("closing bracket expected") 
+   FI; 
+   remove token; 
+   reset symboltable:= symboltable; 
+   TERMS CONST ts:= tp; 
+   tp:= old tp; 
+   consult list (ts); 
+   from file:= FALSE. 
+ 
+ filename read: 
+   BOOL VAR was minus:= FALSE; 
+   IF   look ahead = minus 
+   THEN remove token; 
+        was minus:= TRUE 
+   FI; 
+   IF   look ahead = identifier 
+   THEN new tp (tp); 
+        read term (t); 
+        replace(tcsymbol,tp, t.symbol); 
+        replace(tcarguments,tp, t.arguments); 
+        replace(tcarity,tp, t.arity); 
+        IF was minus THEN replace(tcarity,tp, var); 
+        FI; 
+        IF   NOT exists (name (symboltable, (tcsymbolISUB(tp)) 
+                        )) 
+        THEN syntax error ("file does not exist"); FALSE 
+        ELIF look ahead = comma THEN remove token; TRUE 
+        ELSE TRUE 
+        FI 
+   ELSE FALSE 
+   FI . 
+ 
+ remove token: 
+   look ahead empty:= TRUE. 
+ENDPROC read consult list; 
+ 
+PROC consult list (TERMS CONST ts): 
+   IF   ts > tp 
+   THEN TERM VAR term:= 
+        TERM:(tcsymbolISUBts, tcargumentsISUBts, tcarityISUBts); 
+        consult list (ts-1); 
+        IF   free of errors 
+        THEN TEXT VAR fname:= name (symboltable, term.symbol); 
+             IF   term.arity = var 
+             THEN put ("reconsulting"); putline (fname); reconsult (fname) 
+             ELSE put (  "consulting"); putline (fname);   consult (fname) 
+             FI 
+        FI 
+   FI 
+ENDPROC consult list; 
+ 
+PROC initiate read terms (TERMS VAR ts, TEXT CONST prompter): 
+   enable stop; 
+   look ahead empty:= TRUE; ahead empty:= TRUE; 
+   from file:= FALSE; 
+   TEXT VAR inputline; 
+   IF   prompter = "-" 
+   THEN inputline:= "" 
+   ELSE inputline:= ""13"" 
+   FI; 
+   REP 
+       WHILE sysin = "" CAND is escape 
+       REP   write (""13""15"gib kommando: "); 
+             get command; 
+             IF   inputline = "" 
+             THEN write (""14""3""3"") 
+             ELSE write (""14""13""10""); 
+                  IF   prompter = "-" 
+                  THEN lernsequenz auf taste legen ("k", inputline); 
+                  FI; 
+                  disable stop; 
+                  lernsequenz auf taste legen ("q","break"13""); 
+                  do (inputline); 
+                  lernsequenz auf taste legen ("q","bye"13""); 
+                  IF   is error 
+                  THEN put (errormessage); clear error 
+                  FI; 
+                  enable stop; 
+             FI; 
+             write (""13""10""5"?"); 
+             write (prompter); 
+             write (" ") 
+       PER; 
+       getline (inputline); 
+       IF   inputline <> "" 
+       CAND (inputline SUB length (inputline)) <> "." 
+       THEN inputline CAT "." 
+       FI; 
+       scan (inputline); 
+       ts:= nil 
+   UNTIL inputline <> "" PER; 
+   IF   prompter = "-" 
+   THEN lernsequenz auf taste legen ("k", inputline) 
+   FI. 
+ 
+ is escape: 
+   REP  IF   inputline = ""13"" 
+        THEN write (""13""10""5"?"); 
+             write (prompter); 
+             write (" ") 
+        ELIF inputline = "?" 
+        THEN putline ("?"); inform; push (""13"") 
+        FI; 
+        getchar (inputline) 
+   UNTIL pos ("?"13"", inputline) = 0 
+   PER; 
+   IF   inputline = ""27"" 
+   THEN getchar (inputline); 
+        IF   inputline = ""27"" 
+        THEN TRUE 
+        ELSE push (inputline); push (""27""); FALSE 
+        FI 
+   ELSE push (inputline); FALSE 
+   FI. 
+ 
+ get command: 
+   getchar (inputline); 
+   IF   inputline = ""27"" 
+   THEN getchar (inputline); 
+        IF   inputline = ""27"" 
+        THEN inputline:= ""; 
+             line 
+        ELSE push (inputline); 
+             push (""27""); 
+             getline (inputline) 
+        FI 
+   ELSE push (inputline); 
+        getline (inputline) 
+   FI. 
+ 
+ENDPROC initiate read terms; 
+ 
+PROC initiate read terms (TEXT CONST knowledge, TERMS VAR ts): 
+   look ahead empty:= TRUE; ahead empty:= TRUE; 
+   file:= sequential file (input, knowledge); 
+   from file:= TRUE; 
+   scan (file); 
+   ts:= nil 
+ENDPROC initiate read terms; 
+ 
+PROC read terms (TERMS VAR ts): 
+   { the actual parameter for ts should be initiated < ts:=nil > 
+     at top level of recursion 
+   } 
+   TERM VAR t; 
+   WHILE look ahead <> close paren CAND look ahead <> close bracket 
+    CAND look ahead <> period 
+   REP  read term (t); 
+        append term (t, ts) 
+   UNTIL end of list PER. 
+ 
+ end of list: 
+   IF   look ahead = comma 
+   THEN remove comma; 
+        FALSE 
+   ELSE TRUE 
+   FI. 
+ 
+ remove comma: look ahead empty:= TRUE. 
+ 
+ENDPROC read terms; 
+  
+PROC read term (TERM VAR t): 
+   IF   look ahead = open paren 
+   THEN remove token; 
+        read term (t); 
+        transform infix to prefix (t, 0); 
+        IF   look ahead = close paren 
+        THEN remove token 
+        ELSE syntax error ("closing parentheses missing") 
+        FI 
+   ELSE read prefix term (t); 
+        transform infix to prefix (t, 0) 
+   FI . 
+ 
+ remove token: look ahead empty:= TRUE . 
+ENDPROC read term; 
+ 
+PROC transform infix to prefix (TERM VAR t, INT CONST last prio): 
+     SELECT look ahead OF 
+     CASE minus, plus, times, slash, less, equal, uneq, grt, eqeq, eqdotdot, 
+          boldvar: 
+          operator:= look ahead value; 
+          IF   last prio <= priority (operator) 
+          THEN 
+               remove token; 
+               IF   look ahead = open paren 
+               THEN read term (t2); 
+               ELSE read prefix term (t2); 
+               FI; 
+               IF   last prio < priority (operator) 
+               THEN transform infix to prefix (t2, priority (operator)); 
+               FI; 
+               form result; 
+               transform infix to prefix (t, last prio) 
+          FI 
+     ENDSELECT. 
+ 
+ form result: 
+     second operand; 
+     first operand; 
+     prefix. 
+ 
+second operand: 
+     TERMS VAR p2; 
+     TERM VAR t2; 
+     new tp (p2); 
+     replace(tcsymbol, p2, t2.symbol); 
+     replace(tcarguments, p2, t2.arguments); 
+     replace(tcarity, p2, t2.arity); 
+     replace(tcrest, p2, nil). 
+ 
+first operand: 
+     TERMS VAR p1; 
+     new tp (p1); 
+     replace(tcsymbol, p1, t.symbol); 
+     replace(tcarguments, p1, t.arguments); 
+     replace(tcarity, p1, t.arity); 
+     replace(tcrest, p1, p2). 
+ 
+prefix: 
+     INT VAR operator; 
+     t.symbol:= operator; 
+     t.arguments:= p1; 
+     t.arity:= 2. 
+ 
+ remove token: 
+   look ahead empty:= TRUE. 
+ 
+ENDPROC transform infix to prefix; 
+ 
+INT PROC priority (INT CONST operator): 
+   SELECT operator OF 
+   CASE times, slash, mod:  7 
+   CASE minus, plus:        6 
+   CASE 9,10,11,12,13:      5 
+   OTHERWISE                2 
+   ENDSELECT 
+ENDPROC priority; 
+ 
+PROC read prefix term (TERM VAR t): 
+   SELECT look ahead OF 
+   CASE exclamation:  term is cut 
+   CASE bold var:     term is a variable 
+   CASE underscore:   term is anonym 
+   CASE number:       term is number 
+   CASE identifier, 
+        minus, plus, times, slash, less, equal, uneq, grt, eqeq, eqdotdot: 
+                      IF   look ahead = minus 
+                      THEN remove token; 
+                           IF   look ahead = number  {monadic minus} 
+                           THEN look ahead value:= - look ahead value; 
+                                term is number; 
+                                LEAVE read prefix term 
+                           FI 
+                      ELSE remove token 
+                      FI; 
+                      term is identifier; 
+                      IF   look ahead = open paren 
+                      THEN term is compound 
+                    { ELSE term is a constant } 
+                      FI 
+   CASE open bracket: term is list 
+   CASE colon:        term is colon 
+   OTHERWISE          syntax error ("wrong expression"); 
+                      t:= TERM:(nil, nil, 0) 
+   ENDSELECT. 
+ 
+ term is cut: 
+   remove token; 
+   t:= TERM:(cut, nil, 0). 
+ 
+ term is a variable: 
+   remove token; 
+   t:= TERM:(look ahead value, nil, var). 
+ 
+ term is anonym: 
+   remove token; 
+   anonym value DECR 1; 
+   t:= TERM:(anonym value, nil, var). 
+ 
+ term is number: 
+   remove token; 
+   t:= TERM:(look ahead value, nil, integer). 
+ 
+ term is identifier: 
+   t:= TERM:(look ahead value, nil, 0). 
+ 
+ term is list: 
+   remove token; 
+   t:= TERM:(nil, nil, 0); 
+   IF   look ahead = close bracket 
+   THEN remove token 
+   ELSE non empty list 
+   FI. 
+ 
+ non empty list: 
+   TERM VAR t1; 
+   read term (t1); 
+   append term (t1, t.arguments); 
+   IF   look ahead = close bracket 
+   THEN remove token; 
+        t.arity:= 1 
+   ELSE list with more than one element 
+   FI. 
+ 
+ list with more than one element: 
+   IF   look ahead = stroke 
+   THEN t.symbol:= cons 
+   ELIF look ahead <> comma CAND look ahead <> colon 
+   THEN syntax error ("comma missing") 
+   FI; 
+   term is compound list. 
+ 
+ term is compound list: 
+   remove token; 
+   read terms (t.arguments); 
+   t.arity:= no of terms (t.arguments); 
+   IF   look ahead = close bracket 
+   THEN remove token 
+   ELSE syntax error ("closing bracket missing") 
+   FI. 
+ 
+ term is compound: 
+   remove token; 
+   read terms (t.arguments); 
+   t.arity:= no of terms (t.arguments); 
+   IF   look ahead = close paren 
+   THEN remove token 
+   ELSE syntax error ("closing parentheses missing") 
+   FI. 
+ 
+ term is colon: 
+   remove token; 
+   INT VAR i:= link (symboltable, ":-"); 
+   IF   i = 0 
+   THEN insert (symboltable, ":-", i) 
+   FI; 
+   t:= TERM:(i, nil, 0). 
+ 
+ remove token: 
+   look ahead empty:= TRUE. 
+ 
+ENDPROC read prefix term;  
+ 
+INT PROC no of terms (TERMS CONST ts): 
+   INT VAR i:= 0, t:=ts; 
+   WHILE t <> nil 
+   REP  t:= (tcrestISUB(t)) ; 
+        i INCR 1 
+   PER; 
+   i 
+ENDPROC no of terms; 
+  
+INT PROC arith (TERM CONST term, FRAME CONST curr frame):  
+   TERM VAR t; 
+   IF   term.arity = var 
+   THEN value (term, t, curr frame) 
+   ELSE t:= term 
+   FI; 
+   IF   t.arity = integer 
+   THEN t.symbol 
+   ELIF t.arity = var 
+   THEN syntax error ("free variable in arith expression"); 0 
+   ELIF t.arity = 1 
+   THEN SELECT t.symbol OF 
+        CASE plus:    arith (t1, curr frame) 
+        CASE minus: - arith (t1, curr frame) 
+        OTHERWISE syntax error ("unknown arith operator"); 0 
+        ENDSELECT 
+   ELIF t.arity = 2 
+   THEN SELECT t.symbol OF 
+        CASE plus:  arith (t1, curr frame)  +  arith (t2, curr frame) 
+        CASE minus: arith (t1, curr frame)  -  arith (t2, curr frame) 
+        CASE times: arith (t1, curr frame)  *  arith (t2, curr frame) 
+        CASE slash: arith (t1, curr frame) DIV arith (t2, curr frame) 
+        CASE mod:   arith (t1, curr frame) MOD arith (t2, curr frame) 
+        OTHERWISE syntax error ("unknown arith operator"); 0 
+        ENDSELECT 
+   ELSE syntax error ("wrong arith expression"); 0 
+   FI. 
+ 
+ t1: TERM:(tcsymbolISUBt.arguments, 
+           tcargumentsISUBt.arguments, 
+           tcarityISUBt.arguments) . 
+ 
+ t2: TERM:(tcsymbolISUB(tcrestISUB(t.arguments)) , 
+           tcargumentsISUB(tcrestISUB(t.arguments)) , 
+           tcarityISUB(tcrestISUB(t.arguments)) ) . 
+ 
+ENDPROC arith; 
+ 
+TOKEN PROC look ahead : 
+   { Returns the token in the look ahead.  
+     If the look ahead is empty it calls the scanner 
+     to get the next symbol, 
+     which is then placed into the look ahead. 
+   } 
+   SYMBOLTYPE VAR symboltype; 
+   IF   look ahead empty 
+   THEN look ahead empty:= FALSE; 
+        get next symbol; 
+        store the symbol 
+   FI; 
+   look ahead token. 
+ 
+ get next symbol: 
+   IF   ahead empty 
+   THEN IF   from file 
+        THEN next symbol (file, look ahead symbol, symboltype) 
+        ELSE next symbol (look ahead symbol, symboltype) 
+        FI 
+   ELSE ahead empty:= TRUE; 
+        look ahead symbol:= ahead symbol; 
+        symboltype:= ahead symboltype 
+   FI. 
+ 
+ store the symbol: 
+   SELECT symboltype OF 
+   CASE tag,tex:     look ahead token:= identifier; 
+                     IF   look ahead symbol = "" 
+                     THEN look ahead value:= 0; 
+                     ELSE install 
+                     FI 
+   CASE num:         look ahead token:= number; 
+                     look ahead value:= int(look ahead symbol) 
+   CASE bold:        look ahead token:= bold var; 
+                     install 
+   CASE operator:    look ahead token:= 
+                     pos  ("|!:-+*/_<=<>==..", look ahead symbol); 
+                     IF   look ahead token = equal 
+                     THEN get next symbol; 
+                          IF   symboltype = operator 
+                          CAND look ahead symbol = "=" 
+                          THEN look ahead token:= eqeq; 
+                               look ahead symbol:= "==" 
+                          ELIF look ahead symbol = "." 
+                          THEN get next symbol; 
+                               IF   look ahead symbol = "." 
+                               THEN look ahead token:= eqdotdot; 
+                                    look ahead symbol:= "=.." 
+                               ELSE syntax error ("second period missing") 
+                               FI 
+                          ELSE ahead symbol:= look ahead symbol; 
+                               ahead symboltype:= symboltype; 
+                               ahead empty:= FALSE; 
+                               look ahead symbol:= "="; 
+                               look ahead token := equal 
+                          FI 
+                     FI; 
+                     IF   look ahead token > 3 
+                     THEN install 
+                     FI 
+   CASE delimiter:   look ahead token:= 
+                     pos ("|!:-+*/_<=<>==..,;()[]", look ahead symbol); 
+                     SELECT look ahead token OF 
+                     CASE colon: minus must follow 
+                     CASE 0:     syntax error ("wrong delimiter") 
+                     ENDSELECT 
+   CASE endoffile:   look ahead token:= end of input 
+   CASE within com:  look ahead token:= end of input; 
+                     syntax error ("within comment") 
+   CASE within tex:  look ahead token:= end of input; 
+                     syntax error ("within text") 
+   ENDSELECT. 
+ 
+ minus must follow: 
+   get next symbol; 
+   IF  look ahead symbol <> "-" 
+   THEN syntax error ("minus after colon expected") FI. 
+ 
+ install: 
+   look ahead value:= link (symboltable, look ahead symbol); 
+   IF   look ahead value = 0 
+   THEN insert(symboltable,look ahead symbol,look ahead value) 
+   FI. 
+ENDPROC look ahead; 
+ 
+PROC inform: 
+   enable stop; 
+   put ("  "); 
+   put (clock(0) - start time); put ("SEC"); 
+   IF   inference count > 0 CAND clock(0) > start time 
+   THEN 
+        put (inference count); put ("inferences"); 
+        put (int (real (inference count) / (clock(0) - start time))); 
+        put ("LIPS") 
+   FI; 
+   FOR k FROM 2 UPTO fsp 
+   REP line; 
+       FRAME CONST f:= fsc(k).frame; 
+       INT CONST ind:= fc(f).level; 
+       IF   ind <= 40 
+       THEN write (ind*" ") 
+       ELSE write (text(ind) + ":  ") 
+       FI; 
+       value (fc(f).call, t, fc(f).father); 
+       write term backward (t) 
+   PER; 
+   IF   testing 
+   THEN put(tp); put(kp); put(fp); put(fsp); put(np); put(ep) 
+   FI; 
+   line 
+ENDPROC inform; 
+ 
+PROC syntax error (TEXT CONST message): 
+   free of errors:= FALSE; 
+   write ("!- "); 
+   write note (message); 
+   write note (" at '"); 
+   write note (look ahead symbol); 
+   write note ("' "); 
+   IF   from file 
+   THEN write note ("in rule "); write note (rule count); 
+        write note ("line "); write note (lineno(file) - 1) 
+   FI; 
+   look ahead empty:= TRUE; 
+   line; note line 
+ENDPROC syntax error; 
+ 
+PROC write note (TEXT CONST t): 
+     write (t); 
+     IF from file THEN note (t) FI 
+ENDPROC write note; 
+ 
+PROC write note (INT CONST i): 
+     put (i); 
+     IF from file THEN note (i) FI 
+ENDPROC write note; 
+ 
+PROC trace (TEXT CONST on): 
+     testing:= test on; 
+     tracing:= trace on. 
+     trace on: pos (on, "on") > 0. 
+     test on : pos (on, "test") > 0 
+ENDPROC trace; 
+ 
+PROC new kp (INT VAR pointer): 
+     kp INCR 1; pointer:= kp; 
+     IF   length (kcfirst) < 2*kp 
+     THEN IF   kp > 15990 
+          THEN pegel overflow 
+          ELSE kcfirst CAT "1234567890123456"; 
+               kcrest  CAT "1234567890123456"; 
+     FI   FI 
+ENDPROC new kp; 
+ 
+PROC new tp (INT VAR pointer): 
+     tp INCR 1; pointer:= tp; 
+     IF   length (tcsymbol) < 2*tp 
+     THEN IF   tp = 15990 
+          THEN pegel overflow 
+          ELSE tcsymbol CAT "1234567890123456"; 
+               tcarguments CAT "1234567890123456"; 
+               tcarity CAT "1234567890123456"; 
+               tcrest CAT "1234567890123456" 
+     FI   FI 
+ENDPROC new tp; 
+ 
+PROC new (INT VAR pegel, pointer): 
+     IF   pegel = limit 
+     THEN pegel overflow 
+     ELSE pegel INCR 1; pointer:= pegel 
+     FI 
+ENDPROC new; 
+ 
+PROC pegeloverflow: line; write ("   "); 
+     put(tp); put(kp); put(fp); put(fsp); put(np); put(ep); 
+     errorstop ("pegeloverflow") 
+ENDPROC pegeloverflow; 
+  
+ 
+{                                                            
+Programmtransformation: 
+ 
+   PASCAL mit Pointer ==>  ELAN 
+ 
+ 
+1. Rekursive Datentypen: 
+ 
+   type t = ^tcell;   ==>  LET T = INT; 
+ 
+                         { schwache Datenabstraktion mit LET ist besser, 
+                           weil keine neuen Zugriffsprozeduren erforderlich. 
+ 
+                           GLOBAL: 
+                         } 
+                           LET nil = 0, limit <= 500; 
+                           ROW limit TCELL VAR tc;     { t cell     } 
+                           INT VAR tp:= nil;           { t pegel    } 
+ 
+ 
+2. Deklaration: 
+ 
+   var x : t;         ==>  T VAR x;    { Type checking selber machen ! } 
+ 
+ 
+3. Pointer-Initialisierung: 
+ 
+   x:= nil;           ==>  x:= nil; 
+ 
+ 
+4. Allokation: 
+ 
+   new (x);           ==>  new (tp,x); 
+ 
+   dispose (x);       ==>  kommt nicht vor 
+ 
+ 
+5. Applikation: 
+ 
+   x^.feld            ==>  TERMSCELL:(TERM:(tcsymbolISUBx, tcargumentsISUBx, tcarityISUBx), tcrestISUBx).feld 
+ 
+   WITH               ==>  Refinement verwenden 
+ 
+{ Programmtransformation  ROW limit TERMSCELL VAR tc => TEXT VAR } 
+   T1; 
+   "new (tp, " CA "new tp ("; 
+   T1; 
+   REP 
+        col(1); 
+        D    "tc("; 
+        IF   at ("tc(tc(") 
+        THEN D "tc("; 
+             attest; 
+             col(1); 
+             D "tc(" 
+        FI; 
+        attest 
+   UNTIL eof PER 
+.  
+attest: 
+IF   at ("tc("+any**1+").first."+any**2+":="+any**3+";"+any**4) 
+THEN C ("replace(tc"+match(2)+","+match(1)+","+match(3)+");"+match(4)) 
+ELIF at ("tc("+any**1+").rest:="+any**3+";"+any**4) 
+THEN C ("replace(tcrest,"+match(1)+","+match(3)+");"+match(4)) 
+ELIF at ("tc("+any**1+").first:="+any**3+";"+any**4) 
+THEN C ("replace(tcsymbol,"+match(1)+","+match(3)+ 
+   ".symbol); replace(tcarguments,"+match(1)+","+match(3)+ 
+   ".arguments); replace(tcarity,"+match(1)+","+match(3)+ 
+   ".arity);"+match(4)) 
+ELIF at ("tc("+any**1+").first."+any**2+" "+any**4) 
+THEN C ("(tc"+match(2)+"ISUB("+match(1)+")) "+match(4)) 
+ELIF at ("tc("+any**1+").rest"+any**4) 
+THEN C ("(tcrestISUB("+match(1)+")) "+match(4)) 
+ELIF at ("tc("+any**1+").first).first"+any**4) 
+THEN C ("TERM:(tcsymbolISUB"+match(1)+ 
+   ").first, tcargumentsISUB"+match(1)+ 
+   ").first, tcarityISUB"+match(1)+").first)"+match(4)) 
+ELIF at ("tc("+any**1+").first"+any**4) 
+THEN C ("TERM:(tcsymbolISUB"+match(1)+ 
+   ", tcargumentsISUB"+match(1)+", tcarityISUB"+match(1)+")"+match(4)) 
+ELIF at ("tc("+any**1+"):= TERMSCELL:("+any**2+","+any**3+")"+any**4) 
+THEN C ("replace(tcsymbol,"+match(1)+","+match(2)+ 
+   ".symbol); replace(tcarguments,"+match(1)+","+match(2)+ 
+   ".arguments); replace(tcarity,"+match(1)+","+match(2)+ 
+   ".arity); replace(tcrest,"+match(1)+","+match(3)+")"+match(4)) 
+ELIF at ("tc("+any**1+")"+any**4) 
+THEN C ("TERMSCELL:(TERM:(tcsymbolISUB"+match(1)+ 
+              ", tcargumentsISUB"+match(1)+", tcarityISUB"+match(1) 
+         +"), tcrestISUB"+match(1)+")" +match(4)) 
+ELIF NOT eof 
+THEN stop 
+FI; 
+col(col-1); D("*"); C "" 
+.  
+ 
+}  
+ 
+END PACKET prolog; 
+  
+{ TEST } 
+lernsequenz auf taste legen ("7",""124""); 
+lernsequenz auf taste legen ("ü",""91""); 
+lernsequenz auf taste legen ("+",""93""); 
+
diff --git a/prolog/prolog installation b/prolog/prolog installation
new file mode 100644
index 0000000..cc674fa
--- /dev/null
+++ b/prolog/prolog installation	
@@ -0,0 +1,117 @@
+(*************************************************************************)
+(*** Insertiert die für PROLOG benötigten Pakete und holt die          ***)
+(*** Beispiele vom Archiv.                                             ***)
+(***                                                                   ***)
+(*** Autor : W. Metterhausen                          Stand : 03.12.87 ***)
+(*************************************************************************)
+
+erste bildschirmmeldung;
+
+
+IF yes("Prolog insertieren?")
+
+   THEN
+        hole sourcen vom archiv;
+        insertiere alle pakete;
+        hole beispiele vom archiv;
+      forget ("prolog installation", quiet);
+   type("push(""bye""13""prolog again"");prolog(""standard"")"13""); 
+FI.
+
+
+insertiere alle pakete :
+   insert and say ("thesaurus");
+   insert and say ("prolog").
+
+erste bildschirmmeldung :
+   page;
+   put center (" Generator für Prolog gestartet."); line;
+   put center ("--------------------------------------------------");line;
+   put center (" Prolog kann nur in einer Task aufgebaut werden, ");line;
+   put center (" die nicht bereits umfangreiche insertierte Pakete ");line;
+   put center (" enthält! Gegebenenfalls sollte Prolog in ");line;
+   put center (" einer Task direkt unter ""UR"" angelegt werden. ");line;
+   line (2).
+
+hole sourcen vom archiv :
+   TEXT VAR  datei;
+   datei := "thesaurus";          hole wenn noetig;
+   datei := "prolog";             hole wenn noetig;
+   line.
+
+hole beispiele vom archiv :
+   datei := "standard";           hole wenn noetig;
+   datei := "sum";                hole wenn noetig;
+   datei := "permute";            hole wenn noetig;
+   datei := "family";             hole wenn noetig;
+   datei := "puzzle";             hole wenn noetig;
+   datei := "calc";               hole wenn noetig;
+   datei := "prieks";             hole wenn noetig;
+   datei := "topographie";        hole wenn noetig;
+   datei := "quicksort";          hole wenn noetig;
+   datei := "prolog dokumentation";
+                                  hole wenn noetig;
+   release(archive);
+   line.
+
+hole wenn noetig :
+   IF NOT exists (datei) THEN
+      put line (""""+ datei + """ wird vom Archiv geholt");
+      fetch (datei, archive)
+   FI.
+
+PROC insert and say (TEXT CONST datei) :
+
+   INT VAR cx, cy;
+   put line ("Inserting """ + datei + """...");
+   get cursor (cx, cy);
+   checkoff;
+   insert (datei);
+   checkon;
+   cl eop (cx, cy); line;
+   forget (datei, quiet).
+
+END PROC insert and say;
+
+TEXT PROC inverse (TEXT CONST t):
+  ""15"" + t + " " + ""14""
+END PROC inverse;
+
+PROC put center (TEXT CONST t):
+   put center (t, 80)
+END PROC put center;
+
+PROC put center (INT CONST zeile, TEXT CONST t):
+   put center (zeile, t, 80)
+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; 
+
+
diff --git a/prolog/puzzle b/prolog/puzzle
new file mode 100644
index 0000000..648beb6
--- /dev/null
+++ b/prolog/puzzle
@@ -0,0 +1,24 @@
+                {Solution: 9,5,6,7,0,8,2} 
+puzzle:- repeat, permute ((9,8,7,6,5,2,0), SENDMORY), 
+                 write (SENDMORY), 
+                 puzzle (SENDMORY, SEND, MORE, MONEY), 
+                 elan (line), 
+                 write (SEND), write (+), 
+                 write (MORE), write (=), 
+                 write (MONEY). 
+ 
+puzzle([S,E,N,D,O,R,Y], SEND, MORE, MONEY):- 
+  SEND   IS  ((S * 10 + E) * 10 + N) * 10 + D, 
+  MORE   IS  ((10 + O) * 10 + R) * 10 + E, 
+  MONEY  IS  (((10 + O) * 10 + N) * 10 + E) * 10 + Y, 
+  MONEY  IS  SEND + MORE. 
+ 
+permute ([], []). 
+permute ([E|X], Z):- permute (X, Y), insert (E, Y, Z). 
+ 
+insert  (E, X, [E|X]). 
+insert  (E, [F|X], [F|Y]):- insert (E, X, Y). 
+ 
+repeat. 
+repeat:- repeat. 
+
diff --git a/prolog/quicksort b/prolog/quicksort
new file mode 100644
index 0000000..79276c0
--- /dev/null
+++ b/prolog/quicksort
@@ -0,0 +1,14 @@
+(* quicksort algorithm nach Clocksin-Mellish *) 
+ 
+(* Example :  quicksort ([1,3,2,4], [1,2,3,4], [])  *) 
+ 
+quicksort ([H|T], S, X) :- 
+          split (H, T, A, B), 
+          quicksort (A, S, [H|Y]), 
+          quicksort (B, Y, X). 
+quicksort ([], X, X). 
+ 
+split (H, [A|X], [A|Y], Z) :- A <= H, split (H, X, Y, Z). 
+split (H, [A|X], Y, [A|Z]) :- split (H, X, Y, Z). 
+split (_, [], [], []). 
+
diff --git a/prolog/standard b/prolog/standard
new file mode 100644
index 0000000..bc983ca
--- /dev/null
+++ b/prolog/standard
@@ -0,0 +1,35 @@
+abolish    (X)                :-  elan (abolish, X). 
+append     ([], X, X)         :-  !. 
+append     ([X|Y], Z, [X|W])  :-  append (Y, Z, W). 
+atom       (X)                :-  functor (X, Y, 0). 
+atomic     (X)                :-  atom (X); integer (X). 
+consult    (X)                :-  elan (consult, X). 
+end                           :-  bye. 
+fail                          :-  []. 
+findall    (X, Y, Z)          :-  tell ("$$"), write ("[ "), findall (X,Y); 
+                                  write (" ]"), told, see  ("$$"), read (Z), 
+                                  seen, elan (forget, "$$"). 
+findall    (X, Y)             :-  call (Y), writeq (X), write (","), []. 
+integer    (X)                :-  functor (X, Y, -1). 
+listing    (X). 
+member     (X, [X|Z]).        
+member     (X, [Y|Z])         :-  member (X, Z). 
+nl                            :-  elan (line). 
+non var    (X)                :-  var (X), !, []; . 
+not        (X)                :-  call (X), !, []; . 
+notrace                       :-  elan (trace, off). 
+reconsult  (X)                :-  elan (reconsult, X). 
+repeat. 
+repeat                        :-  repeat. 
+see        (X)                :-  elan (sysin, X). 
+seen                          :-  elan (sysin, ""). 
+tab        (X)                :-  tab(X,1). 
+tab        (X,Y)              :-  Y<=X, !, put (32), incr(Y), tab(X,Y);. 
+tell       (X)                :-  elan (sysout, X). 
+told                          :-  elan (sysout, ""). 
+trace                         :-  elan (trace, on). 
+true. 
+<          (X, Y)             :-  <= (X, Y), <> (X, Y). 
+>          (X, Y)             :-  <= (Y, X). 
+>=         (X, Y)             :-  <  (Y, X). 
+
diff --git a/prolog/sum b/prolog/sum
new file mode 100644
index 0000000..e1b6b13
--- /dev/null
+++ b/prolog/sum
@@ -0,0 +1,13 @@
+suc (0, 1). suc (1, 2). suc (2, 3). suc (3, 4). suc (4, 5). 
+suc (5, 6). suc (6, 7). suc (7, 8). suc (8, 9). 
+sum (0, X, X). 
+sum (X, Y, Z):-  suc (V, X), sum (V, Y, W), suc (W, Z). 
+plus (X, [0,0], X):-  !. 
+plus (X, Y, Z):-  plus one (V, Y), plus (X, V, W), !, plus one (W, Z). 
+plus one ([X, Y], [V, W]):-  suc (Y, W), X = V, !; 
+                             Y = 9, suc (X, V), W = 0. 
+treereverse (X,Y):-  rev (X,Y), !; rev (Y,X), !. 
+rev ([], []). 
+rev ([X|Y], Z):-  X <> [H|T], rev (Y, W), !, append (W, [X], Z); 
+                  rev (X, V), rev (Y, W), !, append (W, [V], Z). 
+
diff --git a/prolog/thesaurus b/prolog/thesaurus
new file mode 100644
index 0000000..4694981
--- /dev/null
+++ b/prolog/thesaurus
@@ -0,0 +1,360 @@
+(* ------------------- VERSION 2     19.01.87 ------------------- *)
+PACKET thesaurus handling                (* Autor: J.Liedtke      *)
+ 
+       DEFINES     THESAURUS , 
+                   := , 
+                   empty thesaurus , 
+                   insert,               (* fuegt ein Element ein               *)
+                   delete,               (* loescht ein Element falls vorhanden *)
+                   rename,               (* aendert ein Element falls vorhanden *)
+                   CONTAINS ,            (* stellt fest, ob enthalten           *)
+                   link ,                (* index in thesaurus                  *) 
+                   name ,                (* name of entry                       *)
+                   decode invalid chars ,(* Steuerzeichen dekodieren            *)
+                   get ,                 (* get next entry ("" is eof)          *)
+                   highest entry :       (* highest valid index of thes         *)
+
+
+TYPE THESAURUS = TEXT ;
+ 
+LET nil = 0 ,
+    niltext = "" ,
+    max name length = 80 ,
+    begin entry char = ""0"" ,
+    end entry char   = ""255"" ,
+    nil entry        = ""0""255"" ,
+    nil name         = "" ,
+    quote            = """" ;
+
+TEXT VAR entry ,
+         dummy ;
+INT VAR  cache index := 0 ,
+         cache pos ;
+
+
+TEXT PROC decode (INT CONST number) :
+
+  dummy := "  " ;
+  replace (dummy, 1, number) ;
+  dummy .
+
+ENDPROC decode ;
+
+INT PROC decode (TEXT CONST string, INT CONST position) :
+
+  subtext (string, position, position + 1) ISUB 1 .
+
+ENDPROC decode ;
+
+PROC access (THESAURUS CONST thesaurus, TEXT CONST name) :
+
+  construct entry ;
+  IF NOT cache identifies entry
+    THEN search through thesaurus list
+  FI ;
+  IF entry found
+    THEN cache index := decode (list, cache pos - 2)
+    ELSE cache index := 0
+  FI .
+
+construct entry :
+  entry := begin entry char ;
+  entry CAT name ;
+  decode invalid chars (entry, 2) ;
+  entry CAT end entry char .
+
+search through thesaurus list :
+  cache pos := pos (list, entry) .
+
+cache identifies entry :
+  cache pos <> 0 AND
+  pos (list, entry, cache pos, cache pos + LENGTH entry) = cache pos .
+
+entry found :  cache pos > 0 .
+
+list :  CONCR (thesaurus) .
+
+ENDPROC access ;
+
+PROC access (THESAURUS CONST thesaurus, INT CONST index) :
+
+  IF cache identifies index
+    THEN cache index := index ;
+         construct entry
+    ELSE cache pos := pos (list, decode (index) + begin entry char) ;
+         IF entry found
+           THEN cache pos INCR 2 ;
+                cache index := index ;
+                construct entry
+           ELSE cache index := 0 ;
+                entry := niltext
+         FI
+  FI .
+
+construct entry :
+  entry := subtext (list, cache pos, pos (list, end entry char, cache pos)) .
+
+cache identifies index :
+  subtext (list, cache pos-2, cache pos) = decode (index) + begin entry char .
+
+entry found :  cache pos > 0 .
+
+list :    CONCR (thesaurus) .
+
+ENDPROC access ;
+
+
+
+THESAURUS PROC empty thesaurus :
+
+  THESAURUS : (""1""0"")
+
+ENDPROC empty thesaurus ; 
+ 
+ 
+OP := (THESAURUS VAR dest, THESAURUS CONST source ) : 
+ 
+  CONCR (dest) := CONCR (source) .
+
+ENDOP := ; 
+ 
+TEXT VAR insert name ;
+
+PROC insert (THESAURUS VAR thesaurus, TEXT CONST name, INT VAR index) : 
+ 
+  insert name := name ;
+  decode invalid chars (insert name, 1) ;
+  insert name if possible .
+
+insert name if possible :
+  IF insert name = "" OR LENGTH insert name > max name length
+    THEN index := nil ; errorstop ("Name unzulaessig")
+  ELIF overflow
+      THEN index := nil
+      ELSE insert element
+  FI .
+ 
+overflow :
+  LENGTH CONCR (thesaurus) + LENGTH insert name + 4 > max text length .
+
+insert element :
+  search free entry ;
+  IF   entry found 
+    THEN insert into directory 
+    ELSE add entry to directory if possible
+  FI .
+
+search free entry :
+  access (thesaurus, nil name) .
+
+insert into directory :
+  change (list, cache pos + 1, cache pos, insert name) ;
+  index := cache index .
+
+add entry to directory if possible :
+  INT CONST next free index := decode (list, LENGTH list - 1) ;
+  add entry to directory .
+
+add entry to directory :
+  list CAT begin entry char ;
+  cache pos := LENGTH list ;
+  cache index := next free index ;
+  list CAT insert name ;
+  list CAT end entry char + decode (next free index + 1) ;
+  index := cache index .
+
+entry found :   cache index > 0 .
+
+list :          CONCR (thesaurus) .
+
+ENDPROC insert ; 
+ 
+PROC decode invalid chars (TEXT VAR name, INT CONST start pos) :
+
+  INT VAR invalid char pos := pos (name, ""0"", ""31"", start pos) ;
+  WHILE invalid char pos > 0 REP
+    change (name, invalid char pos, invalid char pos, decoded char) ;
+    invalid char pos := pos (name, ""0"", ""31"", invalid char pos)
+  PER ;
+  change all (name, ""255"", quote + "255" + quote) .
+
+decoded char :  quote + text(code(name SUB invalid char pos)) + quote.
+
+ENDPROC decode invalid chars ;
+
+PROC insert (THESAURUS VAR thesaurus, TEXT CONST name) :
+
+  INT VAR index ;
+  insert (thesaurus, name, index) ;
+  IF index = nil AND NOT is error
+    THEN errorstop ("THESAURUS-Ueberlauf")
+  FI .
+
+ENDPROC insert ;
+
+PROC delete (THESAURUS VAR thesaurus, TEXT CONST name, INT VAR index) : 
+ 
+  access (thesaurus, name) ;
+  index := cache index ;
+  delete (thesaurus, index) .
+
+ENDPROC delete ;
+
+PROC delete (THESAURUS VAR thesaurus, INT CONST index) :
+
+  access (thesaurus, index) ;
+  IF entry found
+    THEN delete entry
+  FI .
+
+delete entry :
+  IF is last entry of thesaurus
+    THEN cut off as much as possible
+    ELSE set to nil entry
+  FI .
+
+set to nil entry :
+  change (list, cache pos, cache pos + LENGTH entry - 1, nil entry) . 
+
+cut off as much as possible :
+  WHILE predecessor is also nil entry REP
+    set cache to this entry
+  PER ;
+  list := subtext (list, 1, cache pos - 1) ;
+  erase cache .
+
+predecessor is also nil entry :
+  subtext (list, cache pos - 4, cache pos - 3) = nil entry .
+
+set cache to this entry :
+  cache pos DECR 4 .
+
+erase cache :
+  cache pos := 0 ;
+  cache index := 0 .
+
+is last entry of thesaurus :
+  pos (list, end entry char, cache pos) = LENGTH list - 2 .
+
+list :     CONCR (thesaurus) .
+
+entry found :   cache index > nil .
+
+ENDPROC delete ;
+
+ 
+BOOL OP CONTAINS (THESAURUS CONST thesaurus, TEXT CONST name ) : 
+ 
+  IF   name = niltext OR LENGTH name > max name length
+    THEN FALSE
+    ELSE access (thesaurus, name) ; entry found
+  FI . 
+ 
+entry found :   cache index > nil . 
+ 
+ENDOP CONTAINS ; 
+ 
+PROC rename (THESAURUS VAR thesaurus, TEXT CONST old, new) :
+ 
+  rename (thesaurus, link (thesaurus, old), new)
+
+ENDPROC rename ;
+
+PROC rename (THESAURUS VAR thesaurus, INT CONST index, TEXT CONST new) :
+
+  insert name := new ;
+  decode invalid chars (insert name, 1) ;
+  IF overflow
+    THEN errorstop ("THESAURUS-Ueberlauf")
+  ELIF insert name = "" OR LENGTH insert name > max name length 
+    THEN errorstop ("Name unzulaessig")
+    ELSE change to new name
+  FI .
+ 
+overflow :
+  LENGTH CONCR (thesaurus) + LENGTH insert name + 4 > max text length .
+
+change to new name :
+  access (thesaurus, index) ;
+  IF cache index <> 0 AND entry <> ""
+    THEN change (list, cache pos + 1, cache pos + LENGTH entry - 2, insert name)
+  FI .
+
+list :    CONCR (thesaurus) .
+
+ENDPROC rename ;
+ 
+INT PROC link (THESAURUS CONST thesaurus, TEXT CONST name) : 
+ 
+  access (thesaurus, name) ;
+  cache index .
+
+ENDPROC link ; 
+ 
+TEXT PROC name (THESAURUS CONST thesaurus, INT CONST index) : 
+ 
+  access (thesaurus, index) ;
+  subtext (entry, 2, LENGTH entry - 1) .
+
+ENDPROC name ;
+
+PROC get (THESAURUS CONST thesaurus, TEXT VAR name, INT VAR index) :
+
+  identify index ;
+  REP
+    to next entry
+  UNTIL end of list COR valid entry found PER .
+
+identify index :
+  IF index = 0
+    THEN cache index := 0 ;
+         cache pos   := 1
+    ELSE access (thesaurus, index)
+  FI .
+
+to next entry :
+  cache pos := pos (list, begin entry char, cache pos + 1) ;
+  IF cache pos > 0
+    THEN correct cache pos ;
+         get entry
+    ELSE get nil entry
+  FI .
+
+correct cache pos :
+  IF (list SUB cache pos + 2) = begin entry char
+    THEN cache pos INCR 2
+  ELIF (list SUB cache pos + 1) = begin entry char
+    THEN cache pos INCR 1
+  FI .
+
+get entry :
+  cache index INCR 1 ;
+  index := cache index ;
+  name := subtext (list, cache pos + 1, end entry pos - 1) .
+
+get nil entry :
+  cache index := 0 ;
+  cache pos := 0 ;
+  index := 0 ;
+  name := "" .
+
+end entry pos :     pos (list, end entry char, cache pos) .
+
+end of list :       index = 0 .
+
+valid entry found : name <> "" .
+
+list :              CONCR (thesaurus) .
+
+ENDPROC get ;
+
+INT PROC highest entry (THESAURUS CONST thesaurus) :              (*840813*)
+
+  decode (list, LENGTH list - 1) - 1 .
+
+list :   CONCR (thesaurus) .
+
+ENDPROC highest entry ;
+
+ENDPACKET thesaurus handling ;
+
diff --git a/prolog/topographie b/prolog/topographie
new file mode 100644
index 0000000..c0924cf
--- /dev/null
+++ b/prolog/topographie
@@ -0,0 +1,59 @@
+member(X,[X|_]). 
+member(X,[_|Y]):- 
+    member(X,Y). 
+   
+append([],L,L). 
+append([X|A],B,[X|C]):- 
+    append(A,B,C). 
+   
+efface(A,[A|L],L):- 
+    !. 
+efface(A,[B|L],[B|M]):- 
+    efface(A,L,M). 
+efface(_,[],[]). 
+   
+   
+nol(N):- 
+    read(N). 
+   
+input(_,_,N,N,L,L). 
+input(X,Y,R,N,L,O):- 
+    read(X), 
+    read(Y), 
+    append([[X,Y]],L,M), 
+    C IS R+1, 
+    input(_,_,C,N,M,O). 
+   
+enter(L):- 
+    nol(N), 
+    input(X,Y,0,N,[],L). 
+   
+   
+searchnext(X,Y,[H|T]):- 
+    H=[X,Y]; 
+    H=[Y,X]; 
+    searchnext(X,Y,T). 
+   
+onemove(_,_,[],L):- 
+    write(L). 
+onemove(X,Y,L,H):- 
+    searchnext(X,Y,L), 
+    efface([X,Y],L,N), 
+    L<>N, 
+    write(N),elan(line), 
+    append(H,[Y],F),     
+    onemove(Y,Z,N,F). 
+onemove(X,Y,L,H):- 
+    searchnext(X,Y,L), 
+    efface([Y,X],L,N), 
+    L<>N, 
+    write(N),elan(line), 
+    append(H,[Y],F),     
+    onemove(Y,Z,N,F). 
+   
+   
+   
+go:- 
+    enter(L),!, 
+    onemove(X,Y,L,[X]). 
+
diff --git a/prozess/ls-MENUKARTE:Prozess b/prozess/ls-MENUKARTE:Prozess
new file mode 100644
index 0000000..9a2e009
Binary files /dev/null and b/prozess/ls-MENUKARTE:Prozess differ
diff --git "a/prozess/ls-Prozess 1 f\303\274r AKTRONIC-Adapter" "b/prozess/ls-Prozess 1 f\303\274r AKTRONIC-Adapter"
new file mode 100644
index 0000000..c42cfa5
--- /dev/null
+++ "b/prozess/ls-Prozess 1 f\303\274r AKTRONIC-Adapter"	
@@ -0,0 +1,57 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                     ls-Prozess 1                     ** 
+         **                                                      ** 
+         **            Anpassung für AKTRONIC-Adapter            ** 
+         **                                                      ** 
+         **                     Version 1.02                     ** 
+         **                                                      ** 
+         **                  (Stand : 26.01.90)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **         Autoren: Bruno Pollok, Bielefeld             ** 
+         **                  Wolfgang Weber, Bielefeld           ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls prozess 1 DEFINES                   
+       run pdv,{}       run pdv again,{}       initialisiere interface,{}       schalte alles aus,{}       ausgeben,{}       eingabe,{}       warte,{}       abbruch gewuenscht,{}       tue nichts,{}       trage kanaldaten ein,{}       beende kanaldaten eintragen,{}       hole spannungsbereich,{}       letzte ausgabe,{}       pruefe kanal,{}       pruefe abbruch,{}       teste interface,{}       oeffne interface,{}       schliesse interface,{}       nicht belegt,{}       digital aus,{}       analog aus,{}
+       digital ein,{}       analog ein,{}       kanalbreite,{}       ganzzahl obergrenze,{}       adapterart,{}    (* ------------------------- *){}       kanalkoppler,{}       interface kanal,{}       oeffne interface direkt,{}       schliesse interface direkt,{}       initialisiere interface direkt,{}       direkt ausgeben,{}       direkt eingabe:{}(******** A N P A S S U N G  A N  A K T R O N I C - A D A P T E R ********){}LET interface test  code = ""240"",{}    interface open  code = ""176"",{}
+    interface close code = ""176"",{}    adresse 0 code       = ""176"",{}    interface write code =    64  ,{}    interface read  code =   192  ;{}TEXT CONST adapterart :: "AKTRONIC-Adapter";{}TEXT PROC interface anpassung (INT CONST kanalnummer, steuerungscode):{}  IF   es ist ein ausgabekanal{}       THEN code (interface write code + device + faktor * steuerungscode){}  ELIF es ist ein eingabekanal{}       THEN lesecode in abhaengigkeit von der taktzahl{}       ELSE ""{}  FI.{}  es ist ein ausgabekanal:{}
+    kanal [kanalnummer].betriebsart < 0.{}  es ist ein eingabekanal:{}    kanal [kanalnummer].betriebsart > 0.{}  device:{}    IF steckplatznummer < 3{}       THEN 16{}       ELSE 32{}    FI.{}  faktor:{}    IF steckplatznummer MOD 2 = 0{}       THEN 4{}       ELSE 1{}    FI.{}  steckplatznummer:{}    IF kanalnummer < 10{}       THEN 1{}       ELSE kanalnummer DIV 10{}    FI.{}  lesecode in abhaengigkeit von der taktzahl:{}    SELECT kanal [kanalnummer].taktzahl OF{}      CASE 1: code fuer digital oder analog eingang{}
+      CASE 2: code fuer kombi e1{}      CASE 3: code fuer kombi e2{}    OTHERWISE "" END SELECT.{}  code fuer digital oder analog eingang:{}    IF kanal [kanalnummer].betriebsart = analog ein{}       THEN kanal [kanalnummer].taktzahl := 2;  (* ad wandler muss hier *){}            lesecode + lesecode                 (* 2x gelesen werden!   *){}       ELSE lesecode{}    FI.{}  lesecode  :  code (interface read code + device + faktor * steuerungscode).{}  code fuer kombi e1:{}    kanal [kanalnummer].taktzahl INCR 1; (* bei Analogport1 der Kombikarte *){}
+    adresse 0 code + (3 * lesecode).     (* sind hier 3 Takte     noetig ! *){}  code fuer kombi e2:{}    kanal [kanalnummer].taktzahl DECR 1;     (* hier nur 2 Takte noetig ! *){}    adresse 0 code + lesecode + lesecode.{}END PROC interface anpassung;{}(************ H A R D W A R E U N A B H Ä N G I G E R  T E I L ************){}LET       max kanalanzahl          =   49,{}          initcode                 =   50,{}          endcode                  =   51,{}          alles aus code           =   52,{}
+          endezeichen              =  "q",{}          abbruchzeichen           =  "h",{}          esc                      =  ""27"";{}INT CONST analog aus               ::  -2,            (* Betriebsarten *){}          digital aus              ::  -1,{}          nicht belegt             ::   0,{}          digital ein              ::   1,{}          analog  ein              ::   2,{}          kanalbreite              ::   8,{}          ganzzahl obergrenze      ::   2 ** kanalbreite,{}          configuration error code ::  -1,{}
+          kanal besetzt code       ::  -3,{}          interface error code     ::  -4,{}          not init code            ::  -5;{}INT VAR   interfacechannel         ::   2,{}          dummy;{}TEXT VAR  meldung                  ::  "";{}BOOL VAR  kanaldaten sind eingetragen :: FALSE,{}          endezeichen gegeben         :: FALSE,{}          programm mit pdv gestartet  :: FALSE,{}          fehler zu melden            :: FALSE;{}TASK VAR  interface task              :: niltask;{}DATASPACE VAR  ds :: nilspace;{}
+TYPE KANAL     = STRUCT (INT  betriebsart, taktzahl, TEXT steuercode),{}     SPANNUNG  = STRUCT (REAL minimalwert, maximalwert);{}ROW max kanalanzahl INT      VAR vorherige ausgabe;{}ROW max kanalanzahl KANAL    VAR kanal;{}ROW max kanalanzahl SPANNUNG VAR spannung;{}ROW 5 TEXT CONST fehlermeldung :: ROW 5 TEXT :{}  ("Interface ist noch nicht konfiguriert!",{}   "Interface-Task ist besetzt!",{}   "Interface-Kanal ist belegt!",{}   "Interface meldet sich nicht!",{}   "Interface kann nicht geöffnet werden!");{}
+PROC run pdv:{}  run pdv (last param){}END PROC run pdv;{}PROC run pdv (TEXT CONST programmname):{}  enable stop;{}  last param (programmname);{}  programm mit pdv gestartet := TRUE;{}  teste interface;{}  disable stop;{}  run (programmname);{}  IF is error{}     THEN fehlerbehandlung{}     ELSE melde programmende{}  FI;{}  schliesse interface;{}  programm mit pdv gestartet := FALSE;{}  enable stop;{}  IF fehler zu melden{}     THEN errorstop (meldung){}  FI{}END PROC run pdv;{}PROC run pdv again:{}
+  enable stop;{}  programm mit pdv gestartet := TRUE;{}  teste interface;{}  disable stop;{}  run again;{}  IF is error{}     THEN fehlerbehandlung{}     ELSE melde programmende{}  FI;{}  schliesse interface;{}  programm mit pdv gestartet := FALSE;{}  enable stop;{}  IF fehler zu melden{}     THEN errorstop (meldung){}  FI{}END PROC run pdv again;{}PROC melde programmende:{}  page;{}  menufootnote ("Programmende! Zum Weitermachen bitte irgendeine Taste tippen.");{}  pause;{}  schalte alles aus{}END PROC melde programmende;{}
+PROC initialisiere interface:{}  enable stop;{}  pruefe abbruch;{}  IF programm mit pdv gestartet{}     THEN schalte alles aus{}     ELSE errorstop ("PDV-Programme müssen mit 'run pdv' gestartet werden!"){}  FI{}END PROC initialisiere interface;{}PROC schalte alles aus:{}  INT VAR k;{}  FOR k FROM 1 UPTO max kanalanzahl REP{}    vorherige ausgabe [k] := 0{}  PER;{}  forget (ds); ds := nilspace;{}  call (interface task, alles aus code, ds, dummy){}END PROC schalte alles aus;{}PROC ausgeben (INT CONST kanalnummer, wert):{}
+  merke wert;{}  gib wert aus.{}  merke wert:{}    vorherige ausgabe [kanalnummer] := wert.{}  gib wert aus:{}    call (interface task, 256 * kanalnummer + wert, ds, dummy).{}END PROC ausgeben;{}INT PROC eingabe (INT CONST kanalnummer):{}  INT VAR eingabewert;{}  call (interface task, kanalnummer, ds, eingabewert);{}  eingabewert{}END PROC eingabe;{}PROC warte (REAL CONST sekunden):{}  TEXT VAR eingabe;{}  pruefe abbruch;{}  eingabe := incharety (int (sekunden * 10.0 + 0.5));{}  IF eingabe = esc{}
+     THEN untersuche naechstes zeichen{}  FI.{}  untersuche naechstes zeichen:{}    eingabe := incharety (30);{}    IF   eingabe = endezeichen{}         THEN endezeichen gegeben := TRUE{}    ELIF eingabe = abbruchzeichen{}         THEN errorstop ("Programm-Abbruch durch <ESC><"{}                             + abbruchzeichen + ">!"){}    FI.{}END PROC warte;{}PROC warte (INT CONST sekunden):{}  TEXT VAR eingabe;{}  pruefe abbruch;{}  eingabe := incharety (sekunden * 10);{}  IF eingabe = esc{}     THEN untersuche naechstes zeichen{}
+  FI.{}  untersuche naechstes zeichen:{}    eingabe := incharety (30);{}    IF   eingabe = endezeichen{}         THEN endezeichen gegeben := TRUE{}    ELIF eingabe = abbruchzeichen{}         THEN errorstop ("Programm-Abbruch durch <ESC><"{}                             + abbruchzeichen + ">!"){}    FI.{}END PROC warte;{}BOOL PROC abbruch gewuenscht:{}  pruefe abbruch;{}  BOOL VAR entscheidung :: endezeichen gegeben;{}  endezeichen gegeben := FALSE;{}  entscheidung{}END PROC abbruch gewuenscht;{}PROC tue nichts:{}
+  pruefe abbruch{}END PROC tue nichts;{}PROC trage kanaldaten ein (INT CONST  kanalnummer,{}                           ROW 2 REAL CONST spannungsbereich,{}                           ROW 3 INT  CONST kanalparameter):{}   spannung [kanalnummer].minimalwert := spannungsbereich [1];{}   spannung [kanalnummer].maximalwert := spannungsbereich [2];{}   kanal [kanalnummer].betriebsart    := kanalparameter   [1];{}   kanal [kanalnummer].taktzahl       := kanalparameter   [2];{}   kanal [kanalnummer].steuercode     := interface anpassung{}
+                                         (kanalnummer, kanalparameter [3]){}END PROC trage kanaldaten ein;{}PROC beende kanaldaten eintragen:{}  loesche interface task;{}  begin (PROC kanal koppler, interface task);{}  kanaldaten sind eingetragen := TRUE.{}  loesche interface task:{}    disable stop;{}    end (interface task);{}    IF is error{}       THEN clear error{}    FI;{}    enable stop.{}END PROC beende kanaldaten eintragen;{}PROC hole spannungsbereich (INT CONST kanalnummer, REAL VAR  u min, u max):{}
+  u min := spannung [kanalnummer].minimalwert;{}  u max := spannung [kanalnummer].maximalwert{}END PROC hole spannungsbereich;{}INT PROC letzte ausgabe (INT CONST kanalnummer):{}  vorherige ausgabe [kanalnummer]{}END PROC letzte ausgabe;{}PROC pruefe kanal (INT CONST kanalnummer, gewuenschte betriebsart):{}  pruefe abbruch;{}  pruefe kanalnummer;{}  pruefe betriebsart.{}  pruefe kanalnummer:{}    IF kanalnummer < 1 OR kanalnummer > max kanalanzahl{}       THEN errorstop ("Kanalnummer " + text (kanalnummer) +{}
+                        " ist unzulaessig !"){}    FI.{}  pruefe betriebsart:{}    IF gewuenschte betriebsart <> kanal [kanalnummer].betriebsart{}       THEN errorstop ("An Kanal " + text (kanalnummer) +{}                          " keine " +  wunsch + " moeglich!"){}    FI.{}  wunsch:{}    IF   gewuenschte betriebsart = analog aus{}         THEN "Analog-Ausgabe"{}    ELIF gewuenschte betriebsart = digital aus{}         THEN "Digital-Ausgabe"{}    ELIF gewuenschte betriebsart = digital ein{}         THEN "Digital-Eingabe"{}
+    ELIF gewuenschte betriebsart = analog ein{}         THEN "Analog-Eingabe"{}         ELSE "Ein- oder Ausgabe"{}    FI.{}END PROC pruefe kanal;{}PROC pruefe abbruch:{}  IF incharety = esc{}     THEN pruefe weiter{}  FI.{}  pruefe weiter:{}    TEXT CONST zeichen :: incharety (30);{}    IF   zeichen = endezeichen{}         THEN endezeichen gegeben := TRUE{}    ELIF zeichen = abbruchzeichen{}         THEN errorstop ("Programm-Abbruch durch <ESC><"{}                             + abbruchzeichen + ">!"){}
+    FI.{}END PROC pruefe abbruch;{}PROC oeffne interface (INT VAR status):{}  enable stop;{}  forget (ds); ds := nilspace;{}  IF kanaldaten sind eingetragen{}     THEN pingpong (interfacetask, initcode, ds, status){}     ELSE status := configuration error code{}  FI;{}  IF status > 0 THEN status DECR maxint FI;{}  forget (ds); ds := nilspace{}END PROC oeffne interface;{}PROC schliesse interface:{}  enable stop;{}  forget (ds); ds := nilspace;{}  pingpong (interface task, end code, ds, dummy);{}  forget (ds); ds := nilspace{}
+END PROC schliesse interface;{}PROC teste interface:{}  INT VAR test;{}  oeffne interface (test);{}  IF test < 0{}     THEN errorstop (fehlermeldung [min (5, abs (test))]){}     ELSE fehler zu melden           := FALSE;{}          endezeichen gegeben        := FALSE{}  FI{}END PROC teste interface;{}PROC fehlerbehandlung:{}  meldung := errormessage;{}  IF meldung <> ""{}     THEN meldung CAT fehlerzeile;{}          fehler zu melden := TRUE{}  FI;{}  clear error;{}  initialisiere interface.{}  fehlerzeile:{}
+    IF errorline = 0{}       THEN ""{}       ELSE " (bei Zeile " + text (errorline) + ")"{}    FI.{}END PROC fehlerbehandlung;{}(********************  EIN-/AUSGABE AM INTERFACE-KANAL ********************){}PROC kanalkoppler:{}  IF name (myself) <> "-"{}     THEN errorstop ("Unzulässiges Kommando!"){}     ELSE warte auf anrufe{}  FI.{}  warte auf anrufe:{}    TASK      VAR absender;{}    TEXT      VAR dummy;{}    INT       VAR codenummer, antwort;{}    disable stop;{}    REP forget (ds);{}        wait (ds, codenummer, absender);{}
+        IF codenummer = initcode{}           THEN kopple an interface kanal;{}                IF interface ist betriebsbereit{}                   THEN bearbeite weitere auftraege{}                   ELSE gib negative rueckmeldung{}                FI;{}                gib kanal frei{}           ELSE antwort := not init code;{}                gib negative rueckmeldung{}        FI{}    PER.{} kopple an interface kanal:{}  continue (interface channel);{}  IF is error{}     THEN clear error;{}          antwort := kanal besetzt code{}
+     ELSE oeffne interface direkt (antwort){}  FI.{} interface ist betriebsbereit:  antwort = 0.{} gib negative rueckmeldung:     send (absender, antwort, ds).{} gib kanal frei:{}   break (quiet);{}   send  (absender, 0, ds, antwort);{}   collect heap garbage.{} bearbeite weitere auftraege:{}   REP   call (absender, antwort, ds, codenummer);{}         IF   codenummer > 255{}              THEN sende wert an interface{}         ELIF codenummer <  50{}              THEN hole wert von interface{}         ELIF codenummer = alles aus code{}
+              THEN initialisiere interface direkt{}         FI{}   UNTIL codenummer = endcode PER;{}   IF is error THEN clear error FI;{}   schliesse interface direkt.{}  sende wert an interface:{}    out (kanal [codenummer DIV 256].steuercode);{}    out (code (codenummer)).{}  hole wert von interface:{}    out (kanal [codenummer].steuercode);{}    SELECT kanal [codenummer].taktzahl OF{}      CASE 1 :  antwort := erstes  zeichen{}      CASE 2 :  antwort := zweites zeichen{}      CASE 3 :  antwort := drittes zeichen{}
+      OTHERWISE antwort := -1{}    END SELECT.{}    erstes zeichen:{}      code (incharety (1)).{}    zweites zeichen:{}      dummy := incharety (1);{}      code (incharety (1)).{}    drittes zeichen:{}      dummy := incharety (1);{}      dummy := incharety (1);{}      code (incharety (1)).{}END PROC kanalkoppler;{}PROC interface kanal (INT CONST kanalnummer):{}  enable stop;{}  IF kanalnummer < 1 OR kanalnummer > 24{}     THEN errorstop ("Unzulaessige Kanalnummer"){}     ELSE interface channel := kanalnummer{}
+  FI{}END PROC interface kanal;{}INT PROC interface kanal:{}  interface channel{}END PROC interface kanal;{}PROC oeffne interface direkt (INT VAR status):{}  leere puffer;{}  out (interface test code);{}  IF antwort <> ""{}     THEN status := 0;{}          out (interface open code){}     ELSE status := interface error code{}  FI.{}  leere puffer:{}    REP  UNTIL incharety = "" PER.{}  antwort: incharety (1).{}END PROC oeffne interface direkt;{}PROC schliesse interface direkt:{}  out (interface close code){}
+END PROC schliesse interface direkt;{}PROC initialisiere interface direkt:{}  schalte alles aus.{}  schalte alles aus:{}    INT VAR kanalnummer, kanalbetriebsart;{}    FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{}        kanalbetriebsart := kanal [kanalnummer].betriebsart;{}        IF   kanalbetriebsart = digital aus{}             THEN direkt ausgeben (kanalnummer, 0){}        ELIF kanalbetriebsart = analog aus{}             THEN direkt ausgeben (kanalnummer, gewandelte nullspannung){}        FI{}
+    PER.{}  gewandelte nullspannung:{}    int(- real (ganzzahl obergrenze) * u min / (u max - u min) + 0.5).{}    u max :  spannung [kanalnummer].maximalwert.{}    u min :  spannung [kanalnummer].minimalwert.{}END PROC initialisiere interface direkt;{}PROC direkt ausgeben (INT CONST kanalnummer, wert):{} out (kanal [kanalnummer].steuercode);{} out (code (wert)){}END PROC direkt ausgeben;{}INT PROC direkt eingabe (INT CONST kanalnummer):{}  gib lesecode aus;{}  erhaltene antwort.{}  gib lesecode aus:{}
+    out (kanal [kanalnummer].steuercode).{}  erhaltene antwort:{}    TEXT VAR dummy;{}    SELECT kanal [kanalnummer].taktzahl OF{}      CASE 1 :  erstes  zeichen{}      CASE 2 :  zweites zeichen{}      CASE 3 :  drittes zeichen{}      OTHERWISE -1{}    END SELECT.{}    erstes zeichen:{}      code (incharety (1)).{}    zweites zeichen:{}      dummy := incharety (1);{}      code (incharety (1)).{}    drittes zeichen:{}      dummy := incharety (1);{}      dummy := incharety (1);{}      code (incharety (1)).{}
+END PROC direkt eingabe;{}PROC initialisiere die kanaele:{}  INT VAR kanalnummer;{}  FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{}      trage kanaldaten ein (kanalnummer, keine spannung, leere karte);{}      vorherige ausgabe [kanalnummer] := 0{}  PER.{}  keine spannung:{}    ROW 2 REAL : (0.0, 0.0).{}  leere karte:{}    ROW 3 INT : (nicht belegt, 0, 0).{}END PROC initialisiere die kanaele;{}initialisiere die kanaele;{}END PACKET ls prozess 1{}
+
diff --git "a/prozess/ls-Prozess 1 f\303\274r MUFI als Endger\303\244t" "b/prozess/ls-Prozess 1 f\303\274r MUFI als Endger\303\244t"
new file mode 100644
index 0000000..4d2a5f4
--- /dev/null
+++ "b/prozess/ls-Prozess 1 f\303\274r MUFI als Endger\303\244t"	
@@ -0,0 +1,57 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                     ls-Prozess 1                     ** 
+         **                                                      ** 
+         **           Anpassung für  MUFI als Endgerät           ** 
+         **                                                      ** 
+         **                     Version 1.02                     ** 
+         **                                                      ** 
+         **                  (Stand : 26.01.90)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **         Autoren: Bruno Pollok, Bielefeld             ** 
+         **                  Wolfgang Weber, Bielefeld           ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls prozess 1 DEFINES 
+       run pdv,{}       run pdv again,{}       initialisiere interface,{}       schalte alles aus,{}       ausgeben,{}       eingabe,{}       warte,{}       abbruch gewuenscht,{}       tue nichts,{}       trage kanaldaten ein,{}       beende kanaldaten eintragen,{}       hole spannungsbereich,{}       letzte ausgabe,{}       pruefe kanal,{}       pruefe abbruch,{}       teste interface,{}       oeffne interface,{}       schliesse interface,{}       nicht belegt,{}       digital aus,{}       analog aus,{}
+       digital ein,{}       analog ein,{}       kanalbreite,{}       ganzzahl obergrenze,{}       adapterart,{}    (* ------------------------- *){}       kanalkoppler,{}       interface kanal,{}       oeffne interface direkt,{}       schliesse interface direkt,{}       initialisiere interface direkt,{}       direkt ausgeben,{}       direkt eingabe:{}(******************** A N P A S S U N G  A N  M U F I ********************){}LET interface test  code = ""27""27"10",{}    interface okay  code = ""27""27"00",{}
+    interface open  code = ""27""27"1A18",{}    interface close code = ""25""27""27"13",{}    adresse 0 code       = ""61"",{}    leertakt  code       = ""62"",{}    interface write code =   80  ,{}    interface read  code =   64  ,{}    erwartete zeichen    =    4  ;{}TEXT CONST adapterart   :: "MUFI als Endgerät";{}TEXT PROC interface anpassung (INT CONST kanalnummer, steuerungscode):{}  IF   es ist ein ausgabekanal{}       THEN code (interface write code + device + 4 * steuerungscode){}  ELIF es ist ein eingabekanal{}
+       THEN lesecode in abhaengigkeit von der taktzahl{}       ELSE ""{}  FI.{}  es ist ein ausgabekanal:{}    kanal [kanalnummer].betriebsart < 0.{}  es ist ein eingabekanal:{}    kanal [kanalnummer].betriebsart > 0.{}  device:{}    IF kanalnummer < 10{}       THEN 0{}       ELSE kanalnummer DIV 10  -  1{}    FI.{}  lesecode in abhaengigkeit von der taktzahl:{}    SELECT kanal [kanalnummer].taktzahl OF{}      CASE 1: lesecode{}      CASE 2: adresse 0 code + lesecode + lesecode{}      CASE 3: adresse 0 code + lesecode + zwei weitere takte{}
+    OTHERWISE "" END SELECT.{}  lesecode  :  code (interface read code + device + 4 * steuerungscode).{}  zwei weitere takte:{}    IF leertakt code = ""{}       THEN lesecode + lesecode{}       ELSE kanal [kanalnummer].taktzahl DECR 1;{}            leertakt code + lesecode{}    FI.{}END PROC interface anpassung;{}(************ H A R D W A R E U N A B H Ä N G I G E R  T E I L ************){}LET       max kanalanzahl          =   49,{}          initcode                 =   50,{}          endcode                  =   51,{}
+          alles aus code           =   52,{}          endezeichen              =  "q",{}          abbruchzeichen           =  "h",{}          esc                      =  ""27"";{}INT CONST analog aus               ::  -2,            (* Betriebsarten *){}          digital aus              ::  -1,{}          nicht belegt             ::   0,{}          digital ein              ::   1,{}          analog  ein              ::   2,{}          kanalbreite              ::   8,{}          ganzzahl obergrenze      ::   2 ** kanalbreite,{}
+          configuration error code ::  -1,{}          kanal besetzt code       ::  -3,{}          interface error code     ::  -4,{}          not init code            ::  -5;{}INT VAR   interfacechannel         ::   2,{}          dummy;{}TEXT VAR  meldung                  ::  "";{}BOOL VAR  kanaldaten sind eingetragen :: FALSE,{}          endezeichen gegeben         :: FALSE,{}          programm mit pdv gestartet  :: FALSE,{}          fehler zu melden            :: FALSE;{}TASK VAR  interface task              :: niltask;{}
+DATASPACE VAR  ds :: nilspace;{}TYPE KANAL     = STRUCT (INT  betriebsart, taktzahl, TEXT steuercode),{}     SPANNUNG  = STRUCT (REAL minimalwert, maximalwert);{}ROW max kanalanzahl INT      VAR vorherige ausgabe;{}ROW max kanalanzahl KANAL    VAR kanal;{}ROW max kanalanzahl SPANNUNG VAR spannung;{}ROW 5 TEXT CONST fehlermeldung :: ROW 5 TEXT :{}  ("Interface ist noch nicht konfiguriert!",{}   "Interface-Task ist besetzt!",{}   "Interface-Kanal ist belegt!",{}   "Interface meldet sich nicht!",{}   "Interface kann nicht geöffnet werden!");{}
+PROC run pdv:{}  run pdv (last param){}END PROC run pdv;{}PROC run pdv (TEXT CONST programmname):{}  enable stop;{}  last param (programmname);{}  programm mit pdv gestartet := TRUE;{}  teste interface;{}  disable stop;{}  run (programmname);{}  IF is error{}     THEN fehlerbehandlung{}     ELSE melde programmende{}  FI;{}  schliesse interface;{}  programm mit pdv gestartet := FALSE;{}  enable stop;{}  IF fehler zu melden{}     THEN errorstop (meldung){}  FI{}END PROC run pdv;{}PROC run pdv again:{}
+  enable stop;{}  programm mit pdv gestartet := TRUE;{}  teste interface;{}  disable stop;{}  run again;{}  IF is error{}     THEN fehlerbehandlung{}     ELSE melde programmende{}  FI;{}  schliesse interface;{}  programm mit pdv gestartet := FALSE;{}  enable stop;{}  IF fehler zu melden{}     THEN errorstop (meldung){}  FI{}END PROC run pdv again;{}PROC melde programmende:{}  page;{}  menufootnote ("Programmende! Zum Weitermachen bitte irgendeine Taste tippen.");{}  pause;{}  schalte alles aus{}END PROC melde programmende;{}
+PROC initialisiere interface:{}  enable stop;{}  pruefe abbruch;{}  IF programm mit pdv gestartet{}     THEN schalte alles aus{}     ELSE errorstop ("PDV-Programme müssen mit 'run pdv' gestartet werden!"){}  FI{}END PROC initialisiere interface;{}PROC schalte alles aus:{}  INT VAR k;{}  FOR k FROM 1 UPTO max kanalanzahl REP{}    vorherige ausgabe [k] := 0{}  PER;{}  forget (ds); ds := nilspace;{}  call (interface task, alles aus code, ds, dummy){}END PROC schalte alles aus;{}PROC ausgeben (INT CONST kanalnummer, wert):{}
+  merke wert;{}  gib wert aus.{}  merke wert:{}    vorherige ausgabe [kanalnummer] := wert.{}  gib wert aus:{}    call (interface task, 256 * kanalnummer + wert, ds, dummy).{}END PROC ausgeben;{}INT PROC eingabe (INT CONST kanalnummer):{}  INT VAR eingabewert;{}  call (interface task, kanalnummer, ds, eingabewert);{}  eingabewert{}END PROC eingabe;{}PROC warte (REAL CONST sekunden):{}  TEXT VAR eingabe;{}  pruefe abbruch;{}  eingabe := incharety (int (sekunden * 10.0 + 0.5));{}  IF eingabe = esc{}
+     THEN untersuche naechstes zeichen{}  FI.{}  untersuche naechstes zeichen:{}    eingabe := incharety (30);{}    IF   eingabe = endezeichen{}         THEN endezeichen gegeben := TRUE{}    ELIF eingabe = abbruchzeichen{}         THEN errorstop ("Programm-Abbruch durch <ESC><"{}                             + abbruchzeichen + ">!"){}    FI.{}END PROC warte;{}PROC warte (INT CONST sekunden):{}  TEXT VAR eingabe;{}  pruefe abbruch;{}  eingabe := incharety (sekunden * 10);{}  IF eingabe = esc{}     THEN untersuche naechstes zeichen{}
+  FI.{}  untersuche naechstes zeichen:{}    eingabe := incharety (30);{}    IF   eingabe = endezeichen{}         THEN endezeichen gegeben := TRUE{}    ELIF eingabe = abbruchzeichen{}         THEN errorstop ("Programm-Abbruch durch <ESC><"{}                             + abbruchzeichen + ">!"){}    FI.{}END PROC warte;{}BOOL PROC abbruch gewuenscht:{}  pruefe abbruch;{}  BOOL VAR entscheidung :: endezeichen gegeben;{}  endezeichen gegeben := FALSE;{}  entscheidung{}END PROC abbruch gewuenscht;{}PROC tue nichts:{}
+  pruefe abbruch{}END PROC tue nichts;{}PROC trage kanaldaten ein (INT CONST  kanalnummer,{}                           ROW 2 REAL CONST spannungsbereich,{}                           ROW 3 INT  CONST kanalparameter):{}   spannung [kanalnummer].minimalwert := spannungsbereich [1];{}   spannung [kanalnummer].maximalwert := spannungsbereich [2];{}   kanal [kanalnummer].betriebsart    := kanalparameter   [1];{}   kanal [kanalnummer].taktzahl       := kanalparameter   [2];{}   kanal [kanalnummer].steuercode     := interface anpassung{}
+                                         (kanalnummer, kanalparameter [3]){}END PROC trage kanaldaten ein;{}PROC beende kanaldaten eintragen:{}  loesche interface task;{}  begin (PROC kanal koppler, interface task);{}  kanaldaten sind eingetragen := TRUE.{}  loesche interface task:{}    disable stop;{}    end (interface task);{}    IF is error{}       THEN clear error{}    FI;{}    enable stop.{}END PROC beende kanaldaten eintragen;{}PROC hole spannungsbereich (INT CONST kanalnummer, REAL VAR  u min, u max):{}
+  u min := spannung [kanalnummer].minimalwert;{}  u max := spannung [kanalnummer].maximalwert{}END PROC hole spannungsbereich;{}INT PROC letzte ausgabe (INT CONST kanalnummer):{}  vorherige ausgabe [kanalnummer]{}END PROC letzte ausgabe;{}PROC pruefe kanal (INT CONST kanalnummer, gewuenschte betriebsart):{}  pruefe abbruch;{}  pruefe kanalnummer;{}  pruefe betriebsart.{}  pruefe kanalnummer:{}    IF kanalnummer < 1 OR kanalnummer > max kanalanzahl{}       THEN errorstop ("Kanalnummer " + text (kanalnummer) +{}
+                        " ist unzulaessig !"){}    FI.{}  pruefe betriebsart:{}    IF gewuenschte betriebsart <> kanal [kanalnummer].betriebsart{}       THEN errorstop ("An Kanal " + text (kanalnummer) +{}                          " keine " +  wunsch + " moeglich!"){}    FI.{}  wunsch:{}    IF   gewuenschte betriebsart = analog aus{}         THEN "Analog-Ausgabe"{}    ELIF gewuenschte betriebsart = digital aus{}         THEN "Digital-Ausgabe"{}    ELIF gewuenschte betriebsart = digital ein{}         THEN "Digital-Eingabe"{}
+    ELIF gewuenschte betriebsart = analog ein{}         THEN "Analog-Eingabe"{}         ELSE "Ein- oder Ausgabe"{}    FI.{}END PROC pruefe kanal;{}PROC pruefe abbruch:{}  IF incharety = esc{}     THEN pruefe weiter{}  FI.{}  pruefe weiter:{}    TEXT CONST zeichen :: incharety (30);{}    IF   zeichen = endezeichen{}         THEN endezeichen gegeben := TRUE{}    ELIF zeichen = abbruchzeichen{}         THEN errorstop ("Programm-Abbruch durch <ESC><"{}                             + abbruchzeichen + ">!"){}
+    FI.{}END PROC pruefe abbruch;{}PROC oeffne interface (INT VAR status):{}  enable stop;{}  forget (ds); ds := nilspace;{}  IF kanaldaten sind eingetragen{}     THEN pingpong (interfacetask, initcode, ds, status){}     ELSE status := configuration error code{}  FI;{}  IF status > 0 THEN status DECR maxint FI;{}  forget (ds); ds := nilspace{}END PROC oeffne interface;{}PROC schliesse interface:{}  enable stop;{}  forget (ds); ds := nilspace;{}  pingpong (interface task, end code, ds, dummy);{}  forget (ds); ds := nilspace{}
+END PROC schliesse interface;{}PROC teste interface:{}  INT VAR test;{}  oeffne interface (test);{}  IF test < 0{}     THEN errorstop (fehlermeldung [min (5, abs (test))]){}     ELSE fehler zu melden           := FALSE;{}          endezeichen gegeben        := FALSE{}  FI{}END PROC teste interface;{}PROC fehlerbehandlung:{}  meldung := errormessage;{}  IF meldung <> ""{}     THEN meldung CAT fehlerzeile;{}          fehler zu melden := TRUE{}  FI;{}  clear error;{}  initialisiere interface.{}  fehlerzeile:{}
+    IF errorline = 0{}       THEN ""{}       ELSE " (bei Zeile " + text (errorline) + ")"{}    FI.{}END PROC fehlerbehandlung;{}(********************  EIN-/AUSGABE AM INTERFACE-KANAL ********************){}PROC kanalkoppler:{}  IF name (myself) <> "-"{}     THEN errorstop ("Unzulässiges Kommando!"){}     ELSE warte auf anrufe{}  FI.{}  warte auf anrufe:{}    TASK      VAR absender;{}    TEXT      VAR dummy;{}    INT       VAR codenummer, antwort;{}    disable stop;{}    REP forget (ds);{}        wait (ds, codenummer, absender);{}
+        IF codenummer = initcode{}           THEN kopple an interface kanal;{}                IF interface ist betriebsbereit{}                   THEN bearbeite weitere auftraege{}                   ELSE gib negative rueckmeldung{}                FI;{}                gib kanal frei{}           ELSE antwort := not init code;{}                gib negative rueckmeldung{}        FI{}    PER.{} kopple an interface kanal:{}  continue (interface channel);{}  IF is error{}     THEN clear error;{}          antwort := kanal besetzt code{}
+     ELSE oeffne interface direkt (antwort){}  FI.{} interface ist betriebsbereit:  antwort = 0.{} gib negative rueckmeldung:     send (absender, antwort, ds).{} gib kanal frei:{}   break (quiet);{}   send  (absender, 0, ds, antwort);{}   collect heap garbage.{} bearbeite weitere auftraege:{}   REP   call (absender, antwort, ds, codenummer);{}         IF   codenummer > 255{}              THEN sende wert an interface{}         ELIF codenummer <  50{}              THEN hole wert von interface{}         ELIF codenummer = alles aus code{}
+              THEN initialisiere interface direkt{}         FI{}   UNTIL codenummer = endcode PER;{}   IF is error THEN clear error FI;{}   schliesse interface direkt.{}  sende wert an interface:{}    out (kanal [codenummer DIV 256].steuercode);{}    out (code (codenummer)).{}  hole wert von interface:{}    out (kanal [codenummer].steuercode);{}    SELECT kanal [codenummer].taktzahl OF{}      CASE 1 :  antwort := erstes  zeichen{}      CASE 2 :  antwort := zweites zeichen{}      CASE 3 :  antwort := drittes zeichen{}
+      OTHERWISE antwort := -1{}    END SELECT.{}    erstes zeichen:{}      code (incharety (1)).{}    zweites zeichen:{}      dummy := incharety (1);{}      code (incharety (1)).{}    drittes zeichen:{}      dummy := incharety (1);{}      dummy := incharety (1);{}      code (incharety (1)).{}END PROC kanalkoppler;{}PROC interface kanal (INT CONST kanalnummer):{}  enable stop;{}  IF kanalnummer < 1 OR kanalnummer > 24{}     THEN errorstop ("Unzulaessige Kanalnummer"){}     ELSE interface channel := kanalnummer{}
+  FI{}END PROC interface kanal;{}INT PROC interface kanal:{}  interface channel{}END PROC interface kanal;{}PROC oeffne interface direkt (INT VAR status):{}  leere puffer;{}  out (interface test code);{}  fange antwort;{}  IF antwort = interface okay code{}     THEN status := 0;{}          out (interface open code){}     ELSE status := interface error code{}  FI.{}  leere puffer:{}    REP  UNTIL incharety = "" PER.{}  fange antwort:{}    INT  VAR zaehler;{}    TEXT VAR antwort :: "";{}    FOR zaehler FROM 1 UPTO erwartete zeichen REP{}
+      antwort CAT incharety (1){}    PER.{}END PROC oeffne interface direkt;{}PROC schliesse interface direkt:{}  out (interface close code){}END PROC schliesse interface direkt;{}PROC initialisiere interface direkt:{}  schalte alles aus.{}  schalte alles aus:{}    INT VAR kanalnummer, kanalbetriebsart;{}    FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{}        kanalbetriebsart := kanal [kanalnummer].betriebsart;{}        IF   kanalbetriebsart = digital aus{}             THEN direkt ausgeben (kanalnummer, 0){}
+        ELIF kanalbetriebsart = analog aus{}             THEN direkt ausgeben (kanalnummer, gewandelte nullspannung){}        FI{}    PER.{}  gewandelte nullspannung:{}    int(- real (ganzzahl obergrenze) * u min / (u max - u min) + 0.5).{}    u max :  spannung [kanalnummer].maximalwert.{}    u min :  spannung [kanalnummer].minimalwert.{}END PROC initialisiere interface direkt;{}PROC direkt ausgeben (INT CONST kanalnummer, wert):{} out (kanal [kanalnummer].steuercode);{} out (code (wert)){}END PROC direkt ausgeben;{}
+INT PROC direkt eingabe (INT CONST kanalnummer):{}  gib lesecode aus;{}  erhaltene antwort.{}  gib lesecode aus:{}    out (kanal [kanalnummer].steuercode).{}  erhaltene antwort:{}    TEXT VAR dummy;{}    SELECT kanal [kanalnummer].taktzahl OF{}      CASE 1 :  erstes  zeichen{}      CASE 2 :  zweites zeichen{}      CASE 3 :  drittes zeichen{}      OTHERWISE -1{}    END SELECT.{}    erstes zeichen:{}      code (incharety (1)).{}    zweites zeichen:{}      dummy := incharety (1);{}      code (incharety (1)).{}
+    drittes zeichen:{}      dummy := incharety (1);{}      dummy := incharety (1);{}      code (incharety (1)).{}END PROC direkt eingabe;{}PROC initialisiere die kanaele:{}  INT VAR kanalnummer;{}  FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{}      trage kanaldaten ein (kanalnummer, keine spannung, leere karte);{}      vorherige ausgabe [kanalnummer] := 0{}  PER.{}  keine spannung:{}    ROW 2 REAL : (0.0, 0.0).{}  leere karte:{}    ROW 3 INT : (nicht belegt, 0, 0).{}END PROC initialisiere die kanaele;{}
+initialisiere die kanaele;{}END PACKET ls prozess 1{}
+
diff --git "a/prozess/ls-Prozess 1 f\303\274r MUFI im Terminalkanal" "b/prozess/ls-Prozess 1 f\303\274r MUFI im Terminalkanal"
new file mode 100644
index 0000000..d1edbc1
--- /dev/null
+++ "b/prozess/ls-Prozess 1 f\303\274r MUFI im Terminalkanal"	
@@ -0,0 +1,55 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                     ls-Prozess 1                     ** 
+         **                                                      ** 
+         **         Anpassung für  MUFI im Terminalkanal         ** 
+         **                                                      ** 
+         **                     Version 1.02                     ** 
+         **                                                      ** 
+         **                  (Stand : 26.01.90)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **         Autoren: Bruno Pollok, Bielefeld             ** 
+         **                  Wolfgang Weber, Bielefeld           ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET altes incharety DEFINES old incharety: 
+TEXT PROC old incharety:{}  incharety{}END PROC old incharety;{}TEXT PROC old incharety (INT CONST timelimit):{}  incharety (timelimit){}END PROC old incharety;{}END PACKET altes incharety;{}PACKET ls prozess 1 DEFINES{}       run pdv,{}       run pdv again,{}       initialisiere interface,{}       ausgeben,{}       eingabe,{}       warte,{}       abbruch gewuenscht,{}       tue nichts,{}       trage kanaldaten ein,{}       beende kanaldaten eintragen,{}       hole spannungsbereich,{}       letzte ausgabe,{}
+       pruefe kanal,{}       pruefe abbruch,{}       teste interface,{}      schalte alles aus,{}       oeffne interface,{}       schliesse interface,{}       nicht belegt,{}       digital aus,{}       analog aus,{}       digital ein,{}       analog ein,{}       kanalbreite,{}       ganzzahl obergrenze,{}       adapterart,{}       incharety,{}       inchar,{}       pause:{}(******************** A N P A S S U N G  A N  M U F I ********************){}LET mufikennung       = ""31""31"",{}    erwartete zeichen =        4  ;{}
+TEXT CONST adapterart           :: "MUFI im Terminalkanal",{}           interface test  code :: ""27""27"10",{}           interface okay  code :: ""27""27"00",{}           interface open  code :: ""27""27"1C" + hex (mufikennung),{}           interface close code :: mufikennung  + "1C" + hex (""27""27""),{}           adresse 0 code       :: mufikennung + "3D",{}           leertakt  code       :: mufikennung + "3E",{}           interface write code :: mufikennung + "5" ,{}           interface read  code :: mufikennung + "4" ;{}
+TEXT VAR   puffer :: "";{}ROW 256 TEXT CONST hexcode :: ROW 256 TEXT : ({}"00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",{}"10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",{}"20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",{}"30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",{}"40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",{}"50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",{}
+"60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",{}"70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",{}"80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",{}"90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",{}"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",{}"B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",{}"C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",{}
+"D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",{}"E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",{}"F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF");{}TEXT PROC interface anpassung (INT CONST kanalnummer, steuerungscode):{}  LET  hexzeichen = "0123456789ABCDEF";{}  IF   es ist ein ausgabekanal{}       THEN interface write code{}            + (hexzeichen SUB (device + 4 * steuerungscode)){}  ELIF es ist ein eingabekanal{}
+       THEN lesecode in abhaengigkeit von der taktzahl{}       ELSE ""{}  FI.{}  es ist ein ausgabekanal:{}    kanal [kanalnummer].betriebsart < 0.{}  es ist ein eingabekanal:{}    kanal [kanalnummer].betriebsart > 0.{}  device:{}    IF kanalnummer < 10{}       THEN 1{}       ELSE kanalnummer DIV 10{}    FI.{}  lesecode in abhaengigkeit von der taktzahl:{}    SELECT kanal [kanalnummer].taktzahl OF{}      CASE 1: lesecode{}      CASE 2: adresse 0 code + lesecode + lesecode{}      CASE 3: adresse 0 code + lesecode + zwei weitere takte{}
+    OTHERWISE "" END SELECT.{}  lesecode:{}    interface read code + (hexzeichen SUB (device + 4 * steuerungscode)).{}  zwei weitere takte:{}    IF leertakt code = ""{}       THEN lesecode + lesecode{}       ELSE kanal [kanalnummer].taktzahl DECR 1;{}            leertakt code + lesecode{}    FI.{}END PROC interface anpassung;{}PROC ausgeben (INT CONST kanalnummer, wert):{}  merke wert;{}  gib wert aus.{}  merke wert:{}   vorherige ausgabe [kanalnummer] := wert.{}  gib wert aus:{}    out (kanal [kanalnummer].steuercode);{}
+    out (hexcode [wert + 1]).{}END PROC ausgeben;{}INT PROC eingabe (INT CONST kanalnummer):{}  gib lesecode aus;{}  erhaltene antwort.{}  gib lesecode aus:{}    out (kanal [kanalnummer].steuercode).{}  erhaltene antwort:{}    TEXT VAR dummy;{}    SELECT kanal [kanalnummer].taktzahl OF{}      CASE 1 :  erste  sendung{}      CASE 2 :  zweite sendung{}      CASE 3 :  dritte sendung{}      OTHERWISE -1{}    END SELECT.{}    erste sendung:{}      fange mufikennung;{}      dezimalwert (old incharety (1), old incharety (1)).{}
+    zweite sendung:{}      fange mufikennung;{}      dummy := old incharety (1);{}      dummy := old incharety (1);{}      erste sendung.{}    dritte sendung:{}      fange mufikennung;{}      dummy := old incharety (1);{}      dummy := old incharety (1);{}      zweite sendung.{}    fange mufikennung:{}      puffer CAT old incharety;{}      REP puffer CAT old incharety{}      UNTIL pos (puffer, mufikennung) > 0 PER;{}      puffer := subtext (puffer, 1, length (puffer) - 2).{}END PROC eingabe;{}(************ H A R D W A R E U N A B H Ä N G I G E R  T E I L ************){}
+LET       max kanalanzahl          =   49,{}          endezeichen              =  "q",{}          abbruchzeichen           =  "h",{}          esc                      =  ""27"";{}INT CONST analog aus               ::  -2,            (* Betriebsarten *){}          digital aus              ::  -1,{}          nicht belegt             ::   0,{}          digital ein              ::   1,{}          analog  ein              ::   2,{}          kanalbreite              ::   8,{}          ganzzahl obergrenze      ::   2 ** kanalbreite,{}
+          configuration error code ::  -1,{}          interface error code     ::  -4;{}TEXT VAR  meldung                  ::  "";{}BOOL VAR  kanaldaten sind eingetragen :: FALSE,{}          endezeichen gegeben         :: FALSE,{}          programm mit pdv gestartet  :: FALSE,{}          fehler zu melden            :: FALSE;{}TYPE KANAL     = STRUCT (INT  betriebsart, taktzahl, TEXT steuercode),{}     SPANNUNG  = STRUCT (REAL minimalwert, maximalwert);{}ROW max kanalanzahl INT      VAR vorherige ausgabe;{}
+ROW max kanalanzahl KANAL    VAR kanal;{}ROW max kanalanzahl SPANNUNG VAR spannung;{}PROC run pdv:{}  run pdv (last param){}END PROC run pdv;{}PROC run pdv (TEXT CONST programmname):{}  enable stop;{}  last param (programmname);{}  programm mit pdv gestartet := TRUE;{}  teste interface;{}  disable stop;{}  run (programmname);{}  IF is error{}     THEN fehlerbehandlung{}     ELSE melde programmende{}  FI;{}  schliesse interface;{}  programm mit pdv gestartet := FALSE;{}  enable stop;{}  IF fehler zu melden{}
+     THEN errorstop (meldung){}  FI{}END PROC run pdv;{}PROC run pdv again:{}  enable stop;{}  programm mit pdv gestartet := TRUE;{}  teste interface;{}  disable stop;{}  run again;{}  IF is error{}     THEN fehlerbehandlung{}     ELSE melde programmende{}  FI;{}  schliesse interface;{}  programm mit pdv gestartet := FALSE;{}  enable stop;{}  IF fehler zu melden{}     THEN errorstop (meldung){}  FI{}END PROC run pdv again;{}PROC melde programmende:{}  page;{}  menufootnote ("Programmende! Zum Weitermachen bitte irgendeine Taste tippen.");{}
+  pause;{}  schalte alles aus{}END PROC melde programmende;{}PROC initialisiere interface:{}  enable stop;{}  pruefe abbruch;{}  IF programm mit pdv gestartet{}     THEN schalte alles aus{}     ELSE errorstop ("PDV-Programme müssen mit 'run pdv' gestartet werden!"){}  FI{}END PROC initialisiere interface;{}PROC schalte alles aus:{}  INT VAR kanalnummer, kanalbetriebsart;{}  FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{}      kanalbetriebsart := kanal [kanalnummer].betriebsart;{}      IF   kanalbetriebsart = digital aus{}
+           THEN ausgeben (kanalnummer, 0){}      ELIF kanalbetriebsart = analog aus{}           THEN ausgeben (kanalnummer, gewandelte nullspannung){}      FI{}  PER.{}  gewandelte nullspannung:{}    int(- real (ganzzahl obergrenze) * u min / (u max - u min) + 0.5).{}    u max :  spannung [kanalnummer].maximalwert.{}    u min :  spannung [kanalnummer].minimalwert.{}END PROC schalte alles aus;{}PROC warte (REAL CONST sekunden):{}  TEXT VAR eingabe;{}  pruefe abbruch;{}  eingabe := incharety (int (sekunden * 10.0 + 0.5));{}
+  IF eingabe = esc{}     THEN untersuche naechstes zeichen{}  FI.{}  untersuche naechstes zeichen:{}    eingabe := incharety (30);{}    IF   eingabe = endezeichen{}         THEN endezeichen gegeben := TRUE{}    ELIF eingabe = abbruchzeichen{}         THEN errorstop ("Programm-Abbruch durch <ESC><"{}                             + abbruchzeichen + ">!"){}    FI.{}END PROC warte;{}PROC warte (INT CONST sekunden):{}  TEXT VAR eingabe;{}  pruefe abbruch;{}  eingabe := incharety (sekunden * 10);{}  IF eingabe = esc{}
+     THEN untersuche naechstes zeichen{}  FI.{}  untersuche naechstes zeichen:{}    eingabe := incharety (30);{}    IF   eingabe = endezeichen{}         THEN endezeichen gegeben := TRUE{}    ELIF eingabe = abbruchzeichen{}         THEN errorstop ("Programm-Abbruch durch <ESC><"{}                             + abbruchzeichen + ">!"){}    FI.{}END PROC warte;{}TEXT PROC incharety:{}  IF puffer = ""{}     THEN old incharety{}     ELSE erstes zeichen von puffer{}  FI.{}  erstes zeichen von puffer:{}    TEXT CONST zeichen :: puffer SUB 1;{}
+    puffer := subtext (puffer, 2);{}    zeichen.{}END PROC incharety;{}TEXT PROC incharety (INT CONST timelimit):{}  IF puffer = ""{}     THEN old incharety (timelimit){}     ELSE erstes zeichen von puffer{}  FI.{}  erstes zeichen von puffer:{}    TEXT CONST zeichen :: puffer SUB 1;{}    puffer := subtext (puffer, 2);{}    zeichen.{}END PROC incharety;{}PROC inchar (TEXT VAR character):{}  REP character := incharety{}  UNTIL character <> "" PER{}END PROC inchar;{}PROC pause:{}  TEXT VAR dummy;{}  inchar (dummy){}
+END PROC pause;{}PROC pause (INT CONST timelimit):{}  TEXT VAR dummy := incharety (timelimit){}END PROC pause;{}BOOL PROC abbruch gewuenscht:{}  pruefe abbruch;{}  BOOL VAR entscheidung :: endezeichen gegeben;{}  endezeichen gegeben := FALSE;{}  entscheidung{}END PROC abbruch gewuenscht;{}PROC tue nichts:{}  pruefe abbruch{}END PROC tue nichts;{}PROC trage kanaldaten ein (INT CONST  kanalnummer,{}                           ROW 2 REAL CONST spannungsbereich,{}                           ROW 3 INT  CONST kanalparameter):{}
+   spannung [kanalnummer].minimalwert := spannungsbereich [1];{}   spannung [kanalnummer].maximalwert := spannungsbereich [2];{}   kanal [kanalnummer].betriebsart    := kanalparameter   [1];{}   kanal [kanalnummer].taktzahl       := kanalparameter   [2];{}   kanal [kanalnummer].steuercode     := interface anpassung{}                                         (kanalnummer, kanalparameter [3]){}END PROC trage kanaldaten ein;{}PROC beende kanaldaten eintragen:{}  kanaldaten sind eingetragen := TRUE{}END PROC beende kanaldaten eintragen;{}
+PROC hole spannungsbereich (INT CONST kanalnummer, REAL VAR  u min, u max):{}  u min := spannung [kanalnummer].minimalwert;{}  u max := spannung [kanalnummer].maximalwert{}END PROC hole spannungsbereich;{}INT PROC letzte ausgabe (INT CONST kanalnummer):{}  vorherige ausgabe [kanalnummer]{}END PROC letzte ausgabe;{}PROC pruefe kanal (INT CONST kanalnummer, gewuenschte betriebsart):{}  pruefe abbruch;{}  pruefe kanalnummer;{}  pruefe betriebsart.{}  pruefe kanalnummer:{}    IF kanalnummer < 1 OR kanalnummer > max kanalanzahl{}
+       THEN errorstop ("Kanalnummer " + text (kanalnummer) +{}                        " ist unzulaessig !"){}    FI.{}  pruefe betriebsart:{}    IF gewuenschte betriebsart <> kanal [kanalnummer].betriebsart{}       THEN errorstop ("An Kanal " + text (kanalnummer) +{}                          " keine " +  wunsch + " moeglich!"){}    FI.{}  wunsch:{}    IF   gewuenschte betriebsart = analog aus{}         THEN "Analog-Ausgabe"{}    ELIF gewuenschte betriebsart = digital aus{}         THEN "Digital-Ausgabe"{}
+    ELIF gewuenschte betriebsart = digital ein{}         THEN "Digital-Eingabe"{}    ELIF gewuenschte betriebsart = analog ein{}         THEN "Analog-Eingabe"{}         ELSE "Ein- oder Ausgabe"{}    FI.{}END PROC pruefe kanal;{}PROC pruefe abbruch:{}  TEXT VAR zeichen :: incharety;{}  IF zeichen = esc{}     THEN pruefe weiter{}  FI.{}  pruefe weiter:{}    zeichen := incharety (30);{}    IF   zeichen = endezeichen{}         THEN endezeichen gegeben := TRUE{}    ELIF zeichen = abbruchzeichen{}         THEN errorstop ("Programm-Abbruch durch <ESC><"{}
+                             + abbruchzeichen + ">!"){}    FI.{}END PROC pruefe abbruch;{}PROC oeffne interface (INT VAR status):{}  enable stop;{}  IF kanaldaten sind eingetragen{}     THEN teste interface funktion{}     ELSE status := configuration error code{}  FI.{}  teste interface funktion:{}    leere puffer;{}    out (interface test code);{}    fange antwort;{}    IF antwort = interface okay code{}       THEN status := 0;{}            out (interface open code){}       ELSE status := interface error code{}
+    FI.{}  leere puffer:{}    puffer := "";{}    REP  UNTIL old incharety = "" PER.{}  fange antwort:{}    INT  VAR zaehler;{}    TEXT VAR antwort :: "";{}    FOR zaehler FROM 1 UPTO erwartete zeichen REP{}      antwort CAT old incharety (1){}    PER.{}END PROC oeffne interface;{}PROC schliesse interface:{}  enable stop;{}  out (interface close code){}END PROC schliesse interface;{}(*********************  H I L F S P R O Z E D U R E N *********************){}PROC teste interface:{}  INT VAR test;{}
+  warte etwas;{}  oeffne interface (test);{}  IF test < 0{}     THEN errorstop (fehlermeldung){}     ELSE endezeichen gegeben        := FALSE;{}          fehler zu melden           := FALSE{}  FI.{}  warte etwas:{}    pause (1); pause (1); pause (1); pause (1); pause (1).{}  fehlermeldung:{}    IF   test = configuration error code{}         THEN "Interface ist noch nicht konfiguriert!"{}    ELIF test = interface error code{}         THEN "Interface meldet sich nicht!"{}         ELSE "Interface kann nicht geöffnet werden!"{}
+    FI.{}END PROC teste interface;{}PROC fehlerbehandlung:{}  meldung := errormessage;{}  IF meldung <> ""{}     THEN meldung CAT fehlerzeile;{}          fehler zu melden := TRUE{}  FI;{}  clear error;{}  initialisiere interface.{}  fehlerzeile:{}    IF errorline = 0{}       THEN ""{}       ELSE " (bei Zeile " + text (errorline) + ")"{}    FI.{}END PROC fehlerbehandlung;{}INT PROC dezimalwert (TEXT CONST zeichen 1, zeichen 2):{}  16 * pos (hexzeichen, zeichen 1) + pos (hexzeichen, zeichen 2).{}  hexzeichen: "123456789ABCDEF".{}
+END PROC dezimalwert;{}TEXT PROC hex (TEXT CONST zwei zeichen):{}  hex (code (zwei zeichen SUB 1)) + hex (code (zwei zeichen SUB 2)){}END PROC hex;{}TEXT PROC hex (INT CONST wert):{}  (hexzeichen SUB (wert DIV 16 + 1)) + (hexzeichen SUB (wert MOD 16 + 1)).{}  hexzeichen: "0123456789ABCDEF".{}END PROC hex;{}PROC initialisiere die kanaele:{}  INT VAR kanalnummer;{}  FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{}      trage kanaldaten ein (kanalnummer, keine spannung, leere karte);{}      vorherige ausgabe [kanalnummer] := 0{}
+  PER.{}  keine spannung:{}    ROW 2 REAL : (0.0, 0.0).{}  leere karte:{}    ROW 3 INT : (nicht belegt, 0, 0).{}END PROC initialisiere die kanaele;{}initialisiere die kanaele{}END PACKET ls prozess 1{}
+
diff --git a/prozess/ls-Prozess 2 b/prozess/ls-Prozess 2
new file mode 100644
index 0000000..11cb4e7
--- /dev/null
+++ b/prozess/ls-Prozess 2	
@@ -0,0 +1,39 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                     ls-Prozess 2                     ** 
+         **                                                      ** 
+         **                     Version 1.02                     ** 
+         **                                                      ** 
+         **                  (Stand : 06.06.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **         Autoren: Bruno Pollok, Bielefeld             ** 
+         **                  Wolfgang Weber, Bielefeld           ** 
+         **                                                      ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls prozess 2 DEFINES                   
+       wert an analogausgang ausgeben,{}       spannungswert ausgeben,{}       bitsymbol ausgeben,{}       bitmuster ausgeben,{}       dezimalwert ausgeben,{}       bitmuster gleich,{}       bit ist gesetzt,{}       wert von analogeingang,{}       spannungswert,{}       bitsymbol,{}       bitmuster,{}       dezimalwert:{}LET    eins   = "I",{}       null   = "O",{}       invers = "T",{}       egal   = "X";{}REAL CONST maximalwert :: real (ganzzahl obergrenze - 1);{}(********************* A U S G A B E - B E F E H L E *********************){}
+PROC wert an analogausgang ausgeben (INT CONST kanal, wert):{}  pruefe kanal (kanal, analog aus);{}  ausgeben (kanal, wert MOD ganzzahlobergrenze){}END PROC wert an analogausgang ausgeben;{}PROC spannungswert ausgeben (INT  CONST kanal, REAL CONST wert):{}  pruefe kanal (kanal, analog aus);{}  pruefe spannungswert;{}  ausgeben (kanal, gewandelte spannung).{}  pruefe spannungswert:{}    REAL VAR u min, u max;{}    hole spannungsbereich (kanal, u min, u max);{}    IF wert < u min OR wert > u max{}       THEN errorstop ("Der Spannungswert " + text (wert) +{}
+                       " ist nicht zulaessig!"){}    FI.{}  gewandelte spannung:{}    int (((wert - u min) * maximalwert) / (u max - u min) + 0.5).{}END PROC spannungswert ausgeben;{}PROC bitsymbol ausgeben (INT  CONST kanal, bitnummer, TEXT CONST zeichen):{}  pruefe kanal (kanal, digital aus);{}  pruefe bitnummer (bitnummer);{}  ausgeben (kanal, relativer dezimalwert (zeichen, bitnummer, kanal)){}END PROC bitsymbol ausgeben;{}PROC bitmuster ausgeben (INT  CONST kanal, TEXT CONST zeichenkette):{}
+  pruefe kanal (kanal, digital aus);{}  ausgeben (kanal, relativer dezimalwert (zeichenkette, kanal)){}END PROC bitmuster ausgeben;{}PROC dezimalwert ausgeben (INT CONST kanal, wert):{}  pruefe kanal (kanal, digital aus);{}  ausgeben (kanal, wert MOD ganzzahl obergrenze){}END PROC dezimalwert ausgeben;{}(********************* E I N G A B E - B E F E H L E *********************){}BOOL PROC bitmuster gleich (INT CONST kanal, TEXT CONST zeichenkette):{}  INT CONST eingabewert :: dezimalwert (kanal);{}
+  pruefe zeichenkette;{}  eingabe passt zur zeichenkette.{}  pruefe zeichenkette:{}    IF length (zeichenkette) <> kanalbreite{}       THEN errorstop ("Das Bitmuster '" + zeichenkette +{}                       "' hat eine unzulaessige Laenge!"){}    FI.{}  eingabe passt zur zeichenkette:{}   INT VAR stelle;{}   BOOL VAR abweichung gefunden :: FALSE;{}   FOR stelle FROM 1 UPTO kanalbreite REP{}     teste bit an dieser stelle{}   UNTIL abweichung gefunden PER;{}   NOT abweichung gefunden.{} teste bit an dieser stelle:{}
+   TEXT CONST einzelbit :: zeichenkette SUB stelle;{}   IF   einzelbit = eins{}        THEN teste eingabebit auf eins{}   ELIF einzelbit = null{}        THEN teste eingabebit auf null{}   ELIF einzelbit = egal{}        THEN eingabebit ist beliebig{}   ELSE errorstop ("'" + einzelbit + "' ist unzulaessiges " +{}                   "Bitsymbol in '" + zeichenkette + "'!"){}   FI.{} teste eingabebit auf eins:{}   IF NOT bit (eingabewert, kanalbreite - stelle){}      THEN abweichung gefunden := TRUE{}   FI.{}
+ teste eingabebit auf null:{}   IF bit (eingabewert, kanalbreite - stelle){}      THEN abweichung gefunden := TRUE{}   FI.{} eingabebit ist beliebig:{}   .{}END PROC bitmuster gleich;{}BOOL PROC bit ist gesetzt (INT CONST kanal, bitnummer):{}  pruefe kanal (kanal, digital ein);{}  pruefe bitnummer (bitnummer);{}  IF bit (eingabe (kanal), bitnummer){}     THEN TRUE{}     ELSE FALSE{}  FI{}END PROC bit ist gesetzt;{}INT PROC wert von analogeingang (INT CONST kanal):{}  pruefe kanal (kanal, analog ein);{}
+  eingabe (kanal){}END PROC wert von analogeingang;{}REAL PROC spannungswert (INT CONST kanal):{}  INT CONST dezimalwert :: wert von analogeingang (kanal);{}  REAL  VAR u min, u max;{}  hole spannungsbereich (kanal, u min, u max);{}  round (real (dezimalwert) * (u max - u min) / maximalwert + u min, 3){}END PROC spannungswert;{}TEXT PROC bitsymbol (INT CONST kanal, bitnummer):{}  pruefe kanal (kanal, digital ein);{}  pruefe bitnummer (bitnummer);{}  IF bit (eingabe (kanal), bitnummer){}     THEN eins{}
+     ELSE null{}  FI{}END PROC bitsymbol;{}TEXT PROC bitmuster (INT CONST kanal):{}  TEXT VAR   zeichenkette :: "";{}  INT  CONST wert         :: dezimalwert (kanal);{}  wandle wert;{}  zeichenkette.{}  wandle wert:{}    INT VAR zeiger;{}    FOR zeiger FROM kanalbreite - 1 DOWNTO 0 REP{}      IF bit (wert, zeiger){}         THEN zeichenkette CAT eins{}         ELSE zeichenkette CAT null{}      FI{}    PER.{}END PROC bitmuster;{}INT PROC dezimalwert (INT CONST kanal):{}  pruefe kanal (kanal, digital ein);{}
+  eingabe (kanal){}END PROC dezimalwert;{}(******************** H I L F S - P R O Z E D U R E N ********************){}INT PROC relativer dezimalwert (TEXT CONST zeichenkette, INT CONST kanal):{}   INT VAR wert := letzte ausgabe (kanal);{}   pruefe zeichenkette auf korrekte laenge;{}   veraendere alten wert;{}   wert.{}   pruefe zeichenkette auf korrekte laenge:{}     IF length (zeichenkette) <> kanalbreite{}        THEN errorstop ("Bitmuster '" + zeichenkette + "' hat "{}                                      + "unzulaessige Laenge!"){}
+     FI.{}   veraendere alten wert:{}     INT VAR zeiger;{}     FOR zeiger FROM 1 UPTO kanalbreite REP{}       veraendere dieses bit{}     PER.{}   veraendere dieses bit:{}     TEXT CONST einzelbit :: zeichenkette SUB zeiger;{}     IF   einzelbit = eins   THEN setze bit{}     ELIF einzelbit = null   THEN loesche bit{}     ELIF einzelbit = invers THEN invertiere bit{}     ELIF einzelbit = egal   THEN lasse bit{}     ELSE errorstop ("'" + einzelbit + "' ist unzulaessiges " +{}                     "Bitsymbol in '" + zeichenkette + "'!"){}
+     FI.{}   setze bit:{}     set bit (wert, kanalbreite - zeiger).{}   loesche bit:{}     reset bit (wert, kanalbreite - zeiger).{}   invertiere bit:{}     IF bit (wert, kanalbreite - zeiger){}        THEN loesche bit{}        ELSE setze bit{}     FI.{}   lasse bit:{}     .{}  END PROC relativer dezimalwert;{}INT PROC relativer dezimalwert (TEXT CONST bitzeichen,{}                                INT  CONST bitnummer, kanal):{}    INT VAR wert :: letzte ausgabe (kanal);{}    IF   bitzeichen = eins   THEN setze bit{}
+    ELIF bitzeichen = null   THEN loesche bit{}    ELIF bitzeichen = invers THEN invertiere bit{}    ELIF bitzeichen = egal   THEN lasse bit{}    ELSE errorstop ("'" + bitzeichen + "' ist ein unzulaessiges " +{}                                       "Bitsymbol!"){}    FI;{}    wert.{}   setze bit:{}     set bit (wert, bitnummer).{}   loesche bit:{}     reset bit (wert, bitnummer).{}   invertiere bit:{}     IF bit (wert, bitnummer){}        THEN loesche bit{}        ELSE setze bit{}     FI.{}   lasse bit:{}
+     .{}END PROC relativer dezimalwert;{}PROC pruefe bitnummer (INT CONST bitnummer):{}  IF bitnummer < 0  OR  bitnummer > kanalbreite - 1{}     THEN errorstop ("Bitnummer " + text (bitnummer) +{}                     " ist nicht zulaessig!"){}  FI{}END PROC pruefe bitnummer{}END PACKET ls prozess 2{}
+
diff --git a/prozess/ls-Prozess 3 b/prozess/ls-Prozess 3
new file mode 100644
index 0000000..28ef825
--- /dev/null
+++ b/prozess/ls-Prozess 3	
@@ -0,0 +1,26 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                     ls-Prozess 3                     ** 
+         **                                                      ** 
+         **                     Version 1.02                     ** 
+         **                                                      ** 
+         **                  (Stand : 06.06.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **         Autoren: Bruno Pollok, Bielefeld             ** 
+         **                  Wolfgang Weber, Bielefeld           ** 
+         **                                                      ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls prozess 3 DEFINES                    
+       temperatur:{}LET thermometerkonstante = 50.0,{}    minimaltemperatur    = 10.0;{}REAL PROC temperatur (REAL CONST spannungswert):{}  spannungswert * thermometerkonstante - minimaltemperatur{}END PROC temperatur{}END PACKET ls prozess 3{}
+
diff --git a/prozess/ls-Prozess 4 b/prozess/ls-Prozess 4
new file mode 100644
index 0000000..158b548
--- /dev/null
+++ b/prozess/ls-Prozess 4	
@@ -0,0 +1,61 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                     ls-Prozess 4                     ** 
+         **                                                      ** 
+         **                     Version 1.02                     ** 
+         **                                                      ** 
+         **                  (Stand : 26.01.90)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **         Autoren: Bruno Pollok, Bielefeld             ** 
+         **                  Wolfgang Weber, Bielefeld           ** 
+         **                                                      ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls prozess 4 DEFINES 
+           pdv befehlsuebersicht anzeigen,{}           pdv ausgabebefehle anzeigen,{}           pdv eingabebefehle anzeigen,{}           pdv testbefehle anzeigen,{}           pdv weitere befehle anzeigen,{}           pdv bitmuster erlaeutern,{}           pdv symbole erlaeutern,{}           pdv digital analog werte,{}           pdv programm neu erstellen,{}           pdv programm ansehen,{}           pdv programm starten,{}           pdv programm wiederholen,{}           pdv dateien verzeichnis,{}
+           pdv datei kopieren,{}           pdv datei umbenennen,{}           pdv dateien loeschen,{}           pdv dateien drucken,{}           init pdv,{}           pdv:{}LET  menukarte       = "ls-MENUKARTE:Prozess",{}     niltext         =         "",{}     maxlaenge       =         45,{}     maxnamenslaenge =         35;{}WINDOW VAR w :: window (1, 3, 79, 19);{}TEXT   VAR programmname :: "";{}BOOL   VAR noch kein programm gelaufen :: TRUE;{}PROC pdv:{}  init pdv;{}  install menu (menukarte, FALSE);{}
+  handle menu  ("PDV"){}END PROC pdv;{}PROC init pdv:{}  programmname := "";{}  noch kein programm gelaufen := TRUE;{}  cursor off;{}END PROC init pdv;{}PROC pdv befehlsuebersicht anzeigen:{}  menuinfo (anwendungstext (20)){}END PROC pdv befehlsuebersicht anzeigen;{}PROC pdv ausgabebefehle anzeigen:{}  INT VAR i;{}  REP{}    i := menualternative (anwendungstext (1), anwendungstext (3),{}                          anwendungstext (4), 5, TRUE);{}    SELECT i OF{}      CASE 1, 101: menuinfo (anwendungstext (21)){}
+      CASE 2, 102: menuinfo (anwendungstext (22)){}      CASE 3, 103: menuinfo (anwendungstext (23)){}      CASE 4, 104: menuinfo (anwendungstext (24)){}      CASE 5, 105: menuinfo (anwendungstext (25)){}    END SELECT{}  UNTIL i = 6 OR i = 106 PER;{}END PROC pdv ausgabebefehle anzeigen;{}PROC pdv eingabebefehle anzeigen:{}  INT VAR i;{}  REP{}    i := menualternative (anwendungstext (2), anwendungstext (3),{}                          anwendungstext (4), 5, TRUE);{}    SELECT i OF{}      CASE 1, 101: menuinfo (anwendungstext (31)){}
+      CASE 2, 102: menuinfo (anwendungstext (32)){}      CASE 3, 103: menuinfo (anwendungstext (33)){}      CASE 4, 104: menuinfo (anwendungstext (34)){}      CASE 5, 105: menuinfo (anwendungstext (35)){}    END SELECT{}  UNTIL i = 6 OR i = 106 PER;{}END PROC pdv eingabebefehle anzeigen;{}PROC pdv testbefehle anzeigen:{}  INT VAR i;{}  REP{}    i := menualternative (anwendungstext (5), anwendungstext (7),{}                          anwendungstext (8), 5, TRUE);{}    SELECT i OF{}      CASE 1, 101: menuinfo (anwendungstext (41)){}
+      CASE 2, 102: menuinfo (anwendungstext (42)){}    END SELECT{}  UNTIL i = 3 OR i = 103 PER;{}END PROC pdv testbefehle anzeigen;{}PROC pdv weitere befehle anzeigen:{}  INT VAR i;{}  REP{}    i := menualternative (anwendungstext (6), anwendungstext (7),{}                          anwendungstext (8), 5, TRUE);{}    SELECT i OF{}      CASE 1, 101: menuinfo (anwendungstext (43)){}      CASE 2, 102: menuinfo (anwendungstext (44)){}    END SELECT{}  UNTIL i = 3 OR i = 103 PER;{}END PROC pdv weitere befehle anzeigen;{}
+PROC pdv bitmuster erlaeutern:{}  menuinfo (anwendungstext (46)){}END PROC pdv bitmuster erlaeutern;{}PROC pdv symbole erlaeutern:{}  menuinfo (anwendungstext (47)){}END PROC pdv symbole erlaeutern;{}PROC pdv digital analog werte:{}  menuinfo (anwendungstext (48)){}END PROC pdv digital analog werte;{}PROC pdvdateien verzeichnis:{}  disable stop;{}  forget ("Verzeichnis der Dateien", quiet);{}  THESAURUS VAR programme :: ALL myself;{}  FILE VAR f ::{}  sequential file (output, "Verzeichnis der Dateien");{}
+  f FILLBY programme;{}  modify (f);{}  to line (f, 1); insert record (f);{}  menufootnote ("Verlassen: <ESC> <q>");{}  cursor on;{}  show (w, f);{}  cursor off;{}  forget ("Verzeichnis der Dateien", quiet);{}  IF is error{}     THEN regenerate menuscreen;{}          out (""7"");{}          menuinfo  (" " + invers ("FEHLER: " + errormessage));{}          clear error{}     ELSE menu bildschirm{}  FI;{}  enable stop{}END PROC pdvdateien verzeichnis;{}PROC pdvprogramm neu erstellen:{}  hole programmname;{}
+  kontrolliere den programmnamen;{}  command dialogue (FALSE);{}  cursor on;{}  disable stop;{}  stdinfoedit (programmname, 3);{}  cursor off;{}  command dialogue (TRUE);{}  IF is error{}     THEN regenerate menuscreen;{}          out (""7"");{}          menuinfo  (" " + invers (errormessage));{}          clear error{}     ELSE menu bildschirm{}  FI;{}  enable stop.{}  hole programmname:{}    programmname := "";{}    programmname := menuanswer (ausgabe, programmname, 5).{}  ausgabe:{}    center (maxlaenge, invers ("Programm neu erstellen")) + ""13""13""{}
+                 + " Bitte den Namen für das Programm "13""13"".{}  kontrolliere den programmnamen:{}    IF   programmname = niltext{}         THEN LEAVE pdvprogramm neu erstellen{}    ELIF length (programmname) > maxnamenslaenge{}         THEN meckere zu langen namen an;{}              programmname := niltext;{}              LEAVE pdvprogramm neu erstellen{}    ELIF exists (programmname){}         THEN meckere existierendes programm an;{}              LEAVE pdvprogramm neu erstellen{}    FI.{}END PROC pdvprogramm neu erstellen;{}
+PROC pdvprogramm ansehen:{}  IF programmname <> niltext CAND exists (programmname){}     THEN frage nach diesem programm{}     ELSE lasse programm auswaehlen{}  FI;{}  cursor on;{}  disable stop;{}  stdinfoedit (programmname, 3);{}  cursor off;{}  IF is error{}     THEN regenerate menuscreen;{}          out (""7"");{}          menuinfo  (" " + invers ("FEHLER: " + errormessage));{}          clear error{}     ELSE menu bildschirm{}  FI;{}  enable stop.{}  frage nach diesem programm:{}    IF menuno (ueberschrift + " Zuletzt bearbeitetes Programm: " + name{}
+              + " Soll mit diesem Programm gearbeitet werden", 5){}       THEN lasse programm auswaehlen{}    FI.{}  ueberschrift:{}    center (maxlaenge, invers ("Programm ansehen/ändern")) + ""13""13"".{}  name:{}    ""13""13" " + invers (programmname) + ""13""13"".{}  lasse programm auswaehlen:{}    THESAURUS VAR verfuegbare :: ALL myself;{}    IF NOT not empty (verfuegbare){}       THEN noch kein programm;{}            LEAVE pdvprogramm ansehen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}
+    programmname := menuone (verfuegbare, "Programm ansehen/ändern",{}                             "Bitte das gewünschte Programm ankreuzen!",{}                              FALSE);{}    IF programmname = niltext{}       THEN menu bildschirm;{}            LEAVE pdvprogramm ansehen{}    FI.{}END PROC pdvprogramm ansehen;{}PROC pdvdateien drucken:{}  lasse programme auswaehlen;{}  drucke programme;{}  menu bildschirm.{}  lasse programme auswaehlen:{}    THESAURUS VAR verfuegbare :: ALL myself;{}    IF NOT not empty (verfuegbare){}
+       THEN noch kein programm;{}            LEAVE pdvdateien drucken{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    verfuegbare := menusome (verfuegbare, "Dateien drucken",{}                   "Bitte die Dateien ankreuzen, die gedruckt werden sollen!",{}                    FALSE).{}  drucke programme:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers ("Dateien drucken")));{}    menuwindowline (2);{}    command dialogue (FALSE);{}
+    fuehre einzelne operationen aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (" Alle ausgewählten Dateien wurden gedruckt!");{}    menuwindowstop.{}  fuehre einzelne operationen aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              menuwindowout ( " """ + name (verfuegbare, k) +{}                              """ wird gedruckt!");{}              menuwindowline;{}
+              print (name (verfuegbare, k));{}              fehlerbehandlung{}      FI{}    PER.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}       THEN menuwindowline (2);{}            menuwindowout (" Es wurde keine Datei ausgewählt!");{}            menuwindowstop;{}            menu bildschirm;{}            LEAVE pdvdateien drucken{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}
+    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen; out (""7"");{}            menuinfo  (" " + invers (errormessage));{}            clear error; enable stop;{}            LEAVE pdvdateien drucken{}       ELSE enable stop{}    FI.{}END PROC pdvdateien drucken;{}PROC pdvdatei kopieren:{}  ermittle alten programmnamen;{}  erfrage neuen programmnamen;{}  kopiere ggf das programm.{}  ermittle alten programmnamen:{}    IF NOT not empty (ALL myself){}       THEN noch kein programm;{}
+            LEAVE pdvdatei kopieren{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    TEXT VAR alter name := menuone (ALL myself, "Datei kopieren",{}            "Bitte die Datei ankreuzen, das kopiert werden soll!",FALSE);{}    menu bildschirm;{}    IF alter name = niltext{}       THEN LEAVE pdvdatei kopieren{}    FI.{}  erfrage neuen programmnamen:{}    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}     ueberschrift + " Name der 'alten' Datei: " + bisheriger name{}
+                  + " Bitte den Namen für die Kopie: ".{}  ueberschrift:{}    center (maxlaenge, invers ("Datei kopieren")) + ""13""13"".{}  bisheriger name:{}    ""13""13" " + invers (alter name) + ""13""13"".{}  kopiere ggf das programm:{}    IF   neuer name = niltext{}         THEN menuinfo (" " + invers ("Der gewünschte Name ist unzulässig!"));{}              LEAVE pdvdatei kopieren{}    ELIF exists (neuer name){}         THEN mache vorwurf;{}              LEAVE pdvdatei kopieren{}       ELSE copy (alter name, neuer name){}
+    FI.{}  mache vorwurf:{}    menuinfo (" " + invers ("Eine Datei mit diesem Namen gibt es bereits!")).{}END PROC pdvdatei kopieren;{}PROC pdvdatei umbenennen:{}  ermittle alten programmnamen;{}  erfrage neuen programmnamen;{}  benenne ggf das programm um.{}  ermittle alten programmnamen:{}    IF NOT not empty (ALL myself){}       THEN noch kein programm;{}            LEAVE pdvdatei umbenennen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    TEXT VAR alter name := menuone ( ALL myself, "Datei umbenennen",{}
+        "Bitte die Datei ankreuzen, die umbenannt werden soll!", FALSE);{}    menu bildschirm;{}    IF alter name = niltext{}       THEN LEAVE pdvdatei umbenennen{}    FI.{}  erfrage neuen programmnamen:{}    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}     ueberschrift + " Bisheriger  Dateiname: " + bisheriger name{}                  + " Zukünftiger Dateiname: ".{}  ueberschrift:{}    center (maxlaenge, invers ("Datei umbenennen")) + ""13""13"".{}  bisheriger name:{}
+    ""13""13" " + invers (alter name) + ""13""13"".{}  benenne ggf das programm um:{}    IF   neuer name = niltext{}         THEN menuinfo (" " + invers ("Der gewünschte Name ist unzulässig!"));{}              LEAVE pdvdatei umbenennen{}    ELIF exists (neuer name){}         THEN mache vorwurf;{}              LEAVE pdvdatei umbenennen{}       ELSE rename (alter name, neuer name);{}            programmname := neuer name{}    FI.{}  mache vorwurf:{}    menuinfo (" " + invers ("Eine Datei mit diesem Namen gibt es bereits!")).{}
+END PROC pdvdatei umbenennen;{}PROC pdvdateien loeschen:{}  lasse programme auswaehlen;{}  loesche programme;{}  menu bildschirm.{}  lasse programme auswaehlen:{}    THESAURUS VAR verfuegbare :: ALL myself;{}    IF NOT not empty (verfuegbare){}       THEN noch kein programm;{}            LEAVE pdvdateien loeschen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    verfuegbare := menusome (verfuegbare, "Dateien löschen",{}    "Bitte alle Dateien ankreuzen, die gelöscht werden sollen!", FALSE).{}
+  loesche programme:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers ("Dateien löschen")));{}    menuwindowline (2);{}    command dialogue (FALSE);{}    fuehre einzelne operationen aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (" Alle ausgewählten Dateien wurden gelöscht!");{}    menuwindowstop.{}  fuehre einzelne operationen aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}
+      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              IF menuwindowyes (" """ + name (verfuegbare, k) + """ löschen"){}                 THEN forget (name (verfuegbare, k), quiet){}              FI;{}              fehlerbehandlung{}      FI{}    PER;{}    programmname := "".{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}       THEN menuwindowline (2);{}            menuwindowout (" Es wurde keine Datei ausgewählt!");{}            menuwindowstop;{}
+            menu bildschirm;{}            LEAVE pdvdateien loeschen{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen; out (""7"");{}            menuinfo  (" " + invers (errormessage));{}            clear error; enable stop;{}            LEAVE pdvdateien loeschen{}       ELSE enable stop{}    FI.{}END PROC pdvdateien loeschen;{}
+PROC pdvprogramm starten:{}  programmname ermitteln;{}  bildschirm vorbereiten;{}  cursor on;{}  disable stop;{}  warnings off;{}  check on;{}  run pdv (programmname);{}  noch kein programm gelaufen := FALSE;{}  cursor off;{}  IF is error{}     THEN fehler ggf melden;{}          clear error{}     ELSE regenerate menuscreen{}  FI;{}  enable stop.{}  bildschirm vorbereiten:{}    cursor (17, 2); out (waagerecht);{}    cursor (38, 2); out (waagerecht);{}    cursor ( 1, 3); out (""4"");{}    menufootnote ("Programmabbruch: <ESC><h>");{}
+    cursor (1, 5);{}    out ("Das Programm wird übersetzt.  Zeilen-Nr.: ").{}  fehler ggf melden:{}    IF errormessage <> ""{}       THEN fehler melden{}    FI.{}  fehler melden:{}    IF   pos (errormessage, "'halt' vom Terminal") > 0{}       THEN regenerate menuscreen;{}            out (""7""); menuinfo (" "15"'halt' vom Terminal "14""){}    ELIF pos (errormessage, "Programm-Abbruch durch <ESC><h>") > 0{}       THEN regenerate menuscreen;{}            out (""7""); menuinfo (" "15"Programm-Abbruch durch <ESC><h> "14""){}
+    ELIF pos (errormessage, "(bei Zeile") > 0 AND exists (programmname){}       THEN programm mit fehler im notebook zeigen;{}            regenerate menuscreen{}       ELSE regenerate menuscreen;{}            out (""7""); menuinfo  (" " + invers ("FEHLER: "{}                                        + subtext (errormessage, 1, 61))){}    FI.{}  programm mit fehler im notebook zeigen:{}    noteline;{}    note ("FEHLER: " + errormessage);{}    INT VAR n; FOR n FROM 1 UPTO 9 REP noteline PER;{}    note (""15"Verlassen: <ESC><q> "14"");{}
+    FILE VAR p :: sequential file (modify, programmname);{}    to line (p, max (1, fehlerzeile));{}    col (1);{}    clear error;{}    out (""7"");{}    cursor on;{}    noteedit (p);{}    cursor off.{}  fehlerzeile:{}    int (subtext (errormessage, zahlposition)).{}    zahlposition: pos (errormessage, "(bei Zeile") + 10.{}  programmname ermitteln:{}    IF programmname <> niltext CAND exists (programmname){}       THEN frage nach diesem programm{}       ELSE lasse programm auswaehlen{}    FI.{}  frage nach diesem programm:{}
+    IF menuno (ueberschrift + " Zuletzt bearbeitetes Programm: " +{}               name + " Soll mit diesem Programm gearbeitet werden", 5){}       THEN lasse programm auswaehlen{}    FI.{}  ueberschrift:{}    center (maxlaenge, invers ("Programm starten")) + ""13""13"".{}  name:{}    ""13""13" " + invers (programmname) + ""13""13"".{}  lasse programm auswaehlen:{}    THESAURUS VAR verfuegbare :: ALL myself;{}    IF NOT not empty (verfuegbare){}       THEN noch kein programm;{}            LEAVE pdvprogramm starten{}
+       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    programmname := menuone (verfuegbare, "Programm starten",{}                    "Bitte das gewünschte Programm ankreuzen!", FALSE);{}    IF programmname = niltext{}       THEN menubildschirm;{}            LEAVE pdv programm starten{}    FI.{}END PROC pdvprogramm starten;{}PROC pdv programm wiederholen:{}  bildschirm vorbereiten;{}  cursor on;{}  disable stop;{}  IF noch kein programm gelaufen{}     THEN errorstop ("Eine Wiederholung ist nicht moeglich!"){}
+     ELSE run pdv again{}  FI;{}  cursor off;{}  regenerate menuscreen;{}  IF is error{}     THEN zeige fehler;{}          clear error{}  FI;{}  enable stop.{}  bildschirm vorbereiten:{}    cursor (17, 2); out (waagerecht);{}    cursor (38, 2); out (waagerecht);{}    cursor ( 1, 3); out (""4"");{}    menufootnote ("Programmabbruch: <ESC><h>");{}    cursor (1,3).{}  zeige fehler:{}    out (""7"");{}    IF errormessage = "'run again' nicht moeglich"{}       THEN menuinfo (" "15"Eine Wiederholung ist nicht moeglich! "14""){}
+    ELIF pos (errormessage, "'halt' vom Terminal") > 0{}       THEN menuinfo (" "15"'halt' vom Terminal "14""){}    ELIF pos (errormessage, "Programm-Abbruch durch <ESC><h>") > 0{}       THEN menuinfo (" "15"Programm-Abbruch durch <ESC><h> "14""){}       ELSE menuinfo (" " + invers ("FEHLER: "{}                          + subtext (errormessage, 1, 61))){}    FI.{}END PROC pdv programm wiederholen;{}PROC meckere zu langen namen an:{}  menuinfo (" " + invers ("Hier dürfen Namen höchstens "{}                + text (max namenslaenge){}
+                + " Zeichen lang sein!")){}END PROC meckere zu langen namen an;{}PROC meckere existierendes programm an:{}  menuinfo (" " + invers ("Ein Programm mit diesem Namen gibt es bereits!")){}END PROC meckere existierendes programm an;{}PROC noch kein programm:{}  menuinfo (" " + invers ("Es existiert noch kein Programm!")){}END PROC noch kein programm;{}PROC menu bildschirm:{}  cursor (1, 2);{}  out (5 * waagerecht);{}  cursor (1, 3);{}  out (""4"");{}  cursor (1,23);{}  out (79 * waagerecht);{}
+  refresh submenu{}END PROC menu bildschirm{}END PACKET ls prozess 4{}
+
diff --git a/prozess/ls-Prozess 5 b/prozess/ls-Prozess 5
new file mode 100644
index 0000000..66bdf94
--- /dev/null
+++ b/prozess/ls-Prozess 5	
@@ -0,0 +1,84 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                     ls-Prozess 5                     ** 
+         **                                                      ** 
+         **                     Version 1.02                     ** 
+         **                                                      ** 
+         **                  (Stand : 26.01.90)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **         Autoren: Bruno Pollok, Bielefeld             ** 
+         **                  Wolfgang Weber, Bielefeld           ** 
+         **                                                      ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls prozess 5 DEFINES 
+       pdv konfiguration zugelassen,{}       pdv konfiguration evtl aktivieren,{}       pdv konfiguration zeigen,{}       pdv kanal konfigurieren,{}       pdv interfaceausgabe testen,{}       pdv interfaceeingabe testen:{}LET max steckplaetze     =  4,{}    max portanzahl       =  4,{}    anzahl kartensorten  =  5,{}    betriebsart          =  1,{}    keine karte          =  1,{}    ea karte             =  2,{}    kombi                =  3,{}    da karte             =  4,{}    ad karte             =  5,{}
+    compact              =  6,{}    einzel               =  7,{}    mehrfach             =  8;{}LET testfenster x        = 11,{}    testfenster y        =  5,{}    testfenster xsize    = 59,{}    testfenster ysize    = 15;{}WINDOW VAR testfenster   :: window (testfenster x,     testfenster y,{}                                    testfenster xsize, testfenster ysize);{}INT    VAR steckplatzart :: 0;{}BOOL   VAR mit konfigurationsmoeglichkeit :: TRUE;{}TASK   VAR konfigurationsmanager          :: niltask;{}
+ROW max steckplaetze INT VAR kartenart :: ROW max steckplaetze INT :{}                                          (keine karte, keine karte,{}                                           keine karte, keine karte);{}LET SPANNUNG = ROW 2 REAL,{}    PORT     = ROW 3 INT,{}    KARTE    = ROW max portanzahl PORT;{}ROW anzahl kartensorten KARTE CONST karte :: ROW anzahl kartensorten KARTE :{}(* ---------------------------------------------------------------------- *){}(   KARTE : ({}(* ---------------------------------------------------------------------- *){}
+(*         *)       PORT : (nicht belegt, 0, 0),        (*     Port 1     *){}(*  leere  *)       PORT : (nicht belegt, 0, 0),        (*     Port 2     *){}(*  Karte  *)       PORT : (nicht belegt, 0, 0),        (*     Port 3     *){}(*         *)       PORT : (nicht belegt, 0, 0)),       (*     Port 4     *){}(*----------------------------------------------------------------------- *){}    KARTE : ({}(* ---------------------------------------------------------------------- *){}(*         *)       PORT : (digital ein,  1, 3),        (*     Port 1     *){}
+(*   E/A   *)       PORT : (digital aus,  1, 1),        (*     Port 2     *){}(*  Karte  *)       PORT : (digital ein,  1, 3),        (*     Port 3     *){}(*         *)       PORT : (digital aus,  1, 1)),       (*     Port 4     *){}(*----------------------------------------------------------------------- *){}    KARTE : ({}(* ---------------------------------------------------------------------- *){}(*         *)       PORT : (analog  ein,  2, 2),        (*     Port 1     *){}(*  Kombi  *)       PORT : (analog  ein,  3, 2),        (*     Port 2     *){}
+(*  Karte  *)       PORT : (digital ein,  1, 3),        (*     Port 3     *){}(*         *)       PORT : (digital aus,  1, 1 )),      (*     Port 4     *){}(*----------------------------------------------------------------------- *){}    KARTE : ({}(* ---------------------------------------------------------------------- *){}(*         *)       PORT : (analog  aus,  1, 1),        (*     Port 1     *){}(*   D/A   *)       PORT : (analog  aus,  1, 3),        (*     Port 2     *){}(* Wandler *)       PORT : (nicht belegt, 0, 0),        (*     Port 3     *){}
+(*         *)       PORT : (nicht belegt, 0, 0)),       (*     Port 4     *){}(*----------------------------------------------------------------------- *){}    KARTE : ({}(* ---------------------------------------------------------------------- *){}(*         *)       PORT : (analog  ein,  1, 1),        (*     Port 1     *){}(*   A/D   *)       PORT : (analog  ein,  1, 3),        (*     Port 2     *){}(* Wandler *)       PORT : (nicht belegt, 0, 0),        (*     Port 3     *){}(*         *)       PORT : (nicht belegt, 0, 0))        (*     Port 4     *){}
+(*----------------------------------------------------------------------- *){}                                                                           );{}PROC pdv konfiguration zugelassen (BOOL CONST wahrheitswert):{}  teste berechtigung;{}  mit konfigurationsmoeglichkeit := wahrheitswert;{}  IF mit konfigurationsmoeglichkeit{}     THEN konfigurationsmanager := niltask{}     ELSE konfigurationsmanager := myself{}  FI.{}  teste berechtigung:{}    enable stop;{}    IF NOT (konfigurationsmanager = niltask  OR{}
+            konfigurationsmanager = myself){}       THEN errorstop ("Befehl ist nur in Task '" +{}                        name (konfigurationsmanager) + "' zugelassen!"){}    FI.{}END PROC pdv konfiguration zugelassen;{}PROC pdv konfiguration evtl aktivieren:{}  IF mit konfigurationsmoeglichkeit{}     THEN activate (3){}     ELSE deactivate (3){}  FI{}END PROC pdv konfiguration evtl aktivieren;{}PROC pdv kanal konfigurieren:{}  TEXT CONST info   ::  "  "15"Auswahl der Steckplatzart "14" "13""13""{}
+                      + "     c  Compactbox             "13""{}                      + "     e  Einzelsteckplatz       "13""{}                      + "     m  Mehrfachsteckplatz     ",{}             liste  :: "Compact"13"Einzel"13"Mehrfach",{}             tasten :: "cemCEM";{}   INT VAR auswahl := menualternative (info, liste, tasten, 5, FALSE);{}   SELECT auswahl OF{}     CASE 1, 101, 104 :  trage compactbox ein;{}                         zeige kanalbelegung (0){}     CASE 2, 102, 105 :  trage einzelplatzbelegung ein;{}
+                         zeige kanalbelegung (0){}     CASE 3, 103, 106 :  bearbeite die steckplaetze einzeln{}   END SELECT;{}   beende kanaldaten eintragen.{}   trage compactbox ein:{}     steckplatzart := compact;{}     trage steckplatzbelegung ein (1, kombi);{}     trage steckplatzbelegung ein (2, keine karte);{}     trage steckplatzbelegung ein (3, keine karte);{}     trage steckplatzbelegung ein (4, keine karte).{}   trage einzelplatzbelegung ein:{}     steckplatzart := einzel;{}     trage steckplatzbelegung ein (1, ermittelte kartenart (0));{}
+     trage steckplatzbelegung ein (2, keine karte);{}     trage steckplatzbelegung ein (3, keine karte);{}     trage steckplatzbelegung ein (4, keine karte).{}   bearbeite die steckplaetze einzeln:{}     INT VAR platz;{}     steckplatzart := mehrfach;{}     FOR platz FROM 1 UPTO max steckplaetze REP{}       trage steckplatzbelegung ein (platz, ermittelte kartenart (platz));{}       zeige kanalbelegung (platz * 10){}     PER.{}END PROC pdv kanal konfigurieren;{}PROC pdv konfiguration zeigen:{}  SELECT steckplatzart OF{}
+    CASE compact  : zeige kanalbelegung (0){}    CASE einzel   : zeige kanalbelegung (0){}    CASE mehrfach : zeige belegung einzelner steckplaetze{}    OTHERWISE       noch nicht konfiguriert{}  END SELECT.{}  noch nicht konfiguriert:{}    menuinfo ("                  "15"Warnung: "14"           "13""13""13""{}            + " Das Interface wurde noch nicht konfiguriert! "13""13""{}            + "  In diesem Zustand sind weder Eingaben noch  "13""{}            + "     Ausgaben über das Interface möglich.     "13"").{}
+  zeige belegung einzelner steckplaetze:{}    TEXT CONST info   ::{}                      "   "15"Eingestellt: Mehrfachsteckplatz "14" "13""13""{}                    + "         1   Info Steckplatz 1         "13""{}                    + "         2   Info Steckplatz 2         "13""{}                    + "         3   Info Steckplatz 3         "13""{}                    + "         4   Info Steckplatz 4         "13""13""{}                    + "         z   Zurück ins Hauptmenü      ",{}               liste  :: "1"13"2"13"3"13"4"13"z",{}
+               tasten :: "1234zZ";{}   INT VAR auswahl;{}   REP auswahl := menualternative (info, liste, tasten, 5, FALSE);{}     SELECT auswahl OF{}       CASE 1, 101 :  zeige kanalbelegung (10){}       CASE 2, 102 :  zeige kanalbelegung (20){}       CASE 3, 103 :  zeige kanalbelegung (30){}       CASE 4, 104 :  zeige kanalbelegung (40){}     END SELECT{}   UNTIL (auswahl = 5) OR (auswahl > 104) PER{}END PROC pdv konfiguration zeigen;{}PROC pdv interfaceausgabe testen:{}  gestalte testfenster ("Ausgabetest");{}
+  disable stop;{}  teste interface;{}  IF NOT is error{}     THEN teste interface ausgabe{}  FI;{}  IF is error{}     THEN fehlerbehandlung{}     ELSE schliesse interface;{}          enable stop;{}          beseitige testfenster;{}          refresh submenu{}  FI.{}  fehlerbehandlung:{}    TEXT VAR meldung :: errormessage;{}    clear error;{}    schalte alles aus;{}    schliesse interface;{}    enable stop;{}    cursor off;{}    regenerate menuscreen;{}    menuinfo (" " + invers (meldung)).{}END PROC pdv interfaceausgabe testen;{}
+PROC pdv interfaceeingabe testen:{}  gestalte testfenster ("Eingabetest");{}  disable stop;{}  teste interface;{}  IF NOT is error{}     THEN teste interface eingabe{}  FI;{}  IF is error{}     THEN fehlerbehandlung{}     ELSE schliesse interface;{}          enable stop;{}          beseitige testfenster;{}          refresh submenu{}  FI.{}  fehlerbehandlung:{}    TEXT VAR meldung :: errormessage;{}    clear error;{}    schalte alles aus;{}    schliesse interface;{}    enable stop;{}    cursor off;{}
+    regenerate menuscreen;{}    menuinfo (" " + invers (meldung)).{}END PROC pdv interfaceeingabe testen;{}PROC beseitige testfenster:{}  INT VAR z;{}  FOR z FROM testfenster y + testfenster ysize DOWNTO testfenster y - 1 REP{}    cursor (testfenster x - 1, z);{}    out (""5""){}  PER{}END PROC beseitige testfenster;{}PROC gestalte testfenster (TEXT CONST funktionsart):{}  show (testfenster);{}  cursor (testfenster x - 1, testfenster y + testfenster ysize - 2);{}  out (balken links + (testfenster xsize * waagerecht) + balken rechts);{}
+  cursor (testfenster, 1, 2);{}  out (testfenster, center (testfenster, invers (funktionsart))){}END PROC gestalte testfenster;{}PROC testfensterfussnote (TEXT CONST meldung):{}  cursor (testfenster, 2, testfenster ysize);{}  out (testfenster, meldung){}END PROC testfensterfussnote;{}PROC teste interfaceausgabe:{}  INT  VAR kanalnummer, steckplatz, port;{}  TEXT VAR nummer :: "";{}  enable stop;{}  REP hole kanalnummer;{}      teste ausgabe an kanal{}  PER.{}  hole kanalnummer:{}    SELECT steckplatzart OF{}
+      CASE compact  :  kanalnummer := 4; steckplatz := 1; port := 4{}      CASE einzel   :  kanalnummer muss evtl erfragt werden{}      CASE mehrfach :  kanalnummer muss erfragt werden{}    OTHERWISE errorstop ("Interface ist noch nicht konfiguriert!"){}    END SELECT;{}    cursor (testfenster, 2, 5);{}    out (testfenster, "Ausgabe an Kanal " + text (kanalnummer) + klammer +{}                       kanalbeschreibung (steckplatz, port));{}    IF steckplatzart = mehrfach{}       THEN cursor (testfenster, 25, 6);{}
+            out (testfenster, "in Steckplatz " + text (steckplatz)){}    FI;{}    out (testfenster, ")").{}    klammer:{}      IF kanalnummer < 10{}         THEN "  (= "{}         ELSE " (= "{}      FI.{}  kanalnummer muss evtl erfragt werden:{}    SELECT kartenart [1] OF{}      CASE kombi   :  kanalnummer := 4; steckplatz := 1; port := 4{}      CASE eakarte :  kanalnummer := 2; steckplatz := 1; port := 2{}      CASE dakarte :  frage nach kanalnummer auf da karte;{}                      steckplatz  := 1; port := kanalnummer{}
+    OTHERWISE errorstop ("Keine Ausgabe an " + kartenname + " möglich!"){}    END SELECT.{}  kartenname:{}    IF kartenart [1] = ad karte{}       THEN "A/D-Karte"{}       ELSE "leeren Steckplatz"{}    FI.{}  frage nach kanalnummer auf da karte:{}    menufootnote ("Zurück zum Hauptmenü: <ESC><q>");{}    testfensterfussnote ("Bitte eine Kanalnummer eingeben!");{}    cursor (testfenster, 2, 5);{}    out (testfenster, "Ausgabe - Kanal (1 oder 2): ");{}    cursor on;{}    REP inchar (nummer){}    UNTIL (pos ("12", nummer) > 0) OR esc q gedrueckt PER;{}
+    cursor off;{}    IF nummer = ""27""{}       THEN LEAVE teste interface ausgabe{}       ELSE kanalnummer := int (nummer){}    FI.{}    esc q gedrueckt:{}      (nummer = ""27"") AND (incharety (20) = "q").{}  kanalnummer muss erfragt werden:{}    TEXT VAR exit char;{}    menufootnote ("Zurück zum Hauptmenü: <ESC><q>");{}    testfensterfussnote ("Bitte eine Kanalnummer eingeben!");{}    cursor (testfenster, 2, 5);{}    out (testfenster, "Ausgabe - Kanal:");{}    cursor on;{}    REP cursor (testfenster, 19, 5);{}
+        editget (testfenster, nummer, 4, 4, "", "q", exit char){}    UNTIL (exit char = ""27"q") OR ausgabekanal eingegeben PER;{}    cursor off;{}    IF exit char = ""27"q"{}       THEN LEAVE teste interface ausgabe{}    FI.{}  ausgabekanal eingegeben:{}    kanalnummer := abs (int (nummer));{}    steckplatz  := kanalnummer DIV 10;{}    port        := kanalnummer MOD 10;{}    IF steckplatz = 0 THEN steckplatz := 1 FI;{}    cursor (testfenster, 2, 7);{}    IF   (kanalnummer < 1) OR (kanalnummer > 49){}
+         THEN out (testfenster, "Unzulässige Kanalnummer!          "); FALSE{}    ELIF (port = 0) OR (port > max portanzahl) OR kein ausgabeport{}         THEN out (testfenster, "Dies ist kein Ausgabe-Kanal!      "); FALSE{}         ELSE out (testfenster, "                                  "); TRUE{}    FI.{}    kein ausgabeport:{}      (port betriebsart <> digital aus) AND (port betriebsart <> analog aus).{}      port betriebsart: karte [sorte][port][betriebsart].{}      sorte           : kartenart [steckplatz].{}
+  teste ausgabe an kanal:{}    TEXT VAR wert;{}    cursor (testfenster, 1, 8);{}    out (testfenster, testfenster xsize * "-");{}    cursor (testfenster, 2, 11);{}    out (testfenster, "Ausgabewert: ");{}    testfenster fussnote ("Bitte einen Wert zwischen 0 und 255 eingeben!");{}    menufootnote ("'Werte ausgeben' beenden: <ESC><q>");{}    cursor on;{}    REP cursor (testfenster, 15, 11);{}        wert := "0";{}        editget (testfenster, wert, 4, 4, "", "qh", exit char);{}        IF exit char = return{}
+           THEN ausgeben (kanalnummer, int (wert) MOD ganzzahlobergrenze){}        ELIF exit char = ""27"h"{}           THEN errorstop ("Programm-Abbruch durch <ESC><h>!"){}        FI{}    UNTIL exitchar = ""27"q" PER;{}    cursor off;{}    IF (steckplatzart = mehrfach) OR (kartenart [1] = da karte){}       THEN cursor (testfenster, 1, 5);{}            out (testfenster, (2 * testfenster xsize) * " ");{}            cursor (testfenster, 2, 11);{}            out (testfenster, "                       ");{}
+            testfenster fussnote ((testfenster xsize - 2) * " "){}       ELSE LEAVE teste interfaceausgabe{}    FI.{}    return: ""13"".{}END PROC teste interfaceausgabe;{}PROC teste interfaceeingabe:{}  INT  VAR kanalnummer, steckplatz, port;{}  TEXT VAR nummer :: "";{}  enable stop;{}  REP hole kanalnummer;{}      teste eingabe vom kanal{}  PER.{}  hole kanalnummer:{}    IF   steckplatzart = 0{}         THEN errorstop ("Interface ist noch nicht konfiguriert!"){}         ELSE kanalnummer erfragen{}
+    FI;{}    cursor (testfenster, 2, 5);{}    out (testfenster, "Eingabe von Kanal " + text (kanalnummer) + klammer +{}                       kanalbeschreibung (steckplatz, port));{}    IF steckplatzart = mehrfach{}       THEN cursor (testfenster, 26, 6);{}            out (testfenster, "in Steckplatz " + text (steckplatz)){}    FI;{}    out (testfenster, ")").{}    klammer:{}      IF kanalnummer < 10{}         THEN "  (= "{}         ELSE " (= "{}      FI.{}  kanalnummer erfragen:{}    SELECT steckplatzart OF{}
+      CASE compact  : drei kanaele anbieten;{}                      steckplatz := 1; port := kanalnummer{}      CASE einzel   : zwei oder drei kanaele anbieten;{}                      steckplatz := 1; port := kanalnummer{}      CASE mehrfach : alle kanaele moeglich{}    END SELECT.{}  drei kanaele anbieten:{}    menufootnote ("Zurück zum Hauptmenü: <ESC><q>");{}    testfensterfussnote ("Bitte eine Kanalnummer eingeben!");{}    cursor (testfenster, 2, 5);{}    out (testfenster, "Eingabe - Kanal (1, 2 oder 3): ");{}
+    cursor on;{}    REP inchar (nummer){}    UNTIL (pos ("123", nummer) > 0) OR esc q gedrueckt PER;{}    cursor off;{}    IF nummer = ""27""{}       THEN LEAVE teste interface eingabe{}       ELSE kanalnummer := int (nummer){}    FI.{}    esc q gedrueckt:{}      (nummer = ""27"") AND (incharety (20) = "q").{}  zwei oder drei kanaele anbieten:{}    SELECT kartenart [1] OF{}      CASE kombi    : drei kanaele anbieten{}      CASE ad karte : zwei kanaele anbieten{}      CASE ea karte : kanalnummer := 1{}
+    OTHERWISE errorstop ("Eingabe bei " + kartenname + " nicht möglich!"){}    END SELECT.{}    kartenname:{}      IF kartenart [1] = da karte{}         THEN "D/A-Karte"{}         ELSE "leerem Steckplatz"{}      FI.{}  zwei kanaele anbieten:{}    menufootnote ("Zurück zum Hauptmenü: <ESC><q>");{}    testfensterfussnote ("Bitte eine Kanalnummer eingeben!");{}    cursor (testfenster, 2, 5);{}    out (testfenster, "Eingabe - Kanal (1 oder 2): ");{}    cursor on;{}    REP inchar (nummer){}    UNTIL (pos ("12", nummer) > 0) OR esc q gedrueckt PER;{}
+    cursor off;{}    IF nummer = ""27""{}       THEN LEAVE teste interface eingabe{}       ELSE kanalnummer := int (nummer){}    FI.{}  alle kanaele moeglich:{}    TEXT VAR exit char;{}    menufootnote ("Zurück zum Hauptmenü: <ESC><q>");{}    testfensterfussnote ("Bitte eine Kanalnummer eingeben!");{}    cursor (testfenster, 2, 5);{}    out (testfenster, "Eingabe - Kanal:");{}    cursor on;{}    REP cursor (testfenster, 19, 5);{}        editget (testfenster, nummer, 4, 4, "", "q", exit char){}    UNTIL (exit char = ""27"q") OR eingabekanal eingegeben PER;{}
+    cursor off;{}    IF exit char = ""27"q"{}       THEN LEAVE teste interface eingabe{}    FI.{}  eingabekanal eingegeben:{}    kanalnummer := abs (int (nummer));{}    steckplatz  := kanalnummer DIV 10;{}    port        := kanalnummer MOD 10;{}    IF steckplatz = 0 THEN steckplatz := 1 FI;{}    cursor (testfenster, 2, 7);{}    IF   (kanalnummer < 1) OR (kanalnummer > 49){}         THEN out (testfenster, "Unzulässige Kanalnummer!          "); FALSE{}    ELIF (port = 0) OR (port > max portanzahl) OR kein eingabeport{}
+         THEN out (testfenster, "Dies ist kein Eingabe-Kanal!      "); FALSE{}         ELSE out (testfenster, "                                  "); TRUE{}    FI.{}    kein eingabeport:{}      (port betriebsart <> digital ein) AND (port betriebsart <> analog ein).{}      port betriebsart: karte [sorte][port][betriebsart].{}      sorte           : kartenart [steckplatz].{}  teste eingabe vom kanal:{}    cursor (testfenster, 1, 8);{}    out (testfenster, testfenster xsize * "-");{}    cursor (testfenster, 2, 11);{}
+    out (testfenster, "Eingelesener Wert: ");{}    testfenster fussnote ("                                             ");{}    menufootnote ("'Werte einlesen' beenden: <ESC><q>");{}    REP cursor (testfenster, 21, 11);{}        out (text (eingabe (kanalnummer), 3));{}        warte (0.1){}    UNTIL abbruch gewuenscht PER;{}    IF (steckplatzart = einzel) AND (kartenart [1] = ea karte){}       THEN LEAVE teste interfaceeingabe{}       ELSE cursor (testfenster, 1, 5);{}            out (testfenster, (2 * testfenster xsize) * " ");{}
+            cursor (testfenster, 2, 11);{}            out (testfenster, "                       "){}    FI.{}END PROC teste interfaceeingabe;{}TEXT PROC kanalbeschreibung (INT CONST steckplatz, port):{}  IF steckplatzart = compact{}     THEN port auf compactbox{}     ELSE port auf steckkarte{}  FI.{}  port auf compactbox:{}    portbeschreibung + " der Compact-Box".{}  port auf steckkarte:{}    SELECT kartenart [steckplatz] OF{}      CASE kombi    : portbeschreibung + " der Kombi-Karte"{}      CASE ea karte : portbeschreibung + " der E/A-Karte"{}
+      CASE da karte : portbeschreibung + " der D/A-Karte"{}      CASE ad karte : portbeschreibung + " der A/D-Karte"{}    OTHERWISE ""{}    END SELECT.{}  portbeschreibung:{}    SELECT 2 + karte [kartenart [steckplatz]][port][betriebsart] OF{}      CASE 1 : "Digitalausgang"{}      CASE 3 : "Digitaleingang"{}      CASE 0 : "Analogausgang " + text (port){}      CASE 4 : "Analogeingang " + text (port){}    OTHERWISE ""{}    END SELECT.{}END PROC kanalbeschreibung;{}PROC trage steckplatzbelegung ein (INT CONST steckplatz, art):{}
+  INT VAR port;{}  kartenart [steckplatz] := art;{}  klaere spannungsbereiche;{}  FOR port FROM 1 UPTO max portanzahl REP{}    trage kanaldaten ein (kanalnummer, spannungsbereich, portdaten);{}    IF steckplatz = 1{}       THEN trage kanaldaten ein (port, spannungsbereich, portdaten){}    FI{}  PER.{}  kanalnummer:  port  +  10 * steckplatz.{}  portdaten  :  karte [kartenart [steckplatz]][port].{}  spannungsbereich:{}    IF   port = 1{}         THEN bereich von e1{}    ELIF port = 2{}         THEN bereich von e2{}
+         ELSE SPANNUNG : (0.0, 0.0){}    FI.{}  klaere spannungsbereiche:{}    SPANNUNG VAR bereich von e1, bereich von e2;{}    SELECT kartenart [steckplatz] OF{}      CASE kombi    : spannungsbereich 0 bis 5 volt{}      CASE da karte : setze spannungsbereiche{}      CASE ad karte : erfrage adkarte schalterstellungen{}    OTHERWISE alles auf 0 setzen{}    END SELECT.{}  spannungsbereich 0 bis 5 volt:{}    bereich von e1 := SPANNUNG : (0.0, 5.0);{}    bereich von e2 := SPANNUNG : (0.0, 5.0).{}  setze spannungsbereiche:{}
+    bereich von e1 := SPANNUNG : (-5.0, 5.0);{}    bereich von e2 := SPANNUNG : ( 0.0, 5.0).{}  alles auf 0 setzen:{}    bereich von e1 := SPANNUNG : (0.0, 0.0);{}    bereich von e2 := SPANNUNG : (0.0, 0.0).{}erfrage adkarte schalterstellungen:{}  REP{}   hole schalterstellung{}  UNTIL schalterstellung sinnvoll PER;{}  bestimme spannungsbereiche (schalterzustand, bereich von e1, bereich von e2).{}  hole schalterstellung:{}    TEXT VAR schalterzustand := menuanswer (infotext, "00000000", 5).{}  infotext:{}
+    ueberschrift{}    + "  Bitte die aktuelle Schalterstellung eintragen: "13""13""{}    + "  Es bedeutet :  1  -  Schalterstellung 'on'     "13""{}    + "                 0  -  Schalterstellung 'off'    "13""13""{}    + " Nummer : 12345678 "13""{}    + "          |||||||| ".{} ueberschrift:{}   IF steckplatzart = mehrfach{}      THEN " "15"Angabe der Schalterstellungen auf der A/D-Karte "14""13""{}         + " "15"                in Steckplatz "{}         + text (steckplatz) + ":                "14""13""13""{}
+      ELSE " "15"Angabe der Schalterstellungen auf der A/D-Karte: "14""13""13""{}   FI.{} schalterstellung sinnvoll:{}   (length (schalterzustand) = 8) AND nur nullen und einsen.{} nur nullen und einsen:{}   BOOL VAR ok := TRUE; INT VAR m;{}   FOR m FROM 1 UPTO 8 REP{}     IF NOT ((schalterzustand SUB m) = "1" OR (schalterzustand SUB m ) = "0"){}        THEN ok := FALSE{}     FI{}   PER;{}   ok.{}END PROC trage steckplatzbelegung ein;{}INT PROC ermittelte kartenart (INT CONST steckplatz):{}  TEXT CONST info e ::  "     "15"Angabe der Interfacekarte: "14"    "13""13""{}
+                      + "     k   Kombikarte              "13""{}                      + "     e   E / A - Karte           "13""{}                      + "     d   D / A - Wandler - Karte "13""{}                      + "     a   A / D - Wandler - Karte "13""{}                      + "     0   Keine Steckkarte        ",{}             info m ::  "  "15"Angabe der Interfacekarte für Steckplatz "{}                      + text (steckplatz) + ": "14" "13""13""{}                      + "             k   Kombikarte              "13""{}
+                      + "             e   E / A - Karte           "13""{}                      + "             d   D / A - Wandler - Karte "13""{}                      + "             a   A / D - Wandler - Karte "13""{}                      + "             0   Keine Steckkarte        ",{}             liste  :: "Kombi"13"E/A"13"D/A"13"A/D"13"Keine",{}             tasten :: "keda0KEDA";{}   INT VAR auswahl := menualternative (infotext, liste, tasten, 5, FALSE);{}   SELECT auswahl OF{}     CASE 1, 101, 106 :  kombi{}
+     CASE 2, 102, 107 :  eakarte{}     CASE 3, 103, 108 :  dakarte{}     CASE 4, 104, 109 :  adkarte{}     OTHERWISE           keine karte{}   END SELECT.{}   infotext:{}     IF steckplatz = 0{}        THEN info e{}        ELSE info m{}     FI.{}END PROC ermittelte kartenart;{}PROC zeige kanalbelegung (INT  CONST steckplatz):{}   ROW 4 TEXT VAR kanalnummer;{}   kanalnummer [1] := text (steckplatz + 1, 2);{}   kanalnummer [2] := text (steckplatz + 2, 2);{}   kanalnummer [3] := text (steckplatz + 3, 2);{}
+   kanalnummer [4] := text (steckplatz + 4, 2);{}   IF steckplatzart = compact{}      THEN zeige compactboxbelegung{}      ELSE zeige steckplatz mit karte{}   FI.{}  zeige steckplatz mit karte:{}    SELECT kartenart [steckplatznummer] OF{}      CASE kombi  : zeige steckplatz mit kombi{}      CASE eakarte: zeige steckplatz mit eakarte{}      CASE dakarte: zeige steckplatz mit dakarte{}      CASE adkarte: zeige steckplatz mit adkarte{}      OTHERWISE     zeige steckplatz ohne karte{}    END SELECT.{}
+  steckplatznummer:{}    IF steckplatz = 0{}       THEN 1{}       ELSE steckplatz DIV 10{}    FI.{}  zeige compactboxbelegung:{}    menuinfo ({}      "              "15"Eingestellt: Compactbox "14"         "13""13""{}    + "                 Belegung der Kanäle:               "13""13""13""{}    + kanalnummeranzeige kombikarte).{}  zeige steckplatz mit kombi:{}    menuinfo (ueberschrift + " mit Kombikarte: "14"    "13""13""{}    + "                Belegung der Kanäle:               "13""13""13""{}    + kanalnummeranzeige kombikarte).{}
+  zeige steckplatz mit eakarte:{}    menuinfo (ueberschrift + " mit E / A - Karte: "14"    "13""13""{}    + "                Belegung der Kanäle:               "13""13""13""{}    + kanalnummeranzeige eakarte).{}  zeige steckplatz mit dakarte:{}    menuinfo (ueberschrift + " mit D / A - Karte: "14"    "13""13""{}    + "                Belegung der Kanäle:               "13""13""{}    + kanalnummeranzeige dakarte).{}  zeige steckplatz mit adkarte:{}    hole spannungsbereiche;{}    menuinfo ("     " + ueberschrift + " mit A / D - Karte: "14""13""13""{}
+    + "           Zwei analoge Eingänge stehen zur Verfügung:   "13""13""{}    + kanalnummeranzeige adkarte).{}  hole spannungsbereiche:{}    SPANNUNG VAR e1 bereich, e2 bereich;{}    hole spannungsbereich (steckplatz + 1, e1 bereich [1], e1 bereich [2]);{}    hole spannungsbereich (steckplatz + 2, e2 bereich [1], e2 bereich [2]).{}  zeige steckplatz ohne karte:{}    IF steckplatz = 0{}       THEN menuinfo ({}            "    "15"Einzelsteckplatz ohne Steckkarte: "14"   "13""13""13""{}          + " Es sind weder Ein- noch Ausgaben möglich! "13""){}
+       ELSE menuinfo ({}            "        "15"Steckplatz "{}          + text (steckplatz DIV 10) + " ohne Steckkarte: "14""13""13""13""{}          + " Es sind hier weder Ein- noch Ausgaben möglich! "13""){}    FI.{}  ueberschrift:{}    IF steckplatz = 0{}       THEN "         "15"Einzelsteckplatz"{}       ELSE "           "15"Steckplatz " + text (steckplatz DIV 10){}    FI.{}  kanalnummeranzeige kombikarte:{}      "     "15"Kanal " + kanalnummer [1]{}                             + ": "14"  Analogeingang 1 (E1) "13""13""{}
+    + "     "15"Kanal " + kanalnummer [2]{}                             + ": "14"  Analogeingang 2 (E2) "13""13""{}    + "     "15"Kanal " + kanalnummer [3]{}                             + ": "14"  Digitaleingang       "13""13""{}    + "     "15"Kanal " + kanalnummer [4]{}                             + ": "14"  Digitalausgang       "13"".{}  kanalnummeranzeige eakarte:{}    "     "15"Kanal " + kanalnummer [1]{}    + ": "14"  Digitaleingang "13""13""{}    + "     "15"Kanal " + kanalnummer [2]{}    + ": "14"  Digitalausgang "13""13""{}
+    + "   ( "15"Kanal " + kanalnummer [3]{}    + ": "14"  Digitaleingang (= Kanal " + kanalnummer [1] + ") )"13""13""{}    + "   ( "15"Kanal " + kanalnummer [4]{}    + ": "14"  Digitalausgang (= Kanal " + kanalnummer [2] + ") )"13"".{}  kanalnummeranzeige adkarte:{}      "  "15"Kanal " + kanalnummer [1]{}                     + ": "14" (E1)  Spannungsbereich  " + bereich1 + ""13""13""{}    + "  "15"Kanal " + kanalnummer [2]{}                     + ": "14" (E2)  Spannungsbereich  " + bereich2 + ""13"".{}
+  bereich1:{}    IF e1 bereich [1] = 0.0{}       THEN "  0.000 V  -  +" + text (e1 bereich [2], 6, 3) + " V  "{}       ELSE text (e1 bereich [1], 7, 3) + " V  -  +" + text (e1 bereich [2], 6, 3) + " V  "{}    FI.{}  bereich2:{}    IF e2 bereich [1] = 0.0{}       THEN "  0.000 V  -  +" + text (e2 bereich [2], 6, 3) + " V"{}       ELSE text (e2 bereich [1], 7, 3) + " V  -  +" + text (e2 bereich [2], 6, 3) + " V"{}    FI.{}  kanalnummeranzeige dakarte:{}      "  Die Karte stellt einen Analogausgang zur Verfügung, "13""{}
+    + "  der auf zwei Arten angesprochen werden kann:        "13""13""13""{}    + "     "15"Kanal " + kanalnummer [1]{}                               + ": "14"  Spannungsbereich  -5 V  -  +5 V "13""13""{}    + "     "15"Kanal " + kanalnummer [2]{}                               + ": "14"  Spannungsbereich   0 V  -  +5 V "13"".{}END PROC zeige kanalbelegung;{}PROC bestimme spannungsbereiche (TEXT CONST schalterstellung,{}                                 SPANNUNG VAR bereich von e1,{}                                 SPANNUNG VAR bereich von e2):{}
+  bestimme bereich von e1;{}  bestimme bereich von e2.{}  bestimme bereich von e1:{}    IF   schalter 3 geschlossen{}         THEN umax1 :=  0.25{}    ELIF schalter 2 geschlossen{}         THEN umax1 :=  2.5{}    ELIF schalter 1 geschlossen{}         THEN umax1 := 25.0{}         ELSE umax1 :=  0.0{}    FI;{}    IF schalter 8 geschlossen{}       THEN symmetrische spannungsmessung ueber e1{}       ELSE asymmetrische spannungsmessung ueber e1{}    FI.{}    schalter 1 geschlossen:  (schalterstellung SUB 1) = on.{}
+    schalter 2 geschlossen:  (schalterstellung SUB 2) = on.{}    schalter 3 geschlossen:  (schalterstellung SUB 3) = on.{}    schalter 8 geschlossen:  (schalterstellung SUB 8) = on.{}    umin1:  bereich von e1 [1].{}    umax1:  bereich von e1 [2].{}  symmetrische spannungsmessung ueber e1:{}    umax1 := umax1 / 2.0;{}    umin1 := - umax1.{}  asymmetrische spannungsmessung ueber e1:{}    umin1 := 0.0.{}  bestimme bereich von e2:{}    IF   schalter 6 geschlossen{}         THEN umax2 :=  0.25{}    ELIF schalter 5 geschlossen{}
+         THEN umax2 :=  2.5{}    ELIF schalter 4 geschlossen{}         THEN umax2 := 25.0{}         ELSE umax2 :=  0.0{}    FI;{}    IF schalter 7 geschlossen{}       THEN symmetrische spannungsmessung ueber e2{}       ELSE asymmetrische spannungsmessung ueber e2{}    FI.{}    schalter 4 geschlossen:  (schalterstellung SUB 4) = on.{}    schalter 5 geschlossen:  (schalterstellung SUB 5) = on.{}    schalter 6 geschlossen:  (schalterstellung SUB 6) = on.{}    schalter 7 geschlossen:  (schalterstellung SUB 7) = on.{}
+    umin2:  bereich von e2 [1].{}    umax2:  bereich von e2 [2].{}  symmetrische spannungsmessung ueber e2:{}    umax2 := umax2 / 2.0;{}    umin2 := - umax2.{}  asymmetrische spannungsmessung ueber e2:{}    umin2 := 0.0.{}  on:  "1".{}END PROC bestimme spannungsbereiche{}END PACKET ls prozess 5{}
+
diff --git a/prozess/ls-Prozess-gen b/prozess/ls-Prozess-gen
new file mode 100644
index 0000000..b93e4b9
--- /dev/null
+++ b/prozess/ls-Prozess-gen
@@ -0,0 +1,146 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                    ls-Prozess/gen                    ** 
+         **                                                      ** 
+         **                     Version 1.02                     ** 
+         **                                                      ** 
+         **                  (Stand : 26.01.90)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **         Autoren: Bruno Pollok, Bielefeld             ** 
+         **                  Wolfgang Weber, Bielefeld           ** 
+         **                                                      ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+WINDOW VAR fenster := window (1, 1, 79, 24); 
+TEXT CONST titel        :: ""15"ls-Prozess :  Automatische Generierung "14"",
+           ueberschrift :: "Auswahl der Interface-Anpassung",
+           hinweis      :: "Bitte gewünschte Anpassung ankreuzen!";
+TEXT VAR   anpassung;
+BOOL VAR   alles okay;
+frage nach diskette;
+IF alles okay
+   THEN installation
+FI;
+PROC installation:
+  THESAURUS VAR thes :: infix namen (ALL archive, "ls-Prozess 1");
+  anpassung := boxone (fenster, thes, ueberschrift, hinweis, FALSE);
+  cursor (1, 3);
+  out (""4"");
+  IF anpassung <> ""
+     THEN installiere ls prozess
+     ELSE warnung
+  FI.
+  warnung:
+    out (""7"");
+    line (2);
+    out ("    FEHLER: Es muß unbedingt eine Anpassung ausgewaehlt werden!");
+    cursor (5, 7);
+    IF no ("Generierung abbrechen")
+       THEN installation
+    FI.
+END PROC installation;
+PROC installiere ls prozess:
+  forget ("ls-Prozess/gen", quiet);
+  frage evtl nach interfacekanal;
+  check off;
+  warnings off;
+  installiere (anpassung);
+  installiere ("ls-Prozess 2");
+  installiere ("ls-Prozess 3");
+  installiere ("ls-Prozess 4");
+  installiere ("ls-Prozess 5");
+
+  installiere ("ls-MENUKARTE:Prozess");
+  check on;
+  release (archive);
+  setze ggf interface kanal;
+  global manager.
+  frage evtl nach interfacekanal:
+    IF adapter fuer separate schnittstelle
+       THEN erfrage kanalnummer
+    FI.
+  erfrage kanalnummer:
+    INT VAR kanalnummer;
+    line (2);
+    REP put ("    Gib Interfacekanal:");
+        get (kanalnummer);
+        IF kanalnummer < 1 OR kanalnummer > 24
+           THEN out (""7"    Unzulaessige Kanalnummer!");
+                line (2)
+
+        FI
+    UNTIL kanalnummer > 0 AND kanalnummer < 25 PER;
+    cursor (1, 3);
+    out (""4"").
+  setze ggf interfacekanal:
+    IF adapter fuer separate schnittstelle
+       THEN do ("interface kanal (" + text (kanalnummer) + ")")
+    FI.
+  adapter fuer separate schnittstelle:
+    (anpassung = "ls-Prozess 1 für AKTRONIC-Adapter") OR
+    (anpassung = "ls-Prozess 1 für MUFI als Endgerät").
+END PROC installiere ls prozess;
+PROC installiere (TEXT CONST datei):
+  INT VAR zeile, spalte;
+
+  hole datei vom archiv;
+  IF datei = "ls-MENUKARTE:Prozess"
+     THEN schicke zu menukarten task
+     ELSE insertiere
+  FI.
+  hole datei vom archiv:
+    line (2);
+    out ("'" + datei + "' ");
+    get cursor (spalte, zeile);
+    IF NOT exists (datei)
+       THEN out ("wird von der Archivdiskette geholt.");
+            fetch (datei, archive)
+    FI.
+  insertiere:
+    cursor (spalte, zeile);
+    out (""5"");
+    out ("wird insertiert.");
+    insert (datei);
+    cursor (spalte, zeile);
+
+    out (""4"");
+    forget (datei, quiet).
+  schicke zu menukarten task:
+    cursor (spalte, zeile);
+    out (""5"");
+    command dialogue (FALSE);
+    save (datei, /"ls-MENUKARTEN");
+    command dialogue (TRUE);
+    forget (datei, quiet).
+END PROC installiere;
+PROC frage nach diskette:
+  page;
+  out (center (fenster, titel));
+  line (4);
+  putline ("      Ist das Archiv angemeldet,");
+  putline ("      die Diskette mit 'ls-Prozess' eingelegt");
+  IF yes  ("      und das Laufwerk geschlossen")
+
+     THEN alles okay := TRUE
+     ELSE alles okay := FALSE;
+          warnung
+  FI.
+  warnung:
+    line (3);
+    out ("      FEHLER : Diskettenzugriff nicht gesichert!"7"");
+    line (2);
+    out ("      Bitte Fehler beseitigen und Programm neu starten!");
+    line (5)
+END PROC frage nach diskette;
+
+
diff --git a/system/crypt b/system/crypt
new file mode 100644
index 0000000..b04728a
--- /dev/null
+++ b/system/crypt
@@ -0,0 +1,138 @@
+(* ------------------- VERSION 2 vom 21.04.86 ------------------- *)
+PACKET cryptograf DEFINES                     (* Autor: J.Liedtke *)
+
+  crypt ,
+  decrypt :
+ 
+TEXT VAR char , in buffer, out buffer ;
+INT VAR in pos , key index ;
+DATASPACE VAR scratch space ;
+FILE VAR in, out;
+ 
+PROC crypt (TEXT CONST file, key) :
+ 
+  open (file) ;
+  initialize crypt (key) ;
+  WHILE NOT eof REP
+    read char ;
+    crypt char ;
+    write char
+  PER ;
+  close (file) .
+ 
+crypt char :
+  char := code (( character + random char + key char ) MOD 250) ;
+  IF key index = LENGTH key
+    THEN key index := 1
+    ELSE key index INCR 1
+  FI .
+ 
+character   : code (char) .
+ 
+random char : random (0,250).
+ 
+key char    : code (key SUB key index) .
+ 
+ENDPROC crypt ;
+ 
+PROC decrypt (TEXT CONST file, key) :
+ 
+  open (file) ;
+  initialize crypt (key) ;
+  WHILE NOT eof REP
+    read char ;
+    decrypt char ;
+    write char
+  PER ;
+  close (file) .
+ 
+decrypt char :
+  char := code (( character - random char - key char ) MOD 250) ;
+  IF key index = LENGTH key
+    THEN key index := 1
+    ELSE key index INCR 1
+  FI .
+ 
+character   : code (char) .
+ 
+random char : random (0,250) .
+ 
+key char    : code (key SUB key index) .
+ 
+ENDPROC decrypt ;
+ 
+PROC initialize crypt (TEXT CONST key) :
+ 
+  INT VAR random key := 0 ;
+  FOR key index FROM 1 UPTO LENGTH key REP
+    random key := (random key + code (key SUB key index)) MOD 32000
+  PER ;
+  initialize random (random key) ;
+  key index := 1
+ 
+ENDPROC initialize crypt ;
+ 
+PROC open (TEXT CONST source file) :
+ 
+  in := sequential file (input, source file) ;
+  getline (in, in buffer) ;
+  in pos := 1 ;
+  forget (scratch space) ; 
+  scratch space := nilspace ; 
+  out := sequential file (output, scratch space) ;
+  out buffer := "" .
+ 
+ENDPROC open ;
+ 
+PROC close (TEXT CONST source file) :
+ 
+  IF out buffer <> ""
+    THEN putline (out, out buffer)
+  FI ;
+  forget (source file, quiet) ;
+  copy (scratch space, source file) ;
+  forget (scratch space) .
+ 
+ENDPROC close ;
+ 
+BOOL PROC eof :
+ 
+  IF in pos > LENGTH in buffer
+    THEN eof (in)
+    ELSE FALSE
+  FI
+ 
+ENDPROC eof ;
+ 
+PROC read char :
+ 
+  IF in pos > 250
+    THEN getline (in, in buffer) ;
+         in pos := 1 ;
+         read char
+  ELIF in pos > LENGTH in buffer
+    THEN in pos := 1 ;
+         getline (in, in buffer) ;
+         char := ""13""
+    ELSE char := in buffer SUB in pos ;
+         in pos INCR 1
+  FI .
+ 
+ENDPROC read char ;
+ 
+PROC write char :
+ 
+  IF char = ""13""
+    THEN putline (out, out buffer) ;
+         out buffer := ""
+    ELSE out buffer CAT char
+  FI ;
+  IF LENGTH out buffer = 250
+    THEN putline (out, out buffer) ;
+         out buffer := ""
+  FI .
+ 
+ENDPROC write char ;
+ 
+ENDPACKET cryptograf ;
+
diff --git a/system/eumel printer.5 b/system/eumel printer.5
new file mode 100644
index 0000000..e61a073
--- /dev/null
+++ b/system/eumel printer.5	
@@ -0,0 +1,3473 @@
+PACKET eumel printer                           (* Autor   : Rudolf Ruland *)
+                                               (* Version : 5             *)
+                                               (* Stand   : 25.04.88      *)
+       DEFINES print, 
+               with elan listings,
+               is elan source,
+               bottom label for elan listings,
+               x pos,
+               y pos,
+               y offset index,
+               line type,
+               material,
+               pages printed,
+ 
+(* >>> ***************************************************************** <<< *)
+(* >>> Aus Kompatibilitätsgründen zur Textverarbeitung der Version 1.8.0 <<< *)
+(* >>> siehe bei 'Berechnung des Zeilenvorschubs'                        <<< *)
+ 
+               old linefeed :
+ 
+BOOL VAR old linefeed calculation := TRUE;
+ 
+PROC old linefeed (BOOL CONST value) : old linefeed calculation := value END PROC old linefeed;
+ 
+BOOL PROC old linefeed : old linefeed calculation END PROC old linefeed;
+ 
+(* >>> ***************************************************************** <<< *)
+ 
+INT CONST int length  :=  length of one int;
+
+. length of one int :
+    INT VAR int counter := 0, int value := max int;
+    REP int counter INCR 1;
+        int value   := int value DIV 256;
+    UNTIL int value = 0 PER;
+    int counter
+.;
+
+(* >>> ***************************************************************** <<< *)
+ 
+LET std x wanted                   =  2.54,
+    std y wanted                   =  2.35,
+    std limit                      =  16.0,
+    std pagelength                 =  25.0,
+    std linefeed faktor            =  1.0,
+    std material                   =  "";
+ 
+LET blank                          =  " ",
+    blank code 1                   =  33,
+    geschuetztes blank             =  ""223"", 
+    keine blankanalyse             =  0,
+    einfach blank                  =  1,
+    doppel blank                   =  2,
+ 
+    anweisungszeichen              =  "#",
+    anweisungszeichen code 1       =  36,
+    geschuetztes anweisungszeichen =  ""222"",
+    druckerkommando zeichen        =  "/",
+    quote                          =  """",
+    kommentar zeichen              =  "-",
+ 
+    punkt                          =  ".",
+ 
+    leer                           =   0,
+ 
+    kommando token                 =  0,
+    text token                     =  1,
+ 
+    underline linetype             =  1,
+(*  fraction  linetype             =  2,
+    root      linetype             =  3,
+*)
+    underline bit                  =  0,
+    bold bit                       =  1,
+    italics bit                    =  2,
+    modifikations liste            =  "ubir",
+    anzahl modifikationen          =  4, 
+ 
+    document                       =  1,
+    page                           =  2,
+ 
+    write text                     =  1,
+    write cmd                      =  2,
+    carriage return                =  3, 
+    move                           =  4,
+    draw                           =  5,
+    on                             =  6, 
+    off                            =  7,
+    type                           =  8,
+ 
+    text code                      =  1, 
+(*  error code                     =  2, *)
+    token code                     =  3,
+     
+    tag type                       =  1,
+    bold type                      =  2,
+    number type                    =  3,
+    text type                      =  4,
+    delimiter type                 =  6,
+    eof type                       =  7;
+ 
+ 
+INT CONST null ausgang            :=  minint,
+          erweiterungs ausgang    :=  maxint,
+          blank ausgang           :=  maxint - 1,
+          anweisungs ausgang      :=  maxint - 2,
+          d code ausgang          :=  maxint - 3,
+          max breite              :=  maxint - 4,
+ 
+          linien token            := -1;
+ 
+ROW anzahl modifikationen INT CONST modifikations werte :=
+                               ROW anzahl modifikationen INT : (1, 2, 4, 8);
+ 
+TEXT CONST anweisungsliste := 
+    "type:1.1on:2.1off:3.1center:4.0right:5.0u:6.0d:7.0e:8.0b:9.0" +
+    "fillchar:10.1mark:11.2markend:12.0" +
+    "ub:13.0ue:14.0fb:15.0fe:16.0" +
+    "block:20.0columns:21.2columnsend:22.0free:23.1limit:24.1linefeed:25.1" + 
+    "material:26.1page:27.01pagelength:29.1start:30.2" + 
+    "table:31.0tableend:32.0clearpos:33.01" + 
+    "lpos:35.1rpos:36.1cpos:37.1dpos:38.2bpos:39.2" +
+    "textbegin:40.02textend:42.0" +
+    "indentation:43.1ytab:44.1";
+ 
+LET a type             =   1,      a block            =  20,
+    a on               =   2,      a columns          =  21,
+    a off              =   3,      a columnsend       =  22,
+    a center           =   4,      a free             =  23,
+    a right            =   5,      a limit            =  24,
+    a up               =   6,      a linefeed         =  25,
+    a down             =   7,      a material         =  26,
+    a end up or down   =   8,      a page0            =  27,
+    a bsp              =   9,      a page1            =  28,
+    a fill char        =  10,      a pagelength       =  29,
+    a mark             =  11,      a start            =  30,
+    a markend          =  12,      a table            =  31,
+    a ub               =  13,      a tableend         =  32,
+    a ue               =  14,      a clearpos0        =  33,
+    a fb               =  15,      a clearpos1        =  34,
+    a fe               =  16,      a lpos             =  35,
+                                   a rpos             =  36,
+                                   a cpos             =  37,
+                                   a dpos             =  38,
+                                   a bpos             =  39,
+                                   a textbegin0       =  40,
+                                   a textbegin2       =  41,
+                                   a textend          =  42,
+                                   a indentation      =  43,
+                                   a y tab            =  44;
+ 
+INT VAR  a xpos, a breite, a font, a modifikationen,
+         a modifikationen fuer x move, a ypos, aktuelle ypos,
+         letzter font, letzte modifikationen,
+         d ypos, d xpos, d font, d modifikationen, 
+ 
+         zeilenpos, alte zeilenpos, zeilen laenge, anzahl zeichen, ausgang,
+         anzahl einrueck blanks, blankbreite, fuehrende anweisungen,
+         einrueckbreite, aktuelle einrueckbreite, alte einrueckbreite,
+         aktuelle zeilentiefe der letzten zeile,
+         blankmodus, alter blankmodus,
+         token zeiger, erstes token der zeile, 
+ 
+         erstes tab token, tab anfang, anzahl blanks, 
+         d code 1, d pitch, fuell zeichen breite, erstes fuell token, 
+         letztes fuell token, 
+ 
+         x size, y size, x wanted, y wanted, x start, y start,
+         pagelength, limit, indentation,
+         left margin, top margin, seitenlaenge,
+         papierlaenge, papierbreite,
+         luecke, anzahl spalten, aktuelle spalte,
+ 
+         verschiebung, linien verschiebung,
+         rest, neue modifikationen, modifikations modus, pass,
+ 
+         int param, anweisungs index, anzahl params,
+ 
+         gedruckte seiten;
+ 
+BOOL VAR zeile ist absatzzeile, letzte zeile war absatzzeile,
+         zeile muss geblockt werden, rechts, a block token, offsets,
+         tabellen modus, block modus, center modus, right modus,
+         seite ist offen, vor erster seite;
+ 
+REAL VAR linefeed faktor, real param;
+ 
+TEXT VAR zeile, anweisung, par1, par2, material wert, replacements,
+         fuell zeichen, d string, font offsets;
+ 
+ROW 256 INT VAR zeichenbreiten, replacement tabelle, zeichen zaehler;
+ 
+INITFLAG VAR in dieser task := FALSE;
+ 
+. zeile ist zu ende               : zeilenpos > zeilen laenge
+ 
+. zeilen breite                   : a xpos - left margin
+ 
+. naechstes zeichen ist blank     : pos (zeile, blank, zeilenpos + 1, zeilenpos + 1) <> 0
+ 
+. naechstes nicht blankes zeichen : pos (zeile, ""33"", ""255"", zeilenpos)
+ 
+. in letzter spalte               : aktuelle spalte >= anzahl spalten
+ 
+. anfangs blankmodus :
+    INT VAR dummy;
+    IF   center modus OR right modus
+         THEN dummy
+    ELIF index zaehler = 0
+         THEN blankmodus
+         ELSE alter blankmodus
+    FI
+ 
+. initialisiere tab variablen : 
+    erstes tab token := token index f + 1;
+    tab anfang       := zeilen breite;
+    anzahl blanks    := 0;
+    a block token    := FALSE;
+.;
+ 
+(******************************************************************)
+ 
+LET zeilen nr laenge  =  4,
+    teil einrueckung  =  5,
+ 
+    headline pre  = "Zeile    ****   E L A N    EUMEL 1.8.2  ****   ",
+    headline post = "   ****    ";
+ 
+INT  VAR zeilen nr, rest auf seite,
+         max zeichen zeile, max zeichen fuss, layout laenge, layout laenge name,
+         symbol type, naechster symbol type, select counter;
+ 
+BOOL VAR vor erstem packet, innerhalb einer liste;
+ 
+TEXT VAR bottom label, dateiname, layout blanks, refinement layout zeile;
+ 
+ 
+. symbol           : fuell zeichen
+. naechstes symbol : d string
+. elan text        : d token. text
+.; 
+ 
+(******************************************************************)
+(*** Berechnung des Zeilenvorschubs                             ***)
+ 
+INT VAR                 fonthoehe,                fonttiefe, fontdurchschuss,
+         groesste       fonthoehe, groesste       fonttiefe,
+         groesste analysatorhoehe, groesste analysatortiefe,
+         letzte   zeilenhoehe, letzte   zeilentiefe, 
+         aktuelle zeilenhoehe, aktuelle zeilentiefe;
+REAL VAR real fontgroesse;
+ 
+.          fontgroesse   :          fonthoehe   +          fonttiefe
+. groesste fontgroesse   : groesste fonthoehe   + groesste fonttiefe
+. letzte   zeilengroesse : letzte   zeilenhoehe + letzte   zeilentiefe
+. aktuelle zeilengroesse : aktuelle zeilenhoehe + aktuelle zeilentiefe
+ 
+.
+  initialisiere zeilenvorschub :
+    aktuelle zeilenhoehe     := letzte zeilenhoehe;
+    aktuelle zeilentiefe     := letzte zeilentiefe;
+    groesste fonthoehe       := fonthoehe;
+    groesste fonttiefe       := fonttiefe;
+    groesste analysatorhoehe := 0;
+    groesste analysatortiefe := 0;
+ 
+.
+  ueberpruefe groesste fontgroesse :
+    IF old linefeed calculation
+       THEN
+(* >>> Maximumsbestimmung über Fontgröße ******************************* <<< *)
+            IF fontgroesse >= groesste fontgroesse
+               THEN groesste fonthoehe := fonthoehe;
+                    groesste fonttiefe := fonttiefe;
+            FI;
+       ELSE
+(* >>> Maximumsbestimmung über Fonthöhe und Fonttiefe ****************** <<< *)
+            groesste fonthoehe := max (fonthoehe, groesste fonthoehe);
+            groesste fonttiefe := max (fonttiefe, groesste fonttiefe);
+    FI;
+ 
+.
+  berechne fontgroesse :
+    fonthoehe INCR (fontdurchschuss DIV 2 + fontdurchschuss MOD 2);
+    fonttiefe INCR  fontdurchschuss DIV 2;
+    real fontgroesse := real (fontgroesse);
+ 
+.
+  berechne letzte zeilengroesse :
+    REAL CONST zeilengroesse := real fontgroesse * linefeed faktor;
+    letzte zeilenhoehe := int (real (fonthoehe) * zeilengroesse / real fontgroesse + 0.5);
+    letzte zeilentiefe := int (zeilengroesse + 0.5) - letzte zeilenhoehe;
+.;
+ 
+PROC berechne aktuelle zeilengroesse :
+ 
+    IF linefeed faktor >= 1.0
+       THEN aktuelle zeilenhoehe := max (groesste fonthoehe, letzte zeilenhoehe);
+            aktuelle zeilentiefe := max (groesste fonttiefe, letzte zeilentiefe);
+       ELSE
+            IF old linefeed calculation
+               THEN
+(* >>> Maximumsbestimmung über Fontgröße ******************************* <<< *)
+                    IF letzte zeilengroesse >= aktuelle zeilengroesse
+                       THEN aktuelle zeilenhoehe := letzte zeilenhoehe;
+                            aktuelle zeilentiefe := letzte zeilentiefe;
+                    FI;
+               ELSE
+(* >>> Maximumsbestimmung über Fonthöhe und Fonttiefe ****************** <<< *)
+                    aktuelle zeilenhoehe := max (letzte zeilenhoehe, aktuelle zeilenhoehe);
+                    aktuelle zeilentiefe := max (letzte zeilentiefe, aktuelle zeilentiefe);
+            FI;
+    FI;
+    aktuelle zeilenhoehe := max (groesste analysatorhoehe, aktuelle zeilenhoehe);
+    aktuelle zeilentiefe := max (groesste analysatortiefe, aktuelle zeilentiefe);
+ 
+END PROC berechne aktuelle zeilengroesse;
+ 
+(******************************************************************)
+(*** tokenspeicher                                              ***)
+ 
+LET max number token  = 3000,
+    max number ypos   = 1000,
+ 
+    TOKEN      = STRUCT (TEXT text,
+                         INT  xpos, breite, font, modifikationen,
+                              modifikationen fuer x move, 
+                              offset index, naechster token index, 
+                         BOOL block token ),
+ 
+    YPOS       = STRUCT (INT ypos, vorheriger ypos index, naechster ypos index,
+                             erster token index, letzter token index ), 
+ 
+    TOKENLISTE = STRUCT (ROW max number token TOKEN token liste,
+                         ROW max number ypos  YPOS  ypos  liste );
+ 
+DATASPACE VAR ds;
+ 
+BOUND TOKENLISTE VAR tokenspeicher;
+ 
+TOKEN VAR d token, offset token;
+ 
+INT VAR erster ypos index a, letzter ypos index a, 
+        erster ypos index d, letzter ypos index d, 
+        ypos  index, ypos  index f, ypos  index a, ypos  index d, 
+        token index, token index f;
+ 
+. t  : tokenspeicher. token liste (token index)
+. tf : tokenspeicher. token liste (token index f)
+ 
+. y  : tokenspeicher. ypos  liste (ypos  index) 
+. yf : tokenspeicher. ypos  liste (ypos  index f) 
+. ya : tokenspeicher. ypos  liste (ypos  index a)
+. yd : tokenspeicher. ypos  liste (ypos  index d)
+ 
+. loesche druckspeicher :
+    erster ypos index d := 0;
+           ypos index f := 0;
+          token index f := 0;
+ 
+. druckspeicher ist nicht leer :
+    erster ypos index d <> 0
+ 
+. loesche analysespeicher :
+    erster ypos index a := 0;
+ 
+. analysespeicher ist nicht leer :
+    erster ypos index a <> 0
+.; 
+ 
+(******************************************************************)
+(*** anweisungsspeicher                                         ***)
+ 
+INT  VAR anweisungszaehler;
+TEXT VAR anweisungs indizes, params1 zeiger, params2 zeiger;
+THESAURUS VAR params1, params2; 
+ 
+PROC loesche anweisungsspeicher :
+ 
+    anweisungs zaehler := 0;
+    anweisungs indizes := "";
+    params1 zeiger     := "";
+    params2 zeiger     := "";
+    params1            := empty thesaurus;
+    params2            := empty thesaurus;
+ 
+END PROC loesche anweisungsspeicher; 
+ 
+(******************************************************************)
+(*** indexspeicher                                              ***)
+ 
+INT  VAR index zaehler, hoechster index zaehler;
+TEXT VAR letzte index breite, xpos vor index, zeilenpos nach index, grosse fonts,
+         index verschiebung;
+ 
+PROC loesche indexspeicher :
+ 
+    index zaehler           := 0;
+    hoechster index zaehler := 0;
+    letzte index breite     := "";
+    xpos vor index          := "";
+    zeilenpos nach index    := "";
+    index verschiebung      := "";
+    grosse fonts            := "";
+ 
+END PROC loesche indexspeicher; 
+ 
+ 
+PROC loesche hoehere index level :
+ 
+    IF hoechster index zaehler > index zaehler
+       THEN letzte index breite  := subtext (letzte index breite, 1, int length * index zaehler);
+            xpos vor index       := subtext (xpos vor index, 1, int length * index zaehler);
+            zeilenpos nach index := subtext (zeilenpos nach index, 1, int length * index zaehler);
+            index verschiebung   := subtext (index verschiebung, int length * index zaehler);
+            grosse fonts         := subtext (grosse fonts, 1, int length * index zaehler);
+            hoechster index zaehler := index zaehler;
+    FI;
+ 
+END PROC loesche hoehere index level;
+ 
+(******************************************************************)
+(*** tabellenspeicher                                           ***)
+ 
+LET max tabs          =  30,
+    TABELLENEINTRAG   =  STRUCT (INT tab typ, tab position, tab param);
+ 
+TEXT VAR tab liste, fill char;
+THESAURUS VAR d strings;
+ROW max tabs TABELLENEINTRAG VAR tabspeicher;
+ 
+INT VAR tab index;
+ 
+. tab typ       : tab speicher (tab liste ISUB tab index). tab typ
+. tab position  : tab speicher (tab liste ISUB tab index). tab position
+. tab param     : tab speicher (tab liste ISUB tab index). tab param 
+. anzahl tabs   : LENGTH tab liste DIV int length 
+.;
+ 
+PROC loesche tabellenspeicher :
+ 
+    fill char := " ";
+    tabliste  := "";
+    d strings := empty thesaurus;
+    FOR tab index FROM 1 UPTO max tabs
+        REP tab speicher (tab index). tab typ := leer PER;
+ 
+END PROC loesche tabellenspeicher;
+ 
+(******************************************************************)
+(*** markierungsspeicher                                        ***)
+ 
+INT VAR mark index l, mark index r, alter mark index l, alter mark index r;
+ 
+ROW 4 TOKEN VAR mark token;
+ 
+. markierung links  : mark index l > 0
+. markierung rechts : mark index r > 0
+.;
+ 
+PROC loesche markierung :
+ 
+     mark index l := 0;
+     mark index r := 0;
+ 
+END PROC loesche markierung;
+ 
+ 
+PROC loesche alte markierung :
+ 
+     alter mark index l := 0;
+     alter mark index r := 0;
+ 
+END PROC loesche alte markierung;
+ 
+ 
+PROC initialisiere markierung :
+ 
+     FOR mark index l FROM 1 UPTO 4
+     REP mark token (mark index l). modifikationen fuer x move := 0;
+         mark token (mark index l). offset index               := text token;
+         mark token (mark index l). block token                := FALSE;
+         mark token (mark index l). naechster token index      := 0;
+     PER;
+ 
+END PROC initialisiere markierung;
+ 
+(******************************************************************)
+(*** durchschuss                                                ***)
+ 
+INT VAR durchschuss 1, durchschuss 2, anzahl durchschuss 1, 
+        anzahl durchschuss, zeilen zaehler;
+ 
+BOOL VAR wechsel := TRUE;
+ 
+INT PROC durchschuss :
+ 
+     zeilen zaehler INCR 1;
+     IF   zeilen zaehler <= anzahl durchschuss 1
+          THEN durchschuss 1
+     ELIF zeilen zaehler <= anzahl durchschuss 
+          THEN durchschuss 2
+          ELSE 0
+     FI
+ 
+END PROC durchschuss;
+ 
+ 
+PROC neuer durchschuss (INT CONST anzahl, rest l) :
+ 
+     zeilen zaehler     := 0;
+     anzahl durchschuss := anzahl;
+     IF anzahl > 0 
+        THEN IF wechsel
+                THEN durchschuss 1        := rest l DIV anzahl durchschuss;
+                     durchschuss 2        := durchschuss 1 + sign (rest l);
+                     anzahl durchschuss 1 := anzahl durchschuss -
+                                             abs (rest l) MOD anzahl durchschuss;
+                     wechsel              := FALSE;
+                ELSE durchschuss 2        := rest l DIV anzahl durchschuss; 
+                     durchschuss 1        := durchschuss 2 + sign (rest l);
+                     anzahl durchschuss 1 := abs (rest l) MOD anzahl durchschuss;
+                     wechsel              := TRUE;
+             FI;
+        ELSE loesche durchschuss
+     FI;
+ 
+END PROC neuer durchschuss;
+ 
+ 
+PROC loesche durchschuss :
+ 
+     durchschuss 1           := 0;
+     durchschuss 2           := 0;
+     anzahl durchschuss 1    := 0;
+     anzahl durchschuss      := 0;
+     zeilen zaehler          := 0;
+ 
+END PROC loesche durchschuss;
+ 
+(****************************************************************)
+ 
+PROC initialisierung :
+ 
+  INT VAR index;
+  forget (ds);
+  ds := nilspace; tokenspeicher := ds;
+  loesche druckspeicher;
+  loesche anweisungsspeicher;
+  loesche indexspeicher;
+  initialisiere markierung;
+  right  modus                 := FALSE;
+  center modus                 := FALSE;
+  seite ist offen              := FALSE;
+  pass                         := 0;
+  a breite                     := 0;
+  a modifikationen fuer x move := 0;
+  aktuelle zeilentiefe der letzten zeile := 0;
+  d code 1                     := leer;
+  erstes fuell token           := leer;
+  IF two bytes
+     THEN FOR index FROM   1 UPTO 129 REP zeichen zaehler (index) := 1 PER; 
+          FOR index FROM 130 UPTO 160 REP zeichen zaehler (index) := - maxint PER;
+          FOR index FROM 161 UPTO 224 REP zeichen zaehler (index) := 1 PER;
+          FOR index FROM 225 UPTO 240 REP zeichen zaehler (index) := - maxint PER;
+          FOR index FROM 241 UPTO 256 REP zeichen zaehler (index) := 1 PER;
+     ELSE FOR index FROM   1 UPTO 256 REP zeichen zaehler (index) := 1 PER; 
+  FI;
+ 
+END PROC initialisierung;
+ 
+(****************************************************************)
+(*** print - Kommando                                         ***)
+ 
+BOOL VAR elan listings erlaubt;
+FILE VAR eingabe;
+THESAURUS VAR elan bolds := empty thesaurus;
+ 
+insert (elan bolds, "PACKET");       insert (elan bolds, "PROC");
+insert (elan bolds, "PROCEDURE");    insert (elan bolds, "OP");
+insert (elan bolds, "OPERATOR");     insert (elan bolds, "LET");
+insert (elan bolds, "ROW");          insert (elan bolds, "STRUCT");
+insert (elan bolds, "TYPE");         insert (elan bolds, "BOUND");
+insert (elan bolds, "IF");           insert (elan bolds, "REP");
+insert (elan bolds, "REPEAT");       insert (elan bolds, "FOR");
+insert (elan bolds, "WHILE");        insert (elan bolds, "SELECT");
+ 
+with elan listings (TRUE);
+ 
+PROC with elan listings (BOOL CONST flag) :
+     elan listings erlaubt := flag;
+END PROC with elan listings;
+ 
+BOOL PROC with elan listings : elan listings erlaubt END PROC with elan listings;
+ 
+ 
+PROC print (FILE VAR 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) :
+ 
+  eingabe := file;
+  input (eingabe);
+  print (PROC (TEXT VAR) lese zeile, BOOL PROC is eof,
+         PROC (INT CONST, INT VAR, INT VAR) open,
+         PROC (INT CONST, INT CONST) close,
+         PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute, 
+         PROC (INT CONST, TEXT VAR,
+               INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) std analysator,
+         elan listings erlaubt CAND is elan source (eingabe), 
+         headline (eingabe) );
+ 
+END PROC print;
+ 
+ 
+PROC print (FILE VAR 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,
+            PROC (INT CONST, TEXT VAR,
+                  INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator ) :
+ 
+  eingabe := file;
+  input (eingabe);
+  print (PROC (TEXT VAR) lese zeile, BOOL PROC is eof,
+         PROC (INT CONST, INT VAR, INT VAR) open,
+         PROC (INT CONST, INT CONST) close,
+         PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute, 
+         PROC (INT CONST, TEXT VAR,
+               INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator,
+         elan listings erlaubt CAND is elan source (eingabe), 
+         headline (eingabe) );
+ 
+END PROC print;
+ 
+PROC lese zeile (TEXT VAR zeile l) : getline (eingabe, zeile l) END PROC lese zeile;
+ 
+BOOL PROC is eof : eof (eingabe) END PROC is eof;
+ 
+ 
+BOOL PROC is elan source (FILE VAR eingabe l) :
+ 
+hole erstes symbol;
+elan programm tag COR elan programm bold COR kommentar COR elanlist anweisung
+ 
+. elan programm tag :
+    symbol type = tag type CAND pos (zeile, ";") > 0 
+ 
+. elan programm bold :
+    symbol type = bold type CAND is elan bold
+ 
+    . is elan bold :
+        (elan bolds CONTAINS symbol) COR deklaration COR proc oder op (naechstes symbol)
+ 
+    . deklaration :
+        next symbol (naechstes symbol);
+        naechstes symbol = "VAR" OR naechstes symbol = "CONST"
+ 
+. kommentar :
+    pos (zeile, "(*") > 0 OR pos (zeile, "{") > 0 
+ 
+. elanlist anweisung :
+    symbol = "#" AND elanlist folgt
+ 
+    . elanlist folgt :
+        next symbol (naechstes symbol);
+        naechstes symbol = "elanlist"
+ 
+. 
+  hole erstes symbol :
+    hole erstes nicht blankes symbol; 
+    scan (zeile);
+    next symbol (symbol, symbol type);
+ 
+    . hole erstes nicht blankes symbol :
+        IF eof (eingabe l) THEN LEAVE is elan source WITH FALSE FI;
+        REP getline (eingabe l, zeile);
+        UNTIL pos (zeile, ""33"",""254"", 1) > 0 OR eof (eingabe l) PER;
+        reset (eingabe l);
+ 
+END PROC is elan source;
+ 
+(****************************************************************)
+ 
+bottom label for elan listings ("");
+ 
+PROC bottom label for elan listings (TEXT CONST label) :
+     bottom label := label;
+END PROC bottom label for elan listings;
+ 
+TEXT PROC bottom label for elan listings : bottom label END PROC bottom label for elan listings;
+ 
+ 
+PROC print (PROC (TEXT VAR) next line, BOOL PROC eof, 
+            PROC (INT CONST, INT VAR, INT VAR) open,
+            PROC (INT CONST, INT CONST) close,
+            PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute,
+            PROC (INT CONST, TEXT VAR,
+                  INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator,
+            BOOL CONST elan listing, TEXT CONST file name) :
+ 
+disable stop;
+gedruckte seiten := 0;
+drucke datei (PROC (TEXT VAR) next line, BOOL PROC eof,
+              PROC (INT CONST, INT VAR, INT VAR) open,
+              PROC (INT CONST, INT CONST) close,
+              PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute,
+              PROC (INT CONST, TEXT VAR,
+                    INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator,
+              elan listing, file name );
+IF is error THEN behandle fehlermeldung FI;
+ 
+. behandle fehlermeldung :
+    TEXT CONST fehler meldung := error message;
+    INT  CONST fehler zeile   := error line,
+               fehler code    := error code;
+    clear error;
+    IF NOT vor erster seite
+       THEN IF seite ist offen
+               THEN schliesse seite ab (PROC (INT CONST, INT CONST) close,
+                    PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute )
+            FI;
+            clear error;
+            close (document, 0);
+            clear error;
+    FI;
+    initialisierung;
+    errorstop (fehler code, fehler meldung (* + " -> " + text (fehler zeile) *) );
+ 
+END PROC print; 
+ 
+d xpos                := 0;
+d ypos                := 0;
+d token. offset index := 1;
+material wert         := "";
+gedruckte seiten      := 0;
+ 
+INT PROC x pos          :   d xpos                END PROC x pos;
+INT PROC y pos          :   d ypos                END PROC y pos;
+INT PROC y offset index :   d token. offset index END PROC y offset index;
+INT PROC linetype       : - d token. offset index END PROC linetype;
+TEXT PROC material      : material wert           END PROC material;
+INT PROC pages printed  : gedruckte seiten        END PROC pages printed;
+ 
+(****************************************************************)
+ 
+PROC drucke datei (PROC (TEXT VAR) next line, BOOL PROC eof,
+                   PROC (INT CONST, INT VAR, INT VAR) open,
+                   PROC (INT CONST, INT CONST) close,
+                   PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute,
+                   PROC (INT CONST, TEXT VAR,
+                         INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator,
+                   BOOL CONST elan listing, TEXT CONST file name ) :
+ 
+ 
+enable stop;
+IF elan listing
+   THEN dateiname := file name;
+        drucke elan listing;
+   ELSE drucke text datei;
+FI;
+ 
+.
+  drucke text datei :
+    initialisiere druck; 
+    WHILE NOT eof
+    REP next line (zeile); 
+        analysiere zeile (PROC (INT CONST, TEXT VAR,
+          INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+        drucke token soweit wie moeglich;
+        werte anweisungsspeicher aus;
+    PER;
+    schliesse druck ab; 
+ 
+. 
+  initialisiere druck :
+    IF NOT initialized (in dieser task)
+       THEN ds := nilspace;
+            initialisierung
+    FI;
+    vor erster seite               := TRUE;
+    tabellen modus                 := FALSE;
+    block modus                    := FALSE;
+    zeile ist absatzzeile          := TRUE;
+    x wanted                       := x step conversion (std x wanted);
+    y wanted                       := y step conversion (std y wanted);
+    limit                          := x step conversion (std limit);
+    pagelength                     := y step conversion (std pagelength);
+    linefeed faktor                := std linefeed faktor;
+    material wert                  := std material;
+    indentation                    := 0;
+    modifikations modus            := maxint; 
+    seitenlaenge                   := maxint;
+    papierlaenge                   := maxint;
+    left margin                    := 0;
+    top  margin                    := 0;
+    a ypos                         := top margin;
+    a font                         := -1;
+    a modifikationen               := 0;
+    aktuelle spalte                := 1;
+    anzahl spalten                 := 1;
+    stelle neuen font ein (1);
+    loesche tabellenspeicher;
+    loesche markierung;
+    loesche alte markierung;
+    loesche durchschuss;
+ 
+. 
+  schliesse druck ab :
+    IF NOT vor erster seite
+       THEN IF seite ist offen
+               THEN schliesse seite ab (PROC (INT CONST, INT CONST) close,
+                    PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute )
+            FI;
+            close (document, 0);
+    FI;
+ 
+.
+  drucke token soweit wie moeglich :
+    IF analysespeicher ist nicht leer
+       THEN letztes token bei gleicher ypos; 
+            IF NOT seite ist offen
+               THEN eroeffne seite (x wanted, y wanted,
+                                  PROC (INT CONST, INT VAR, INT VAR) open);
+            FI;
+            IF seitenlaenge ueberschritten OR papierlaenge ueberschritten 
+               THEN neue seite oder spalte;
+                    analysiere zeile nochmal;
+               ELSE sortiere neue token ein;
+                    IF in letzter spalte
+                       THEN drucke tokenspeicher (a ypos,
+                            PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+                    FI;
+            FI;
+    FI;
+ 
+    . seitenlaenge ueberschritten :
+        a ypos + aktuelle zeilentiefe > seitenlaenge 
+ 
+    . papierlaenge ueberschritten :
+        a ypos + aktuelle zeilentiefe > papierlaenge 
+ 
+    . neue seite oder spalte :
+        IF in letzter spalte
+           THEN INT CONST aktuelles y wanted := y wanted bei seitenwechel ohne page;
+                schliesse seite ab (PROC (INT CONST, INT CONST) close,
+                      PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+                eroeffne seite (x wanted, aktuelles y wanted,
+                      PROC (INT CONST, INT VAR, INT VAR) open);
+           ELSE neue spalte;
+        FI;
+ 
+        . y wanted bei seitenwechel ohne page :
+            IF seitenlaenge ueberschritten
+               THEN y wanted
+               ELSE 0
+            FI
+ 
+    . analysiere zeile nochmal :
+        setze auf alte werte zurueck;
+        loesche anweisungsspeicher;
+        analysiere zeile (PROC (INT CONST, TEXT VAR,
+          INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+        letztes token bei gleicher ypos;
+        sortiere neue token ein;
+ 
+        . setze auf alte werte zurueck :
+           zeile ist absatzzeile := letzte zeile war absatzzeile;
+           a modifikationen      := letzte modifikationen;
+           stelle neuen font ein (letzter font);
+ 
+.
+  werte anweisungsspeicher aus :
+    INT VAR index;
+    FOR index FROM 1 UPTO anweisungszaehler
+    REP
+        SELECT anweisungs indizes ISUB index OF
+          CASE a block             : block anweisung
+          CASE a columns           : columns anweisung
+          CASE a columnsend        : columnsend anweisung
+          CASE a free              : free anweisung
+          CASE a limit             : limit anweisung
+          CASE a linefeed          : linefeed anweisung
+          CASE a material          : material anweisung
+          CASE a page0, a page1    : page anweisung
+          CASE a pagelength        : pagelength anweisung
+          CASE a start             : start anweisung
+          CASE a table             : table anweisung
+          CASE a tableend          : tableend anweisung 
+          CASE a clearpos0         : clearpos0 anweisung
+          CASE a clearpos1         : clearpos1 anweisung
+          CASE a lpos, a rpos, a cpos, a dpos
+                                   : lpos rpos cpos dpos anweisung
+          CASE a bpos              : bpos anweisung
+          CASE a fillchar          : fillchar anweisung
+          CASE a textbegin0        : textbegin0 anweisung
+          CASE a textbegin2        : textbegin2 anweisung
+          CASE a textend           : textend anweisung
+          CASE a indentation       : indentation anweisung
+          CASE a y tab             : y tab anweisung
+        END SELECT
+   PER; 
+   loesche anweisungsspeicher;
+ 
+   . block anweisung :
+       blockmodus := TRUE;
+ 
+   . columns anweisung :
+       IF anzahl spalten = 1 AND int  conversion ok (param1)
+                             AND real conversion ok (param2) 
+          THEN anzahl spalten := max (1, int param); 
+               luecke         := x step conversion (real param);
+       FI;
+ 
+   . columnsend anweisung :
+       anzahl spalten  := 1;
+       aktuelle spalte := 1; 
+       left margin     := x wanted - x start + indentation;
+ 
+   . free anweisung :
+       IF real conversion ok (param1) THEN a ypos INCR y step conversion (real param) FI;
+ 
+   . limit anweisung :
+       IF real conversion ok (param1) THEN limit := x step conversion (real param) FI;
+ 
+   . linefeed anweisung :
+       IF real conversion ok (param1)
+          THEN linefeed faktor    := real param;
+               berechne letzte zeilengroesse;
+       FI;
+ 
+   . material anweisung :
+       material wert := param1;
+ 
+   . page anweisung :
+       IF seite ist offen
+          THEN IF NOT in letzter spalte
+                  THEN neue spalte
+                  ELSE schliesse seite ab (PROC (INT CONST, INT CONST) close,
+                         PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+                       papier laenge := maxint;
+               FI;
+          ELSE a ypos        := top margin;
+               papier laenge := maxint;
+       FI;
+ 
+   . pagelength anweisung :
+       IF real conversion ok (param1)
+          THEN pagelength   := y step conversion (real param);
+       FI;
+ 
+   . start anweisung :
+       IF real conversion ok (param1) THEN x wanted := x step conversion (real param) FI;
+       IF real conversion ok (param2) THEN y wanted := y step conversion (real param) FI;
+ 
+   . table anweisung :
+       tabellenmodus := TRUE;
+ 
+   . tableend anweisung :
+       tabellenmodus := FALSE;
+ 
+   . clearpos0 anweisung :
+       loesche tabellenspeicher;
+ 
+   . clearpos1 anweisung :
+       IF real conversion ok (param1) 
+          THEN int param := x step conversion (real param);
+               FOR tab index FROM 1 UPTO anzahl tabs
+               REP IF tab position = int param
+                      THEN tab typ := leer;
+                           delete int (tab liste, tab index);
+                           LEAVE clearpos1 anweisung;
+                   FI;
+               PER;
+       FI; 
+ 
+   . lpos rpos cpos dpos anweisung :
+       IF real conversion ok (param1)
+          THEN neuer tab eintrag (anweisungs indizes ISUB index, param2) FI; 
+ 
+   . bpos anweisung :
+       IF real conversion ok (param2) CAND real conversion ok (param1)
+            CAND real (param2) > real param
+          THEN neuer tab eintrag (a bpos, param2) FI;
+ 
+   . fillchar anweisung :
+        fill char := param1;
+ 
+   . textbegin0 anweisung :
+       aktuelle einrueckbreite := alte einrueckbreite;
+       mark index l            := alter mark index l;
+       mark index r            := alter mark index r;
+       loesche alte markierung;
+ 
+   . textbegin2 anweisung :
+       aktuelle einrueckbreite := alte einrueckbreite;
+       mark index l            := alter mark index l;
+       mark index r            := alter mark index r;
+       loesche alte markierung;
+       neuer durchschuss (int (param1), y step conversion (real (param 2)));
+ 
+   . textend anweisung :
+       alte einrueckbreite := aktuelle einrueckbreite;
+       alter mark index l  := mark index l;
+       alter mark index r  := mark index r;
+       loesche markierung;
+       loesche durchschuss;
+ 
+   . indentation anweisung :
+(**)   IF real conversion ok (param1)
+          THEN int param   := x step conversion (real param);
+               left margin INCR (int param - indentation);
+               indentation :=    int param;
+       FI;
+(**)
+   . y tab anweisung :
+(**)   IF real conversion ok (param1)
+          THEN int param := y step conversion (real param);
+               IF int param <= seitenlaenge THEN a ypos := int param FI;
+       FI;
+(**)
+       . param1 :
+           IF (params1 zeiger ISUB index) <> 0
+              THEN name (params1, params1 zeiger ISUB index)
+              ELSE ""
+           FI
+ 
+       . param2 :
+           IF (params2 zeiger ISUB index) <> 0
+              THEN name (params2, params2 zeiger ISUB index)
+              ELSE ""
+           FI
+ 
+ 
+.
+  drucke elan listing :
+    initialisiere elan listing;
+    WHILE NOT eof
+    REP next line (zeile);
+        zeilen nr INCR 1;
+        drucke elan zeile;
+    PER;
+    schliesse elan listing ab;
+ 
+.
+  initialisiere elan listing :
+    open document cmd;
+    hole elan list font;
+    initialisiere variablen;
+    elan fuss und kopf (1,
+               PROC (INT CONST, INT CONST) close,
+               PROC (INT CONST, INT VAR, INT VAR) open,
+               PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ 
+    . open document cmd :
+        material wert         := "";
+        d token. offset index := 1;
+        erster ypos index d   := 0; 
+        vor erster seite      := FALSE;
+        seite ist offen       := TRUE;
+        open (document, x size, y size);
+        vor erster seite      := FALSE;
+ 
+    . hole elan list font :
+        d font := max (1, font ("elanlist"));
+        get replacements (d font, replacements, replacement tabelle);
+        einrueckbreite := indentation pitch (d font) ;
+        font hoehe     := font lead (d font) + font height (d font) + font depth (d font);
+ 
+    . initialisiere variablen :
+        innerhalb einer liste := FALSE;
+        vor erstem packet     := TRUE;
+        zeilen nr             := 0;
+        select counter        := 0;
+        y wanted              := y size DIV 23;
+        pagelength            := y size - y wanted - y wanted; 
+        x wanted              := (min (x size DIV 10, x step conversion (2.54))
+                                        DIV einrueckbreite) * einrueckbreite; 
+        max zeichen zeile     := (x size - x wanted - (x wanted DIV 3)) DIV einrueckbreite;
+        max zeichen fuss      := fusszeilenbreite;
+        layout laenge         := min (38, max zeichen zeile DIV 3);
+        layout laenge name    :=  layout laenge - zeilen nr laenge - 8; 
+        layout blanks         := (layout laenge - zeilen nr laenge - 1) * " "; 
+        refinement layout zeile := (layout laenge - 1) * " " ;
+        refinement layout zeile CAT "|" ;
+        IF pagelength DIV fonthoehe - 6 < 35 OR max zeichen zeile < 65
+           THEN errorstop ("Schreibfeld fuer 'elan listing' zu klein") FI;
+ 
+        . fusszeilenbreite :
+            INT CONST dina 4 breite := x step conversion (21.0);
+            IF   x size <= dina 4 breite
+                 THEN (x size - 2 * x wanted) DIV einrueckbreite 
+            ELIF 120 * einrueckbreite <= dina 4 breite - 2 * x wanted
+                 THEN (dina 4 breite - 2 * x wanted) DIV einrueckbreite 
+                 ELSE min (120, (x size - 2 * x wanted) DIV einrueckbreite)
+            FI
+ 
+.
+  schliesse elan listing ab :
+    elan fuss und kopf (-1,
+               PROC (INT CONST, INT CONST) close,
+               PROC (INT CONST, INT VAR, INT VAR) open,
+               PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+    close (document, 0);
+ 
+. 
+  drucke elan zeile :
+    IF   pos (zeile, "#page#") = 1 
+         THEN IF nicht am seiten anfang THEN seiten wechsel FI;
+    ELIF pos (zeile, "#elanlist#") <> 1 
+         THEN bestimme elan layout;
+              bestimme elan zeile;
+              gib elan text aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute); 
+              seitenwechsel wenn noetig;
+    FI;
+ 
+    . nicht am seitenanfang :
+        rest auf seite < pagelength - 3 * font hoehe
+ 
+    . seiten wechsel :
+        elan fuss und kopf (0,
+               PROC (INT CONST, INT CONST) close,
+               PROC (INT CONST, INT VAR, INT VAR) open,
+               PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ 
+. 
+  bestimme elan layout :
+    IF   innerhalb einer liste
+         THEN leeres layout;
+              pruefe ende der liste 
+    ELIF pos (zeile, "P") <> 0 COR pos (zeile, ":") <> 0
+         THEN analysiere elan zeile
+    ELIF innerhalb einer select kette  
+         THEN leeres layout;
+              pruefe ende der select kette
+    ELIF pos (zeile, "SELECT") <> 0
+         THEN analysiere select kette
+         ELSE leeres layout 
+    FI;
+    elan text CAT "|";
+ 
+    . leeres layout :
+        elan text := text (zeilen nr, zeilen nr laenge);
+        elan text CAT layout blanks;
+ 
+    . analysiere elan zeile :
+        scan (zeile);
+        next symbol (symbol, symbol type);
+        next symbol (naechstes symbol, naechster symbol type);
+        IF   packet anfang
+             THEN packet layout 
+        ELIF type anfang
+             THEN type layout
+        ELIF proc op anfang
+             THEN proc op layout
+             ELSE IF   innerhalb einer select kette
+                       THEN pruefe ende der select kette;
+                            leeres layout
+                  ELIF refinement anfang
+                       THEN refinement layout
+                       ELSE leeres layout
+             FI;
+        FI;
+
+ 
+    . packet anfang :
+        symbol = "PACKET"
+ 
+    . type anfang :
+        symbol = "TYPE"
+ 
+    . proc op anfang :
+        IF   proc oder op (symbol)
+             THEN naechster symbol type <> delimiter type
+        ELIF (symbol <> "END") AND proc oder op (naechstes symbol)
+             THEN symbol := naechstes symbol;
+                  next symbol (naechstes symbol, naechster symbol type);
+                  naechster symbol type <> delimiter type
+             ELSE FALSE
+        FI
+ 
+    . refinement anfang :
+        symbol type = tag type AND naechstes symbol = ":" 
+ 
+    . packet layout :
+        IF nicht am seiten anfang AND
+           (NOT vor erstem packet OR gedruckte seiten > 1)
+          THEN seiten wechsel
+        FI;
+        layout ("   ", naechstes symbol, "*") ;
+        vor erstem packet     := FALSE;
+        select counter        := 0;
+        innerhalb einer liste := TRUE;
+        pruefe ende der liste;
+ 
+    . type layout :
+        layout ("   ", naechstes symbol, ".");
+        select counter        := 0;
+
+    . proc op layout :
+        IF   keine vier zeilen mehr
+             THEN seiten wechsel
+        ELIF nicht am seitenanfang
+             THEN cr plus lf (2, PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute); 
+        FI ; 
+        layout ("   ", naechstes symbol, ".");
+        select counter        := 0;
+        innerhalb einer liste := TRUE;
+        pruefe ende der liste;
+ 
+        . keine vier zeilen mehr :
+            rest auf seite <= 8 * font hoehe 
+ 
+    . refinement layout :
+        IF   keine drei zeilen mehr
+             THEN seiten wechsel
+        ELIF nicht am seitenanfang
+             THEN elan text := refinement layout zeile;
+                  gib elan text aus
+                       (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+        FI ; 
+        layout ("      ", symbol, " ");
+ 
+        . keine drei zeilen mehr :
+            rest auf seite <= 7 * font hoehe 
+ 
+    . pruefe ende der liste :
+        IF pos (zeile, ":") <> 0
+           THEN scan (zeile);
+                WHILE innerhalb einer liste
+                REP next symbol (symbol);
+                    IF symbol = ":" THEN innerhalb einer liste := FALSE FI;
+                UNTIL symbol = "" PER;
+        FI;
+
+    . innerhalb einer select kette :
+        select counter > 0
+
+    . analysiere select kette :
+        scan (zeile);
+        naechstes symbol := "";
+        REP symbol := naechstes symbol;
+            next symbol (naechstes symbol);
+            IF naechstes symbol = "SELECT" CAND symbol <> "END"
+               THEN select counter := 1;
+                    untersuche select kette;
+            FI;
+        UNTIL naechstes symbol = "" PER;
+        leeres layout;
+ 
+    . pruefe ende der select kette :
+        IF pos (zeile, "SELECT") <> 0
+           THEN scan (zeile);
+                naechstes symbol := "";
+                untersuche select kette;
+        FI;
+
+        . untersuche select kette :
+            REP symbol := naechstes symbol;
+                next symbol (naechstes symbol);
+                IF   naechstes symbol = "SELECT"
+                     THEN select counter INCR select step
+                ELIF naechstes symbol = "ENDSELECT"
+                     THEN select counter DECR 1
+                FI;
+             UNTIL naechstes symbol = "" PER;
+
+             . select step :
+                 IF symbol = "END" THEN -1 ELSE 1 FI
+
+. 
+  bestimme elan zeile : 
+    IF zeile ist nicht zu lang
+       THEN elan text CAT zeile;
+       ELSE drucke zeile in teilen 
+    FI;
+ 
+    . zeile ist nicht zu lang :
+        zeilen laenge := LENGTH zeile;
+        zeilen laenge <= rest auf zeile
+ 
+       . rest auf zeile :
+           max zeichen zeile - LENGTH elan text
+ 
+    . drucke zeile in teilen :
+        zeilen pos := 1;
+        bestimme einrueckung;
+        WHILE zeile noch nicht ganz gedruckt REP teil layout PER;
+ 
+    . bestimme einrueckung :
+        anzahl einrueck blanks := naechstes nicht blankes zeichen - 1;
+        IF anzahl einrueck blanks > rest auf zeile - 20
+           THEN anzahl einrueck blanks := 0 FI;
+ 
+    . zeile noch nicht ganz gedruckt :
+        bestimme zeilenteil;
+        NOT zeile ist zu ende
+ 
+        . bestimme zeilenteil :
+            bestimme laenge;
+            zeilen teil := subtext (zeile, zeilen pos, zeilen pos + laenge - 1);
+            elan text CAT zeilen teil;
+            zeilen pos INCR laenge;
+ 
+            . zeilen teil : par1
+ 
+            . bestimme laenge :
+               INT VAR laenge := zeilen laenge - zeilen pos + 1;
+               IF laenge > rest auf zeile
+                  THEN laenge := rest auf zeile;
+                       WHILE (zeile SUB (zeilen pos + laenge - 1)) <> " "
+                       REP laenge DECR 1 UNTIL laenge = 0 PER;
+                       IF laenge = 0 THEN laenge := rest auf zeile FI;
+               FI;
+ 
+    . teil layout :
+        gib elan text aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute); 
+        elan text :=  (zeilen nr laenge - 1) * " "; 
+        elan text CAT "+";
+        elan text CAT layout blanks;
+        elan text CAT "|";
+        elan text cat blanks (anzahl einrueck blanks + teil einrueckung);
+ 
+. 
+  seiten wechsel wenn noetig :
+    IF keine zeilen mehr AND NOT eof THEN seiten wechsel FI; 
+ 
+    . keine zeilen mehr :
+        rest auf seite <= 4 * font hoehe 
+ 
+END PROC drucke datei;
+ 
+ 
+BOOL PROC real conversion ok (TEXT CONST param) :
+     real param := real (param);
+     last conversion ok AND real param >= 0.0
+END PROC real conversion ok;
+ 
+ 
+BOOL PROC int conversion ok (TEXT CONST param) :
+     int param := int (param);
+     last conversion ok AND int param >= 0 
+END PROC int conversion ok;
+ 
+ 
+PROC neuer tab eintrag (INT CONST typ, TEXT CONST param) :
+ 
+     suche neuen eintrag;
+     sortiere neue tab position ein;
+     tab typ      := typ;
+     tab position := neue tab position;
+     tab param    := eventueller parameter;
+ 
+     . suche neuen eintrag :
+         INT VAR index := 0;
+         REP index INCR 1;
+             IF tab speicher (index). tab typ = leer
+                THEN LEAVE suche neuen eintrag FI;
+         UNTIL index = max tabs PER;
+         LEAVE neuer tab eintrag;
+ 
+     . sortiere neue tab position ein :
+         INT VAR neue tab position := x step conversion (real param);
+         FOR tab index FROM 1 UPTO anzahl tabs
+         REP IF   tab position = neue tab position
+                THEN LEAVE neuer tab eintrag
+             ELIF tab position > neue tab position
+                THEN insert int (tab liste, tab index, index);
+                     LEAVE sortiere neue tab position ein;
+             FI;
+         PER;
+         tab liste CAT index;
+         tab index :=  anzahl tabs;
+ 
+     . eventueller parameter :
+         INT VAR link;
+         SELECT typ OF
+           CASE a dpos : insert (d strings, param, link); link
+           CASE a bpos : x step conversion (real(param))
+             OTHERWISE : 0
+         END SELECT
+ 
+END PROC neuer tab eintrag;
+ 
+ 
+PROC neue spalte :
+     a ypos :=  top margin;
+     aktuelle zeilentiefe der letzten zeile := 0;
+     left margin     INCR (limit + luecke);
+     aktuelle spalte INCR 1;
+END PROC neue spalte ;
+ 
+ 
+BOOL PROC proc oder op (TEXT CONST symbol) :
+ 
+  symbol = "PROC" OR symbol = "PROCEDURE"
+    OR symbol = "OP" OR symbol = "OPERATOR" 
+ 
+ENDPROC proc oder op ;
+ 
+ 
+PROC layout (TEXT CONST pre, TEXT VAR name, TEXT CONST post) :
+ 
+name := subtext (name, 1, layout laenge name) ;
+elan text :=  text (zeilen nr, zeilen nr laenge);
+elan text CAT pre;
+elan text CAT name;
+elan text CAT " ";
+generiere strukturiertes layout;
+ 
+. generiere strukturiertes layout :
+    INT VAR index;
+    FOR index FROM 1 UPTO layout laenge - LENGTH elan text - 1
+        REP elan text CAT post PER;
+ 
+END PROC layout ;
+ 
+ 
+PROC elan text cat blanks (INT CONST anzahl) :
+ 
+  par2 := anzahl * " ";
+  elan text CAT par2;
+ 
+END PROC elan text cat blanks;
+ 
+ 
+(***********************************************************************)
+ 
+PROC analysiere zeile (PROC (INT CONST, TEXT VAR,
+    INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator) :
+ 
+loesche analysespeicher;
+behandle fuehrende blanks;
+pruefe ob markierung links;
+ 
+IF   tabellen modus
+     THEN analysiere tabellenzeile
+ELIF letzte zeile war absatzzeile 
+     THEN analysiere zeile nach absatzzeile 
+     ELSE analysiere zeile nach blockzeile
+FI; 
+ 
+pruefe center und right modus;
+pruefe ob tabulation vorliegt;
+werte indexspeicher aus;
+IF zeile ist keine anweisungszeile  
+   THEN berechne zeilenvorschub;
+        pruefe ob markierung rechts;
+   ELSE behandle anweisungszeile;
+FI;
+ 
+.
+  analysiere zeile nach absatzzeile :
+    test auf aufzaehlung;
+    IF zeile muss geblockt werden 
+       THEN analysiere blockzeile nach absatzzeile 
+       ELSE analysiere absatzzeile nach absatzzeile 
+    FI; 
+.
+  analysiere zeile nach blockzeile :
+    IF zeile muss geblockt werden 
+       THEN analysiere blockzeile nach blockzeile 
+       ELSE analysiere absatzzeile nach blockzeile
+    FI; 
+ 
+ 
+.
+  behandle fuehrende blanks :
+    zeilenpos := 1;
+    zeilenpos := naechstes nicht blankes zeichen; 
+    letzte zeile war absatzzeile := zeile ist absatzzeile; 
+    IF letzte zeile war absatzzeile THEN neue einrueckung FI;
+    IF zeilenpos = 0
+       THEN behandle leerzeile;
+            LEAVE analysiere zeile;
+       ELSE initialisiere analyse;
+    FI;
+ 
+    . behandle leerzeile :
+        a ypos INCR (letzte zeilenhoehe +
+                         aktuelle zeilentiefe der letzten zeile + durchschuss);
+        aktuelle zeilentiefe der letzten zeile := letzte zeilentiefe;
+        zeile ist absatzzeile := LENGTH zeile > 0;
+        pruefe ob markierung links;
+        pruefe ob markierung rechts;
+ 
+    . neue einrueckung :
+        aktuelle einrueckbreite := einrueckbreite;
+ 
+    . initialisiere analyse :
+        zeile ist absatzzeile        := (zeile SUB LENGTH zeile) = blank;
+        zeile muss geblockt werden   := block modus AND NOT zeile ist absatzzeile;
+        erstes token der zeile       := token index f + 1;
+        zeilen laenge                := laenge der zeile;
+        anzahl einrueck blanks       := zeilen pos - 1; 
+        anzahl zeichen               := anzahl einrueck blanks;
+        a xpos                       := left margin + anzahl zeichen * aktuelle einrueckbreite; 
+        a modifikationen fuer x move := 0;
+        letzter font                 := a font;
+        letzte modifikationen        := a modifikationen;
+        fuehrende anweisungen        := 0;
+        initialisiere zeilenvorschub;
+        IF zeile muss geblockt werden THEN initialisiere tab variablen FI;
+        IF hoechster index zaehler > 0 THEN loesche index speicher FI;
+ 
+        . laenge der zeile :
+            IF zeile ist absatzzeile
+               THEN LENGTH zeile - 1
+               ELSE LENGTH zeile 
+            FI
+ 
+.
+  pruefe ob markierung links :
+    INT VAR linkes markierungs token;
+    IF markierung links
+       THEN mark token (mark index l). xpos := 
+                             left margin - mark token (mark index l). breite;
+            linkes markierungs token := token index f + 1;
+            lege markierungs token an (mark index l);
+            erstes token der zeile := token index f + 1;
+            initialisiere tab variablen;
+       ELSE linkes markierungs token := 0;
+    FI;
+ 
+. 
+  analysiere tabellenzeile : 
+    anfangs blankmodus := doppel blank;
+    alte zeilenpos     := zeilen pos;
+    a xpos             := left margin;
+    FOR tab index FROM 1 UPTO anzahl tabs
+    REP lege fuell token an wenn noetig;
+        initialisiere tab variablen; 
+        SELECT tab typ OF
+          CASE a lpos  :  linksbuendige spalte
+          CASE a rpos  :  rechtsbuendige spalte
+          CASE a cpos  :  zentrierte spalte
+          CASE a dpos  :  dezimale spalte
+          CASE a bpos  :  geblockte spalte
+        END SELECT;
+        berechne fuell token wenn noetig;
+        tabulation;
+    PER;
+    analysiere rest der zeile;
+ 
+    . lege fuell token an wenn noetig :
+        IF fill char <> blank
+           THEN fuellzeichen                 := fill char;
+                fuellzeichen breite          := string breite (fuellzeichen);
+                token zeiger                 := zeilen pos;
+                erstes fuell token           := token index f + 1;
+                lege token an (zeile, token zeiger, zeilen pos - 1, text token);
+                letztes fuell token          := token index f;
+                a modifikationen fuer x move := a modifikationen
+        FI;
+ 
+    . berechne fuell token wenn noetig :
+        IF erstes fuell token <> leer
+           THEN IF letztes fuell token <> token index f 
+                   THEN berechne fuell token;
+                   ELSE loesche letzte token;
+                FI;
+                erstes fuell token := leer
+        FI;
+ 
+        . berechne fuell token :
+            INT VAR anzahl fuellzeichen, fuell breite;
+            token index         := erstes fuell token;
+            anzahl fuellzeichen := (tab anfang - t. xpos + left margin) 
+                                                 DIV fuellzeichen breite;
+            rest                := (tab anfang - t. xpos + left margin) 
+                                                 MOD fuellzeichen breite;
+            IF anzahl fuell zeichen > 0
+               THEN fuell text   := anzahl fuellzeichen * fuellzeichen; 
+                    fuell breite := anzahl fuellzeichen * fuellzeichen breite; 
+                    FOR token index FROM erstes fuell token UPTO letztes fuell token
+                    REP t. text   := fuell text;
+                        t. breite := fuell breite;
+                        IF erstes fuell token <> erstes token der zeile
+                           THEN t. xpos INCR rest DIV 2;
+                                t. modifikationen fuer x move := t. modifikationen;
+                        FI;
+                    PER;
+            FI;
+ 
+            . fuell text : par1
+ 
+        . loesche letzte token :
+            FOR token index FROM letztes fuell token DOWNTO erstes fuell token
+            REP loesche letztes token PER;
+ 
+    . tabulation :
+        alte zeilenpos := zeilenpos;
+        zeilenpos := naechstes nicht blankes zeichen; 
+        IF zeilenpos = 0
+           THEN zeilenpos := zeilenlaenge + 1; 
+                LEAVE analysiere tabellenzeile;
+        FI;
+        anzahl zeichen INCR zeilenpos - alte zeilenpos; 
+ 
+    . linksbuendige spalte : 
+        a xpos     := left margin + tab position;
+        tab anfang := tab position;
+        bestimme token bis terminator oder zeilenende
+          (PROC (INT CONST, TEXT VAR,
+           INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ 
+    . rechtsbuendige spalte :
+        bestimme token bis terminator oder zeilenende
+          (PROC (INT CONST, TEXT VAR,
+           INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+        schreibe zeile rechtsbuendig (tab position);
+ 
+    . zentrierte spalte :
+        bestimme token bis terminator oder zeilenende
+          (PROC (INT CONST, TEXT VAR,
+           INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+        zentriere zeile (tab position);
+ 
+    . dezimale spalte :
+        d string                  := name (d strings, tab param);
+        d code 1                  := code (d string SUB 1) + 1;
+        d pitch                   := zeichenbreiten (d code 1);
+        zeichenbreiten (d code 1) := d code ausgang;
+        bestimme token bis terminator oder zeilenende
+          (PROC (INT CONST, TEXT VAR,
+           INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+        zeichenbreiten (d code 1) := d pitch;
+        d code 1                  := leer;
+        schreibe zeile rechtsbuendig (tab position);
+        IF zeichen ist dezimal zeichen
+           THEN IF tab position <> zeilen breite
+                   THEN a xpos     := left margin + tab position;
+                        tab anfang := tab position;
+                FI;
+                bestimme token bis terminator oder zeilenende
+                (PROC (INT CONST, TEXT VAR,
+                 INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+        FI;
+ 
+        . zeichen ist dezimal zeichen :
+            pos (zeile, d string,  zeilen pos) = zeilen pos
+ 
+    . geblockte spalte :
+        blankmodus := einfach blank;
+        a xpos     := left margin + tab position;
+        tab anfang := tab position;
+        REP bestimme token bis terminator oder zeilenende
+             (PROC (INT CONST, TEXT VAR,
+              INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+            IF zeile ist zu ende OR naechstes zeichen ist blank
+               THEN blocke spalte wenn noetig;
+                    LEAVE geblockte spalte;
+               ELSE dehnbares blank gefunden;
+            FI;
+        PER;
+ 
+        . blocke spalte wenn noetig :
+            IF letztes zeichen ist kein geschuetztes blank
+               THEN blocke zeile (tab param) FI;
+            blank modus := doppel blank;
+ 
+        . letztes zeichen ist kein geschuetztes blank :
+            pos (zeile, geschuetztes blank,  zeilen pos - 1, zeilen pos - 1) = 0
+              AND NOT within kanji (zeile, zeilen pos - 2)
+ 
+    . analysiere rest der zeile :
+        blankmodus := keine blankanalyse;
+        zeilen pos := alte zeilenpos;
+        bestimme token bis terminator oder zeilenende
+          (PROC (INT CONST, TEXT VAR,
+           INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ 
+.
+  test auf aufzaehlung : 
+    anfangs blankmodus := einfach blank;
+    bestimme token bis terminator oder zeilenende
+      (PROC (INT CONST, TEXT VAR,
+       INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+    IF zeile ist zu ende
+       THEN LEAVE analysiere zeile nach absatzzeile
+       ELSE aufzaehlung moeglich
+    FI;
+ 
+    . aufzaehlung moeglich :
+        bestimme letztes zeichen;
+        IF    (anzahl zeichen bei aufzaehlung < 2  AND letztes zeichen = "-")
+           OR (anzahl zeichen bei aufzaehlung < 20 AND letztes zeichen = ":")
+           OR (anzahl zeichen bei aufzaehlung < 7
+                                        AND pos (".)", letztes zeichen) <> 0)
+           OR naechstes zeichen ist blank
+          THEN tabulator position gefunden;
+        ELIF zeile muss geblockt werden
+          THEN dehnbares blank gefunden;
+        FI;
+ 
+        . bestimme letztes zeichen : 
+            token index := token index f;
+            WHILE token index >= erstes token der zeile
+            REP IF token ist text token 
+                   THEN letztes zeichen := t. text SUB LENGTH t. text;
+                        LEAVE bestimme letztes zeichen;
+                FI;
+                token index DECR 1;
+            PER;
+            letztes zeichen := "";
+ 
+        . letztes zeichen : par1
+ 
+        . anzahl zeichen bei aufzaehlung :
+            anzahl zeichen - anzahl einrueck blanks
+ 
+        . token ist text token :
+            t. offset index >= text token
+.
+  analysiere blockzeile nach absatzzeile :
+    REP bestimme token bis terminator oder zeilenende
+          (PROC (INT CONST, TEXT VAR,
+           INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+        IF zeile ist zu ende 
+           THEN blocke zeile (limit);
+                LEAVE analysiere blockzeile nach absatzzeile
+           ELSE analysiere blank in blockzeile nach absatzzeile 
+        FI;
+    PER;
+ 
+    . analysiere blank in blockzeile nach absatzzeile : 
+        IF naechstes zeichen ist blank
+           THEN tabulator position gefunden;
+           ELSE dehnbares blank gefunden;
+        FI;
+ 
+.
+  analysiere absatzzeile nach absatzzeile :
+    blankmodus := doppel blank;
+    REP bestimme token bis terminator oder zeilenende
+          (PROC (INT CONST, TEXT VAR,
+           INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+        IF zeile ist zu ende 
+           THEN LEAVE analysiere absatzzeile nach absatzzeile
+           ELSE tabulator position gefunden
+        FI;
+    PER;
+ 
+.
+  analysiere blockzeile nach blockzeile :
+    anfangs blankmodus := einfach blank;
+    REP bestimme token bis terminator oder zeilenende
+          (PROC (INT CONST, TEXT VAR,
+           INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+        IF zeile ist zu ende 
+           THEN blocke zeile (limit);
+                LEAVE analysiere blockzeile nach blockzeile
+           ELSE dehnbares blank gefunden 
+        FI;
+    PER;
+ 
+.
+  analysiere absatzzeile nach blockzeile :
+    anfangs blankmodus := keine blankanalyse;
+    bestimme token bis terminator oder zeilenende
+      (PROC (INT CONST, TEXT VAR,
+       INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+ 
+ 
+.
+  dehnbares blank gefunden :
+    anzahl zeichen INCR 1;
+    zeilenpos      INCR 1;
+    a xpos         INCR blankbreite;
+    a modifikationen fuer x move := a modifikationen;
+    IF NOT a block token
+       THEN anzahl blanks  INCR 1;
+            a block token := TRUE; 
+    FI;
+.
+  tabulator position gefunden :
+    alte zeilenpos := zeilenpos; 
+    zeilenpos := naechstes nicht blankes zeichen;
+    IF zeilenpos = 0 
+       THEN zeilenpos := zeilen laenge + 1;
+       ELSE IF erstes token der zeile > token index f
+               THEN token zeiger := zeilen pos;
+                    lege token an (zeile, token zeiger, zeilen pos - 1, text token);
+            FI;
+            anzahl zeichen INCR (zeilenpos - alte zeilenpos);
+            a xpos := left margin + anzahl zeichen * aktuelle einrueckbreite; 
+            a modifikationen fuer x move := a modifikationen;
+            IF zeile muss geblockt werden THEN initialisiere tab variablen FI;
+    FI;
+ 
+.
+  pruefe center und right modus : 
+    IF center modus THEN zentriere zeile (limit DIV 2) FI;
+    IF right  modus THEN schreibe zeile rechtsbuendig (limit) FI;
+.
+  pruefe ob tabulation vorliegt:
+    IF analyse speicher ist nicht leer CAND a xpos > tf. xpos + tf. breite
+       THEN a modifikationen fuer x move := a modifikationen; 
+            token zeiger := zeilen pos;
+            lege token an (zeile, token zeiger, zeilen pos - 1, text token);
+    FI;
+.
+  werte indexspeicher aus :
+    INT VAR index;
+    IF index zaehler > 0
+       THEN FOR index FROM index zaehler DOWNTO 1
+                REP a ypos DECR (index verschiebung ISUB index);
+                    IF (letzte index breite ISUB index) <> 0
+                       THEN a xpos := (xpos vor index ISUB index) +
+                                      min (a xpos - (xpos vor index ISUB index),
+                                                letzte index breite ISUB index);
+                    FI;
+                PER;
+            stelle neuen font ein (grosse fonts ISUB 1);
+    FI;
+.
+  zeile ist keine anweisungszeile :
+    fuehrende anweisungen  <> zeilen laenge
+.
+  berechne zeilenvorschub :
+    verschiebung := aktuelle zeilenhoehe +
+                        aktuelle zeilentiefe der letzten zeile + durchschuss;
+    aktuelle zeilentiefe der letzten zeile := aktuelle zeilentiefe;
+    a ypos INCR verschiebung;
+    verschiebe token ypos (verschiebung);
+ 
+.
+  pruefe ob markierung rechts :
+    IF markierung rechts
+       THEN mark token (mark index r). xpos := left margin + limit;
+            lege markierungs token an (mark index r);
+    FI;
+. 
+  behandle anweisungszeile :
+    IF linkes markierungs token > 0
+       THEN IF erstes token der zeile = token index f + 1
+               THEN loesche analysespeicher;
+               ELSE FOR token index FROM linkes markierungs token
+                                    UPTO erstes token der zeile - 1
+                    REP t. text   := "";
+                        t. xpos   := 0;
+                        t. breite := 0;
+                    PER;
+            FI;
+    FI;
+ 
+END PROC analysiere zeile;
+ 
+ 
+PROC blocke zeile (INT CONST rechter rand) :
+ 
+rest := rechter rand - zeilen breite;
+IF rest > 0 AND anzahl blanks > 0
+   THEN INT CONST schmaler schritt       := rest DIV anzahl blanks,
+                  breiter schritt        := schmaler schritt + 1,
+                  anzahl breite schritte := rest MOD anzahl blanks;
+        IF rechts
+           THEN blocke token xpos (breiter schritt, schmaler schritt,
+                                                     anzahl breite schritte);
+                rechts := FALSE; 
+           ELSE blocke token xpos (schmaler schritt, breiter schritt,
+                                     anzahl blanks - anzahl breite schritte);
+                rechts := TRUE;
+       FI;
+       a xpos INCR ( breiter schritt * anzahl breite schritte +
+              schmaler schritt * (anzahl blanks - anzahl breite schritte) );
+FI;
+ 
+END PROC blocke zeile;
+ 
+ 
+PROC zentriere zeile (INT CONST zentrier pos) :
+ 
+IF erstes tab token <= token index f
+   THEN verschiebung := zentrier pos - tab anfang -
+                                   (zeilen breite - tab anfang) DIV 2; 
+        verschiebe token xpos (verschiebung);
+        a xpos     INCR verschiebung; 
+        tab anfang INCR verschiebung; 
+FI;
+center modus := FALSE;
+ 
+END PROC zentriere zeile;
+ 
+ 
+PROC schreibe zeile rechtsbuendig (INT CONST rechte pos) :
+ 
+IF erstes tab token <= token index f
+   THEN verschiebung := rechte pos - zeilen breite;
+        verschiebe token xpos (verschiebung);
+        a xpos     INCR verschiebung;
+        tab anfang INCR verschiebung; 
+FI;
+right modus := FALSE;
+ 
+ 
+END PROC schreibe zeile rechtsbuendig;
+ 
+ 
+PROC bestimme token bis terminator oder zeilenende
+     (PROC (INT CONST, TEXT VAR,
+            INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator):
+ 
+token zeiger := zeilen pos;
+REP stranalyze (zeichenbreiten, a breite, max breite, 
+                zeile, zeilen pos, zeilen laenge,
+                ausgang);
+    zeilen pos INCR 1;
+    IF   ausgang = blank ausgang
+         THEN analysiere blank
+    ELIF ausgang = anweisungs ausgang
+         THEN anweisung gefunden
+    ELIF ausgang = d code ausgang
+         THEN analysiere d string
+    ELIF ausgang = erweiterungs ausgang
+         THEN erweiterung gefunden
+         ELSE terminator oder zeilenende gefunden
+    FI;
+PER;
+ 
+. analysiere blank :
+    IF blankmodus = einfach blank OR
+       (blankmodus = doppel blank AND naechstes zeichen ist blank)
+       THEN terminator oder zeilenende gefunden 
+       ELSE a breite INCR blankbreite;
+            zeilenpos INCR 1;
+    FI;
+ 
+. analysiere d string :
+    IF pos (zeile, d string, zeilen pos) = zeilen pos 
+       THEN terminator oder zeilenende gefunden 
+       ELSE IF   d pitch = maxint
+                 THEN erweiterung gefunden
+            ELIF d pitch < 0
+                 THEN a breite INCR (d pitch XOR - maxint - 1); 
+                      zeilen pos INCR 2; 
+                 ELSE a breite INCR d pitch; 
+                      zeilenpos INCR 1;
+            FI;
+    FI;
+ 
+. erweiterung gefunden :
+    a breite INCR extended char pitch (a font, zeile SUB zeilen pos, 
+                                               zeile SUB zeilen pos + 1); 
+    zeilen pos INCR 2;
+ 
+. anweisung gefunden :
+    gegebenfalls neues token gefunden;
+    analysiere anweisung (PROC (INT CONST, TEXT VAR,
+      INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator);
+    IF zeile ist zu ende
+       THEN LEAVE bestimme token bis terminator oder zeilenende FI;
+    token zeiger := zeilenpos;
+ 
+. terminator oder zeilenende gefunden :
+    IF ausgang = null ausgang THEN  zeilen laenge DECR 1 FI;
+    gegebenfalls neues token gefunden;
+    LEAVE bestimme token bis terminator oder zeilenende;
+ 
+    . gegebenfalls neues token gefunden :
+        IF token zeiger < zeilenpos
+           THEN lege token an (zeile, token zeiger, zeilen pos - 1, text token) FI;
+ 
+END PROC bestimme token bis terminator oder zeilen ende;
+ 
+ 
+PROC analysiere anweisung (PROC (INT CONST, TEXT VAR,
+       INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR, INT VAR) analysator) :
+ 
+   bestimme anweisung;
+   IF   anweisung ist kommando
+        THEN lege token an (anweisung, 1, maxint, kommando token);
+   ELIF anweisung ist kein kommentar
+        THEN werte anweisung aus; 
+   FI;
+ 
+    . anweisungsende   : zeilen pos - 2
+ 
+    . erstes zeichen   : par1
+ 
+. bestimme anweisung :
+    INT CONST anweisungsanfang := zeilenpos + 1;
+    zeilen pos := pos (zeile, anweisungszeichen, anweisungsanfang, zeilenlaenge);
+    IF zeilenpos = 0
+       THEN zeilenpos := anweisungsanfang - 1;
+            replace (zeile, zeilenpos, geschuetztes anweisungszeichen);
+            LEAVE analysiere anweisung;
+    FI;
+    IF fuehrende anweisungen = anweisungsanfang - 2 THEN fuehrende anweisungen := zeilen pos FI;
+    zeilen pos INCR 1; 
+    anweisung      := subtext (zeile, anweisungsanfang, anweisungsende);
+    erstes zeichen := anweisung SUB 1;
+ 
+. anweisung ist kommando : 
+    IF   erstes zeichen = quote
+         THEN scan (anweisung);
+              next symbol (anweisung, symbol type);
+              next symbol (par2, naechster symbol type);
+              IF symbol type <> text type OR naechster symbol type <> eof type
+                 THEN LEAVE analysiere anweisung FI;
+              TRUE
+    ELIF erstes zeichen = druckerkommando zeichen
+         THEN delete char (anweisung, 1);
+              TRUE
+         ELSE FALSE
+    FI
+    
+. anweisung ist kein kommentar :
+    erstes zeichen <> kommentar zeichen
+ 
+. 
+  werte anweisung aus :
+    analyze command (anweisungs liste, anweisung, number type,
+                     anweisungs index, anzahl params, par1, par2);
+    SELECT anweisungs index OF
+      CASE a type           : type anweisung
+      CASE a on             : on anweisung
+      CASE a off            : off anweisung
+      CASE a ub, a fb       : ub fb anweisung
+      CASE a ue, a fe       : ue fe anweisung
+      CASE a center         : center anweisung
+      CASE a right          : right anweisung
+      CASE a up, a down     : index anweisung
+      CASE a end up or down : end index anweisung
+      CASE a bsp            : bsp anweisung
+      CASE a fillchar       : fillchar anweisung
+      CASE a mark           : mark anweisung
+      CASE a markend        : markend anweisung
+      OTHERWISE : IF anweisungs index > 0
+                     THEN speichere anweisung
+                     ELSE rufe analysator
+                  FI;
+    END SELECT;
+ 
+    . type anweisung :
+        change all (par1, " ", "");
+        stelle neuen font ein (font (par1));
+        a modifikationen   := 0;
+        ueberpruefe groesste fontgroesse;
+        IF nicht innerhalb eines indexes
+           THEN berechne aktuelle zeilengroesse FI;
+ 
+        . nicht innerhalb eines indexes :
+            index zaehler = 0
+ 
+    . on anweisung :
+        par1 := par1 SUB 1;
+        IF pos (modifikations liste, par1) > 0
+           THEN set bit (a modifikationen, pos (modifikations liste, par1) - 1 );
+        FI;
+ 
+    . off anweisung :
+        par1 := par1 SUB 1;
+        IF pos (modifikations liste, par1) > 0
+           THEN reset bit (a modifikationen, pos (modifikations liste, par1) - 1 );
+        FI;
+ 
+    . ub fb anweisung :
+        IF anweisungs index = a ub
+           THEN par1 := "u"
+           ELSE par1 := "b"
+        FI;
+        on anweisung;
+ 
+    . ue fe anweisung :
+        IF anweisungs index = a ue
+           THEN par1 := "u"
+           ELSE par1 := "b"
+        FI;
+        off anweisung;
+ 
+    . center anweisung :
+        IF NOT zeile muss geblockt werden AND NOT tabellen modus
+               AND NOT right modus
+           THEN center modus := TRUE;
+                blankmodus   := keine blankanalyse;
+                initialisiere tab variablen; 
+        FI;
+ 
+    . right anweisung :
+        IF NOT zeile muss geblockt werden AND NOT tabellen modus
+           THEN IF center modus THEN zentriere zeile (limit DIV 2) FI;
+                right modus := TRUE;
+                blankmodus  := keine blankanalyse;
+                initialisiere tab variablen; 
+        FI;
+ 
+    . index anweisung :
+        INT CONST grosser font := a font,
+                  grosse fonthoehe := fonthoehe, grosse fonttiefe := fonttiefe;
+        INT VAR   kleiner font;
+        IF next smaller font exists (grosser font, kleiner font)
+           THEN stelle neuen font ein (kleiner font) FI;
+        IF font hoehe < grosse fonthoehe
+           THEN verschiebung := verschiebung fuer kleinen font
+           ELSE verschiebung := verschiebung fuer grossen font
+        FI;
+        a ypos INCR verschiebung;
+        merke index werte;
+ 
+        . verschiebung fuer kleinen font :
+            IF anweisungs index = a down
+               THEN    15 PROZENT (grosse fonthoehe + grosse fonttiefe)
+               ELSE - ( 4 PROZENT (grosse fonthoehe + grosse fonttiefe) )
+                    - (grosse fonthoehe + grosse fonttiefe - fonthoehe - fonttiefe)
+            FI
+ 
+        . verschiebung fuer grossen font :
+            IF anweisungs index = a down
+               THEN    25 PROZENT (fonthoehe + fonttiefe)
+               ELSE - (50 PROZENT (fonthoehe + fonttiefe) )
+            FI
+ 
+        . merke index werte :
+            index zaehler INCR 1;
+            IF hoechster index zaehler < index zaehler
+               THEN neues index level
+               ELSE altes index level
+            FI;
+            IF index zaehler = 1
+               THEN alter blankmodus := blankmodus; 
+                    blankmodus := keine blankanalyse;
+            FI;
+ 
+            . neues index level :
+                hoechster index zaehler := index zaehler;
+                letzte index breite  CAT 0;
+                xpos vor index       CAT a xpos;
+                zeilenpos nach index CAT -1;
+                index verschiebung   CAT verschiebung;
+                grosse fonts         CAT grosser font;
+ 
+            . altes index level :
+                IF (zeilenpos nach index ISUB index zaehler) = anweisungsanfang - 1
+                    AND sign (index verschiebung ISUB index zaehler) <> sign (verschiebung)
+                   THEN doppelindex gefunden;
+                   ELSE replace (xpos vor index, index zaehler, a xpos);
+                FI;
+                replace (index verschiebung, index zaehler, verschiebung);
+                replace (grosse fonts, index zaehler, grosser font);
+ 
+                . doppelindex gefunden :
+                    replace (letzte index breite, index zaehler,
+                             a xpos - (xpos vor index ISUB index zaehler));
+                    a xpos := xpos vor index ISUB index zaehler;
+ 
+    . end index anweisung :
+        IF index zaehler > 0
+           THEN schalte auf alte index werte zurueck;
+        FI;
+ 
+        . schalte auf alte index werte zurueck :
+            IF index zaehler = 1 THEN blankmodus := alter blankmodus FI;
+            a ypos DECR (index verschiebung ISUB index zaehler);
+            stelle neuen font ein (grosse fonts ISUB index zaehler);
+            IF (letzte index breite ISUB index zaehler) <> 0
+               THEN berechne doppelindex
+               ELSE replace (zeilenpos nach index, index zaehler, zeilenpos);
+            FI;
+            index zaehler DECR 1;
+ 
+            . berechne doppelindex :
+                a xpos := (xpos vor index ISUB index zaehler) +
+                           max (a xpos - (xpos vor index ISUB index zaehler),
+                                     letzte index breite ISUB index zaehler);
+                replace (zeilenpos nach index, index zaehler, -1);
+                replace (letzte index breite, index zaehler, 0);
+ 
+    . bsp anweisung :
+        INT VAR breite davor, breite dahinter;
+        IF anweisungs anfang - 2 >= 1 AND anweisungs ende + 2 <= zeilen laenge
+           THEN IF is kanji esc (zeile SUB anweisungs anfang - 3)
+                   THEN zeichen davor := subtext (zeile, anweisungs anfang - 3,
+                                                         anweisungs anfang - 2);
+                   ELSE zeichen davor := zeile SUB anweisungs anfang - 2;
+                FI;
+                IF is kanji esc (zeile SUB anweisungs ende + 2)
+                   THEN zeichen dahinter := subtext (zeile, anweisungs ende + 2,
+                                                            anweisungs ende + 3 );
+                   ELSE zeichen dahinter := zeile SUB anweisungs ende + 2;
+                FI;
+                IF pos (" #", zeichen davor) = 0 AND pos (" #", zeichen dahinter) = 0 
+                   THEN breite davor    := char pitch (a font, zeichen davor);
+                        breite dahinter := char pitch (a font, zeichen dahinter);
+                        IF breite davor < breite dahinter THEN vertausche zeichen FI;
+                        lege token fuer zeichen dahinter an;
+                        a xpos INCR (breite davor - breite dahinter) DIV 2; 
+                FI;
+        FI;
+ 
+        . zeichen davor    : par1
+        . zeichen dahinter : par2
+ 
+        . vertausche zeichen :
+            change (zeile, anweisungs anfang - 2 - LENGTH zeichen davor + 1, 
+                           anweisungs anfang - 2, zeichen dahinter);
+            change (zeile, anweisungs ende + 2,
+                           anweisungs ende + 2 + LENGTH zeichen dahinter - 1, zeichen davor);
+            change (tf. text, LENGTH tf. text - LENGTH zeichen davor + 1,
+                              LENGTH tf. text, zeichen dahinter);
+            tf. breite INCR (breite dahinter - breite davor);
+            a xpos     INCR (breite dahinter - breite davor);
+            int param        := breite davor;
+            breite davor     := breite dahinter;
+            breite dahinter  := int param;
+ 
+        . lege token fuer zeichen dahinter an :
+            token zeiger := zeilen pos;
+            a breite     := breite dahinter;
+            zeilen pos INCR LENGTH zeichen dahinter;
+            a xpos     DECR (breite davor + breite dahinter) DIV 2; 
+            lege token an (zeile, token zeiger, zeilen pos - 1, text token);
+            anzahl zeichen DECR 1;
+ 
+    . fillchar anweisung :
+        IF par1 = "" THEN par1 := " " FI;
+        fill char := par1;
+        speichere anweisung;
+ 
+    . mark anweisung :
+        IF par1 <> "" 
+           THEN mark index l := (alter mark index l MOD 2) + 1;
+                neue markierung (par1, mark index l);
+           ELSE mark index l := 0;
+        FI;
+        IF par2 <> "" 
+           THEN mark index r := (alter mark index r MOD 2) + 3;
+                neue markierung (par2, mark index r);
+           ELSE mark index r := 0;
+        FI;
+ 
+    . markend anweisung :
+        loesche markierung;
+ 
+    . speichere anweisung :
+        anweisungs zaehler INCR 1;
+        anweisungs indizes CAT anweisungs index;
+        IF par1 <> ""
+           THEN insert (params1, par1); 
+                params1 zeiger CAT highest entry (params1);
+           ELSE params1 zeiger CAT 0;
+        FI;
+        IF par2 <> ""
+           THEN insert (params2, par2); 
+                params2 zeiger CAT highest entry (params2);
+           ELSE params2 zeiger CAT 0;
+        FI;
+ 
+    . rufe analysator :
+        INT CONST alte xpos := a xpos, alte y pos := a ypos;
+        INT VAR analysatorbreite, analysatorhoehe, analysatortiefe,
+                analysator font           := a font,
+                analysator modifikationen := a modifikationen;
+        zeilen pos := anweisungsanfang - 1;
+disable stop;
+        analysator (text code, zeile, zeilen pos,
+                    analysator font, analysator modifikationen,
+                    analysatorbreite, analysatorhoehe, analysatortiefe, dummy);
+IF is error
+   THEN par1 := error message;
+        par1 CAT " a1-> ";
+        par1 CAT text (errorline);
+        clear error;
+        errorstop (par1);
+FI;
+enable stop;
+        hole token der analyse;
+        a xpos               := alte xpos + analysatorbreite;
+        a ypos               := alte ypos;
+        a modifikationen     := analysator modifikationen;
+        groesste analysatorhoehe := max (analysatorhoehe, groesste analysator hoehe);
+        groesste analysatortiefe := max (analysatortiefe, groesste analysator tiefe);
+        IF analysator font <> a font
+           THEN stelle neuen font ein (analysator font);
+                ueberpruefe groesste fontgroesse;
+                IF nicht innerhalb eines indexes
+                   THEN berechne aktuelle zeilengroesse FI;
+           ELSE aktuelle zeilenhoehe := max (groesste analysatorhoehe,
+                                                      aktuelle zeilenhoehe);
+                aktuelle zeilentiefe := max (groesste analysatortiefe,
+                                                      aktuelle zeilentiefe);
+        FI;
+           
+        . hole token der analyse :
+            INT VAR token nr := 0, token font, token xpos, token ypos, token typ;
+            BOOL VAR font changed := FALSE;
+            token text := "";
+            REP
+disable stop;
+                analysator (token code, token text, token nr,
+                            token font, a modifikationen, a breite,
+                            token xpos, token ypos, token typ);
+IF is error
+   THEN par1 := error message;
+        par1 CAT " a2-> ";
+        par1 CAT text (errorline);
+        clear error;
+        errorstop (par1);
+FI;
+enable stop;
+                IF token nr = 0
+                   THEN IF font changed THEN a font := -1 FI;
+                        LEAVE hole token der analyse
+                FI;
+                IF token font <> a font
+                   THEN a font       := token font;
+                        font offsets := y offsets (a font);
+                        offsets      := LENGTH font offsets > 2;
+                        font changed := TRUE;
+                FI;
+                a xpos := alte xpos + token xpos;
+                a ypos := alte ypos + token ypos;
+                lege token an (token text, 1, max int, token typ)
+            PER;
+ 
+            . token text : par1
+ 
+END PROC analysiere anweisung;
+ 
+ 
+PROC stelle neuen font ein (INT CONST font nr ) :
+ 
+  IF font nr <> a font THEN neuer font FI;
+ 
+  . neuer font :
+      a font := max (1, font nr);
+      get font (a font, einrueckbreite, fontdurchschuss, fonthoehe, fonttiefe,
+                zeichenbreiten);
+      blankbreite                                := zeichenbreiten (blank code 1);
+      zeichenbreiten (blank code 1)              := blank ausgang;
+      zeichenbreiten (anweisungs zeichen code 1) := anweisungs ausgang;
+      font offsets                               := y offsets (a font);
+      offsets                                    := LENGTH font offsets > int length;
+      berechne fontgroesse;
+      berechne letzte zeilengroesse;
+      IF d code 1 <> leer
+         THEN d pitch                            := zeichenbreiten (d code 1);
+              zeichenbreiten (d code 1)          := d code ausgang;
+     FI;
+ 
+END PROC stelle neuen font ein;
+ 
+ 
+INT OP PROZENT (INT CONST prozent, wert) :
+ 
+    (wert * prozent + 99) DIV 100
+ 
+END OP PROZENT; 
+ 
+ 
+PROC neue markierung (TEXT CONST text, INT CONST mark index) :
+ 
+      mark token (mark index). text           := text;
+      mark token (mark index). breite         := string breite (text);
+      mark token (mark index). font           := a font;
+      mark token (mark index). modifikationen := a modifikationen;
+ 
+END PROC neue markierung;
+ 
+ 
+INT PROC string breite (TEXT CONST string) :
+ 
+    INT VAR summe := 0, pos := 1;
+    REP stranalyze (zeichenbreiten, summe, max breite, string, pos, maxint, ausgang);
+        IF   ausgang = erweiterungs ausgang
+             THEN summe INCR extended char pitch (a font,
+                                       string SUB pos+1, string SUB pos+2);
+                  pos INCR 3;
+        ELIF ausgang = blank ausgang
+             THEN summe INCR blankbreite;
+                  pos INCR 2;
+        ELIF ausgang = anweisungs ausgang
+             THEN summe INCR char pitch (a font, anweisungszeichen);
+                  pos INCR 2;
+             ELSE LEAVE string breite WITH summe
+        FI;
+    PER;
+    0
+ 
+END PROC string breite;
+ 
+(*******************************************************************)
+ 
+PROC lege token an (TEXT CONST token text,
+                    INT  CONST token anfang, token ende, token typ) :
+ 
+  INT VAR anfang := token anfang;
+  aktuelle ypos := a ypos + (font offsets ISUB 1); 
+  neuer token index;
+  uebertrage token (tf, token text, token anfang, token ende, token typ);
+  IF   token typ >= text token
+       THEN IF offsets THEN lege offsets an (font offsets) FI;
+            stranalyze (zeichen zaehler, anzahl zeichen, max int,
+                        token text, anfang, token ende, ausgang);
+            a xpos INCR a breite;
+  FI;
+  a breite                     := 0;
+  a modifikationen fuer x move := 0;
+  a block token                := FALSE;
+ 
+END PROC lege token an;
+ 
+ 
+PROC uebertrage token (TOKEN VAR tf, TEXT CONST token text,
+                       INT CONST token anfang, token ende, token typ) :
+ 
+  tf. text                       := subtext (token text, token anfang, token ende);
+  tf. xpos                       := a xpos;
+  tf. breite                     := a breite;
+  tf. font                       := a font;
+  tf. modifikationen             := a modifikationen;
+  tf. modifikationen fuer x move := a modifikationen fuer x move;
+  tf. offset index               := token typ;
+  tf. block token                := a block token;
+ 
+END PROC uebertrage token;
+ 
+ 
+PROC lege markierungs token an (INT CONST mark index) :
+ 
+  aktuelle ypos := a ypos + (mark font offsets ISUB 1); 
+  neuer token index;
+  tf := mark token (mark index);
+  IF mark offsets THEN lege offsets an (mark font offsets) FI;
+ 
+  . mark font offsets   : y offsets (mark token (mark index). font)
+ 
+  . mark offsets        : LENGTH mark font offsets > int length
+ 
+END PROC lege markierungs token an;
+ 
+ 
+PROC lege offsets an (TEXT CONST offsets l) :
+ 
+  INT CONST anzahl offsets := LENGTH offsets l DIV int length;
+  INT VAR index;
+  offset token := tf;
+  offset token. block token := FALSE;
+  reset bit (offset token. modifikationen, underline bit);
+  reset bit (offset token. modifikationen fuer x move, underline bit);
+  FOR index FROM 2 UPTO anzahl offsets
+  REP aktuelle ypos := a ypos + (offsets l ISUB index); 
+      neuer token index;
+      tf               := offset token;
+      tf. offset index := index;
+  PER;
+ 
+END PROC lege offsets an;
+ 
+ 
+PROC neuer token index :
+ 
+IF   erster ypos index a = 0
+     THEN erste ypos
+ELIF ya. ypos = aktuelle ypos 
+     THEN neues token bei gleicher ypos
+     ELSE fuege neue ypos ein
+FI;
+ 
+  . erste ypos :
+      ypos  index f INCR 1;
+          erster     ypos index a := ypos index f;
+          letzter    ypos index a := ypos index f;
+      yf. vorheriger ypos index   := 0;
+      yf. naechster  ypos index   := 0;
+      erstes token bei neuer ypos;
+ 
+  . fuege neue ypos ein :
+      letztes token bei gleicher ypos;
+      IF ya. ypos > aktuelle ypos
+         THEN richtige ypos ist oberhalb
+         ELSE richtige ypos ist unterhalb
+      FI;
+ 
+      . richtige ypos ist oberhalb :
+          REP ypos index a := ya. vorheriger ypos index;
+              IF   ypos index a = 0
+                   THEN fuege ypos vor erstem ypos index ein;
+                        LEAVE richtige ypos ist oberhalb;
+              ELIF ya. ypos = aktuelle ypos
+                   THEN neues token bei neuer ypos;
+                        LEAVE richtige ypos ist oberhalb;
+              ELIF ya. ypos < aktuelle ypos
+                   THEN fuege ypos nach ypos index ein;
+                        LEAVE richtige ypos ist oberhalb;
+              FI;
+          PER;
+ 
+      . richtige ypos ist unterhalb :
+          REP ypos index a := ya. naechster ypos index;
+              IF   ypos index a = 0
+                   THEN fuege ypos nach letztem ypos index ein;
+                        LEAVE richtige ypos ist unterhalb;
+              ELIF ya. ypos = aktuelle ypos
+                   THEN neues token bei neuer ypos;
+                        LEAVE richtige ypos ist unterhalb;
+              ELIF ya. ypos > aktuelle ypos 
+                   THEN fuege ypos vor ypos index ein;
+                        LEAVE richtige ypos ist unterhalb;
+              FI;
+          PER;
+ 
+          . fuege ypos vor erstem ypos index ein :
+              ypos  index f INCR 1;
+              yf. vorheriger ypos index   := 0;
+              yf. naechster  ypos index   :=     erster    ypos index a;
+                  erster     ypos index a :=               ypos index f;
+                             ypos index a := yf. naechster ypos index;
+              ya. vorheriger ypos index   :=               ypos index f;
+              erstes token bei neuer ypos;
+ 
+          . fuege ypos nach ypos index ein :
+              ypos  index f INCR 1;
+              yf. vorheriger ypos index   :=               ypos index a;
+              yf. naechster  ypos index   := ya. naechster ypos index;
+              ya. naechster  ypos index   :=               ypos index f;
+                             ypos index a := yf. naechster ypos index;
+              ya. vorheriger ypos index   :=               ypos index f;
+              erstes token bei neuer ypos;
+ 
+          . fuege ypos vor ypos index ein :
+              ypos  index f INCR 1;
+              yf. naechster  ypos index   :=                ypos index a;
+              yf. vorheriger ypos index   := ya. vorheriger ypos index;
+              ya. vorheriger ypos index   :=                ypos index f;
+                             ypos index a := yf. vorheriger ypos index;
+              ya. naechster  ypos index   :=                ypos index f;
+              erstes token bei neuer ypos;
+ 
+          . fuege ypos nach letztem ypos index ein :
+              ypos  index f INCR 1;
+              yf. naechster  ypos index   := 0;
+              yf. vorheriger ypos index   :=     letzter    ypos index a;
+                  letzter    ypos index a :=                ypos index f;
+                             ypos index a := yf. vorheriger ypos index;
+              ya. naechster  ypos index   :=                ypos index f;
+              erstes token bei neuer ypos;
+ 
+END PROC neuer token index;
+ 
+ 
+PROC erstes token bei neuer ypos :
+     token index f INCR 1;
+                 ypos index a := ypos index f;
+     ya. erster token index   := token index f; 
+     ya. ypos                 := aktuelle ypos;
+END PROC erstes token bei neuer ypos;
+ 
+ 
+PROC neues token bei neuer ypos :
+     token index f INCR 1;
+     ya. ypos                 := aktuelle ypos;
+                  token index := ya. letzter token index;
+     t. naechster token index := token index f;
+END PROC neues token bei neuer ypos;
+ 
+ 
+PROC neues token bei gleicher ypos :
+     tf. naechster token index := token index f + 1;
+     token index f INCR 1;
+END PROC neues token bei gleicher ypos;
+ 
+ 
+PROC letztes token bei gleicher ypos : 
+     tf. naechster token index := 0;
+     ya. letzter   token index := token index f;
+END PROC letztes token bei gleicher ypos;
+ 
+ 
+PROC loesche letztes token :
+ 
+     IF token index f = ya. erster token index 
+        THEN loesche ypos
+        ELSE token index f DECR 1;
+     FI;
+ 
+     . loesche ypos :
+         kette vorgaenger um;
+         kette nachfolger um;
+         bestimme letzten ypos index;
+ 
+         . kette vorgaenger um :
+             ypos index := ya. vorheriger ypos index; 
+             IF ypos index = 0
+                THEN       erster ypos index a := ya. naechster ypos index;
+                ELSE y. naechster ypos index   := ya. naechster ypos index; 
+             FI;
+ 
+         . kette nachfolger um :
+             ypos index := ya. naechster ypos index;
+             IF ypos index = 0
+                THEN       letzter ypos index a := ya. vorheriger ypos index;
+                ELSE y. vorheriger ypos index   := ya. vorheriger ypos index; 
+             FI;
+ 
+         . bestimme letzten ypos index :
+             IF ypos index a = ypos index f THEN ypos index f DECR 1 FI;
+             token index f DECR 1;
+             ypos index a := letzter ypos index a; 
+             WHILE ypos index a <> 0
+                       CAND ya. letzter token index <> token index f
+             REP ypos index a := ya. vorheriger ypos index PER;
+ 
+END PROC loesche letztes token;
+ 
+ 
+PROC blocke token xpos (INT CONST dehnung 1, dehnung 2,
+                                  anzahl dehnungen fuer dehnung 1 ) :
+ 
+  INT VAR dehnung := 0, anzahl dehnungen := 0;
+  token index := erstes tab token;
+  WHILE token index <= token index f
+  REP erhoehe token xpos bei block token;
+      t. xpos INCR dehnung;
+      token index INCR 1; 
+  PER;
+ 
+  . erhoehe token xpos bei block token :
+      IF t. block token
+         THEN IF anzahl dehnungen < anzahl dehnungen fuer dehnung 1
+                 THEN anzahl dehnungen INCR 1;
+                      dehnung INCR dehnung 1;
+                 ELSE dehnung INCR dehnung 2;
+              FI;
+      FI;
+ 
+END PROC blocke token xpos;
+ 
+ 
+PROC verschiebe token xpos (INT CONST verschiebung l) :
+ 
+  token index := erstes tab token;
+  WHILE token index <= token index f
+  REP t. xpos INCR verschiebung l;
+      token index INCR 1; 
+  PER;
+ 
+END PROC verschiebe token xpos;
+ 
+ 
+PROC verschiebe token ypos (INT CONST verschiebung l) :
+ 
+  ypos index := erster ypos index a;
+  WHILE ypos index <> 0
+  REP y. ypos INCR verschiebung l; 
+      ypos index := y. naechster ypos index;
+  PER;
+ 
+END PROC verschiebe token ypos;
+ 
+ 
+PROC sortiere neue token ein :
+ 
+INT VAR index; 
+IF analysespeicher ist nicht leer
+   THEN IF druckspeicher ist nicht leer
+           THEN sortiere neue token in sortierte liste ein
+           ELSE sortierte liste ist leer
+        FI;
+FI;
+ 
+. sortierte liste ist leer :
+    IF erster ypos index a <> 0
+       THEN erster  ypos index d := erster  ypos index a;
+            letzter ypos index d := letzter ypos index a;
+                    ypos index d := letzter ypos index a;
+    FI;
+ 
+. sortiere neue token in sortierte liste ein :
+    gehe zum ersten neuen token;
+    bestimme erste einsortierposition;
+    WHILE es gibt noch neue token
+    REP IF   ypos index d = 0
+             THEN haenge neue token ans ende der sortierten liste 
+        ELIF ya. ypos > yd. ypos
+             THEN naechste ypos der sortierten liste
+        ELIF ya. ypos = yd. ypos
+             THEN neues token auf gleicher ypos
+             ELSE neue token vor ypos
+        FI; 
+    PER;
+ 
+    . gehe zum ersten neuen token :
+        ypos index a := erster ypos index a;
+ 
+    . bestimme erste einsortierposition :
+        WHILE ypos index d <> 0  CAND  ya. ypos < yd. ypos
+          REP ypos index d := yd. vorheriger ypos index PER;
+        IF ypos index d = 0 THEN erste neue token vor listen anfang FI;
+ 
+        . erste neue token vor listen anfang :
+                   ypos index d := erster ypos index d;
+            erster ypos index d := erster ypos index a;
+            REP ypos index a := ya. naechster ypos index;
+                IF   ypos index a = 0
+                     THEN verkette letztes ya mit yd;
+                          LEAVE sortiere neue token in sortierte liste ein
+                ELIF ya. ypos = yd. ypos
+                     THEN verkette ya mit yd;
+                          LEAVE erste neue token vor listen anfang
+                ELIF ya. ypos > yd. ypos
+                     THEN verkette vorheriges ya mit yd;
+                          ypos index d := yd. naechster ypos index;
+                          LEAVE erste neue token vor listen anfang
+                FI;
+            PER;
+ 
+    . es gibt noch neue token :
+        ypos index a <> 0
+ 
+    . haenge neue token ans ende der sortierten liste : 
+                       ypos index d := letzter ypos index d;
+        yd. naechster  ypos index   :=         ypos index a;
+        ya. vorheriger ypos index   :=         ypos index d;
+            letzter    ypos index d := letzter ypos index a;
+                       ypos index d := letzter ypos index a;
+                       ypos index a := 0;
+ 
+    . naechste ypos der sortierten liste :
+        ypos index d := yd. naechster ypos index;
+ 
+    . neues token auf gleicher ypos :
+                      token index   := yd. letzter   token index;
+        t . naechster token index   := ya. erster    token index;
+        yd. letzter   token index   := ya. letzter   token index;
+                      ypos  index a := ya. naechster ypos  index;
+                      ypos  index d := yd. naechster ypos  index;
+        IF ypos index d = 0 THEN ypos index d := letzter ypos index d FI;
+ 
+    . neue token vor ypos :
+        verkette ya mit vorherigem yd;
+        REP ypos index a := ya. naechster ypos index;
+            IF   ypos index a = 0
+                 THEN verkette letztes ya mit yd;
+                      LEAVE sortiere neue token in sortierte liste ein
+            ELIF ya. ypos = yd. ypos
+                 THEN verkette ya mit yd;
+                      LEAVE neue token vor ypos
+            ELIF ya. ypos > yd. ypos 
+                 THEN verkette vorheriges ya mit yd;
+                      ypos index d := yd. naechster ypos index;
+                      LEAVE neue token vor ypos
+            FI;
+        PER;
+ 
+ 
+. verkette ya mit vorherigem yd :
+                        index   := ypos index d;
+                   ypos index d := yd. vorheriger ypos index; 
+    yd. naechster  ypos index   :=                ypos index a;
+    ya. vorheriger ypos index   :=                ypos index d;
+                   ypos index d := index;
+ 
+. verkette letztes ya mit yd :
+                   ypos index a := letzter ypos index a;
+    yd. vorheriger ypos index   :=         ypos index a;
+    ya. naechster  ypos index   :=         ypos index d;
+                   ypos index a := 0;
+ 
+. verkette vorheriges ya mit yd :
+                        index   := ypos index a;
+                   ypos index a := ya. vorheriger ypos index; 
+    yd. vorheriger ypos index   :=         ypos index a;
+    ya. naechster  ypos index   :=         ypos index d;
+                   ypos index a := index;
+ 
+. verkette ya mit yd :
+    verkette vorheriges ya mit yd;
+    neues token auf gleicher ypos;
+ 
+END PROC sortiere neue token ein;
+ 
+(***************************************************************)
+ 
+PROC drucke tokenspeicher
+             (INT CONST max ypos,
+              PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+IF druckspeicher ist nicht leer
+   THEN gehe zur ersten ypos; 
+        WHILE yd. ypos <= max ypos 
+        REP drucke token bei ypos;
+            gehe zur naechsten ypos; 
+        PER;
+        loesche gedruckte token;
+FI;
+ 
+. gehe zur ersten ypos :
+    ypos index d := erster ypos index d;
+ 
+. drucke token bei ypos :
+    IF yd. ypos >= - y start
+       THEN druck durchgang;
+            IF bold      pass THEN fett         durchgang FI;
+            IF underline pass THEN unterstreich durchgang FI;
+    FI;
+ 
+    . bold      pass : bit (pass, bold bit)
+ 
+    . underline pass : bit (pass, underline bit)
+ 
+. gehe zur naechsten ypos : 
+    IF ypos index d = letzter ypos index d
+       THEN loesche druckspeicher;
+            LEAVE drucke tokenspeicher;
+    FI;
+    ypos index d := yd. naechster ypos index;
+ 
+. loesche gedruckte token :
+        erster     ypos index d := ypos index d;
+    yd. vorheriger ypos index   := 0;
+ 
+. 
+  druck durchgang :
+    verschiebung := yd. ypos - d ypos;
+    y move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+    gehe zum ersten token dieser ypos; 
+    REP drucke token UNTIL kein token mehr vorhanden PER;
+ 
+    . drucke token :
+        IF NOT token passt in zeile
+           THEN IF token ist text token
+                   THEN berechne token teil
+                   ELSE LEAVE drucke token
+                FI;
+        FI;
+        font wechsel wenn noetig;
+        x move mit modifikations ueberpruefung; 
+        IF   token ist text token
+             THEN gib text token aus
+                    (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+        ELIF token ist linien token
+             THEN gib linien token aus
+             ELSE gib kommando token aus
+        FI;
+ 
+    . gib linien token aus :
+        linien verschiebung := d token. breite;
+        ziehe horizontale linie (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ 
+    . gib kommando token aus :
+        execute (write cmd, d token. text, 1, LENGTH d token. text)
+ 
+        . berechne token teil :
+            INT CONST fuenf punkte := 5 * char pitch (d token. font, punkt);
+            INT VAR token pos, token breite, anzahl punkte, zeichen laenge, zeichen breite; 
+            IF   d token. xpos < - x start
+                   AND d token. xpos + d token. breite > - x start 
+                 THEN berechne token teil von links
+            ELIF d token. xpos < papierbreite
+                   AND d token. xpos + d token. breite > papierbreite
+                 THEN berechne token teil nach rechts
+                 ELSE LEAVE drucke token
+            FI;
+ 
+        . berechne token teil von links :
+            rest          := min (x size, d token. xpos + d token. breite + x start);
+            d token. xpos := - x start;
+            IF rest <= fuenf punkte 
+               THEN anzahl punkte   := rest DIV char pitch (d token. font, punkt);
+                    d token. text   := anzahl punkte * punkt;
+                    d token. breite := anzahl punkte * char pitch (d token. font, punkt);
+               ELSE token pos    := LENGTH d token. text + 1;
+                    token breite := fuenf punkte;
+                    berechne token teil breite von hinten;
+                    change (d token. text, 1, token pos - 1, 5 * punkt);
+                    d token. breite := token breite;
+            FI;
+ 
+            . berechne token teil breite von hinten :
+                WHILE naechstes zeichen passt noch davor
+                REP token breite INCR zeichen breite; 
+                    token pos    DECR zeichen laenge;
+                PER;
+ 
+            . naechstes zeichen passt noch davor :
+                IF within kanji (d token. text, token pos - 1) 
+                   THEN zeichen laenge := 2
+                   ELSE zeichen laenge := 1
+                FI;
+                zeichen breite := char pitch (d token. font,
+                    subtext (d token. text, token pos - zeichen laenge, token pos - 1));
+                token breite + zeichen breite < rest
+ 
+        . berechne token teil nach rechts :
+            rest := papier breite - d token. xpos;
+            IF rest <= fuenf punkte 
+               THEN anzahl punkte   := rest DIV char pitch (d token. font, punkt);
+                    d token. text   := anzahl punkte * punkt;
+                    d token. breite := anzahl punkte * char pitch (d token. font, punkt);
+               ELSE token pos    := 0;
+                    token breite := fuenf punkte;
+                    berechne token teil breite von vorne;
+                    change (d token. text, token pos + 1, LENGTH d token. text, 5 * punkt);
+                    d token. breite := token breite;
+            FI;
+ 
+            . berechne token teil breite von vorne :
+                WHILE naechstes zeichen passt noch dahinter
+                REP token breite INCR zeichen breite; 
+                    token pos    INCR zeichen laenge;
+                PER;
+ 
+            . naechstes zeichen passt noch dahinter :
+                IF is kanji esc (d token. text SUB token pos + 1) 
+                   THEN zeichen laenge := 2
+                   ELSE zeichen laenge := 1
+                FI;
+                zeichen breite := char pitch (d token. font,
+                    subtext (d token. text, token pos + 1, token pos + zeichen laenge));
+                token breite + zeichen breite < rest
+ 
+.
+  fett durchgang :
+    reset bit (pass, bold bit);
+    gib cr aus;
+    gehe zum ersten token dieser ypos;
+    REP gib token nochmal aus UNTIL kein token mehr vorhanden PER;
+    schalte modifikationen aus wenn noetig;
+ 
+    . gib token nochmal aus :
+        INT CONST min verschiebung := bold offset (d token. font); 
+        d token. xpos INCR min verschiebung;
+        IF bit (d token. modifikationen, bold bit) AND
+               token passt in zeile AND token ist text token 
+          THEN verschiebung := d token. xpos - d xpos;
+               font wechsel wenn noetig;
+               schalte italics ein wenn noetig;
+               x move wenn noetig;
+               gib text token aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute); 
+        FI;
+        d token. xpos DECR min verschiebung;
+ 
+        . schalte italics ein wenn noetig :
+            IF bit (d token. modifikationen, italics bit)
+               THEN neue modifikationen := modifikations werte (italics bit + 1);
+                    schalte modifikationen ein wenn noetig;
+               ELSE schalte modifikationen aus wenn noetig;
+            FI;
+ 
+. 
+  unterstreich durchgang :
+    INT VAR l xpos := 0;
+    reset bit (pass, underline bit);
+    gib cr aus;
+    schalte modifikationen aus wenn noetig;
+    gehe zum ersten token dieser ypos;
+    REP unterstreiche token UNTIL kein token mehr vorhanden PER;
+ 
+    . unterstreiche token :
+        IF token muss unterstrichen werden AND
+                token passt in zeile AND token ist text token 
+           THEN font wechsel wenn noetig;
+                berechne x move laenge; 
+                x move wenn noetig;
+                berechne unterstreich laenge;
+                ziehe horizontale linie (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+         FI;
+         l xpos := d token. xpos + d token. breite;
+ 
+         . token muss unterstrichen werden :
+             bit (d token. modifikationen, underline bit) OR
+                bit (d token. modifikationen fuer x move, underline bit)
+ 
+         . berechne x move laenge :
+             IF bit (d token. modifikationen fuer x move, underline bit) 
+                THEN verschiebung := l  xpos - d xpos
+                ELSE verschiebung := d token. xpos - d xpos
+             FI;
+ 
+         . berechne unterstreich laenge :
+             IF bit (d token. modifikationen, underline bit) 
+                THEN linien verschiebung := d token. xpos + 
+                                                d token. breite - d xpos
+                ELSE linien verschiebung := d token. xpos - d xpos
+             FI;
+             d token. offset index := - underline line type;
+ 
+ 
+. gehe zum ersten token dieser ypos :
+    token index := yd. erster token index;
+    d token := t;
+ 
+. kein token mehr vorhanden :
+    token index := d token. naechster token  index;
+    IF token index = 0
+       THEN TRUE
+       ELSE d token := t;
+            FALSE
+    FI
+ 
+. token ist text token :
+    d token. offset index >= text token
+ 
+. token ist linien token :
+    d token. offset index <= linien token
+ 
+. token passt in zeile :
+    d token. xpos >= - x start AND
+         d token. xpos + d token. breite <= papier breite 
+ 
+. font wechsel wenn noetig :
+    IF d token. font <>  d font
+       THEN font wechsel (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) FI;
+ 
+. schalte modifikationen ein wenn noetig :
+    IF d modifikationen <> neue modifikationen
+       THEN schalte modifikationen ein (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) FI;
+ 
+. schalte modifikationen aus wenn noetig :
+    IF d modifikationen <> 0
+       THEN schalte modifikationen aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) FI;
+ 
+. x move wenn noetig :
+    IF verschiebung <> 0
+       THEN x move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) FI; 
+ 
+. 
+  x move mit modifikations ueberpruefung :
+    verschiebung := d token. xpos - d xpos;
+    IF verschiebung <> 0
+       THEN neue modifikationen := d token. modifikationen fuer x move;
+            schalte modifikationen ein wenn noetig;
+            x move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+    FI;
+    neue modifikationen := d token. modifikationen;
+    schalte modifikationen ein wenn noetig;
+ 
+. gib cr aus :
+    IF d xpos <> 0
+       THEN execute (carriage return, "", d xpos, 0);
+            d xpos := 0;
+    FI;
+ 
+END PROC drucke tokenspeicher;
+ 
+ 
+PROC ziehe horizontale linie (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+    IF linien verschiebung > 0
+       THEN disable stop; 
+            d xpos INCR linien verschiebung;
+            execute (draw, "", linien verschiebung, 0);
+            IF is error
+               THEN ziehe horizontale linie nach cr;
+            FI;
+            enable stop;
+    FI;
+ 
+    . ziehe horizontale linie nach cr :
+        clear error;
+        d xpos DECR linien verschiebung;
+        verschiebung := d xpos;
+        gib cr aus;
+        x move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+        d xpos INCR linien verschiebung;
+        execute (draw, "", linien verschiebung, 0);
+        IF is error
+           THEN clear error; 
+                d xpos DECR linien verschiebung;
+        FI;
+ 
+    . gib cr aus :
+        IF d xpos <> 0
+           THEN execute (carriage return, "", d xpos, 0);
+                d xpos := 0;
+        FI;
+ 
+END PROC ziehe horizontale linie;
+ 
+ 
+PROC y move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+    IF verschiebung <> 0
+       THEN gib cr aus;
+            disable stop; 
+            d ypos INCR verschiebung;
+            execute (move, "", 0, verschiebung);
+            IF is error
+               THEN clear error;
+                    d ypos DECR verschiebung;
+                    verschiebung := 0;
+            FI;
+            enable stop;
+    FI;
+ 
+    . gib cr aus :
+        IF d xpos <> 0
+           THEN execute (carriage return, "", d xpos, 0);
+                d xpos := 0;
+        FI;
+ 
+END PROC y move;
+ 
+ 
+PROC x move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+    disable stop;
+    d xpos INCR verschiebung; 
+    execute (move, "", verschiebung, 0);
+    IF is error
+       THEN fuehre x move nach cr aus
+    FI;
+ 
+    . fuehre x move nach cr aus :
+        clear error;
+        schalte modifikationen aus wenn noetig;
+        gib cr bei x move aus;
+        IF d xpos <> 0
+           THEN execute (move, "", d xpos, 0);
+                IF is error
+                   THEN clear error;
+                        d xpos := 0;
+                FI
+        FI;
+        schalte modifikationen ein wenn noetig;
+ 
+        . gib cr bei x move aus :
+            execute (carriage return,  "", d xpos - verschiebung, 0);
+ 
+        . schalte modifikationen aus wenn noetig :
+            neue modifikationen := d modifikationen;
+            IF d modifikationen <> 0
+               THEN schalte modifikationen aus
+                    (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+            FI;
+ 
+        . schalte modifikationen ein wenn noetig :
+            IF d modifikationen <> neue modifikationen
+               THEN schalte modifikationen ein
+                    (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+            FI;
+ 
+END PROC x move;
+ 
+ 
+PROC schalte modifikationen ein 
+            (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+     disable stop;
+     INT VAR index;
+     IF d modifikationen <> 0
+        THEN schalte modifikationen aus
+               (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+     FI;
+     d modifikationen := neue modifikationen;
+     FOR index FROM 1 UPTO anzahl modifikationen
+     REP IF bit (d modifikationen, modifikations bit)
+            THEN modifikation muss eingeschaltet werden
+         FI; 
+     PER;
+ 
+     . modifikations bit : index - 1
+ 
+     . modifikation muss eingeschaltet werden :
+         IF bit (modifikations modus, modifikations bit) 
+            THEN execute (on, "", modifikations werte (index), 0);
+                 IF is error
+                    THEN clear error;
+                         reset bit (modifikations modus, modifikations bit); 
+                         set bit   (pass,                modifikations bit);
+                 FI;
+            ELSE set bit (pass, modifikations bit); 
+         FI;
+ 
+END PROC schalte modifikationen ein;
+ 
+ 
+PROC schalte modifikationen aus 
+            (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+     disable stop;
+     INT VAR index;
+     FOR index FROM 1 UPTO anzahl modifikationen
+     REP IF bit (d modifikationen, modifikations bit)
+            THEN modifikation muss ausgeschaltet werden
+         FI; 
+     PER;
+     d modifikationen := 0;
+ 
+     . modifikations bit : index - 1
+ 
+     . modifikation muss ausgeschaltet werden :
+         IF bit (modifikations modus, modifikations bit) 
+            THEN execute (off, "", modifikations werte (index), 0);
+                 IF is error THEN clear error FI;
+         FI;
+ 
+END PROC schalte modifikationen aus;
+ 
+ 
+PROC font wechsel 
+            (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+     disable stop;
+     d font := d token. font;
+     get replacements (d font, replacements, replacement tabelle);
+     execute (type, "", d font, 0);
+     IF is error THEN font wechsel nach cr FI;
+     enable stop;
+ 
+     . font wechsel nach cr :
+         clear error;
+         verschiebung := d xpos;
+         gib cr aus;
+         execute (type, "", d font, 0);
+         IF NOT is error
+            THEN schalte modifikationen aus
+                    (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+                 x move
+                    (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+         FI;
+ 
+     . gib cr aus :
+         IF d xpos <> 0
+            THEN execute (carriage return, "", d xpos, 0);
+                 d xpos := 0;
+         FI;
+ 
+END PROC font wechsel;
+ 
+ 
+PROC gib text token aus 
+            (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+  INT CONST token laenge := LENGTH d token. text;
+  INT VAR token pos := 1, alte token pos, summe := 0;
+  IF token laenge > 0
+     THEN REP alte token pos := token pos;
+              stranalyze (replacement tabelle, summe, 0,
+                          d token. text, token pos, token laenge,
+                          ausgang);
+              IF ausgang = 0 
+                 THEN gib token rest aus;
+                 ELSE gib token teil aus;
+                      gib ersatzdarstellung aus;
+              FI;
+          PER;
+  FI;
+ 
+  . gib token rest aus :
+      IF token laenge >= alte token pos
+         THEN execute (write text, d token. text, alte token pos, token laenge) FI;
+      d xpos INCR d token. breite;
+      LEAVE gib text token aus;
+ 
+  . gib token teil aus :
+      IF token pos >= alte token pos
+         THEN execute (write text, d token. text, alte token pos, token pos) FI;
+ 
+  . gib ersatzdarstellung aus :
+      IF ausgang = maxint
+         THEN ersatzdarstellung := extended replacement (d token. font,
+                d token. text SUB token pos + 1, d token. text SUB token pos + 2);
+              execute (write text, ersatzdarstellung, 1, LENGTH ersatzdarstellung);
+              tokenpos INCR 3;
+         ELSE IF ausgang < 0
+                 THEN ausgang := ausgang XOR minint;
+                      token pos INCR 1;
+              FI;
+              execute (write text, replacements, ausgang + 1, ausgang + code (replacements SUB ausgang));
+              token pos INCR 2;
+      FI;
+ 
+      . ersatzdarstellung : par1
+ 
+END PROC gib text token aus;
+ 
+ 
+PROC schliesse seite ab (PROC (INT CONST, INT CONST) close,
+                         PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+enable stop;
+gebe restliche token aus;
+gib cr aus;
+seiten ende kommando;
+ 
+. gebe restliche token aus :
+    IF erster ypos index d <> 0
+       THEN drucke tokenspeicher (maxint,
+                 PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+    FI;
+    rest := papier laenge - d ypos;
+    aktuelle zeilentiefe der letzten zeile := 0;
+ 
+. gib cr aus :
+    IF d xpos <> 0
+       THEN execute (carriage return, "", d xpos, 0);
+            d xpos := 0;
+    FI;
+ 
+. seiten ende kommando :
+    seite ist offen := FALSE;
+    a ypos          := top margin;
+    aktuelle spalte := 1;
+    close (page, rest);
+ 
+END PROC schliesse seite ab;
+ 
+ 
+PROC eroeffne seite (INT CONST x wanted l, y wanted l,
+                     PROC (INT CONST, INT VAR, INT VAR) open ) :
+ 
+IF vor erster seite THEN eroeffne druck FI;
+seiten anfang kommando;
+initialisiere neue seite;
+ 
+. eroeffne druck :
+    open (document, x size, y size);
+    vor erster seite := FALSE;
+    d font           := -1;
+    d modifikationen := 0;
+ 
+. seiten anfang kommando :
+    x start := x wanted l;
+    y start := y wanted l;
+    open (page, x start, y start);
+    gedruckte seiten INCR 1;
+    seite ist offen := TRUE;
+ 
+. initialisiere neue seite :
+    INT CONST dif left margin := x wanted l - x start - left margin + indentation,
+              dif top  margin := y wanted l - y start - top  margin; 
+    IF dif left margin <> 0
+       THEN erstes tab token := 1;
+            verschiebe token xpos (dif left margin);
+            a xpos      INCR dif left margin;
+            left margin INCR dif left margin;
+    FI;
+    IF dif top margin <> 0
+       THEN verschiebe token ypos (dif top margin);
+            a ypos      INCR dif top margin;
+            top margin  INCR dif top margin;
+    FI;
+    d xpos := 0;
+    d ypos := 0;
+    IF seitenlaenge <= papierlaenge
+       THEN seitenlaenge := top margin + pagelength; 
+       ELSE seitenlaenge DECR papierlaenge;
+    FI;
+    papierlaenge := y size - y start;
+    papierbreite := x size - x start;
+ 
+END PROC eroeffne seite;
+ 
+(****************************************************************)
+ 
+PROC elan fuss und kopf (INT CONST fuss oder kopf,
+                PROC (INT CONST, INT CONST) close,
+                PROC (INT CONST, INT VAR, INT VAR) open,
+                PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+IF fuss oder kopf <= 0 THEN elan fuss FI;
+IF fuss oder kopf >= 0 THEN elan kopf FI;
+ 
+.
+  elan fuss :
+    y move zur fusszeile;
+    drucke elan fuss;
+    close page cmd;
+ 
+. y move zur fusszeile :
+    execute (carriage return,  "", d xpos, 0);
+    d xpos := 0;
+    verschiebung := rest auf seite - font hoehe;
+    y move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ 
+. drucke elan fuss :
+    IF bottom label = ""
+       THEN seiten nr := ""
+       ELSE seiten nr := bottom label;
+            seiten nr CAT "/";
+    FI;
+    seiten nr CAT text (gedruckte seiten);
+    elan text := seiten nr;
+    elan text CAT "   ";
+    elan text cat blanks ((max zeichen fuss - LENGTH dateiname) DIV 2 - LENGTH elan text);
+    elan text CAT dateiname;
+    elan text cat blanks (max zeichen fuss - LENGTH seiten nr - LENGTH elan text - 3);
+    elan text CAT "   ";
+    elan text CAT seiten nr;
+    IF LENGTH elan text > max zeichen zeile
+       THEN elan text := subtext (elan text, 1, max zeichen zeile) FI;
+    gib elan text aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute); 
+ 
+    . seiten nr : par1
+ 
+. close page cmd :
+    execute (carriage return,  "", d xpos, 0);
+    d xpos := 0;
+    close (page, papierlaenge - d ypos);
+    seite ist offen := FALSE;
+ 
+.
+  elan kopf :
+    open page cmd ;
+    y move zur kopfzeile;
+    drucke elan kopf;
+ 
+. open page cmd :
+    x start         := x wanted;
+    y start         := y wanted;
+    open (page, x start, y start);
+    IF fuss oder kopf = 1 THEN execute (type, "", d font, 0) FI;
+    gedruckte seiten INCR 1;
+    seite ist offen := TRUE;
+    top  margin     := y wanted - y start;
+    left margin     := x wanted - x start;
+    rest auf seite  := pagelength;
+    papierlaenge    := y size - y start;
+    d ypos          := 0; 
+    d xpos          := 0;
+ 
+. y move zur kopf zeile :
+    verschiebung := top margin;
+    y move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+    IF verschiebung = 0 THEN rest auf seite INCR top margin FI;
+ 
+. drucke elan kopf :
+    elan text :=  headline pre;
+    elan text CAT date;
+    elan text CAT headline post;
+    elan text CAT datei name;
+    IF LENGTH elan text > max zeichen zeile
+       THEN elan text := subtext (elan text, 1, max zeichen zeile) FI;
+    gib elan text aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute); 
+    cr plus lf (2, PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute); 
+ 
+ENDPROC elan fuss und kopf;
+ 
+ 
+PROC gib elan text aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) :
+ 
+cr plus lf (1, PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+linker rand wenn noetig;
+d token. breite := LENGTH elan text * einrueckbreite;
+gib text token aus (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ 
+. linker rand wenn noetig :
+    IF left margin > 0
+       THEN disable stop;
+            d xpos := left margin;
+            execute (move, "", left margin, 0);
+            IF is error 
+               THEN clear error;
+                    d xpos := 0;
+            FI;
+            enable stop;
+    FI;
+ 
+END PROC gib elan text aus;
+ 
+ 
+PROC cr plus lf (INT CONST anzahl,
+                 PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute) : 
+ 
+gib cr aus;
+gib lf aus;
+rest auf seite DECR verschiebung;
+ 
+. gib cr aus :
+    execute (carriage return, "", d xpos, 0);
+    d xpos := 0;
+ 
+. gib lf aus :
+    verschiebung := anzahl * font hoehe;
+    y move (PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute);
+ 
+END PROC cr plus lf ; 
+ 
+ 
+END PACKET eumel printer;
+
diff --git a/system/eumelmeter b/system/eumelmeter
new file mode 100644
index 0000000..ba92476
--- /dev/null
+++ b/system/eumelmeter
@@ -0,0 +1,131 @@
+                                              (* Author: J.Liedtke*)
+PACKET eumelmeter DEFINES                     (* Stand:  11.10.83 *)
+ 
+     init log ,
+     log :
+ 
+ 
+LET snapshot interval = 590.0 ;
+
+REAL VAR next snapshot time ,
+         time        , timex ,
+         paging wait , paging wait x ,
+         paging busy , paging busy x ,
+         fore cpu    , fore cpu x ,
+         back cpu    , back cpu x ,
+         system cpu  , system cpu x ,
+         delta t ;
+INT VAR storage max, used ;
+TEXT VAR record ;
+
+PROC init log :
+
+  time        := clock (1) ;
+  paging wait := clock (2) ;
+  paging busy := clock (3) ;
+  fore cpu    := clock (4) ;
+  back cpu    := clock (5) ;
+  system cpu  := clock (6) ;
+  next snapshot time := time + snapshot interval
+
+ENDPROC init log ;
+
+PROC log (INT CONST active terminals, active background) :
+
+  new snapshot time if was clock reset ;
+  IF clock (1) >= next snapshot time
+    THEN save values ;
+         get new values ;
+         create stat record ;
+         put log (record) ;
+         define next snapshot time
+  FI .
+
+new snapshot time if was clock reset :
+  IF clock (1) < next snapshot time - snapshot interval 
+    THEN next snapshot time := clock (1)
+  FI .
+
+save values :
+  time x := time ;
+  paging wait x := paging wait ;
+  paging busy x := paging busy ;
+  fore cpu x    := fore cpu ;
+  back cpu x    := back cpu ;
+  system cpu x  := system cpu .
+
+get new values :
+  time := clock (1) ;
+  paging wait := clock (2) ;
+  paging busy := clock (3) ;
+  fore cpu    := clock (4) ;
+  back cpu    := clock (5) ;
+  system cpu  := clock (6) ;
+  storage (storage max, used) .
+
+create stat record :
+  record :=  text (used, 5) ;
+  record CAT text (active terminals,3) ;
+  record CAT text (active background,3) ;
+  delta t := (time - time x) ;
+  percent (paging wait, paging wait x) ;
+  percent (paging busy, paging busy x) ;
+  percent (fore cpu, fore cpu x) ;
+  percent (back cpu, back cpu x) ;
+  percent (system cpu, system cpu x) ;
+  percent (last, 0.0) ;
+  percent (nutz, 0.0) .
+
+last :   paging wait  + paging busy  + fore cpu  + back cpu  + system cpu
+       - paging waitx - paging busyx - fore cpux - back cpux - system cpux .
+
+nutz :   time  - paging wait  - system cpu
+       - timex + paging waitx + system cpux .
+
+define next snapshot time :
+  next snapshot time := time + snapshot interval .
+ 
+ENDPROC log ;
+
+PROC percent (REAL CONST neu, alt ) :
+
+  record CAT text ( (neu-alt) / delta t * 100.0, 6,1) + "%"
+
+ENDPROC percent ;
+
+ENDPACKET eumelmeter ;
+ 
+INT VAR active terminals , active background ;
+
+task password ("-") ;
+break ;
+command dialogue (FALSE) ;
+forget ("eumelmeter") ;
+init log ;
+REP
+  pause (6000) ;
+  count active processes (active terminals, active background) ;
+  log (active terminals, active background)
+PER ;
+
+PROC count active processes (INT VAR active terminals, active background) :
+ 
+  active terminals := 0 ;
+  active background := 0 ;
+  TASK VAR process := myself ;
+  REP
+    next active (process) ;
+    IF user process 
+      THEN IF process at terminal
+             THEN active terminals INCR 1
+             ELSE active background INCR 1
+           FI
+    FI
+  UNTIL process = myself PER .
+
+user process :         NOT (process < supervisor) .
+
+process at terminal :  channel (process) >= 0 .
+
+ENDPROC count active processes ;
+
diff --git a/system/font convertor 9 b/system/font convertor 9
new file mode 100644
index 0000000..a5d0ea7
--- /dev/null
+++ b/system/font convertor 9	
@@ -0,0 +1,1095 @@
+PACKET font convertor                             (* Autor : Rudolf Ruland *) 
+                                                  (* Stand : 29.03.88      *)
+        DEFINES create font table ,
+                add fonts,
+                create font file :
+ 
+(* >>> ***************************************************************** <<< *)
+ 
+INT CONST int length  := length of one int,
+          highest bit := int length * 8 - 1;
+
+. length of one int :
+    INT VAR int counter := 0, int value := max int;
+    REP int counter INCR 1;
+        int value   := int value DIV 256;
+    UNTIL int value = 0 PER;
+    int counter
+.;
+
+(* >>> ***************************************************************** <<< *)
+ 
+LET t tag                         =  1,
+    t bold                        =  2,
+    t number                      =  3,
+    t text                        =  4,
+    t operator                    =  5,
+    t delimiter                   =  6,
+    t end of file                 =  7,
+ 
+    nil modus                     =  0,
+    font table modus              =  1,
+    font modus                    =  2,
+    extension modus               =  3,
+ 
+    x unit                        =  1,
+    y unit                        =  2,
+    on string                     =  3,
+    off string                    =  4,
+    indentation pitch             =  5,
+    font lead                     =  6,
+    font height                   =  7,
+    font depth                    =  8,
+    larger font                   =  9,
+    smaller font                  = 10,
+    font string                   = 11,
+    y off sets                    = 12,
+    bold off set                  = 13;
+ 
+THESAURUS VAR names, english identification := empty thesaurus,
+                     german  identification := empty thesaurus;
+ 
+insert (english identification, "xunit");
+insert (english identification, "yunit");
+insert (english identification, "onstring");
+insert (english identification, "offstring");
+insert (english identification, "indentationpitch");
+insert (english identification, "fontlead");
+insert (english identification, "fontheight");
+insert (english identification, "fontdepth");
+insert (english identification, "nextlargerfont");
+insert (english identification, "nextsmallerfont");
+insert (english identification, "fontstring");
+insert (english identification, "yoffsets");
+insert (english identification, "boldoffset");
+ 
+insert (german identification, "xeinheit");
+insert (german identification, "yeinheit");
+insert (german identification, "onsequenz");
+insert (german identification, "offsequenz");
+insert (german identification, "einrueckbreite");
+insert (german identification, "durchschuss");
+insert (german identification, "fonthoehe");
+insert (german identification, "fonttiefe");
+insert (german identification, "groessererfont");
+insert (german identification, "kleinererfont");
+insert (german identification, "fontsequenz");
+insert (german identification, "yverschiebungen");
+insert (german identification, "boldverschiebung");
+ 
+INT VAR modus, last modus, symbol type, int symbol, pitch,
+        identification nr, link nr, extension code 1,
+        char code 1, char code, char pos, vorzeichen,
+        replacements length, index;
+TEXT VAR symbol, font table name, replacement, char, buffer, z;
+BOOL VAR english;
+FILE VAR file, font file;
+ 
+(*****************************************************************) 
+ 
+LET max fonts       = 50,
+    max extensions  = 120, 
+    font table type = 3009,
+ 
+    FONTTABLE = STRUCT (
+ 
+        THESAURUS font names, 
+ 
+        TEXT replacements, font name links,
+             extension chars, extension indexes, 
+ 
+        ROW 4 TEXT on strings, off strings,
+ 
+        REAL x unit, y unit,
+ 
+        ROW 256 INT replacements table,
+ 
+        INT last font, last extension,
+ 
+        ROW max fonts STRUCT (
+            TEXT font string, font name indexes, replacements,
+                 extension chars, extension indexes, y offsets,
+            ROW 256 INT pitch table, replacements table,
+            INT  indentation pitch, font lead, font height, font depth,
+                 next larger font, next smaller font, bold offset ) fonts ,
+ 
+        ROW max extensions STRUCT (
+            TEXT replacements,
+            ROW 256 INT pitch table, replacements table,
+            INT std pitch                                        ) extensions ,
+ 
+                        );
+ 
+BOUND FONTTABLE VAR font table;
+ 
+DATASPACE VAR ds;
+ 
+INT VAR font nr, extension nr;
+ 
+. font      : font table. fonts (font nr)
+. extension : font table. extensions (extension nr)
+. line nr   : line no (file) - 1
+.;
+ 
+(*****************************************************************) 
+ 
+ 
+PROC create font table :
+ 
+     create font table  (last param)
+ 
+END PROC create font table;
+ 
+ 
+PROC create font table (TEXT CONST font file name) :
+ 
+file := sequential file (input, font file name);
+disable stop;
+ds    := nilspace;
+modus := nil modus;
+load;
+IF is error THEN error (errormessage) FI;
+forget (ds);
+ 
+END PROC create font table;
+ 
+ 
+PROC add fonts (TEXT CONST font tab name, font file name) :
+ 
+file := sequential file (input, font file name);
+font table name := font tab name;
+change all (font table name, " ", "");
+IF NOT exists (font table name) COR type (old (font table name)) <> font table type
+   THEN errorstop ("Fonttabelle """ + font table name + """ gibt es nicht")
+FI;
+disable stop;
+ds           := old (font table name);
+fonttable    := ds;
+modus        := font modus;
+font nr      := fonttable. last font;
+extension nr := fonttable. last extension;
+load;
+IF is error THEN error (errormessage) FI;
+forget (ds);
+ 
+END PROC add fonts;
+ 
+ 
+PROC load :
+ 
+enable stop;
+initialize loading;
+REP get kennung; 
+    get identification;
+    get char specifications;
+UNTIL symbol type >= t end of file PER;
+font table found;
+ 
+. initialize loading :
+    scan (file);
+    get next symbol;
+ 
+. font table found :
+    IF font nr = 0
+       THEN errorstop ("Fonts zur Fonttabelle """
+                        + font table name + """ fehlen"); 
+       ELSE font table. last font      := font nr; 
+            font table. last extension := extension nr; 
+            forget (font table name, quiet);
+            copy (ds, font table name);
+            type (old (font table name), font table type);
+            forget (ds); ds := nilspace;
+    FI; 
+ 
+. get next symbol :
+    next symbol (file, symbol, symbol type);
+ 
+. get semicolon :
+    get next symbol;
+    IF symbol <> ";" OR symbol type <> t delimiter 
+       THEN errorstop ("';' erwartet") FI;
+ 
+.
+  get kennung :
+    cout (line nr);
+    IF symbol type <> t bold 
+       THEN errorstop ("Kennung erwartet") FI;
+    IF   symbol = "FONTTABLE" OR symbol = "FONTTABELLE" 
+      THEN initialize font table;
+           get font table name;
+    ELIF symbol = "FONT"
+      THEN initialize font;
+           get font names;
+    ELIF symbol = "EXTENSION" OR symbol = "ERWEITERUNG" 
+      THEN get extension char;
+           initialize extension;
+    ELIF modus = nil modus
+      THEN errorstop ("Kennung 'FONTTABLE' oder 'FONTTABELLE' zu Beginn der Datei erwartet") 
+      ELSE errorstop ("unzulaessige Kennung")
+    FI;
+ 
+    . initialize font table :
+        IF modus <> nil modus THEN font table found FI;
+        modus                          := font table modus;
+        font nr                        := 0;
+        extension nr                   := 0;
+        font table                     := ds;
+        font table. font names         := empty thesaurus; 
+        font table. replacements       := "";
+        font table. font name links    := "";
+        font table. extension chars    := "";
+        font table. extension indexes  := ""; 
+        font table. x unit             := 10.0/2.54;
+        font table. y unit             :=  6.0/2.54;
+        font table. replacements table := 0;
+        FOR index FROM 1 UPTO 4
+        REP font table. on  strings (index) := "";
+            font table. off strings (index) := "";
+        PER;
+ 
+    . get font table name :
+        get name list;
+        symbol type := t text;
+        symbol      := name (names, 1);
+        IF exists (symbol)
+           THEN  forget (symbol);
+                 IF exists (symbol)
+                    THEN errorstop ("Fonttabelle existiert schon") FI;
+        FI;
+        font table name := symbol;
+ 
+    . initialize font :
+        IF font nr = max fonts
+           THEN errorstop ("zu viele Fonts") FI;
+        font nr INCR 1;
+        modus                    := font modus;
+        replacements length      := LENGTH font table. replacements; 
+        font. font string        := "";
+        font. font name indexes  := "";
+        font. replacements       := "";
+        font. extension chars    := "";
+        font. extension indexes  := "";
+        font. y offsets          := int length * ""0"";
+        font. indentation pitch  := int (font table. x unit * 2.54 / 10.0);
+        font. font lead          := 0;
+        font. font height        := int (font table. y unit * 2.54 / 6.0); 
+        font. font depth         := 0;
+        font. next larger  font  := 0;
+        font. next smaller font  := 0;
+        font. bold offset        := 0;
+        font. pitch table        := font. indentation pitch;
+        font. replacements table := font table. replacements table;
+        FOR index FROM 1 UPTO LENGTH font table. extension chars
+        REP font. replacements table 
+              ( code (font table. extension chars SUB index) + 1 ) := maxint;
+        PER;
+ 
+    . get font names :
+        get name list;
+        index := 0;
+        symbol type := t text;
+        WHILE next font name
+        REP link nr := link (font table. font names, symbol);
+            IF link nr = 0
+               THEN insert (font table. font names, symbol, link nr); 
+                    font table. font name links CAT font nr;
+            ELIF (font table. font name links ISUB link nr) = 0
+               THEN replace (font table. font name links, link nr, font nr);
+               ELSE errorstop ("Font existiert in Fonttabelle """
+                                + font table name + """ schon")
+            FI;
+            font. font name indexes CAT link nr;
+        PER;
+ 
+        . next font name :
+            get (names, symbol, index);
+            symbol <> ""
+ 
+    . get extension char :
+        IF NOT two bytes
+           THEN errorstop ("Erweiterungen nur im zwei-Byte-Modus erlaubt") FI;
+        get name list;
+        symbol type := t text;
+        symbol      := name (names, 1);
+        IF LENGTH symbol <> 1 
+           THEN errorstop ("nur ein Zeichen bei Erweiterung erlaubt") FI;
+        extension code 1 := code (symbol) + 1;
+        IF NOT is kanji esc (symbol) 
+           THEN errorstop ("Kanji-ESC-Zeichen erwartet") FI;
+ 
+    . initialize extension :
+        IF extension nr = max extensions
+           THEN errorstop ("zu viele Erweiterungen") FI;
+        extension nr INCR 1;
+        IF modus <> extension modus THEN last modus := modus FI;
+        modus      := extension modus;
+        IF last modus = font table modus
+           THEN initalize font table extension
+           ELSE initalize font extension
+        FI;
+ 
+        . initalize font table extension :
+            IF pos (font table. extension chars, symbol) <> 0
+               THEN errorstop ("Erweiterung wurde schon definiert") FI;
+            extension. replacements        := "";
+            extension. std pitch           := 0;
+            extension. pitch table         := 0;
+            extension. replacements table  := 0;
+            font table. extension chars   CAT symbol;
+            font table. extension indexes CAT extension nr;
+            font table. replacements table (extension code 1) := max int;
+            replacements length            := 0;
+ 
+        . initalize font extension :
+            IF pos (font. extension chars, symbol) <> 0
+               THEN errorstop ("Erweiterung wurde schon definiert") FI;
+            extension. replacements   := "";
+            extension. std pitch      := font. pitch table (extension code 1) XOR (-maxint-1);
+            extension. pitch table    := extension. std pitch;
+            font. extension chars    CAT symbol;
+            font. extension indexes  CAT extension nr;
+            char pos := pos (font table. extension chars, symbol);
+            IF char pos <> 0
+               THEN index := font table. extension indexes ISUB char pos;
+                    extension. replacements table := 
+                          font table. extensions (index). replacements table;
+                    replacements length           :=
+                   LENGTH font table. extensions (index). replacements; 
+                    font. replacements table (extension code 1) := max int;
+               ELSE extension. replacements table := 0;
+                    replacements length           := 0;
+            FI;
+ 
+.
+  get identification :
+    WHILE identification found
+    REP cout (line nr);
+        determine identification link nr;
+        select identification;
+    PER;
+ 
+    . identification found :
+        get next symbol; 
+        symbol type = t tag
+ 
+    . determine identification link nr :
+        identification nr := link (english identification, symbol); 
+        english := TRUE;
+        IF identification nr = 0
+           THEN identification nr := link (german identification, symbol); 
+                english := FALSE;
+                IF identification nr = 0
+                   THEN errorstop ("unzulaesige Identifikation") FI;
+        FI;
+ 
+    . select identification :
+        get next symbol;
+        IF symbol <> "=" OR symbol type <> t operator
+           THEN errorstop ("'=' nach Identifikation fehlt") FI;
+        get next symbol; 
+        SELECT identification nr OF
+          CASE x unit            : x unit found
+          CASE y unit            : y unit found
+          CASE on string         : on string found
+          CASE off string        : off string found
+          CASE indentation pitch : indentation pitch found
+          CASE font lead         : font lead found
+          CASE font height       : font height found
+          CASE font depth        : font depth found
+          CASE larger font       : larger font found
+          CASE smaller font      : smaller font found
+          CASE font string       : font string found
+          CASE y offsets         : y offsets found
+          CASE bold offset       : bold offset found
+        END SELECT;
+ 
+    . x unit found :
+        check modus (font table modus);
+        font table. x unit := real (symbol);
+        IF NOT last conversion ok
+           THEN IF english
+                   THEN errorstop ("REAL-Denoter nach 'x unit' erwartet") 
+                   ELSE errorstop ("REAL-Denoter nach 'x einheit' erwartet")
+                FI;
+        FI;
+        get semicolon;
+ 
+    . y unit found :
+        check modus (font table modus);
+        font table. y unit := real (symbol); 
+        IF NOT last conversion ok
+           THEN IF english
+                   THEN errorstop ("REAL-Denoter nach 'y unit' erwartet")
+                   ELSE errorstop ("REAL-Denoter nach 'y einheit' erwartet")
+                FI;
+        FI;
+        get semicolon;
+ 
+    . on string found :
+        check modus (font table modus);
+        FOR index FROM 1 UPTO 4
+        REP IF symbol type <> t text
+               THEN IF english
+                       THEN errorstop ("TEXT-Denoter nach 'on string' erwartet") 
+                       ELSE errorstop ("TEXT-Denoter nach 'on sequenz' erwartet") 
+                    FI;
+            FI;
+            font table. on strings (index) := symbol;
+            get next symbol;
+            IF (symbol <> "," AND symbol <> ";") OR symbol type <> t delimiter 
+               THEN errorstop ("',' oder ';' in Liste erwartet") FI;
+            IF symbol = ";" THEN LEAVE on string found FI;
+            IF index = 4 THEN errorstop ("';' erwartet") FI;
+            get next symbol;
+        PER;
+ 
+    . off string found :
+        check modus (font table modus);
+        FOR index FROM 1 UPTO 4
+        REP IF symbol type <> t text
+               THEN IF english
+                       THEN errorstop ("TEXT-Denoter nach 'off string' erwartet") 
+                       ELSE errorstop ("TEXT-Denoter nach 'off sequenz' erwartet") 
+                    FI;
+            FI;
+            font table. off strings (index) := symbol;
+            get next symbol;
+            IF (symbol <> "," AND symbol <> ";") OR symbol type <> t delimiter 
+               THEN errorstop ("',' oder ';' in Liste erwartet") FI;
+            IF symbol = ";" THEN LEAVE off string found FI;
+            IF index = 4 THEN errorstop ("';' erwartet") FI;
+            get next symbol;
+        PER;
+ 
+    . indentation pitch found :
+        check modus (font modus);
+        font. indentation pitch := int (symbol);
+        IF NOT last conversion ok
+           THEN IF english
+                   THEN errorstop ("INT-Denoter nach 'indentation pitch' erwartet")
+                   ELSE errorstop ("INT-Denoter nach 'einrueckbreite' erwartet")
+                FI;
+        FI;
+        font. pitch table       := font. indentation pitch;
+        get semicolon;
+ 
+    . font lead found :
+        check modus (font modus);
+        font. font lead := int (symbol);
+        IF NOT last conversion ok
+           THEN IF english
+                   THEN errorstop ("INT-Denoter nach 'font lead' erwartet")
+                   ELSE errorstop ("INT-Denoter nach 'durchschuss' erwartet")
+                FI;
+        FI;
+        get semicolon;
+ 
+    . font height found :
+        check modus (font modus);
+        font. font height := int (symbol);
+        IF NOT last conversion ok
+           THEN IF english
+                   THEN errorstop ("INT-Denoter nach 'font height' erwartet")
+                   ELSE errorstop ("INT-Denoter nach 'fonthoehe' erwartet")
+                FI;
+        FI;
+        get semicolon;
+ 
+    . font depth found :
+        check modus (font modus);
+        font. font depth := int (symbol);
+        IF NOT last conversion ok
+           THEN IF english
+                   THEN errorstop ("INT-Denoter nach 'font depth' erwartet")
+                   ELSE errorstop ("INT-Denoter nach 'fonttiefe' erwartet")
+                FI;
+        FI;
+        get semicolon;
+ 
+    . larger font found :
+        check modus (font modus);
+        IF symbol type <> t text
+           THEN IF english
+                   THEN errorstop ("TEXT-Denoter nach 'next larger font' erwartet")
+                   ELSE errorstop ("TEXT-Denoter nach 'groesserer font' erwartet")
+                FI;
+        FI;
+        determine link nr;
+        font. next larger font := link nr;
+        get semicolon;
+ 
+    . smaller font found :
+        check modus (font modus);
+        IF symbol type <> t text
+           THEN IF english
+                   THEN errorstop ("TEXT-Denoter nach 'next smaller font' erwartet")
+                   ELSE errorstop ("TEXT-Denoter nach 'kleinerer font' erwartet")
+                FI;
+        FI;
+        determine link nr;
+        font. next smaller font := link nr;
+        get semicolon;
+ 
+        . determine link nr :
+            change all (symbol, " ", "");
+            IF   symbol = ""
+              THEN link nr := 0
+              ELSE link nr := link (font table. font names, symbol);
+                   IF link nr = 0
+                      THEN insert (font table. font names, symbol, link nr);
+                           font table. font name links CAT 0;
+                   FI;
+            FI;
+ 
+    . font string found :
+        check modus (font modus);
+        IF symbol type <> t text
+           THEN IF english
+                   THEN errorstop ("TEXT-Denoter nach 'font string' erwartet")
+                   ELSE errorstop ("TEXT-Denoter nach 'fontsequenz' erwartet")
+                FI;
+        FI;
+        font. font string := symbol;
+        get semicolon;
+ 
+    . y offsets found :
+        check modus (font modus);
+        font. y offsets := "";
+        REP IF symbol = "-" AND symbol type = t operator
+               THEN vorzeichen := -1;
+                    get next symbol;
+               ELSE vorzeichen :=  1;
+            FI;
+            int symbol := vorzeichen * int (symbol);
+            IF NOT last conversion ok
+               THEN IF english
+                       THEN errorstop ("INT-Denoter nach 'y offsets' erwartet")
+                       ELSE errorstop ("INT-Denoter nach 'y verschiebungen' erwartet")
+                    FI;
+            FI;
+            font. y offsets CAT int symbol;
+            get next symbol;
+            IF (symbol <> "," AND symbol <> ";") OR symbol type <> t delimiter 
+               THEN errorstop ("',' oder ';' in Liste erwartet") FI;
+            IF symbol = ";" THEN LEAVE y offsets found FI;
+            get next symbol;
+        PER;
+ 
+    . bold offset found :
+        check modus (font modus);
+        IF symbol = "-" AND symbol type = t operator
+           THEN vorzeichen := -1;
+                get next symbol;
+           ELSE vorzeichen :=  1;
+        FI;
+        font. bold offset := vorzeichen * int (symbol);
+        IF NOT last conversion ok
+           THEN IF english
+                   THEN errorstop ("INT-Denoter nach 'bold offset' erwartet")
+                   ELSE errorstop ("INT-Denoter nach 'bold verschiebungen' erwartet")
+                FI;
+        FI;
+        get semicolon;
+ 
+.
+  get char specifications :
+    WHILE char found
+    REP cout (line nr); 
+        char specification;
+        get next symbol; 
+    PER;
+ 
+    . char found :
+        symbol type = t text
+ 
+    . char specification :
+        IF LENGTH symbol <> 1 
+           THEN errorstop ("nur ein Zeichen bei Zeichenangabe erlaubt") FI;
+        char := symbol; 
+        char code 1 := code (char) + 1;
+        look for specification;
+        look for specification;
+        get semicolon;
+ 
+    . look for specification :
+        get next symbol; 
+        IF   symbol = ";" AND symbol type = t delimiter 
+          THEN LEAVE char specification
+        ELIF symbol = "," AND symbol type = t delimiter 
+          THEN get specification
+          ELSE errorstop ("',' oder ';' bei Zeichenspezifikation erwartet")
+        FI;
+ 
+    . get specification :
+        get next symbol;
+        IF   symbol type = t number
+          THEN pitch specification;
+        ELIF symbol type = t text 
+          THEN replacement specification
+          ELSE errorstop ("unzulaessiger Wert bei Zeichenspezifikation")
+        FI;
+ 
+        . pitch specification :
+            int symbol := int (symbol);
+            IF NOT last conversion ok
+               THEN errorstop ("INT-Denoter bei Breitenangabe erwartet") FI;
+            IF   modus = font modus
+               THEN font. pitch table (char code 1) := int symbol;
+                    IF is kanji esc (char)
+                       THEN set bit (font. pitch table (char code 1), highest bit) FI; 
+            ELIF modus = extension modus
+               THEN IF last modus = font modus AND
+                         font. pitch table (extension code 1) <> max int
+                       THEN font. pitch table (extension code 1) := max int FI;
+                    extension. pitch table (char code 1) := int symbol;
+            FI;
+ 
+        . replacement specification : 
+            IF LENGTH symbol > 255
+               THEN errorstop ("Ersatzdarstellungen duerfen nur 255 Zeichen haben") FI;
+            IF   modus = font table modus
+               THEN font table. replacements table (char code 1) := 
+                                       (LENGTH font table. replacements + 1); 
+                    font table. replacements CAT code (LENGTH symbol);
+                    font table. replacements CAT symbol;
+                    IF is kanji esc (char)
+                       THEN set bit (font table. replacements table (char code 1), highest bit) FI; 
+            ELIF modus = font modus
+               THEN font. replacements table (char code 1) :=
+                       (replacements length + LENGTH font. replacements + 1); 
+                    font. replacements CAT code (LENGTH symbol);
+                    font. replacements CAT symbol;
+                    IF is kanji esc (char)
+                       THEN set bit (font. replacements table (char code 1), highest bit) FI; 
+            ELIF modus = extension modus
+               THEN IF last modus = font modus AND
+                         font. replacements table (extension code 1) <> max int
+                       THEN font. replacements table (extension code 1) := max int FI;
+                    extension. replacements table (char code 1) :=
+                      (replacements length + LENGTH extension. replacements + 1); 
+                    extension. replacements CAT code (LENGTH symbol);
+                    extension. replacements CAT symbol;
+            FI;
+ 
+END PROC load;
+ 
+ 
+PROC get name list :
+ 
+   names := empty thesaurus;
+   get next symbol;
+   IF symbol <> ":" OR symbol type <> t delimiter 
+      THEN errorstop ("':' nach Kennung erwartet") FI;
+   REP get next symbol;
+       change all (symbol, " ", "");
+       IF symbol type <> t text
+          THEN errorstop ("TEXT-Denoter in Namesliste erwartet") FI;
+       IF symbol = ""
+          THEN errorstop ("'niltext' als Name nicht erlaubt") FI;
+       insert (names, symbol);
+       get next symbol;
+       IF (symbol <> "," AND symbol <> ";") OR symbol type <> t delimiter 
+          THEN errorstop ("',' oder ';' in Liste erwartet") FI;
+   UNTIL symbol = ";" PER;
+ 
+   . get next symbol :
+       next symbol (file, symbol, symbol type);
+ 
+END PROC get name list;
+ 
+ 
+OP := (ROW 256 INT VAR l, INT CONST r) :
+ 
+INT VAR i;
+IF modus = extension modus OR NOT two bytes
+   THEN FOR i FROM   1 UPTO 256 REP l (i) := r PER; 
+   ELSE FOR i FROM   1 UPTO 129 REP l (i) := r PER;
+        FOR i FROM 130 UPTO 160 REP l (i) := r - maxint - 1 PER;
+        FOR i FROM 161 UPTO 224 REP l (i) := r PER;
+        FOR i FROM 225 UPTO 240 REP l (i) := r - maxint - 1 PER;
+        FOR i FROM 241 UPTO 256 REP l (i) := r PER;
+FI;
+ 
+END OP :=;
+ 
+ 
+PROC check modus (INT CONST mod) :
+ 
+  IF mod <> modus THEN errorstop ("unzulaessige Identifikation") FI;
+ 
+END PROC check modus;
+ 
+ 
+PROC error (TEXT CONST message) :
+ 
+(*INT CONST l := error line;*)
+  clear error;
+  errorstop ("Zeile " + text (line nr) + " bei " + letztes symbol +
+             " : " + message (* + errorline if neccessary *) ); 
+ 
+  . letztes symbol :
+      IF   symbol type  = t text
+           THEN decode (symbol);
+                """" + symbol + """"
+      ELIF symbol type >= t end of file
+           THEN "EOF"
+           ELSE symbol
+      FI
+(*
+  . errorline if neccessary :
+      IF l = 0 
+         THEN ""
+         ELSE " -> " + text (l) 
+      FI
+*)
+END PROC error;
+ 
+ 
+(*******************************************************************)
+ 
+ 
+PROC create font file (TEXT CONST font tab name, font file name) :
+ 
+enable stop;
+connect font table;
+put font table in font file;
+ 
+.
+  connect font table :
+    buffer := font tab name;
+    change all (buffer, " ", "");
+    IF NOT exists (buffer) COR type (old (buffer)) <> font table type
+       THEN errorstop ("Fonttabelle """ + buffer + """ gibt es nicht")
+    FI;
+   font table := old (buffer);
+ 
+.
+  put font table in font file :
+    INT VAR font file nr := 0;
+    enable stop;
+    font file := sequential file (output, font file name);
+    max line length (font file, 16000);
+    check file overflow;
+    z := " ";
+    put font table;
+    FOR font nr FROM 1 UPTO font table. last font REP put font PER;
+ 
+    . check file overflow :
+        WHILE lines (font file) > 3600
+        REP font file nr INCR 1;
+            font file := sequential file (output, font file name + "." + text (font file nr));
+            max line length (font file, 16000);
+        PER;
+
+. put font table :
+    put z;
+    z CAT "FONTTABLE  :  """; z CAT buffer;                  z CAT """;"; put z; 
+    z CAT "  x unit      =  ";   z CAT text (font table. x unit); z CAT ";"; put z; 
+    z CAT "  y unit      =  ";   z CAT text (font table. y unit); z CAT ";"; put z; 
+    z CAT "  on string   =  """; z cat on strings;              z CAT """;"; put z; 
+    z CAT "  off string  =  """; z cat off strings;             z CAT """;"; put z; 
+    put font table replacements;
+    put font table extensions;
+    put z;
+ 
+    . z cat on strings :
+        FOR index FROM 1 UPTO 4
+        REP buffer := font table. on strings (index);
+            decode (buffer); 
+            z CAT buffer;
+            IF index <> 4 THEN z CAT """,  """ FI;
+        PER;
+ 
+    . z cat off strings :
+        FOR index FROM 1 UPTO 4
+        REP buffer := font table. off strings (index);
+            decode (buffer); 
+            z CAT buffer;
+            IF index <> 4 THEN z CAT """,  """ FI;
+        PER;
+ 
+    . put font table replacements : 
+        put z;
+        FOR char code FROM 0 UPTO 255
+        REP char code 1 := char code + 1;
+            link nr     := font table. replacements table (char code 1);
+            reset bit (link nr, highest bit);
+            IF link nr > 0 AND link nr <> maxint
+               THEN z CAT "  ";
+                    put char code;
+                    put font table replacement;
+                    put z;
+            FI;
+        PER;
+ 
+        . put font table replacement :
+            replacement := subtext (font table.  replacements, link nr + 1,
+                     link nr + code (font table. replacements SUB link nr) );
+            put replacement;
+ 
+    . put font table extensions :
+        IF font table. extension chars <> ""
+           THEN FOR index FROM 1 UPTO LENGTH font table. extension chars 
+                REP put font table extension PER;
+        FI;
+ 
+    . put font table extension :
+        check file overflow;
+        put z;
+        z CAT "  EXTENSION  :  """"";
+        z CAT text 3 (code (font table. extension chars SUB index));
+        z CAT """"";";
+        put z; put z; 
+        replacements length := 0;
+        extension nr        := font table. extension indexes ISUB index;
+        FOR char code FROM 0 UPTO 255
+        REP char code 1 := char code + 1;
+            link nr     := extension. replacements table (char code 1);
+            IF link nr > 0
+               THEN z CAT "  ";
+                    put char code;
+                    put extension replacement;
+                    put z;
+            FI;
+        PER;
+ 
+. put font :
+    check file overflow;
+    put z;
+            z CAT "  FONT  :  "; z cat font names; z CAT ";"; put z; 
+            z CAT "    indentation pitch  =  ";
+            z CAT text(font. indentation pitch);
+            z CAT ";"; put z; 
+    IF font. font lead <> 0 
+       THEN z CAT "    font lead          =  ";
+            z CAT text(font. font lead);
+            z CAT ";"; put z;
+    FI;
+            z CAT "    font height        =  ";
+            z CAT text(font. font height);
+            z CAT ";"; put z; 
+    IF font. font depth <> 0
+       THEN z CAT "    font depth         =  ";
+            z CAT text(font. font depth);
+            z CAT ";"; put z;
+    FI;
+    IF next larger <> ""
+       THEN z CAT "    next larger font   =  """;
+            z CAT next larger;
+            z CAT """;"; put z;
+    FI;
+    IF next smaller <> ""
+       THEN z CAT "    next smaller font  =  """;
+            z CAT next smaller;
+            z CAT """;"; put z;
+    FI;
+    IF font. font string <> ""
+       THEN z CAT "    font string        =  """;
+            z CAT font string;
+            z CAT """;"; put z;
+    FI;
+    IF (font. y offsets ISUB 1) <> 0 OR LENGTH font. y offsets > int length
+       THEN z CAT "    y offsets          =  ";
+            z cat y offsets;
+            z CAT ";"; put z; 
+    FI;
+    IF font. bold offset <> 0
+       THEN z CAT "    bold offset        =  ";
+            z CAT text(font. bold offset);
+            z CAT ";"; put z;
+    FI;
+    put font pitches and replacements;
+    put font extensions;
+ 
+    . next larger  : name (font table. font names, font. next larger font)
+    . next smaller : name (font table. font names, font. next smaller font)
+    . font string  : buffer := font. font string; decode (buffer); buffer
+ 
+    . z cat font names :
+        z CAT """";
+        z CAT name (font table. font names, font. font name indexes ISUB 1);
+        z CAT """";
+        FOR index FROM 2 UPTO LENGTH font. font name indexes DIV int length
+        REP z CAT ",  """;
+            z CAT name (font table. font names, font. font name indexes ISUB index);
+            z CAT """";
+        PER;
+ 
+    . z cat y offsets :
+        z CAT text (font. y offsets ISUB 1);
+        FOR index FROM 2 UPTO LENGTH font. y offsets DIV int length
+        REP z CAT ",  ";
+            z CAT text (font. y offsets ISUB index);
+        PER;
+ 
+    . put font pitches and replacements :
+        BOOL VAR ausgabe := FALSE; 
+        replacements length := LENGTH font table. replacements;
+        put z;
+        z CAT "  "; 
+        FOR char code FROM 0 UPTO 255
+        REP char code 1 := char code + 1;
+            pitch       := font. pitch table (char code 1); 
+            reset bit (pitch, highest bit); 
+            link nr     := font. replacements table (char code 1);
+            reset bit (link nr, highest bit);
+            IF (pitch <> font. indentation pitch) OR
+               (link nr > replacements length AND link nr <> maxint)
+               THEN put font char pitch and replacement;
+                    IF ausgabe 
+                       THEN put z;
+                            ausgabe := FALSE;
+                       ELSE ausgabe := TRUE;
+                    FI;
+                    z CAT "  "; 
+            FI;
+        PER;
+        IF ausgabe THEN put z ELSE z := " " FI;
+ 
+        . put font char pitch and replacement :
+            put char code;
+            put font char pitch; 
+            IF   link nr > replacements length AND link nr <> maxint
+                 THEN put font replacement;
+                      IF NOT ausgabe THEN z CAT (6 - LENGTH replacement) * " " FI;
+            ELIF ausgabe
+                 THEN z CAT ";"
+                 ELSE z CAT ";            ";
+            FI;
+ 
+        . put font char pitch :
+            IF pitch = max int 
+               THEN char pos := pos (font. extension chars, code (char code));
+                    IF char pos <> 0
+                       THEN pitch := font table. extensions
+                              (font. extension indexes ISUB char pos). std pitch 
+                    FI;
+            FI;
+            put char pitch; 
+ 
+        . put font replacement :
+            link nr DECR replacements length;
+            replacement := subtext (font.  replacements, link nr + 1,
+                           link nr + code (font. replacements SUB link nr) );
+            put replacement;
+ 
+    . put font extensions :
+        IF font. extension chars <> ""
+           THEN FOR index FROM 1 UPTO LENGTH font. extension chars 
+                REP put font extension PER;
+        FI;
+ 
+    . put font extension :
+        check file overflow;
+        put z;
+        z CAT "  EXTENSION  :  """"";
+        z CAT text 3 (code (font. extension chars SUB index));
+        z CAT """"";";
+        put z; put z; z CAT "  "; 
+        detemine replacements length;
+        extension nr := font. extension indexes ISUB index;
+        ausgabe      := FALSE;
+        FOR char code FROM 0 UPTO 255
+        REP char code 1 := char code + 1;
+            pitch       := extension. pitch table (char code 1);
+            link nr     := extension. replacements table (char code 1);
+            IF pitch <> extension. std pitch OR link nr > replacements length
+               THEN put extension char pitch and replacement; 
+                    IF ausgabe 
+                       THEN put z;
+                            ausgabe := FALSE;
+                       ELSE ausgabe := TRUE;
+                    FI;
+                    z CAT "  "; 
+            FI;
+        PER;
+        IF ausgabe THEN put z ELSE z := " " FI;
+ 
+        . detemine replacements length :
+            char pos := pos (font table. extension chars,
+                                         font. extension chars SUB index); 
+            IF char pos <> 0
+               THEN replacements length := LENGTH font table. extensions
+                  (font table. extension indexes ISUB char pos). replacements; 
+               ELSE replacements length := 0;
+            FI;
+ 
+        . put extension char pitch and replacement :
+            put char code;
+            put char pitch;
+            IF   link nr > replacements length
+                 THEN put extension replacement;
+                      IF NOT ausgabe THEN z CAT (6 - LENGTH replacement) * " " FI;
+            ELIF ausgabe
+                 THEN z CAT ";"
+                 ELSE z CAT ";            ";
+            FI;
+ 
+. put extension replacement :
+    link nr DECR replacements length;
+    replacement := subtext (extension. replacements, link nr + 1,
+                     link nr + code (extension. replacements SUB link nr) );
+    put replacement;
+ 
+. put char code :
+    IF (char code >= 32  AND char code <= 122) OR
+       (char code >= 214 AND char code <= 223) OR
+        char code  = 124  OR char code  = 126  OR char code  = 251
+       THEN z CAT "(* ";
+            z CAT code (char code);
+            z CAT " *) """"";
+       ELSE z CAT "        """"";
+    FI;
+    z CAT text 3 (char code);
+    z CAT """""";
+ 
+. put char pitch : 
+    z CAT ",";
+    z CAT text (pitch, 5);
+ 
+. put replacement :
+    decode (replacement);
+    z CAT ",   """;
+    z CAT replacement;
+    z CAT """;"
+ 
+END PROC create font file;
+ 
+ 
+PROC put z :
+ 
+  putline (font file, z);
+  cout (lines (font file));
+  z := " ";
+ 
+END PROC put z;
+ 
+ 
+PROC decode (TEXT VAR string) :
+ 
+  INT VAR p;
+  change all (string, """", """""");
+  p := pos (string, ""0"", ""31"", 1);
+  WHILE p <> 0
+  REP change (string, p, p, """" + text (code(string SUB p)) + """");
+      p := pos (string, ""0"", ""31"", p);
+  PER;
+  p := pos (string, ""127"", ""255"", 1);
+  WHILE p <> 0
+  REP change (string, p, p, """" + text (code(string SUB p)) + """");
+      p := pos (string, ""127"", ""255"", p);
+  PER;
+ 
+END PROC decode;
+ 
+ 
+TEXT PROC text 3 (INT CONST value) :
+ 
+  buffer := text (value, 3);
+  change all (buffer, " ", "0");
+  buffer
+ 
+END PROC text 3;
+ 
+END PACKET font convertor;
+
diff --git a/system/free channel b/system/free channel
new file mode 100644
index 0000000..3814f9d
--- /dev/null
+++ b/system/free channel	
@@ -0,0 +1,430 @@
+PACKET free channel DEFINES                       (* Autor: J.Liedtke *)
+                                                  (* Stand: 10.06.86  *)
+  FCHANNEL ,
+  := ,
+  free channel ,
+  open ,
+  close ,
+  out ,
+  in ,
+  dialogue ,
+  save ,
+  fetch :
+ 
+ 
+
+LET ack                = 0 ,
+    nak                = 1 ,
+    error nak          = 2 ,
+    empty message code = 256 ,
+    long message code  = 257 ,
+    file send code     = 1024 ,
+    file receive code  = 2048 ,
+    open code          = 1000 ,
+    close code         = 1001 ,
+
+    file type          = 1003 ;
+
+INT CONST task not existing := - 1 ;
+
+
+TYPE FCHANNEL = STRUCT (TASK server, TEXT input buffer, server name) ;
+
+INT VAR message code , response code ;
+TASK VAR partner ;
+DATASPACE VAR ds ;
+
+BOUND TEXT VAR msg ;
+TEXT VAR response, char, esc char , record ;
+
+FILE VAR file ;
+
+
+OP := (FCHANNEL VAR dest, FCHANNEL CONST source) :
+ 
+  dest.server := source.server ;
+  dest.input buffer := "" ;
+  dest.server name := source.server name ;
+  open (dest)
+
+ENDOP := ;
+
+FCHANNEL PROC free channel (TEXT CONST channel name) :
+
+  FCHANNEL:(niltask,"", channel name)
+
+ENDPROC free channel ;
+
+PROC open (FCHANNEL VAR channel) :
+
+  INT VAR receipt ;
+ 
+  initialize message dataspace ;
+  send open code ;
+  IF receipt <> ack
+    THEN errorstop ("channel not free")
+  FI .
+
+initialize message dataspace :
+  forget (ds) ;
+  ds := nilspace .
+
+send open code :
+  ping pong (channel.server, open code, ds, receipt) ;
+  IF receipt = task not existing
+    THEN channel.server := task (channel.server name) ;
+         ping pong (channel.server, open code, ds, receipt)
+  FI .
+ 
+ENDPROC open ;
+
+PROC close (FCHANNEL VAR channel) :
+
+  forget (ds) ;
+  ds := nilspace ;
+  call (channel.server, close code, ds, response code)
+
+ENDPROC close ;
+
+PROC close (TEXT CONST channel server) :
+
+  forget (ds) ;
+  ds := nilspace ;
+  call (task (channel server), close code, ds, response code)
+
+ENDPROC close ;
+
+
+PROC out (FCHANNEL VAR channel, TEXT CONST message) :
+
+  send message ;
+  get response .
+
+send message :
+  IF message = ""
+    THEN call (channel.server, empty message code, ds, response code)
+    ELSE msg := ds ;
+         CONCR (msg) := message ;
+         call (channel.server, long message code, ds, response code)
+  FI .
+
+get response :
+  IF response code < 0
+    THEN errorstop ("channel not ready")
+  ELIF response code < 256
+    THEN channel.input buffer CAT code (response code)
+  ELIF response code = long message code
+    THEN msg := ds ;
+         channel.input buffer CAT CONCR (msg)
+  FI .
+
+ENDPROC out ;
+
+PROC in (FCHANNEL VAR channel, TEXT VAR response) :
+
+  out (channel, "") ;
+  response := channel.input buffer ;
+  channel.input buffer := ""
+
+ENDPROC in ;
+
+PROC save (FCHANNEL VAR channel, TEXT CONST file name, control chars) :
+
+  prepare ds ;
+  call (channel.server, file send code, ds, response code) ;
+  IF response code = error nak
+    THEN BOUND TEXT VAR error msg := ds ;
+         errorstop (error msg)
+  FI .
+
+prepare ds :
+  forget (ds) ;
+  ds := old (file name, file type) ;
+  FILE VAR f := sequential file (modify, ds) ;
+  headline (f, control chars) .
+
+ENDPROC save ;
+
+PROC fetch (FCHANNEL VAR channel, TEXT CONST file name, control chars) :
+
+  IF NOT exists (file name) COR yes ("""" + file name + """ loeschen")
+    THEN fetch first part ;
+         WHILE more to fetch REP
+           fetch next part
+         PER
+  FI .
+
+fetch first part :
+  INT VAR part := 0 ;
+  receive file (channel, file name, control chars) .
+
+fetch next part :
+  part INCR 1 ;
+  receive file (channel, file name + "." + text (part), control chars) .
+
+more to fetch :  response code = file receive code .
+
+ENDPROC fetch ;
+
+PROC receive file (FCHANNEL VAR channel,TEXT CONST file name, control chars):
+
+  prepare ds ;
+  call (channel.server, file receive code, ds, response code);
+  IF response code = error nak
+    THEN BOUND TEXT VAR error msg := ds ;
+         errorstop (error msg)
+    ELSE forget (file name, quiet) ;
+         copy (ds, file name) ;
+         forget (ds) ;
+         ds := nilspace ;
+  FI .
+
+prepare ds :
+  forget (ds) ;
+  ds := nilspace ;
+  BOUND TEXT VAR ctl := ds ;
+  ctl := control chars .
+
+ENDPROC receive file ;
+
+
+PROC dialogue (FCHANNEL CONST channel, TEXT CONST esc) :
+
+  forget (ds) ;
+  ds := nilspace ;
+  partner := channel.server ;
+  esc char := esc ;
+  enable stop ;
+
+  response code := empty message code ;
+  REP
+    get and send message charety ;
+    out response option
+  PER .
+
+get and send message charety :
+  IF response code = empty message code
+    THEN char := incharety (10)
+    ELSE char := incharety
+  FI ;
+  IF char = ""
+    THEN call (partner, empty message code, ds, response code)
+  ELIF char = esc char
+    THEN LEAVE dialogue
+  ELSE   call (partner, code (char), ds, response code)
+  FI .
+
+out response option :
+  IF response code < 256
+    THEN out (code (response code))
+  ELIF response code = long message code
+    THEN msg := ds ;
+         out (CONCR (msg))
+  FI .
+
+ENDPROC dialogue ;
+
+PROC free channel (INT CONST nr) :
+
+  INT CONST my channel := nr ;
+  break ;
+  disable stop ;
+  REP
+    wait (ds, message code, partner) ;
+    IF message code = open code
+      THEN connect to my channel ;
+           use channel ;
+           break (quiet)
+    ELIF message code >= 0
+      THEN send (partner, nak, ds)
+    FI
+  PER .
+
+use channel :
+  ping pong (partner, ack, ds, message code) ;
+  WHILE message code <> close code AND message code >= 0 REP
+    IF   message code <= long message code  THEN dialogue
+    ELIF message code =  file receive code  THEN receive file
+    ELIF message code =  file send code     THEN send file
+    ELIF message code =  open code          THEN ignore open
+    ELSE errorstop ("falsche Sendung")
+    FI
+  UNTIL is error PER ;
+  IF is error
+    THEN send error message
+    ELSE send handshake ack
+  FI .
+
+dialogue :
+  IF message code < 256
+    THEN out (code (message code))
+  ELIF message code = long message code
+    THEN msg := ds ;
+         out (CONCR (msg))
+  FI ;
+  response := incharety (1) ;
+  IF response = ""
+    THEN ping pong (partner, empty message code, ds, message code)
+    ELSE short or long response
+  FI .
+
+short or long response :
+  char := incharety ;
+  IF char = ""
+    THEN short response
+    ELSE long response
+  FI .
+
+short response :
+  ping pong (partner, code (response), ds, message code) .
+
+long response :
+  msg := ds ;
+  response CAT char ;
+  msg := response ;
+  REP
+    cat input (msg, char) ;
+    msg CAT char
+  UNTIL char = "" OR LENGTH msg > 500 PER ;
+  ping pong (partner, long message code, ds, message code) .
+
+connect to my channel :
+  continue (my channel) ;
+  WHILE is error REP
+    clear error ;
+    pause (100) ;
+    continue (my channel)
+  PER .
+
+send handshake ack :
+  send (partner, ack, ds) .
+
+send error message :
+  forget (ds) ;
+  ds := nilspace ;
+  BOUND TEXT VAR error msg := ds ;
+  error msg := error message ;
+  clear error ;
+  send (partner, error nak, ds) .
+
+ignore open :
+  ping pong (partner, ack, ds, message code) .
+
+ENDPROC free channel ;
+
+PROC send file :
+
+  enable stop ;
+  file := sequential file (input,ds) ;
+  get control chars ;
+  skip chars ;
+  REP
+    getline (file, record) ;
+    out (record) ;
+    end of line
+  UNTIL eof (file) PER ;
+  end of transmission ;
+  send ack reply .
+
+get control chars :
+  TEXT CONST
+  control chars := headline (file) ,
+  end of file char := control chars SUB 1 ,
+  end of line char := control chars SUB 2 ,
+  handshake   char := control chars SUB 3 .
+
+end of line :
+  out (end of line char) ;
+  IF handshake char <> ""
+    THEN wait for handshake
+  FI .
+
+wait for handshake :
+  REP
+    char := incharety (300) ;
+    IF char = ""
+      THEN errorstop ("timeout")
+    FI
+  UNTIL char = handshake char PER .
+
+end of transmission :
+  skip chars ;
+  out (end of file char) .
+
+skip chars :
+  WHILE incharety (3) <> "" REP PER .
+
+send ack reply :
+  forget (ds) ;
+  ds := nilspace ;
+  ping pong (partner, ack, ds, message code) .
+
+ENDPROC send file ;
+
+PROC receive file :
+
+  enable stop ;
+  get control chars ;
+  open file ;
+  INT VAR line no := 0 ;
+  REP
+    receive line ;
+    IF eof received
+      THEN ping pong (partner, ack, ds, message code) ;
+           LEAVE receive file
+    FI ;
+    putline (file, record) ;
+    line no INCR 1
+  UNTIL near file overflow PER ;
+  ping pong (partner, file receive code, ds, message code) .
+
+get control chars :
+  BOUND TEXT VAR control chars := ds ;
+  TEXT CONST
+  end of file char := control chars SUB 1 ,
+  end of line char := control chars SUB 2 ,
+  handshake   char := control chars SUB 3 ,
+  handshake prompt := control chars SUB 4 .
+
+open file :
+  forget (ds) ;
+  ds := nilspace ;
+  file := sequential file (output, ds) .
+
+receive line :
+  record := "" ;
+  REP
+    cat input (record, char) ;
+    IF char = ""
+      THEN wait for char
+    FI ;
+    IF   char = handshake prompt THEN out (handshake char)
+    ELIF char = ""9""            THEN expand tabs
+    ELIF char = ""12""           THEN page
+    FI
+  UNTIL char = end of line char OR char = end of file char PER .
+
+wait for char :
+  char := incharety (300) ;
+  IF char = ""
+    THEN errorstop ("timeout")
+  ELIF char >= ""32""
+    THEN record CAT char
+  FI .
+
+expand tabs:
+  record CAT (8-(LENGTH record MOD 8)) * " " .
+
+page:
+  record := "#page# " .
+
+eof received :
+  char = end of file char OR (record SUB LENGTH record ) = end of file char .
+
+near file overflow :
+  line no > 3999 OR (line no > 3800 AND record = "#page# ") .
+
+ENDPROC receive file ;
+
+ENDPACKET free channel ;
+
diff --git a/system/port server b/system/port server
new file mode 100644
index 0000000..46c647f
--- /dev/null
+++ b/system/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/printer server b/system/printer server
new file mode 100644
index 0000000..b1a30bc
--- /dev/null
+++ b/system/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/purge b/system/purge
new file mode 100644
index 0000000..55230ff
--- /dev/null
+++ b/system/purge
@@ -0,0 +1,85 @@
+PACKET purge DEFINES purge :
+
+ 
+TEXT VAR task name, record, file name, dummy ;
+
+FILE VAR permit ;
+
+
+PROC purge :
+
+  IF exists ("permitted tasks")
+    THEN access catalogue ;
+         permit := sequential file (input, "permitted tasks") ;
+         say (""10""13"TASKS :"10""10""13"") ;
+         IF myself < supervisor
+           THEN purge son tasks (brother (supervisor))
+           ELSE purge son tasks (myself)
+         FI
+  FI ;
+  IF exists ("permitted files")
+    THEN permit := sequential file (input, "permitted files") ;
+         say (""10""13"DATEIEN :"10""10""13"") ;
+         purge files
+  FI
+
+ENDPROC purge ;
+
+PROC purge son tasks (TASK CONST father task) :
+
+  TASK VAR actual task := son (father task) ;
+  WHILE NOT is niltask (actual task) REP
+    purge son tasks (actual task) ;
+    IF NOT actual task permitted
+      THEN erase actual task
+    FI ;
+    actual task := brother (actual task)
+  END REP .
+
+erase actual task :
+  say ("""") ; say (task name) ; say ("""") ;
+  IF yes (" loeschen")
+    THEN end (actual task)
+  FI .
+
+actual task permitted :
+  task name := name (actual task) ;
+  reset (permit) ;
+  WHILE NOT eof (permit) REP
+    getline (permit, record) ;
+    IF task name = record
+      THEN LEAVE actual task permitted WITH TRUE
+    FI
+  END REP ;
+  FALSE .
+
+ENDPROC purge son tasks ;
+
+PROC purge files :
+
+  begin list ;
+  get list entry (file name, dummy) ;
+  WHILE file name <> "" REP
+    IF NOT file permitted
+      THEN forget (file name)
+    FI ;
+    get list entry (file name, dummy)
+  END REP .
+
+file permitted :
+  IF file name = "permitted tasks" OR file name = "permitted files"
+    THEN LEAVE file permitted WITH TRUE
+  FI ;
+  reset (permit) ;
+  WHILE NOT eof (permit) REP
+    getline (permit, record) ;
+    IF file name = record
+      THEN LEAVE file permitted WITH TRUE
+    FI
+  END REP ;
+  FALSE .
+
+ENDPROC purge files ;
+
+ENDPACKET purge ;
+
diff --git a/system/referencer b/system/referencer
new file mode 100644
index 0000000..2ee65e4
--- /dev/null
+++ b/system/referencer
@@ -0,0 +1,1077 @@
+(* ------------------- VERSION 10 vom 01.08.86 -------------------- *)
+PACKET referencer errors DEFINES report referencer error:
+
+(* Programm zur Fehlerbehandlung des referencers.
+   Autor: Rainer Hahn *)
+
+TEXT VAR fehlerdummy,
+         message;
+
+PROC report referencer error (INT CONST error nr,
+                           INT CONST line nr,
+                           TEXT CONST addition):
+
+  einfache fehlermeldung aufbauen;
+  diese auf terminal ausgeben;
+  fehlermeldung in fehlerdatei ausgeben.
+
+einfache fehlermeldung aufbauen:
+  message := "WARNUNG in Zeile ";
+  message CAT text (line nr);
+  message CAT " : ";
+  message CAT simple message.
+
+diese auf terminal ausgeben: 
+  line ; 
+  putline (message).
+ 
+fehlermeldung in fehlerdatei ausgeben: 
+  note (message); 
+  note line ;
+  fehlerdummy := "   >>> ";
+  fehlerdummy CAT zusatz;
+  note (fehlerdummy);
+  note line.
+ 
+simple message: 
+  SELECT error nr OF 
+  CASE 1: "Text Denoter ueber mehr als eine Zeile"
+  CASE 2: "Nicht beendeter Text Denoter bei Programmende" 
+  CASE 3: "Kommentar ueber mehr als eine Zeile" 
+  CASE 4: "Nicht beendeter Kommentar bei Programmende" 
+  CASE 5: "Ueberdeckung"
+  CASE 6, 9: "Refinement mehrmals eingesetzt" 
+  CASE 7, 10: "Refinement wird nicht aufgerufen"
+  CASE 8: "Objekt wird nicht angesprochen"
+  OTHERWISE "" 
+  ENDSELECT. 
+ 
+zusatz: 
+  SELECT error nr OF 
+  CASE 1, 2, 3, 4: "Ueber " + addition + " Zeilen"
+  CASE 5: addition
+  CASE 6, 7, 8: addition
+  CASE 9, 10: addition + " in mindestens einer Prozedur"
+  OTHERWISE "interner Fehler: HRZ Bielefeld benachrichtigen!" 
+  END SELECT.
+END PROC report referencer error 
+END PACKET referencer errors; 
+(************************************************************************)
+ 
+PACKET name table handling
+              DEFINES NAMETABLE,
+                      empty name table,
+                      put name, 
+                      get name,
+                      dump table:
+ 
+(* Programm zur Speicherung von Namen.
+   Autor: Rainer Hahn *)
+
+LET hash table length           = 1024, 
+    hash table length minus one = 1023,
+    start of name table         = 255,
+    name table length           = 2000;
+ 
+TYPE NAMETABLE = STRUCT (INT number of entries, 
+                         ROW hash table length INT hash table,
+                         ROW name table length INT next, 
+                         ROW name table length TEXT name table); 
+ 
+TEXT VAR dummy, f;
+ 
+PROC put name (NAMETABLE VAR n, TEXT CONST name, INT VAR pointer):
+  INT VAR errechneter index; 
+  hash (name, errechneter index); 
+  IF noch kein eintrag 
+    THEN gaenzlich neuer eintrag 
+    ELSE name in vorhandener kette 
+  FI. 
+ 
+noch kein eintrag: 
+  n . hash table [errechneter index] = 0. 
+ 
+gaenzlich neuer eintrag: 
+  n . hash table [errechneter index] := n . number of entries; 
+  neuer eintrag (n, name, pointer).
+ 
+name in vorhandener kette:
+  INT VAR dieser eintrag :: n. hash table [errechneter index]; 
+  REP 
+    IF name ist vorhanden
+      THEN pointer := dieser eintrag;
+           LEAVE put name 
+    ELIF kette zu ende
+      THEN neuer eintrag an vorhandene kette anketten; 
+           neuer eintrag (n, name, pointer);
+           LEAVE put name
+      ELSE naechster eintrag in der kette
+    FI 
+  END REP.
+ 
+name ist vorhanden: 
+  n . name table [dieser eintrag] = name.
+ 
+kette zu ende: 
+  n . next [dieser eintrag] = 0.
+ 
+neuer eintrag an vorhandene kette anketten: 
+  n . next [dieser eintrag] := n . number of entries. 
+ 
+naechster eintrag in der kette:
+  dieser eintrag := n . next [dieser eintrag].
+END PROC put name; 
+ 
+PROC neuer eintrag (NAMETABLE VAR n, TEXT CONST name, INT VAR pointer):
+  n . name table [n . number of entries] := name; 
+  n . next [n . number of entries] := 0; 
+  pointer := n . number of entries;
+  n . number of entries INCR 1; 
+  IF n . number of entries > name table length 
+    THEN errorstop ("volle Namenstabelle")
+  FI 
+END PROC neuer eintrag;
+ 
+PROC hash (TEXT CONST name, INT VAR index) :
+  INT VAR i;
+  index := code (name SUB 1);
+  FOR i FROM 2 UPTO length (name) REP
+    addmult cyclic
+  ENDREP.
+ 
+addmult cyclic :
+  index INCR index ;
+  IF index > hash table length minus one
+    THEN wrap around
+  FI;
+  index := (index + code (name SUB i)) MOD hash table length.
+ 
+wrap around :
+  index DECR hash table length minus one
+ENDPROC hash ;
+ 
+PROC get name (NAMETABLE CONST n, INT CONST index, TEXT VAR t): 
+  IF index < n . number of entries AND index >= start of name table
+    THEN t := n . name table [index] 
+    ELSE errorstop ("Interner Fehler 1") 
+  FI 
+END PROC get name; 
+ 
+PROC empty name table (NAMETABLE VAR n): 
+INT VAR i;
+  n . number of entries := start of name table; 
+  FOR i FROM 1 UPTO hash table length REP 
+    n . hash table [i] := 0 
+  END REP 
+END PROC empty name table;
+ 
+PROC dump table (NAMETABLE CONST n): 
+  line ;
+  put ("Bitte Name der Datei, in die die Namenstabelle gehen soll:");
+  getline (f);
+  line ;
+  file assoziieren; 
+  dump namens ketten; 
+  zusammenfassung.
+ 
+file assoziieren: 
+  FILE VAR file :: sequential file (output, f). 
+ 
+dump namens ketten:
+  INT VAR i,
+          anz hash eintraege :: 0, 
+          kette 3 eintraege  :: 0;
+  FOR i FROM 1 UPTO hash table length REP 
+    IF n . hash table [i] <> 0 
+      THEN anz hash eintraege INCR 1;
+           INT VAR naechster eintrag :: n . hash table [i];
+           dump hash eintrag;
+           ketten eintraege
+    FI 
+  END REP. 
+ 
+dump hash eintrag: 
+  dummy := text (i); 
+  WHILE length (dummy) < 4 REP dummy CAT " " END REP;
+  dummy CAT ": ".
+ 
+ketten eintraege:
+  INT VAR anz eintraege pro kette :: 0;
+  WHILE naechster eintrag > 0 REP 
+    anz eintraege pro kette INCR 1;
+    dummy CAT " ";
+    dummy CAT text (naechster eintrag);
+    dummy CAT " -> ";
+    dummy CAT n . name table [naechster eintrag]; 
+    naechster eintrag := n . next [naechster eintrag];
+  END REP;
+  IF anz eintraege pro kette > 2 
+    THEN kette 3 eintraege INCR 1 
+  FI;
+  putline (file, dummy). 
+ 
+zusammenfassung: 
+  statistik ueberschrift;
+  anzahl hash eintraege; 
+  anzahl namens eintraege;
+  verkettungsfaktor; 
+  anzahl laengerer ketten.
+ 
+statistik ueberschrift: 
+  line (file, 2);
+  dummy := " ---------- "; 
+  dummy CAT "S T A T I S T I K:";
+  dummy CAT " ---------- ";
+  putline (file, dummy);
+  line (file, 2).
+ 
+anzahl hash eintraege:
+  dummy := "Anzahl Hash-Eintraege (max. "; 
+  dummy CAT text (hash table length); 
+  dummy CAT "): "; 
+  dummy CAT text (anz hash eintraege); 
+  putline (file, dummy).
+ 
+anzahl namens eintraege: 
+  dummy := "Anzahl Namen (max. "; 
+  dummy CAT text (name table length - start of name table + 1); 
+  dummy CAT "): "; 
+  dummy CAT text (n . number of entries - start of name table);
+  putline (file, dummy).
+ 
+verkettungsfaktor: 
+  dummy := "Verkettungsfaktor (Anzahl Namen / Anzahl Ketten): "; 
+  dummy CAT text (real (n . number of entries - start of name table) /
+         real (anz hash eintraege));
+  putline (file, dummy).
+ 
+anzahl laengerer ketten:
+  dummy := "Anzahl Ketten > 2 Eintraege: "; 
+  dummy CAT text (kette 3 eintraege); 
+  putline (file, dummy).
+END PROC dump table; 
+END PACKET name table handling; 
+(***************************************************************************)
+ 
+PACKET scanner DEFINES init scanning, 
+                       init name table with,
+                       dump name table,
+                       get name,
+                       end scanning,
+                       line number,
+                       symbol: 
+
+(* Programm zum scannen von ELAN-Programmen.
+   Autor: Rainer Hahn *)
+
+FILE VAR eingabe; 
+ 
+DATASPACE VAR ds alt := nilspace,
+              ds neu := nilspace;
+ 
+BOUND NAMETABLE VAR tabelle;
+ 
+TEXT VAR zeile, 
+         zeichen, 
+         dummy;
+ 
+LET end of program = ""30"",
+    eop            = 1, 
+    identifier     = 2, 
+    keyword        = 3, 
+    delimiter      = 4,
+    punkt          = 46,
+    doppelpunkt    = 58, 
+    init symbol    = 30, 
+    assign symbol  = 31;
+
+INT VAR zeilen nr,
+        zeichen pos;
+ 
+PROC init name table with (TEXT CONST worte):
+INT VAR index;
+  forget (ds alt);
+  ds alt := nilspace;
+  tabelle := dsalt;
+  empty name table (CONCR (tabelle));
+  INT VAR anf :: 1, 
+          ende :: pos (worte, ",", 1); 
+  WHILE ende > 0 REP 
+    dummy := subtext (worte, anf, ende - 1); 
+    put name (CONCR (tabelle), dummy, index); 
+    anf := ende + 1; 
+    ende := pos (worte, ",", ende + 1)
+  END REP; 
+  dummy := subtext (worte, anf); 
+  put name (CONCR (tabelle), dummy, index) 
+END PROC init name table with; 
+
+PROC init scanning (TEXT CONST f): 
+  IF exists (f) 
+    THEN namenstabelle holen;
+         erste zeile lesen 
+    ELSE errorstop ("Datei existiert nicht") 
+  FI. 
+ 
+namenstabelle holen: 
+  forget (ds neu);
+  ds neu := ds alt; 
+  tabelle := ds neu. 
+ 
+erste zeile lesen: 
+  eingabe := sequential file (input, f);
+  IF eof (eingabe) 
+    THEN errorstop ("Datei ist leer")
+    ELSE zeile := "";
+         zeilen nr := 0; 
+         zeile lesen; 
+         naechstes non blank zeichen
+  FI 
+END PROC init scanning; 
+
+PROC dump name table: 
+  dump table (CONCR (tabelle)) 
+END PROC dump name table; 
+ 
+PROC end scanning (TEXT CONST f): 
+  IF anything noted
+    THEN eingabe := sequential file (modify, f);
+         note edit (eingabe) 
+  FI
+END PROC end scanning; 
+ 
+PROC get name (INT CONST index, TEXT VAR t): 
+  get name (CONCR (tabelle), index, t) 
+END PROC get name; 
+ 
+PROC zeile lesen: 
+  getline (eingabe, zeile); 
+  zeilen nr INCR 1; 
+  cout (zeilen nr);
+  zeichen pos := 0
+END PROC zeile lesen; 
+ 
+PROC naechstes non blank zeichen: 
+  REP
+    zeichen pos := pos (zeile, ""33"", ""254"", zeichen pos + 1); 
+    IF zeichen pos <> 0 
+      THEN zeichen := (zeile SUB zeichen pos);
+           LEAVE naechstes non blank zeichen
+    ELIF eof (eingabe) 
+      THEN zeichen := end of program;
+           LEAVE naechstes non blank zeichen
+      ELSE zeile lesen
+    FI
+  END REP.
+END PROC naechstes non blank zeichen; 
+ 
+PROC naechstes zeichen: 
+  IF zeichen pos > length (zeile) 
+    THEN IF eof (eingabe) 
+           THEN zeichen := end of program;
+                LEAVE naechstes zeichen
+           ELSE zeile lesen 
+         FI 
+  FI; 
+  zeichenpos INCR 1; 
+  zeichen := zeile SUB zeichenpos
+END PROC naechstes zeichen; 
+ 
+INT PROC line number:
+  IF zeichenpos = pos (zeile, ""33"", ""254"", 1)
+    THEN zeilen nr - 1 
+    ELSE zeilen nr 
+  FI
+END PROC line number; 
+ 
+PROC symbol (INT VAR symb, type): 
+  REP 
+    suche naechstes checker symbol 
+  END REP. 
+ 
+suche naechstes checker symbol: 
+  SELECT code (zeichen) OF
+  CASE 30: (* end of programn *)
+    symb := eop; 
+    type := eop; 
+    LEAVE symbol
+  CASE 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+       111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122:
+    (* small letters *)
+    identifier aufsammeln; 
+    put name (CONCR (tabelle), dummy, symb); 
+    type := identifier;
+    LEAVE symbol
+  CASE 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+       82, 83, 84, 85, 86, 87, 88, 89, 90: (* large letters *)
+    schluesselwort aufsammeln; 
+    put name (CONCR (tabelle), dummy, symb); 
+    type := keyword; 
+    LEAVE symbol
+  CASE 34: (* " *)
+    skip text denoter 
+  CASE 40: (* ( *) 
+    IF (zeile SUB zeichen pos + 1) = "*" 
+      THEN skip comment 
+      ELSE symb := code (zeichen);
+           type := delimiter;
+           naechstes non blank zeichen;
+           LEAVE symbol;
+    FI 
+  CASE 58: (* : *) 
+    IF (zeile SUB zeichenpos + 1) = "=" 
+      THEN symb := assign symbol;
+           zeichenpos INCR 1
+    ELIF (zeile SUB zeichenpos + 1) = ":" 
+      THEN symb := init symbol; 
+           zeichenpos INCR 1 
+      ELSE symb := doppelpunkt 
+    FI; 
+    type := delimiter; 
+    naechstes non blank zeichen;
+    LEAVE symbol
+  CASE 48, 49, 50, 51, 52, 53, 54, 55, 56, 57: (* 0 - 9 *)
+    int denoter skippen;
+    IF zeichen = "."
+      THEN naechstes non blank zeichen;
+           IF digit
+             THEN real denoter skippen
+             ELSE symb := punkt; 
+                  type := delimiter;
+                  LEAVE symbol
+           FI
+    FI
+  CASE 41, 44, 46, 59, 61: (* ) , . ; =  *) 
+    symb := code (zeichen); 
+    type := delimiter; 
+    naechstes non blank zeichen; 
+    LEAVE symbol
+  OTHERWISE naechstes non blank zeichen
+  END SELECT.
+END PROC symbol; 
+ 
+PROC real denoter skippen:
+  int denoter skippen;
+  IF zeichen = "e" 
+    THEN naechstes non blank zeichen;
+         int denoter skippen
+  FI
+END PROC real denoter skippen;
+
+PROC int denoter skippen:
+  naechstes non blank zeichen;
+  WHILE zeichen >= "0" AND zeichen <= "9" REP
+    naechstes non blank zeichen
+  ENDREP;
+  zeichenpos DECR 1;
+  naechstes non blank zeichen
+END PROC int denoter skippen;
+
+PROC identifier aufsammeln:
+  dummy := zeichen; 
+  REP 
+    naechstes non blank zeichen; 
+    IF small letter or digit 
+      THEN dummy CAT zeichen 
+      ELSE LEAVE identifier aufsammeln 
+    FI 
+  END REP 
+END PROC identifier aufsammeln; 
+ 
+PROC schluesselwort aufsammeln:
+  dummy := "";
+  sammle schluesselwort; 
+  IF dummy = "END" 
+    THEN noch einmal 
+  FI.
+ 
+sammle schluesselwort: 
+  WHILE large letter REP 
+    dummy CAT zeichen;
+    naechstes zeichen
+  END REP; 
+  IF zeichen = " "
+    THEN naechstes non blank zeichen
+  FI.
+ 
+noch einmal: 
+  sammle schluesselwort
+END PROC schluesselwort aufsammeln; 
+ 
+PROC skip text denoter: 
+  INT VAR anz zeilen :: 0; 
+  zeichen pos := pos (zeile, """", zeichenpos + 1);
+  WHILE zeichen pos = 0 REP 
+    naechste zeile einlesen;
+    zeichen pos := pos (zeile, """");
+  END REP;
+  ende text denoter.
+ 
+ende text denoter: 
+  IF anz zeilen > 1 
+    THEN report referencer error (1, zeilen nr, text (anz zeilen))
+  FI; 
+  naechstes non blank zeichen. 
+ 
+naechste zeile einlesen: 
+  IF eof (eingabe) 
+    THEN report referencer error (2, zeilen nr, text (anz zeilen));
+         zeichen := end of program; 
+         LEAVE skip text denoter 
+    ELSE zeile lesen;
+         anz zeilen INCR 1 
+  FI.
+END PROC skip text denoter; 
+
+PROC skip comment:
+  INT VAR anz zeilen :: 0;
+  zeichen pos := pos (zeile, "*)", zeichenpos + 2);
+  WHILE zeichen pos = 0 REP 
+    naechste zeile einlesen; 
+    zeichen pos := pos (zeile, "*)"); 
+  END REP;
+  ende comment.
+ 
+ende comment:
+  IF anz zeilen > 1 
+    THEN report referencer error (3, zeilen nr, text (anz zeilen))
+  FI; 
+  zeichen pos INCR 2;
+  naechstes non blank zeichen. 
+ 
+naechste zeile einlesen: 
+  IF eof (eingabe) 
+    THEN report referencer error (4, zeilen nr, text (anz zeilen));
+         zeichen := end of program; 
+         LEAVE skip comment
+    ELSE zeile lesen;
+         anz zeilen INCR 1 
+  FI.
+END PROC skip comment;
+
+BOOL PROC small letter or digit: 
+  (zeichen >= "0" AND zeichen <= "9") OR (zeichen >= "a" AND zeichen <= "z") 
+END PROC small letter or digit; 
+ 
+BOOL PROC small letter: 
+  zeichen >= "a" AND zeichen <= "z"
+END PROC small letter;
+
+BOOL PROC large letter:
+  zeichen >= "A" AND zeichen <= "Z"
+END PROC large letter;
+
+BOOL PROC digit:
+  zeichen >= "0" AND zeichen <= "9"
+END PROC digit;
+END PACKET scanner;
+(*************************************************************************)
+PACKET referencer2 DEFINES referencer:
+
+(* Programm fuer den 'referencer'
+   Autor: Rainer Hahn *)
+
+INT VAR symb,
+        typ,
+        max index;
+
+TEXT VAR dummy,
+         dummy2,
+         name;
+
+DATASPACE VAR ds;
+
+BOUND ROW max TEXT VAR liste;
+
+FILE VAR f;
+
+BOOL VAR initialisiert :: FALSE,
+         symbol bereits geholt,
+         globale deklarationen;
+
+LET max             = 1751,
+    global text     = "<--G",
+    local text      = "<--L",
+    refinement text = "<--R",
+    procedure text  = "<--P",
+    eop           = 1, 
+    identifier    = 2, 
+    keyword       = 3, 
+    init symbol   = 30, 
+    assign symbol = 31,
+    klammer auf   = 40, 
+    klammer zu    = 41,
+    komma         = 44,
+    punkt         = 46,
+    doppelpunkt   = 58, 
+    semikolon     = 59, 
+    proc symbol       = 255, 
+    end proc symbol   = 256,
+    packet symbol     = 257, 
+    end packet symbol = 258,
+    type symbol       = 259, 
+    var symbol        = 260,
+    const symbol      = 261,
+    let symbol        = 262,
+    leave symbol      = 263,
+    op symbol         = 264,
+    endop symbol      = 265,
+    endif symbol      = 266,
+    fi symbol         = 266;
+ 
+PROC referencer: 
+  referencer (last param) 
+END PROC referencer; 
+ 
+PROC referencer (TEXT CONST check file): 
+  referencer (check file, check file + ".r") 
+END PROC referencer; 
+ 
+PROC referencer (TEXT CONST check file, dump file):
+  IF exists (check file)
+    THEN dump file ggf loeschen
+    ELSE errorstop ("Eingabe-Datei nicht vorhanden")
+  FI;
+  disable stop;
+    start referencing (check file, dump file);
+    forget (ds);
+  enable stop.
+ 
+dump file ggf loeschen:
+  IF exists (dump file)
+    THEN forget (dump file, quiet)
+  FI.
+END PROC referencer;
+ 
+PROC start referencing (TEXT CONST check file, dump file):
+  enable stop;
+  ueberschrift;
+  initialisierung;
+  verkuerzte syntax analyse;
+  line ;
+  in dump file kopieren (dump file);
+  line ;
+  end scanning (check file).
+ 
+ueberschrift:
+  page;
+  put ("REFERENCER:");
+  put (check file);
+  put ("->");
+  putline (dump file).
+ 
+initialisierung:
+  IF NOT initialisiert
+    THEN init name table with
+("PROC,ENDPROC,PACKET,ENDPACKET,TYPE,VAR,CONST,LET,LEAVE,OP,ENDOP,ENDIF,FI"); 
+         initialisiert := TRUE
+  FI; 
+  ds := nilspace;
+  liste := ds;
+  max index := end op symbol;
+  dummy := checkfile.
+ 
+verkuerzte syntax analyse: 
+  globale deklarationen := TRUE;
+  line ;
+  init scanning (dummy);
+  symbol bereits geholt := FALSE;
+  REP 
+    IF symbol bereits geholt 
+      THEN symbol bereits geholt := FALSE 
+      ELSE symbol (symb, typ)
+    FI;
+    IF typ = keyword 
+      THEN nach schluesselwort verarbeiten
+    ELIF symb = punkt
+      THEN ggf refinement aufnehmen
+    ELIF typ = identifier 
+      THEN identifier aufnehmen und ggf aktuelle parameter liste
+    FI
+  UNTIL typ = eop ENDREP. 
+ 
+identifier aufnehmen und ggf aktuelle parameter liste:
+  in die liste (symb, "");
+  symbol (symb, typ); 
+  IF symb = klammer auf 
+    THEN aktuelle parameter aufnehmen 
+    ELSE symbol bereits geholt := TRUE 
+  FI. 
+
+nach schluesselwort verarbeiten:
+  SELECT symb OF 
+  CASE let symbol:
+    let deklarationen aufsammeln
+  CASE packet symbol:
+    namen des interface aufsammeln
+  CASE end packet symbol:
+    skip naechstes symbol 
+  CASE var symbol, const symbol:
+    datenobjekt deklaration aufnehmen
+  CASE proc symbol:
+    globale deklarationen := FALSE; 
+    prozedur name und ggf parameter aufsammeln
+  CASE end proc symbol:
+    globale deklarationen := TRUE;
+    skip naechstes symbol
+  CASE op symbol: 
+    globale deklarationen := FALSE; 
+    operatornamen skippen und ggf parameter aufsammeln 
+  CASE end op symbol: 
+    globale deklarationen := TRUE; 
+    skip until (semikolon) 
+  CASE type symbol: 
+    namen der typ definition aufsammeln
+  CASE leave symbol: 
+    skip naechstes symbol
+  OTHERWISE: 
+  ENDSELECT. 
+ 
+skip naechstes symbol: 
+  symbol (symb, typ). 
+END PROC start referencing;
+
+PROC aktuelle parameter aufnehmen: 
+  REP 
+    symbol (symb, typ); 
+    IF typ = identifier 
+      THEN in die liste (symb, "") 
+    FI 
+  UNTIL symb = klammer zu END REP. 
+END PROC aktuelle parameter aufnehmen; 
+ 
+PROC ggf refinement aufnehmen:
+  symbol (symb, typ); 
+  symbol bereits geholt := TRUE;
+  WHILE typ = identifier REP 
+    doppelpunkt oder selektor
+  END REP.
+ 
+doppelpunkt oder selektor:
+  INT CONST letzter id :: symb; 
+  symbol (symb, typ);
+  IF symb = doppelpunkt
+    THEN in die liste (letzter id, refinement text);
+         LEAVE ggf refinement aufnehmen
+    ELSE in die liste (letzter id, "");
+         IF symb = punkt 
+           THEN symbol (symb, typ) 
+           ELSE LEAVE ggf refinement aufnehmen
+         FI
+  FI
+END PROC ggf refinement aufnehmen; 
+ 
+PROC namen des interface aufsammeln: 
+  packet name ueberspringen;
+  namen der schnittstelle aufsammeln. 
+ 
+packet name ueberspringen: 
+  symbol (symb, typ).
+ 
+namen der schnittstelle aufsammeln:
+  REP 
+    symbol (symb, typ);
+    IF typ = identifier 
+      THEN in die liste (symb, "")
+    FI
+  UNTIL symb = doppelpunkt END REP.
+END PROC namen des interface aufsammeln; 
+ 
+PROC let deklarationen aufsammeln:
+  REP
+    symbol (symb, typ);
+    IF typ = identifier 
+      THEN let name aufnehmen
+    ELIF typ = keyword 
+      THEN bis zum komma oder semikolon
+    FI;
+  UNTIL symb = semikolon END REP.
+
+let name aufnehmen: 
+  IF globale deklarationen
+    THEN in die liste (symb, global text)
+    ELSE in die liste (symb, "")
+  FI;
+  REP
+    symbol (symb, typ);
+    IF typ = identifier
+      THEN in die liste (symb, "")
+    FI
+  UNTIL symb = komma OR symb = semikolon END REP. 
+END PROC let deklarationen aufsammeln;
+
+PROC namen der typ definition aufsammeln: 
+  REP 
+    symbol (symb, typ); 
+    bis zum komma oder semikolon
+  UNTIL symb = semikolon END REP 
+END PROC namen der typ definition aufsammeln;
+
+PROC bis zum komma oder semikolon: 
+  INT VAR anz klammern :: 0; 
+  REP 
+    symbol (symb, typ); (* fields aufnehmen weggelassen *)
+    IF symb = klammer auf 
+      THEN anz klammern INCR 1 
+    ELIF symb = klammer zu
+      THEN anz klammern DECR 1
+    FI
+  UNTIL (symb = komma AND anz klammern = 0) OR symb = semikolon ENDREP.
+END PROC bis zum komma oder semikolon; 
+ 
+PROC datenobjekt deklaration aufnehmen:
+  symbol (symb, typ); 
+  REP 
+    IF globale deklarationen
+      THEN in die liste (symb, global text) 
+      ELSE in die liste (symb, local text) 
+    FI; 
+    skip ggf initialisierung;
+    IF symb = komma 
+      THEN symbol (symb, typ) 
+    FI
+  UNTIL symb = semikolon OR symb = punkt END REP.
+
+skip ggf initialisierung: 
+  symbol (symb, typ); 
+  IF symb = init symbol OR symb = assign symbol
+    THEN initialisierung skippen
+  FI.
+ 
+initialisierung skippen: 
+  INT VAR anz klammern :: 0;
+  REP 
+    INT CONST vorheriges symbol :: symb,
+              vorheriger typ    :: typ;
+    symbol (symb, typ); 
+    IF symb = klammer auf 
+      THEN anz klammern INCR 1;
+           IF vorheriger typ = identifier 
+             THEN in die liste (vorheriges symbol, "") 
+           FI
+    ELIF symb = klammer zu 
+      THEN anz klammern DECR 1; 
+           IF vorheriger typ = identifier 
+             THEN in die liste (vorheriges symbol, "") 
+           FI
+    ELIF vorheriger typ = identifier AND symb = doppelpunkt
+      THEN in die liste (vorheriges symbol, refinement text); 
+           LEAVE datenobjekt deklaration aufnehmen
+    ELIF vorheriger typ = identifier 
+      THEN in die liste (vorheriges symbol, "")
+    FI
+  UNTIL (symb = komma AND anz klammern = 0)
+         OR symb = semikolon OR symb = end proc symbol OR 
+         symb = end op symbol OR symb = endif symbol OR symb = fi symbol
+  END REP.
+END PROC datenobjekt deklaration aufnehmen; 
+ 
+PROC prozedur name und ggf parameter aufsammeln: 
+  prozedurname aufsammeln;
+  symbol (symb, typ); 
+  IF symb <> doppelpunkt
+    THEN formale parameter aufsammeln
+  FI. 
+ 
+prozedurname aufsammeln:
+  symbol (symb, typ); 
+  in die liste (symb, procedure text).
+END PROC prozedurname und ggf parameter aufsammeln; 
+ 
+PROC operatornamen skippen und ggf parameter aufsammeln: 
+  symbol (symb, typ);
+  IF symb <> doppelpunkt
+    THEN formale parameter aufsammeln 
+  FI 
+END PROC operatornamen skippen und ggf parameter aufsammeln;
+ 
+PROC formale parameter aufsammeln: 
+  REP 
+    symbol (symb, typ); 
+    IF typ = identifier 
+      THEN in die liste (symb, local text); 
+    FI 
+  UNTIL symb = doppelpunkt END REP 
+END PROC formale parameter aufsammeln; 
+ 
+PROC skip until (INT CONST zeichencode): 
+  skip until (zeichencode, 0) 
+END PROC skip until; 
+ 
+PROC skip until (INT CONST z1, z2):
+  REP 
+    symbol (symb, typ) 
+  UNTIL symb = z1 OR symb = z2 END REP
+END PROC skip until; 
+ 
+PROC in die liste (INT CONST index, TEXT CONST zusatz): 
+  IF index > max index 
+    THEN listenelemente initialisieren; 
+  FI;
+  IF aktueller eintrag = "" 
+    THEN namens eintrag 
+  FI;
+  aktueller eintrag CAT " ";
+  aktueller eintrag CAT text (line number);
+  aktueller eintrag CAT zusatz.
+ 
+aktueller eintrag: 
+  liste [index]. 
+ 
+listenelemente initialisieren: 
+  INT VAR i; 
+  FOR i FROM max index + 1 UPTO index REP 
+     liste [i] := ""
+  END REP; 
+  max index := index.
+ 
+namens eintrag:
+  get name (index, aktueller eintrag);
+  WHILE length (aktueller eintrag) < 15 REP 
+    aktueller eintrag CAT " "
+  END REP; 
+  aktueller eintrag CAT ":".
+END PROC in die liste; 
+ 
+TEXT VAR zeile;
+
+PROC in dump file kopieren (TEXT CONST dump file): 
+  putline ("Ausgabedatei erstellen"); 
+  f := sequential file (output, dump file); 
+  INT VAR i; 
+  kopieren und ggf fehlermeldung;
+  modify (f);
+  ggf sortieren;
+  zeile ggf aufspalten;
+  modify (f);
+  to line (f, 1).
+
+kopieren und ggf fehlermeldung:
+  FOR i FROM fi symbol UPTO max index REP 
+    cout (i);
+    zeile := liste [i];
+    IF zeile <> "" 
+      THEN ausgabe der referenz und ggf fehlermeldung
+    FI 
+  ENDREP.
+ 
+ausgabe der referenz und ggf fehlermeldung:
+  putline (f, zeile);
+  ggf referencer fehlermeldung.
+ 
+ggf sortieren:
+  IF yes (dump file + " sortieren")
+    THEN sort (dump file);
+  FI.
+
+zeile ggf aufspalten: 
+  i := 0;
+  to line (f, 1);
+  WHILE NOT eof (f) REP
+    i INCR 1;
+    cout (i);
+    read record (f, zeile);
+    ggf aufspalten
+  END REP.
+
+ggf aufspalten:
+INT VAR anf :: 1, ende :: pos (zeile, " ", 72); 
+  IF ende > 0
+    THEN dummy := subtext (zeile, 1, ende - 1);
+         write record (f, dummy);
+         spalte bis restzeile auf;
+         dummy CAT subtext (zeile, anf); 
+         write record (f, dummy);
+  FI;
+  down (f).
+
+spalte bis restzeile auf:
+   REP 
+     dummy :=  "                 ";
+     anf := ende + 1;
+     ende := pos (zeile, " ", ende + 55);
+     down (f);
+     insert record (f);
+     IF ende <= 0
+       THEN LEAVE spalte bis restzeile auf
+     FI;
+     dummy CAT subtext (zeile, anf, ende - 1); 
+     write record (f, dummy); 
+  END REP.
+END PROC in dump file kopieren; 
+ 
+PROC ggf referencer fehlermeldung:
+  name := subtext (zeile, 1, min( pos(zeile, " "), pos(zeile, ":")) - 1);
+  dummy := subtext (zeile, pos (zeile, ": ") + 2); 
+  ueberdeckungs ueberpruefung; 
+  not used ueberpruefung; 
+  IF pos (dummy, "R") > 0
+    THEN refinement mehr als zweimal verwendet
+  FI.
+ 
+ueberdeckungs ueberpruefung: 
+  IF pos (dummy, global text) > 0 AND pos (dummy, local text) > 0 
+    THEN dummy2 := "und Zeile "; 
+         dummy2 CAT text (nr (pos (dummy, local text))); 
+         dummy2 CAT ": "; 
+         dummy2 CAT name;
+         report referencer error
+            (5, nr (pos (dummy, global text)), dummy2) 
+  FI. 
+ 
+not used ueberpruefung: 
+  IF pos (dummy, " ") = 0 AND
+     (pos (dummy, global text) > 0 OR pos (dummy, local text) > 0 OR
+      pos (dummy, refinement text) > 0)
+    THEN not used fehlermeldung
+  FI. 
+ 
+not used fehlermeldung: 
+  report referencer error
+  (8, nr (length (dummy) - length (local text) + 1), name).
+ 
+refinement mehr als zweimal verwendet: 
+  INT VAR refinement deklarationen :: 0, 
+          refinement aufrufe       :: 0, 
+          anf                      :: 1;
+  WHILE pos (dummy,"R", anf) > 0 REP
+    refinement deklarationen INCR 1; 
+    anf := pos (dummy, "R", anf) + 1 
+  END REP; 
+  anf := 1; 
+  WHILE pos (dummy, " ", anf) > 0 REP
+    refinement aufrufe INCR 1; 
+    anf := pos (dummy, " ", anf) + 1 
+  END REP; 
+  IF refinement deklarationen = 1 
+    THEN IF refinement aufrufe > 1 
+           THEN report referencer error
+                     (6, nr (pos (dummy, refinement text)), name) 
+         ELIF refinement aufrufe = 0 
+           THEN report referencer error
+                     (7, nr (pos (dummy, refinement text)), name) 
+         FI
+  ELIF refinement deklarationen > 1 
+    THEN IF 2 * refinement deklarationen - 1 > refinement aufrufe
+           THEN report referencer error (9, 0, name)
+         ELIF 2 * refinement deklarationen - 1 < refinement aufrufe
+           THEN report referencer error (10, 0, name)
+         FI
+  FI.
+END PROC ggf referencer fehlermeldung;
+
+INT PROC nr (INT CONST ende):
+  INT VAR von :: ende - 1;
+  WHILE von > 0 AND ((dummy SUB von) >= "0" AND (dummy SUB von) <= "9") REP
+    von DECR 1
+  END REP;
+  int (subtext (dummy, von + 1, ende - 1))
+END PROC nr;
+END PACKET referencer2;
+
+(*
+REP
+  referencer ("ref fehler");
+  edit       ("ref fehler.r");
+UNTIL no ("nochmal") END REP*)
+
diff --git a/system/reporter b/system/reporter
new file mode 100644
index 0000000..4febc32
--- /dev/null
+++ b/system/reporter
@@ -0,0 +1,531 @@
+(* ------------------- VERSION 12 vom 06.08.86 -------------------- *)
+PACKET reporter routines DEFINES generate counts,
+                                 count on,
+                                 count off,
+                                 generate reports,
+                                 eliminate reports,
+                                 assert,
+                                 report on,
+                                 report off,
+                                 report:
+
+(* Programm zur Ablaufverfolgung von ELAN Programmen. Das Programm 
+   verfolgt Prozedur- und Refinementaufrufe ('trace') und erstellt
+   eine Haeufigkeitszaehlung ('count') und beachtet 'assertions'.
+   Autor: Rainer Hahn *)
+
+FILE VAR input file;
+
+INT VAR zeilen nr,
+        type;
+ 
+TEXT VAR zeile,
+         dummy,
+         dummy1,
+         symbol;
+ 
+LET quadro fis = "####",
+    triple fis = "###",
+    double fis = "##",
+    tag  = 1,
+    bold = 2;
+
+DATASPACE VAR ds := nilspace;
+BOUND ROW max STRUCT (INT anzahl, BOOL proc) VAR zaehlwerk;
+
+LET max = 3000;
+
+(******************* gen report-Routinen ******************************) 
+ 
+PROC generate reports:
+  generate reports (last param)
+END PROC generate reports;
+
+PROC generate reports (TEXT CONST name):
+  disable stop; 
+  gen trace statements (name); 
+  IF is error AND error message = "ende"
+    THEN clear error;
+         last param (name)
+  FI;
+  to line (input file, 1);
+  enable stop. 
+END PROC generate reports;
+
+PROC gen trace statements (TEXT CONST name):
+  enable stop;
+  IF exists (name) 
+    THEN input file := sequential file (modify, name)
+    ELSE errorstop ("input file does not exist") 
+  FI;
+  input file modifizieren
+END PROC gen trace statements; 
+ 
+(*************************** Test file modifizieren *****************) 
+ 
+PROC input file modifizieren:
+  zeilen nr := 1;
+  to line (input file, 1);
+  col (input file, 1);
+  REP 
+    lese zeile;
+    IF triple fis symbol
+      THEN wandele in quadro fis
+    FI;
+    IF proc oder op symbol
+      THEN verarbeite operator oder prozedurkopf
+    ELIF refinement symbol
+      THEN verarbeite ggf refinements
+    FI;
+    vorwaerts
+  END REP.
+ 
+triple fis symbol:
+  pos (zeile, triple fis) > 0 AND 
+       (pos (zeile, triple fis) <> pos (zeile, quadro fis)).
+
+wandele in quadro fis:
+  change all (zeile, triple fis, quadro fis);
+  write record (input file, zeile).
+
+proc oder op symbol:
+  pos (zeile, "PROC") > 0 OR pos (zeile, "OP") > 0.
+
+verarbeite operator oder prozedurkopf:
+  scan (zeile);
+  symbol lesen;
+  IF symbol = "PROC" OR symbol = "OP"
+    THEN 
+  ELIF symbol = "END"
+    THEN LEAVE verarbeite operator oder prozedurkopf
+  ELIF type = bold
+    THEN next symbol (symbol, type);
+         IF NOT (symbol = "PROC" OR symbol = "OP")
+           THEN LEAVE verarbeite operator oder prozedurkopf
+         FI
+    ELSE LEAVE verarbeite operator oder prozedurkopf
+  FI;
+  scanne kopf;
+  insertiere trace anweisung.
+
+scanne kopf:
+  dummy := double fis;
+  dummy CAT "report(""";
+  dummy CAT text (line no (input file) + 1);
+  dummy CAT ": ";
+  dummy CAT symbol; (* PROC oder OP *)
+  dummy CAT " ";
+  symbol lesen;
+  dummy CAT symbol;
+  fuege bis namens ende an;
+  dummy CAT " ";
+  ueberlese ggf parameterliste.
+
+fuege bis namens ende an:
+  REP
+    symbol lesen;
+    IF symbol = "(" OR symbol = ":"
+      THEN LEAVE fuege bis namensende an
+    FI;
+    dummy CAT symbol
+  END REP.
+
+ueberlese ggf parameterliste:
+  WHILE symbol <> ":" REP
+    symbol lesen
+  END REP.
+
+insertiere trace anweisung:
+  WHILE pos (zeile, ":") = 0 REP
+    vorwaerts;
+    lese zeile
+  END REP;
+  schreibe zeile mit report statement.
+
+refinement symbol:
+  INT CONST point pos :=  pos (zeile, ".") ;
+  point pos > 0 AND point pos >= length (zeile) - 1.
+
+verarbeite ggf refinements:
+  ueberlies leere zeilen ; 
+  IF ist wirklich refinement
+    THEN insertiere report fuer refinement
+  FI .
+
+ueberlies leere zeilen :
+  REP 
+    vorwaerts;
+    lese zeile
+  UNTIL pos (zeile, ""33"", ""254"", 1) > 0 PER .
+ 
+ist wirklich refinement :
+  scan (zeile) ;
+  next symbol (symbol, type) ;
+  next symbol (symbol) ;
+  symbol = ":" AND type = tag .
+
+insertiere report fuer refinement:
+  dummy := double fis;
+  dummy CAT "report(""     ";
+  dummy CAT text (line no (input file) + 1);
+  dummy CAT ": ";
+  dummy1 := subtext (zeile, 1, pos (zeile, ":") - 1);
+  dummy CAT dummy1;
+  schreibe zeile mit report statement
+END PROC input file modifizieren; 
+ 
+PROC schreibe zeile mit report statement:
+  dummy CAT """);";
+  dummy CAT double fis;
+  IF doppelpunkt steht am ende der zeile
+    THEN vorwaerts;
+         insert record (input file);
+         write record (input file, dummy)
+    ELSE insert char (dummy, ":", 1);
+         change (zeile, ":", dummy);
+         write record (input file, zeile)
+  FI.
+
+doppelpunkt steht am ende der zeile:
+  (zeile SUB length (zeile)) = ":" OR (zeile SUB length (zeile) - 1) = ":".
+END PROC schreibe zeile mit report statement;
+ 
+PROC symbol lesen:
+  next symbol (symbol, type);
+  IF ende der zeile gescannt
+    THEN vorwaerts;
+         lese zeile;
+         continue scan (zeile);
+         next symbol (symbol, type)
+  FI.
+
+ende der zeile gescannt:
+  type >= 7.
+END PROC symbol lesen;
+
+PROC vorwaerts:
+  IF eof (input file) 
+    THEN errorstop ("ende")
+  FI;
+  down (input file);
+  IF eof (input file) 
+    THEN errorstop ("ende")
+  FI
+END PROC vorwaerts;
+
+PROC lese zeile:
+  read record (input file, zeile); 
+  cout (zeilen nr); 
+  zeilen nr INCR 1
+END PROC lese zeile;
+
+(************************ eliminate reports-Routinen ******************)
+
+PROC eliminate reports:
+  eliminate reports (last param)
+END PROC eliminate reports;
+
+PROC eliminate reports (TEXT CONST name): 
+  disable stop; 
+  eliminate statements (name); 
+  IF is error AND error message = "ende"
+    THEN clear error;
+         last param (name)
+  FI;
+  to line (input file, 1);
+  enable stop. 
+END PROC eliminate reports;
+
+PROC eliminate statements (TEXT CONST name): 
+  enable stop;
+  IF exists (name) 
+    THEN input file := sequential file (modify, name)
+    ELSE errorstop ("input file does not exist") 
+  FI;
+  statements entfernen.
+
+statements entfernen:
+  to line (input file, 1);
+  col (input file, 1);
+  zeilen nr := 1;
+  WHILE NOT eof (input file) REP
+    lese zeile;
+    IF pos (zeile, double fis) > 0
+      THEN eliminiere zeichenketten in dieser zeile
+      ELSE vorwaerts
+    FI
+  END REP.
+
+eliminiere zeichenketten in dieser zeile:
+  INT VAR anfang := pos (zeile, double fis);
+  WHILE es ist noch etwas zu eliminieren REP
+    IF es ist ein quadro fis
+      THEN wandele es in ein triple fis
+    ELIF es ist ein triple fis
+      THEN lass diese sequenz stehen
+      ELSE entferne zeichenkette
+    FI
+  END REP;
+  IF zeile ist jetzt leer
+    THEN delete record (input file)
+    ELSE write record (input file, zeile);
+         vorwaerts
+  FI.
+
+es ist noch etwas zu eliminieren:
+  anfang > 0.
+ 
+es ist ein quadro fis:
+  pos (zeile, quadro fis, anfang) = anfang.
+
+wandele es in ein triple fis:
+  delete char (zeile, anfang);
+  anfang := pos (zeile, double fis, anfang + 3).
+
+es ist ein triple fis:
+  pos (zeile, triple fis, anfang) = anfang.
+
+lass diese sequenz stehen:
+  anfang := pos (zeile, triple fis, anfang + 1) + 3.
+
+entferne zeichenkette:
+  INT VAR end := pos (zeile, double fis, anfang+2) ;
+  IF end > 0
+    THEN change (zeile, anfang, end + 1, "");
+         anfang := pos (zeile, double fis, anfang)
+    ELSE anfang := pos (zeile, double fis, anfang+2) 
+  FI .
+
+zeile ist jetzt leer:
+  pos (zeile, ""33"", ""254"", 1) = 0.
+END PROC eliminate statements; 
+
+(********************** Trace-Routinen *******************************) 
+ 
+FILE VAR trace file;
+
+BOOL VAR zaehlwerk initialisiert :: FALSE,
+         trace on,
+         haeufigkeit on;
+
+PROC report (TEXT CONST message):
+  IF exists ("TRACE")
+    THEN 
+    ELSE trace on := TRUE;
+         haeufigkeit on := FALSE;
+  FI;
+  BOOL CONST ist prozedur ::
+     pos (message, "PROC") > 0 OR pos (message, "OP") > 0;
+  trace file := sequential file (modify, "TRACE");
+  IF lines (trace file) <= 0
+    THEN insert record (trace file);
+         write record (trace file, "")
+    ELSE to line (trace file, lines (trace file));
+         read record (trace file, dummy);
+         IF dummy <> ""
+           THEN down (trace file);
+                insert record (trace file);
+                write record (trace file, "")
+         FI
+  FI;
+  IF trace on
+    THEN write record (trace file, message);
+         down (trace file);
+         insert record (trace file);
+         write record (trace file, "")
+  FI;
+  IF haeufigkeit on
+    THEN haeufigkeits zaehlung
+  FI.
+
+haeufigkeits zaehlung:
+  hole zeilen nr;
+  zaehle mit.
+
+hole zeilen nr:
+  INT CONST von pos :: pos (message, ""33"", ""254"", 1);
+  zeilen nr :=
+     int (subtext (message, von pos, pos (message, ":", von pos + 1) - 1)).
+
+zaehle mit:
+  IF last conversion ok AND zeilen nr > 0 AND zeilen nr <= max
+    THEN zaehlwerk [zeilen nr] . anzahl INCR 1;
+         zaehlwerk [zeilen nr] . proc := ist prozedur
+  FI
+END PROC report;
+ 
+PROC report (TEXT CONST message, INT CONST value):
+  report (message, text (value))
+END PROC report;
+
+PROC report (TEXT CONST message, REAL CONST value):
+  report (message, text (value))
+END PROC report;
+ 
+PROC report (TEXT CONST message, TEXT CONST value):
+  dummy1 := message;
+  dummy1 CAT ": ";
+  dummy1 CAT value;
+  report (dummy1)
+END PROC report;
+
+PROC report (TEXT CONST message, BOOL CONST value):
+  dummy1 := message;
+  dummy1 CAT ": ";
+  IF value
+    THEN dummy1 CAT "TRUE"
+    ELSE dummy1 CAT "FALSE"
+  FI;
+  report (dummy1)
+END PROC report;
+
+PROC report on: 
+  trace on := TRUE;
+  dummy1 := "REPORT ---> ON";
+  report (dummy1)
+END PROC report on;
+ 
+PROC report off: 
+  dummy1 := "REPORT ---> OFF";
+  report (dummy1);
+  trace on := FALSE;
+END PROC report off;
+
+PROC assert (BOOL CONST value):
+  assert ("", value)
+END PROC assert;
+
+PROC assert (TEXT CONST message, BOOL CONST value):
+  dummy1 := "ASSERTION:";
+  dummy1 CAT message;
+  dummy1 CAT " ---> ";
+  IF value
+    THEN dummy1 CAT "TRUE"
+    ELSE line;
+         put ("ASSERTION:"); 
+         put (message);
+         put ("---> FALSE");
+         line;
+         IF yes ("weiter")
+           THEN dummy1 CAT "FALSE"
+           ELSE errorstop ("assertion failed")
+         FI
+  FI;
+  report (dummy1)
+END PROC assert;
+
+(************************** haeufigkeits-zaehlung ****************)
+
+PROC count on:
+  report ("COUNT ---> ON");
+  haeufigkeit on := TRUE;
+  initialisiere haeufigkeit.
+
+initialisiere haeufigkeit:
+  INT VAR i;
+  forget (ds);
+  ds := nilspace;
+  zaehlwerk initialisiert := TRUE;
+  zaehlwerk := ds;
+  FOR i FROM 1 UPTO max REP
+    zaehlwerk [i] . anzahl := 0
+  END REP
+END PROC count on;
+
+PROC count off:
+  report ("COUNT ---> OFF");
+  haeufigkeit on := FALSE
+END PROC count off;
+
+PROC generate counts:
+  generate counts (last param)
+END PROC generate counts;
+
+PROC generate counts (TEXT CONST name): 
+  disable stop; 
+  insert counts (name); 
+  last param (name);
+  to line (input file, 1);
+  enable stop. 
+END PROC generate counts;
+
+PROC insert counts (TEXT CONST name):
+  enable stop;
+  IF exists (name)
+    THEN input file := sequential file (modify, name);
+         col (input file, 1)
+    ELSE errorstop ("input file does not exist")
+  FI;
+  IF NOT zaehlwerk initialisiert
+    THEN errorstop ("count nicht eingeschaltet")
+  FI;
+  counts insertieren;
+  dataspace loeschen;
+  statistik ausgeben.
+ 
+counts insertieren:
+  REAL VAR gesamt aufrufe :: 0.0, 
+           proc   aufrufe :: 0.0, 
+           andere aufrufe :: 0.0; 
+  zeilen nr := 1;
+  WHILE zeilen nr <= lines (input file) REP
+    cout (zeilen nr);
+    IF zaehlwerk [zeilen nr] . anzahl > 0
+      THEN anzahl aufrufe in die eingabe zeile einfuegen;
+           aufrufe mitzaehlen
+    FI;
+    zeilen nr INCR 1
+  END REP.
+
+anzahl aufrufe in die eingabe zeile einfuegen: 
+  to line (input file, zeilen nr);
+  read record (input file, zeile);
+  dummy := double fis;
+  dummy CAT text (zaehlwerk [zeilen nr] . anzahl);
+  dummy CAT double fis;
+  change (zeile, 1, 0, dummy);
+  write record (input file, zeile).
+
+aufrufe mitzaehlen: 
+  gesamt aufrufe INCR real (zaehlwerk [zeilen nr] . anzahl); 
+  IF zaehlwerk [zeilen nr] . proc 
+    THEN proc aufrufe INCR real (zaehlwerk [zeilen nr] . anzahl) 
+    ELSE andere aufrufe INCR real (zaehlwerk [zeilen nr] . anzahl) 
+  FI. 
+ 
+dataspace loeschen:
+  zaehlwerk initialisiert := FALSE;
+  forget (ds).
+ 
+statistik ausgeben: 
+  line (2); 
+  put ("Anzahl der Gesamtaufrufe:"); 
+  ggf int put (gesamt aufrufe); 
+  line; 
+  put ("davon:"); 
+  line; 
+  ggf int put (proc aufrufe); put ("Prozeduren oder Operatoren"); 
+  line; 
+  ggf int put (andere aufrufe); put ("Refinements und andere"); 
+  line. 
+END PROC insert counts;
+
+PROC ggf int put (REAL CONST wert):
+  IF wert >= real (maxint)
+    THEN put (wert)
+    ELSE put (int (wert))
+  FI
+END PROC ggf int put;
+END PACKET reporter routines;
+(*
+REP
+  IF exists ("rep fehler")
+    THEN copy ("rep fehler", "zzz")
+    ELSE errorstop ("rep fehler exisitiert nicht")
+  FI;
+  generate reports ("zzz");
+  edit("zzz");
+  forget ("zzz")
+UNTIL no ("nochmal") END REP;
+edit("reporter")*)
+
diff --git a/system/scheduler b/system/scheduler
new file mode 100644
index 0000000..cba48e0
--- /dev/null
+++ b/system/scheduler
@@ -0,0 +1,420 @@
+ 
+PACKET std schedule strategy DEFINES                (* Autor: J.Liedtke *)
+                                                    (* Stand: 15.10.82  *)
+    strategic decision :
+
+
+PROC strategic decision 
+              (INT CONST foreground workers, background workers,
+               REAL CONST fore cpu load, back cpu load, paging load,
+               INT VAR lowest activation prio, max background tasks) :
+ 
+  IF no background permitted
+    THEN lowest activation prio := 0 ;
+         max background tasks := 0
+    ELSE lowest activation prio := 10 ;
+         select max background tasks
+  FI .
+ 
+no background permitted :
+      foreground workers > 0 AND fore cpu load > 0.03 .
+
+select max background tasks :
+  IF fore cpu load > 0.01
+    THEN max background tasks := 1
+  ELIF paging load < 0.07
+    THEN max background tasks := 3
+  ELIF paging load < 0.15
+    THEN max background tasks := 2
+    ELSE max background tasks := 1
+  FI .
+
+ENDPROC strategic decision ;
+
+ENDPACKET std schedule strategy ;
+
+
+                                              (* Autor: J.Liedtke*)
+PACKET eumelmeter DEFINES                     (* Stand: 11.10.83 *)
+ 
+     init log ,
+     log :
+ 
+ 
+LET snapshot interval = 590.0 ;
+
+REAL VAR next snapshot time ,
+         time        , timex ,
+         paging wait , paging wait x ,
+         paging busy , paging busy x ,
+         fore cpu    , fore cpu x ,
+         back cpu    , back cpu x ,
+         system cpu  , system cpu x ,
+         delta t ;
+INT VAR storage max, used ;
+TEXT VAR record ;
+
+PROC init log :
+
+  time        := clock (1) ;
+  paging wait := clock (2) ;
+  paging busy := clock (3) ;
+  fore cpu    := clock (4) ;
+  back cpu    := clock (5) ;
+  system cpu  := clock (6) ;
+  next snapshot time := time + snapshot interval
+
+ENDPROC init log ;
+
+PROC log (INT CONST active terminals, active background) :
+
+  new snapshot time if was clock reset ;
+  IF clock (1) >= next snapshot time
+    THEN save values ;
+         get new values ;
+         create stat record ;
+         put log (record) ;
+         define next snapshot time
+  FI .
+
+new snapshot time if was clock reset :
+  IF clock (1) < next snapshot time - snapshot interval 
+    THEN next snapshot time := clock (1)
+  FI .
+
+save values :
+  time x := time ;
+  paging wait x := paging wait ;
+  paging busy x := paging busy ;
+  fore cpu x    := fore cpu ;
+  back cpu x    := back cpu ;
+  system cpu x  := system cpu .
+
+get new values :
+  time := clock (1) ;
+  paging wait := clock (2) ;
+  paging busy := clock (3) ;
+  fore cpu    := clock (4) ;
+  back cpu    := clock (5) ;
+  system cpu  := clock (6) ;
+  storage (storage max, used) .
+
+create stat record :
+  record :=  text (used, 5) ;
+  record CAT text (active terminals,3) ;
+  record CAT text (active background,3) ;
+  delta t := (time - time x) ;
+  percent (paging wait, paging wait x) ;
+  percent (paging busy, paging busy x) ;
+  percent (fore cpu, fore cpu x) ;
+  percent (back cpu, back cpu x) ;
+  percent (system cpu, system cpu x) ;
+  percent (last, 0.0) ;
+  percent (nutz, 0.0) .
+
+last :   paging wait  + paging busy  + fore cpu  + back cpu  + system cpu
+       - paging waitx - paging busyx - fore cpux - back cpux - system cpux .
+
+nutz :   time  - paging wait  - system cpu
+       - timex + paging waitx + system cpux .
+
+define next snapshot time :
+  next snapshot time := time + snapshot interval .
+ 
+ENDPROC log ;
+
+PROC percent (REAL CONST neu, alt ) :
+
+  record CAT text ( (neu-alt) / delta t * 100.0, 6,1) + "%"
+
+ENDPROC percent ;
+
+ENDPACKET eumelmeter ;
+
+
+
+PACKET background que manager DEFINES                (* Autor: J.Liedtke *)
+                                                     (* Stand: 15.10.82  *)
+    into background que ,
+    delete from background que ,
+    get first from background que ,
+    get next from background que :
+
+LET que size = 100 ,
+    ENTRY    = STRUCT (TASK task, INT class) ;
+
+INT VAR end of que := 0 ,
+        actual entry pos ;
+
+ROW que size ENTRY VAR que ;
+
+
+PROC into background que (TASK CONST task) :
+
+  INT VAR class := prio (task) ;
+  IF end of que = que size
+    THEN delete all not existing tasks
+  FI ;
+  check whether already in que ;
+  IF already in que
+    THEN IF in same class
+           THEN LEAVE into background que
+           ELSE delete from background que (task) ;
+                into background que (task)
+         FI
+    ELSE insert new entry
+  FI .
+
+check whether already in que :
+  INT VAR entry pos := 1 ;
+  WHILE entry pos <= end of que  REP
+    IF que (entry pos).task = task
+      THEN LEAVE check whether already in que
+    FI ;
+    entry pos INCR 1
+  PER .
+
+already in que :  entry pos <= end of que .
+
+in same class :   que (entry pos).class = class .
+
+insert new entry :
+  end of que INCR 1 ;
+  que (end of que) := ENTRY:( task, class ) .
+
+delete all not existing tasks :
+  INT VAR j ;
+  FOR j FROM 1 UPTO end of que REP
+    TASK VAR examined := que (j).task ;
+    IF NOT exists (examined)
+      THEN delete from background que (examined)
+    FI
+  PER .
+
+ENDPROC into background que ;
+
+PROC delete from background que (TASK CONST task) :
+
+  search for entry ;
+  IF entry found
+    THEN delete entry ;
+         update actual entry pos 
+  FI .
+
+search for entry :
+  INT VAR entry pos := 1 ;
+  WHILE entry pos <= end of que REP
+    IF que (entry pos).task = task
+      THEN LEAVE search for entry
+    FI ;
+    entry pos INCR 1
+  PER .
+
+entry found : entry pos <= end of que .
+
+delete entry :
+  INT VAR i ;
+  FOR i FROM entry pos UPTO end of que - 1 REP
+    que (i) := que (i+1)
+  PER ;
+  end of que DECR 1 .
+
+update actual entry pos :
+  IF actual entry or following one deleted
+    THEN actual entry pos DECR 1
+  FI .
+
+actual entry or following one deleted :
+  entry pos >= actual entry pos .
+
+ENDPROC delete from background que ;
+
+PROC get first from background que (TASK VAR task, INT CONST lowest class) :
+
+  actual entry pos := 0 ;
+  get next from background que (task, lowest class)
+
+ENDPROC get first from background que ;
+
+PROC get next from background que (TASK VAR task, INT CONST lowest class) :
+ 
+  search next entry of permitted class ;
+  IF actual entry pos <= end of que
+    THEN task := que (actual entry pos).task
+    ELSE task := niltask
+  FI .
+
+search next entry of permitted class :
+  REP
+    actual entry pos INCR 1
+  UNTIL actual entry pos > end of que 
+        COR que (actual entry pos).class <= lowest class PER.
+
+ENDPROC get next from background que ;
+
+ENDPACKET background que manager ;
+
+ 
+
+PACKET scheduler DEFINES                         (* Autor: J.Liedtke *)
+                                                 (* Stand: 09.12.82  *)
+    scheduler :
+ 
+
+LET std background prio     = 7 ,
+    highest background prio = 5 ,
+    long slice              = 6000 ,
+    short slice             = 600 ,
+    blocked busy            = 4 ;
+
+INT VAR slice ,
+        foreground workers ,
+        background workers ;
+
+BOOL VAR is logging ;
+
+REAL VAR fore cpu load , back cpu load , paging load ;
+
+
+access catalogue ;
+TASK CONST ur task := brother (supervisor) ;
+
+TASK VAR actual task ;
+
+
+PROC scheduler :
+  IF yes ("mit eumelmeter")
+    THEN is logging := TRUE
+    ELSE is logging := FALSE
+  FI ;
+  task password ("-") ;
+  break ;
+  set autonom ;
+  command dialogue (FALSE) ;
+  forget ("scheduler", quiet) ;
+  disable stop; 
+  REP scheduler operation; 
+      clear error 
+  PER; 
+ 
+END PROC scheduler; 
+ 
+PROC scheduler operation:
+  enable stop;
+  IF is logging 
+    THEN init log 
+  FI;
+  slice := short slice ;
+  init system load moniting ;
+  REP
+    pause (slice) ;
+    monit system load ;
+    look at all active user tasks and block background workers ;
+    activate next background workers if possible ;
+    IF is logging
+      THEN log (foreground workers, background workers)
+    FI
+  PER .
+
+init system load moniting :
+  REAL VAR 
+  time     x := clock (1) ,
+  fore cpu x := clock (4) ,
+  back cpu x := clock (5) ,
+  paging   x := clock (2) + clock (3) .
+
+monit system load :
+  REAL VAR interval := clock (1) - time x ;
+  fore cpu load := (clock (4) - fore cpu x) / interval ;
+  back cpu load := (clock (5) - back cpu x) / interval ;
+  paging load   := (clock (2) + clock (3) - paging x) / interval ;
+  time     x := clock (1) ;
+  fore cpu x := clock (4) ;
+  back cpu x := clock (5) ;
+  paging   x := clock (2) + clock (3) .
+
+ENDPROC scheduler operation;
+
+PROC look at all active user tasks and block background workers :
+
+  foreground workers := 0 ;
+  background workers := 0 ;
+  actual task := myself ;
+  next active (actual task) ;
+  WHILE NOT (actual task = myself) REP
+    IF actual task < ur task
+      THEN look at this task
+    FI ;
+    next active (actual task)
+  END REP .
+
+look at this task :
+  IF channel (actual task) >= 0
+    THEN foreground workers INCR 1
+    ELSE background workers INCR 1 ;
+         block actual task if simple worker
+  FI .
+
+block actual task if simple worker :
+  IF son (actual task) = niltask
+    THEN pause (5) ;
+         block (actual task) ;
+         IF status (actual task) = blocked busy
+           THEN set background prio ;
+                into background que (actual task)
+         ELIF prio (actual task) < highest background prio
+           THEN unblock (actual task)
+         FI
+  FI .
+
+set background prio :
+  IF prio (actual task) < highest background prio
+    THEN prio (actual task, std background prio)
+  FI .
+ 
+ENDPROC look at all active user tasks and block background workers ;
+
+PROC activate next background workers if possible :
+
+  INT VAR lowest activation prio ,
+          max background workers ,
+          active background workers := 0 ;
+
+  strategic decision (foreground workers, background workers,
+                      fore cpu load, back cpu load, paging load,
+                      lowest activation prio, max background workers) ;
+
+  IF background permitted
+    THEN try to activate background workers
+  FI ;
+  IF active background workers > 0
+    THEN slice := short slice
+    ELSE slice := long slice
+  FI .
+
+background permitted : max background workers > 0 .
+
+try to activate background workers :
+  get first from background que (actual task, lowest activation prio) ;
+  IF NOT is niltask (actual task)
+    THEN delete from background que (actual task)
+  FI ;
+
+  WHILE active background workers < max background workers REP
+    IF is niltask (actual task)
+      THEN LEAVE try to activate background workers
+    ELIF status (actual task) <> blocked busy
+      THEN delete from background que (actual task)
+    ELSE
+           unblock (actual task) ;
+           active background workers INCR 1
+    FI ;
+    get next from background que (actual task, lowest activation prio)
+  PER .
+
+ENDPROC activate next background workers if possible ;
+ 
+ENDPACKET scheduler ;
+ 
+scheduler;
+
diff --git a/system/spool cmd b/system/spool cmd
new file mode 100644
index 0000000..9b43d36
--- /dev/null
+++ b/system/spool cmd	
@@ -0,0 +1,178 @@
+PACKET spool cmd                                    (* Autor : R. Ruland  *)
+                                                    (* Stand : 13.08.87   *)
+       DEFINES
+               spool control password,
+ 
+               kill  spool,
+               first spool,
+               start spool,
+               stop  spool,
+               halt  spool,
+               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, TEXT actual entries, password) VAR control msg;
+BOUND TEXT VAR error msg;
+INT VAR reply;
+ 
+INITFLAG VAR in this task := FALSE;
+BOOL VAR dialogue;
+TEXT VAR control password, password;
+ 
+control password := "";
+ 
+PROC spool control password (TEXT CONST new password):
+ 
+  IF on line THEN say (""3""13""5"") FI;
+  disable stop;
+  do ("enter spool control password (""" + new password + """)");
+  clear error;
+  no do again;
+  cover tracks;
+  cover tracks (control password);
+  control password := new password;
+ 
+END PROC spool control password;
+ 
+ 
+PROC call spool (INT CONST op code, TEXT CONST name, TASK CONST spool) :
+ 
+  dialogue :=  command dialogue;
+  password :=  write password;
+  password CAT "/";
+  password CAT read password;
+  disable stop;
+  command dialogue (FALSE);
+  enter password (control password);
+  command dialogue (dialogue);
+  call (op code, name, spool);
+  command dialogue (FALSE);
+  enter password (password);
+  command dialogue (dialogue);
+ 
+END PROC call spool;
+ 
+ 
+PROC start spool (TASK CONST spool) :
+ 
+  enable stop;
+  call spool (halt  code, "", spool);
+  call spool (start code, "", spool);
+ 
+END PROC start spool;
+ 
+ 
+PROC start spool (TASK CONST spool, INT CONST new channel) :
+ 
+  enable stop;
+  call spool (halt  code, "", spool);
+  call spool (start code, text (new channel), spool);
+ 
+END PROC start spool;
+ 
+ 
+PROC stop spool (TASK CONST spool) :
+ 
+  call spool (stop code, "", spool);
+ 
+END PROC stop spool;
+ 
+PROC stop spool (TASK CONST spool, TEXT CONST deactive msg) :
+ 
+  call spool (stop code, deactive msg, spool);
+ 
+END PROC stop spool;
+ 
+ 
+PROC halt spool (TASK CONST spool) :
+ 
+  call spool (halt code, "", spool);
+ 
+END PROC halt spool;
+ 
+PROC halt spool (TASK CONST spool, TEXT CONST deactive msg) :
+ 
+  call spool (halt code, deactive msg, spool);
+ 
+END PROC halt spool;
+ 
+ 
+PROC wait for halt (TASK CONST spool) :
+ 
+  call spool (wait for halt code, "", spool);
+ 
+END PROC wait for halt;
+ 
+PROC wait for halt (TASK CONST spool, TEXT CONST deactive msg) :
+ 
+  call spool (wait for halt code, deactive msg, spool);
+ 
+END PROC wait for halt;
+ 
+ 
+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. password   := control password;
+      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 kill spool (TASK CONST spool) :
+ 
+  control spool (spool, killer code, "   loeschen", FALSE)
+ 
+END PROC kill spool;
+ 
+ 
+PROC first spool (TASK CONST spool) :
+ 
+  control spool (spool, first code, "   als erstes", TRUE)
+ 
+END PROC first spool;
+ 
+ 
+END PACKET spool cmd;             
+
diff --git a/system/spool manager b/system/spool manager
new file mode 100644
index 0000000..6b4fe55
--- /dev/null
+++ b/system/spool manager	
@@ -0,0 +1,1058 @@
+PACKET spool manager DEFINES                        (* Autor : R. Ruland  *)
+                                                    (* Stand : 23.02.88   *)
+ 
+    spool manager ,
+ 
+    server channel ,
+    spool duty,
+    station only, 
+    auto stop,
+    enter spool control password,
+    spool control password,
+ 
+    start spool,
+    stop  spool,
+    halt  spool,
+    kill  spool,
+    first spool,
+    spool entry line,
+    number spool entries,
+    spool status,
+    server task,
+    clear spool,
+    list  spool,
+    :
+ 
+LET que size           = 200 ,
+ 
+    ack                = 0 ,
+    nak                = 1 ,
+    error nak          = 2 ,
+    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 ,
+    help code          = 49 ,
+    continue code      = 100 ,
+ 
+    control codes      = ""23""24""25""26""27""28""29"" ,
+ 
+    file type          = 1003 ,
+    help file name     = "help";
+ 
+LET begin char  =  ""0"",
+    end char    =  ""1"";
+ 
+LET PARAMS  =  STRUCT (TEXT name, userid, password, sendername, INT station);
+ 
+BOUND ROW que size STRUCT (PARAMS ds params, TEXT entry line) VAR que;
+ 
+      ROW que size DATASPACE VAR que space;
+ 
+PARAMS VAR save params;
+ 
+DATASPACE VAR que ds, global ds;
+ 
+FILE VAR file;
+ 
+INT VAR last order, reply, old heap size, que index, fetch index, 
+        station by start, begin pos, end pos, order task station, sp channel;
+ 
+TEXT VAR que entries, free entries, order task name, buffer, deactive message,
+         error message buffer, sp duty, start time, control password;
+ 
+BOOL VAR server is waiting, stop cmd pending, start cmd pending,
+         auto stop pending, stat only;
+ 
+TASK VAR last order task, server, calling parent, task in control; 
+ 
+INITFLAG VAR in this task := FALSE, init que space := FALSE;
+ 
+BOUND STRUCT (TEXT name, userid, password) VAR msg;
+BOUND STRUCT (TEXT entry line, INT index, TEXT actual entries, password) VAR control msg;
+BOUND PARAMS VAR fetch msg;
+BOUND THESAURUS VAR all msg;
+BOUND TEXT VAR error msg;
+ 
+ 
+. que is empty    :  que  entries = ""
+. que is full     :  free entries = ""
+. number entries  :  LENGTH que entries
+ 
+. first index     :  code (que entries SUB 1)
+. list index      :  code (que entries SUB que index)
+. last index      :  code (que entries SUB number entries)
+ 
+. fetch entry     :  que (fetch index)
+. list  entry     :  que (list  index)
+. last  entry     :  que (last  index)
+ 
+. was define station   : station by start <> station (myself)
+. is valid fetch entry : fetch index > 0
+.; 
+ 
+INT VAR command index , params ;
+TEXT VAR param 1, param 2 ;
+LET spool command list = "start:1.01stop:3.0halt:4.0first:5.0killer:6.0";
+ 
+sp channel        := 0;
+sp duty           := ""; 
+deactive message  := "";
+stat only         := FALSE;
+auto stop pending := FALSE;
+task in control   := supervisor;
+control password  := "-";
+ 
+ 
+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 auto stop (BOOL CONST flag) :
+     auto stop pending := flag
+END PROC auto stop;
+ 
+BOOL PROC auto stop :  auto stop pending  END PROC auto stop;
+ 
+ 
+PROC spool duty (TEXT CONST duty) :
+     sp duty := duty;
+END PROC spool duty;
+ 
+TEXT PROC spool duty :  sp duty  END PROC spool duty;
+ 
+ 
+PROC enter spool control password (TEXT CONST new password):
+  disable stop;
+  cover tracks;
+  cover tracks (control password);
+  control password := new password;
+END PROC enter spool control password;
+ 
+PROC spool control password (TEXT CONST new password):
+  IF on line THEN say (""3""13""5"") FI;
+  enter spool control password (new password);
+END PROC spool control password;
+ 
+ 
+PROC spool manager (PROC server start) :
+  spool manager (PROC (DATASPACE VAR, INT CONST,
+                                INT CONST, TASK CONST) spool manager,
+                 PROC server start, TRUE)
+END PROC spool manager;
+ 
+ 
+PROC spool manager (PROC server start, BOOL CONST initial start) :
+  spool manager (PROC (DATASPACE VAR, INT CONST,
+                                INT CONST, TASK CONST) spool manager,
+                 PROC server start, initial start) 
+END PROC spool manager;
+ 
+ 
+PROC spool manager (PROC (DATASPACE VAR, INT CONST,
+                                         INT CONST, TASK CONST) spool,
+                    PROC server start,
+                    BOOL CONST initial start) :
+ 
+  set autonom;
+  break;
+  disable stop;
+  command dialogue (FALSE);
+  initialize spool manager;
+  REP start spool if necessary;
+      wait for next order;
+      IF   order not allowed THEN reject order
+      ELIF is first  phase   THEN first phase
+      ELIF is second phase   THEN second phase
+                             ELSE send nak
+      FI;
+      send error if necessary;
+      collect heap garbage if necessary;
+  PER 
+ 
+  . initialize spool manager :
+      initialize if necessary;
+      stop server;
+      erase fetch entry;
+      start cmd pending := initial start;
+      stop cmd pending  := FALSE;
+      last order task   := niltask;
+ 
+      . initialize if necessary :
+          IF NOT initialized (in this task)
+             THEN clear spool;
+                  global ds            := nilspace;
+                  que ds               := nilspace;
+                  que                  := que ds;
+                  server               := niltask; 
+                  calling parent       := niltask;
+                  server is waiting    := FALSE;
+                  station by start     := station (myself);
+                  old heap size        := 0;
+                  error message buffer := "";
+          FI;
+ 
+  . start spool if necessary :
+      IF start cmd pending AND NOT stop cmd pending
+         THEN start server (PROC server start) FI;
+ 
+  . wait for next order :
+      INT VAR order, phase;
+      TASK VAR order task;
+      forget (global ds);
+      wait (global ds, order, order task);
+ 
+  . order not allowed :
+      station only CAND station (ordertask) <> station (myself) CAND
+                ( order > 255 COR pos (control codes, code (order)) = 0 )
+ 
+  . reject order :
+      errorstop ("kein Zugriffsrecht auf Task " + text (station(myself))
+                  + "/""" + name(myself) + """") 
+ 
+  . is first phase :
+      order <> second phase ack    
+ 
+  . first phase :
+      phase := 1;
+      last order      := order;
+      last order task := order task;
+      spool (global ds, order, phase, order task);
+ 
+  . is second phase :
+      order task = last order task 
+ 
+  . second phase :
+      phase INCR 1 ;
+      order := last order;
+      spool (global ds, order, phase, order task);
+ 
+  . send nak :
+      forget (global ds);
+      global ds := nilspace;
+      send (order task, nak, global ds);
+ 
+  . send error if necessary :
+      IF is error
+         THEN forget (global ds);
+              global ds := nilspace;
+              error msg := global ds;
+              CONCR (error msg) := error message;
+              clear error;
+              send (order task, error nak, global 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 manager (DATASPACE VAR order ds,
+                    INT CONST order, phase,
+                    TASK CONST order task   ):
+ 
+  enable stop;
+  SELECT order OF
+    CASE fetch code, help code  :  out of que or help
+    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
+ 
+    CASE entry line code        :  send next entry line 
+    CASE killer code            :  kill entry 
+    CASE first code             :  make to first
+    CASE start code             :  start server task
+    CASE stop code              :  stop server task
+    CASE halt code, wait for halt code
+                                :  halt server task
+ 
+    OTHERWISE :
+ 
+       IF order >= continue code AND order task = supervisor
+          THEN spool monitor
+          ELSE wrong operation
+       FI;
+ 
+  END SELECT;
+ 
+. wrong operation :
+    IF order > error nak
+       THEN errorstop ("falscher Auftrag fuer Task " + text (station(myself))
+                        + "/""" + name(myself) + """") 
+    FI;
+ 
+. 
+  out of que or help :
+    IF order task = server
+       THEN out of que
+       ELSE send help file
+    FI;
+ 
+    . out of que :
+        erase fetch entry;
+        IF   stop cmd pending 
+             THEN stop server
+        ELIF que is empty
+             THEN IF auto stop pending
+                     THEN stop server
+                     ELSE server is waiting := TRUE
+                  FI;
+             ELSE send first entry;
+        FI;
+ 
+    . send help file :
+        check server (TRUE);
+        IF order = fetch code
+           THEN msg := order ds;
+                IF msg. name <> help file name
+                   THEN errorstop ("keine Servertask") FI;
+        FI;
+        forget (order ds);
+        order ds := old (help file name);
+        send (order task, ack, order ds);
+ 
+. 
+  send fetch params :
+    IF order task = server
+       THEN send params
+       ELSE errorstop ("keine Servertask")
+    FI;
+ 
+    . send params :
+        forget(order ds); order ds := nilspace;
+        fetch msg := order ds;
+        fetch msg := fetch entry. ds params;
+        send (order task, ack, order ds);
+ 
+. 
+  new que entry :
+    IF phase = 1
+       THEN prepare into que
+       ELSE into que (order ds, order task)
+    FI;
+ 
+.
+  prepare into que :
+    msg := order 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 (order ds); order ds := nilspace;
+    send (order task, second phase ack, order ds);
+ 
+. 
+  new file que entry :
+    IF type (order ds) <> file type
+       THEN errorstop ("Datenraum hat falschen Typ");
+       ELSE get file params;
+            into que (order ds, order task);
+    FI;
+ 
+    . get file params :
+        file := sequential file (input, order ds);
+        end pos := 0;
+        next headline information (save params. name); 
+        next headline information (save params. userid); 
+        next headline information (save params. password); 
+        next headline information (save params. sendername); 
+        next headline information (buffer);
+        save params. station := int (buffer);
+        IF NOT last conversion ok
+           THEN save params. station    := station (order task) FI;
+        IF save params. sendername = ""
+           THEN save params. sendername := name    (order task) FI;
+        IF save params. name = ""
+           THEN IF headline (file) <> ""
+                   THEN save params. name := headline (file);
+                   ELSE errorstop ("Name unzulaessig")
+                FI;
+           ELSE headline (file, save params. name);
+        FI;
+ 
+. 
+  exists que entry :
+    msg                := order ds ;
+    order task name    := name (order task);
+    order task station := station (order task);
+    FOR que index FROM 1 UPTO number entries
+    REP IF is entry from order task (msg. name) 
+           THEN send ack;
+                LEAVE exists que entry
+        FI;
+    PER ;
+    forget (order ds); order ds := nilspace;
+    send (order task, false code, order ds)
+ 
+. 
+  erase que entry :
+    msg                := order 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 :
+        FOR que index FROM 1 UPTO number entries
+        REP IF is entry from order task (msg. name) 
+               THEN manager question ("""" + msg.name + """ loeschen", order task); 
+                    LEAVE erase que entry
+            FI;
+        PER ;
+        manager message ("""" + msg.name + """ existiert nicht", order task);
+ 
+    . erase entry from order task :
+        IF is valid que index (que index) CAND is entry from order task (msg. name) 
+           THEN delete que entry; 
+                LEAVE erase que entry 
+           ELSE FOR que index FROM 1 UPTO number entries
+                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", order task);
+        FI;
+ 
+        . delete que entry :
+            kill spool (que index);
+            send ack;
+ 
+.
+  send owners ds names:
+    order task name    := name (order task);
+    order task station := station (order task);
+    forget (order ds); order ds := nilspace; all msg := order ds; 
+    all msg := empty thesaurus; 
+    FOR que index FROM 1 UPTO number entries
+    REP IF is entry from order task ("")
+           THEN insert (all msg, list entry. ds params. name) 
+        FI; 
+    PER;
+    send (order task, ack, order ds) 
+ 
+. 
+  send spool list :
+    forget (global ds); global ds := nilspace;
+    file := sequential file (output, global ds);
+    list spool (file);
+    send (order task, ack, global ds);
+ 
+.
+  send next entry line :
+    control msg := order ds; check control password (control msg. password);
+    IF control msg. index = 0 THEN control msg. actual entries := que entries FI;
+    get next entry line;
+    send (order task, ack, order ds);
+ 
+    . get next entry line :
+        REP control msg. index INCR 1;
+            IF control msg. index > LENGTH control msg. actual entries
+               THEN control msg. index      := 0;
+                    control msg. entry line := "";
+                    LEAVE get next entry line;
+            FI;
+            que index := control que index;
+        UNTIL is valid que index (que index) PER;
+        control msg. entry line := list entry. entry line;
+ 
+    . control que index :
+        pos (que entries, control msg. actual entries SUB control msg. index)
+ 
+. 
+  kill entry :
+    control msg := order ds; check control password (control msg. password);
+    kill spool (control que index);
+    send (order task, ack, order ds);
+ 
+.
+  make to first :
+    control msg := order ds; check control password (control msg. password);
+    first spool (control que index);
+    send (order task, ack, order ds);
+ 
+.
+  start server task :
+    msg := order ds; check control password (msg. password);
+    IF exists (server) AND NOT stop cmd pending
+       THEN errorstop ("Spool muß zuerst gestoppt werden") FI;
+    new server channel is necessary;
+    start cmd pending := TRUE;
+    IF server channel <= 0 OR server channel >= 33
+       THEN manager message ("WARNUNG : Serverkanal nicht eingestellt", order task);
+       ELSE send ack
+    FI;
+ 
+    . new server channel is necessary :
+        INT CONST new channel := int (msg. name);
+        IF last conversion ok THEN server channel (new channel) FI;
+ 
+. 
+  stop server task :
+    msg := order ds; check control password (msg. password);
+    IF phase = 1
+       THEN start cmd pending := FALSE;
+            deactive message  := msg. name;
+            stop server;
+            check fetch entry;
+       ELSE reinsert fetch entry;
+            send ack;
+    FI;
+ 
+. 
+  halt server task :
+    msg := order ds; check control password (msg. password);
+    IF phase = 1
+       THEN stop  cmd pending := TRUE; 
+            start cmd pending := FALSE;
+            deactive message  := msg. name;
+            IF   NOT exists (server) OR server is waiting
+                 THEN stop server;
+                      check fetch entry;
+            ELIF order = wait for halt code
+                 THEN calling parent := order task;
+                 ELSE send ack;
+            FI;
+       ELSE reinsert fetch entry;
+            send ack;
+    FI;
+ 
+    . check fetch entry :
+        IF is valid fetch entry
+           THEN manager question (""13""10"" +
+                   fetch entry. entry line + "   neu eintragen", order task);
+                fetch index := -fetch index;
+           ELSE send ack;
+        FI;
+ 
+.
+  send ack :
+    forget (order ds); order ds := nilspace;
+    send (order task, ack, order ds)
+ 
+.
+  spool monitor :
+    continue (order - continue code);
+    disable stop;
+    put error message if there is one;
+    WHILE online
+    REP command dialogue (TRUE);
+        sysout ("");
+        sysin ("");
+        get command ("gib Spool-Kommando:");
+        analyze command (spool command list, 3, command index, params, param1, param2);
+        reset editor;
+        SELECT command index OF 
+          CASE 1    :  start spool
+          CASE 2    :  start spool (int (param1))
+          CASE 3    :  stop  spool
+          CASE 4    :  halt  spool
+          CASE 5    :  first spool
+          CASE 6    :  kill  spool
+          OTHERWISE :  do command
+        END SELECT;
+    PER;
+    save error message if there is one;
+    command dialogue (FALSE);
+    break (quiet);
+    set autonom;
+ 
+    . put error message if there is one :
+        IF error message buffer <> ""
+           THEN errorstop (error message buffer); FI;
+ 
+    . save error message if there is one :
+        IF is error
+           THEN error message buffer := error message;
+                clear error;
+           ELSE error message buffer := "";
+        FI;
+ 
+    . reset editor :
+        WHILE aktueller editor > 0 REP quit PER;
+        clear error;
+ 
+END PROC spool manager;
+ 
+ 
+PROC  send first entry :
+ 
+  forget (global ds);
+  global ds := que space (first index);
+  send (server, ack, global ds, reply) ;
+  IF reply = ack
+     THEN fetch index       := first index;
+          que entries       := subtext (que entries, 2);
+          server is waiting := FALSE;
+          start time        := time of day;
+          start time        CAT " am ";
+          start time        CAT date;
+  FI;
+ 
+END PROC send first entry;
+ 
+ 
+PROC into que (DATASPACE VAR order ds, TASK CONST order task) :
+ 
+  IF que is full
+     THEN errorstop ("Spool ist voll")
+     ELSE make new entry;
+          send ack;
+          awake server if necessary
+  FI;
+ 
+  . make new entry :
+      que  entries CAT (free entries SUB 1);
+      free entries           := subtext (free entries, 2);
+      que space (last index) := order ds;
+      last entry. ds params  := save params;
+      build entry line;
+ 
+      . 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 (order ds));
+          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
+ 
+  . send ack :
+      forget (order ds); order ds := nilspace;
+      send (order task, ack, order ds)
+ 
+  . awake server if necessary :
+      IF server is waiting THEN send first entry FI;
+ 
+END PROC into que;
+ 
+ 
+(*********************************************************************) 
+(*  Hilfsprozeduren zum Spoolmanager                                 *)
+(*********************************************************************) 
+ 
+ 
+PROC reinsert fetch entry :
+ 
+  IF fetch index <> 0
+     THEN insert char (que entries, code (abs (fetch index)), 1);
+          fetch index := 0;
+  FI;
+ 
+END PROC reinsert fetch entry;
+ 
+ 
+PROC erase fetch entry :
+ 
+  IF fetch index <> 0
+     THEN free entries CAT code (abs (fetch index));
+          forget (que space (abs (fetch index)));
+          fetch index := 0;
+  FI;
+ 
+END PROC erase fetch entry;
+ 
+ 
+PROC start server (PROC server start):
+ 
+  stop server;
+  begin (PROC server start, server);
+  station by start  := station (myself);
+  start cmd pending := FALSE;
+  deactive message  := "";
+ 
+END PROC start server;
+ 
+ 
+PROC stop server :
+ 
+  IF exists (server) THEN end (server) ELSE check server (FALSE) FI;
+  server            := niltask;
+  server is waiting := FALSE;
+  stop cmd pending  := FALSE; 
+  send calling parent reply if necessary;
+ 
+  . send calling parent reply if necessary :
+      IF exists (calling parent)
+         THEN forget (global ds); global ds := nilspace;
+              send (calling parent, ack, global ds);
+              calling parent  := niltask;
+      FI;
+ 
+END PROC stop server;
+ 
+ 
+PROC check server (BOOL CONST with stop) :
+ 
+  IF was define station CAND NOT is niltask (server) 
+     THEN stop old server if necessary FI;
+ 
+  . stop old server if necessary :
+      access catalogue;
+      TASK VAR old server := son (myself);
+      WHILE NOT is niltask (old server)
+      REP IF index (old server) = index (server) THEN old server found FI;
+          old server := brother (old server);
+      PER;
+ 
+      . old server found :
+          IF name (old server) = "-" THEN end (old server) FI;
+          IF with stop THEN stop server FI;
+          LEAVE stop old server if necessary;
+ 
+END PROC check server;
+ 
+ 
+BOOL PROC is valid que index (INT CONST index) :
+ 
+  1 <= index AND index <= number entries
+ 
+END PROC is valid que index;
+ 
+ 
+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 check control password (TEXT CONST password) :
+ 
+ IF   control password = "-"
+      THEN errorstop ("Kontrolle des Spools nicht erlaubt")
+ ELIF control password <> "" CAND control password <> password
+      THEN errorstop ("Passwort falsch")
+ FI;
+ 
+END PROC check control password;
+ 
+ 
+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;
+ 
+(*********************************************************************) 
+(*   Prozeduren zur Verwaltung der Warteschlange                     *) 
+(*********************************************************************) 
+ 
+PROC start spool :
+ 
+  enable stop;
+  IF server channel <= 0 OR server channel >= 33
+     THEN display (""13""10"WARNUNG : Serverkanal nicht eingestellt"13""10"")
+  FI;
+  halt spool;
+  start cmd pending := TRUE;
+ 
+END PROC start spool;
+ 
+PROC start spool (INT CONST new channel) :
+ 
+  enable stop;
+  server channel (new channel);
+  start spool;
+ 
+END PROC start spool;
+ 
+PROC stop spool (TEXT CONST deactive msg) :
+ 
+  disable stop;
+  deactive message  := deactive msg;
+  start cmd pending := FALSE;
+  stop server;
+  IF is valid fetch entry CAND on line CAND
+       yes (""13""10"" + fetch entry. entry line + "   neu eintragen")
+     THEN reinsert fetch entry
+     ELSE erase fetch entry;
+  FI;
+ 
+END PROC stop spool;
+ 
+PROC stop spool :  stop spool ("")  END PROC stop spool;
+ 
+PROC halt spool (TEXT CONST deactive msg) :
+ 
+  enable stop;
+  deactive message  := deactive msg;
+  stop  cmd pending := TRUE; 
+  start cmd pending := FALSE;
+  IF NOT exists (server) OR server is waiting THEN stop spool FI;
+ 
+END PROC halt spool;
+ 
+PROC halt spool :  halt spool ("")  END PROC halt spool;
+ 
+ 
+PROC kill spool :
+ 
+  enable stop;
+  say (""13""10"");
+  que index := 1;
+  WHILE que index <= number entries
+  REP IF yes (list entry. entry line + "   loeschen")
+         THEN kill spool (que index)
+         ELSE que index INCR 1
+      FI;
+  PER;
+ 
+END PROC kill spool;
+ 
+PROC kill spool (INT CONST index) :
+ 
+  IF is valid que index (index)
+     THEN forget (que space (code (que entries SUB index)));
+          free entries CAT (que entries SUB index);
+          delete char (que entries, index);
+  FI;
+ 
+END PROC kill spool;
+ 
+ 
+PROC first spool :
+ 
+  enable stop;
+  say (""13""10"");
+  FOR que index FROM 1 UPTO number entries
+  REP IF yes (list entry. entry line + "   als erstes")
+         THEN first spool (que index);
+              LEAVE first spool
+      FI;
+  PER;
+ 
+END PROC first spool;
+ 
+PROC first spool (INT CONST index) :
+ 
+  IF is valid que index (index)
+      THEN insert char (que entries, que entries SUB index, 1);
+           delete char (que entries, index + 1);
+  FI;
+ 
+END PROC first spool;
+ 
+ 
+TEXT PROC spool entry line (INT CONST index) :
+ 
+  IF   index = 0 CAND is valid fetch entry
+       THEN fetch entry. entry line
+  ELIF is valid que index (index)
+       THEN entry. entry line
+       ELSE ""
+  FI
+ 
+  . entry : que (code (que entries SUB index))
+ 
+END PROC spool entry line;
+ 
+ 
+INT PROC number spool entries : number entries END PROC number spool entries;
+ 
+INT PROC spool status :
+ 
+  IF exists (server)
+     THEN IF stop cmd pending
+             THEN IF start cmd pending
+                     THEN 3         (* aktiviert (neu start)        *)
+                     ELSE 2         (* aktiviert (warten auf halt)  *)
+                  FI
+             ELSE IF server is waiting
+                     THEN 0         (* kein Auftrag in Bearbeitung  *)
+                     ELSE 1         (* aktiviert                    *)
+                  FI
+          FI
+  ELIF start cmd pending
+       THEN               0         (* wird aktiviert               *)
+  ELIF is valid fetch entry
+       THEN IF was define station
+               THEN      -3         (* deaktiviert (define station) *)
+               ELSE      -2         (* deaktiviert (server gelöcht) *)
+            FI
+       ELSE              -1         (* deaktiviert                  *)
+  FI
+ 
+END PROC spool status;
+ 
+TASK PROC server task :  server  END PROC server task;
+ 
+ 
+PROC clear spool :
+ 
+  disable stop;
+  IF NOT initialized (init que space)
+     THEN FOR que index FROM 1 UPTO que size
+              REP que space (que index) := nilspace PER;
+  FI;
+  que  entries := "";
+  free entries := "";
+  fetch index  := 0;
+  stop server;
+  FOR que index FROM 1 UPTO que size 
+  REP forget (que space (que index));
+      free entries CAT code (que index);
+  PER;
+ 
+END PROC clear spool;
+ 
+ 
+PROC list spool :
+ 
+  disable stop;
+  DATASPACE VAR list ds := nilspace;
+  FILE VAR list file := sequential file (output, list ds);
+  list spool (list file);
+  show (list file);
+  forget (list ds);
+ 
+END PROC list spool;
+ 
+ 
+PROC list spool (FILE VAR f) :
+ 
+  enable stop;
+  output (f);
+  max line length (f, 1000);
+  headline (f, 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 (f, "Aufgabe: ");
+              write (f, spool duty );
+              line (f, 2);
+      FI;
+ 
+  . put current job :
+      IF is valid fetch entry
+         THEN write (f, "In Bearbeitung seit ");
+              write (f, start time);
+              write (f, ":");
+              line (f, 2);
+              putline (f, fetch entry. entry line);
+              IF   NOT exists (server)
+                   THEN IF was define station
+                           THEN putline (f, "Spool ist deaktiviert, da Stationsnummer geaendert wurde")
+                           ELSE putline (f, "Spool ist deaktiviert, da der Server gelöscht wurde")
+                        FI;
+              ELIF stop cmd pending
+                   THEN IF start cmd pending
+                           THEN putline (f, "Spool wird nach diesem Auftrag neu aktiviert");
+                           ELSE putline (f, "Spool wird nach diesem Auftrag deaktiviert");
+                        FI;
+              FI;
+              line (f);
+         ELSE write (f, "kein Auftrag in Bearbeitung");
+              IF   NOT exists (server)
+                   THEN write (f, ", da Spool deaktiviert");
+                        IF start cmd pending
+                           THEN line (f);
+                                write (f, "Spool wird nach Verlassen der Task aktiviert");
+                        FI;
+                        IF deactive message <> ""
+                           THEN line (f);
+                                write (f, deactive message);
+                        FI;
+              ELIF que is empty
+                   THEN write (f, ", da Warteschlange leer");
+                        LEAVE list spool;
+              FI;
+              line (f, 2);
+      FI;
+ 
+  . put spool que :
+      IF que is empty
+         THEN putline (f, "Warteschlange ist leer");
+         ELSE write (f, "Warteschlange (");
+              write (f, text (number entries));
+              IF number entries = 1
+                 THEN write (f, " Auftrag):");
+                 ELSE write (f, " Auftraege):");
+              FI;
+              line (f, 2);
+              FOR que index FROM 1 UPTO number entries
+                REP putline (f, list entry. entry line) PER;
+      FI;
+ 
+END PROC list spool;
+ 
+ 
+ENDPACKET spool manager;
+
diff --git a/system/std analysator b/system/std analysator
new file mode 100644
index 0000000..7e14722
--- /dev/null
+++ b/system/std analysator	
@@ -0,0 +1,68 @@
+PACKET std analysator                             (* Autor : Rudolf Ruland *)
+                                                  (* Stand : 06.11.86      *)
+       DEFINES std analysator :
+ 
+ 
+LET text code                      =  1, 
+    error code                     =  2, 
+    token code                     =  3; 
+ 
+INT VAR instruction begin;
+TEXT VAR unknown instruction := "";
+     
+PROC std analysator (INT CONST op code, TEXT VAR string,
+                     INT VAR par1, par2, par3, par4, par5, par6, par7) :
+ 
+  SELECT op code OF 
+   
+    CASE text code   :  analyse text 
+    CASE error code  :  report errors 
+    CASE token code  :  report tokens 
+ 
+  END SELECT ;
+ 
+  . record     :  string
+  . record pos :  par1
+  . width      :  par4
+  . height     :  par5
+  . depth      :  par6
+ 
+  . analyse text : 
+      instruction begin := record pos + 1;
+      record pos := pos (record, "#", instruction begin) + 1;
+      width      := 0;
+      height     := 0;
+      depth      := 0;
+      unknown instruction := subtext (record, instruction begin, instruction end);
+ 
+      . instruction end : record pos - 2
+ 
+ 
+. error msg  :  string 
+. error nr   :  par1
+.
+  report errors :
+    IF error nr = 0
+       THEN error msg := "unbekannte Anweisung (ignoriert): ";
+            error msg CAT unknown instruction;
+            error nr  := 1;
+       ELSE error msg := "";
+            error nr  := 0;
+    FI;
+ 
+ 
+. token text           :  string
+. token nr             :  par1
+. token font nr        :  par2
+. token modifications  :  par3
+. token width          :  par4
+. token x pos          :  par5
+. token y pos          :  par6
+. token type           :  par7
+. 
+  report tokens :
+ 
+END PROC std analysator;
+ 
+END PACKET std analysator;
+
diff --git a/tecal/TeCal b/tecal/TeCal
new file mode 100644
index 0000000..0bcb18e
--- /dev/null
+++ b/tecal/TeCal
@@ -0,0 +1,856 @@
+(**********************************************************************)
+(*                                                                    *)
+(*                      TeCal - Text Calculator                       *)
+(*                                                                    *)
+(*  Autor    : Andreas Schmeink                        06.09.1984     *)
+(*  Korrektur: Hilmar v.d. Bussche                     17.09.1984     *)
+(*                                                     20.09.1984     *)
+(*  Adaption : Uwe Behrend, Andreas Schmeink           03.08.1987     *)
+(**********************************************************************)
+ 
+PACKET pick DEFINES pick up number, left range, right range,
+                    replace number, last pick up ok :
+ 
+(********************************************************************)
+(*                                                                  *)
+(*  Zahlen erkennen und schreiben für TeCal              12.09.84   *)
+(*                                                                  *)
+(********************************************************************)
+ 
+LET ziffern = "0123456789", pseudoblankcode = 223;
+ 
+ROW 10 REAL VAR ziffer plus eins
+            := ROW 10 REAL : (0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0);
+REAL VAR number;
+BOOL VAR ziffer gefunden;
+INT VAR anfang, ende, zeichencode, vorkommastellen, p, dezimalzeichen;
+TEXT VAR worktext;
+ 
+BOOL PROC last pick up ok:
+   ziffer gefunden
+END PROC last pick up ok;
+ 
+REAL PROC code to digit (INT CONST code) :
+   ziffer plus eins (code-47)
+END PROC code to digit; 
+ 
+INT PROC left range :
+   anfang
+END PROC left range;
+ 
+INT PROC right range :
+   ende
+END PROC right range;
+ 
+REAL PROC pick up number (TEXT CONST source, INT CONST where) :
+ 
+   suche ende der zahl; 
+   lies zahl ein;
+   number.
+ 
+suche ende der zahl :
+   fange bei gegebener position an;
+   IF vorzeichen THEN
+      nach rechts ruecken
+   FI; 
+   WHILE erlaubtes zeichen REP 
+      nach rechts ruecken 
+   PER;
+   ende merken.
+ 
+fange bei gegebener position an:
+   ziffer gefunden := FALSE;
+   p := where;
+   betrachte aktuelles zeichen.
+ 
+nach rechts ruecken:
+   p INCR 1;
+   betrachte aktuelles zeichen.
+ 
+nach links ruecken:
+   p DECR 1;
+   betrachte aktuelles zeichen.
+ 
+ende merken :
+   ende := p - 1.
+ 
+lies zahl ein :
+   fange hinter der zahl an;
+   sammle ziffern auf;
+   pruefe vorzeichen;
+   werte exponent aus.
+ 
+sammle ziffern auf :
+   REP
+      nach links ruecken;
+      IF ziffer THEN
+         ziffer behandeln
+      ELIF punkt OR komma THEN
+         IF wirkt als dezimalzeichen THEN
+             dezimalzeichen behandeln
+         ELSE ignorieren
+         FI
+      ELIF pseudoblank vor ziffer THEN
+         ignorieren
+      ELSE
+         LEAVE sammle ziffern auf
+      FI;
+   PER.
+ 
+pruefe vorzeichen :
+   IF minus THEN
+      anfang := p;
+      number := number * -1.0
+   ELIF plus THEN
+      anfang := p
+   ELSE
+      anfang := p+1
+   FI.
+ 
+werte exponent aus :
+   set exp (vorkommastellen+decimal exponent(number), number).
+ 
+fange hinter der zahl an :
+   vorkommastellen := 0;
+   dezimalzeichen := 0;
+   number := 0.0;
+   p := ende + 1.
+ 
+betrachte aktuelles zeichen: 
+   zeichencode := code (source SUB p).
+ 
+ziffer behandeln :
+   ziffer gefunden := TRUE;
+   number := (number + code to digit (zeichencode))/10.0;
+   vorkommastellen INCR 1.
+ 
+dezimalzeichen behandeln :
+   dezimalzeichen := zeichencode;
+   vorkommastellen := 0.
+ 
+wirkt als dezimalzeichen :
+   dezimalzeichen = 0 OR dezimalzeichen = zeichencode.
+ 
+erlaubtes zeichen :
+   ziffer OR punkt OR komma OR pseudoblank vor ziffer.
+ 
+pseudoblank vor ziffer :
+   zeichencode = pseudoblankcode AND pos (ziffern, source SUB (p+1) ) > 0.
+ 
+vorzeichen : plus OR minus.
+ 
+ziffer : zeichencode >= 48 AND zeichencode <= 57. 
+ 
+plus : zeichencode = 43.
+ 
+minus : zeichencode = 45.
+ 
+punkt : zeichencode = 46.
+ 
+komma : zeichencode = 44.
+ 
+ignorieren :.
+ 
+END PROC pick up number;
+ 
+PROC replace number (TEXT VAR source, REAL CONST value, INT CONST where,
+                                                        nachkommastellen) :
+ 
+   alte grenzen feststellen;
+   wenn noetig auf format der neuen zahl erweitern;
+   zahl in text umwandeln;
+   zahl ersetzen. 
+ 
+alte grenzen feststellen :
+   REAL VAR dummy; 
+   dummy := pick up number (source, where).
+ 
+wenn noetig auf format der neuen zahl erweitern :
+   INT VAR schreibanfang := min (anfang, neuer anfang),
+           schreibende := max (ende, neues ende).
+ 
+neuer anfang : where - vorkommazeichen + 1.
+ 
+vorkommazeichen : max (2,(decimal exponent (value) + 2)).
+ 
+neues ende : where + nachkommastellen + 1.
+ 
+zahl in text umwandeln :
+  worktext := text (value,stellen,nachkommastellen);
+  IF decimal exponent (value) < 0 THEN
+     change (worktext," .","0."); change (worktext," -.","-0.");
+  FI;
+  IF nachkommastellen = 0 THEN 
+     replace (worktext, LENGTH worktext, " ")
+  FI;
+  WHILE LENGTH worktext < schreibende-schreibanfang+1 REP
+     worktext CAT " "
+  PER.
+ 
+zahl ersetzen : 
+  WHILE LENGTH source < schreibende REP
+     source CAT " "
+  PER;
+  replace (source, schreibanfang, worktext) .
+ 
+stellen : where-schreibanfang+2+nachkommastellen. 
+ 
+END PROC replace number;
+ 
+END PACKET pick;
+ 
+PACKET rechner DEFINES clear, push, result, do,
+                       superklammer auf, superklammer zu,
+                       empty, operand expected, dump:
+ 
+(********************************************************************)
+(*                                                                  *)
+(*  Rechenwerk fuer TeCal                                13.09.84   *)
+(*                                                                  *)
+(********************************************************************)
+ 
+LET  plus = 1, minus = 2, mal = 3, durch = 4, hoch = 5,
+     monad minus = 6, klammer auf = 7, klammer zu = 8, gleich = 9; 
+ 
+LET klammerpriostufe = 10, superklammerpriostufe = 500;
+ 
+LET tiefe = 30; 
+ 
+REAL VAR dummy;
+BOOL VAR war operand; 
+ 
+INT VAR operandentop, operatorentop, klammerprio, superklammerprio; 
+ 
+ROW tiefe INT VAR operatorenstack;
+ROW tiefe REAL VAR operandenstack; 
+ 
+PROC superklammer auf :
+   IF war operand THEN
+      pop (dummy)
+   FI;
+   superklammerprio INCR superklammerpriostufe;
+   klammerprio INCR superklammerpriostufe
+END PROC superklammer auf;
+ 
+PROC superklammer zu :
+   IF superklammerprio > 0 THEN
+      push (gleich);
+      superklammerprio DECR superklammerpriostufe;
+      klammerprio DECR superklammerpriostufe
+   FI;
+END PROC superklammer zu;
+ 
+INT PROC prio (INT CONST op):
+   klammer prio + elementar prio.
+ 
+elementar prio :
+   SELECT op OF 
+   CASE plus,minus : 2
+   CASE mal,durch  : 3
+   CASE hoch       : 4
+   CASE monadminus : 6
+   CASE klammerzu  : 0
+   CASE gleich     : -klammerprio+superklammerprio
+   OTHERWISE errorstop ("prio("+text(op)+")"); 0
+   END SELECT
+END PROC prio;
+ 
+PROC clear :
+   operandentop := 0;
+   operatorentop := 0; 
+   war operand := FALSE;
+   klammerprio := 0;
+   superklammerprio := 0;
+END PROC clear;
+ 
+PROC push (INT CONST op) :
+   enable stop;
+   IF war operand THEN
+      dyadischer operator oder gleich oder klammer zu 
+   ELIF op = minus COR op = monad minus THEN
+      push monadisches minus
+   ELIF op = plus THEN
+      (* ignoriere monad plus *)
+   ELIF op = klammer auf THEN
+      IF stack zu voll THEN
+         errorstop ("Zuviele offene Klammern")
+      FI;
+      klammerprio INCR klammerpriostufe
+   ELSE
+      errorstop ("Zahl erwartet, letzten Operator ignoriert")
+   FI.
+ 
+dyadischer operator oder gleich oder klammer zu :
+   IF op = monad minus COR op = klammer auf THEN
+      (* errorstop ("Operator (+,-,*,/) vor Klammer auf fehlt")*)
+      ignore last operand;
+      push (op);
+      LEAVE push
+   ELSE
+      WHILE prio (op) <= stack top prio REPEAT
+         auswerten
+      PER;
+      push operator
+   FI.
+ 
+stack top prio : 
+   IF operatorentop = 0 THEN -1
+   ELSE operator DIV 10
+   FI.
+ 
+stack zu voll :
+   operandentop >= tiefe - 4.
+ 
+auswerten :
+   REAL VAR op2;
+   SELECT operator MOD 10 OF
+   CASE monad minus : operand := - operand
+   CASE plus : pop (op2); operand INCR op2
+   CASE minus: pop (op2); operand DECR op2
+   CASE mal  : pop (op2); operand := operand * op2
+   CASE durch: pop (op2); operand := operand / op2 
+   CASE hoch : pop (op2); operand := operand ** op2 
+   OTHERWISE
+(**) errorstop ("Im Opstack ("+text(operatorentop)+") gefunden : "+text(operator))
+   END SELECT;
+   war operand := TRUE;
+   operatorentop DECR 1.
+ 
+push operator :
+   IF op = klammerzu THEN
+      IF klammerprio > superklammerprio THEN
+         klammerprio DECR klammerpriostufe (* ELSE ignoriere ")" zuviel *)
+      FI
+   ELIF op = gleich THEN
+      klammerprio := superklammerprio; 
+   ELSE
+      operatorentop INCR 1;
+      operator := prio (op) * 10 + op;
+      war operand := FALSE
+   FI.
+ 
+push monadisches minus :
+   operatorentop INCR 1;
+   operator := prio (monad minus) * 10 + monad minus.
+ 
+ignore last operand :
+   pop (dummy).
+ 
+END PROC push;
+ 
+PROC push (REAL CONST op) :
+   IF war operand THEN
+      operand := op; (* Operand wird ueberschrieben *)
+   ELSE
+      operandentop INCR 1;
+      operand := op;
+      war operand := TRUE
+   FI
+END PROC push;
+ 
+PROC pop (REAL VAR r) :
+   IF operandentop = 0 THEN
+      errorstop ("Operand fehlt")
+   ELSE r := operand;
+      operandentop DECR 1
+   FI;
+   war operand := FALSE
+END PROC pop;
+ 
+REAL PROC result :
+   IF operanden top > 0 THEN operand ELSE 0.0 FI
+END PROC result;
+ 
+BOOL PROC empty :
+   operandentop < 1
+END PROC empty;
+ 
+BOOL PROC operand expected :
+   NOT war operand
+END PROC operand expected;
+ 
+PROC do (REAL PROC (REAL CONST) f):
+   IF NOT war operand THEN
+      push (f(result))
+   ELSE
+      operand := f(operand)
+   FI
+END PROC do;
+ 
+PROC dump :
+  INT VAR x,y;
+  get cursor (x,y);
+  cursor (1,1);
+   INT VAR i;
+   put(operatorentop);put ("OPERATOREN");
+   FOR i FROM 1 UPTO operatorentop REP
+       put (text (operatorenstack(i),8));
+   PER;out (""5""); line; 
+   put (operandentop);put ("OPERANDEN ");
+   FOR i FROM 1 UPTO operandentop REP
+       put (text (operandenstack(i),8,2));
+   PER;out (""5""); line;
+   put ("Klammern:");put(klammerprio);
+   put ("Superklammern:");put(superklammerprio);
+   IF war operand THEN put ("war operand") ELSE put ("war operator") FI;line;
+   cursor (x,y);
+END PROC dump;
+ 
+.
+operand : operandenstack (operandentop).
+operator: operatorenstack(operatorentop).
+ 
+END PACKET rechner;
+ 
+PACKET tecalfunctions DEFINES merke, prozentsatz, kommastellen,
+                              prozent, evaluate, tecal :
+ 
+(********************************************************************)
+(*                                                                  *)
+(*  TeCal - Funktionen                                   15.09.84   *)
+(*                                                                  *)
+(********************************************************************)
+ 
+LET operatorenliste = "+-*/^ ()=", gib ausdruck = ""15" gib wert : ";
+ 
+REAL VAR speicher := 0.0, percent := 14.0, displayed value := -1.0;
+INT VAR nachkommastellen := 2;
+ 
+INT VAR zeiger,dachpos;   (* fuer evaluate *)
+TEXT VAR char;            (* fuer evaluate *)
+ 
+TEXT VAR status line, anzeigetext;
+INT VAR anzeigestart, anzeigelaenge, memorystart, prozentstart;
+init status line;
+ 
+PROC evaluate (TEXT CONST formel):
+   evaluate (formel,1)
+END PROC evaluate;
+ 
+PROC evaluate (TEXT CONST formel, INT CONST ab wo):
+   enable stop;
+   zum formelanfang; 
+   REP
+      zum naechsten relevanten zeichen;
+      IF formelende THEN LEAVE evaluate
+      FI;
+      symbol verarbeiten
+   UNTIL gleich zeichen verarbeitet PER.
+ 
+zum formelanfang :
+   dachpos := pos (formel,"^");
+   zeiger:= ab wo - 1.
+ 
+zum naechsten relevanten zeichen :
+   REP
+      zum naechsten wahrscheinlich relevanten zeichen
+   UNTIL formelende COR wirklich relevant PER.
+ 
+zum naechsten wahrscheinlich relevanten zeichen:
+   zeiger := pos (formel,"%","=",zeiger+1);
+   IF dachpos <> 0 CAND zeiger > dachpos THEN
+      zeiger := dachpos;
+      dachpos := pos (formel,"^",dachpos+1)
+   FI.
+ 
+formelende :
+   zeiger = 0.
+ 
+wirklich relevant :
+   char := formel SUB zeiger;
+   pos ("',.:;<", char) = 0.
+ 
+symbol verarbeiten :
+   IF ziffer THEN
+      push (abs(pick up number(formel,zeiger)));
+      zeiger := right range
+   ELSE
+      INT VAR op := pos (operatorenliste,char);
+      IF op > 0 THEN
+         push (op)
+      ELIF char = "%" THEN
+         do (REAL PROC (REAL CONST) prozent)
+      ELSE errorstop ("TeCal FEHLER : symbol verarbeiten")
+      FI
+   FI.
+ 
+gleichzeichen verarbeitet : char = "=".
+ 
+ziffer : pos ("0123456789",char) > 0.
+ 
+END PROC evaluate;
+ 
+PROC merke (REAL CONST wert) :
+ speicher := wert;
+ set anzeigetext (speicher);
+ replace (statusline,memorystart,anzeigetext);
+ show status line
+END PROC merke;
+ 
+PROC merke (INT CONST wert) :
+ merke (real (wert));
+END PROC merke;
+ 
+PROC prozentsatz (REAL CONST wert) :
+ percent := wert;
+ replace (statusline,prozentstart,text(percent,6,2));
+ show status line;
+END PROC prozentsatz;
+ 
+PROC prozentsatz (INT CONST wert) :
+ prozentsatz (real (wert));
+END PROC prozentsatz;
+ 
+PROC kommastellen (INT CONST anz stellen) :
+ nachkommastellen := max  (  0,  min (anz stellen, 16)) ;
+ set anzeigetext (0.0);
+ replace (statusline,anzeigestart,anzeigetext);
+ merke (speicher);
+END PROC kommastellen;
+ 
+REAL PROC prozent (REAL CONST wovon) :
+ percent * wovon / 100.0
+END PROC prozent;
+ 
+REAL PROC runden (REAL CONST was) :
+  round (was,nachkommastellen)
+END PROC runden;
+ 
+PROC init status line :
+   statusline := 
+"$Anzeige: & __________._________  $    %%%.%%% Memory: ----------.--------- &"
+;  change all (statusline,"$",""15"");
+   change all (statusline,"&",""14"");
+   anzeigestart := pos (statusline,"_");
+   anzeigelaenge:= pos (statusline," ",anzeigestart)-anzeigestart; 
+   memorystart  := pos (statusline,"-");
+   prozentstart := pos (statusline,"%");
+   set anzeigetext (0.0);
+   replace (statusline,anzeigestart,anzeigetext);
+   set anzeigetext (speicher);
+   replace (statusline,memorystart,anzeigetext);
+   replace (statusline,prozentstart,text(percent,6,2))
+END PROC init status line;
+ 
+PROC show status line :
+   cursor (1,y screen size); out (statusline);
+   displayed value := 0.0;
+   display value
+END PROC show status line;
+ 
+PROC display value :
+   IF displayed value <> result THEN
+      cursor (anzeigestart,y screen size);
+      set anzeigetext (result);
+      out (anzeigetext)
+   FI.
+ 
+END PROC display value;
+ 
+PROC get expression (TEXT VAR exp) :
+  cursor (1,yscreen size);
+  out (gib ausdruck);
+  (x screen size - 4 - LENGTH gib ausdruck) TIMESOUT " ";
+  out (""14""15""8" ");
+  cursor (LENGTH gib ausdruck, y screen size);
+  editget (exp);
+END PROC get expression;
+ 
+PROC set anzeigetext (REAL CONST r) :
+  IF decimal exponent (r) + nachkommastellen + 3 <= anzeigelaenge THEN
+     anzeigetext := text (r,anzeigelaenge,nachkommastellen);
+     IF decimal exponent (r) < 0 THEN
+        change (anzeigetext," .","0."); change (anzeigetext," -.","-0.");
+     FI;
+     IF nachkommastellen = 0 THEN 
+        replace (anzeigetext, LENGTH anzeigetext, " ")
+     FI;
+  ELSE
+     anzeigetext := text (r,anzeigelaenge)
+  FI
+END PROC set anzeigetext;
+ 
+(***************  TeCal - Editor - Schnittstelle  *****************)
+ 
+ 
+LET  tecal tasten    = "tq%()*+-/=CEFHKLMNRSVW^T"9"?",
+     funktionenliste = "LSCEFHKMNRVWtq%"9"T?"        ,
+     zahlzeichen     = "1234567890.,-+"              ,
+     std tasten      = "tqevw19dpgn"9""              ;
+ 
+LET kommando prozent  = 15,
+    kommando clear    = 3,
+    kommando einlesen = 4,
+    kommando formel   = 5,
+    kommando recall   = 7,
+    kommando lesen    = 1,
+    kommando store    = 8,
+    kommando naechste = 9,
+    kommando q        = 14,
+    kommando runden   = 10,
+    kommando schreiben= 2,
+    kommando umschalt = 13,
+    kommando ver sum  = 11,
+    kommando fenster  = 12,
+    kommando type     = 17,
+    kommando help     = 18;
+ 
+LET x screen size       = 79,
+    y screen size       = 24;
+ 
+FILE VAR tecal file;
+ 
+TEXT VAR record, input buffer;
+INT VAR record pos;
+ 
+PROC dateizeile lesen :
+  set busy indicator;
+  read record (tecal file, record);
+  record pos := col (tecal file)
+END PROC dateizeile lesen; 
+ 
+PROC zahl aufsammeln :
+   dateizeile lesen;
+   REAL VAR zahl := pick up number (record, record pos);
+   IF last pick up ok THEN
+      push (zahl)
+   ELSE
+      errorstop ("Keine Zahl gefunden")
+   FI
+END PROC zahl aufsammeln;
+ 
+REAL PROC spaltensumme :
+ 
+   anfangsposition merken;
+   nach oben laufen und addieren;
+   zum anfang zurueck;
+   summe.
+ 
+nach oben laufen und addieren :
+   WHILE NOT oben angekommen REP
+      hochgehen und satz lesen;
+      record auswerten
+   PER.
+ 
+anfangsposition merken :
+   INT VAR alte zeile := line no (tecal file);
+   dateizeile lesen;
+   REAL VAR summe := pick up number (record,record pos);
+   BOOL VAR weiterlaufen := TRUE
+   IF NOT last pick up ok THEN
+       summe := 0.0
+   FI.
+ 
+zum anfang zurueck :
+   to line (tecalfile, alte zeile).
+ 
+hochgehen und satz lesen :
+   up (tecal file);
+   read record (tecal file, record).
+ 
+oben angekommen : line no (tecalfile) = 1 COR NOT weiterlaufen.
+ 
+record auswerten :
+   IF blankzeile THEN
+      weiterlaufen := TRUE 
+   ELIF kein zahlzeichen THEN
+      weiterlaufen := FALSE
+   ELSE
+      summe INCR pick up number (record,record pos);
+      weiterlaufen := last pick up ok
+   FI.
+ 
+blankzeile : LENGTH record < record pos COR (record SUB record pos) = " ".
+ 
+kein zahlzeichen : pos (zahlzeichen,record SUB recordpos) = 0. 
+ 
+END PROC spaltensumme;
+ 
+PROC tecal (TEXT CONST filename) :
+  type (""27"t");
+  edit (filename).
+ 
+END PROC tecal;
+ 
+PROC tecal :
+ IF groesster editor > 0
+    THEN tecal auf editfile
+    ELSE tecal (lastparam)
+ FI.
+ 
+tecal auf editfile :
+   FILE VAR f := editfile;
+   quit;
+   tecal (f) .
+ 
+END PROC tecal;
+ 
+PROC tecal (FILE VAR ed file) :
+  enable stop     ;
+  open editor (groesster editor + 1, ed file,  TRUE,
+               1, 1, x screen size, y screen size - 1);
+  show status line;
+  edit (groesster editor, tecal tasten + std tasten,
+        PROC (TEXT CONST) tecal interpreter) .
+ 
+END PROC tecal;
+ 
+PROC tecal interpreter (TEXT CONST symbol) :
+ 
+  tecal file := editfile ;
+  nichts neu ;
+  INT VAR kommando := pos (operatorenliste,symbol);
+  IF kommando > 0 THEN
+     normale rechenoperation
+  ELSE kommando := pos (funktionenliste,symbol);
+     sonderfunktion
+  FI.
+ 
+normale rechenoperation :
+  IF operand expected CAND keine klammer auf THEN
+     zahl aufsammeln
+  FI;
+  push (kommando);
+  display value.
+ 
+keine klammer auf : symbol <> "(".
+ 
+sonderfunktion :
+  SELECT kommando OF
+    CASE kommando prozent  : do prozent
+    CASE kommando clear    : do clear
+    CASE kommando einlesen : do get
+    CASE kommando formel   : do formelrechnung
+    CASE kommando ver sum  : do spaltensumme
+    CASE kommando recall   : do speicher lesen
+    CASE kommando lesen    : do zahl aufsammeln
+    CASE kommando store    : do speicher schreiben
+    CASE kommando naechste : do zur naechsten zahl
+    CASE kommando q        : quit
+    CASE kommando runden   : do runden
+    CASE kommando schreiben: do schreiben
+    CASE kommando umschalt : do tecal abschalten
+    CASE kommando type     : do type displayed value
+(*  CASE kommando hor sum  : calculate ver sum*)
+    CASE kommando fenster  : do fenster als zweiten operanden
+(*  CASE kommando tab      :  calculate tab sum *)
+    CASE kommando help     : do ("tecal auskunft")
+    OTHERWISE              : std kommando interpreter (symbol)
+  END SELECT.
+ 
+do prozent :
+  IF operand expected THEN
+     zahl aufsammeln
+  FI;
+  do (REAL PROC (REAL CONST) prozent);
+  display value.
+ 
+do clear :
+  clear;
+  ueberschrift neu;
+  show status line.
+ 
+do get : 
+  input buffer := "";
+  get expression (input buffer);
+  IF input buffer > " " THEN
+     disable stop;
+     superklammer auf;
+     evaluate (input buffer);
+     superklammer zu;
+     show status line;
+     enable stop;
+  ELSE
+     show status line
+  FI.
+ 
+do zahl aufsammeln :
+  zahl aufsammeln;
+  display value.
+ 
+do speicher schreiben :
+  merke (result);
+  show status line.
+ 
+do type displayed value :
+  set anzeigetext (result);
+  push(compress(anzeigetext)).
+ 
+do speicher lesen :
+  push (speicher);
+  display value.
+ 
+do spaltensumme :
+  push (spaltensumme);
+  display value.
+ 
+do formelrechnung :
+  dateizeile lesen;
+     disable stop;
+     superklammer auf;
+     evaluate (record);
+     superklammer zu;
+     enable stop;
+  display value;
+  IF enthaelt gleichzeichen CAND NOT empty THEN 
+     ergebnis dahinter schreiben 
+  ELSE
+     col (LENGTH record + 1)
+  FI.
+ 
+enthaelt gleichzeichen :
+  INT VAR gleichpos := pos (record,"=");
+  gleichpos > 0.
+ 
+ergebnis dahinter schreiben :
+  record pos := gleichpos + 2 + decimal exponent (result);
+  gleich pos := pos (record, ".", recordpos + 1) -1;
+  IF gleichpos > 0 THEN
+     record pos := gleichpos
+  FI;
+  ergebnis eintragen und dateizeile zurueckschreiben.
+ 
+ergebnis eintragen und dateizeile zurueckschreiben :
+  replace number (record, result, record pos, nachkommastellen);
+  write record (tecal file, record);
+  zeile neu;
+  col (record pos).
+ 
+do zur naechsten zahl :
+  dateizeile lesen;
+  record pos := pos (record,"0","9",record pos);
+  IF record pos = 0 THEN
+     record pos := LENGTH record + 1
+  FI;
+  col (record pos).
+ 
+do schreiben :
+  IF NOT empty THEN
+     dateizeile lesen;
+     ergebnis eintragen und dateizeile zurueckschreiben
+  FI.
+ 
+do runden :
+  IF NOT empty AND NOT operand expected THEN
+     do (REAL PROC (REAL CONST) runden)
+  FI.
+ 
+do fenster als zweiten operanden :
+  IF empty THEN 
+     push (0.0)
+  ELSE
+     push (result)
+  FI.
+ 
+do tecal abschalten :
+  quit;
+  edit (tecalfile).
+ 
+END PROC tecal interpreter;
+ 
+clear;
+kommando auf taste legen ("t","tecal");
+(*kommando auf taste legen ("?","tecalauskunft");*)
+ 
+END PACKET tecal functions; 
+
diff --git a/tecal/TeCal Auskunft b/tecal/TeCal Auskunft
new file mode 100644
index 0000000..9468265
Binary files /dev/null and b/tecal/TeCal Auskunft differ
diff --git a/tecal/TeCal.gen b/tecal/TeCal.gen
new file mode 100644
index 0000000..c670db7
--- /dev/null
+++ b/tecal/TeCal.gen
@@ -0,0 +1,55 @@
+LET tecal    = "TeCal",
+    auskunft = "TeCal Auskunft";
+
+IF NOT exists ("TeCal") THEN fetch ("TeCal",archive) FI;
+IF NOT exists ("TeCal Auskunft") THEN fetch ("TeCal Auskunft",archive) FI;
+
+checkoff;
+insert tecal;
+insert auskunft;
+shorten auskunft file;
+forget ("Tecal.gen", quiet).
+
+insert tecal   :
+  display (""13""10""15" TeCal-Rechner wird installiert  "14""13""10"");
+  insert (tecal);
+  forget (tecal, quiet).
+
+insert auskunft:
+  display (""13""15" TeCal-Auskunftfile wird installiert  "14""13""10"");
+  insert (auskunft).
+
+shorten auskunft file :
+  display (""13""10""15" TeCal-Auskunftfile wird komprimiert  "14""13""10"");
+  disable stop;
+  DATASPACE VAR dspace := nil space;
+  FILE      VAR file   := sequential file ( input, auskunft),
+                shorted:= sequential file (output, dspace);
+  TEXT      VAR buffer;
+   INT      VAR i;
+
+  WHILE NOT eof (file)
+  REPEAT get line (file, buffer)
+  UNTIL  (pos ("(*", buffer) > 0) OR is error PER;
+  i:= 1;
+  IF eof (file) COR text not transfered
+     THEN errorstop ("TeCal-Auskunftsfile ist bereits komprimiert!"13""10"" +
+                     "'ESC <?>' funktioniert wahrscheinlich nicht."13""10"" +
+                     "Bitte ORIGINAL Auskunftsfile von Diskette verwenden")
+     ELSE forget (auskunft, quiet);
+          copy (dspace, auskunft)
+  FI;
+  forget (dspace) .
+
+ text not transfered :
+    WHILE NOT eof (file)
+    REPEAT cout (i);
+           get line (file, buffer);
+           IF pos (buffer, "*)") > 0
+              THEN LEAVE text not transfered WITH FALSE
+              ELSE put line (shorted, buffer)
+           FI;
+           i INCR 1
+    UNTIL is error PER;
+    TRUE .
+
diff --git a/warenhaus/ls-MENUKARTE:Warenhaus b/warenhaus/ls-MENUKARTE:Warenhaus
new file mode 100644
index 0000000..414470a
Binary files /dev/null and b/warenhaus/ls-MENUKARTE:Warenhaus differ
diff --git a/warenhaus/ls-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter b/warenhaus/ls-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter
new file mode 100644
index 0000000..36de5ef
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 0: mit Kartenleser an AKTRONIC-Adapter	
@@ -0,0 +1,36 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                    ls-Warenhaus 0                    ** 
+         **                                                      ** 
+         **    Anpassung für Kartenleser an  AKTRONIC-Adapter    ** 
+         **                                                      ** 
+         **                     Version 1.01                     ** 
+         **                                                      ** 
+         **                  (Stand:  30.08.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **           Autor: Bruno Pollok, Bielefeld             ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         **                                                      ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls warenhaus 0  DEFINES                       
+       interface anpassung,{}       oeffne interface,{}       schliesse interface,{}       wert von interface,{}       pressed key,{}(* --------------------------- *){}       kanalkoppler,{}       interfacechannel,{}       init interfacechannel:{}TEXT CONST interface anpassung :: "mit Kartenleser an AKTRONIC-Adapter";{}LET  max channel = 24,{}     initcode    = 26,{}     endcode     = 27,{}     read code   = 28;{}INT CONST  nicht initialisiert code :: -3,{}           interface error code     :: -4,{}
+           kanal besetzt code       :: -5;{}INT  VAR  interfacekanal  :: 0;{}TEXT VAR  puffer          :: "";{}TASK VAR  hardwaremanager :: niltask,{}          interface task  :: niltask,{}          absender;{}DATASPACE VAR  ds :: nilspace;{}INT PROC interfacechannel:{}  interfacekanal{}END PROC interfacechannel;{}PROC oeffne interface (INT VAR status):{}  puffer := "";{}  forget (ds); ds := nilspace;{}  pingpong (interfacetask, init code, ds, status);{}  IF status > 0 THEN status DECR maxint FI;{}
+  forget (ds); ds := nilspace{}END PROC oeffne interface;{}INT PROC wert von interface:{}  INT VAR wert;{}  puffer CAT incharety (1);{}  call (interface task, read code, ds, wert);{}  wert.{}END PROC wert von interface;{}PROC schliesse interface:{}  forget (ds); ds := nilspace;{}  send (interface task, end code, ds);{}  forget (ds); ds := nilspace{}END PROC schliesse interface;{}TEXT PROC pressed key:{}  IF puffer = ""{}     THEN incharety{}     ELSE erstes pufferzeichen{}  FI.{}  erstes pufferzeichen:{}
+    TEXT VAR zeichen :: puffer SUB 1;{}    puffer := subtext (puffer, 2);{}    zeichen.{}END PROC pressed key;{}TEXT PROC pressed key (INT CONST warten):{}  IF puffer = ""{}     THEN incharety (warten){}     ELSE erstes pufferzeichen{}  FI.{}  erstes pufferzeichen:{}    TEXT VAR zeichen :: puffer SUB 1;{}    puffer := subtext (puffer, 2);{}    zeichen.{}END PROC pressed key;{}(*************************************************************************){}PROC kanalkoppler:{}  enable stop;{}  IF name (myself) <> "-"{}
+     THEN errorstop ("Unzulässiges Kommando!"){}     ELSE warte auf anrufe{}  FI.{}  warte auf anrufe:{}    INT VAR codenummer, antwort;{}    disable stop;{}    REP wait (ds, codenummer, absender);{}        reagiere auf anruf;{}        loesche ggf fehlerzustand{}    PER.{}  reagiere auf anruf:{}    IF codenummer = initcode{}       THEN kopple an interface;{}            IF interface ist betriebsbereit{}               THEN bearbeite weitere auftraege{}               ELSE gib negative rueckmeldung{}
+            FI;{}            gib kanal frei{}       ELSE send (absender, nicht initialisiert code, ds){}    FI.{}  loesche ggf fehlerzustand:{}    IF is error{}       THEN clear error{}    FI.{} kopple an interface:{}  IF task (interfacekanal) <> niltask AND task (interfacekanal) <> myself{}     THEN antwort := kanal besetzt code;{}     ELSE continue (interfacekanal);{}          teste interface{}  FI.{} teste interface:{}  leere puffer;{}  out (""240"");{}  IF incharety (1) <> ""{}     THEN antwort := 0;{}
+          out (""176""){}     ELSE antwort := interface error code{}  FI.{}  leere puffer:{}    REP  UNTIL incharety = "" PER.{} interface ist betriebsbereit:  antwort = 0.{} gib negative rueckmeldung:     send (absender, antwort, ds).{} gib kanal frei:                break (quiet).{} ende:                          out (""176"").{} bearbeite weitere auftraege:{}   REP   pingpong (absender, antwort, ds, codenummer);{}         IF   codenummer = read code{}              THEN hole wert von interface{}
+         ELIF codenummer < 0{}              THEN send (absender, codenummer, ds);{}                   codenummer := endcode{}              ELSE antwort := 0{}         FI{}   UNTIL codenummer = endcode PER;{}   ende.{} hole wert von interface:{}    out (""211"");{}    antwort := code (incharety (1)).{}END PROC kanalkoppler;{}PROC init interfacechannel:{}  teste auf zulaessigkeit;{}  loesche interfacetask;{}  erfrage interface kanal;{}  generiere ggf neue interfacetask.{} teste auf zulaessigkeit:{}
+  enable stop;{}  IF hardwaremanager <> niltask AND hardwaremanager <> myself{}     THEN errorstop ("Dieses Kommando kann nur von der Task '" +{}                      name (hardwaremanager) + "' aus gegeben werden!"){}     ELSE hardwaremanager := myself{}  FI.{} loesche interfacetask:{}  disable stop;{}  end (interfacetask);{}  IF is error THEN clear error FI;{}  enable stop.{} generiere ggf neue interfacetask:{}  IF interface kanal = 0{}     THEN interface task  := niltask;{}          hardwaremanager := niltask{}
+     ELSE begin (PROC kanalkoppler, interface task);{}          hardwaremanager := myself{}  FI.{} erfrage interfacekanal:{}   INT VAR kanalnummer;{}   put ("Gib Interface - Kanal:");{}   get (kanalnummer);{}   set interfacechannel (kanalnummer).{}END PROC init interfacechannel;{}PROC set interface channel (INT CONST channel number):{}  IF channel number < 0 OR channel number > max channel{}     THEN errorstop ("Unzulässige Kanalnummer"){}     ELSE interfacekanal := channel number{}  FI{}END PROC set interface channel;{}
+BOOL OP <> (TASK CONST t1, t2):{}  NOT (t1 = t2){}END OP <>;{}init interfacechannel{}END PACKET ls warenhaus 0{}
+
diff --git "a/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endger\303\244t" "b/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endger\303\244t"
new file mode 100644
index 0000000..f108f7b
--- /dev/null
+++ "b/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI als Endger\303\244t"	
@@ -0,0 +1,36 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                    ls-Warenhaus 0                    ** 
+         **                                                      ** 
+         **    Anpassung für Kartenleser an MUFI als Endgerät    ** 
+         **                                                      ** 
+         **                     Version 1.01                     ** 
+         **                                                      ** 
+         **                  (Stand:  30.08.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **           Autor: Bruno Pollok, Bielefeld             ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         **                                                      ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls warenhaus 0  DEFINES                       
+       interface anpassung,{}       oeffne interface,{}       schliesse interface,{}       wert von interface,{}       pressed key,{}(* --------------------------- *){}       kanalkoppler,{}       interfacechannel,{}       init interfacechannel:{}TEXT CONST interface anpassung :: "mit Kartenleser an MUFI als Endgerät";{}LET  mufikennung = ""27""27"",{}     max channel = 24,{}     initcode    = 26,{}     endcode     = 27,{}     read code   = 28;{}INT CONST  nicht initialisiert code :: -3,{}           interface error code     :: -4,{}
+           kanal besetzt code       :: -5;{}INT  VAR  interfacekanal  :: 2;{}TEXT VAR  puffer          :: "";{}TASK VAR  hardwaremanager :: niltask,{}          interface task  :: niltask,{}          absender;{}DATASPACE VAR  ds :: nilspace;{}INT PROC interfacechannel:{}  interfacekanal{}END PROC interfacechannel;{}PROC oeffne interface (INT VAR status):{}  puffer := "";{}  forget (ds); ds := nilspace;{}  pingpong (interfacetask, init code, ds, status);{}  IF status > 0 THEN status DECR maxint FI;{}
+  forget (ds); ds := nilspace{}END PROC oeffne interface;{}INT PROC wert von interface:{}  INT VAR wert;{}  puffer CAT incharety (1);{}  call (interface task, read code, ds, wert);{}  wert.{}END PROC wert von interface;{}PROC schliesse interface:{}  forget (ds); ds := nilspace;{}  send (interface task, end code, ds);{}  forget (ds); ds := nilspace{}END PROC schliesse interface;{}TEXT PROC pressed key:{}  IF puffer = ""{}     THEN incharety{}     ELSE erstes pufferzeichen{}  FI.{}  erstes pufferzeichen:{}
+    TEXT VAR zeichen :: puffer SUB 1;{}    puffer := subtext (puffer, 2);{}    zeichen.{}END PROC pressed key;{}TEXT PROC pressed key (INT CONST warten):{}  IF puffer = ""{}     THEN incharety (warten){}     ELSE erstes pufferzeichen{}  FI.{}  erstes pufferzeichen:{}    TEXT VAR zeichen :: puffer SUB 1;{}    puffer := subtext (puffer, 2);{}    zeichen.{}END PROC pressed key;{}(*************************************************************************){}PROC kanalkoppler:{}  enable stop;{}  IF name (myself) <> "-"{}
+     THEN errorstop ("Unzulässiges Kommando!"){}     ELSE warte auf anrufe{}  FI.{}  warte auf anrufe:{}    INT VAR codenummer, antwort;{}    disable stop;{}    REP wait (ds, codenummer, absender);{}        reagiere auf anruf;{}        loesche ggf fehlerzustand{}    PER.{}  reagiere auf anruf:{}    IF codenummer = initcode{}       THEN kopple an interface;{}            IF interface ist betriebsbereit{}               THEN bearbeite weitere auftraege{}               ELSE gib negative rueckmeldung{}
+            FI;{}            gib kanal frei{}       ELSE send (absender, nicht initialisiert code, ds){}    FI.{}  loesche ggf fehlerzustand:{}    IF is error{}       THEN clear error{}    FI.{} kopple an interface:{}  IF task (interfacekanal) <> niltask AND task (interfacekanal) <> myself{}     THEN antwort := kanal besetzt code;{}     ELSE continue (interfacekanal);{}          teste interface{}  FI.{} teste interface:{}  leere puffer;{}  out (mufikennung + "10");{}  fange status;{}  IF status = mufikennung + "00"{}
+     THEN antwort := 0;{}          out (mufikennung + "1A18"22""){}     ELSE antwort := interface error code{}  FI.{}  leere puffer:{}    REP  UNTIL incharety = "" PER.{}  fange status:{}    INT  VAR zaehler;{}    TEXT VAR status :: "";{}    FOR zaehler FROM 1 UPTO 4 REP{}      status CAT incharety (1){}    PER.{} interface ist betriebsbereit:  antwort = 0.{} gib negative rueckmeldung:     send (absender, antwort, ds).{} gib kanal frei:                break (quiet).{} ende:                          out (""25"").{}
+ bearbeite weitere auftraege:{}   REP   pingpong (absender, antwort, ds, codenummer);{}         IF   codenummer = read code{}              THEN hole wert von interface{}         ELIF codenummer < 0{}              THEN send (absender, codenummer, ds);{}                   codenummer := endcode{}              ELSE antwort := 0{}         FI{}   UNTIL codenummer = endcode PER;{}   ende.{} hole wert von interface:{}    out (""76"");{}    antwort := code (incharety (1)).{}END PROC kanalkoppler;{}PROC init interfacechannel:{}
+  teste auf zulaessigkeit;{}  loesche interfacetask;{}  erfrage interface kanal;{}  generiere ggf neue interfacetask.{} teste auf zulaessigkeit:{}  enable stop;{}  IF hardwaremanager <> niltask AND hardwaremanager <> myself{}     THEN errorstop ("Dieses Kommando kann nur von der Task '" +{}                      name (hardwaremanager) + "' aus gegeben werden!"){}  FI.{} loesche interfacetask:{}  disable stop;{}  end (interfacetask);{}  IF is error THEN clear error FI;{}  enable stop.{} generiere ggf neue interfacetask:{}
+  IF interface kanal = 0{}     THEN interface task  := niltask;{}          hardwaremanager := niltask{}     ELSE begin (PROC kanalkoppler, interface task);{}          hardwaremanager := myself{}  FI.{} erfrage interfacekanal:{}   INT VAR kanalnummer;{}   put ("Gib Interface - Kanal:");{}   get (kanalnummer);{}   set interfacechannel (kanalnummer).{}END PROC init interfacechannel;{}PROC set interface channel (INT CONST channel number):{}  IF channel number < 0 OR channel number > max channel{}     THEN errorstop ("Unzulässige Kanalnummer!"){}
+     ELSE interface kanal := channel number{}  FI{}END PROC set interface channel;{}BOOL OP <> (TASK CONST t1, t2):{}  NOT (t1 = t2){}END OP <>;{}init interfacechannel{}END PACKET ls warenhaus 0{}
+
diff --git a/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal b/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal
new file mode 100644
index 0000000..30c69da
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 0: mit Kartenleser an MUFI im Terminalkanal	
@@ -0,0 +1,30 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                    ls-Warenhaus 0                    ** 
+         **                                                      ** 
+         **  Anpassung für Kartenleser an MUFI im Terminalkanal  ** 
+         **                                                      ** 
+         **                     Version 1.01                     ** 
+         **                                                      ** 
+         **                  (Stand:  30.08.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **           Autor: Bruno Pollok, Bielefeld             ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         **                                                      ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls warenhaus 0  DEFINES                     
+       interface anpassung,{}       oeffne interface,{}       schliesse interface,{}       wert von interface,{}       pressed key:{}TEXT CONST interface anpassung :: "mit Kartenleser an MUFI im Terminalkanal";{}LET  mufikennung = ""31""31"";{}INT  CONST interface error code :: -4;{}TEXT CONST readcode :: mufikennung + "4C";{}TEXT VAR   puffer   :: "";{}PROC oeffne interface (INT VAR status):{}  cursor (2,24);{}  warte etwas;{}  leere eingangspuffer;{}  out (""27""27"10");{}  fange antwort;{}  IF antwort = ""27""27"00"{}
+     THEN status := 0;{}          out (""27""27"1C" + hex (mufikennung)){}     ELSE status := interface error code{}  FI.{}  warte etwas:{}    pause (1); pause (1); pause (1); pause (1); pause (1).{}  leere eingangspuffer:{}    puffer := "";{}    REP UNTIL incharety = "" PER.{}  fange antwort:{}    TEXT VAR antwort :: incharety (1);{}    INT VAR i;{}    FOR i FROM 1 UPTO 3 REP{}      antwort CAT incharety (1){}    PER.{}END PROC oeffne interface;{}INT PROC wert von interface:{}  puffer CAT incharety (1);{}
+  out (readcode);{}  fange mufikennung;{}  dezimalwert (incharety (1), incharety (1)).{}  fange mufikennung:{}    REP puffer CAT incharety{}    UNTIL pos (puffer, mufikennung) > 0 PER;{}    change (puffer, mufikennung, "").{}END PROC wert von interface;{}PROC schliesse interface:{}  cursor (2,24);{}  out (mufikennung + "1C" + hex (""27""27"")){}END PROC schliesse interface;{}TEXT PROC pressed key:{}  IF puffer = ""{}     THEN incharety{}     ELSE erstes pufferzeichen{}  FI.{}  erstes pufferzeichen:{}
+    TEXT VAR zeichen :: puffer SUB 1;{}    puffer := subtext (puffer, 2);{}    zeichen.{}END PROC pressed key;{}TEXT PROC pressed key (INT CONST warten):{}  IF puffer = ""{}     THEN incharety (warten){}     ELSE erstes pufferzeichen{}  FI.{}  erstes pufferzeichen:{}    TEXT VAR zeichen :: puffer SUB 1;{}    puffer := subtext (puffer, 2);{}    zeichen.{}END PROC pressed key;{}INT PROC dezimalwert (TEXT CONST zeichen 1, zeichen 2):{}  16 * pos (hexzeichen, zeichen 1) + pos (hexzeichen, zeichen 2).{}
+  hexzeichen: "123456789ABCDEF".{}END PROC dezimalwert;{}TEXT PROC hex (TEXT CONST zwei zeichen):{}  hex (code (zwei zeichen SUB 1)) + hex (code (zwei zeichen SUB 2)){}END PROC hex;{}TEXT PROC hex (INT CONST wert):{}  (hexzeichen SUB (wert DIV 16 + 1)) + (hexzeichen SUB (wert MOD 16 + 1)).{}  hexzeichen: "0123456789ABCDEF".{}END PROC hex{}END PACKET ls warenhaus 0{}
+
diff --git a/warenhaus/ls-Warenhaus 0: ohne Kartenleser b/warenhaus/ls-Warenhaus 0: ohne Kartenleser
new file mode 100644
index 0000000..4912d64
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 0: ohne Kartenleser	
@@ -0,0 +1,27 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                    ls-Warenhaus 0                    ** 
+         **                                                      ** 
+         **      Anpassung für den Betrieb ohne Kartenleser      ** 
+         **                                                      ** 
+         **                     Version 1.01                     ** 
+         **                                                      ** 
+         **                  (Stand:  30.08.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **           Autor: Bruno Pollok, Bielefeld             ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         **                                                      ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls warenhaus 0 DEFINES                    
+       interface anpassung,{}       oeffne interface,{}       schliesse interface,{}       wert von interface,{}       pressed key:{}TEXT CONST interface anpassung :: "ohne Kartenleser";{}PROC oeffne interface (INT VAR test):{}  test := -6{}END PROC oeffne interface;{}PROC schliesse interface:{}END PROC schliesse interface;{}INT PROC wert von interface:{}  INT VAR wert :: 0;{}  wert{}END PROC wert von interface;{}TEXT PROC pressed key:{}  incharety{}END PROC pressed key;{}TEXT PROC pressed key (INT CONST warten):{}
+  incharety (warten){}END PROC pressed key;{}END PACKET ls warenhaus 0{}
+
diff --git a/warenhaus/ls-Warenhaus 1 b/warenhaus/ls-Warenhaus 1
new file mode 100644
index 0000000..81fd8ee
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 1	
@@ -0,0 +1,37 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                    ls-Warenhaus 1                    ** 
+         **                                                      ** 
+         **                     Version 1.01                     ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                  (Stand:  30.08.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **           Autor: Bruno Pollok, Bielefeld             ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         **                                                      ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET monitor alt DEFINES original monitor:          
+  PROC original monitor:{}    monitor{}  END PROC originalmonitor{}END PACKET monitor alt;{}PACKET ls warenhaus 1 DEFINES{}       zentrale,{}       monitor,{}       warenhaus direktstart,{}       warenhaus hauptstelle,{}       hauptstellenname:{}LET  max kundenzahl             =  31,{}     min kundennummer           = 129,{}     kundendatei holen code     = 100,{}     kundendatei ergaenzen code = 200;{}TYPE KUNDENDATEN   = STRUCT (TEXT nachname, vorname, geschlecht),{}     KUNDENDATEI   = ROW max kundenzahl KUNDENDATEN;{}{}
+BOUND KUNDENDATEN VAR kundendaten;{}BOUND KUNDENDATEI VAR bound kundendatei;{}KUNDENDATEI VAR kundendatei;{}DATASPACE   VAR ds;{}TASK        VAR absender,{}                zentraltask        :: niltask,{}                hauptstelle        :: niltask,{}                direktstartmanager :: niltask;{}BOOL        VAR mit direktstart    :: FALSE,{}                mit loeschen       :: FALSE;{}INT         VAR codenummer;{}PROC zentrale:{}  enable stop;{}  IF pos (name (myself), ".Zentrale") = 0{}     THEN errorstop ("Unzulaessiger Befehl!"){}{}
+  FI;{}  disable stop;{}  REP wait (ds, codenummer, absender);{}      bearbeite auftrag;{}      send (absender, codenummer, ds);{}      IF is error THEN clear error FI{}  PER.{}  bearbeite auftrag:{}    IF   codenummer = kundendatei holen code{}         THEN hole kundendatei{}    ELIF codenummer = kundendatei ergaenzen code{}         THEN ergaenze kundendatei{}    ELIF codenummer >= min kundennummer{}         THEN lies kundendaten{}         ELSE speichere kundendaten{}    FI.{}END PROC zentrale;{}{}
+PROC hole kundendatei:{}  bound kundendatei := ds;{}  bound kundendatei := kundendatei{}END PROC hole kundendatei;{}PROC ergaenze kundendatei:{}  INT VAR kundennummer;{}  bound kundendatei := ds;{}  FOR kundennummer FROM 1 UPTO max kundenzahl REP{}    IF kundendatei [kundennummer].nachname = ""{}       THEN kundendatei [kundennummer] := bound kundendatei [kundennummer]{}    FI{}  PER;{}  init ds{}END PROC ergaenze kundendatei;{}PROC lies kundendaten:{}  kundendaten := ds;{}  kundendaten := kundendatei [platznummer].{}{}
+  platznummer: codenummer - min kundennummer + 1.{}END PROC lies kundendaten;{}PROC speichere kundendaten:{}  kundendaten := ds;{}  kundendatei [codenummer] := kundendaten;{}  init ds{}END PROC speichere kundendaten;{}PROC warenhaus hauptstelle (BOOL CONST task soll hauptstelle sein):{}  enable stop;{}  IF task soll hauptstelle sein{}     THEN mache task zur hauptstelle{}     ELSE mache hauptstellenstatus rueckgaengig{}  FI.{}  mache task zur hauptstelle:{}    sei eine hauptstelle;{}    line (2);{}{}
+    IF NOT mit direktstart CAND yes ("Mit Direktstart"){}       THEN warenhaus direktstart (TRUE){}       ELSE global manager{}    FI{}END PROC warenhaus hauptstelle;{}PROC sei eine hauptstelle:{}  IF NOT (hauptstelle = niltask OR hauptstelle = myself){}     THEN errorstop ("Hauptstelle ist bereits die Task '" +{}                      name (hauptstelle) + "'!"){}  FI;{}  disable stop;{}  end (zentraltask);{}  IF is error THEN clear error FI;{}  enable stop;{}  hauptstelle := niltask;{}  begin (name (myself) + ".Zentrale", PROC zentrale, zentraltask);{}{}
+  hauptstelle := myself{}END PROC sei eine hauptstelle;{}PROC mache hauptstellenstatus rueckgaengig:{}  IF NOT (hauptstelle = niltask OR hauptstelle = myself){}     THEN errorstop ("Dieses Kommando darf nur in der Task '" +{}                      name (hauptstelle) + " gegeben werden!"){}  FI;{}  disable stop;{}  end (zentraltask);{}  IF is error THEN clear error FI;{}  enable stop;{}  hauptstelle := niltask;{}  warenhaus direktstart (FALSE){}END PROC mache hauptstellenstatus rueckgaengig;{}PROC warenhaus direktstart (BOOL CONST wahl):{}{}
+  pruefe zulaessigkeit;{}  mit direktstart := wahl;{}  IF mit direktstart{}     THEN direktstartmanager := myself;{}          mit loeschen := yes ("Mit automatischem Löschen"){}     ELSE direktstartmanager := niltask{}  FI;{}  global manager.{}  pruefe zulaessigkeit:{}    enable stop;{}    IF NOT (direktstartmanager = niltask OR direktstartmanager = myself){}       THEN errorstop ("Der Direktstart kann nur aus der Task '" +{}                        name (direktstartmanager) + "'geaendert werden!"){}{}
+    FI.{}END PROC warenhaus direktstart;{}TEXT PROC hauptstellenname:{}  name (hauptstelle){}END PROC hauptstellenname;{}PROC monitor:{}  IF mit direktstart{}     THEN warenhaus monitor{}     ELSE original  monitor{}  FI{}END PROC monitor;{}PROC warenhausmonitor:{}  disable stop;{}  INT VAR previous heapsize := heap size;{}  REP command dialogue (TRUE);{}      sysin (""); sysout ("");{}      cry if not enough storage;{}      reset dialog; erase menunotice;{}      do ("warenhaus");{}      IF is error{}{}
+         THEN clear error{}         ELSE sitzungsende{}      FI{}  PER.{}  sitzungsende:{}    collect heap garbage if necessary;{}    page;{}    IF mit loeschen{}       THEN break; end (myself){}       ELSE end; break{}    FI.{}  collect heap garbage if necessary:{}    IF heap size > previous heapsize + 10{}       THEN collect heap garbage;{}            previous heapsize := heap size{}    FI.{}  cry if not enough storage:{}    INT VAR size, used;{}    storage (size, used);{}    IF used > size{}       THEN out (""7"Speicher Engpass! Dateien loeschen!"13""10""){}{}
+    FI.{}END PROC warenhausmonitor;{}OP := (KUNDENDATEN VAR ziel, KUNDENDATEN CONST quelle):{}   CONCR (ziel) := CONCR (quelle){}END OP :=;{}OP := (KUNDENDATEI VAR ziel, KUNDENDATEI CONST quelle):{}   CONCR (ziel) := CONCR (quelle){}END OP :=;{}PROC init ds:{}  forget (ds); ds := nilspace{}END PROC init ds;{}PROC initialisiere kundendatei:{}  KUNDENDATEN CONST leer :: KUNDENDATEN : ("", "", "");{}  INT VAR nr;{}  FOR nr FROM 1 UPTO max kundenzahl REP{}      kundendatei [nr] := leer{}  PER{}END PROC initialisiere kundendatei;{}{}
+initialisiere kundendatei{}END PACKET ls warenhaus 1{}{}
+
diff --git a/warenhaus/ls-Warenhaus 2 b/warenhaus/ls-Warenhaus 2
new file mode 100644
index 0000000..7048aff
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 2	
@@ -0,0 +1,112 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                    ls-Warenhaus 2                    ** 
+         **                                                      ** 
+         **                     Version 1.01                     ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                  (Stand:  30.08.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **           Autor: Bruno Pollok, Bielefeld             ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         **                                                      ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls warenhaus 2 DEFINES                        
+       max artikelzahl,{}       max kundenzahl,{}       min kundennummer,{}       max kundennummer,{}       min artikelnummer,{}       max artikelnummer,{}       filialverwaltung,{}       initialisiere verwaltung,{}       hole artikeldaten,{}       speichere artikeldaten,{}       registriere verkauf,{}       hole kundendaten,{}       speichere kundendaten,{}       sichere filialdaten,{}       lade filialdaten,{}       hole bestelliste,{}       hole auskunft ein:{}LET  max filialen  =  10,{}     max artikel   =  15,{}
+     max kunden    =  31,{}     min kundennr  = 129,{}     max kundennr  = 159,{}     min artikelnr =   1,{}     max artikelnr =  15;{}LET  zentrale kundendatei holen code     = 100,{}     zentrale kundendatei ergaenzen code = 200,{}     filialdaten holen code              = 201,{}     filialdaten ergaenzen code          = 202;{}INT CONST max artikelzahl   :: max artikel,{}          max kundenzahl    :: max kunden,{}          min kundennummer  :: min kundennr,{}          max kundennummer  :: max kundennr,{}
+          min artikelnummer :: min artikelnr,{}          max artikelnummer :: max artikelnr;{}TYPE ARTIKELDATEN  = STRUCT (TEXT artikelname, REAL preis,{}                             INT  mindestbestand, bestand),{}     KUNDENDATEN   = STRUCT (TEXT nachname, vorname, geschlecht),{}     WARENDATEI    = ROW max artikel ARTIKELDATEN,{}     KUNDENDATEI   = ROW max kunden  KUNDENDATEN,{}     EINKAUFSDATEI = ROW max kunden  ROW max artikel INT,{}     VERKAUFSDATEI = ROW max artikel INT,{}     FILIALDATEN   = STRUCT (WARENDATEI waren, KUNDENDATEI kunden,{}
+                             EINKAUFSDATEI einkaeufe,{}                             VERKAUFSDATEI hitliste);{}KUNDENDATEI   VAR kunde;{}WARENDATEI    VAR artikel;{}EINKAUFSDATEI VAR einkaufsdatei;{}VERKAUFSDATEI VAR verkaufszahl;{}DATASPACE     VAR ds;{}INT           VAR codenummer, reply code;{}TASK          VAR zentrale, verwaltung, absender;{}TEXT          VAR hauptstelle  :: "",{}                  filialnummer :: "0",{}                  filialverwaltungsname :: "";{}PROC filialverwaltung:{}  enable stop;{}
+  IF pos (name (myself), ".Filialverwaltung") = 0{}     THEN errorstop ("Unzulaessiger Befehl!"){}  FI;{}  disable stop;{}  REP wait (ds, codenummer, absender);{}      bearbeite auftrag;{}      send (absender, 0, ds);{}      IF is error THEN clear error FI{}  PER.{}  bearbeite auftrag:{}    IF   codenummer <= max artikel{}         THEN artikeldaten speichern{}    ELIF codenummer <= max kundennr{}         THEN kauf registrieren{}    ELIF codenummer <= max kundennr + max kunden{}         THEN kundendaten speichern{}
+    ELIF codenummer = filialdaten holen code{}         THEN filialdaten holen{}    ELIF codenummer = filialdaten ergaenzen code{}         THEN filialdaten ergaenzen; init ds{}    ELIF codenummer = 256{}         THEN sperre task{}    FI.{}    sperre task:{}      call (absender, 256, ds, codenummer).{}END PROC filialverwaltung;{}PROC artikeldaten speichern:{}  BOUND ARTIKELDATEN VAR artikeldaten :: ds;{}  artikel [codenummer] := artikeldaten;{}  init ds{}END PROC artikeldaten speichern;{}PROC kauf registrieren:{}
+  artikelnummer aus ds lesen;{}  artikel [artikelnummer].bestand DECR 1;{}  verkaufszahl [artikelnummer] INCR 1;{}  IF kundennummer > 0{}     THEN einkaufsdatei [kundennummer][artikelnummer] INCR 1{}  FI.{}  artikelnummer aus ds lesen:{}    BOUND INT VAR nummer    :: ds;{}    INT CONST artikelnummer :: nummer,{}              kundennummer  :: codenummer - min kundennr + 1;{}    init ds{}END PROC kauf registrieren;{}PROC kundendaten speichern:{}  BOUND KUNDENDATEN VAR kundendaten :: ds;{}  kunde [codenummer - min kundennr - max kunden + 1] := kundendaten{}
+END PROC kundendaten speichern;{}PROC filialdaten holen:{}  init ds;{}  BOUND FILIALDATEN VAR filialdaten :: ds;{}  CONCR (filialdaten.waren)     := CONCR (artikel);{}  CONCR (filialdaten.kunden)    := CONCR (kunde);{}  CONCR (filialdaten.einkaeufe) := CONCR (einkaufsdatei);{}  CONCR (filialdaten.hitliste)  := CONCR (verkaufszahl){}END PROC filialdaten holen;{}PROC filialdaten ergaenzen:{}  BOUND FILIALDATEN VAR neue daten :: ds;{}  INT VAR kundennummer, artikelnummer;{}  ergaenze artikeldatei und verkaufszahlen;{}
+  ergaenze kundendatei;{}  ergaenze einkaufsdatei.{}  ergaenze artikeldatei und verkaufszahlen:{}    FOR artikelnummer FROM 1 UPTO max artikel REP{}      verkaufszahl [artikelnummer] INCR neue daten.hitliste [artikelnummer];{}      IF artikel [artikelnummer].artikelname = ""{}         THEN artikel [artikelnummer] := neue daten.waren [artikelnummer]{}      FI{}    PER.{}  ergaenze kundendatei:{}    FOR kundennummer FROM 1 UPTO max kunden REP{}        IF kunde [kundennummer].nachname = ""{}           THEN kunde [kundennummer] := neue daten.kunden [kundennummer]{}
+        FI{}    PER.{}  ergaenze einkaufsdatei:{}    FOR kundennummer FROM 1 UPTO max kunden REP{}      FOR artikelnummer FROM 1 UPTO max artikel REP{}        einkaufsdatei [kundennummer][artikelnummer]{}          INCR neue daten.einkaeufe [kundennummer][artikelnummer]{}      PER{}    PER.{}END PROC filialdaten ergaenzen;{}OP := (ARTIKELDATEN VAR ziel, ARTIKELDATEN CONST quelle):{}  CONCR (ziel) := CONCR (quelle){}END OP :=;{}OP := (KUNDENDATEN VAR ziel, KUNDENDATEN CONST quelle):{}  CONCR (ziel) := CONCR (quelle){}
+END OP :=;{}PROC init ds:{}  forget (ds); ds := nilspace{}END PROC init ds;{}(************************************************************************){}PROC initialisiere verwaltung:{}  hauptstelle := hauptstellenname;{}  zentrale := task (hauptstelle + ".Zentrale");{}  filialnummer := text (channel (myself));{}  filialverwaltungsname := hauptstellenname + ".Filialverwaltung ";{}  begin (filialverwaltungsname + filialnummer,{}         PROC filialverwaltung, verwaltung){}END PROC initialisiere verwaltung;{}
+PROC hole artikeldaten (INT  CONST artikelnummer,{}                        TEXT VAR name,  REAL VAR preis,{}                        INT  VAR mindestbestand, bestand):{}  enable stop;{}  pruefe artikelnummer;{}  hole daten.{}  pruefe artikelnummer:{}    INT CONST artikelindex :: artikelnummer - min artikelnr + 1;{}    IF artikelindex < 1  OR  artikelindex > max artikel{}       THEN errorstop ("Unzulässige Artikelnummer!"){}    FI.{}  hole daten:{}    name           := artikel [artikelindex].artikelname;{}
+    preis          := artikel [artikelindex].preis;{}    mindestbestand := artikel [artikelindex].mindestbestand;{}    bestand        := artikel [artikelindex].bestand.{}END PROC hole artikeldaten;{}PROC speichere artikeldaten (INT  CONST artikelnummer,{}                             TEXT CONST name, REAL CONST preis,{}                             INT  CONST mindestbestand, bestand):{}  enable stop;{}  pruefe artikelnummer;{}  speichere daten;{}  schicke kopie an verwaltung.{}  pruefe artikelnummer:{}
+    INT CONST artikelindex :: artikelnummer - min artikelnr + 1;{}    IF artikelindex < 1  OR  artikelindex > max artikel{}       THEN errorstop ("Unzulässige Artikelnummer!"){}    FI.{}  speichere daten:{}    artikel [artikelindex].artikelname   := name;{}    artikel [artikelindex].preis         := preis;{}    artikel [artikelindex].mindestbestand:= mindestbestand;{}    artikel [artikelindex].bestand       := bestand.{}  schicke kopie an verwaltung:{}    init ds;{}    BOUND ARTIKELDATEN VAR artikeldaten :: ds;{}
+    artikeldaten := artikel [artikelindex];{}    call (verwaltung, artikelindex, ds, reply code).{}END PROC speichere artikeldaten;{}PROC registriere verkauf (INT CONST kundennummer, artikelnummer):{}  enable stop;{}  pruefe daten;{}  speichere daten;{}  schicke kopie zur verwaltung.{}  pruefe daten:{}    INT VAR kundenindex  :: kundennummer  - min kundennr  + 1,{}            artikelindex :: artikelnummer - min artikelnr + 1;{}    IF   kundenindex < 0  OR  kundenindex > max kunden{}         THEN errorstop ("Unzulässige Kundennummer!"){}
+    ELIF artikelindex < 1  OR  artikelindex > max artikel{}         THEN errorstop ("Unzulässige Artikelnummer!"){}    FI.{}  speichere daten:{}    IF artikel [artikelindex].bestand > 0{}       THEN artikel [artikelindex].bestand DECR 1;{}            verkaufszahl [artikelindex] INCR 1;{}            IF kundenindex > 0{}               THEN trage evtl in einkaufsdatei ein{}    FI      FI.{}  trage evtl in einkaufsdatei ein:{}    IF kunde [kundenindex].nachname = ""{}       THEN kundenindex := 0{}       ELSE einkaufsdatei [kundenindex][artikelindex] INCR 1{}
+    FI.{}  schicke kopie zur verwaltung:{}    init ds;{}    BOUND INT VAR nummer :: ds;{}    nummer := artikelindex;{}    call (verwaltung, kundenindex + min kundennr - 1, ds, reply code).{}END PROC registriere verkauf;{}PROC hole kundendaten (INT  CONST kundennummer,{}                       TEXT VAR   nachname, vorname, geschlecht):{}  enable stop;{}  pruefe kundennummer;{}  rufe zentrale an;{}  uebergib die zentraldaten;{}  IF aenderungen vorhanden{}     THEN aktualisiere filialdaten{}  FI;{}  forget (ds).{}
+  pruefe kundennummer:{}    INT CONST index :: kundennummer - min kundennr + 1;{}    IF index < 1  OR  index > max kunden{}       THEN errorstop ("Unzulässige Kundennummer!"){}    FI.{}  rufe zentrale an:{}    init ds;{}    call (zentrale, kundennummer, ds, reply code).{}  aenderungen vorhanden:{}    (kunde [index].nachname   <> nachname  ) OR{}    (kunde [index].vorname    <> vorname   ) OR{}    (kunde [index].geschlecht <> geschlecht).{}  aktualisiere filialdaten:{}    kunde [index] := daten von zentrale;{}
+    call (verwaltung, kundennummer + max kunden, ds, reply code).{}  uebergib die zentraldaten:{}    BOUND KUNDENDATEN VAR daten von zentrale :: ds;{}    nachname    := daten von zentrale.nachname;{}    vorname     := daten von zentrale.vorname;{}    geschlecht  := daten von zentrale.geschlecht.{}END PROC hole kundendaten;{}PROC speichere kundendaten(INT  CONST kundennummer,{}                           TEXT CONST nachname, vorname, geschlecht):{}  enable stop;{}  pruefe kundennummer;{}  IF kundendaten geaendert{}
+     THEN speichere daten;{}          schicke kopie an verwaltung und zentrale{}  FI.{}  pruefe kundennummer:{}    IF kundennummer < min kundennr  OR  kundennummer > max kundennr{}       THEN errorstop ("Unzulässige Kundennummer!"){}    FI.{}  kundendaten geaendert:{}    INT CONST index :: kundennummer - min kundennr + 1;{}    nachname    <> kunde [index].nachname    OR{}    vorname     <> kunde [index].vorname     OR{}    geschlecht  <> kunde [index].geschlecht.{}  speichere daten:{}    kunde [index].nachname    := nachname;{}
+    kunde [index].vorname     := vorname;{}    kunde [index].geschlecht  := geschlecht.{}  schicke kopie an verwaltung und zentrale:{}    init ds;{}    BOUND KUNDENDATEN VAR kundendaten :: ds;{}    kundendaten := kunde [index];{}    call (verwaltung, kundennummer + max kunden, ds, reply code);{}    call (zentrale, kundennummer - min kundennr + 1, ds, reply code);{}    forget (ds).{}END PROC speichere kundendaten;{}PROC sichere filialdaten (TEXT CONST name):{}  enable stop;{}  filialdaten holen;{}
+  type (ds, 1951);{}  forget (name, quiet);{}  copy (ds, name);{}  forget (ds){}END PROC sichere filialdaten;{}PROC lade filialdaten (TEXT CONST name):{}  enable stop;{}  forget (ds);{}  ds := old (name);{}  IF type (ds) = 1951{}     THEN filialdaten ergaenzen;{}          kopie an verwaltung schicken;{}          kopie der kundendatei an zentrale schicken{}     ELSE errorstop ("'" + name + "' enthält keine Filialdaten!"){}  FI.{}  kopie an verwaltung schicken:{}    call (verwaltung, filialdaten ergaenzen code, ds, reply code).{}
+  kopie der kundendatei an zentrale schicken:{}    BOUND KUNDENDATEI VAR kundendatei :: ds;{}    CONCR (CONCR (kundendatei)) := CONCR (kunde);{}    call (zentrale, zentrale kundendatei ergaenzen code, ds, reply code).{}END PROC lade filialdaten;{}PROC hole bestelliste (FILE VAR f):{}  bereite datei vor;{}  schreibe daten in datei.{}  bereite datei vor:{}    forget("Nachbestellung",quiet);{}    f := sequential file (output, "Nachbestellung");{}    line  (f);{}    write (f, "        Nachbestellungen für " +{}
+                       invers ("Filiale " + filialnummer)+":");{}    line;{}    write (f, "        ==================================================");{}    line  (f, 2);{}    write (f, "        |  Art.Nr. | Artikelname             |   Anzahl  |");{}    line  (f);{}    write (f, "        +----------+-------------------------+-----------+");{}    line  (f).{}  schreibe daten in datei:{}    INT VAR artikelnummer;{}    FOR artikelnummer FROM 1 UPTO max artikel REP{}        IF artikel[artikelnummer].bestand{}
+           < artikel[artikelnummer].mindestbestand{}           THEN bestelle artikel nach{}        FI{}    PER;{}    write (f, "        +----------+-------------------------+-----------+");{}    line  (f).{}   bestelle artikel nach:{}    write (f, "        |  " + wirkliche artikelnummer + "   | "{}              + text (artikel [artikelnummer].artikelname, 23) + " |  "{}              + text (nachzubestellende anzahl, 6) + "   |");{}    line  (f);{}    artikel [artikelnummer].bestand{}                           := 2 * artikel [artikelnummer].mindestbestand.{}
+    wirkliche artikelnummer:{}      text (artikelnummer + min artikelnr - 1, 5).{}    nachzubestellende anzahl:{}      2 * artikel [artikelnummer].mindestbestand{}                                  - artikel [artikelnummer].bestand.{}END PROC hole bestelliste;{}PROC hole auskunft ein (INT CONST codenummer, artikel oder kundennummer,{}                        FILE  VAR f):{}  enable stop;{}  hauptstelle := hauptstellenname;{}  SELECT codenummer OF CASE 66 : hitliste von zentrale (f){}                       CASE 67 : hitliste von filiale (f){}
+                       CASE 68 : hitlisten aller filialen (f){}                    (* --------------------------------------------- *){}                       CASE 73 : artikelkaeuferliste von zentrale{}                                   (artikel oder kundennummer, f){}                       CASE 74 : artikelkaeuferliste von filiale{}                                   (artikel oder kundennummer, f){}                       CASE 75 : artikelkaeuferlisten aller filialen{}                                   (artikel oder kundennummer, f){}
+                    (* --------------------------------------------- *){}                       CASE 77 : kundenliste von zentrale (f){}                       CASE 78 : kundenliste von filiale (f){}                       CASE 79 : kundenlisten aller filialen (f){}                    (* --------------------------------------------- *){}                       CASE 84 : kundeneinkaufsliste von zentrale{}                                   (artikel oder kundennummer, f){}                       CASE 85 : kundeneinkaufsliste von filiale{}
+                                   (artikel oder kundennummer, f){}                       CASE 86 : kundeneinkaufslisten aller filialen{}                                   (artikel oder kundennummer, f){}                    (* --------------------------------------------- *){}                       CASE 89 : lageruebersicht von zentrale (f){}                       CASE 90 : lageruebersicht von filiale (f){}                       CASE 91 : lageruebersichten aller filialen (f){}                    (* --------------------------------------------- *){}
+  OTHERWISE  errorstop ("Unzulässige Code - Nummer bei Auskunft!"){}  END SELECT{}END PROC hole auskunft ein;{}PROC hitliste von zentrale (FILE VAR f):{}  INT VAR filialnr;{}  beginne mit eigener filiale;{}  FOR filialnr FROM 1 UPTO max filialen REP{}    TEXT CONST aktuelle verwaltung ::{}               hauptstelle + ".Filialverwaltung " + text (filialnr);{}    IF filialnr <> int (filialnummer) CAND{}       exists task (aktuelle verwaltung){}       THEN hole daten dieser filiale;{}            schreibe daten in zentralliste{}
+    FI{}  PER;{}  werte zentralliste aus.{}  beginne mit eigener filiale:{}    WARENDATEI VAR zentrale warendatei;{}    CONCR (zentrale warendatei) := CONCR (artikel);{}    VERKAUFSDATEI VAR zentrale verkaufsdatei;{}    CONCR (zentrale verkaufsdatei) := CONCR (verkaufszahl).{}   hole daten dieser filiale:{}     init ds;{}     call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{}     BOUND FILIALDATEN VAR aktuelle daten :: ds.{}   schreibe daten in zentralliste:{}     INT VAR i;{}
+     FOR i FROM 1 UPTO max artikel REP{}       IF zentrale warendatei [i].artikelname = ""{}          THEN zentrale warendatei [i] := aktuelle daten.waren [i]{}       FI;{}       zentrale verkaufsdatei [i] INCR aktuelle daten.hitliste [i]{}     PER.{}  werte zentralliste aus:{}    forget (ds);{}    forget ("Auskunft: Zentrale", quiet);{}    f := sequential file (output, "Auskunft: Zentrale");{}    line  (f);{}    write (f, "   Zentrale Warenliste, geordnet nach Verkaufszahlen:");{}    sortiere (zentrale warendatei, zentrale verkaufsdatei);{}
+    fuelle (f, zentrale warendatei, zentrale verkaufsdatei).{}END PROC hitliste von zentrale;{}PROC hitliste von filiale (FILE VAR f):{}  bereite auskunftsdatei vor;{}  kopiere artikeldatei und verkaufsdatei;{}  sortiere (hilfsdatei artikel, hilfsdatei verkaufszahlen);{}  fuelle (f,hilfsdatei artikel, hilfsdatei verkaufszahlen).{}  kopiere artikeldatei und verkaufsdatei:{}    WARENDATEI VAR hilfsdatei artikel;{}    CONCR (hilfsdatei artikel) := CONCR (artikel);{}    VERKAUFSDATEI VAR hilfsdatei verkaufszahlen;{}
+    CONCR (hilfsdatei verkaufszahlen) := CONCR (verkaufszahl).{}  bereite auskunftsdatei vor:{}    forget ("Auskunft: Filiale " + filialnummer, quiet);{}    f := sequential file (output, "Auskunft: Filiale " + filialnummer);{}    line  (f);{}    write (f, "   Warenliste, geordnet nach Verkaufszahlen:").{}END PROC hitliste von filiale;{}PROC hitlisten aller filialen (FILE VAR f):{}  WARENDATEI    VAR aktuelle warendatei;{}  VERKAUFSDATEI VAR aktuelle verkaufsdatei;{}  INT           VAR filialnr;{}
+  bereite auskunftsdatei vor;{}  FOR filialnr FROM 1 UPTO max filialen REP{}    TEXT CONST aktuelle verwaltung ::{}               hauptstelle + ".Filialverwaltung " + text (filialnr);{}    IF   filialnr = int (filialnummer){}         THEN nimm eigene daten{}    ELIF exists task (aktuelle verwaltung){}    THEN hole daten dieser filiale;{}         arbeite mit diesen daten{}    FI{}  PER;{}  forget (ds).{}  bereite auskunftsdatei vor:{}    forget ("Auskunft: Alle Filialen", quiet);{}    f := sequential file (output, "Auskunft: Alle Filialen");{}
+    line  (f).{}  nimm eigene daten:{}    CONCR (aktuelle warendatei) := CONCR (artikel);{}    CONCR (aktuelle verkaufsdatei) := CONCR (verkaufszahl);{}    sortiere und fuelle.{}  sortiere und fuelle:{}    write (f, "   Warenliste von " + invers ("Filiale " + text (filialnr)){}            + ", geordnet nach Verkaufszahlen:");{}    sortiere (aktuelle warendatei, aktuelle verkaufsdatei);{}    fuelle (f,aktuelle warendatei, aktuelle verkaufsdatei).{}   hole daten dieser filiale:{}     init ds;{}     call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{}
+     BOUND FILIALDATEN VAR aktuelle daten :: ds.{}   arbeite mit diesen daten:{}    CONCR (aktuelle warendatei) := CONCR (aktuelle daten.waren);{}    CONCR (aktuelle verkaufsdatei) := CONCR (aktuelle daten.hitliste);{}    sortiere und fuelle.{}END PROC hitlisten aller filialen;{}PROC sortiere (WARENDATEI VAR warendatei, VERKAUFSDATEI VAR stueckzahl):{}  INT VAR i,j;{}  FOR i FROM 1 UPTO max artikel - 1 REP{}    FOR j FROM i + 1 UPTO max artikel REP{}      IF stueckzahl [i] < stueckzahl [j]{}         THEN vertausche{}
+      FI{}  PER PER.{}  vertausche:{}    INT CONST hilfsint :: stueckzahl [i];{}    ARTIKELDATEN CONST hilfsartikel :: warendatei [i];{}    stueckzahl [i] := stueckzahl [j];{}    warendatei [i] := warendatei [j];{}    stueckzahl [j] := hilfsint;{}    warendatei [j] := hilfsartikel.{}END PROC sortiere;{}PROC fuelle (FILE VAR f, WARENDATEI VAR warendat, VERKAUFSDATEI VAR anzahl):{}  INT VAR nummer, platz :: 0;{}  bereite datei vor;{}  schreibe daten in datei.{}bereite datei vor:{} line (f);{} write(f,"   ============================================================");{}
+ line (f,2);{} write(f,"   | Platz | Verk.Anzahl | Artikelname            |   Preis   |");{} line (f);{} write(f,"   +-------+-------------+------------------------+-----------+");{} line (f).{}schreibe daten in datei:{} FOR nummer FROM 1 UPTO max artikel REP{}     IF warendat [nummer].artikelname <> ""{}        THEN schreibe in datei; line (f){}     FI{} PER;{} write(f,"   +-------+-------------+------------------------+-----------+");{} line (f,3).{}schreibe in datei:{}  platz INCR 1;{}  write (f, "   |" + text (platz, 5) + "  |"{}
+                   + text (anzahl [nummer], 9) + "    | "{}                   + text (warendat [nummer].artikelname, 22) + " | "{}                   + text (warendat [nummer].preis,8,2) + "  |").{}END PROC fuelle;{}PROC artikelkaeuferliste von zentrale (INT CONST artikelnummer, FILE VAR f):{}  INT VAR filialnr;{}  pruefe artikelnummer;{}  beginne mit eigener filiale;{}  FOR filialnr FROM 1 UPTO max filialen REP{}    TEXT CONST aktuelle verwaltung ::{}               hauptstelle + ".Filialverwaltung " + text (filialnr);{}
+    IF filialnr <> int (filialnummer) CAND{}       exists task (aktuelle verwaltung){}       THEN hole daten dieser filiale;{}            schreibe daten in zentralliste{}    FI{}  PER;{}  werte zentralliste aus.{}  pruefe artikelnummer:{}    INT CONST artikelindex :: artikelnummer - min artikelnr + 1;{}    IF artikelindex < 1  OR  artikelindex > max artikel{}       THEN errorstop ("Unzulässige Artikelnummer!"){}    FI.{}  beginne mit eigener filiale:{}    TEXT VAR aktueller artikelname :: artikel [artikelindex].artikelname;{}
+    KUNDENDATEI VAR hilfsdatei;{}    CONCR (hilfsdatei) := CONCR (kunde);{}    ROW max kunden INT VAR kaeufe;{}    INT VAR i;{}    FOR i FROM 1 UPTO max kunden REP{}        kaeufe [i] := einkaufsdatei [i][artikelindex]{}    PER.{}   hole daten dieser filiale:{}     init ds;{}     call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code).{}   schreibe daten in zentralliste:{}     BOUND FILIALDATEN VAR aktuelle daten :: ds;{}     IF aktueller artikelname = ""{}        THEN aktueller artikelname{}
+             := aktuelle daten.waren [artikelindex].artikelname{}     FI;{}     FOR i FROM 1 UPTO max kunden REP{}       kaeufe [i] INCR aktuelle daten.einkaeufe [i][artikelindex];{}       IF hilfsdatei [i].nachname = ""{}          THEN hilfsdatei [i] := aktuelle daten.kunden [i]{}       FI{}     PER.{}  werte zentralliste aus:{}    forget (ds);{}    forget ("Auskunft: Zentrale", quiet);{}    f := sequential file (output, "Auskunft: Zentrale");{}    line (f);{}    IF aktueller artikelname = ""{}       THEN write (f, "   Der Artikel Nr. " + text (artikelindex){}
+                      +  " wird in keiner Filiale geführt.");{}            line (f);{}            write(f,{}        "   ============================================================");{}            line (f,3);{}       ELSE write (f, "   Gesamtkäuferliste des Artikels "{}                       +  invers (aktueller artikelname) + ":");{}            fuelle (f, hilfsdatei, kaeufe){}    FI.{}END PROC artikelkaeuferliste von zentrale;{}PROC artikelkaeuferliste von filiale (INT CONST artikelnummer, FILE VAR f):{}
+  pruefe artikelnummer;{}  kopiere einkaufszahlen in hilfsliste;{}  erstelle filialliste.{}  pruefe artikelnummer:{}    INT CONST artikelindex :: artikelnummer - min artikelnr + 1;{}    IF artikelindex < 1  OR  artikelindex > max artikel{}       THEN errorstop ("Unzulässige Artikelnummer!"){}    FI.{}  kopiere einkaufszahlen in hilfsliste:{}    ROW max kunden INT VAR kaeufe;{}    INT VAR i;{}    FOR i FROM 1 UPTO max kunden REP{}        kaeufe [i] := einkaufsdatei [i][artikelindex]{}    PER.{}  erstelle filialliste:{}
+    forget ("Auskunft: Filiale " + filialnummer, quiet);{}    f := sequential file (output, "Auskunft: Filiale " + filialnummer);{}    line (f);{}    IF artikel [artikelindex].artikelname = ""{}       THEN write (f, "   Der Artikel Nr. " + text (artikelindex){}                   +  " wird in dieser Filiale nicht geführt.");{}            line (f);{}            write(f,{}        "   ============================================================");{}            line (f,3);{}       ELSE write (f, "   Käufer des Artikels "{}
+                   +  invers (artikel [artikelindex].artikelname){}                   +  ":");{}            fuelle (f, kunde, kaeufe){}    FI.{}END PROC artikelkaeuferliste von filiale;{}PROC artikelkaeuferlisten aller filialen(INT CONST artikelnummer,FILE VAR f):{}  INT VAR i, filialnr;{}  ROW max kunden INT VAR kaeufe;{}  pruefe artikelnummer;{}  bereite datei vor;{}  FOR filialnr FROM 1 UPTO max filialen REP{}    TEXT CONST aktuelle verwaltung ::{}               hauptstelle + ".Filialverwaltung " + text (filialnr);{}
+    IF   filialnr = int (filialnummer){}         THEN kopiere eigene einkaufszahlen in hilfsliste;{}              schreibe eigene daten in auskunftsdatei{}    ELIF exists task (aktuelle verwaltung){}         THEN hole daten dieser filiale;{}              schreibe daten in auskunftsdatei{}    FI{}  PER;{}  forget (ds).{}  pruefe artikelnummer:{}    INT CONST artikelindex :: artikelnummer - min artikelnr + 1;{}    IF artikelindex < 1  OR  artikelindex > max artikel{}       THEN errorstop ("Unzulässige Artikelnummer!"){}
+    FI.{}  bereite datei vor:{}    forget ("Auskunft: Alle Filialen", quiet);{}    f := sequential file (output, "Auskunft: Alle Filialen");{}    line (f).{}  kopiere eigene einkaufszahlen in hilfsliste:{}    FOR i FROM 1 UPTO max kunden REP{}        kaeufe [i] := einkaufsdatei [i][artikelindex]{}    PER.{}  schreibe eigene daten in auskunftsdatei:{}    IF artikel [artikelindex].artikelname = ""{}       THEN write (f, "   Der Artikel Nr. " + text (artikelindex){}                   +  " wird in "{}
+                   +    invers ("Filiale " + filialnummer){}                   +  " nicht geführt.");{}            line (f);{}            write(f,{}        "   ============================================================");{}            line (f,3){}       ELSE write (f, "   Käufer des Artikels '"{}                   +  artikel [artikelindex].artikelname{}                   +  "' in " + invers ("Filiale " + filialnummer) + ":");{}            fuelle(f, kunde, kaeufe){}    FI.{}   hole daten dieser filiale:{}
+     init ds;{}     call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{}     BOUND FILIALDATEN VAR aktuelle daten :: ds;{}     TEXT CONST aktueller artikelname{}                := aktuelle daten.waren [artikelindex].artikelname{}     FOR i FROM 1 UPTO max kunden REP{}       kaeufe [i] := aktuelle daten.einkaeufe [i][artikelindex];{}     PER.{}  schreibe daten in auskunftsdatei:{}    IF aktueller artikelname = ""{}       THEN write (f, "   Der Artikel Nr. " + text (artikelindex){}
+                   +  " wird in "{}                   +    invers ("Filiale " + text (filialnr)){}                   +  " nicht geführt.");{}            line (f);{}            write(f,{}        "   ============================================================");{}            line (f,3){}       ELSE write (f, "   Käufer des Artikels '"{}                   +  aktueller artikelname{}                   +  "' in " + invers ("Filiale " + text(filialnr)) + ":");{}            fuelle(f, aktuelle daten.kunden, kaeufe){}
+    FI.{}END PROC artikelkaeuferlisten aller filialen;{}PROC fuelle (FILE VAR f, KUNDENDATEI CONST  kundenliste,{}                         ROW max kunden INT CONST einkaufszahlen):{}  INT VAR kundennummer;{}  bereite datei vor;{}  schreibe daten in datei.{}bereite datei vor:{} line (f);{} write(f,"   ============================================================");{} line (f, 2);{} write(f,"   | Anzahl | Nachname,         Vorname          | Geschlecht |");{} line (f);{} write(f,"   +--------+------------------------------------+------------+");{}
+ line (f).{}schreibe daten in datei:{} FOR kundennummer FROM 1 UPTO max kunden REP{}     IF  einkaufszahlen [kundennummer] > 0{}         THEN schreibe in  datei; line (f);{}     FI{} PER;{} write(f,"   +--------+------------------------------------+------------+");{} line (f, 3).{}schreibe in datei:{} write(f,"   |" + text(einkaufszahlen [kundennummer], 5) + "   | "{}                + text(kundenliste [kundennummer].nachname + ",", 17) + " "{}                + text(kundenliste [kundennummer].vorname, 16) + " | ");{}
+ IF   kundenliste [kundennummer].geschlecht = "m"{}      THEN write (f, " männlich  |"){} ELIF kundenliste [kundennummer].geschlecht = "w"{}      THEN write (f, " weiblich  |"){}      ELSE write (f, "           |"){} FI.{}END PROC fuelle;{}PROC kundenliste von zentrale (FILE VAR f):{}  hole kundenliste von zentrale;{}  bereite datei vor;{}  schreibe daten in datei.{}  hole kundenliste von zentrale:{}    init ds;{}    call (zentrale, zentrale kundendatei holen code, ds, reply code);{}    BOUND KUNDENDATEI VAR zentrale kundenliste :: ds.{}
+  bereite datei vor:{}   forget ("Auskunft: Zentrale", quiet);{}   f := sequential file (output, "Auskunft: Zentrale");{}   line  (f);{}   write (f, "   Zentrale Kundenliste:").{}  schreibe daten in datei:{}    fuelle (f, zentrale kundenliste);{}    forget (ds).{}END PROC kundenliste von zentrale;{}PROC kundenliste von filiale (FILE VAR f):{}  bereite datei vor;{}  schreibe daten in datei.{}  bereite datei vor:{}    forget ("Auskunft: Filiale " + filialnummer, quiet);{}    f := sequential file (output, "Auskunft: Filiale " + filialnummer);{}
+    line  (f);{}    write (f,"   Kundenliste:").{}  schreibe daten in datei:{}    fuelle (f, kunde).{}END PROC kundenliste von filiale;{}PROC kundenlisten aller filialen (FILE VAR f):{}  INT VAR filialnr;{}  bereite datei vor;{}  FOR filialnr FROM 1 UPTO max filialen REP{}    TEXT CONST aktuelle verwaltung ::{}               hauptstelle + ".Filialverwaltung " + text (filialnr);{}    IF   filialnr = int (filialnummer){}         THEN schreibe eigene daten in auskunftsdatei{}    ELIF exists task (aktuelle verwaltung){}
+         THEN hole daten dieser filiale;{}              schreibe daten dieser filiale in auskunftsdatei{}    FI{}  PER.{}  bereite datei vor:{}    forget ("Auskunft: Alle Filialen", quiet);{}    f := sequential file (output, "Auskunft: Alle Filialen");{}    line (f).{}  schreibe eigene daten in auskunftsdatei:{}    schreibe ueberschrift;{}    fuelle (f, kunde).{}  hole daten dieser filiale:{}    init ds;{}    call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{}    BOUND FILIALDATEN VAR aktuelle filialdaten :: ds.{}
+  schreibe daten dieser filiale in auskunftsdatei:{}    schreibe ueberschrift;{}    fuelle (f, aktuelle filialdaten.kunden).{}  schreibe ueberschrift:{}   write (f, "   Kundenliste für " +{}                 invers ("Filiale " + text (filialnr)) + ":").{}END PROC kundenlisten aller filialen;{}PROC fuelle (FILE VAR f, KUNDENDATEI VAR kundendatei):{}  INT VAR kundennummer;{}  bereite datei vor;{}  schreibe daten in datei.{}bereite datei vor:{} line (f);{} write(f,"   ============================================================");{}
+ line (f,2);{} write(f,"   | Kun.Nr.| Nachname,         Vorname          | Geschlecht |");{} line (f);{} write(f,"   +--------+------------------------------------+------------+");{} line (f).{}schreibe daten in datei:{} FOR kundennummer FROM 1 UPTO max kunden REP{}     IF kundendatei [kundennummer].nachname <> ""{}        THEN schreibe in datei; line (f){}     FI{} PER;{} write(f,"   +--------+------------------------------------+------------+");{} line (f, 3).{}schreibe in datei:{}  write (f, "   |" + text (kundennummer + min kundennummer - 1, 6) + "  | "{}
+            + text (kundendatei [kundennummer].nachname + ",", 17) + " "{}            + text (kundendatei [kundennummer].vorname, 16) + " | ");{}    IF   kundendatei [kundennummer].geschlecht = "m"{}         THEN write (f, " männlich  |"){}    ELIF kundendatei [kundennummer].geschlecht = "w"{}         THEN write (f, " weiblich  |"){}         ELSE write (f, "           |"){}    FI.{}END PROC fuelle;{}PROC kundeneinkaufsliste von zentrale (INT CONST kundennummer, FILE VAR f):{}  INT VAR filialnr;{}
+  pruefe kundennummer;{}  beginne mit eigener filiale;{}  FOR filialnr FROM 1 UPTO max filialen REP{}    TEXT CONST aktuelle verwaltung ::{}               hauptstelle + ".Filialverwaltung " + text (filialnr);{}    IF filialnr <> int (filialnummer) CAND{}       exists task (aktuelle verwaltung){}       THEN hole daten dieser filiale;{}            schreibe daten in zentralliste{}    FI{}  PER;{}  werte zentralliste aus.{}  pruefe kundennummer:{}    INT CONST kundenindex :: kundennummer - min kundennr + 1;{}
+    IF kundenindex < 1  OR  kundenindex > max kunden{}       THEN errorstop ("Unzulässige Kundennummer!"){}    FI.{}  beginne mit eigener filiale:{}    KUNDENDATEN VAR aktueller kunde :: kunde [kundenindex];{}    WARENDATEI VAR hilfsdatei;{}    CONCR (hilfsdatei) := CONCR (artikel);{}    ROW max artikel INT VAR kaeufe;{}    INT VAR i;{}    FOR i FROM 1 UPTO max artikel REP{}        kaeufe [i] := einkaufsdatei [kundenindex][i]{}    PER.{}   hole daten dieser filiale:{}     init ds;{}     call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code).{}
+   schreibe daten in zentralliste:{}     BOUND FILIALDATEN VAR aktuelle daten :: ds;{}     IF aktueller kunde.nachname = ""{}        THEN aktueller kunde := aktuelle daten.kunden [kundenindex]{}     FI;{}     FOR i FROM 1 UPTO max artikel REP{}       kaeufe [i] INCR aktuelle daten.einkaeufe [kundenindex][i];{}       IF hilfsdatei [i].artikelname = ""{}          THEN hilfsdatei [i] := aktuelle daten.waren [i]{}       FI{}     PER.{}  werte zentralliste aus:{}    forget (ds);{}    forget ("Auskunft: Zentrale", quiet);{}
+    f := sequential file (output, "Auskunft: Zentrale");{}    line (f);{}    IF aktueller kunde.nachname = ""{}       THEN write (f, "   Ein Kunde mit Nr. " + text (kundenindex){}                   +  " ist in keiner Filiale bekannt.");{}            line (f);{}            write(f,{}        "   ============================================================");{}            line (f,3);{}       ELSE write (f, "   Gesamteinkaufsliste " + anrede{}                       +  invers (aktueller kundenname) + ":");{}
+            fuelle (f, hilfsdatei, kaeufe){}    FI.{}  anrede:{}    IF   aktueller kunde.geschlecht = "m"{}         THEN "des Kunden "{}    ELIF aktueller kunde.geschlecht = "w"{}         THEN "der Kundin "{}         ELSE "von "{}    FI.{}  aktueller kundenname:{}    (aktueller kunde.vorname SUB 1) + ". " + aktueller kunde.nachname.{}END PROC kundeneinkaufsliste von zentrale;{}PROC kundeneinkaufsliste von filiale (INT CONST kundennummer, FILE VAR f):{}  pruefe kundennummer;{}  erstelle filialliste.{}
+  pruefe kundennummer:{}    INT CONST kundenindex :: kundennummer - min kundennr + 1;{}    IF kundenindex < 1  OR  kundenindex > max kunden{}       THEN errorstop ("Unzulässige Kundennummer!"){}    FI.{}  erstelle filialliste:{}    forget ("Auskunft: Filiale " + filialnummer, quiet);{}    f := sequential file (output, "Auskunft: Filiale " + filialnummer);{}    line (f);{}    IF kunde [kundenindex].nachname = ""{}       THEN schicke leere liste zurueck{}       ELSE schreibe dateikopf;{}            fuelle (f, artikel, einkaufsdatei [kundenindex]){}
+    FI.{}  schicke leere liste zurueck:{}    write (f,"   Ein Kunde mit Nr. " + text (kundennummer) + " ist in "{}           +  "dieser Filiale nicht bekannt.");{}    line  (f);{}    write (f,{}      "   ============================================================");{}    line (f,3).{}  schreibe dateikopf:{}   write (f, "   Einkaufsliste " + anrede +{}                 invers ((kunde [kundenindex].vorname  SUB 1) + ". " +{}                  kunde [kundenindex].nachname) + ":").{}  anrede:{}    IF   kunde [kundenindex].geschlecht = "m"{}
+         THEN "des Kunden "{}    ELIF kunde [kundenindex].geschlecht = "w"{}         THEN "der Kundin "{}         ELSE "von "{}    FI.{}END PROC kundeneinkaufsliste von filiale;{}PROC kundeneinkaufslisten aller filialen (INT CONST kundennummer,FILE VAR f):{}  INT VAR filialnr;{}  pruefe kundennummer;{}  bereite datei vor;{}  FOR filialnr FROM 1 UPTO max filialen REP{}    TEXT CONST aktuelle verwaltung ::{}               hauptstelle + ".Filialverwaltung " + text (filialnr);{}    IF   filialnr = int (filialnummer){}
+         THEN schreibe eigene daten in auskunftsdatei{}    ELIF exists task (aktuelle verwaltung){}         THEN hole daten dieser filiale;{}              schreibe daten in auskunftsdatei{}    FI{}  PER;{}  forget (ds).{}  pruefe kundennummer:{}    INT CONST kundenindex :: kundennummer - min kundennr + 1;{}    IF kundenindex < 1  OR  kundenindex > max kunden{}       THEN errorstop ("Unzulässige Kundennummer!"){}    FI.{}  bereite datei vor:{}    forget ("Auskunft: Alle Filialen", quiet);{}    f := sequential file (output, "Auskunft: Alle Filialen");{}
+    line (f).{}  schreibe eigene daten in auskunftsdatei:{}    IF kunde [kundenindex].nachname = ""{}       THEN write (f,"   Ein Kunde mit Nr. " + text (kundennummer){}                   + " ist in " + invers ("Filiale " + filialnummer){}                   + " nicht bekannt.");{}            line  (f);{}            write(f,{}        "   ============================================================");{}            line (f,3){}       ELSE write (f, "   Einkaufsliste " + anrede hier +{}                  (kunde [kundenindex].vorname  SUB 1) + ". " +{}
+                   kunde [kundenindex].nachname +{}                  " in " + invers ("Filiale " + filialnummer) + ":");{}            fuelle (f, artikel, einkaufsdatei [kundenindex]){}    FI.{}  anrede hier:{}    IF   kunde [kundenindex].geschlecht = "m"{}         THEN "des Kunden "{}    ELIF kunde [kundenindex].geschlecht = "w"{}         THEN "der Kundin "{}         ELSE "von "{}    FI.{}  hole daten dieser filiale:{}    init ds;{}    call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{}
+    BOUND FILIALDATEN VAR aktuelle daten :: ds;{}    KUNDENDATEN CONST aktueller kunde := aktuelle daten.kunden [kundenindex].{}  schreibe daten in auskunftsdatei:{}    IF aktueller kunde.nachname = ""{}       THEN write (f,"   Ein Kunde mit Nr. " + text (kundennummer){}                   + " ist in " + invers ("Filiale " + text (filialnr)){}                   + " nicht bekannt.");{}            line  (f);{}            write(f,{}        "   ============================================================");{}
+            line (f,3){}       ELSE write (f, "   Einkaufsliste " + anrede +{}                  (aktueller kunde.vorname  SUB 1) + ". " +{}                   aktueller kunde.nachname +{}                  " in " + invers ("Filiale " + text (filialnr)) + ":");{}            fuelle (f, aktuelle daten.waren,{}                       aktuelle daten.einkaeufe [kundenindex]){}     FI.{}  anrede:{}    IF   aktueller kunde.geschlecht = "m"{}         THEN "des Kunden "{}    ELIF aktueller kunde.geschlecht = "w"{}
+         THEN "der Kundin "{}         ELSE "von "{}    FI.{}END PROC kundeneinkaufslisten aller filialen;{}PROC fuelle (FILE VAR f, WARENDATEI CONST warendatei,{}             ROW max artikel INT CONST einkaufszahlen):{}  INT VAR  artikelnummer;{}  REAL VAR gesamtpreis, summe :: 0.0;{}  bereite datei vor;{}  schreibe daten in datei.{}bereite datei vor:{} line (f);{} write(f,"   ============================================================");{} line (f,2);{} write(f,"   | Art.Nr.| Artikelname       | Anzahl |  Preis  |  Gesamt  |");{}
+ line (f);{} write(f,"   +--------+-------------------+--------+---------+----------+");{} line (f).{}schreibe daten in datei:{} FOR artikelnummer FROM 1 UPTO max artikel REP{}     IF einkaufszahlen [artikelnummer] > 0{}        THEN schreibe in datei; line (f){}     FI{} PER;{} write(f,"   +--------+-------------------+--------+---------+----------+");{} line (f);{} write(f,"                                           Summe:   " +{}                                                     text (summe,8,2));{}
+ line (f, 3).{}schreibe in datei:{}  gesamtpreis := real (einkaufszahlen [artikelnummer]) *{}                       warendatei [artikelnummer].preis;{}  summe INCR gesamtpreis;{}  write (f,"   |" + text(artikelnummer,5) + "   | "{}                  + text(warendatei [artikelnummer].artikelname,17) + " |  "{}                  + text(einkaufszahlen [artikelnummer],4) + "  |"{}                  + text(warendatei [artikelnummer].preis,7,2) + "  |"{}                  + text(gesamtpreis,8,2) + "  |").{}
+END PROC fuelle;{}PROC lageruebersicht von zentrale (FILE VAR f):{}  INT VAR filialnr;{}  beginne mit eigener filiale;{}  FOR filialnr FROM 1 UPTO max filialen REP{}    TEXT CONST aktuelle verwaltung ::{}               hauptstelle + ".Filialverwaltung " + text (filialnr);{}    IF filialnr <> int (filialnummer) CAND{}       exists task (aktuelle verwaltung){}       THEN hole daten dieser filiale;{}            schreibe daten in zentralliste{}    FI{}  PER;{}  werte zentralliste aus.{}  beginne mit eigener filiale:{}
+    WARENDATEI VAR hilfsdatei;{}    CONCR (hilfsdatei) := CONCR (artikel).{}   hole daten dieser filiale:{}     init ds;{}     call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code).{}   schreibe daten in zentralliste:{}     BOUND FILIALDATEN VAR aktuelle daten :: ds;{}     INT VAR i;{}     FOR i FROM 1 UPTO max artikel REP{}       IF hilfsdatei [i].artikelname = ""{}          THEN hilfsdatei [i] := aktuelle daten.waren [i]{}          ELSE hilfsdatei [i].mindestbestand INCR aktuell.mindestbestand;{}
+               hilfsdatei [i].bestand INCR aktuell.bestand{}       FI{}     PER.{}  aktuell: aktuelle daten.waren [i].{}  werte zentralliste aus:{}    forget (ds);{}    forget ("Auskunft: Zentrale", quiet);{}    f := sequential file (output, "Auskunft: Zentrale");{}    line  (f);{}    write (f, "   Zentrale Lagerübersicht:");{}    fuelle (f, hilfsdatei).{}END PROC lageruebersicht von zentrale;{}PROC lageruebersicht von filiale (FILE VAR f):{}  forget ("Auskunft: Filiale " + filialnummer, quiet);{}
+  f := sequential file (output, "Auskunft: Filiale " + filialnummer);{}  schreibe dateikopf;{}  fuelle (f, artikel).{}  schreibe dateikopf:{}   line  (f);{}   write (f, "   Lagerübersicht:").{}END PROC lageruebersicht von filiale;{}PROC lageruebersichten aller filialen (FILE VAR f):{}  INT VAR filialnr;{}  bereite datei vor;{}  FOR filialnr FROM 1 UPTO max filialen REP{}    TEXT CONST aktuelle verwaltung ::{}               hauptstelle + ".Filialverwaltung " + text (filialnr);{}    IF   filialnr = int (filialnummer){}
+         THEN schreibe eigene daten in auskunftsdatei{}    ELIF exists task (aktuelle verwaltung){}         THEN hole daten dieser filiale;{}              schreibe daten in auskunftsdatei{}    FI{}  PER;{}  forget (ds).{}  bereite datei vor:{}    forget ("Auskunft: Alle Filialen", quiet);{}    f := sequential file (output, "Auskunft: Alle Filialen").{}  schreibe eigene daten in auskunftsdatei:{}    line   (f);{}    write  (f, "   Lagerübersicht für " +{}                   invers ("Filiale " + filialnummer) + ":");{}
+    fuelle (f, artikel).{}  hole daten dieser filiale:{}    init ds;{}    call (task(aktuelle verwaltung), filialdaten holen code, ds, reply code);{}    BOUND FILIALDATEN VAR aktuelle daten :: ds.{}  schreibe daten in auskunftsdatei:{}    line   (f);{}    write  (f, "   Lagerübersicht für " +{}                  invers ("Filiale " + text (filialnr)) + ":");{}    fuelle (f, aktuelle daten.waren).{}END PROC lageruebersichten aller filialen;{}PROC fuelle (FILE VAR f, WARENDATEI CONST warendatei):{}  INT VAR artikelnummer;{}
+  bereite datei vor;{}  schreibe daten in datei.{}bereite datei vor:{} line (f);{} write(f,"   ============================================================");{} line (f,2);{} write(f,"   | Art.Nr.| Artikelname       |  Preis | Min.Best.| Bestand |");{} line (f);{} write(f,"   +--------+-------------------+--------+----------+---------+");{} line (f).{}schreibe daten in datei:{} FOR artikelnummer FROM 1 UPTO max artikel REP{}     IF warendatei[artikelnummer].artikelname <> ""{}        THEN schreibe in datei; line (f){}
+     FI{} PER;{} write(f,"   +--------+-------------------+--------+----------+---------+");{} line (f, 3).{}schreibe in datei:{}  write (f, "   |" + text(artikelnummer,5) + "   | "{}                   + text(warendatei[artikelnummer].artikelname,17) + " |"{}                   + text(warendatei[artikelnummer].preis,7,2) + " | "{}                   + text(warendatei[artikelnummer].mindestbestand,6)+"   | "{}                   + text(warendatei[artikelnummer].bestand,6) + "  |").{}END PROC fuelle;{}
+PROC initialisiere dateien:{}  INT VAR kundennummer, artikelnummer;{}  FOR kundennummer FROM 1 UPTO max kunden REP{}      kunde [kundennummer].nachname    := "";{}      kunde [kundennummer].vorname     := "";{}      kunde [kundennummer].geschlecht  := ""{}  PER;{}  FOR artikelnummer FROM 1 UPTO max artikel REP{}      verkaufszahl [artikelnummer]                   :=   0;{}      artikel      [artikelnummer].mindestbestand    :=   0;{}      artikel      [artikelnummer].bestand           :=   0;{}      artikel      [artikelnummer].artikelname       :=  "";{}
+      artikel      [artikelnummer].preis             := 0.0;{}      FOR kundennummer FROM 1 UPTO max kunden REP{}          einkaufsdatei[kundennummer][artikelnummer] :=   0{}      PER;{}  PER{}END PROC initialisiere dateien;{}initialisiere dateien{}END PACKET ls warenhaus 2{}
+
diff --git a/warenhaus/ls-Warenhaus 3 b/warenhaus/ls-Warenhaus 3
new file mode 100644
index 0000000..3473e0f
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 3	
@@ -0,0 +1,82 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                    ls-Warenhaus 3                    ** 
+         **                                                      ** 
+         **                     Version 1.01                     ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                  (Stand:  30.08.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **           Autor: Bruno Pollok, Bielefeld             ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         **                                                      ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls warenhaus 3 DEFINES                        
+       artikelnummer lesen,{}       artikeldaten eingeben,{}       kundennummer lesen,{}       kundendaten eingeben,{}       neues blatt,{}       rechnungskopf,{}       artikel kaufen,{}       abrechnung,{}       nachbestellen,{}       auskunft,{}       stoptaste gedrueckt,{}       stoptaste gedrückt,{}       dezimalwert lesen,{}       bitmuster lesen,{}       bildschirm neu,{}(* ------------------------------ *){}       tastatureingabe,{}       eingabesicherheit,{}       eingabe mit codekartenleser,{}
+       cursor w3 1 1:{}LET esc            = ""27"",{}    stopzeichen    = "q",{}    abbruchzeichen = "h";{}WINDOW VAR w1  :: window (43,  3, 36, 16),{}           w2  :: window (43, 20, 36,  3),{}           w3k :: window ( 2,  4, 40,  3),{}           w3  :: window ( 2,  7, 40, 16),{}           w4  :: window ( 8,  4, 66, 18);{}BOOL VAR ende gewuenscht              := FALSE,{}         artikelnummer ist eingelesen := FALSE,{}         kundennummer  ist eingelesen := FALSE,{}         codekartenleser aktiviert    := FALSE,{}
+         auf neuem blatt              := TRUE;{}INT  VAR artikelnummer  ::  0,{}         mindestbestand ::  0,{}         bestand        ::  0,{}         kundennummer   ::  0,{}         sicherheit     ::  5;{}TEXT VAR artikelname    :: "",{}         nachname       :: "",{}         vorname        :: "",{}         geschlecht     :: "",{}         ueberschrift   :: "    RECHNUNG",{}         hilfstext, exit char;{}REAL VAR preis          :: 0.0,{}         summe          :: 0.0;{}PROC eingabesicherheit (INT CONST wert):{}
+  sicherheit := abs (wert){}END PROC eingabesicherheit;{}PROC cursor w3 1 1:{}  cursor (w1,  1, 1);{}  cursor (w2,  1, 1);{}  cursor (w3,  1, 1);{}  cursor (w3k, 1, 1);{}  forget ("WARENHAUS:Rechnung", quiet);{}  setze variable in anfangszustand{}END PROC cursor w3 1 1;{}PROC setze variable in anfangszustand:{}  ende gewuenscht              := FALSE;{}  artikelnummer ist eingelesen := FALSE;{}  kundennummer  ist eingelesen := FALSE;{}  artikelnummer  := 0;{}  mindestbestand := 0;{}  bestand        := 0;{}
+  kundennummer   := 0;{}  artikelname    := "";{}  nachname       := "";{}  vorname        := "";{}  geschlecht     := "";{}  ueberschrift   := "    RECHNUNG";{}  preis          := 0.0;{}  summe          := 0.0{}END PROC setze variable in anfangszustand;{}PROC bildschirm neu:{}     cursor off;{}     pruefe abbruch;{}     cursor (w1, 1, 1);{}     cursor (w2, 1, 1);{}     cursor (w3, 1, 1);{}     cursor (w3k,1, 1);{}     auf neuem blatt := TRUE;{}     page;{}     out ("WARENHAUS:  Info  Eingabeart  Kommandos "15"Programme "14" " +{}
+          "Filialdaten  Archiv"); line;{}     out (ecke oben links + (40 * waagerecht) + balken oben{}                          + (36 * waagerecht) + ecke oben rechts);{}     INT VAR zeile;{}     FOR zeile FROM 3 UPTO 22 REP{}         cursor ( 1, zeile); out (senkrecht);{}         cursor (42, zeile); out (senkrecht);{}         cursor (79, zeile); out (senkrecht){}     PER;{}     cursor (1, 23);{}     out (ecke unten links + (40 * waagerecht) + balken unten{}                           + (36 * waagerecht) + ecke unten rechts);{}
+     cursor (42, 19);{}     out (balken links + (36 * waagerecht) + balken rechts);{}     cursor (2, 24);{}     out ("Programmabbruch: <ESC><" + abbruchzeichen + ">");{}     cursor on{}END PROC bildschirm neu;{}PROC pruefe abbruch:{}     IF pressed key = esc{}        THEN pruefe weiter{}     FI.{}     pruefe weiter:{}       TEXT VAR naechstes zeichen :: pressed key (20);{}       IF naechstes zeichen = stopzeichen{}          THEN ende gewuenscht := TRUE{}       ELIF naechstes zeichen = abbruch zeichen{}
+          THEN setze variable in anfangszustand;{}               cursor off;{}               errorstop (1951, "Programm - Abbruch durch <ESC><"{}                               + abbruchzeichen + ">"){}     FI{}END PROC pruefe abbruch;{}PROC regeneriere w2:{}     cursor (42, 19);{}     out (ecke oben links + (36 * waagerecht));{}     INT VAR zeile;{}     FOR zeile FROM 20 UPTO 22 REP{}         cursor (42, zeile); out (senkrecht);{}     PER;{}     cursor (42, 23); out (balken unten);{}     page (w2){}
+END PROC regeneriere w2;{}PROC fenster putzen:{}     page (w1);{}     page (w2){}END PROC fenster putzen;{}PROC lies nummer ein (INT VAR nummer):{}   line (w2, 2);{}   out  (w2, " Stoptaste: <ESC><" + stopzeichen + ">");{}   hilfstext := text (nummer);{}   REP cursor  (w1, 19, 2);{}       editget (w1, hilfstext, 4, 4, "", stopzeichen + abbruchzeichen,{}                                                       exit char);{}       pruefe exit char;{}       change all (hilfstext, " ", ""){}   UNTIL hilfstext >= "0" AND hilfstext <= "9999" PER;{}
+   nummer := int (hilfstext).{}   pruefe exit char:{}     IF exit char = esc + stopzeichen{}        THEN ende gewuenscht := TRUE;{}             cursor off; fenster putzen; cursor on;{}             nummer := 0;{}             LEAVE lies nummer ein{}     ELIF exit char = esc + abbruchzeichen{}        THEN setze variable in anfangszustand;{}             errorstop (1951, "Progamm - Abbruch durch <ESC><"{}                               + abbruchzeichen + ">"){}        ELSE ende gewuenscht := FALSE{}     FI.{}
+END PROC lies nummer ein;{}PROC lies artikelnummer ein:{}     page (w2);{}     cursor (w1, 2, 2);{}     out  (w1, "Artikelnummer  :           ");{}     IF codekartenleser aktiviert{}        THEN artikelnummer := gesicherter wert von interface{}                 (min artikelnummer , max artikelnummer, "Warenkarte"){}        ELSE artikelnummer von tastatur lesen{}     FI;{}     IF ende gewuenscht{}        THEN artikelnummer ist eingelesen := FALSE{}        ELSE artikelnummer ist eingelesen := TRUE{}
+     FI.{}   artikelnummer von tastatur lesen:{}     cursor on;{}     REP out  (w2, " Artikelnummer eingeben");{}         lies nummer ein (artikelnummer);{}     UNTIL ende gewuenscht COR artikelnummer zulaessig PER.{}     artikelnummer zulaessig:{}       IF  (artikelnummer < min artikelnummer OR{}            artikelnummer > max artikelnummer){}           THEN page (w2); out (""7"");{}                out  (w2, " Unzulässige Artikelnummer!");{}                line (w2, 2);{}                out  (w2, " Bitte irgendeine Taste tippen!");{}
+                pause; page (w2);{}                FALSE{}           ELSE TRUE{}       FI.{}END PROC lies artikelnummer ein;{}PROC artikelnummer lesen:{}  pruefe abbruch;{}  lies artikelnummer ein;{}  IF artikelnummer ist eingelesen{}     THEN hole artikeldaten (artikelnummer, artikelname, preis,{}                             mindestbestand, bestand){}  FI{}END PROC artikelnummer lesen;{}PROC kundennummer lesen:{}  pruefe abbruch;{}  lies kundennummer ein;{}  IF kundennummer ist eingelesen{}     THEN hole kundendaten (kundennummer, nachname, vorname, geschlecht){}
+  FI{}END PROC kundennummer lesen;{}PROC lies kundennummer ein:{}  page (w2);{}  cursor (w1, 2, 2);{}  out  (w1, "Kundennummer   :           ");{}  IF codekartenleser aktiviert{}     THEN kundennummer := gesicherter wert von interface{}                       (min kundennummer , max kundennummer, "Kundenkarte"){}     ELSE kundennummer von tastatur lesen{}  FI;{}  IF ende gewuenscht{}     THEN kundennummer ist eingelesen := FALSE{}     ELSE kundennummer ist eingelesen := TRUE{}  FI.{}  kundennummer von tastatur lesen:{}
+    cursor on;{}    REP out  (w2, " Kundennummer eingeben");{}        lies nummer ein (kundennummer){}    UNTIL ende gewuenscht COR kundennummer zulaessig PER.{}  kundennummer zulaessig:{}    IF  (kundennummer < min kundennummer OR{}         kundennummer > max kundennummer){}        THEN page (w2); out (""7"");{}             out  (w2, " Unzulässige Kundennummer!");{}             line (w2, 2);{}             out  (w2, " Bitte irgendeine Taste tippen!");{}             pause; page (w2);{}             FALSE{}
+        ELSE TRUE{}    FI.{}END PROC lies kundennummer ein;{}PROC zeige artikeldaten:{}     cursor (w1, 2, 6);{}     out    (w1, "Artikelname    : " + text (artikelname, 16));{}     cursor (w1, 2, 8);{}     out    (w1, "Preis          : " + text preis + "        ");{}     cursor (w1, 2, 10);{}     out    (w1, "Mindestbestand : " + text (mindestbestand) + "    ");{}     cursor (w1, 2, 12);{}     out    (w1, "Bestand        : " + text (bestand) + "    ").{}     text preis:{}       TEXT VAR hilfe :: text (preis, min (8, pos(text(preis),".")+2), 2);{}
+       change (hilfe, " ", "0");{}       hilfe.{}END PROC zeige artikeldaten;{}PROC zeige kundendaten:{}     cursor (w1, 2, 6);{}     out    (w1, "Nachname       : " + text (nachname, 16));{}     cursor (w1, 2, 8);{}     out    (w1, "Vorname        : " + text (vorname , 16));{}     cursor (w1, 2, 10);{}     out    (w1, "Geschlecht     : " + geschlecht + "          ");{}END PROC zeige kundendaten;{}PROC artikeldaten speichern:{}  pruefe abbruch;{}  page (w2); line (w2);{}  out (w2, " Artikeldaten werden gespeichert") ;{}
+  speichere artikeldaten (artikelnummer, artikelname, preis,{}                          mindestbestand, bestand);{}  pause (10);{}  IF codekartenleser aktiviert{}     THEN lasse karte entfernen (FALSE){}  FI{}END PROC artikeldaten speichern;{}PROC kundendaten speichern:{}  pruefe abbruch;{}  page (w2); line (w2);{}  out (w2, " Kundendaten werden gespeichert") ;{}  speichere kundendaten (kundennummer, nachname,vorname, geschlecht);{}  pause (10);{}  IF codekartenleser aktiviert{}     THEN lasse karte entfernen (FALSE){}
+  FI{}END PROC kundendaten speichern;{}BOOL PROC stoptaste gedrueckt:{}  pruefe abbruch;{}  ende gewuenscht{}END PROC stoptaste gedrueckt;{}BOOL PROC stoptaste gedrückt:{}  stoptaste gedrueckt{}END PROC stoptaste gedrückt;{}PROC neues blatt:{}  pruefe abbruch;{}  page (w3k);{}  page (w3);{}  auf neuem blatt := TRUE;{}  forget ("WARENHAUS:Rechnung", quiet){}END PROC neues blatt;{}PROC nachbestellen:{}  pruefe abbruch;{}  FILE VAR f;{}  warten in w2;{}  hole bestelliste (f);{}  pruefe abbruch;{}  cursor (2,24);{}
+  out ("Weiter mit <ESC><q>;  Cursor bewegen: <Pfeile>");{}  cursor on;{}  show (w4, f);{}  cursor off;{}  cursor (1, 24); out (""5"");{}  WINDOW VAR  w :: window(45,18,25,3);{}  outframe (w);{}  IF yes (w, "Bestelliste drucken", FALSE){}     THEN drucke (headline (f)){}  FI;{}  cursor on;{}  forget (headline (f), quiet){}END PROC nachbestellen;{}PROC warten in w2:{}  cursor off;{}  page (w2);{}  line (w2);{}  out (w2, " Bitte warten!");{}  cursor on{}END PROC warten in w2;{}PROC codenummer von tastatur lesen (INT VAR codenummer):{}
+     codenummer := 0;{}     out  (w2, " Codenummer eingeben");{}     cursor on;{}     lies nummer ein (codenummer){}END PROC codenummer von tastatur lesen;{}PROC auskunft:{}  pruefe abbruch;{}  FILE VAR f;{}  INT VAR codenummer :: 0;{}  cursor (w1, 2, 2);{}  out  (w1, "Codenummer     :            ");{}  page (w2);{}  IF codekartenleser aktiviert{}     THEN codenummer := gesicherter wert von interface (0,254, "Codekarte");{}          lasse karte entfernen (FALSE){}     ELSE codenummer von tastatur lesen (codenummer){}
+  FI;{}  IF ende gewuenscht THEN LEAVE auskunft FI;{}  SELECT codenummer OF CASE 66, 67, 68 : hitliste{}                       CASE 73, 74, 75 : kaeuferliste{}                       CASE 77, 78, 79 : kundenliste{}                       CASE 84, 85, 86 : einkaufsliste{}                       CASE 89, 90, 91 : lageruebersicht{}  OTHERWISE teste auf artikel oder kundennummer{}  END SELECT;{}  IF codekartenleser aktiviert CAND wert von interface <> 255{}     THEN karte entfernen{}  FI.{}  karte entfernen:{}
+    SELECT codenummer OF{}      CASE 66, 67, 68, 73, 74, 75, 77, 78, 79, 84, 85, 86, 89, 90,{}           91:  lasse karte entfernen (TRUE){}      OTHERWISE lasse karte entfernen (FALSE){}    END SELECT.{}  teste auf artikel oder kundennummer:{}    IF   codenummer >= min artikelnummer AND codenummer <= max artikelnummer{}         THEN gib auskunft ueber artikeldaten{}    ELIF codenummer >= min kundennummer  AND codenummer <= max kundennummer{}         THEN gib auskunft ueber kundendaten{}    ELSE unzulaessige codenummer{}
+    FI.{}  unzulaessige codenummer:{}    out (10 * ""7"");{}    page (w2);{}    out  (w2, " Unzulässige Codenummer !!!");{}    line (w2, 2);{}    out  (w2, " Bitte irgendeine Taste tippen!");{}    pause;{}    page (w2).{}  gib auskunft ueber artikeldaten:{}    hole artikeldaten (codenummer, artikelname, preis,{}                       mindestbestand, bestand);{}    zeige artikeldaten;{}    artikelnummer ist eingelesen := FALSE;{}    stop w2;{}    page (w1).{}  gib auskunft ueber kundendaten:{}    hole kundendaten (codenummer, nachname, vorname, geschlecht);{}
+    zeige kundendaten;{}    kundennummer ist eingelesen := FALSE;{}    stop w2;{}    page (w1).{}  hitliste:{}    warten in w2;{}    hole auskunft ein (codenummer, 0, f);{}    zeige f.{}  kundenliste:{}    warten in w2;{}    hole auskunft ein (codenummer, 0, f);{}    zeige f.{}  zeige f:{}    pruefe abbruch;{}    cursor (2, 24);{}    out ("Weiter mit <ESC><q>;  Cursor bewegen: <Pfeile>");{}    show (w4, f);{}    cursor (1, 24); out (""5"");{}    evtl drucken.{} lageruebersicht:{}   warten in w2;{}
+   hole auskunft ein (codenummer, 0, f);{}   zeige f.{} kaeuferliste:{}   lies artikelnummer ein;{}   IF artikelnummer ist eingelesen{}      THEN artikelnummer ist eingelesen := FALSE;{}           warten in w2;{}           hole auskunft ein (codenummer, artikelnummer, f);{}           zeige f{}   FI.{} einkaufsliste:{}   lies kundennummer ein;{}   IF kundennummer ist eingelesen{}      THEN kundennummer ist eingelesen := FALSE;{}           warten in w2;{}           hole auskunft ein (codenummer, kundennummer, f);{}
+           zeige f{}   FI.{} evtl drucken:{}   WINDOW VAR  w :: window(46,18,22,3);{}   cursor off;{}   outframe (w);{}   IF yes (w, "Auskunft drucken", FALSE){}      THEN drucke (headline (f)){}   FI;{}   cursor on;{}   forget (headline (f), quiet).{}END PROC auskunft;{}PROC rechnungskopf:{}  pruefe abbruch;{}  IF kundennummer ist eingelesen AND nachname <> ""{}     THEN ueberschrift := "    RECHNUNG für " + anrede + (vorname SUB 1) +{}                          ". " + text (nachname, 10){}     ELSE ueberschrift := "    RECHNUNG"{}
+  FI;{}  summe := 0.0;{}  schreibe ueberschrift auf bildschirm;{}  schreibe in rechnungsdatei;{}  IF codekartenleser aktiviert{}     THEN lasse karte entfernen (FALSE){}  FI.{}  schreibe in rechnungsdatei:{}    sysout ("WARENHAUS:Rechnung");{}    line;{}    put (ueberschrift);{}    line;{}    put ("   ==================================");{}    line (2);{}    sysout ("").{}  anrede:{}    IF   geschlecht = "m"{}         THEN "Herrn "{}    ELIF geschlecht = "w"{}         THEN "Frau "{}         ELSE ""{}
+    FI.{}END PROC rechnungskopf;{}PROC schreibe ueberschrift auf bildschirm:{}  INT VAR spalte, zeile;{}  get cursor (w3, spalte, zeile);{}  IF zeile = 1{}     THEN auf neuem blatt := TRUE;{}          schreibe in w3k{}     ELSE auf neuem blatt := FALSE;{}          schreibe in w3{}  FI.{}  schreibe in w3:{}    IF remaining lines (w3) < 7{}       THEN page (w3);{}            page (w3k);{}            auf neuem blatt := TRUE;{}            schreibe in w3k{}       ELSE line (w3);{}            out  (w3, ueberschrift);{}
+            line (w3);{}            out  (w3, "   ==================================");{}            line (w3, 2){}    FI.{}  schreibe in w3k:{}            out  (w3k, ueberschrift);{}            line (w3k);{}            out  (w3k, "   ==================================").{}END PROC schreibe ueberschrift auf bildschirm;{}PROC artikel kaufen:{}  pruefe abbruch;{}  IF artikelnummer ist eingelesen{}     THEN kauf registrieren{}     ELSE setze variable in anfangszustand;{}          errorstop ("Es ist keine Artikelnummer eingelesen worden!"){}
+  FI;{}  IF codekartenleser aktiviert{}     THEN lasse karte entfernen (FALSE){}  FI.{}  kauf registrieren:{}    artikelnummer ist eingelesen := FALSE;{}    IF bestand > 0{}       THEN artikel auf rechnung setzen;{}            registrieren{}       ELSE page (w2); out (""7"");{}            IF artikelname = ""{}               THEN out (w2, " Artikel hier nicht erhältlich!"){}               ELSE out (w2, " Der Artikel ist ausverkauft!"){}            FI;{}            line (w2, 2);{}            out (w2, " Weiter durch Tippen einer Taste");{}
+            pause{}    FI.{}  registrieren:{}    IF kundennummer ist eingelesen{}       THEN registriere verkauf (kundennummer, artikelnummer){}       ELSE registriere verkauf (min kundennummer - 1, artikelnummer){}    FI.{}    artikel auf rechnung setzen:{}      summe INCR preis;{}      IF remaining lines (w3) < 3{}         THEN beginne wieder oben{}      FI;{}      out  (w3, "    " + text (artikelname, 15) + text (preis, 12, 2));{}      line (w3);{}      sysout ("WARENHAUS:Rechnung");{}      put  ("    " + text (artikelname, 15) + text preis);{}
+      line;{}      sysout ("").{}      beginne wieder oben:{}        IF auf neuem blatt{}           THEN page (w3){}           ELSE schreibe ueberschrift auf bildschirm{}       FI.{}      text preis:{}        TEXT VAR hilfe     :: text (preis, 12, 2);{}        INT  VAR vor punkt :: pos  (hilfe, ".") - 1;{}        IF (hilfe SUB vor punkt) = " "{}           THEN change (hilfe, vor punkt, vor punkt, "0"){}        FI;{}        hilfe.{}END PROC artikel kaufen;{}PROC abrechnung:{}  pruefe abbruch;{}  schreibe summe auf bildschirm;{}
+  schreibe summe in rechnungsdatei;{}  setze variable zurueck;{}  frage ob drucken;{}  IF codekartenleser aktiviert{}     THEN lasse karte entfernen (FALSE){}  FI.{}  schreibe summe auf bildschirm:{}    IF remaining lines (w3) < 2{}       THEN beginne wieder oben{}    FI;{}    put  (w3, "                   -------------");{}    line (w3);{}    put  (w3, "    Summe          " + text (summe, 12, 2));{}    line (w3).{}  beginne wieder oben:{}    IF auf neuem blatt{}       THEN page (w3){}       ELSE schreibe ueberschrift auf bildschirm{}
+    FI.{}  schreibe summe in rechnungsdatei:{}    sysout ("WARENHAUS:Rechnung");{}    put ("                   -------------");{}    line;{}    put ("    Summe          " + text (summe, 12, 2));{}    line;{}    sysout ("").{}  setze variable zurueck:{}    BOOL VAR alter wert :: ende gewuenscht;{}    setze variable in anfangszustand;{}    ende gewuenscht := alter wert.{}  frage ob drucken:{}    IF yes (w2, "Rechnung drucken", FALSE){}       THEN cursor (3, 22);{}            disable stop;{}            print ("WARENHAUS:Rechnung");{}
+            IF is error THEN clear error FI;{}            enable stop{}    FI.{}END PROC abrechnung;{}PROC artikeldaten eingeben:{}  pruefe abbruch;{}  IF artikelnummer ist eingelesen{}     THEN lies artikeldaten ein;{}          artikeldaten speichern{}     ELSE setze variable in anfangszustand;{}          errorstop ("Es ist keine Artikelnummer eingelesen worden!"){}  FI.{}  lies artikeldaten ein:{}    zeige artikeldaten;{}    IF artikelname <> ""{}       THEN vielleicht schon fertig{}       ELSE page (w2){}
+    FI;{}    REP line (w2);{}        put  (w2, " Artikeldaten eingeben");{}        eingabe{}    UNTIL yes (w2, "Alles richtig", TRUE){}    PER;{}    artikelnummer ist eingelesen := FALSE.{}  vielleicht schon fertig:{}    IF yes (w2, "Alles richtig", TRUE){}       THEN  artikelnummer ist eingelesen := FALSE;{}             IF codekartenleser aktiviert{}                THEN lasse karte entfernen (FALSE){}             FI;{}             LEAVE artikeldaten eingeben{}    FI.{}  eingabe:{}    name holen;{}
+    preis holen;{}    mindestbestand holen;{}    bestand holen.{}  name holen:{}    REP cursor  (w1, 19, 6);{}        editget (w1, artikelname, 80, 80, "", abbruchzeichen + stopzeichen,{}                                              exit char);{}        teste auf abbruch{}    UNTIL artikelname <> "" PER.{}  preis holen:{}    hilfstext := text (preis, pos(text(preis),".") + 2, 2);{}    change (hilfstext, " ", "0");{}    REP cursor  (w1, 19, 8);{}        editget (w1, hilfstext, 8, 8, "", abbruch zeichen + stopzeichen,{}
+                                          exit char);{}        change (hilfstext, ",", ".");{}        preis := round (real (hilfstext), 2);{}        teste auf abbruch{}    UNTIL preis >= 0.0 PER.{}  mindestbestand holen:{}    hilfstext := text (mindestbestand);{}    REP cursor  (w1, 19, 10);{}        editget (w1, hilfstext, 4, 4, "", abbruch zeichen + stopzeichen,{}                                          exit char);{}        mindestbestand := int (hilfstext);{}        teste auf abbruch{}    UNTIL mindestbestand >= 0 PER.{}
+  bestand holen:{}    hilfstext := text (bestand);{}    REP cursor  (w1, 19, 12);{}        editget (w1, hilfstext, 4, 4, "", abbruch zeichen + stopzeichen,{}                                          exit char);{}        bestand := int (hilfstext);{}        teste auf abbruch{}    UNTIL bestand >= 0 PER.{}  teste auf abbruch:{}    IF   exit char = esc + stopzeichen{}         THEN ende gewuenscht := TRUE{}    ELIF exit char = esc + abbruchzeichen{}         THEN setze variable in anfangszustand;{}              errorstop (1951, "Programm - Abbruch durch <ESC><"{}
+                                + abbruchzeichen + ">"){}    FI.{}END PROC artikeldaten eingeben;{}PROC kundendaten eingeben:{}  IF kundennummer ist eingelesen{}     THEN lies kundendaten ein;{}          kundendaten speichern{}  ELSE setze variable in anfangszustand;{}       errorstop ("Es ist keine Kundennummer eingelesen worden!"){}  FI.{}  lies kundendaten ein:{}    zeige kundendaten;{}    IF nachname <> ""{}       THEN vielleicht schon fertig{}       ELSE page (w2){}    FI;{}    REP line (w2);{}
+        put  (w2, " Kundendaten eingeben");{}        eingabe{}    UNTIL  yes (w2, "Alles richtig", TRUE) PER;{}    kundennummer ist eingelesen := FALSE.{}  vielleicht schon fertig:{}    IF yes (w2, "Alles richtig", TRUE){}       THEN  kundennummer ist eingelesen := FALSE;{}             IF codekartenleser aktiviert{}                THEN lasse karte entfernen (FALSE){}             FI;{}             LEAVE kundendaten eingeben{}    FI.{}  eingabe:{}    nachname holen;{}    vorname holen;{}    geschlecht holen.{}
+  nachname holen:{}    REP cursor  (w1, 19, 6);{}        editget (w1, nachname, 80, 80, "", abbruch zeichen + stopzeichen,{}                                           exit char);{}        teste auf abbruch{}    UNTIL nachname <> "" PER.{}  vorname holen:{}    REP cursor  (w1, 19, 8);{}        editget (w1, vorname, 80, 80, "", abbruch zeichen + stopzeichen,{}                                          exit char);{}        teste auf abbruch{}    UNTIL vorname <> "" PER.{}  geschlecht holen:{}    REP cursor  (w1, 19, 10);{}
+        editget (w1, geschlecht, 9, 9, "", abbruchzeichen + stopzeichen,{}                                           exit char);{}        geschlecht  := geschlecht SUB 1;{}        teste auf abbruch{}    UNTIL geschlecht = "m" OR geschlecht = "w" PER.{}  teste auf abbruch:{}    IF   exit char = esc + stopzeichen{}         THEN ende gewuenscht := TRUE{}    ELIF exit char = esc + abbruchzeichen{}         THEN setze variable in anfangszustand;{}              errorstop (1951, "Programm - Abbruch durch <ESC><"{}
+                                + abbruchzeichen + ">"){}    FI.{}END PROC kundendaten eingeben;{}PROC drucke (TEXT CONST name):{}  TEXT VAR zeile;{}  FILE VAR f :: sequential file (modify, name);{}  to line (f, 1);{}  insert record (f);{}  write  record (f, "#center#" + name);{}  down (f);{}  insert record (f);{}  down (f);{}  WHILE NOT eof (f) REP{}    read record (f, zeile);{}    IF pos (zeile, ""15"") > 0{}       THEN change (zeile, ""15"", "#on(""r"")#");{}            change (zeile, ""14"", "#off(""r"")#");{}
+            write record (f, zeile){}    FI;{}    down (f){}  PER;{}  cursor (3, 22);{}  print (name){}END PROC drucke;{}PROC stop w2:{}  cursor off;{}  page (w2);{}  out (w2," Zum Weitermachen bitte");line(w2);{}  out (w2," irgendeine Taste tippen!");{}  pause;{}  page (w2);{}  cursor on{}END PROC stop w2;{}BOOL PROC yes (WINDOW VAR w, TEXT CONST frage, BOOL CONST default):{}  BOOL VAR antwort :: default;{}  TEXT VAR taste;{}  INT CONST ja pos :: (areaxsize (w) - 9) DIV 2;{}  cursor off;{}  cursor (42,24); out ("Ändern: <Pfeile>  Bestätigen: <RETURN>");{}
+  page (w);{}  out (w, center (w, frage + " ?"));{}  cursor (w, ja pos, 3);{}  IF default{}     THEN  out (w, ""15"Ja "14" Nein ");{}           cursor (w, ja pos, 3){}     ELSE  out (w, " Ja  "15"Nein "14"");{}           cursor (w, ja pos + 5, 3){}  FI;{}  tastendruck auswerten;{}  page (w);{}  cursor (42,24); out (""5"");{}  cursor on;{}  antwort.{}  tastendruck auswerten:{}    REP inchar (taste);{}        SELECT code (taste) OF CASE  2,   8 : position aendern{}                               CASE      13 : LEAVE tastendruck auswerten{}
+                               CASE 74, 106 : antwort := TRUE;  (*Jj*){}                                              LEAVE tastendruck auswerten{}                               CASE 78, 110 : antwort := FALSE; (*Nn*){}                                              LEAVE tastendruck auswerten{}        OTHERWISE out (""7"")  END SELECT{}    PER.{}    position aendern:{}      IF antwort THEN antwort := FALSE;{}                      cursor (w, ja pos, 3);{}                      out (w, " Ja  "15"Nein "14"");{}
+                      cursor (w, ja pos + 5, 3){}                 ELSE antwort := TRUE;{}                      cursor (w, ja pos, 3);{}                      out (w, ""15"Ja "14" Nein ");{}                      cursor (w, ja pos, 3){}      FI.{}END PROC yes;{}PROC tastatureingabe (BOOL CONST erwuenscht, INT VAR rueckmeldung):{}  IF erwuenscht{}     THEN rueckmeldung := 0;{}          codekartenleser aktiviert := FALSE;{}          schliesse interface{}     ELSE oeffne interface (rueckmeldung);{}          IF rueckmeldung >= 0{}
+             THEN codekartenleser aktiviert := TRUE{}             ELSE codekartenleser aktiviert := FALSE{}          FI{}  FI{}END PROC tastatureingabe;{}BOOL PROC eingabe mit codekartenleser:{}  codekartenleser aktiviert{}END PROC eingabe mit codekartenleser;{}PROC dezimalwert lesen:{}  pruefe abbruch;{}  IF codekartenleser aktiviert{}     THEN interfacewerte zeigen{}     ELSE setze variable in anfangszustand;{}          errorstop ("Eingabeart ist auf Tastatur eingestellt!"){}  FI.{}  interfacewerte zeigen:{}
+    cursor off;{}    fenster putzen;{}    line (w1, 4); line (w2);{}    out (w1, " Dezimalwert :");{}    out (w2, " Lesen beenden mit <ESC><q>");{}    ende gewuenscht := FALSE;{}    REP pruefe abbruch;{}        cursor (w1, 17, 5);{}        out (w1, text (wert von interface, 3)){}    UNTIL ende gewuenscht PER;{}    page (w2); cursor (w1, 1, 5); out ("                         ");{}    cursor on.{}END PROC dezimalwert lesen;{}PROC bitmuster lesen:{}  pruefe abbruch;{}  IF codekartenleser aktiviert{}
+     THEN interfacewerte zeigen{}     ELSE setze variable in anfangszustand;{}          errorstop ("Eingabeart ist auf Tastatur eingestellt!"){}  FI.{}  interfacewerte zeigen:{}    cursor off;{}    fenster putzen;{}    line (w1, 4); line (w2);{}    out (w1, " Bitmuster :");{}    out (w2, " Lesen beenden mit <ESC><q>");{}    ende gewuenscht := FALSE;{}    REP pruefe abbruch;{}        cursor (w1, 16, 5);{}        out (w1, bitmuster (wert von interface)){}    UNTIL ende gewuenscht PER;{}    page (w2); cursor (w1, 1, 5); out ("                         ");{}
+    cursor on.{}END PROC bitmuster lesen;{}TEXT PROC bitmuster (INT CONST wert):{}  INT VAR bitnr;{}  TEXT VAR muster :: "";{}  FOR bitnr FROM 7 DOWNTO 0 REP{}    IF bit (wert, bitnr){}       THEN muster CAT "I"{}       ELSE muster CAT "O"{}    FI{}  PER;{}  muster{}END PROC bitmuster;{}PROC lasse karte entfernen (BOOL CONST mit rahmen):{}  IF wert von interface <> 255{}     THEN cursor off;{}          IF mit rahmen THEN regeneriere w2 ELSE page (w2) FI;{}          line (w2);{}          out (w2, " Bitte Karte entfernen");{}
+          REP pruefe abbruch{}          UNTIL (wert von interface = 255) OR ende gewuenscht PER;{}          cursor on{}  FI{}END PROC lasse karte entfernen;{}INT PROC gesicherter wert von interface (INT  CONST von, bis,{}                                         TEXT CONST kartenart):{}  INT VAR wert, zaehler;{}  ende gewuenscht := FALSE;{}  cursor off;{}  REP out (w2, " Bitte " + kartenart + " einschieben");{}      line (w2, 2);{}      out (w2, " Stoptaste: <ESC><" + stopzeichen + ">");{}      cursor (79, 24);{}
+      gesicherten wert einlesen;{}      cursor (w1, 19, 2);{}      out (w1, text (wert, 3));{}      IF wert < von  OR  wert > bis{}         THEN warnung{}      FI{}  UNTIL wert >= von  AND  wert <= bis PER;{}  cursor on;{}  wert.{}  gesicherten wert einlesen:{}    REP zaehler := 0;{}        warte auf karte;{}        wert := wert von interface;{}        lies wert{}    UNTIL wert gesichert AND wert <> 255 PER.{}  warte auf karte:{}    REP beachte esc q{}    UNTIL wert von interface <> 255 PER.{}  beachte esc q:{}
+    pruefe abbruch;{}    IF ende gewuenscht{}       THEN cursor on;{}            LEAVE gesicherter wert von interface WITH 0{}    FI.{}  lies wert:{}    REP beachte esc q;{}        IF wert = wert von interface{}           THEN zaehler INCR 1{}           ELSE LEAVE lies wert{}        FI{}    UNTIL wert gesichert PER.{}    wert gesichert: zaehler = sicherheit.{}  warnung:{}    page (w2); out (""7"");{}    out (w2, " Dies ist keine " + kartenart + "!");{}    line (w2, 2);{}    out (w2, " Bitte Karte entfernen");{}
+    REP beachte esc q{}    UNTIL wert von interface = 255 PER;{}    page (w2).{}END PROC gesicherter wert von interface{}END PACKET ls warenhaus 3{}
+
diff --git a/warenhaus/ls-Warenhaus 4 b/warenhaus/ls-Warenhaus 4
new file mode 100644
index 0000000..a19a6d6
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 4	
@@ -0,0 +1,48 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                    ls-Warenhaus 4                    ** 
+         **                                                      ** 
+         **                     Version 1.01                     ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                  (Stand:  30.08.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **           Autor: Bruno Pollok, Bielefeld             ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         **                                                      ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls warenhaus 4 DEFINES                        
+       uebersetze:{}TYPE VOKABEL    = STRUCT (TEXT grin, elan),{}     REFINEMENT = STRUCT (TEXT name, INT aufruf);{}LET  befehlsanzahl         = 10,{}     max refinements       = 20,{}     max offene strukturen = 10,{}     schleife              =  1,{}     abfrage               =  2;{}ROW befehlsanzahl VOKABEL CONST befehl :: ROW befehlsanzahl VOKABEL :{}    (VOKABEL : ("Artikelnummerlesen",   "artikelnummer lesen"),{}     VOKABEL : ("Artikeldateneingeben", "artikeldaten eingeben"),{}     VOKABEL : ("Kundennummerlesen",    "kundennummer lesen"),{}{}
+     VOKABEL : ("Kundendateneingeben",  "kundendaten eingeben"),{}     VOKABEL : ("Rechnungskopf",        "rechnungskopf"),{}     VOKABEL : ("Artikelkaufen",        "artikel kaufen"),{}     VOKABEL : ("Abrechnung",           "abrechnung"),{}     VOKABEL : ("Auskunft",             "auskunft"),{}     VOKABEL : ("neuesBlatt",           "neues blatt"),{}     VOKABEL : ("Bildschirmneu",        "bildschirm neu"));{}ROW max refinements REFINEMENT VAR refinement;{}ROW max offene strukturen  INT VAR offene struktur;{}{}
+INT VAR zeilennummer, erster fehler;{}OP := (VOKABEL VAR links, VOKABEL CONST rechts):{}   CONCR (links) := CONCR (rechts){}END OP :=;{}PROC uebersetze (TEXT CONST dateiname):{}forget ("elanprogramm", quiet);{}FILE VAR quelle :: sequential file (input, dateiname),{}         ziel   :: sequential file (output, "elanprogramm");{}suche programmanfang;{}WHILE NOT (eof (quelle) OR anything noted) REP{}  bearbeite zeile{}PER;{}IF NOT anything noted{}   THEN abschlusspruefung{}FI;{}IF anything noted{}   THEN quelle := sequential file (modify, dateiname);{}{}
+        to line (quelle, erster fehler);{}        col (1);{}        noteedit (quelle);{}        errorstop (""){}FI.{}abschlusspruefung:{}  IF anzahl refinements > 0{}     THEN pruefe refinementliste{}     ELSE pruefe programmende{}  FI.{}pruefe programmende:{}  IF programmende fehlt{}     THEN zeilennummer INCR 1;{}          fehler (16){}  FI.{}pruefe refinementliste:{}  zeilennummer INCR 1;{}  pruefe auf offene schleife oder abfrage;{}  put (ziel, "END PROC refinement " + text (letztes refinement));{}{}
+  FOR index FROM 1 UPTO anzahl refinements REP{}    IF refinement [index].aufruf > 0{}       THEN zeilennummer := refinement [index].aufruf;{}            fehler (25){}    ELIF refinement [index].aufruf < 0{}       THEN zeilennummer := - refinement [index].aufruf;{}            fehler (26){}    FI{}  PER.{}suche programmanfang:{}  TEXT VAR restzeile, zeile :: "";{}  BOOL VAR programmende fehlt := FALSE,{}           refinement muss folgen := FALSE;{}  INT VAR anzahl refinements := 0,{}          letztes refinement := 0,{}{}
+          letzte geoeffnete  := 0,{}          index;{}  zeilennummer       := 0;{}  erster fehler      := 0;{}  WHILE NOT eof (quelle) AND zeile = "" REP{}    getline (quelle, zeile);{}    zeile := compress (zeile);{}    zeilennummer INCR 1;{}    cout (zeilennummer);{}    IF zeile = "" THEN line (ziel) FI;{}  PER;{}  put (ziel, "bildschirm neu;");{}  IF zeile = "" THEN LEAVE uebersetze{}  ELIF pos (zeile, "PROGRAMM") = 1{}       THEN programmende fehlt := TRUE{}       ELSE fehler (1){}  FI.{}bearbeite zeile:{}{}
+  zeilennummer INCR 1;{}  cout (zeilennummer);{}  getline (quelle, zeile);{}  zeile := compress (zeile);{}  change all (zeile, " ", "");{}  IF zeile = ""{}     THEN line (ziel){}     ELSE analysiere und uebersetze{}  FI.{}analysiere und uebersetze:{}  IF refinement muss folgen{}     THEN erstes refinement{}     ELSE pruefe zunaechst auf schluesselworte;{}          durchsuche befehlsliste{}  FI.{}erstes refinement:{}  IF pos (zeile, ":") = 0{}     THEN fehler (19){}  ELIF pos (zeile, ":") < length (zeile){}{}
+     THEN fehler (20){}  ELIF (pos (zeile, "PROGRAMM")   = 1) OR{}       (pos (zeile, "ENDE")       = 1) OR{}       (pos (zeile, "WIEDERHOLE") = 1) OR{}       (pos (zeile, "BIS")        = 1) OR{}       (pos (zeile, "WENN")       = 1){}     THEN fehler (21){}  ELIF (zeile = "Stoptastegedrückt:") OR{}       (zeile = "nichtStoptastegedrückt:") OR{}       (zeile = "Stoptastegedrueckt:") OR{}       (zeile = "nichtStoptastegedrueckt:"){}     THEN fehler (22){}     ELSE refinement muss folgen := FALSE;{}{}
+          line (ziel);{}          trage befehlsdefinition ein{}  FI.{}trage befehlsdefinition ein:{}   change (zeile, ":", "");{}   FOR index FROM 1 UPTO anzahl refinements REP{}     IF refinement [index].name = zeile{}        THEN pruefe aufruf; LEAVE trage befehlsdefinition ein{}     FI{}   PER;{}   anzahl refinements INCR 1;{}   IF anzahl refinements > max refinements{}      THEN fehler (24){}   ELSE refinement [anzahl refinements].name := zeile;{}        refinement [anzahl refinements].aufruf := - zeilennummer;{}{}
+        letztes refinement := anzahl refinements;{}        line (ziel);{}        put (ziel, "PROC refinement " + text (anzahl refinements) + ":"){}   FI.{}pruefe aufruf:{}  IF refinement [index].aufruf > 0{}     THEN refinement [index].aufruf := 0;{}          line (ziel);{}          put (ziel, "PROC refinement " + text (index) + ":");{}          letztes refinement := index{}     ELSE fehler (23){}  FI.{}pruefe zunaechst auf schluesselworte:{}  IF   pos (zeile, "WIEDERHOLE") = 1{}       THEN oeffne schleife; LEAVE analysiere und uebersetze{}{}
+  ELIF pos (zeile, "WENN") = 1{}       THEN oeffne if; LEAVE analysiere und uebersetze{}  ELIF pos (zeile, "BIS")  = 1{}       THEN schliesse mit until; LEAVE analysiere und uebersetze{}  ELIF pos (zeile, "ENDE") = 1{}       THEN schliesse; LEAVE analysiere und uebersetze{}  ELIF pos (zeile, "PROGRAMM") = 1{}       THEN fehler (18); LEAVE analysiere und uebersetze{}  FI.{}oeffne schleife:{}  IF letzte geoeffnete = max offene strukturen{}     THEN fehler (2){}     ELSE letzte geoeffnete INCR 1;{}          offene struktur [letzte geoeffnete] := schleife;{}{}
+          analysiere schleifenart{}  FI.{}analysiere schleifenart:{}  IF zeile = "WIEDERHOLE"{}     THEN line (ziel); put (ziel, "REPEAT"){}     ELSE es muss eine zaehlschleife sein{}  FI.{}es muss eine zaehlschleife sein:{}  restzeile := subtext (zeile, 11);{}  INT  VAR malpos := pos (restzeile, "MAL");{}  IF malpos > 0{}     THEN zaehlschleife{}     ELSE fehler (3){}  FI.{}zaehlschleife:{}  IF length (restzeile) > malpos + 2{}     THEN fehler (4){}     ELSE bestimme anzahl der wiederholungen{}  FI.{}{}
+bestimme anzahl der wiederholungen:{}  INT VAR wdh := int (subtext (restzeile, 1, malpos - 1));{}  IF last conversion ok{}     THEN line (ziel);{}          put (ziel, "INT VAR index" + text (zeilennummer) +{}                     "; FOR index" + text (zeilennummer) +{}                     " FROM 1 UPTO " + text (wdh) + " REPEAT"){}     ELSE fehler (5){}  FI.{}oeffne if:{}  IF letzte geoeffnete = max offene strukturen{}     THEN fehler (6){}     ELSE letzte geoeffnete INCR 1;{}          offene struktur [letzte geoeffnete] := abfrage;{}{}
+          uebersetze abfrage{}  FI.{}uebersetze abfrage:{}  restzeile := subtext (zeile, 5);{}  IF   (restzeile = "Stoptastegedrückt") OR{}       (restzeile = "Stoptastegedrueckt"){}       THEN line (ziel); put (ziel, "IF stoptaste gedrueckt THEN"){}  ELIF (restzeile = "nichtStoptastegedrückt") OR{}       (restzeile = "nichtStoptastegedrueckt"){}       THEN line (ziel); put (ziel, "IF NOT stoptaste gedrueckt THEN"){}  ELIF restzeile = ""{}       THEN fehler (7){}       ELSE fehler (8){}  FI.{}schliesse mit until:{}{}
+  teste ob als letztes schleife offen;{}  letzte geoeffnete DECR 1;{}  restzeile := subtext (zeile, 4);{}  IF   (restzeile = "Stoptastegedrückt") OR{}       (restzeile = "Stoptastegedrueckt"){}       THEN line (ziel);{}            put (ziel, "UNTIL stoptaste gedrueckt END REPEAT;");{}  ELIF (restzeile = "nichtStoptastegedrückt") OR{}       (restzeile = "nichtStoptastegedrueckt"){}       THEN line (ziel);{}            put (ziel, "UNTIL NOT stoptaste gedrueckt END REPEAT;");{}  ELIF restzeile = ""{}{}
+       THEN fehler (9){}       ELSE fehler (8){}  FI.{}schliesse:{}  restzeile := subtext (zeile, 5);{}  IF restzeile = "WIEDERHOLE"{}     THEN schliesse schleife{}  ELIF restzeile = "WENN"{}     THEN schliesse if{}  ELIF restzeile = "PROGRAMM"{}     THEN programmende{}     ELSE fehler (10){}  FI.{}schliesse schleife:{}  teste ob als letztes schleife offen;{}  letzte geoeffnete DECR 1;{}  line (ziel); put (ziel, "END REPEAT;").{}teste ob als letztes schleife offen:{}  IF letzte geoeffnete = 0{}     THEN fehler (11);{}{}
+          LEAVE bearbeite zeile{}  ELIF offene struktur [letzte geoeffnete] = abfrage{}     THEN fehler (12){}  FI.{}schliesse if:{}  teste ob als letztes abfrage offen;{}  line (ziel); put (ziel, "END IF;");{}  letzte geoeffnete DECR 1.{}teste ob als letztes abfrage offen:{}  IF letzte geoeffnete = 0{}     THEN fehler (13);{}          LEAVE bearbeite zeile{}  ELIF offene struktur [letzte geoeffnete] = schleife{}     THEN fehler (14){}  FI.{}programmende:{}  IF programmende fehlt{}     THEN programmende fehlt     := FALSE;{}{}
+          refinement muss folgen := TRUE{}     ELSE fehler (17);{}          LEAVE programmende{}  FI;{}  pruefe auf offene schleife oder abfrage.{}pruefe auf offene schleife oder abfrage:{}  IF letzte geoeffnete = 0{}     THEN alles okay{}  ELIF offene struktur [letzte geoeffnete] = schleife{}     THEN fehler (14){}     ELSE fehler (12){}  FI.{}  alles okay: .{}durchsuche befehlsliste:{}  IF pos (zeile, ":") > 0{}     THEN auf refinementdefinition pruefen{}     ELSE befehl suchen{}  FI.{}befehl suchen:{}{}
+  BOOL VAR gefunden := FALSE;{}  INT VAR i;{}  verhindere bedingung;{}  FOR i FROM 1 UPTO befehlsanzahl REP{}    IF befehl [i].grin = zeile{}       THEN gefunden := TRUE;{}            line (ziel);{}            put (ziel, befehl [i].elan + ";"){}    FI{}  UNTIL gefunden PER;{}  IF NOT gefunden{}     THEN trage in refinementliste ein{}  FI.{}auf refinementdefinition pruefen:{}  IF pos (zeile, ":") < length (zeile){}     THEN fehler (20){}  ELIF programmende fehlt{}     THEN fehler (16){}  ELIF (zeile = "Stoptastegedrückt:") OR{}{}
+       (zeile = "nichtStoptastegedrückt:") OR{}       (zeile = "Stoptastegedrueckt:") OR{}       (zeile = "nichtStoptastegedrueckt:"){}     THEN fehler (22){}     ELSE pruefe auf offene schleife oder abfrage;{}          put (ziel, "END PROC refinement " + text (letztes refinement){}                                             + ";");{}          trage befehlsdefinition ein{}  FI.{}trage in refinementliste ein:{}  FOR index FROM 1 UPTO anzahl refinements REP{}    IF refinement [index].name = zeile{}{}
+       THEN trage evtl aufruf ein;{}            LEAVE trage in refinementliste ein{}    FI{}  PER;{}  anzahl refinements INCR 1;{}  IF anzahl refinements > max refinements{}     THEN fehler (24){}     ELSE refinement [anzahl refinements].name := zeile;{}          refinement [anzahl refinements].aufruf := zeilennummer;{}          line (ziel);{}          put (ziel, "refinement " + text (anzahl refinements) + ";"){}  FI.{}trage evtl aufruf ein:{}  line (ziel);{}  put (ziel, "refinement " + text (index) + ";");{}{}
+  IF refinement [index].aufruf < 0{}     THEN refinement [index].aufruf := 0{}  FI.{}verhindere bedingung:{}  IF (zeile = "Stoptastegedrückt") OR (zeile = "nichtStoptastegedrückt") OR{}     (zeile = "Stoptastegedrueckt") OR (zeile = "nichtStoptastegedrueckt"){}     THEN fehler (15);{}          LEAVE bearbeite zeile{}  FI.{}END PROC uebersetze;{}PROC fehler (INT CONST fehlernr):{}  noteline;{}  note ("FEHLER in Zeile " + text (zeilennummer) + ": ");{}  noteline;{}  note ("       " + anwendungstext (fehlernr + 20));{}{}
+  noteline;{}  IF erster fehler = 0{}     THEN erster fehler := zeilennummer{}  FI{}END PROC fehler{}END PACKET ls warenhaus 4{}{}
+
diff --git a/warenhaus/ls-Warenhaus 5 b/warenhaus/ls-Warenhaus 5
new file mode 100644
index 0000000..6b05bad
--- /dev/null
+++ b/warenhaus/ls-Warenhaus 5	
@@ -0,0 +1,103 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                    ls-Warenhaus 5                    ** 
+         **                                                      ** 
+         **                     Version 1.01                     ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                  (Stand:  30.08.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **           Autor: Bruno Pollok, Bielefeld             ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         **                                                      ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+PACKET ls warenhaus 5 DEFINES                        
+       warenhaus,{}       grin,{}       direktbefehl 1,{}       direktbefehl 2,{}       direktbefehl 3,{}       direktbefehl 4,{}       direktbefehl 5,{}       direktbefehl 6,{}       direktbefehl 7,{}       warenhausbefehle zeigen,{}       eingabe grundeinstellung,{}       tastatur einstellen,{}       kartenleser einstellen,{}       evtl d und b sperren,{}       loesche zwischenraum,{}       eingabeart anzeigen,{}       filialdaten zusammenstellen,{}       filialdaten eintragen,{}       filialdaten verzeichnis,{}
+       filialdaten umbenennen,{}       filialdaten loeschen,{}       warenhausprogramme verzeichnis,{}       warenhausprogramm neu erstellen,{}       warenhausprogramm ansehen,{}       warenhausprogramm kopieren,{}       warenhausprogramm umbenennen,{}       warenhausprogramme loeschen,{}       warenhausprogramme drucken,{}       warenhausprogramm starten,{}       warenhausprogramm wiederholen:{}LET  menukarte       = "ls-MENUKARTE:Warenhaus",{}     praefix         = "Filialdaten:",{}     filialdatentyp  =       1951,{}
+     niltext         =         "",{}     maxlaenge       =         45,{}     maxnamenslaenge =         35;{}TEXT VAR  filialdatenname :: "",{}          programmname    :: "";{}INT  VAR  fehlerzeile     :: 0;{}BOOL VAR  grin version    :: FALSE,{}          noch kein programm gelaufen :: TRUE,{}          bildschirm neu eingesetzt   :: FALSE;{}WINDOW VAR w :: window (1, 3, 79, 19);{}INITFLAG VAR in this task :: FALSE;{}PROC warenhausbefehle zeigen:{}  TEXT VAR info, liste, tasten;{}  INT  VAR grinoffset;{}
+  IF grin version{}     THEN grinbefehle{}     ELSE elanbefehle{}  FI;{}  REP{}   INT VAR auswahl := menualternative (info, liste, tasten, 5, FALSE);{}   SELECT auswahl OF{}     CASE 1, 101, 105 : menuinfo (anwendungstext (1 + grinoffset)){}     CASE 2, 102, 106 : menuinfo (anwendungstext (2 + grinoffset)){}     CASE 3, 103, 107 : menuinfo (anwendungstext (3 + grinoffset)){}   END SELECT{}  UNTIL auswahl = 4 OR auswahl = 104 OR auswahl = 108 PER.{}  grinbefehle:{}    grinoffset := 13;{}    info := "       "15"Info zu den Programmierbefehlen "14""13""13""{}
+          + "          d  Datei - Bearbeitung           "13""{}          + "          e  Einkaufen und Auskunft        "13""{}          + "          k  Kontroll - Strukturen         "13""13""{}          + "          z  Zurück zum Hauptmenü          ";{}  liste  := "Datei"13"Kaufen/Auskunft"13"Kontroll"13"Zurück";{}  tasten := "dekzDEKZ".{}  elanbefehle:{}    grinoffset := 0;{}    info := "       "15"Info zu den Programmierbefehlen "14""13""13""{}          + "          d  Datei - Bearbeitung           "13""{}
+          + "          e  Einkaufen und Auskunft        "13""{}          + "          s  Sonstige Befehle              "13""13""{}          + "          z  Zurück zum Hauptmenü          ";{}  liste  := "Datei"13"Kaufen/Auskunft"13"Sonstige"13"Zurück";{}  tasten := "deszDESZ".{}END PROC warenhausbefehle zeigen;{}PROC eingabe grundeinstellung:{}  INT VAR dummy;{}  IF eingabe mit codekartenleser{}     THEN tastatureingabe (TRUE, dummy){}  FI{}END PROC eingabe grundeinstellung;{}PROC tastatur einstellen:{}
+  eingabe grundeinstellung;{}  menuinfo (anwendungstext (6), 4){}END PROC tastatur einstellen;{}PROC kartenleser einstellen:{}  INT VAR ergebnis;{}  IF eingabe mit codekartenleser{}     THEN tastatureingabe (TRUE, ergebnis){}  FI;{}  pause (10);{}  tastatureingabe (FALSE, ergebnis);{}  IF ergebnis < 0{}     THEN menuinfo (anwendungstext (7 - ergebnis), 5){}     ELSE menuinfo (anwendungstext (7), 4){}  FI{}END PROC kartenleser einstellen;{}PROC loesche zwischenraum:{}  INT VAR zeile;{}  cursor (1, 2); out (79 * waagerecht + " ");{}
+  FOR zeile FROM 3 UPTO 22 REP{}    cursor (1, zeile); out (""5"");{}  PER;{}  cursor (1, 23); out (79 * waagerecht + " ");{}  cursor (1, 24); out (""5"");{}END PROC loesche zwischenraum;{}PROC ergaenze bildschirm:{}  cursor ( 1, 2); out (ecke oben links);{}  cursor (42, 2); out (balken oben);{}  cursor (80, 2); out (ecke oben rechts);{}  INT VAR zeile;{}  FOR zeile FROM 3 UPTO 22 REP{}    cursor ( 1, zeile); out (senkrecht);{}    cursor (42, zeile); out (senkrecht);{}    cursor (80, zeile); out (senkrecht){}
+  PER;{}  cursor ( 1, 23); out (ecke unten links);{}  cursor (42, 23); out (balken unten);{}  cursor (80, 23); out (ecke unten rechts);{}  cursor (42, 19);{}  out (balken links + (37 * waagerecht) + balken rechts);{}  cursor w3 1 1{}END PROC ergaenze bildschirm;{}PROC zweite zeile:{}  cursor (1, 2); out (79 * waagerecht + " "){}END PROC zweite zeile;{}PROC evtl d und b sperren:{}  IF eingabe mit codekartenleser{}     THEN activate ( 9);{}          activate (10){}     ELSE deactivate ( 9);{}          deactivate (10){}
+  FI{}END PROC evtl d und b sperren;{}PROC direktbefehl 1:{}  disable stop;{}  warendatei bearbeiten;{}  cursor off;{}  IF is error{}     THEN regenerate menuscreen;{}          menuinfo (" " + invers (errormessage));{}          clear error{}     ELSE zweite zeile;{}          menu bildschirm{}  FI;{}  enable stop{}END PROC direktbefehl 1;{}PROC warendatei bearbeiten:{}  enable stop;{}  loesche zwischenraum;{}  ergaenze bildschirm;{}  cursor (2, 24); out (invers ("Warendatei bearbeiten"));{}  REP artikelnummer lesen;{}
+      IF NOT stoptaste gedrueckt{}         THEN artikeldaten eingeben{}      FI{}  UNTIL stoptaste gedrueckt PER{}END PROC warendatei bearbeiten;{}PROC direktbefehl 2:{}  disable stop;{}  kundendatei bearbeiten;{}  cursor off;{}  IF is error{}     THEN regenerate menuscreen;{}          menuinfo (" " + invers (errormessage));{}          clear error{}     ELSE zweite zeile;{}          menu bildschirm{}  FI;{}  enable stop{}END PROC direktbefehl 2;{}PROC kundendatei bearbeiten:{}  enable stop;{}  loesche zwischenraum;{}
+  ergaenze bildschirm;{}  cursor (2, 24); out (invers ("Kundendatei bearbeiten"));{}  REP kundennummer lesen;{}      IF NOT stoptaste gedrueckt{}         THEN kundendaten eingeben{}      FI{}  UNTIL stoptaste gedrueckt PER{}END PROC kundendatei bearbeiten;{}PROC direktbefehl 3:{}  disable stop;{}  einkaufen gehen;{}  cursor off;{}  IF is error{}     THEN regenerate menuscreen;{}          menuinfo (" " + invers (errormessage));{}          clear error{}     ELSE zweite zeile;{}          menu bildschirm{}
+  FI;{}  enable stop{}END PROC direktbefehl 3;{}PROC einkaufen gehen:{}  enable stop;{}  loesche zwischenraum;{}  ergaenze bildschirm;{}  cursor (2, 24); out (invers ("Einkaufen"));{}  forget ("WARENHAUS:Rechnung", quiet);{}  kundennummer lesen;{}  rechnungskopf;{}  REP   einkaufen{}  UNTIL stoptaste gedrueckt PER;{}  abrechnung;{}  forget ("WARENHAUS:Rechnung", quiet).{}  einkaufen:{}    artikelnummer lesen;{}    IF NOT stoptaste gedrueckt{}       THEN artikel kaufen{}    FI.{}END PROC einkaufen gehen;{}
+PROC direktbefehl 4:{}  disable stop;{}  auskunft einholen;{}  cursor off;{}  IF is error{}     THEN regenerate menuscreen;{}          menuinfo (" " + invers (errormessage));{}          clear error{}     ELSE zweite zeile;{}          menu bildschirm{}  FI;{}  enable stop{}END PROC direktbefehl 4;{}PROC auskunft einholen:{}  enable stop;{}  loesche zwischenraum;{}  ergaenze bildschirm;{}  cursor (2, 24); out (invers ("Auskunft"));{}  auskunft{}END PROC auskunft einholen;{}PROC direktbefehl 5:{}  disable stop;{}
+  ware nachbestellen;{}  cursor off;{}  IF is error{}     THEN regenerate menuscreen;{}          menuinfo (" " + invers (errormessage));{}          clear error{}     ELSE zweite zeile;{}          menu bildschirm{}  FI;{}  enable stop{}END PROC direktbefehl 5;{}PROC ware nachbestellen:{}  enable stop;{}  loesche zwischenraum;{}  ergaenze bildschirm;{}  cursor (2, 24); out (invers ("Nachbestellen"));{}  nachbestellen{}END PROC ware nachbestellen;{}PROC direktbefehl 6:{}  disable stop;{}  dezimalwerte von interface lesen;{}
+  cursor off;{}  IF is error{}     THEN regenerate menuscreen;{}          menuinfo (" " + invers (errormessage));{}          clear error{}     ELSE zweite zeile;{}          menu bildschirm{}  FI;{}  enable stop{}END PROC direktbefehl 6;{}PROC dezimalwerte von interface lesen:{}  enable stop;{}  loesche zwischenraum;{}  ergaenze bildschirm;{}  cursor (2, 24); out (invers ("Dezimalwert lesen"));{}  dezimalwert lesen{}END PROC dezimalwerte von interface lesen;{}PROC direktbefehl 7:{}  disable stop;{}
+  bitmuster von interface lesen;{}  cursor off;{}  IF is error{}     THEN regenerate menuscreen;{}          menuinfo (" " + invers (errormessage));{}          clear error{}     ELSE zweite zeile;{}          menu bildschirm{}  FI;{}  enable stop{}END PROC direktbefehl 7;{}PROC bitmuster von interface lesen:{}  enable stop;{}  loesche zwischenraum;{}  ergaenze bildschirm;{}  cursor (2, 24); out (invers ("Bitmuster lesen"));{}  bitmuster lesen{}END PROC bitmuster von interface lesen;{}PROC eingabeart anzeigen:{}
+  IF eingabe mit codekartenleser{}     THEN menuinfo (anwendungstext (7), 4){}     ELSE menuinfo (anwendungstext (6), 4){}  FI{}END PROC eingabeart anzeigen;{}PROC warenhaus:{}  BOOL VAR am ende loeschen :: TRUE;{}  pruefe zulaessigkeit;{}  installiere menukarte mit anfangsbild;{}  initialisiere warenhaus;{}  handle menu ("WARENHAUS");{}  IF am ende loeschen{}     THEN sperre verwaltungstask;{}          end (task (verwaltung)){}  FI.{}  installiere menukarte mit anfangsbild:{}    install menu (menukarte, TRUE);{}
+    cursor off;{}    cursor (17, 20);{}    out (" W A R E N H A U S ");{}    cursor (21, 22);{}    out (invers("Filiale " + text (channel (myself))));{}    cursor (79, 24);{}    pause (10).{}  sperre verwaltungstask:{}    DATASPACE VAR ds;{}    INT VAR dummy;{}    forget (ds); ds := nilspace;{}    call (task (verwaltung), 256, ds, dummy).{}  pruefe zulaessigkeit:{}    IF   hauptstellenname = ""{}         THEN line;{}         putline ("Keine uebergeordnete Task ist 'warenhaus hauptstelle'!");{}              end; LEAVE warenhaus{}
+    ELIF name (myself) = hauptstellenname{}         THEN errorstop ("Dieser Befehl darf nur von Söhnen dieser "{}                       + "Task aus gegeben werden!");{}              LEAVE warenhaus{}    FI.{} initialisiere warenhaus:{}  TEXT CONST verwaltung :: hauptstellenname + ".Filialverwaltung "{}                                            + text (channel (myself));{}  IF NOT exists task (verwaltung){}     THEN initialisiere verwaltung{}     ELSE biete evtl loeschen an{}  FI;{}  IF NOT initialized (in this task){}
+     THEN filialdatenname := "";{}          programmname    := ""{}  FI;{}  noch kein programm gelaufen := TRUE.{}  biete evtl loeschen an:{}    access catalogue;{}    IF NOT (father (task (verwaltung)) = myself){}       THEN fehlermeldung;{}            line;{}            end;{}            am ende loeschen := FALSE{}    FI.{}    fehlermeldung:{}      cursor (1, 22);{}      putline ("Filiale " + text (channel (myself)) +{}               " ist bereits besetzt durch TASK '"{}               + name (father (task (verwaltung))) + "'!");{}
+      putline ("Es ist so kein geregelter Warenhaus-Betrieb moeglich!").{}END PROC warenhaus;{}PROC grin (BOOL CONST entscheidung):{}  enable stop;{}  IF hauptstellenname = "" OR hauptstellenname = name (myself){}     THEN grin version := entscheidung{}     ELSE errorstop ("Dieser Befehl darf nur von der Task '" +{}                      hauptstellenname + "' aus gegeben werden!"){}  FI;{}  bildschirm neu eingesetzt := FALSE{}END PROC grin;{}PROC filialdaten verzeichnis:{}  disable stop;{}  THESAURUS VAR filialdaten ::{}
+  ohne praefix (infix namen (ALL myself, praefix, filialdatentyp), praefix);{}  forget ("Verzeichnis der Filialdaten-Dateien", quiet);{}  FILE VAR f ::{}  sequential file (output, "Verzeichnis der Filialdaten-Dateien");{}  f FILLBY filialdaten;{}  modify (f);{}  to line (f, 1); insert record (f);{}  menufootnote ("Verlassen: <ESC> <q>");{}  cursor on;{}  show (w, f);{}  cursor off;{}  forget ("Verzeichnis der Filialdaten-Dateien", quiet);{}  IF is error{}     THEN regenerate menuscreen;{}          out (""7"");{}
+          menuinfo  (" " + invers ("FEHLER: " + errormessage));{}          clear error{}     ELSE menu bildschirm{}  FI;{}  enable stop{}END PROC filialdaten verzeichnis;{}PROC warenhausprogramme verzeichnis:{}  disable stop;{}  forget ("Verzeichnis der Programme", quiet);{}  THESAURUS VAR programme ::{}  ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{}  IF exists ("WARENHAUS:Rechnung"){}     THEN programme := programme - "WARENHAUS:Rechnung"{}  FI;{}  FILE VAR f ::{}  sequential file (output, "Verzeichnis der Programme");{}
+  f FILLBY programme;{}  modify (f);{}  to line (f, 1); insert record (f);{}  menufootnote ("Verlassen: <ESC> <q>");{}  cursor on;{}  show (w, f);{}  cursor off;{}  forget ("Verzeichnis der Programme", quiet);{}  IF is error{}     THEN regenerate menuscreen;{}          out (""7"");{}          menuinfo  (" " + invers ("FEHLER: " + errormessage));{}          clear error{}     ELSE menu bildschirm{}  FI;{}  enable stop{}END PROC warenhausprogramme verzeichnis;{}PROC filialdaten zusammenstellen:{}  hole filialdatenname;{}
+  kontrolliere den filialdatennamen;{}  disable stop;{}  sichere filialdaten (praefix + filialdatenname);{}  IF is error{}     THEN out (""7"");{}          menuinfo  (" " + invers ("FEHLER: " + errormessage));{}          clear error{}     ELSE bestaetige{}  FI;{}  enable stop.{}  hole filialdatenname:{}    filialdatenname :=  menuanswer (ausgabe, filialdatenname, 5).{}  ausgabe:{}    center (maxlaenge, invers ("Filialdaten zusammenstellen")) + ""13""13""{}                   + " Bitte den Namen für die Filialdaten "13""13"".{}
+  kontrolliere den filialdatennamen:{}    IF   filialdatenname = niltext{}         THEN enable stop; LEAVE filialdaten zusammenstellen{}    ELIF length (filialdatenname) > maxnamenslaenge{}         THEN meckere zu langen namen an;{}              filialdatenname := niltext;{}              enable stop; LEAVE filialdaten zusammenstellen{}    ELIF exists (praefix + filialdatenname){}         THEN meckere existierenden filialdatennamen an;{}              enable stop; LEAVE filialdaten zusammenstellen{}
+    FI.{}    bestaetige:{}      menuinfo ("           "15"Bestätigung "14" "13""13"" +{}                "  Die  Filialdaten  wurden von der  "13"" +{}                "  Verwaltung unter dem gewünschten  "13"" +{}                "  Namen zusammengestellt.           "13"" , 3).{}END PROC filialdaten zusammenstellen;{}PROC warenhausprogramm neu erstellen:{}  hole programmname;{}  kontrolliere den programmnamen;{}  command dialogue (FALSE);{}  cursor on;{}  disable stop;{}  stdinfoedit (programmname, 3);{}
+  cursor off;{}  command dialogue (TRUE);{}  IF is error{}     THEN regenerate menuscreen;{}          out (""7"");{}          menuinfo  (" " + invers (errormessage));{}          clear error{}     ELSE menu bildschirm{}  FI;{}  enable stop.{}  hole programmname:{}    programmname := "";{}    programmname :=  menuanswer (ausgabe, programmname, 5).{}  ausgabe:{}    center (maxlaenge, invers ("Programm neu erstellen")) + ""13""13""{}                 + " Bitte den Namen für das Programm "13""13"".{}  kontrolliere den programmnamen:{}
+    IF   programmname = niltext{}         THEN LEAVE warenhausprogramm neu erstellen{}    ELIF length (programmname) > maxnamenslaenge{}         THEN meckere zu langen namen an;{}              programmname := niltext;{}              LEAVE warenhausprogramm neu erstellen{}    ELIF exists (programmname){}         THEN meckere existierendes programm an;{}              LEAVE warenhausprogramm neu erstellen{}    FI.{}END PROC warenhausprogramm neu erstellen;{}PROC warenhausprogramm ansehen:{}  IF programmname <> niltext CAND exists (programmname){}
+     THEN frage nach diesem programm{}     ELSE lasse programm auswaehlen{}  FI;{}  cursor on;{}  disable stop;{}  stdinfoedit (programmname, 3);{}  cursor off;{}  IF is error{}     THEN regenerate menuscreen;{}          out (""7"");{}          menuinfo  (" " + invers ("FEHLER: " + errormessage));{}          clear error{}     ELSE menu bildschirm{}  FI;{}  enable stop.{}  frage nach diesem programm:{}    IF menuno (ueberschrift + " Zuletzt bearbeitetes Programm: " + name{}              + " Soll mit diesem Programm gearbeitet werden", 5){}
+       THEN lasse programm auswaehlen{}    FI.{}  ueberschrift:{}    center (maxlaenge, invers ("Programm ansehen/ändern")) + ""13""13"".{}  name:{}    ""13""13" " + invers (programmname) + ""13""13"".{}  lasse programm auswaehlen:{}    THESAURUS VAR verfuegbare ::{}    ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{}    IF exists ("WARENHAUS:Rechnung"){}       THEN verfuegbare := verfuegbare - "WARENHAUS:Rechnung"{}    FI;{}    IF NOT not empty (verfuegbare){}       THEN noch kein programm;{}
+            LEAVE warenhausprogramm ansehen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    programmname := menuone (verfuegbare, "Programm ansehen/ändern",{}                             "Bitte das gewünschte Programm ankreuzen!",{}                              FALSE);{}    IF programmname = niltext{}       THEN menu bildschirm;{}            LEAVE warenhausprogramm ansehen{}    FI.{}END PROC warenhausprogramm ansehen;{}PROC filialdaten eintragen:{}  lasse filialdaten auswaehlen;{}
+  trage filialdaten ein;{}  menu bildschirm.{}  lasse filialdaten auswaehlen:{}    THESAURUS VAR verfuegbare ::{}    ohne praefix (infix namen (ALL myself,praefix,filialdatentyp),praefix);{}    IF NOT not empty (verfuegbare){}       THEN noch keine filialdaten;{}            LEAVE filialdaten eintragen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    verfuegbare := menusome (verfuegbare, bezeichnung,{}    "Bitte die Filialdaten ankreuzen, die eingetragen werden sollen!", FALSE).{}  trage filialdaten ein:{}
+    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers (bezeichnung)));{}    menuwindowline (2);{}    command dialogue (FALSE);{}    fuehre einzelne operationen aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (schlussbemerkung);{}    menuwindowstop.{}  bezeichnung:{}    "Filialdaten eintragen/ergänzen".{}  schlussbemerkung:{}    " Alle ausgewählten Filialdaten wurden eingetragen!".{}  fuehre einzelne operationen aus:{}
+    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              menuwindowout ( " Filialdaten """ + name (verfuegbare, k){}                                    + """ werden eingetragen!");{}              menuwindowline;{}              lade filialdaten (praefix + name (verfuegbare, k));{}              fehlerbehandlung{}      FI{}    PER.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}
+       THEN menuwindowline (2);{}            menuwindowout (" Es wurde keine Filialdaten-Datei ausgewählt!");{}            menuwindowstop;{}            menu bildschirm;{}            LEAVE filialdaten eintragen{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen; out (""7"");{}            menuinfo  (" " + invers (errormessage));{}
+            clear error; enable stop;{}            LEAVE filialdaten eintragen{}       ELSE enable stop{}    FI.{}END PROC filialdaten eintragen;{}PROC warenhausprogramme drucken:{}  lasse programme auswaehlen;{}  drucke programme;{}  menu bildschirm.{}  lasse programme auswaehlen:{}    THESAURUS VAR verfuegbare ::{}    ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{}    IF exists ("WARENHAUS:Rechnung"){}       THEN verfuegbare := verfuegbare - "WARENHAUS:Rechnung"{}    FI;{}    IF NOT not empty (verfuegbare){}
+       THEN noch kein programm;{}            LEAVE warenhausprogramme drucken{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    verfuegbare := menusome (verfuegbare, "Programme drucken",{}                   "Bitte die Programme ankreuzen, die gedruckt werden sollen!",{}                    FALSE).{}  drucke programme:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers ("Programme drucken")));{}    menuwindowline (2);{}    command dialogue (FALSE);{}
+    fuehre einzelne operationen aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (" Alle ausgewählten Programme wurden gedruckt!");{}    menuwindowstop.{}  fuehre einzelne operationen aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              menuwindowout ( " """ + name (verfuegbare, k) +{}                              """ wird gedruckt!");{}              menuwindowline;{}
+              print (name (verfuegbare, k));{}              fehlerbehandlung{}      FI{}    PER.{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}       THEN menuwindowline (2);{}            menuwindowout (" Es wurde kein Programm ausgewählt!");{}            menuwindowstop;{}            menu bildschirm;{}            LEAVE warenhausprogramme drucken{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}
+       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen; out (""7"");{}            menuinfo  (" " + invers (errormessage));{}            clear error; enable stop;{}            LEAVE warenhausprogramme drucken{}       ELSE enable stop{}    FI.{}END PROC warenhausprogramme drucken;{}PROC warenhausprogramm kopieren:{}  ermittle alten programmnamen;{}  erfrage neuen programmnamen;{}  kopiere ggf das programm.{}  ermittle alten programmnamen:{}    IF NOT not empty (bestand){}
+       THEN noch kein programm;{}            LEAVE warenhausprogramm kopieren{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    TEXT VAR alter name := menuone ( bestand, "Programm kopieren",{}            "Bitte das Programm ankreuzen, das kopiert werden soll!",FALSE);{}    menu bildschirm;{}    IF alter name = niltext{}       THEN LEAVE warenhausprogramm kopieren{}    FI.{}  bestand:{}    ALL myself - infix namen (ALL myself, praefix, filialdatentyp){}               - "WARENHAUS:Rechnung".{}
+  erfrage neuen programmnamen:{}    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}     ueberschrift + " Name des 'alten' Programms: " + bisheriger name{}                  + " Bitte den Namen für die Kopie: ".{}  ueberschrift:{}    center (maxlaenge, invers ("Programm kopieren")) + ""13""13"".{}  bisheriger name:{}    ""13""13" " + invers (alter name) + ""13""13"".{}  kopiere ggf das programm:{}    IF   neuer name = niltext{}         THEN menuinfo (" " + invers ("Der gewünschte Name ist unzulässig!"));{}
+              LEAVE warenhausprogramm kopieren{}    ELIF exists (neuer name){}         THEN mache vorwurf;{}              LEAVE warenhausprogramm kopieren{}       ELSE copy (alter name, neuer name){}    FI.{}  mache vorwurf:{}    menuinfo (" " + invers ("Ein Programm mit diesem Namen gibt es bereits!")).{}END PROC warenhausprogramm kopieren;{}PROC filialdaten umbenennen:{}  ermittle alten filialdatennamen;{}  erfrage neuen filialdatennamen;{}  benenne ggf die filialdaten um.{}  ermittle alten filialdatennamen:{}
+    IF NOT not empty (bestand){}       THEN noch keine filialdaten;{}            LEAVE filialdaten umbenennen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    TEXT VAR alter name := menuone ( bestand, text1, text2, FALSE);{}    menu bildschirm;{}    IF alter name = niltext{}       THEN LEAVE filialdaten umbenennen{}    FI.{}  bestand:{}    ohne praefix (infix namen (ALL myself, praefix, filialdatentyp), praefix).{}  text1: "Filialdaten umbenennen".{}  text2:{}    "Bitte die Filialdaten-Datei ankreuzen, die umbenannt werden soll!" .{}
+  erfrage neuen filialdatennamen:{}    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}     ueberschrift + hinweis auf alt + bisheriger name + aufforderung.{}  ueberschrift:{}    center (maxlaenge, invers ("Filialdaten umbenennen")) + ""13""13"".{}  hinweis auf alt:{}    " Bisheriger  Filialdaten-Name: ".{}  bisheriger name:{}    ""13""13" " + invers (alter name) + ""13""13"".{}  aufforderung:{}    " Zukünftiger Filialdaten-Name: ".{}  benenne ggf die filialdaten um:{}    IF   neuer name = niltext{}
+         THEN menuinfo (" " + invers ("Der gewünschte Name ist unzulässig!"));{}              LEAVE filialdaten umbenennen{}    ELIF exists (praefix + neuer name){}         THEN menuinfo (" " + invers("Filialdaten mit diesem Namen gibt es bereits!"));{}              LEAVE filialdaten umbenennen{}    ELSE rename (praefix + alter name, praefix + neuer name);{}         filialdatenname := neuer name{}    FI.{}END PROC filialdaten umbenennen;{}PROC warenhausprogramm umbenennen:{}  ermittle alten programmnamen;{}
+  erfrage neuen programmnamen;{}  benenne ggf das programm um.{}  ermittle alten programmnamen:{}    IF NOT not empty (bestand){}       THEN noch kein programm;{}            LEAVE warenhausprogramm umbenennen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    TEXT VAR alter name := menuone ( bestand, "Programm umbenennen",{}        "Bitte das Programm ankreuzen, das umbenannt werden soll!", FALSE);{}    menu bildschirm;{}    IF alter name = niltext{}       THEN LEAVE warenhausprogramm umbenennen{}
+    FI.{}  bestand:{}    ALL myself - infix namen (ALL myself, praefix, filialdatentyp){}               - "WARENHAUS:Rechnung".{}  erfrage neuen programmnamen:{}    TEXT VAR neuer name :: menuanswer (ausgabe, alter name, 5).{}  ausgabe:{}     ueberschrift + " Bisheriger  Programmname: " + bisheriger name{}                  + " Zukünftiger Programmname: ".{}  ueberschrift:{}    center (maxlaenge, invers ("Programm umbenennen")) + ""13""13"".{}  bisheriger name:{}    ""13""13" " + invers (alter name) + ""13""13"".{}
+  benenne ggf das programm um:{}    IF   neuer name = niltext{}         THEN menuinfo (" " + invers ("Der gewünschte Name ist unzulässig!"));{}              LEAVE warenhausprogramm umbenennen{}    ELIF exists (neuer name){}         THEN mache vorwurf;{}              LEAVE warenhausprogramm umbenennen{}       ELSE rename (alter name, neuer name);{}            programmname := neuer name{}    FI.{}  mache vorwurf:{}    menuinfo (" " + invers ("Ein Programm mit diesem Namen gibt es bereits!")).{}END PROC warenhausprogramm umbenennen;{}
+PROC filialdaten loeschen:{}  lasse filialdaten auswaehlen;{}  loesche filialdaten;{}  menu bildschirm.{}  lasse filialdaten auswaehlen:{}    THESAURUS VAR verfuegbare ::{}    ohne praefix (infix namen (ALL myself, praefix, filialdatentyp), praefix);{}    IF NOT not empty (verfuegbare){}       THEN noch keine filialdaten;{}            LEAVE filialdaten loeschen{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    verfuegbare := menusome (verfuegbare, "Filialdaten-Dateien löschen",{}    "Bitte alle Dateien ankreuzen, die gelöscht werden sollen!", FALSE).{}
+  loesche filialdaten:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers ("Filialdaten-Dateien löschen")));{}    menuwindowline (2);{}    command dialogue (FALSE);{}    fuehre einzelne operationen aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}    menuwindowout (" Alle ausgewählten Dateien wurden gelöscht!");{}    menuwindowstop.{}  fuehre einzelne operationen aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}
+      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              IF menuwindowyes (" """ + name (verfuegbare, k){}                                      + """ löschen"){}                 THEN forget (praefix + name (verfuegbare, k), quiet){}              FI;{}              fehlerbehandlung{}      FI{}    PER;{}    filialdatenname := "".{}  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}       THEN menuwindowline (2);{}            menuwindowout (" Es wurde keine Filialdaten-Datei ausgewählt!");{}
+            menuwindowstop;{}            menu bildschirm;{}            LEAVE filialdaten loeschen{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            menuinfo  (" " + invers (errormessage));{}            clear error; enable stop;{}            LEAVE filialdaten loeschen{}       ELSE enable stop{}    FI.{}
+END PROC filialdaten loeschen;{}PROC warenhausprogramme loeschen:{}  lasse programme auswaehlen;{}  loesche programme;{}  menu bildschirm.{}  lasse programme auswaehlen:{}    THESAURUS VAR verfuegbare ::{}              ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{}    IF exists ("WARENHAUS:Rechnung"){}       THEN verfuegbare := verfuegbare - "WARENHAUS:Rechnung"{}    FI;{}    IF NOT not empty (verfuegbare){}       THEN noch kein programm;{}            LEAVE warenhausprogramme loeschen{}
+       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    verfuegbare := menusome (verfuegbare, "Programm löschen",{}    "Bitte alle Programme ankreuzen, die gelöscht werden sollen!", FALSE).{}  loesche programme:{}    show menuwindow;{}    steige ggf bei leerem thesaurus aus;{}    menuwindowout (menuwindowcenter (invers ("Programme löschen")));{}    menuwindowline (2);{}    command dialogue (FALSE);{}    fuehre einzelne operationen aus;{}    command dialogue (TRUE);{}    schlage ggf neue seite auf;{}
+    menuwindowout (" Alle ausgewählten Programme wurden gelöscht!");{}    menuwindowstop.{}  fuehre einzelne operationen aus:{}    INT VAR k;{}    FOR k FROM 1 UPTO highest entry (verfuegbare) REP{}      IF name (verfuegbare, k) <> ""{}         THEN disable stop;{}              IF menuwindowyes (" """ + name (verfuegbare, k) + """ löschen"){}                 THEN forget (name (verfuegbare, k), quiet){}              FI;{}              fehlerbehandlung{}      FI{}    PER;{}    programmname := "".{}
+  steige ggf bei leerem thesaurus aus:{}    IF NOT not empty (verfuegbare){}       THEN menuwindowline (2);{}            menuwindowout (" Es wurde kein Programm ausgewählt!");{}            menuwindowstop;{}            menu bildschirm;{}            LEAVE warenhausprogramme loeschen{}    FI.{}  schlage ggf neue seite auf:{}    IF remaining menuwindowlines < 7{}       THEN menuwindowpage; menuwindowline{}       ELSE menuwindowline (2){}    FI.{}  fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen; out (""7"");{}
+            menuinfo  (" " + invers (errormessage));{}            clear error; enable stop;{}            LEAVE warenhausprogramme loeschen{}       ELSE enable stop{}    FI.{}END PROC warenhausprogramme loeschen;{}PROC warenhausprogramm starten:{}  IF grin version{}     THEN warenhausprogramm uebersetzen und starten{}     ELSE warenhausprogramm direkt starten{}  FI{}END PROC warenhausprogramm starten;{}PROC warenhausprogramm direkt starten:{}  programmname ermitteln;{}  bildschirm neu eingesetzt := FALSE;{}
+  untersuche programmdatei auf bildschirm neu;{}  cursor w3 1 1;{}  cursor (1, 24); out(""5"Das Programm wird übersetzt.  Zeilen-Nr.: ");{}  cursor on;{}  check on;{}  warnings off;{}  disable stop;{}  run (programmname);{}  noch kein programm gelaufen := FALSE;{}  IF bildschirm neu eingesetzt{}     THEN entferne befehl aus programmdatei{}  FI;{}  cursor off;{}  fehlerbehandlung;{}  cursor (2,23); out ((40 * waagerecht) + balken unten + (36 * waagerecht));{}  cursor (2,24);{}  out ("Das Programm ist beendet. " +{}
+       "Zum Weitermachen bitte irgendeine Taste tippen!");{}  pause;{}  regenerate menuscreen.{}  fehlerbehandlung:{}    IF is error{}       THEN fehler ggf melden{}       ELSE enable stop{}    FI.{}  fehler ggf melden:{}    IF errormessage = ""{}       THEN regenerate menuscreen{}       ELSE fehler melden{}    FI;{}    clear error; enable stop;{}    LEAVE warenhausprogramm direkt starten.{}  fehler melden:{}    out (""7"");{}    IF errorcode = 1  OR  errorcode = 1951{}       THEN regenerate menuscreen;{}
+            menuinfo  (" " + invers (errormessage)){}       ELSE programm mit fehler zeigen;{}            regenerate menuscreen{}    FI.{}  programmname ermitteln:{}    IF programmname <> niltext CAND exists (programmname){}       THEN frage nach diesem programm{}       ELSE lasse programm auswaehlen{}    FI.{}  frage nach diesem programm:{}    IF menuno (ueberschrift + " Zuletzt bearbeitetes Programm: " +{}               name + " Soll mit diesem Programm gearbeitet werden", 5){}       THEN lasse programm auswaehlen{}
+    FI.{}  ueberschrift:{}    center (maxlaenge, invers ("Programm starten")) + ""13""13"".{}  name:{}    ""13""13" " + invers (programmname) + ""13""13"".{}  lasse programm auswaehlen:{}    THESAURUS VAR verfuegbare ::{}              ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{}    IF exists ("WARENHAUS:Rechnung"){}       THEN verfuegbare := verfuegbare - "WARENHAUS:Rechnung"{}    FI;{}    IF NOT not empty (verfuegbare){}       THEN noch kein programm;{}            LEAVE warenhausprogramm direkt starten{}
+       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    programmname := menuone (verfuegbare, "Programm starten",{}                    "Bitte das gewünschte Programm ankreuzen!", FALSE);{}    menubildschirm;{}    menufootnote ("");{}    IF programmname = niltext{}       THEN LEAVE warenhaus programm direkt starten{}    FI.{}  untersuche programmdatei auf bildschirm neu:{}    FILE VAR a :: sequential file (modify, programmname);{}    TEXT VAR zeile;{}    to line (a, 1);{}    REP{}      read record (a, zeile);{}
+      IF NOT eof (a) THEN down (a) FI{}    UNTIL zeile <> "" OR eof (a) PER;{}    change all (zeile, " ", "");{}    IF pos (zeile, "bildschirmneu") = 0{}       THEN setze befehl in datei ein{}    FI.{}  setze befehl in datei ein:{}    to line (a, 1);{}    zeile := "bildschirm neu; (* ergänzt *)";{}    insert record (a);{}    write record (a, zeile);{}    bildschirm neu eingesetzt := TRUE.{}  entferne befehl aus programmdatei:{}    FILE VAR b :: sequential file (modify, programmname);{}    to line (b, 1);{}
+    REP{}      read record (b, zeile);{}      IF NOT eof (b) THEN down (b) FI{}    UNTIL zeile <> "" OR eof (b) PER;{}    change all (zeile, " ", "");{}    IF pos (zeile, "bildschirmneu;(*ergänzt*)") > 0{}       THEN up (b); delete record (b){}    FI.{}END PROC warenhausprogramm direkt starten;{}PROC warenhausprogramm uebersetzen und starten:{}  programmname ermitteln;{}  cursor w3 1 1;{}  cursor (1, 24); out(""5"Das Programm wird übersetzt.  Zeilen-Nr.: ");{}  cursor on;{}  disable stop;{}  uebersetze (programmname);{}
+  IF NOT is error{}     THEN check on;{}          warnings off;{}          run ("elanprogramm");{}          noch kein programm gelaufen := FALSE{}  FI;{}  forget ("elanprogramm", quiet);{}  cursor off;{}  fehlerbehandlung;{}  cursor (2,23); out ((40 * waagerecht) + balken unten + (36 * waagerecht));{}  cursor (2,24);{}  out ("Das Programm ist beendet. " +{}       "Zum Weitermachen bitte irgendeine Taste tippen!");{}  pause;{}  regenerate menuscreen.{}  fehlerbehandlung:{}    IF is error{}       THEN fehler ggf melden{}
+       ELSE enable stop{}    FI.{}  fehler ggf melden:{}    IF errormessage = ""{}       THEN regenerate menuscreen{}       ELSE fehler melden{}    FI;{}    clear error; enable stop;{}    LEAVE warenhausprogramm uebersetzen und starten.{}  fehler melden:{}    out (""7"");{}    IF errorcode = 1  OR  errorcode = 1951{}       THEN regenerate menuscreen;{}            menuinfo  (" " + invers (errormessage)){}       ELSE programm mit fehler zeigen ;{}            regenerate menuscreen{}    FI.{} programmname ermitteln:{}
+    IF programmname <> niltext CAND exists (programmname){}       THEN frage nach diesem programm{}       ELSE lasse programm auswaehlen{}    FI.{}  frage nach diesem programm:{}    IF menuno (ueberschrift + " Zuletzt bearbeitetes Programm: " +{}               name + " Soll mit diesem Programm gearbeitet werden", 5){}       THEN lasse programm auswaehlen{}    FI.{}  ueberschrift:{}    center (maxlaenge, invers ("Programm starten")) + ""13""13"".{}  name:{}    ""13""13" " + invers (programmname) + ""13""13"".{}
+  lasse programm auswaehlen:{}    THESAURUS VAR verfuegbare ::{}              ALL myself - infix namen (ALL myself, praefix, filialdatentyp);{}    IF exists ("WARENHAUS:Rechnung"){}       THEN verfuegbare := verfuegbare - "WARENHAUS:Rechnung"{}    FI;{}    IF NOT not empty (verfuegbare){}       THEN noch kein programm;{}            LEAVE warenhausprogramm uebersetzen und starten{}       ELSE biete auswahl an{}    FI.{}  biete auswahl an:{}    programmname := menuone (verfuegbare, "Programm starten",{}
+                    "Bitte das gewünschte Programm ankreuzen!", FALSE);{}    menubildschirm;{}    menufootnote ("");{}    IF programmname = niltext{}       THEN LEAVE warenhaus programm uebersetzen und starten{}    FI.{}END PROC warenhausprogramm uebersetzen und starten;{}PROC programm mit fehler zeigen:{}  IF exists (programmname){}    THEN noteline;{}         note (fehlermeldung mit zeilennummer);{}         INT VAR i; FOR i FROM 1 UPTO 9 REP noteline PER;{}         note (invers ("Verlassen: <ESC><q>"));{}
+         FILE VAR f :: sequential file (modify, programmname);{}         to line (f, max (1, fehlerzeile));{}         col (1);{}         clear error;{}         cursor on;{}         noteedit (f);{}        cursor off{}    ELSE menuinfo (invers (fehlermeldung mit zeilennummer)){}  FI{}END PROC programm mit fehler zeigen;{}PROC warenhausprogramm wiederholen:{}  cursor on;{}  disable stop;{}  IF noch kein programm gelaufen{}     THEN errorstop ("'run again' nicht moeglich"){}     ELSE runagain{}  FI;{}
+  cursor off;{}  fehlerbehandlung;{}  cursor (2,23); out ((40 * waagerecht) + balken unten + (36 * waagerecht));{}  cursor (2,24);{}  out ("Das Programm ist beendet. " +{}       "Zum Weitermachen bitte irgendeine Taste tippen!");{}  pause;{}  regenerate menuscreen.{}fehlerbehandlung:{}    IF is error{}       THEN regenerate menuscreen;{}            fehler melden;{}            clear error; enable stop;{}            LEAVE warenhausprogramm wiederholen{}       ELSE enable stop{}    FI.{}  fehler melden:{}
+    out (""7"");{}    IF errorcode = 1  OR  errorcode = 1951{}       THEN menuinfo  (" " + invers (errormessage)){}    ELIF errormessage = "'run again' nicht moeglich"{}       THEN menuinfo  (" " + invers ("Wiederholung nicht möglich!")){}       ELSE menuinfo  (" " + invers (fehlermeldung mit zeilennummer)){}    FI{}END PROC warenhausprogramm wiederholen;{}TEXT PROC fehlermeldung mit zeilennummer:{}  TEXT VAR meldung :: "FEHLER: " + errormessage;{}  fuege ggf fehlerzeile an;{}  IF length (meldung) < 70{}
+     THEN meldung{}     ELSE subtext (meldung, 1, 69){}  FI.{}  fuege ggf fehlerzeile an:{}    fehlerzeile := errorline;{}    IF errorline < 1{}       THEN LEAVE fuege ggf fehlerzeile an{}    ELIF bildschirm neu eingesetzt{}       THEN meldung CAT " (bei Zeile " + text (errorline - 1) + ")"{}       ELSE meldung CAT " (bei Zeile " + text (errorline) + ")"{}    FI.{}END PROC fehlermeldung mit zeilennummer;{}PROC meckere zu langen namen an:{}  menuinfo (" " + invers ("Hier dürfen Namen höchstens "{}
+                + text (max namenslaenge){}                + " Zeichen lang sein!")){}END PROC meckere zu langen namen an;{}PROC meckere existierenden filialdatennamen an:{}  menuinfo (" " + invers ("Filialdaten mit diesem Namen gibt es bereits!")){}END PROC meckere existierenden filialdatennamen an;{}PROC meckere existierendes programm an:{}  menuinfo (" " + invers ("Ein Programm mit diesem Namen gibt es bereits!")){}END PROC meckere existierendes programm an;{}PROC noch keine filialdaten:{}  menuinfo (" " + invers ("Es existiert noch keine Filialdaten-Datei!")){}
+END PROC noch keine filialdaten;{}PROC noch kein programm:{}  menuinfo (" " + invers ("Es existiert noch kein Programm!")){}END PROC noch kein programm;{}PROC menu bildschirm:{}  cursor (1, 2);{}  out (5 * waagerecht);{}  cursor (1, 3);{}  out (""4"");{}  cursor (1, 23);{}  out (79 * waagerecht);{}  refresh submenu{}END PROC menu bildschirm{}END PACKET ls warenhaus 5{}
+
diff --git a/warenhaus/ls-Warenhaus-gen b/warenhaus/ls-Warenhaus-gen
new file mode 100644
index 0000000..f4bd77f
--- /dev/null
+++ b/warenhaus/ls-Warenhaus-gen
@@ -0,0 +1,29 @@
+(* 
+        
+         ********************************************************** 
+         ********************************************************** 
+         **                                                      ** 
+         **                   ls-Warenhaus/gen                   ** 
+         **                                                      ** 
+         **                     Version 1.01                     ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                  (Stand:  30.08.89)                  ** 
+         **                                                      ** 
+         **                                                      ** 
+         **                                                      ** 
+         **           Autor: Bruno Pollok, Bielefeld             ** 
+         **                                                      ** 
+         **    Copyright (C) 1988  Eva Latta-Weber, Bielefeld    ** 
+         **    Copyright (C) 1990  ERGOS GmbH, Siegburg          ** 
+         **                                                      ** 
+         ********************************************************** 
+         ********************************************************** 
+ 
+                                                                           *) 
+LET kartenleserkennung = "ls-Warenhaus 0: mit Kartenleser";
+baue bildschirm auf;{}schicke menukarte ab;{}erfrage anpassung;{}check off;{}warnings off;{}insertiere (anpassung);{}loesche alle anpassungen;{}insertiere ("ls-Warenhaus 1");{}insertiere ("ls-Warenhaus 2");{}insertiere ("ls-Warenhaus 3");{}insertiere ("ls-Warenhaus 4");{}insertiere ("ls-Warenhaus 5");{}check on;{}frage nach grin;{}frage nach hauptstelle.{}baue bildschirm auf:{}  page;{}  cursor (18, 1);{}  out (invers ("ls-Warenhaus :  Automatische Generierung"));{}  line (3).{}erfrage anpassung:{}
+  WINDOW VAR w :: window (1, 1, 79, 24);{}  TEXT VAR anpassung :: boxone (w, alle kartenleser,{}           "Auswahl einer Interface - Anpassung für den Codekartenleser",{}           "Wenn kein Kartenleser benutzt wird, <ESC><q> tippen!", FALSE);{}  IF anpassung = ""{}     THEN anpassung := "ls-Warenhaus 0: ohne Kartenleser"{}  FI;{}  baue bildschirm auf.{}alle kartenleser:{}  infix namen (ALL myself, kartenleserkennung).{}loesche alle anpassungen:{}  command dialogue (FALSE);{}  forget (infixnamen (ALL myself, "ls-Warenhaus 0"));{}
+  forget ("--------------------------------------------------------",quiet);{}  command dialogue (TRUE).{}schicke menukarte ab:{}  command dialogue (FALSE);{}  save ("ls-MENUKARTE:Warenhaus", /"ls-MENUKARTEN");{}  command dialogue (TRUE);{}  forget ("ls-MENUKARTE:Warenhaus", quiet);{}  forget ("ls-Warenhaus/gen", quiet).{}frage nach grin:{}  line;{}  IF yes ("Version für GRIN"){}     THEN do ("grin (TRUE)"){}     ELSE do ("grin (FALSE)"){}  FI.{}frage nach hauptstelle:{}  line (2);{}  IF yes ("Soll diese Task Warenhaus - Hauptstelle sein"){}
+     THEN do ("warenhaus hauptstelle (TRUE)"){}     ELSE global manager{}  FI.{};{}PROC insertiere (TEXT CONST dateiname):{}  INT VAR s, z;{}  out ("'" + dateiname + "'");{}  get cursor (s, z);{}  out (" wird insertiert.  ");{}  insert (dateiname);{}  forget (dateiname, quiet);{}  cursor (s, z);{}  out (""4"") ;{}  line{}END PROC insertiere{}
+
-- 
cgit v1.2.3