summaryrefslogtreecommitdiff
path: root/doc/porting-mc68k
diff options
context:
space:
mode:
Diffstat (limited to 'doc/porting-mc68k')
-rw-r--r--doc/porting-mc68k/1985.11.26/doc/Port.680002173
-rw-r--r--doc/porting-mc68k/1985.11.26/source-disk1
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