diff options
Diffstat (limited to 'doc/porting-mc68k')
| -rw-r--r-- | doc/porting-mc68k/1985.11.26/doc/Port.68000 | 2173 | ||||
| -rw-r--r-- | doc/porting-mc68k/1985.11.26/source-disk | 1 | 
2 files changed, 2174 insertions, 0 deletions
| diff --git a/doc/porting-mc68k/1985.11.26/doc/Port.68000 b/doc/porting-mc68k/1985.11.26/doc/Port.68000 new file mode 100644 index 0000000..0ca6840 --- /dev/null +++ b/doc/porting-mc68k/1985.11.26/doc/Port.68000 @@ -0,0 +1,2173 @@ +#type ("trium8")##limit (12.0)#  +#start(2.0,1.5)#  +#type("triumb36")#  +#free(4.0)#  +   EUMEL  +   Portierungs  +   handbuch  +   MC68000  +#type("triumb18")#  +#free(1.5)#  +      Stand 26.11.85  +#page(1)#  +#type ("trium8")##limit (12.0)#  +#block#  +#pagelength(18.4)#  +#head#  +#center#- % -  +  +  +#end#  +#type("triumb12")#Inhalt#a#  +  +  +  +Teil 1: Einführung                                     #topage("ein")#  +#free(0.3)#  +        Zweck dieses Handbuchs                         #topage("zweck")#  +        Referenzliteratur                              #topage("reflit")#  +        Minimale Hardwarevoraussetzungen               #topage("hardw")#  +        Systemdurchsatz                                #topage("durchsatz")#  +        Softwarekomponenten des EUMEL-Systems          #topage("kompo")#  +        Anlieferung des MC68000-EUMEL-Systems          #topage("anlief")#  +  +Teil 2: Allgemeine Strukturen                          #topage("allgem")#  +#free(0.3)#  +        Hintergrund                                    #topage("hg")#  +        Archiv                                         #topage("arch")#  +        Hauptspeicher                                 #topage("speicher")#  +  +Teil 3: SHard-Interface Spezifikation                 #topage("shardifc")#  +#free(0.3)#  +   0. Vorbemerkungen                                  #topage("vor")#  +        Zur Notation                                  #topage("not")#  +        Link-Leisten                                  #topage("leist")#  +        Allgemeine Link-Bedingungen                   #topage("link")#  +        Interrupts                                    #topage("intr")#  +   1. System laden                                    #topage("laden")#  +   2. Systemstart und -ende                           #topage("start")#  +   3. Speicherverwaltung                              #topage("spver")#  +      Hauptspeicher                                   #topage("haupt")#  +      Speicherfehler                                  #topage("memerr")#  +   4. Zeitgeber                                       #topage("zeit")#  +   5. Kanäle                                          #topage("channel")#  +   5.1  Stream-IO                                     #topage("stream")#  +        Terminals                                     #topage("term")#  +        Drucker, Plotter                              #topage("druck")#  +        Exoten                                        #topage("exot")#  +   5.2  Block-IO                                      #topage("block")#  +        Block-IO bei Hintergrund und Archiv           #topage("bhgarch")#  +   5.3  I/O-Steuerung                                 #topage("iocontrol")#  +        Konfigurierung serieller Schnittstellen       #topage("v24")#  +        Flußkontrolle                                 #topage("fluss")#  +        Kalender                                      #topage("kalender")#  +   6. SHard-Interface Version                         #topage("shdver")#  +   7. ID-Konstanten                                   #topage("ID")#  +   8. Zusätzliche Leistungen                          #topage("shdelan")#  +   9. Spezialroutinen                                 #topage("ke")#  +  +Teil 4: Tips zur Portierung                           #topage("tips")#  +#free(0.3)#  +        Nullversion des SHards                        #topage("0ver")#  +        Typische Fehler                               #topage("fehler")#  +        Effizienzprobleme                             #topage("eff")#  +  +Anhang A: EUMEL-Debugger "Info"                       #topage("info")#  +#free(0.3)#  +        Aufruf des Infos                              #topage("aufrinf")#  +        Info-Format                                   #topage("forminf")#  +        Info-Kommandos                                #topage("cmdinf")#  +        Einige Systemadressen                         #topage("sysaddr")#  +        Leitblock                                     #topage("pcb")#  +  +Anhang B: Einige EUMEL-Begriffe                       #topage("glossar")#  +#page#  +#cc("Teil 1: ","Einführung")##goalpage("ein")#  +  +  +#b("Zweck dieses Handbuchs")##goalpage("zweck")#  +  +Dieses Portierungshandbuch wendet sich an diejenigen, die das EUMEL-System auf +einem neuen Rechnertyp implementieren wollen. Es ist Teil einer Serie von Portierungs +handbüchern für verschiedene Prozessortypen. Dieses bezieht sich auf Rechner mit +MC68000-Prozessoren.  +  +Zum Betrieb eines EUMEL-Systems wird dieses Handbuch nicht benötigt!  +  +  +  +#b("Referenzliteratur")##goalpage("reflit")#  +  +  +    "EUMEL Benutzerhandbuch"  +  +    "EUMEL Systemhandbuch"  +  +    "EUMEL Quellcode der insertierten ELAN-Pakete"  +  +    "MC68000 16-bit microprocessor  -  Users Manual"  +    Motorola, 1982  +  +    "68000 Assembler Reference"  +    XENIX Group, Microsoft Corp., 1982  +  +    "Anhang zu '68000 Assembler Reference'"  +    TA Nürnberg, 1984  +  +  +Siehe auch die Vorbemerkungen zur Notation in Teil 3 (S. #topage("not")#), sowie die Begriffserklä +rungen im Anhang B (S. #topage("glossar")#).  +  +  +#b("Minimale Hardwarevoraussetzungen")##goalpage("hardw")#  +  +Um das EUMEL-System effizient einsetzen zu können, sollte die Hardware mindestens +folgenden Kriterien genügen:  +  +    #ib#CPU#ie#           Die MC68000-CPU sollte mit mindestens 8.0 MHz arbeiten. Falls die +                  Buszugriffe durch einen CRTC o.ä. verlangsamt werden, sollte die +                  echte MC68000-Leistung durchschnittlich mindestens einem unge +                  bremsten 8.0 MHz System entsprechen.  +                  Seltene Verlangsamungen (z.B. nur bei I/O-Operationen) spielen bei +                  diesen Überlegungen keine Rolle.  +  +    RAM           Das System sollte über mindestens 256 KByte #ib#Hauptspeicher#ie# verfü +                  gen.  +  +    #ib#Hintergrund#ie#   Als Hintergrundmedium sind #ib#Diskette#ie#, #ib#Platte#ie# und RAM bzw. ROM +                  denkbar.  +  +                  Kapazität:  +                        > 300 K, besser > 400 K (Single-User)  +                        > 750 K, besser > 1000 K (Multi-User)  +  +                  Zugriff: *)  +#foot#  +#f#*) Hier ist die durchschnittliche Zugriffszeit auf einen 512 Byte großen Block gemeint. Für Platten und Disketten kann +man sie als Summe der Positionierzeit über die halbe Anzahl der Spuren und der Zeit einer halben Umdrehung be +rechnen.  +#a#  +#end#  +                        < 500 ms  (Single-User)  +                        < 200 ms  (Multi-User)  +  +    #ib#Archiv#ie#        Als Archiv wird meistens eine Diskette eingesetzt. Aber auch Band +                  oder Kassette sind denkbar. Die Anforderungen an Kapazität und +                  Geschwindigkeit sind anwendungsspezifisch.  +  +    #ib#Bildschirm#ie#    Angestrebt werden sollte ein Bildschirm mit 24 Zeilen zu je 80 Zeichen +                  (oder größer). Kleinere Bildschirme sind anschließbar, aber mit 40 Zei +                  chen pro Zeile läßt sich nicht mehr komfortabel arbeiten.  +                  Rollup und freie Cursorpositionierung sind notwendige Voraussetzun +                  gen, invers-video ist erwünscht, aber nicht notwendig. Weiterhin +                  werden die Funktionen 'Löschen bis Zeilenende' und 'Löschen bis +                  Schirmende' benötigt.  +  +    #ib#Tastatur#ie#      An Steuertasten sollten mindestens ESC und die vier Cursortasten +                  vorhanden sein. Dabei ist es günstig, wenn die Cursortasten ergono +                  misch als Block bzw. Kreuz angeordnet sind. EUMEL benötigt weitere +                  Steuertasten für HOP, RUBIN, RUBOUT und MARK. Dafür können +                  beliebige, anderweitig nicht benötigte Tasten der Tastatur gewählt +                  werden.  +  +  +  +#b("Systemdurchsatz")##goalpage("durchsatz")#  +  +Da das EUMEL-System auf dem Prinzip des Demand Paging aufbaut, hängt der System +durchsatz von  +  +    - CPU Leistung  +    - Speichergröße (RAM)  +    - Geschwindigkeit beim Hintergrundzugriff (Diskette, Platte)  +  +ab. Mit zunehmender Benutzerzahl steigen in der Regel die Anforderungen an das Paging +(Hintergrund-Zugriff) schneller als an die CPU. In diesem Bereich kann man die System +leistung dann durch mehr Speicher und/oder eine schnellere Platte in größerem Umfang +steigern. Dabei läßt sich eine langsame Platte teilweise durch mehr RAM und umgekehrt +wenig RAM durch eine schnelle Platte ausgleichen.  +  +  +  +#b("Softwarekomponenten des EUMEL-Systems")##goalpage("kompo")#  +  +Das EUMEL-System besteht aus mehreren Schichten:  +  +  +          EUMEL  2:   Standardpakete, Editor, ...  +  +          EUMEL  1:   ELAN Compiler  +  +          EUMEL  0:   Systemkern (EUMEL-0-Maschine, EUMEL-0)  +  +          EUMEL -1:   SHard  +  +                  H a r d w a r e  +  +  +Dieses #ib#Schichtenmodell#ie# ist nach oben offen und kann deshalb um beliebig viele (höhere) +Schichten erweitert werden.  +  +EUMEL > 0    Die Standardsoftware der Schichten > 0 ist in der Sprache ELAN ge +             schrieben (siehe "EUMEL Quellcode"). Dementsprechend sind alle Schich +             ten oberhalb der EUMEL-0-Maschine prozessor- und rechnerunabhän +             gig, d.h. Anpassungen an einen neuen Rechnertyp sind nicht erforderlich.  +  +EUMEL   0    Die sogenannte "EUMEL-0-Maschine" enthält alle Basisoperationen und +             hängt davon ab, welchen Prozessortyp der Rechner als CPU verwendet. Sie +             existiert für verschiedene Prozessortypen. Hier wird nur auf den Typ +             MC68000 Bezug genommen. Bei der Portierung auf einen MC68000- +             Rechner wird die MC68000-EUMEL-0-Maschine ohne Anpassungen (!) +             übernommen.  +  +EUMEL  -1    Diese Schicht stellt das Interface zwischen der EUMEL-0-Maschine und +             der eigentlichen Hardware (vom Prozessor abgesehen) dar. Insbesondere +             umfaßt sie alle Routinen zur Ansteuerung peripherer Geräte (Gerätetreiber). +             Diese Schicht wird "SHard" genannt ("S"oftware-"Hard"ware Interface).  +  +Der SHard ist der einzige Teil des Systems, der bei der Portierung auf einen MC68000- +Rechner angepaßt bzw. neu geschrieben werden muß. Deshalb besteht der größte Teil +dieses Handbuchs aus der Spezifikation des MC68000-SHards.  +  +  +  +#b("Anlieferung des MC68000-EUMEL-Systems")##goalpage("anlief")#  +  +Der Implementierer erhält die EUMEL-Software auf Disketten. Dabei stehen folgende +Standardformate zur Wahl:  +  +    Diskette 200 (8"), 1D, 77 Spuren, 16 Sektoren (\#0...\#15) zu 512 Byte  +  +    Diskette 130 (5.25"), 2D, 40 Spuren, 9 Sektoren (\#1...\#9) zu 512 Byte *)  +#foot#  +#f#*) 48 tpi  +#a#  +#end#  +  +  +Die Diskettenlieferung **) enthält  +#foot#  +#f#**) Zu Inhalt und Zweck der angelieferten Disketten siehe EUMEL Systemhandbuch, Teil 1: System einrichten.  +#a#  +#end#  +  +    - Single-User Hintergrund  +    - Multi-User Hintergrund  +    - Standardarchive  +    - ggfs. Archive mit weiterer Anwendersoftware (installationsspezifisch)  +  +Dabei enthält der Hintergrund auch die EUMEL-0-Maschine (oft auch als "Urlader" +bezeichnet).  +  +#on("i")#Bitte gehen Sie vorsichtig mit diesen Mutterdisketten um. Verwenden Sie sie nur als +Quelle beim Kopieren. Sie sollten nur auf Kopien davon arbeiten!#off("i")#  +#page#  +#cc("Teil 2: ","Allgemeine Strukturen")##goalpage("allgem")#  +  +  +#b("Hintergrund")##goalpage("hg")#  +  +Der Hintergrund ist in 512 Bytes große Blöcke unterteilt. Sie werden durch Blocknummern +(0, 1, 2, ...) adressiert. Die physische Ablage der Blöcke auf dem Hintergrundmedium +bleibt dem SHard überlassen. Er kann sie z.B. linear oder versetzt anordnen. Man sollte +darauf achten, daß Positionierungen auf logisch "nahe" Blöcke möglichst schnell gehen +sollten. Deshalb ist in der Regel zylinderorientierte Anordnung der oberflächenorientierten +vorzuziehen.  +  +Falls auf dem Hintergrundmedium spezielle Blöcke z.B. für Bootstrap und SHard freige +halten werden sollen, muß das bei der Abbildung der Hintergrundblocknummern auf die +Sektoren der Diskette bzw. der Platte berücksichtigt werden.  +  +Aufbau des Hintergrundes:  +  +    Block  0                Systemetikett  +  +    Block  10...10+k-1      EUMEL-0-Maschine (z.Zt. ist k=200; dieser Wert ist nur +                            für EUMEL-0 von Bedeutung)  +  +    Block  1...9, 10+k ...  Paging-Bereich  +  +  +Aufbau des #ib#Systemetikett#ie#s (#ib#Block 0#ie#):  +  +    Byte        Wert/Aufgabe  +  +    0...5       "EUMEL-"; Kennzeichen für EUMEL-Hintergrund.  +    6...11      Versionsnummer in druckbaren Zeichen. Sie stellt sicher, daß System- +                kern und Hintergrund kompatibel sind.  +    12          zur Zeit ohne Bedeutung  +    13          enthält Wert 0 , wenn System im Shutupzustand ist.  +    14..15      Systemlaufzähler (14=low, 15=high). Wird bei jedem Systemstart um 1 +                erhöht.  +    16..35      Reserviert; zur Zeit ohne Bedeutung  +    36..37      Aus historischen Gründen für interne Zwecke belegt.  +    38..69      Hier kann eine Installationsnummer geführt werden.  +    70..79      Info-Paßwort  +    80          =0 Normalzustand  +                =1 Kompresslauf erforderlich (System frisch von Archiv geladen)  +    81...255    Reserviert.  +    256..511    Kann von SHard beliebig verwendet werden.  +  +  +  +#b("Archiv")##goalpage("arch")#  +  +Wie der Hintergrund, sind die Archive in 512 Bytes große Blöcke unterteilt *). Bisher gibt +es folgende #d("Standardformate")#:  +#foot#  +#f#*) Der genaue Aufbau der Archivblöcke ist weder für den SHard-Implementierer, noch für den Benutzer von Be +deutung. SHard hantiert nur mit Blöcken aufgrund von Blocknummern, unabhängig vom Inhalt der Blöcke. Der Benut +zer "sieht" nur Datenräume bzw. Dateien, unabhängig von ihrem Format auf dem Archiv.  +#a#  +#end#  +  +  +    Diskette 200 (8"), 1D, 77 Spuren, 16 Sektoren (\#0...\#15) zu 512 Byte  +    Diskette 200 (8"), 2D, 77 Spuren, 16 Sektoren (\#0...\#15) zu 512 Byte  +  +      Block       Seite             Spur             Sektor  +  +        0           0                 0                 0  +       16           0                 1                 0  +      77*16         1                 0                 0  +  +        n     n DIV (77*16)   n MOD (77*16) DIV 16   n MOD 16  +  +  +    Diskette 130 (5.25"), 2D, 40 Spuren, 9 Sektoren (\#1...\#9) zu 512 Byte  +  +      Block       Seite             Spur             Sektor  +  +        0           0                 0                 1  +        9           0                 1                 1  +      40*9          1                 0                 1  +  +        n     n DIV (40*9)    n MOD (40*9) DIV 9   n MOD 9 + 1  +  +  +     Diskette 130 (5.25"), 2D, 80 Spuren, 9 Sektoren (\#1...\#9) zu 512 Byte  +  +       Block       Seite             Spur             Sektor  +  +         0           0                 0                 1  +         9           0                 1                 1  +       80*9          1                 0                 1  +  +         n     n DIV (80*9)   n MOD (80*9) DIV 9    n MOD 9 + 1  +  +  +     Diskette 130 (5.25"), HD, 80 Spuren, 15 Sektoren (\#1...\#15) zu 512 Byte  +  +       Block       Seite             Spur             Sektor  +  +         0           0                 0                 1  +        15           0                 1                 1  +       80*15         1                 0                 1  +  +         n   n DIV (80*15)   n MOD (80*15) DIV 15    n MOD 15 + 1  +  +  +Selbstverständlich können auch andere #ib#Archivformate#ie# implementiert werden, falls das aus +Hardwaregründen notwendig ist oder sich dadurch wesentliche Verbesserungen (z.B. in +der Kapazität) ergeben.  +  +Wenn irgend möglich sollte aber mindestens eines der oben aufgeführten Standardformate +unterstützt werden - evtl. als zusätzliches Format -, um den Austausch zwischen ver +schiedenen Rechnertypen zu vereinfachen.  +  +#on("i")#Hinweis:  Um den Datenaustausch zwischen verschiedenen Rechnertypen zu vereinfa +          chen, sollten möglichst alle hardwaremäßig möglichen Standardformate (min +          destens lesend) unterstützt werden. Dabei sollte SHard sich automatisch auf +          das Format der jeweils eingelegten Diskette einstellen:#off("i")#  +  +  +            Laufwerkstyp      Diskettentyp(en)  +  +               8" 1D              8" 1D  +               8" 2D              8" 2D, 1D  +  +               5" 2D-40           5" 2D-40  +               5" 2D-80           5" 2D-80, 2D-40 *)  +               5" HD-80           5" HD-80, 2D-80, 2D-40 *)  +  +#foot#  +#f#*) Bei der Behandlung von 40-Spur-Disketten auf 80-Spur-Laufwerken gelten meistens folgende Regeln:  +     a) Lesen funktioniert sicher.  +     b) Schreiben ist unsicher, funktioniert aber häufig.  +     c) Formatieren funktioniert fast nie.  +#a#  +#end#  +  +  +  +#b("Hauptspeicher")##goalpage("speicher")#  +  +Der #ib#Speicher#ie# wird EUMEL-0 vom SHard in maximal vier Speicherbereichen (M0...M3) +zugewiesen. Die Anfangsadresse eines solchen Bereiches muß ein Vielfaches von 512B +sein. M0 muß immer vorhanden sein, M1, M2 und M3 nur in speziellen Betriebsarten:  +  +     #d("M0")#   #on("b")#allgemeines #ib#RAM#ie(1,", allgemeines")##off("b")#  +          Dieser Bereich muß immer vorhanden sein. Bei den meisten Rechnern liegt der +          Systemkern nicht in einem ROM, sondern wird von SHard in das RAM geladen. +          Das geschieht dann an den Anfang von M0. Der Rest wird für Tabellen und als +          Pagingbereich benutzt. M0 umfaßt deshalb meistens allen verfügbaren Spei +          cher, bis auf den Platz für SHard, Boot-ROM und Bildwiederholspeicher. **)  +#foot#  +#f#**) Der im Tabellenspeicher liegende 'ktab' ist für die Verwaltung von max. 2048 Kacheln (=1MB) ausgelegt. Der +Speicherbedarf des Systemkerns liegt bei 80KB, für Tabellen werden 40KB benötigt. Dies sollte man bei der Angabe +von M0SIZE berücksichtigen.  +#a#  +#end#  +  +     #d("M1")#   #on("b")#Systemkern-#ib#ROM#ie(1,", Systemkern")##off("b")#  +          Gibt es nur bei Rechnern, die den Systemkern in einem ROM haben. (M0 wird +          dann nur für Tabellen und als Pagingspeicher eingesetzt.)  +  +     #d("M2")#   #on("b")#Hintergrund-#ib#ROM#ie(1,",Hintergrund")##off("b")#  +          Gibt es nur bei Rechnern, die nicht Diskette oder Platte sondern ROM und +          RAM als Hintergrundspeicher verwenden.  +  +     #d("M3")#   #on("b")#Hintergrund-#ib#RAM#ie(1,",Hintergrund")##off("b")#  +          Gibt es nur bei Rechnern, die nicht Diskette oder Platte sondern ROM und +          RAM oder RAM allein als Hintergrundspeicher verwenden.  +  +Damit sind drei verschiedene Betriebsarten des EUMEL-Systems möglich:  +  +     #d("Normalbetrieb")#:     M0  (> 256 KB)  +                        Hintergrundgerät (Platte oder Diskette)  +                        Archivgerät (Diskette)  +  +          Im Normalbetrieb befindet sich der Hintergrund auf einer Platte oder Diskette +          RAM wird für den Systemkern und zum Paging eingesetzt. Alle mittleren und +          größeren Systeme verwenden den Normalbetrieb.  +  +  +     #d("Minibetrieb")#:       M0  (> 256 KB)  +                        M3  (mindestens 300 KB)  +                        Archivgerät (Diskette)  +  +          Im Minibetrieb wird RAM als Hintergrundspeicher eingesetzt. Dieser wird beim +          Einschalten über das Archivgerät geladen und beim Abschalten ('shutup') +          wieder zurückgeschrieben.  +  +  +     #d("ROM-Betrieb")#:       M0  (>40 KB)  +                        M1  (>60 KB)  +                        M2  (>170 KB)  +                        M3  (>60 KB)  +                        Archivgerät (Kassettenrecorder oder Diskettenlaufwerk)  +  +          Im ROM-Betrieb stehen Systemkern und Standardteil des Hintergrundes im +          ROM. Der übrige Hintergrund befindet sich im RAM. *)  +#foot#  +#f#*) Für ROM-Betrieb benötigt man eine Spezialversion des Systemkerns.  +#a#  +#end#  +  +#page#  +#cc("Teil 3: SHard ","Interface Spezifikation")##goalpage("shardifc")#  +  +  +#bb("0.  ","Vorbemerkungen")##goalpage("vor")#  +  +  +#b("Zur Notation")##goalpage("not")#  +  +Im folgenden wird zwischen #d("0-Routinen")#, die dem SHard vom EUMEL-0-System zur +Verfügung gestellt werden, und  +#d("SHard-Routinen")# unterschieden, die der SHard implementieren muß. Damit dieser Unter +schied bei der Spezifikation deutlich wird, werden 0-Routinen folgendermaßen aufgeführt:  +  +          name       (0-Routine)  +  +Zusätzlich werden 0-Routinen grundsätzlich klein und SHard-Routinen groß geschrie +ben.  +  +MC68000-Befehle werden wie im "Anhang zu '68000 Assembler Reference'", (TA, 1984) +notiert:  +  +          moveq  \#27,d0  +          addw   d3,d1  +  +  +Hexadezimale Zahlen werden durch ein vorangestelltes '/' gekennzeichnet:  +  +          /12    = 18  +          /1f    = 31  +          /ffff  = 65535  +  +  +Achtung: Die Übergabe von Integer-Parametern zwischen SHard und EUMEL-0 erfolgt +         grundsätzlich in den niederwertigen 16 Bits des jeweils angegebenen Daten +         registers.  +  +#b("Link-Leisten")##goalpage("leist")#  +  +Die Verbindung zwischen SHard und EUMEL-0 erfolgt über zwei Tabellen. In der +"0-Leiste" stellt EUMEL-0 dem SHard verschiedene 0-Routinen zur Verfügung. Diese +Leiste beginnt an der Adresse M0 (im Normal- oder Minimodus) bzw. M1 (im ROM- +Modus):  +  + Adresse  Assemblerbefehl  +  +  M0 + 0  eumel0id:        .ascii "EUMEL jj-mm-tt  " !Kennung mit Datum  +     +16  eumel0blocks:    .word ...   !Anzahl EUMEL0-Bloecke auf HG  +     +18  hgver:           .word 173   !HG-Versionsnummer  +     +20  cputype:         .word 4     !MC68000 oder kompat. CPU  +     +22  eumel0ver:       .word mmmtt !EUMEL0-Version (mmm=1 --> Jan.84)  +     +24  shdvermin:       .word 8     !Minimum bzw. Maximum fuer die  +     +26  shdvermax:       .word 8     ! SHard-Versionsnummer  +     +28  systemstart:     jmp ...     !Ab hier stehen Sprungbefehle zu  +     +34  inputinterrupt:  jmp ...     ! den entsprechenden 0-Routinen  +     +40  timerinterrupt:  jmp ...  +     +46  warte:           jmp ...  +     +52  shutup:          jmp ...  +     +58  info:            jmp ...  +  +  +Für die Gegenrichtung muß SHard der 0-Maschine die "SHard-Leiste" zur Verfügung +stellen:  +  + Adresse  Assemblerbefehl  +  +SHDID+ 0  SHDID:       .ascii "SHARD jj-mm-tt  " !Kennung mit Datum  +     +16  SHDVER:      .word 8  !Versionsnummer d. SHard-Schnittstelle  +     +18  MODE:        .word    !Modusbits:  +           BITEUDEL   =  0          ! EUMEL-0-Bloecke auf HG freigeben  +           BITNORMAL  =  1          ! Normalbetrieb  +           BITMINI    =  2          ! Minibetrieb  +           BITROM     =  3          ! ROM-Betrieb  +     +20  ID4:         .word    !ID-Konstanten (s.S. #topage("ID")#)  +     +22  ID5:         .word    ! dito  +     +24  ID6:         .word    ! dito  +     +26  ID7:         .word    ! dito  +     +28  OUTCHAR:     jmp      !Ab hier stehen Sprungbefehle in die  +     +34  OUTPUT:      jmp      ! entsprechenden SHard-Routinen  +     +40  BLOCKIN:     jmp  +     +46  BLOCKOUT:    jmp  +     +52  IOCONTROL:   jmp  +     +58  SYSEND:      jmp  +     +64  SYSABORT:    jmp  +     +70  M0START:     .long    !Startadr bzw.  +     +74  M0SIZE:      .long    ! Länge (in Bytes) des Bereiches M0  +     +78  M1START:     .long    ! dito f. M1  +     +82  M1SIZE:      .long  +     +86  M2START:     .long    ! dito f. M2  +     +90  M2SIZE:      .long  +     +94  M3START:     .long    ! dito f. M3  +     +98  M3SIZE:      .long  +  +  +  +#b("Allgemeine Link-Bedingungen")##goalpage("link")#  +  +In der Regel sind sowohl 0-Routinen als auch SHard-Routinen durch 'jbsr' aufzurufen:  +  +          jbsr   <routine>  +  +Ausnahmen von dieser Regel sind im folgenden stets besonders vermerkt.  +  +Generelle Link-Bedingung (für SHard- und 0-Routinen) ist:  +  +     Alle Register - bis auf die jeweils spezifizierten Ausgangsparameter und die 'condi +     tion code'-Flags im Status Register *) - bleiben unverändert.  +#foot#  +#f#*) Condition-Code-Flags sind i.a. nach dem Aufruf einer Routine undefiniert. Ausnahmen sind natürlich die Flags, +die als Ausgangsparameter in manchen Fällen definiert sind.  +#a#  +#end#  +  +Jede SHard-Routine muß also alle Register, die sie verändert und die keine Ausgangs +parameter sind, retten und wiederherstellen. Im Gegenzug braucht SHard beim Aufruf von +0-Routinen selbst keine Register zu retten.  +  +  +  +#b("Interrupts")##goalpage("intr")#  +  +Zwei externe Ereignisse (Zeitgeber und Eingabe, siehe S.#topage("zeit")# und S.#topage("inp")#) werden von +EUMEL-0 behandelt. Die entsprechenden Interrupts muß SHard per 'jbsr' an 0-Routinen +weiterleiten.  +Die Register (bis auf die Parameterregister) werden von den aufzurufenden 0-Routinen +selbst gesichert. Die normale Interrupt-Sequenz im SHard sieht dann folgendermaßen +aus:  +  +      intadr:  movl   d0,(sp)-  +               movw   <parameter>,d0  +               jbsr   <routine>  +               andw   \#/fcff,sr ! interrupt level freigeben  +               movl   (sp)+,d0  +               rti  +  +Achtung: SHard muß die Interrupt-Routinen im 'disable-int'-Modus anspringen, d.h. im +         Status Register muß der korrekte Interrupt-Level gesetzt sein. (MC68000 setzt +         beim Interrupt schon automatisch die Interrupt-Level-Flags.)  +  +  +  +  +  +#bb("1.  System ","laden")##goalpage("laden")#  +  +SHard muß die EUMEL-0-Software vor dem eigentlichen Start an den Anfang des Spei +cherbereiches M0 laden. EUMEL-0 befindet sich auf dem Hintergrund von Block 10 ab. +Der erste Block von EUMEL-0 enthält am Anfang die 0-Leiste. Dort steht an der +Byteadresse 16 die Größe 'eumel0blocks'. Sie gibt an, wieviel Blöcke konsekutiv geladen +werden müssen. Hat sie beispielsweise den Wert 80, müssen die Blöcke 10 bis 89 gela +den werden.  +  +    Achtung: Zu diesem Zeitpunkt kann SHard die oben aufgeführten 0-Routinen natür +             lich noch nicht benutzen. Insbesondere dürfen die Laderoutinen nicht +             'warte' aufrufen. Das wird hier besonders betont, weil der Hintergrundzugriff +             beim eigentlichen Systemlauf in der Regel 'warte' verwenden wird.  +  +    Hinweis: Der erste Block von EUMEL-0 enthält in den ersten fünf Bytes den Text +             "EUMEL", um eine Identifikation durch den SHard-Lader zu ermöglichen.  +  +Es wird empfohlen, nach folgendem Verfahren zu laden:  +  +    IF archivgeraet enthaelt diskette AND eumel 0 auf archiv  +      THEN lade eumel 0 vom archiv  +    ELIF eumel 0 auf hintergrund  +      THEN lade eumel 0 vom hintergrund  +    ELSE laden unmoeglich  +    FI .  +  +So kann man auch bei einem frisch formatierten Hintergrundmedium einen neuen Hinter +grund (mit EUMEL-0) einspielen, indem man ein Hintergrundarchiv vor dem Systemstart +in das Archivgerät legt. Dann wird EUMEL-0 von dort geladen, so daß man den Hinter +grund dann wie im Systemhandbuch beschrieben vom Archiv auf das Hintergrundmedium +kopieren kann.*)  +#foot#  +#f#*) Kopiervorgänge (Archiv -> Hintergrund) werden von EUMEL-0 erledigt, so daß SHard keine derartigen Routinen +enthalten muß.  +#a#  +#end#  +  +  +  +  +#bb("2.  System","start und -ende")##goalpage("start")#  +  +SHard muß alle für den Rechner notwendigen (Hardware-) Initialisierungen durchführen +und erst danach die EUMEL-0-Maschine starten ('systemstart').  +  +    #d("systemstart")#           (0-Routine)  +  +       Eingang:      a0 = Adresse der SHard-Leiste  +  +       Aufruf:       jmp systemstart  +  +       Zweck:        Die EUMEL-0-Maschine wird gestartet. Alle notwendigen Hard +                     wareinitialisierungen (z.B. der Peripheriebausteine) müssen vorher +                     schon geschehen sein.  +  +       Hinweis:      SHard muß den Stackpointer (a7) "vorläufig" definieren (etwa 100 +                     Langworte reichen dafür aus), da beim Sprung in EUMEL-0 Inter +                     rupts auftreten können.  +  +  +  +    #d("SYSEND")#  +  +       Parameter:    -  +  +       Zweck:        Hiermit wird SHard das Ende eines Systemlaufs mitgeteilt. Somit +                     können evtl. notwendige Abschlußbehandlungen durchgeführt +                     werden. SHard kann mit 'rts' zu EUMEL-0 zurückkehren, muß +                     aber nicht. Diese Routine kann z.B. dazu benutzt werden, die +                     Hardware auszuschalten oder in ein umgebendes System zurück +                     zukehren (EUMEL als Subsystem). In den meisten Fällen wird die +                     Routine leer implementiert werden, d.h. nur aus 'rts' bestehen.  +  +  +  +  +#bb("3.  ","Speicherverwaltung")##goalpage("spver")#  +  +  +#b("Hauptspeicher")##goalpage("haupt")#  +  +Der Hauptspeicher umfaßt die Teile des MC68000-Speichers, die EUMEL-0 verwalten +darf.  +  +  +  +#b("Speicherfehler")##goalpage("memerr")#  +  +Falls die Hardware Speicherfehler aufgrund von Paritybits, ECC oder ähnlichem feststellen +und an SHard melden kann, sollte das zur Erhöhung der Systemsicherheit genutzt wer +den.  +  +Wenn SHard (z.B. über Interrupt) einen Speicherfehler mitgeteilt bekommt, sollte er, wenn +möglich, eine entsprechende Meldung ausgeben und das System anhalten:  +  +       basta: jra basta  +  +  +Wenn Speicherfehler mit Sicherheit bemerkt werden, verhindert diese Reaktion, daß die +Fehler auf dem Hintergrund festgeschrieben werden und evtl. später zu Systemfehlern +führen.  +  +Der Anwender kann dann durch Hardware-Reset auf den letzten Fixpunkt des EUMEL- +Systems zurücksetzen. So verliert er zwar evtl. die letzten Minuten seiner Arbeit, behält +aber auf alle Fälle ein konsistentes System.  +  +  +  +  +#bb("4.  ","Zeitgeber")##goalpage("zeit")#  +  +SHard muß einen Zeitgeberinterrupt erzeugen, der ca. 10 bis 100 mal pro Sekunde auftritt. +Dabei ist die 0-Routine 'timerinterrupt' aufzurufen. Ohne diesen Interrupt wird die Uhr +nicht geführt, und die Zeitscheibenlogik für das Timesharing fällt aus.  +  +    #d("timerinterrupt")#         (0-Routine)  +  +       Eingang:      d0 = seit letztem Zeitgeberinterrupt vergangene Zeit (in ms)  +  +       Zweck:        Wird von EUMEL-0 für interne Uhren und für das Scheduling +                     (Zeitscheibenlogik) verwendet. Es werden keine hohen Genauig +                     keitsanforderungen an die Zeitangaben bei #on("i")#einzelnen#off("i")# Interrupts +                     gestellt. Um EUMEL-0 eine genaue Realzeituhr zu ermöglichen, +                     sollte die so erzeugte Zeitangabe #on("i")#im Mittel#off("i")# aber möglichst genau +                     sein, d.h. die Summe der innerhalb einer Minute so übergebenen +                     Werte sollte zwischen 59995 und 60005 liegen.  +  +  +  +  +#bb("5.  ","Kanäle")##goalpage("channel")#  +  +Einiges zum Kanalkonzept:  +  +Das System kennt die Kanäle 0..32.  +  +     Kanal 0        ist der Systemhintergrund.  +     Kanäle 1..15   sind für Stream-IO (Terminals, Drucker, ...) vorgesehen.  +     Kanal 31       ist der Standard-Archivkanal.  +     Kanal 32       ist der Parameterkanal.  +  +Die Kanäle 2..30 können installationsabhängig verfügbar sein oder auch nicht. Deren +Funktion ist dann Absprachesache zwischen Installation und SHard.  +  +Kanäle können über Block-IO (BLOCKOUT, BLOCKIN) oder Stream-IO (OUTPUT,..) +angesprochen werden. Das System erfährt über IOCONTROL, welche Betriebsart des +Kanals sinnvoll ist.  +  +#on("i")##on("b")#Achtung:  Alle Kanaloperationen müssen grundsätzlich für alle Kanäle (0...32) aufgerufen +          werden können. Dabei können Operationen auf nicht vorhandenen Kanälen und +          unsinnige Operationen (z.B. Stream-IO auf Kanal 0) leer implementiert werden.#off("b")# +          (Dafür werden im folgenden bei jeder SHard-Routine Vorschläge gemacht.)#off("i")#  +  +  +  +#bb("5.1 ","Stream-IO")##goalpage("stream")#  +  +Über Stream-IO wickelt das System die übliche zeichenorientierte Ein-/Ausgabe auf Ter +minals, Druckern, Plottern usw. ab. Stream-IO wird nur für die Kanäle 1...15 gemacht.  +  +    #d("inputinterrupt")#        (0-Routine)#goalpage("inp")#  +  +       Aufruf:            movl  kanalnummer,(sp)-    !1...15  +                          movl  zeichen,(sp)-        !rechtsbündig  +                          jbsr  inputinterrupt  +                          lea   8(sp),sp             !restore stackpointer  +  +       Zweck:        SHard muß EUMEL-0 durch Aufruf dieser Routine mitteilen, daß +                     eine Eingabe vorliegt.  +  +       Hinweise:     EUMEL-0 puffert die Zeichen. EUMEL-0 signalisiert den Zustand +                     "Puffer voll" durch IOCONTROL "stop" und ignoriert weitere +                     Eingaben, bis wieder Platz im Puffer vorhanden ist. (siehe +                     IOCONTROL "stop" und "weiter", S.#topage("weiter")#)  +  +                     Bei Kanalnummern <1 oder >15 wird der Aufruf von EUMEL-0 +                     ignoriert.  +  +                     Falls die Hardware keine Inputinterrupts zur Verfügung stellt, sollte +                     ein Timer benutzt werden, um alle möglichen Inputquellen regel +                     mäßig abzufragen. Dabei muß man allerdings den goldenen Mittel +                     weg zwischen zu häufiger (Systemdurchsatz sinkt) und zu seltener +                     Abfrage (Zeichen gehen verloren) suchen. Man sollte dabei nicht +                     nur an die menschliche Tippgeschwindigkeit sondern auch an die +                     höchste Baudrate denken, die man für Rechnerkopplungen noch +                     unterstützen will. *)  +  +#foot#  +#f#*) Eine weitere Möglichkeit, auf manchen Kanälen ohne Interrupts auszukommen, wird bei der IOCONTROL-Funk +tion "weiter" beschrieben (siehe S.#topage("weiter")#).  +#a#  +#end#  +  +Achtung:             #on("i")#Keinesfalls darf 'inputinterrupt' rekursiv aufgerufen werden. Nor +                     malerweise wird das automatisch verhindert, wenn man den +                     zugehörigen Hardwareinterrupt erst nach der 0-Routine wieder +                     freigibt. Falls das nicht möglich ist und unter bestimmten Umstän +                     den das nächste Zeichen abgeholt werden muß, bevor die +                     0-Routine beendet ist, muß SHard einen eigenen Puffer imple +                     mentieren:#off("i")#  +  +                         hardwareinterrupt:  +                             IF input interrupt aktiv  +                             THEN trage zeichen in shard puffer ein;  +                                  gib hardware interrupt frei  +                             ELSE input interrupt aktiv := true;  +                                  gib hardware interrupt frei;  +                                  input interrupt;  +                                  disable interrupt;  +                                  WHILE shard puffer enthaelt noch zeichen  +                                  REP nimm zeichen aus shard puffer;  +                                      enable interrupt;  +                                      input interrupt;  +                                      disable interrupt  +                                  PER;  +                                  input interrupt := false;  +                                  enable interrupt  +                             FI.  +  +  +    #d("OUTPUT")#  +  +       Eingang:      d0 = Kanalnummer (1...15)  +                     d2 = Anzahl auszugebender Zeichen  +                     a0 = Adresse der Zeichenkette  +       Ausgang:      d2 = Anzahl der übernommenen Zeichen  +  +       Zweck:        Ausgabe einer Zeichenkette. Diese ist (möglichst ganz) zwischen +                     zupuffern, denn die Ausführung von OUTPUT sollte kein Warten +                     auf IO enthalten. Der Ausgabepuffer muß mindestens 50 Zeichen +                     fassen können. Durch eine Interruptlogik oder etwas Äquivalentes +                     ist sicherzustellen, daß dieser Puffer parallel zur normalen Verar +                     beitung ausgegeben wird. Wenn die auszugebende Zeichenkette +                     nicht vollständig in den Puffer paßt, sollten trotzdem so viele +                     Zeichen wie möglich übernommen werden. Im weiteren Verlauf ruft +                     EUMEL-0 dann wieder OUTPUT mit dem Rest der Zeichenkette +                     auf.  +  +  +       Achtung:      #on("i")#Keinesfalls darf innerhalb von OUTPUT die 0-Routine 'warte' auf +                     gerufen werden.#off("i")#  +  +       Vorschlag:    Falls der Kanal nicht existiert bzw. OUTPUT darauf unsinnig ist, +                     sollte vorgegaukelt werden, alle Zeichen seien ausgegeben (d2 +                     unverändert).  +  +  +  +    #d("OUTCHAR")#  +  +       Eingang:      d0 = Kanalnummer (1...15)  +                     d1 = auszugebendes Zeichen  +  +       Zweck:        Ausgabe eines Zeichens.  +  +       Hinweis:      Ob das Zeichen übernommen wird, kann vorher durch einen Aufruf +                     IOCONTROL "frout" erfragt werden, s. S. #topage("frout")#.  +  +  +  +#b("Terminals")##goalpage("term")#  +  +"Normale" #ib#Terminal#ie(1,", normales")#s können ohne weitere Unterstützung des SHards angeschlossen +werden. Die zur Anpassung an den EUMEL-Zeichensatz *) notwendigen #ib#Umcodierungen#ie# +werden von den höheren Ebenen aus eingestellt. Da diese Umsetztabellen vom SHard +unabhängig sind, stehen automatisch alle so angepaßten Terminaltypen allen EUMEL- +Anwendern zur Verfügung!  +#foot#  +#f#*) Siehe "EUMEL Benutzerhandbuch, Teil 3: Editor, 5. Zeichencode"  +#a#  +#end#  +  +Für den Anschluß eines #on("b")##on("i")#integrierten #ib#Terminal#ie(1,", integriertes")#s#off("i")##off("b")#, in dessen Bildwiederholspeicher direkt +gearbeitet wird, kann man häufig den Terminaltyp 'psi' verwenden (siehe auch "Exoten").  +  +Näheres zu Terminaltypen und -anschlüssen findet man im "EUMEL Systemhandbuch" +unter den Stichwörtern #on("i")#Konfiguration#off("i")# und #on("i")#Konfigurierung#off("i")#.  +  +  +  +#bb("Drucker, ","Plotter")##goalpage("druck")#  +  +#ib#Drucker#ie# und Plotter werden vom EUMEL-System wie Terminals angesehen. Da in der +Regel der Rechner aber schneller Zeichen senden als der Drucker drucken kann, müssen +solche Geräte in der Regel mit Flußkontrolle angeschlossen werden (siehe S.#topage("fluss")#).  +  +Wenn Drucker oder Plotter über eine Parallelschnittstelle angeschlossen werden, kann man +auf diesem Kanal möglicherweise auf einen Ausgabepuffer verzichten. Voraussetzung ist +dabei, daß  +  +    a)   der Drucker einen eigenen Puffer hat und  +    b)   der Puffer "schnell" gefüllt werden kann (<0.1 ms je Zeichen).  +  +Dann kann man auf den bei der SHard-Routine OUTPUT geforderten Puffer verzichten +und die Zeichenkette direkt über die Parallelschnittstelle an den Drucker übergeben. Wenn +der Drucker 'Puffer voll' signalisiert, sollte die Zeichenübernahme bei OUTPUT abgebro +chen werden. **) #on("i")#Auf keinen Fall darf CPU-intensiv auf Freiwerden des Puffers gewartet +werden!#off("i")#  +#foot#  +#f#**) siehe auch IOCONTROL "frout", S.#topage("frout")#  +#a#  +#end#  +  +  +  +#b("Exoten")##goalpage("exot")#  +  +Exotische #ib#Terminal#ie(1," exotisches")#s (im Sinne dieser Beschreibung) sind solche, für die eine Umsetz +tabelle im System (siehe Konfiguratorbeschreibung) nicht ausreicht bzw. nicht nötig ist +(Beispiele: Terminals, in deren Bildwiederholspeicher direkt gearbeitet wird; Terminals, die +soweit programmierbar sind, daß sie den EUMEL-Zeichencode können).  +  +Für solche Terminals muß in der Konfiguration der Terminaltyp '#ib#psi#ie#' eingestellt werden. +Dieser wirkt ohne Umcodierungen, d.h. die EUMEL-Codes (siehe Benutzerhandbuch 1.7 +Seite 106) werden direkt dem SHard zugestellt (wie bei 'transparent'), jedoch mit folgenden +Besonderheiten:  +  +Eingabeseitig werden zusätzlich folgende Codezuordnungen getroffen:  +  +    Code   Funktion  +  +    7      SV      (Aktivierung: 'gib supervisor kommando:')  +    17     STOP    (Ausgabe auf diesen Kanal wird gestoppt)  +    23     WEITER  (Ausgabe läuft wieder weiter)  +    4      INFO    (System geht in Debugger, falls Debugoption)  +  +  +  +#bb("5.2 ","Block-IO")##goalpage("block")#  +  +Über Block-IO wickelt das System die Zugriffe zum Hintergrund und zum Archiv ab. +Ferner ist daran gedacht, auch auf V.24-Schnittstellen Block-IO z.B. für Rechnerkopp +lung zuzulassen. Die Kanalnummer in Reg. d0 unterscheidet diese Fälle. Außer beim +Paging (d0=0) wird ein Block-IO durch die ELAN-Prozeduren 'blockin' und blockout' +induziert.  +  +Bei Block-IO wird immer ein 512 Byte großer Hauptspeicherbereich mit übergeben. +Dieser kann (im Gegensatz zu OUTPUT) direkt benutzt werden, d.h. es muß keine Um +pufferung erfolgen.  +  +Dieser Hauptspeicherbereich darf nur bei BLOCKIN verändert werden.  +  +SHard darf (anders als bei OUTPUT) erst dann zur Aufrufstelle zurückgeben, wenn die +verlangte Operation abgeschlossen ist. Treten während der Operation Wartezeiten auf, so +muß SHard die 0-Routine 'warte' aufrufen, damit das System andere Prozesse weiter +laufen lassen kann.  +  +EUMEL-0 definiert bestimmte Funktionen für Hintergrund (Kanal 0) und Archiv (Kanal 31). +Operationen auf anderen Kanälen kann SHard nach Belieben implementieren und deren +Leistung seinen Installationen über ELAN-Pakete zur Verfügung stellen. Das System +vergibt auch in Zukunft für den #ib##on("i")#Funktionscode#ie##off("i")# in Register d1 nur positive Werte (Bit 15 +von d1 = 0). Der SHard kann selbst negative Codes einführen.  +  +  +    #d("BLOCKIN")#  +  +       Eingang:      d0 = Kanalnummer (0...32)  +                     d1 = Funktionscode 1  +                     d2 = Funktionscode 2  +                     a0 = Adresse des Hauptspeicherbereichs  +       Ausgang:      d0 = undefiniert (darf also verändert werden)  +                     d1 = Rückmeldecode  +                     a0 = darf verändert werden  +  +                     Der Inhalt des Hauptspeicherbereichs (<a0>... <a0>+511) darf +                     verändert sein.  +  +       Zweck:        "Einlesen" von Blöcken. Die genaue Wirkung hängt vom Funk +                     tionscode und dem Kanal ab.  +  +       Vorschlag:    Falls der Kanal nicht existiert bzw. BLOCKIN darauf unsinnig ist, +                     sollte die Rückmeldung -1 in d1 geliefert werden.  +  +  +    #d("BLOCKOUT")#  +  +       Eingang:      d0 = Kanalnummer (0...32)  +                     d1 = Funktionscode 1  +                     d2 = Funktionscode 2  +                     a0 = Adresse des Hauptspeicherbereichs  +       Ausgang:      d0 = undefiniert (darf also verändert werden)  +                     d1 = Rückmeldecode  +                     a0 = darf verändert werden  +  +                     Der Inhalt des Hauptspeicherbereichs darf #on("i")#nicht#off("i")# verändert werden!  +  +       Zweck:        "Ausgeben" von Blöcken. Die genaue Wirkung hängt vom Funk +                     tionscode und dem Kanal ab.  +  +       Vorschlag:    Falls der Kanal nicht existiert bzw. BLOCKOUT darauf unsinnig ist, +                     sollte die Rückmeldung -1 in d1 geliefert werden.  +  +  +    #d("warte")#             (0-Routine)  +  +       Ausgang:      Alle Register undefiniert!  +  +       Zweck:        Diese Routine ist bei 'blockin' oder 'blockout' dann aufzurufen, +                     wenn SHard im Augenblick nichts zu tun hat. Durch den Aufruf von +                     'warte' erhalten andere Systemteile die Möglichkeit, weiter zu ar +                     beiten. Ein 'warte' kann bis zu ca. 1/4 Sekunde Zeit aufnehmen. +                     'warte' darf nicht in Interruptroutinen und Stream-IO verwendet +                     werden! 'warte' zerstört alle Register! SHard muß davon ausgehen, +                     daß 'warte' seinerseits andere SHard-Komponenten aufruft.  +  +  +Die Verwendung der 0-Routine 'warte' soll hier an einigen Beispielen verdeutlicht wer +den:  +  +  +    blockout auf platte :  +         WHILE platte noch nicht frei REP  +           warte  +         ENDREP ;  +         uebertrage schreibbefehl an controller ;  +         uebertrage daten an controller .  +  +    blockin von platte :  +         WHILE platte noch nicht frei REP  +           warte  +         ENDREP ;  +         uebertrage lesebefehl an controller ;  +         WHILE daten noch nicht gelesen REP  +           warte  +         ENDREP ;  +         hole daten vom controller .  +  +  +    blockout auf floppy :  +         seekbefehl an controller ;  +         WHILE seek noch nicht fertig REP  +           warte  +         ENDREP ;  +         setze dma auf schreiben block zur floppy ;  +         schreibbefehl an controller ;  +         WHILE schreiben noch nicht fertig REP  +           warte  +         ENDREP .  +  +    blockin von floppy :  +         seekbefehl an controller ;  +         WHILE seek noch nicht fertig REP  +           warte  +         ENDREP ;  +         setze dma auf lesen block von floppy ;  +         lesebefehl an controller ;  +         WHILE lesen noch nicht fertig REP  +           warte  +         ENDREP .  +  +  +  +#b("Block-IO bei Hintergrund und Archiv")##goalpage("bhgarch")#  +  +#ib#Hintergrund#ie# (Kanal 0) und #ib#Archiv#ie# (Kanal 31) unterscheiden sich in den Link-Bedingungen +nur in der Kanalnummer. Die Aufrufe von BLOCKIN und BLOCKOUT werden mit folgenden +Eingangsparametern versorgt:  +  +    #on("b")#BLOCKIN#off("b")#          d0 = 0 bzw. 31  +                     d1 = 0  +                     d2 = Blocknummer  +                     a0 = Hauptspeicheradresse  +  +                     Der angegebene 512-Byte-Block ist in den Hauptspeicher ab +                     <a0> einzulesen.  +  +    #on("b")#BLOCKOUT#off("b")#         d0 = 0 bzw. 31  +                     d1 = 0  +                     d2 = Blocknummer  +                     a0 = Hauptspeicheradresse  +  +                     Der Hauptspeicherbereich (<a0>... <a0>+511) ist auf den +                     angegebenen Block zu schreiben.  +  +Als Rückmeldungen sind zu liefern:#goalpage("errcod")#  +  +               0     Operation korrekt ausgeführt.  +               1     Manuell behebbarer Fehler (z.B. Laufwerktür offen)  +               2     Permanenter Fehler (z.B. Daten nicht lesbar)  +               3     Versorgungsfehler (zu hohe Blocknummer)  +  +  +#d("Fehlerwiederholung")#:  Das EUMEL-System führt von sich aus Fehlerwiederholungen beim +                     Hintergrund- und beim Archivzugriff durch. SHard sollte deshalb +                     im Fehlerfall die Operation nicht selbst wiederholen, sondern einen +                     Lese/ Schreibfehler zurückmelden. So werden dem EUMEL-Sy +                     stem auch Soft-Errors gemeldet. In manchen Fällen soll vor +                     einem erneuten Lese- oder Schreibversuch der Arm auf Spur 0 +                     positioniert werden o.ä. Um das zu erreichen, sollte SHard diese +                     "Reparaturaktion" direkt im Anschluß an den fehlerhaften Versuch +                     durchführen.  +  +#d("Kontrollesen")#:        Falls Kontrollesen (nach jedem Schreibzugriff) notwendig ist, muß das +                     allerdings vom SHard durchgeführt werden. In der Regel reicht es +                     dazu, den geschriebenen Block "ohne Datentransport" zu lesen, + + + + + + + + + + + + + + + + + + + + + +System verwendet nur positive Codes. Der SHard-Schreiber kann auch negative Codes +für Sonderzwecke vorsehen.  +  +  +    #d("IOCONTROL")#  +  +       Eingang:      d0 = Kanalnummer (0...32)  +                     d1 = Funktionscode 1  +                     d2 = Funktionscode 2  +                     d3 = Funktionscode 3  +       Ausgang:      d1 = Rückmeldung  +  +       Zweck:        abhängig von 'Funktionscode 1' (s.u.)  +  +Das System verlangt folgende Informations- und Steuerleistungen über IOCONTROL:  +  +  +    #d("IOCONTROL ""typ""")#  +  +       Eingang:      d0 = Kanalnummer (0...31)  +                     d1 = 1  +       Ausgang:      d1 = Kanaltyp  +  +       Zweck:        Informiert EUMEL-0, welche IO für den angegebenen Kanal +                     sinnvoll ist. Die Rückmeldung in d1 wird bitweise interpretiert:  +  +                     Bit 0 gesetzt  <=>  'inputinterrupt' kann kommen.  +                     Bit 1 gesetzt  <=>  OUTPUT ist sinnvoll.  +                     Bit 2 gesetzt  <=>  BLOCKIN ist sinnvoll.  +                     Bit 3 gesetzt  <=>  BLOCKOUT ist sinnvoll.  +                     Bit 4 gesetzt  <=>  IOCONTROL "format" ist sinnvoll.  +  +       Hinweis:      #on("i")#Trotz dieser Informationsmöglichkeit wird nicht garantiert, daß nur +                     sinnvolle Operationen für den Kanal aufgerufen werden.#off("i")#  +  +  +    #d("IOCONTROL ""frout""")##goalpage("frout")#  +  +       Eingang:      d0 = Kanalnummer (1...15)  +                     d1 = 2  +       Ausgang:      d1 = Anzahl Zeichen, die nächster OUTPUT übernimmt, bzw. +                          Anzahl der OUTCHAR-Aufrufe, deren Zeichen übernommen +                          wird.  +  +       Zweck:        Liefert Information über die Belegung des Puffers. Diese Informa +                     tion wird von EUMEL-0 zum Scheduling benutzt.  +  +       Achtung:      #on("i")#Wenn EUMEL-0 längere Zeit kein OUTPUT gemacht hat, muß +                     irgendwann d1 > 49 gemeldet werden.#off("i")#  +  +       Hinweis:      Unter Berücksichtigung des oben Gesagten darf "gelogen" werden. +                     Man kann z.B. immer 50 in d1 zurückmelden, muß dann aber +                     schlechtere Nutzung der CPU bei Multi-User-Systemen in Kauf +                     nehmen.  +  +                     Falls auf dem angegebenen Kanal ein Drucker mit eigenem Puffer +                     über Parallelschnittstelle angeschlossen ist (siehe S.#topage("druck")# ) und man +                     auf einen SHard-internen Puffer verzichtet hat, sollte bei 'Druk +                     kerpuffer voll' 0 in d1 zurückgemeldet werden. Wenn aber Zeichen +                     übernommen werden können, sollte 50 in d1 gemeldet werden  +  +       Vorschlag:    Falls der Kanal nicht existiert oder nicht für Stream-IO zur Verfü +                     gung steht, sollten 200 in d1 zurückgemeldet werden.  +  +  +    #d("IOCONTROL ""weiter""")##goalpage("weiter")#  +  +       Eingang:      d0 = Kanalnummer (1...15)  +                     d1 = 4  +       Ausgang:      -  +  +       Zweck:        Das System ruft "weiter" für den in d0 angegebenen Kanal auf, +                     wenn es wieder Eingabezeichen puffern kann. (siehe auch: Fluß +                     kontrolle S.#topage("fluss")#)  +  +       Hinweis:      "weiter" wird von EUMEL-0 auch immer dann aufgerufen, wenn +                     ein Prozeß auf dem angegebenen Kanal auf Eingabe wartet und +                     keine Zeichen mehr gepuffert sind. Wenn der betroffene Kanal von +                     sich aus keine Interrupts erzeugt, kann SHard diesen Aufruf dazu +                     benutzen, den Kanal auf mögliche Eingabe abzufragen und ggfs. +                     das Eingabezeichen durch Aufruf von 'inputinterrupt' EUMEL-0 +                     zuzustellen.  +                     #on("i")#Diese Betriebsart sollte nicht für normale Terminalkanäle eingesetzt +                     werden, weil sie die SV-Taste nur dann an EUMEL-0 zustellt, +                     wenn ein Prozeß auf diesem Kanal auf Eingabe wartet. Dadurch +                     wären aber CPU-intensive Endlosschleifen nicht normal abbrech +                     bar! #off("i")#  +  +  +    #d("IOCONTROL ""size""")#  +  +       Eingang:      d0 = Kanalnummer (0...31)  +                     d1 = 5  +                     d2 = Schlüssel  +       Ausgang:      d1 = Anzahl Blöcke  +  +       Zweck:        EUMEL-0 ruft 'size' auf, um die Anzahl Blöcke zu erfahren, die +                     ein Block-IO-Kanal verkraften kann (Größe von Hintergrund und +                     Archiven). Bei Archivlaufwerken, die meherere Formate bearbeiten +                     können, dient dieser Aufruf auch zum Einstellen des Formats für +                     die folgenden blockin/blockout-Operationen anhand des Schlüs +                     sels.  +  +       Schlüssel:    0    Wenn möglich 'erkennend', sonst 'standard'. Im ersten Fall +                          erkennt SHard das Format der eingelegten Diskette und stellt +                          dieses ein.  +  +                     Die weiteren Schlüssel sind stets definierend:  +  +                     1    5.25" 2D-40, Sektor 1..9, 512 Bytes  +                     2    5.25" 2D-80, Sektor 1..9, 512 Bytes  +                     3    5.25" HD-80, Sektor 1..15, 512 Bytes  +                     4    5.25" 1D-80, Sektor 1..9, 512 Bytes  +                     10   8" 1D-77, Sektor 0..15, 512 Bytes  +                     11   8" 2D-77, Sektor 0..15, 512 Bytes  +                     12   8" 1S-77, Sektor 1..26, 128 Bytes  +                     13   8" 1D-77, Sektor 1..26, 256 Bytes  +                     14   8" 2D-77, Sektor 1..16, 256 Bytes  +  +       Hinweis:      Bei Archiven wird 'size' aufgerufen, nachdem der Archivträger ein +                     gelegt wurde. D.h. SHard hat die Gelegenheit, die Größe anhand +                     des eingelegten Archivträgers zu bestimmen (z.B. ob single- oder +                     doublesided).  +  +       Vorschlag:    Diese Funktion sollte auf nicht vorhandenen und den Stream-IO- +                     Kanälen 0 liefern. Sie muß aber mindestens auf Kanal 0 (Hinter +                     grund) und Kanal 31 (Archiv) "echte" Werte liefern.  +  +       Achtung:      #on("i")#Ausnahmsweise darf bei dieser IOCONTROL-Funktion die +                     0-Routine 'warte' aufgerufen werden.#off("i")#  +  +  +    #d("IOCONTROL ""format""")#  +  +       Eingang:      d0 = Kanalnummer (0...31)  +                     d1 = 7  +                     d2 = Schlüssel  +       Ausgang:      d1 = Fehlercode wie bei Archiv-BLOCKOUT (siehe S.#topage("errcod")#)  +  +       Zweck:        Dient zum Formatieren eines Mediums. Diese Funktion kann für +                     jeden Kanal leer implementiert sein ('rts'). Sie sollte aber "forma +                     tierend" (z.B. auf Kanal 31) arbeiten, falls auf diesem Kanal die +                     "typ"-Abfrage "Formatieren sinnvoll" liefert. Falls (bei Disketten +                     laufwerken) mehrere Formate möglich sind, bestimmt der Schlüssel +                     das gewünschte Format.  +  +       Schlüssel:    0    Standardformat dieses Rechners  +                     1    5.25" 2D-40, Sektor 1..9, 512 Bytes  +                     2    5.25" 2D-80, Sektor 1..9, 512 Bytes  +                     3    5.25" HD-80, Sektor 1..15, 512 Bytes  +                     4    5.25" 1D-80, Sektor 1..9, 512 Bytes  +                     10   8" 1D-77, Sektor 0..15, 512 Bytes  +                     11   8" 2D-77, Sektor 0..15, 512 Bytes  +                     12   8" 1S-77, Sektor 1..26, 128 Bytes  +                     13   8" 1D-77, Sektor 1..26, 256 Bytes  +                     14   8" 2D-77, Sektor 1..16, 256 Bytes  +  +       Hinweis:      Falls für das Formatieren ein großer Speicherbereich benötigt wird, +                     sollte das Formatieren von Disketten besser in einem Boot-Dialog +                     vor dem Start von EUMEL-0 angeboten werden. Denn sonst +                     müßte der Pagingbereich unnötig eingeschränkt werden.  +                     Man kann das Formatieren #on("i")#einer Spur#off("i")# CPU-intensiv implementie +                     ren (d.h. ohne DMA im Interrupts-Disabled-Modus), wenn man in +                     Kauf nimmt, daß alle anderen Tasks des EUMEL-Systems in +                     dieser Zeit "stehen". Dann sollte man aber nach jeder Spur +                     mehrmals die 0-Routine 'warte' aufrufen.  +  +       Achtung:      #on("i")#Ausnahmsweise darf bei dieser IOCONTROL-Funktion die +                     0-Routine 'warte' aufgerufen werden.#off("i")#  +  +  +  +#b("Konfigurierung serieller Schnittstellen")##goalpage("v24")#  +  +Bei Kanälen, die hardwaremäßig auf #ib#serielle Schnittstellen#ie# (#ib# V.24#ie#) zurückgeführt werden, +sind in der Regel die Größen  +  +       - #ib#Baudrate#ie# (..., 2400, 4800, 9600, ...)  +       - #ib#Zeichenlänge#ie# (7 Bits, 8 Bits)  +       - #ib#Parität#ie# (keine, gerade, ungerade)  +  +einstellbar. Dafür muß SHard die IOCONTROL-Funktionen "baud" und "bits" zur Verfü +gung stellen. Diese werden in zwei Modi benutzt:  +  +    a) #on("b")#einstellend#off("b")#  +       Läuft der aufrufende EUMEL-Prozeß auf dem privilegierten Steuerkanal (d0 = 32), +       wird der als Parameter mit übergebene #on("i")#adressierte Kanal#off("i")# auf die geforderten Werte +       eingestellt, sofern das möglich ist.  +  +    b) #on("b")#abfragend#off("b")#  +       Läuft der aufrufende EUMEL-Prozeß nicht auf Kanal 32 (d0 <> 32), wird lediglich +       abgefragt, ob der #on("i")#adressierte Kanal#off("i")# auf die übergebenen Werte eingestellt werden +       könnte.  +  +Aufgrund des zweiten Modus können die höheren EUMEL-Ebenen dem Anwender bei der +Konfigurierung mitteilen, welche Werte sich auf dem jeweiligen Kanal einstellen lassen. Das +nutzt z.B. das Standard-Konfigurationsprogramm aus.  +  +Hinweis:  Bei einigen Kanälen (z.B. bei einem integrierten Terminal oder einer Parallel +          schnittstelle) sind Baudrateneinstellungen sinnlos. Bei anderen können sie nur +          hardwaremäßig vorgenommen werden (Jumper, Dip Switches). In allen diesen +          Fällen muß SHard bei allen Einstellungen 'unmöglich' melden. (Standardmäßig +          wird der Anwender bei der Einstellung seiner Konfiguration dann auch nicht +          danach gefragt.)  +  +  +    #d("IOCONTROL ""baud""")#  +  +       Eingang:      d0 = eigener Kanal (1...15 / 32)  +                     d1 = 8  +                     d2 = 0  +                     d3 = Schlüssel * 256 + adressierter Kanal  +       Ausgang:      d1 = Rückmeldung (0 = ok, 1 = nicht möglich)  +  +       Zweck:        Wird diese Routine auf dem Steuerkanal (d0=32) aufgerufen, wird +                     die angegebene Baudrate für den durch Register d3(0..7) adres +                     sierten Kanal eingestellt, falls das möglich ist. Wird diese Routine +                     auf einem anderen Kanal als 32 aufgerufen, informiert sie den +                     Aufrufer lediglich, ob eine derartige Einstellung des adressierten +                     Kanals möglich wäre.  +  +       Schlüssel:          1       50 Baud  +                           2       75 Baud  +                           3      110 Baud  +                           4      134.5 Baud  +                           5      150 Baud  +                           6      300 Baud  +                           7      600 Baud  +                           8     1200 Baud  +                           9     1800 Baud  +                          10     2400 Baud  +                          11     3600 Baud  +                          12     4800 Baud  +                          13     7200 Baud  +                          14     9600 Baud  +                          15    19200 Baud  +                          16    38400 Baud  +  +       Anmerkung:    In der Regel werden nicht alle Baudraten vom SHard unterstützt +                     werden. Bei V.24 Schnittstellen sollten aber mindestens 2400, +                     4800 und 9600 Baud zur Verfügung stehen, besser auch 300, 600, +                     1200 und 19200 Baud.  +  +       Hinweis:      Falls SHard-spezifisch weitere Baudraten implementiert werden +                     sollen, darf SHard hierfür negative Schlüsselwerte in d3(8..15) ver +                     geben.  +  +  +    #d("IOCONTROL ""bits""")#  +  +       Eingang:      d0 = eigener Kanal (1...15 / 32)  +                     d1 = 9  +                     d2 = 0  +                     d3 = Schlüssel * 256 + adressierter Kanal  +       Ausgang:      d1 = Rückmeldung (0 = ok, 1 = nicht möglich)  +  +       Zweck:        Wird diese Routine auf dem Steuerkanal (d0=32) aufgerufen, wird +                     die angegebene Zeichenlänge (Bits pro Zeichen) und Parität für +                     den durch Register d3(0..7) adressierten Kanal eingestellt, falls das +                     möglich ist.  +                     Wird diese Routine auf einem anderen Kanal als 32 aufgerufen, +                     informiert sie den Aufrufer lediglich, ob eine derartige Einstellung +                     des adressierten Kanals möglich wäre.  +  +  +       Schlüssel:    stop * 32 + par * 8 + (bit - 1)  +  +                     stop:     0    1 Stopbit  +                               1    1.5 Stopbits  +                               2    2 Stopbits  +  +                     par:      0    keine Parität  +                               1    ungerade Parität  +                               2    gerade Parität  +  +                     bit:      1...8 Bits pro Zeichen  +  +  +       Anmerkung:    In der Regel werden nicht alle Kombinationen vom SHard unter +                     stützt werden. Bei V.24 Schnittstellen sollten aber möglichst 1 +                     Stopbit, 7 und 8 Bits pro Zeichen und alle drei Paritätseinstellun +                     gen zur Verfügung stehen.  +  +       Hinweis:      Falls SHard-spezifisch weitere Einstellungen implementiert werden +                     sollen, darf SHard hierfür negative Schlüsselwerte in d3(8..15) ver +                     geben.  +  +  +  +#b("Flußkontrolle")##goalpage("fluss")#  +  +Die stromorientierten Kanäle (1...15) werden nicht nur zum Anschluß schneller Geräte (wie +Terminals) verwendet, sondern auch, um langsame Geräte (wie Drucker) anzuschließen, die +die Daten u.U. nicht so schnell übernehmen können, wie sie der Rechner schickt. Dabei +ist auf eine geeignete Flußkontrolle zu achten (nicht schneller senden, als der Andere +empfangen kann). Dieses Problem stellt sich auch bei einer Rechner-Rechner-Kopplung. +Hier ist in der Regel sogar zweiseitige Flußkontrolle notwendig.  +  +Als Flußkontrolle ist die #ib#REQUEST TO SEND/CLEAR TO SEND#ie# Logik der V.24-Schnitt +stelle oder das #ib#XON/XOFF#ie#-Protokoll zu verwenden. Das Letztere kann auch bei Parallel +schnittstellen eingesetzt werden.  +  +Zur eingabeseitigen Flußkontrollsteuerung kann SHard die IOCONTROL-Funktionen +"stop" und "weiter" (siehe S.#topage("weiter")#) verwenden:  +  +Nach "stop" muß SHard weiter einlaufenden Input selbst zwischenpuffern oder auf der +V.24-Schnittstelle das Signal 'REQUEST TO SEND' wegnehmen bzw. XON senden. +Dadurch wird bei den meisten Fremdrechnern ein weiteres Senden unterbrochen, sofern +(im ersten Fall) das Signal 'REQUEST TO SEND' dort mit dem V.24-Eingang 'CLEAR TO +SEND' verbunden ist. Wird von EUMEL-0 "weiter" aufgerufen, so kann auf dem ent +sprechenden Kanal wieder empfangen werden (RTS setzen bzw. XON senden).  +  +Für die ausgabeseitige Flußkontrolle muß rechnerseitig ebenfalls das Signal 'CLEAR TO +SEND' bzw. der Empfang von XOFF berücksichtigt werden. Wenn an der Schnittstelle das +'CLEAR TO SEND' weggenommen wird, darf SHard keinen weiteren Output auf dieser +Schnittstelle machen, bis 'CLEAR TO SEND' wieder anliegt. Entsprechend muß der +Empfang von XOFF die Ausgabe anhalten und XON sie wieder starten.  +  +Bemerkung:   Die meisten Systeme enthalten diese CTS-Funktion schon in ihrer Hard +             ware, so daß im SHard dafür keine Vorkehrungen getroffen werden müs +             sen.  +  +  +Zur Einstellung der gewünschten Flußkontrolle eines Kanals dient die IOCONTROL- +Funktion "flow". Ähnlich wie "baud" und "bits" wirkt auch "flow" nur auf Kanal 32 #on("i")#ein +stellend#off("i")# und auf allen anderen Kanälen lediglich #on("i")#abfragend#off("i")#.  +  +  +    #d("IOCONTROL ""flow""")#  +  +       Eingang:      d0 = eigener Kanal (1...15 / 32)  +                     d1 = 6  +                     d2 = 0  +                     d3 = Modus * 256 + adressierter Kanal  +       Ausgang:      d1 = Rückmeldung (0 = ok, 1 = nicht möglich)  +  +       Zweck:        Wird diese Routine auf dem Steuerkanal (d0=32) aufgerufen, muß +                     sie den gewünschten Flußkontrollmodus für den adressierten Kanal +                     einstellen.  +                     Dabei sind folgende Modi festgelegt:  +  +                          Modus = 0     Keine Flußkontrolle  +                          Modus = 1     XON/XOFF (in beiden Richtungen)  +                          Modus = 2     RTS/CTS (in beiden Richtungen)  +                          Modus = 5     XON/XOFF (nur ausgabeseitig)  +                          Modus = 6     RTS/CTS (nur ausgabeseitig)  +                          Modus = 9     XON/XOFF (nur eingabeseitig)  +                          Modus = 10    RTS/CTS (nur eingabeseitig)  +  +                     SHard wird hierdurch informiert, wie er auf "stop" und "weiter" +                     reagieren soll. Wenn keine Flußkontrolle gewünscht wird +                     (Modus=0), muß SHard "stop" und "weiter" ignorieren; bei +                     Modus=1 oder Modus=9 muß bei "stop" XOFF und bei "weiter" +                     XON geschickt werden; bei Modus=2 oder Modus=10 muß bei +                     "stop" das Signal RTS auf low und bei "weiter" wieder auf high +                     gesetzt werden. Mit "stop" ist hierbei das Unterschreiten des +                     Schwellwertes bei der Rückmeldung von +                     "inputinterrupt" gemeint.  +  +                     Bei Modus=1 oder Modus=5 müssen empfangene XON/XOFF +                     -Zeichen, bei Modus=2 oder Modus=6 das Signal CTS beachtet +                     werden.  +  +                     Wird diese Routine auf einem anderen Kanal als 32 aufgerufen, +                     informiert sie den Aufrufer lediglich, ob der geforderte Flußkontroll +                     modus auf dem adressierten Kanal einstellbar wäre.  +  +       Hinweis:      Falls SHard-spezifisch weitere Flußkontrollmodi implementiert +                     werden sollen, darf SHard hierfür negative Moduswerte in d3(8..15) +                     vergeben.  +  +                     "weiter" wird von EUMEL-0 sehr oft aufgerufen. Es +                      ist daher nicht sinnvoll, jedesmal XON zu senden, da dies die Gegenstelle +                      damit überfluten würde. SHard muß sich +                      merken, ob der Kanal im XOFF-Zustand ist und +                      nur dann bei "weiter" ein XON senden.  +  +#b("Kalender")##goalpage("kalender")#  +  +Die Datums- und Uhrzeitabfrage ist bei Rechnern mit eingebauter Uhr unnötig. EUMEL +holt sich Datum und Uhrzeit dann von SHard.  +  +    #d("IOCONTROL ""calendar""")#  +  +       Eingang:      d1 = 10  +                     d2 = gewünschte Einheit (1=Minute, 2=Stunde, 3=Tag,  +                           4=Monat, 5=Jahr)  +       Ausgang:      d1 = Rückmeldung  +  +       Zweck:        Erfragen von Datum und Uhrzeit. Falls keine Uhr vorhanden ist, +                     muß bei jedem Aufruf -1 zurückgemeldet werden, bei eingebauter +                     Uhr jeweils das Gewünschte (Minute: 0..59, Stunde: 0..23, Tag: +                     1..31, Monat: 1..12, Jahr: 0..99).  +  +       Hinweis:      Die Uhr darf zwischen zwei Aufrufen umspringen. Die daraus re +                     sultierenden Probleme werden auf höheren Ebenen abgehandelt.  +  +  +  +#bb("6.  SHard-","Interface Version")##goalpage("shdver")#  +  +Die #ib#Versionsnummer#ie# der Interface-Spezifikation, auf der SHard aufbaut, muß als +2-Byte-Konstante #ib#SHDVER#ie# in der SHard-Leiste stehen. Für das hier beschriebene +Interface muß sie den Wert 8 haben.  +  +So sind spätere Erweiterungen des SHard-Interfaces möglich, ohne daß alle SHard- +Moduln geändert werden müssen.  +  +  +  +  +#bb("7.  ","ID-Konstanten")##goalpage("ID")#  +  +SHard muß in der Leiste vier 2-Byte-Konstanten ablegen. Diese können von den höhe +ren Ebenen durch die ELAN-Prozedur  +  +       INT PROC #ib#id#ie# (INT CONST no)  +  +abgefragt werden. Dabei werden id(0) bis id(3) von EUMEL-0 geliefert, während SHard in +der Leiste die Werte für id(4) bis id(7) zur Verfügung stellen muß:  +  +       ID4     #ib#Lizenznummer#ie# des SHards *)  +#foot#  +#f#*) Dieser Wert muß mit der Nummer des Lizenzvertrags zwischen Implementierer und GMD übereinstimmen!  +#a#  +#end#  +  +       ID5     #ib#Installationsnummer#ie# des EUMEL-Anwenders **)  +#foot#  +#f#**) Diese Nummer vergibt der Lizenznehmer an die von ihm belieferten Anwender.  +#a#  +#end#  +  +       ID6     zur freien Verfügung  +  +       ID7     zur freien Verfügung  +  +  +  +  +#bb("8.  ","Zusätzliche Leistungen")##goalpage("shdelan")#  +  +Will der SHard-Implementierer zusätzliche Leistungen anbieten, die mit den Standardope +rationen nicht möglich sind, kann er weitere Codes für BLOCKIN, BLOCKOUT und +IOCONTROL zur Verfügung stellen. Um Überdeckungen mit Codes zu vermeiden, die von +EUMEL-0 intern verwendet oder erst später eingeführt werden, darf SHard für zusätzliche +Leistungen nur negative Werte als 'Funktionscode 1' verwenden.  +  +  +Zum Ansprechen der neuen Leistungen stehen die ELAN-Prozeduren #on("i")#'#ib#blockout#ie#', '#ib#blockin#ie#'#off("i")# +und #on("i")#'#ib#control#ie#'#off("i")# zur Verfügung.  +  +Ferner steht dem SHard ein Parameterkanal (32) zur Verfügung. Funktionen, die (im Multi +-User) nicht jeder Task zur Verfügung stehen dürfen, müssen über diesen Kanal 32 +abgewickelt werden und dürfen nur dort wirken.  +  +  +     PROC blockout (ROW 256 INT CONST para,      (* --> a0 *)  +                    INT CONST funktion1,         (* --> d1 *)  +                              funktion2,         (* --> d2 *)  +                    INT VAR antwort)             (* <-- d1 *)  +  +     PROC blockin (ROW 256 INT VAR para,         (* --> a0 *)  +                   INT CONST funktion1,          (* --> d1 *)  +                             funktion2,          (* --> d2 *)  +                   INT VAR antwort)              (* <-- d1 *)  +  +     PROC control (INT CONST funktion1,          (* --> d1 *)  +                             funktion2,          (* --> d2 *)  +                             funktion3,          (* --> d3 *)  +                   INT VAR   antwort)            (* <-- d1 *)  +  +Hinweis:   Der SHard darf für 'funktion 1' (d1) zusätzlich zu den hier beschriebenen +           Standardcodes nur negative Codes vereinbaren.  +  +  +Beispiel:  Gibt eine Task, die durch 'continue (x)' an Kanal 'x' hängt, den Befehl  +  +                  control (-7,1200,13,antwort),  +  +           so wird IOCONTROL mit (d0='x', d1=-7, d2=1200, d3=13) aufgerufen. +           Verläßt SHard 'control' mit d1 = 1, so enthält 'antwort' anschließend eine 1.  +  +  +Hinweis:   Um die zusätzlichen Leistungen dem Anwender einfach (und abgesichert) zur +           Verfügung zu stellen, sollte man sie in ein ELAN-Paket einbetten und dieses +           ebenfalls an die Anwender ausliefern.  +  +           Beispiel:  PACKET zusatz DEFINES fanfare, ... :  +  +                      PROC fanfare (INT CONST tonhoehe, dauer):  +  +                       IF dauer < 0  +                         THEN errorstop ("negative dauer")  +                       ELIF tonhoehe < 16  +                         THEN errorstop ("infraschall")  +                       ELIF tonhoehe > 20000  +                         THEN errorstop ("ultraschall")  +                       ELSE control (-37, 20000 DIV tonhoehe,  +                                                        dauer)  +                       FI  +  +                      ENDPROC fanfare ;  +  +                           . . .  +  +  +  +  +#bb("9.  ","Spezialroutinen")##goalpage("ke")#  +  +Als Testhilfe und zur Fehlerdiagnose kann SHard in seine Routinen Kontrollereignisse ein +bauen. Das geschieht durch Aufruf der 0-Routine 'info'. Dieser EUMEL-Debugger wird +im Anhang A (siehe S.#topage("info")#) beschreiben.  +  +  +    #d("info")#                  (0-Routine)  +  +       Aufruf:                movl   \#infomsg,(sp)-  +                              jbsr   info  +                              lea    4(sp),sp    ! restore stackpointer  +                               .  +                               .  +                     infomsg: .asciz "text"  +  +       Zweck:        Info wird aufgerufen. Dabei wird 'text' zur Identifikation des Kon +                     trollereignisses ausgegeben. #on("i")#Hinter dem übergebenen Text muß +                     ein Byte /00 stehen (durch '.asciz' sichergestellt)!#off("i")#  +  +       Hinweis:      Bei Systemen "ohne Info" (nur solche dürfen an Anwender aus +                     geliefert werden) wird nur der Info-Text ausgegeben und +                     EUMEL-0 angehalten.  +  +       Achtung:      Da der Info selbst die hier beschriebenen Stream-IO-Routinen +                     benutzt, darf man ihn von diesen Routinen aus (inputinterrupt, +                     OUTPUT, OUTCHAR, IOCONTROL "frout", IOCONTROL "stop", +                     IOCONTROL "weiter") nicht aufrufen. Wenn die Ein-/Ausgabe auf +                     Terminal 1 interruptgetrieben läuft, dürfen die Interrupts beim Info +                     -Aufruf natürlich nicht gesperrt sein.  +  +#page#  +#cc("Teil 4: ","Tips zur Portierung")##goalpage("tips")#  +  +  +#b("Nullversion des SHards")##goalpage("0ver")#  +  +  +Es wird empfohlen, zuerst eine "Nullversion" des SHard zu entwickeln, die möglichst +einfach aufgebaut und nicht auf Effizienz und vollständige Ausnutzung der Betriebsmittel +ausgerichtet sein sollte. Damit kann man rasch praktische Erfahrung gewinnen, die dann +den Entwurf und die Implementation des eigentlichen SHard erleichtert. Die Nullversion +sollte  +  +     - nur die Kanäle 0 (Hintergrund), 1 (Terminal) und 31 (Archiv) behandeln,  +  +     - keine Baudraten-, Zeichenlängen-, Paritäts- und Flußkontrolleinstellungen un +       terstützen (immer 'nicht möglich' melden),  +  +     - vorhandene (ROM-) Routinen möglichst nutzen, ohne sich um Unschönes wie +       "busy wait" beim Disketten- bzw. Plattenzugriff zu grämen.  +  +Mit dieser Nullversion sollte man dann versuchen, EUMEL zu starten. Da der Hintergrund +                     keitsanforderungen an die Zeitangaben bei #on("i")#einzelnen#off("i")# Interrupts +höheren Ebenen) in das Archivlaufwerk einlegen und von dort laden. Der Vortest sollte +sich direkt nach dem Start folgendermaßen auf Terminal 1 melden:  +  +                E U M E L - Vortest  + +          Terminals:  1,  +          RAM-Groesse (gesamt):     ... KB  +          Pufferbereich:            ... KB  +          Hintergrund-Speicher:     ... KB  +  +          Speichertest: ************  +  +Man sollte während der ****-Ausgabe des Speichertests irgendein Zeichen eingeben. +Das EUMEL-System muß dann in das ausführliche Start-Menü überwechseln. (Andern +falls funktioniert die Eingabe nicht richtig!)  +  +Als nächstes sollte man versuchen, den Hintergrund vom Archiv aus zu laden. (Diese +Möglichkeit wird im Start-Menü angeboten.) Nach dem Ende dieser Operation wird der +EUMEL-Lauf automatisch beendet. Jetzt kann man das HG-Archiv aus dem Archivlauf +werk entfernen und das System neu starten. Dann sollte EUMEL-0 vom Hintergrund +geladen werden.  +  +Bei Problemen kann der "Info" (siehe S.#topage("info")#) hilfreich sein. Voraussetzung für seine +Verwendung ist aber, daß die Terminal-Ein-/Ausgabe schon funktioniert.  +  +Beim Start des EUMEL-Systems kann (wie im Systemhandbuch beschrieben) durch den +Konfigurationsdialog der Terminaltyp von Kanal 1 eingestellt werden. Falls das verwendete +Terminal in dieser Liste nicht aufgeführt wird und auch keinem der aufgeführten (in Bezug +auf die Steuercodes) gleicht, kann man z.B.  +  +    - den neuen Terminaltyp an einem anderen EUMEL-Rechner verfügbar machen +      (Umsetztabellen definieren) und per Archiv zum neuen Rechner tragen,  +  +    - die notwendigen Umcodierungen per SHard durchführen.  +  +Diese Problematik entsteht bei Rechnern mit integriertem Terminal in der Regel nicht, weil +Steuerzeichen dort sowieso algorithmisch interpretiert werden müssen. In diesem Fall wird +man direkt die EUMEL-Codes als Grundlage wählen, so daß keine Umsetzungen erfor +derlich sind.  +  +Bei einer provisorischen Anpassung kann man auf Invers-Video ohne weiteres verzich +ten.  +  +  +Im Gegensatz zu der Nullversion sollte man bei der eigentlichen SHard-Implementierung +darauf achten, die Möglichkeiten der Hardware effizient zu nutzen. Der Testverlauf ent +spricht dann wieder im wesentlichen dem oben beschriebenen Vorgang.  +  +  +  +#b("Typische Fehler")##goalpage("fehler")#  +  +  +    a)   SHard-Routinen zerstören Registerinhalte bzw. sichern sie beim Interrupt nicht +         vollständig.  +  +    b)   'jbsr' bzw. 'rts' verändern den Stackpointer.  +  +    c)   Fehler bei der Interruptbehandlung führen zu Blockaden ("hängende Inter +         rupts").  +  +    d)   Cursorpositionierung außerhalb des Bildschirms bei einem internen Terminal +         (Bildwiederholspeicher im Rechner) wird nicht abgefangen. Das führt dann zu +         wildem Schreiben in den Hauptspeicher.  +  +    e)   'warte' wird unerlaubt aufgerufen. ('warte' darf nur von BLOCKIN, BLOCKOUT, +         IOCONTROL "size" und IOCONTROL "format" aus aufgerufen werden. Ferner +         kann man 'warte' noch nicht beim Systemladen aufrufen!)  +  +    f)   OUTPUT-Verhaspler oder -Blockaden entstehen durch Fehlsynchronisation +         zwischen dem Füllen des Ausgabepuffers durch die Routine OUTPUT und der +         Interruptroutine, die den Puffer leert und ausgibt.  +  +    g)   IOCONTROL "frout" meldet in gewissen Situationen nie "mindestens 50 Zeichen +         im Puffer frei" und "Puffer leer". Das kann schon im Vortest zu Output-Blok +         kaden führen.  +  +    h)   Obwohl "frout" einen Wert größer als x meldet, nimmt "output" nicht alle x +         Zeichen an.  +  +    i)   IOCONTROL "size" meldet falsche Werte.  +  +    j)   IOCONTROL verkraftet keine beliebigen (auch unsinnige) Werte.  +  +    k)   BLOCKIN bzw. BLOCKOUT geben die Kontrolle an das System zurück, bevor +         alle Daten übertragen sind. (Sofort nach der Rückgabe geht EUMEL-0 davon +         aus, daß der Puffer frei ist und anderweitig benutzt werden kann!)  +  +    l)   Die Stepping-Rate eines Plattencontrollers wird falsch eingestellt, beziehungs +         weise die Platte wird nicht im 'buffered step mode' betrieben, obwohl sie be +         schleunigend positionieren kann. Dadurch werden die Zugriffszeiten auf dem +         Hintergrund unnötig verlangsamt. Man bedenke, daß man so einen Fehler leicht +         übersieht, weil sich das System nicht fehlerhaft, sondern nur langsamer verhält. +         Außerdem macht sich die Verlangsamung erst bemerkbar, wenn größere Teile +         des Hintergrundes benutzt werden.  +  +    m)   Bei schnellem Zeichenempfang treten "Dreher" auf. Das deutet meistens auf +         einen rekursiven Aufruf der 0-Routine 'inputinterrupt' hin. Dabei überholt dann +         das zweite Zeichen das erste.  +  +    n)   Bei schnellem Zeichenempfang, speziell bei gleichzeitiger Ausgabe, gehen +         Eingabezeichen verloren oder werden verfälscht. In der Regel ist das auf +         Timingprobleme bei der Interruptbehandlung zurückzuführen. Interrupts gehen +         verloren bzw. die Zeichen werden nicht schnell genug abgeholt.  +  +  +  +  +#b("Effizienzprobleme")##goalpage("eff")#  +  +    a)   Bei #on("i")##on("b")#V.24- und Parallelschnittstellen#off("i")##off("b")# ist schlechter Durchsatz in der Regel auf +         Fehlverhalten von "frout" zurückzuführen. Auch kostet es in Multi-User- +         Systemen sehr viel, wenn OUTPUT immer nur ein Zeichen übernimmt. (Dann +         läuft der ganze Apparat der EUMEL-0-Maschine für jedes Zeichen wieder an.)  +  +         Besonders bei der Parallelschnittstelle achte man darauf, daß nicht durch un +         glückliches Timing häufig Blockaden auftreten. So kann zu kurzes 'busy wait' auf +         Freiwerden der Parallelschnittstelle dazu führen, daß jedes zweite Zeichen abge +         lehnt wird, so daß OUTPUT faktisch zeichenweise arbeitet. Andererseits darf na +         türlich 'busy wait' auch nicht auf Millisekunden ausgedehnt werden.  +  +  +    b)   Wenn #on("i")##on("b")#Disketten ohne DMA#off("i")##off("b")# angeschlossen werden, kann man bei Single- +         User-Systemen ohne weiteres 'busy wait' einsetzen, um nach dem Seek- +         Vorgang auf den Block zu warten. Im Multi-User sollte das aber wenn irgend +         möglich umgangen werden, da eine halbe Umdrehung immerhin ca. 100 ms +         kostet.  +         Falls nur ein Endeinterrupt nach jeder Diskettenoperation zur Verfügung steht, +         kann folgendes Verfahren günstig sein:  +  +            seek befehl an controller ;  +            warten auf endeinterrupt ;  +            lesebefehl ohne datentransport auf sektor davor ;  +            warten auf endeinterrupt ;  +            lese oder schreib befehl auf adressierten sektor ;  +            cpu intensives warten und datentransport .  +  +         Die Dummyoperation auf den Sektor vor dem adressierten dient dabei nur dazu, +         ohne CPU-Belastung einen Zeitpunkt zu finden, wo man dem eigentlichen +         Sektor möglichst nahe ist. Die Zeit, in der die CPU benötigt wird, sinkt damit auf +         ca. 25 ms. Die Implementation dieses Algorithmus' ist aber nicht ganz einfach, +         da die 0-Routine 'warte' wegen der verlangten kurzen Reaktionszeiten nicht +         verwendet werden kann. Alle 'warte auf ...' müssen also durch Interrupts reali +         siert werden:  +  +            setze interrupt auf lesen davor ;  +            stosse seek an ;  +            REP  +              warte  +            UNTIL komplette operation beendet ENDREP .  +  +               lesen davor :  +                  setze interrupt auf eigentliche operation ;  +                  stosse lesen davor an .  +  +               eigentliche operation :  +                  ignoriere fehler beim datentransport ;  +                  stosse lesen oder schreiben an ;  +                  REP  +                    REP UNTIL bereit ENDREP ;  +                    uebertrage ein byte  +                  UNTIL alles uebertragen ENDREP ;  +                  melde komplette operation beendet .  +  +  +    c)   Bei der Ansteuerung von #on("i")##on("b")#Platten#off("b")##off("i")# sollte man darauf achten, daß die 0-Routi +         ne 'warte' nicht öfter als notwendig aufgerufen wird. Sonst wird das Paging +         zugunsten der CPU-intensiven Prozesse zu stark verlangsamt. Z.B. kann man +         bei vielen Plattencontrollern auf eine eigene Seek-Phase verzichten:  +  +            beginne seek ;             beginne seek und lesen ;  +            REP                        REP  +              warte                      warte  +            UNTIL fertig PER ;         UNTIL fertig PER  +            beginne lesen ;  +            REP  +              warte  +            UNTIL fertig PER  +  +         Hier braucht die linke Fassung immer mindestens ein 'warte' mehr als die +         rechte. Bei starker CPU Belastung wird sie deshalb bis zu 100 ms länger für das +         Einlesen eines Blocks benötigen.  +  +         Eine ähnliche Situation kann auftreten, wenn die Platte in 256-Byte-Sektoren +         unterteilt ist, so daß zu jedem EUMEL-Block zwei Sektoren gehören. Wenn +         möglich sollte dann zwischen diesen beiden Sektoren kein 'warte' aufgerufen +         werden. Andererseits darf natürlich auch nicht längere Zeit CPU-intensiv ge +         wartet werden. Evtl. lohnt es sich in solchem Fall, mit der Sektorverschränkung +         zu experimentieren.  +  +#page#  +#cc("Anhang A: EUMEL-","Debugger ""Info""")##goalpage("info")#  +  +  +Für interne Testzwecke gibt es den "Info". Systeme "mit Info" und "ohne Info" unter +scheiden sich nur im EUMEL-0-Teil (Systemkern). Der SHard-Implementierer erhält +zum Test Hintergründe "mit Info" und zur Auslieferung solche "ohne Info". Infofähige +Systeme dürfen nur von den SHard-Implementierern verwendet werden.  +  +    #on("i")##on("b")#Achtung: Infofähige Systeme dürfen auf keinen Fall an Anwender ausgeliefert werden, +             da vermittels Info alle Systemsicherungs- und Datenschutzmaßnahmen un +             terlaufen werden können.#off("i")##off("b")# *)  +#foot#  +#f#*) Ausnahmen von dieser Regel bedürfen der expliziten Zustimmung der EUMEL-Systemgruppe (GMD bzw. HRZ +Bielefeld) und des jeweiligen Anwenders. Solche System müssen immer durch spezielle Schlüsselworte abgesichert +werden.  +#a#  +#end#  +  +  +  +#b("Aufruf des Info")##goalpage("aufrinf")#  +  +Zum Aufruf des Infos gibt es drei Möglichkeiten:  +  +    a) Beim Start des EUMEL-Systems geht man durch Eingabe eines beliebigen Zei +       chens während des Vortests in den ausführlichen Start-Dialog. Durch Eingabe +       von 'I' gelangt man dann in den Info-Modus. #on("i")#(Diese Möglichkeit wird in dem +       Startmenü nicht aufgeführt.)#off("i")#  +  +    b) Man kann den Info durch die ELAN-Prozedur 'ke' aufrufen. D.h. wenn das +       System gestartet wurde und sich eine Task am Terminal mit "gib kommando" +       gemeldet hat, kann man durch 'ke *return*' in den Info-Modus gelangen.  +  +    c) Wenn sich am Terminal keine Task befindet, die auf Eingabe wartet, gelangt man +       durch die Tastenfolge 'i *info*' (*info* meist = CTL d, zur Tastendefinition siehe +       "Systemhandbuch, Konfigurierung") in den Info-Modus.  +  +Alle diese Möglichkeiten funktionieren nur bei infofähigen Systemen.  +  +Bei schweren Systemfehlern, die eine Weitermeldung an die höheren Ebenen des +EUMEL-Systems unmöglich machen, wird soweit möglich ebenfalls der Info aufgerufen. +Bei Systemen "ohne Info" wird lediglich eine Meldung auf Kanal 1 ausgegeben und das +System angehalten.  +  +  +  +#b("Info-Format")##goalpage("forminf")#  +  +Der Info ist bildschirmorientiert. Beim Aufruf des Infos und nach den meisten Info-Kom +mandos werden die zwei obersten Zeilen wie folgt aufgebaut: *)  +#foot#  +#f#*) Bildschirmgetreues Verhalten kann der Info allerdings erst nach der Konfigurierung des Kanals zeigen. Vorher (d.h. +insbesondere beim Aufruf aus dem Vortest heraus) werden Cursorpositionierungen in der Regel nicht korrekt durchge +führt.  +#a#  +#end#  +  +Mini: nnnn   text  eeee  +Maxi: xxxx  +  +  +wobei  +  +    #on("b")#nnnn#off("b")#  den Miniprozeß bezeichnet, der den Übergang in den Info veranlaßt hat: INTER +          (Interpreter), LADER, MUELL (Müllabfuhr) oder ARCHIV,  +  +    #on("b")#xxxx#off("b")#  den Maxiprozeß (Task) bezeichnet, der gerade durch den Elan-Prozessor +          bearbeitet wird (xxxx ist code (tasknummer + code ("0"))),  +  +    #on("b")#text#off("b")#  den Grund für den Info-Modus anzeigt und  +  +    #on("b")#eeee#off("b")#  eine interne, nur den EUMEL-0-Entwickler interessierende Fehlernummer +          ist.  +  +In der untersten Zeile erscheint (hinter der Angabe des evtl. angezeigten Datenraumes, der +Adresse und der Länge) die Eingabeaufforderung 'info:'.  +  +  +  +#b("Info-Kommandos")##goalpage("cmdinf")#  +  +Info-Kommandos können in der 'info:'-Zeile mit dem Format  +  +          [<zahl>]<buchstabe>  +  +gegeben werden oder, wenn der Cursor sich im Dump befindet, mit dem Format  +  +          <buchstabe>  +  +wobei dann für <zahl> die der Cursorposition entsprechende Dumpadresse (modulo +2**16) gesetzt wird (siehe '*cup*').  +  +<zahl> ist immer in Hexaform einzugeben.  +  +'g'    Der Info-Modus wird wieder verlassen. Dies ist allerdings bei harten Fehlern ge +       sperrt.  +  +'z'    Der Leitblock des angezeigten Maxiprozesses wird dargestellt. (Nur im Miniprozeß +       INTER.)  +  +'s'    Dumps werden auf den Datenraum <zahl> eingestellt (s:=<zahl>). Auch der +       Realspeicher kann hiermit in verschiedenen Modi eingestellt werden:  +  +                 1s    Programmspeicher (absolute Adressen)  +                ffs    Tabellenspeicher (relativ zum Tabellenanfang)  +  +'l'    Dumps werden auf die Länge <zahl> eingestellt. Desungeachtet kann man einen +       versehentlich zu langen Dump durch eine beliebige Eingabe abbrechen. Dann wird +       allerdings '*cup*' gesperrt (siehe unten).  +  +'p'    Dumps werden auf die Byteadresse <zahl> eingestellt (p:= <zahl>; wmodus:= +       FALSE).  +  +'w'    Dumps werden auf die Wortadresse <zahl> eingestellt. Die vor jeder Dumpzeile +       ausgegebene Adresse ist dann auch eine Wortadresse. Ein Wort = 2 Bytes +       (p:=2*<zahl>; wmodus:=TRUE).  +  +'k'    Block <zahl> laden und per Dump anzeigen. Es erfolgt dabei eine Umstellung auf +       den Realdatenraum (s:=/ff).  +  +'x'    Suchen nach Bytekette:  +  +-->    xctext  +-->    xhxx xx ...  +-->    x  +  +       Es wird nach 'text' bzw. Hexafolge 'xx xx ...' bzw. nach der durch das letzte +       'x'-Kommando eingestellten Bytekette gesucht.  +       Das Kommando ist durch *return* abzuschließen.  +       Die Suche beginnt ab Position 'p' und ist auf die Länge <zahl> Seiten (512 +       Byte-Einheiten) begrenzt (0=unendlich).  +       Eine beliebige Eingabe bricht die Suche vorzeitig ab.  +  +'*return*'  +       Es wird der eingestellte Dump ausgegeben (siehe 's', 'l', 'p', 'w'). Bei wmodus +       (siehe 'p', 'w') werden Wortadressen ausgegeben.  +  +'o'    Wie '*return*', jedoch wird zuvor p := p+l  gesetzt (zum Weiterblättern).  +  +  +'*cup*' *)  (Cursor up). Umschaltung in den Modus zum Ändern in Dumps.  +#foot#  +#f#*) Falls der Kanal noch nicht konfiguriert ist, muß man natürlich eine Taste betätigen, die den EUMEL-Code für +Cursor Up erzeugt. In der Regel ist das CTL c. Falls das Terminal ohne Konfigurierung keine Cursorpositionierungen +durchführt, ist dieser Modus nicht sehr gut benutzbar.  +#a#  +#end#  +       Der Cursor fährt in den Dump und kann mit den Cursortasten dort bewegt werden. +       Wird eine Hexazahl jetzt eingegeben, so wird diese als Inhalt des Bytes eingetra +       gen, auf dem der Cursor gerade steht. Dies funktioniert auch auf beliebigen Da +       tenräumen. Info beantragt dann bei der Speicherverwaltung einen Schreibzugriff für +       die entsprechende Datenraumseite, so daß Änderungen mit der Copy-on- +       Write-Logik erfolgen, also nur taskspezifisch sind. Für diese Task sind die Ände +       rungen allerdings dann permanent, da sie auch auf den Hintergrund wirken.  +  +       Hinweis:  Dumpt man mit 'k' einen Block und ändert dann darin, so sind diese +                 Änderungen u.U. nur temporär, da der Info kein Rückschreiben des +                 Blockes veranlaßt.  +  +       Achtung:  Jede Eingabe, die kein Positionierzeichen und kein gültiges Zahlzeichen +                 ist, beendet diesen Modus. Das neue Zeichen wird als Info-Komman +                 do aufgefaßt, wobei <zahl> auf die aktuelle Adresse gesetzt wird.  +                 Somit wird dieser Änderungsmodus üblicherweise durch *return* been +                 det.  +  +  +  +#b("Einige Systemadressen")##goalpage("sysaddr")#  +  +Der Info nützt nur wenig, wenn man nicht weiß, was man sich anschauen soll. Wesentliche +Angaben über die Systemstruktur enthält das 'Brikett' (interne Systemdokumentation für +Projekt Mikros der GMD). Da diese etwas allgemeiner gehalten ist, geht sie nicht auf +implementationsabhängige Konstanten ein. Diese sind hier aufgeführt.  +  +Der Tabellenspeicher der EUMEL-0-Maschine wird relativ zu M0START angelegt. Im Info +kann der Tabellenspeicher durch die Datenraumangabe ffs adressiert werden, z.B. wird +durch das Kommando ffs1000p der Anfang der 'ktab' gezeigt.  +  +Ab /1000 liegt die 'ktab'. Sie enthält Informationen, welche Blöcke an welcher Stelle des +Arbeitsspeichers liegen: In der Kachel mit der Adresse /a000+/200*i befindet sich der +Inhalt des Blockes, dessen Nummer in <ktab+2*i> steht. Ferner enthält die Tabelle, zu +welchem Datenraum (drid) und welcher Seite des Datenraums der Inhalt gehört. (Nur +relevant, wenn die Prozeßnummer <> /ff ist).  +  +    ktab:  +  +   /1000      Blocknummern (je 2 Bytes)  +   /2000      Prozeßnummern (je 1 Byte)  +   /2800      drid's (prozeßspezifisch, je 1 Byte)  +   /3000      Seitennummern (je 2 Bytes)  +   /4000      Steuerbits (je 1 Byte):  +  +              2**0:  Inhalt wird gerade transportiert (zum HG oder Archiv).  +              2**1:  Inhalt ist identisch mit Inhalt auf HG. Wird beim Schreiben auf die +                     Kachel (per Software) zurückgesetzt.  +              2**2:  Schreiberlaubnis (siehe Brikett).  +              2**3:  Inhalt wurde kürzlich benutzt. Solche Kacheln werden 'weniger +                     stark' verdrängt.  +  +  +  +/5d50    enthält den 'Laderpool'. Es handelt sich um Blocknummern von zu ladenden +         Blöcken. Ist der höherwertige Teil der Blocknummer gleich /fd, so ist dies keine +         Anforderung.  +  +         Blocknummern > /ff00 stehen für Blöcke mit dem Inhalt 512mal /ff und werden +         nie auf dem Hintergrundmedium gespeichert.  +  +  +  +/0       enthält den DR-Eintrag des drdr (siehe Brikett).  +  +  +  +  +/5c00.../5cff:  +         enthält die Aktivierungstabelle. Ist (/5c00+i)=/01, so ist die Task i aktiv. Hin +         weis: /5cff enthält immer /01, ohne daß dieser Zelle eine Task zugeordnet ist.  +  +  +  +#b("Leitblock")##goalpage("pcb")#  +  +Mit dem 'z'-Kommando wird der Leitblock einer Task dargestellt. Die einzelnen Einträge, +die voneinander durch je 2 Blanks getrennt sind, haben die Form  +             Bezeichnung=Wert  +wobei Wert in hexadezimaler Form angegeben ist. In der folgenden Beschreibung steht x, +y und z für irgendeine Hexadezimalziffer.  +  +    ic=0xxxxx       Der virtuelle Befehlszähler der Task zeigt auf /xxxxx im Datenraum 4 +                    dieser Task. Durch die Eingabefolge:  +                          4s<xxxxx>w*return*  +                    kann man sich den Code, der ausgeführt werden soll, ansehen.  +  +    flags=xxyy      Bit /80 von yy zeigt den Fehlerzustand an.  +                    Bit /40 von yy zeigt 'disable stop' (siehe Benutzerhandbuch) an.  +                    Bit /10 von yy zeigt vorzeichenlose Arithmetik an (Compilierung).  +  +    lbas=xxxx       Die lokale Basis steht auf /1xxxx im Datenraum 4 (Wortadresse).  +  +    pbas=xx         Die Paketbasis steht auf /xx00 im Datenraum 4 (Wortadresse).  +  +    hptop=xyz3      Der Arbeitsheap geht von /30000 (Byteadresse!) bis /3xyz0 (Byte +                    adresse!).  +  +    chan=xx         Die Task hängt an Kanal /xx (Terminalnummer).  +                    0 <==> kein Terminal angekoppelt.  +  +    task=xxyy,zzzz  Die Tasknummer der betrachteten Task ist /yy. /xx ist die Stations +                    nummer im EUMEL-Netz, /zzzz ist die Versionsnummer zum +                    Abdichten von 'send'/ 'wait'.  +  +Um den Code, auf den der 'ic' zeigt, zu interpretieren, ziehe man das Brikett zu Rate.  +#page#  +#cc("Anhang B: Einige ","EUMEL-Begriffe")##goalpage("glossar")#  +  +  +#on("bold")#Archiv:#off("bold")#  +  +     Medium (z.B. Diskette, Band, Kassette) zur Speicherung von Datenräumen (Pro +     grammen, Daten und Dateien) einer oder mehrerer Tasks außerhalb eines +     EUMEL-Systems zum Zwecke der Aufbewahrung oder des Datenaustauschs.  +  +     Auch ein ganzer EUMEL-Hintergrund kann (durch 'save system') auf Archiv (z.B. auf +     eine oder mehrere Disketten) geschrieben werden. Ein solches "Hintergrundarchiv" +     kann dann zur Erzeugung eines EUMEL-Hintergrundes (im Vortest) dienen.  +  +  +#on("bold")#Archivsystem:#off("bold")#  +  +     Programmsystem zur Übertragung von Datenräumen zwischen Archiv und Hinter +     grund.  +  +  +#on("bold")#EUMEL-0 (EUMEL-0-Maschine, Systemkern):#off("bold")#  +  +     Softwareschicht, aufbauend auf die hardwareabhängige Schicht SHard. EUMEL-0 ist +     nur vom Prozessor, nicht aber von der jeweiligen Rechnerkonfiguration abhängig. Die +     durch EUMEL-0 definierte Schnittstelle zu höheren (in ELAN implementierten) +     Schichten ist auf allen EUMEL-Systemen identisch. EUMEL-0 wird auf dem +     EUMEL-Hintergrundarchiv angeliefert.  +  +  +#on("bold")#Hintergrund (EUMEL-Hintergrund, HG):#off("bold")#  +  +     1. Medium (z.B. Platte, Diskette, RAM) zur Speicherung von Datenräumen (Pro +        grammen, Daten und Dateien) aller Tasks eines EUMEL-Systems;  +     2. Die Gesamtheit der auf diesem Medium gespeicherten Information.  +  +     Die Bezeichnung "Hintergrund" ist im Zusammenhang mit dem Konzept des im +     EUMEL realisierten Virtuellen Speichers zu sehen. Der Datentransfer zwischen Hin +     tergrund und Arbeitsspeicher (RAM) erfolgt ohne Zutun oder Wissen des EUMEL- +     Benutzers bzw. der Task, der die Daten gehören.  + diff --git a/doc/porting-mc68k/1985.11.26/source-disk b/doc/porting-mc68k/1985.11.26/source-disk new file mode 100644 index 0000000..bf86ccf --- /dev/null +++ b/doc/porting-mc68k/1985.11.26/source-disk @@ -0,0 +1 @@ +porting/portdoc-m68k_eumel-netz-1985-11-26.img | 
