diff options
Diffstat (limited to 'doc/porting-8086/8')
-rw-r--r-- | doc/porting-8086/8/doc/Port.8086 | 2483 | ||||
-rw-r--r-- | doc/porting-8086/8/source-disk | 1 |
2 files changed, 2484 insertions, 0 deletions
diff --git a/doc/porting-8086/8/doc/Port.8086 b/doc/porting-8086/8/doc/Port.8086 new file mode 100644 index 0000000..a709a2a --- /dev/null +++ b/doc/porting-8086/8/doc/Port.8086 @@ -0,0 +1,2483 @@ +#type ("trium6")##limit (12.)# +#limit (30.0)# +#type ("trium8")##limit (12.0)# +#start(1.5,1.5)# +#type("triumb36")# +#free(4.0)# + EUMEL + Portierungshand + buch + 8086 / 8088 +#type("triumb18")# +#free(1.5)# + Version 8 +#page(1)# +#type ("trium8")##limit (12.0)# +#block# +#pagelength(19.5)# +#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 8086/8088-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")# + Block-IO zur MS-DOS-Partition #topage("bmsdosp")# + 5.3 IO-Steuerung #topage("iocontrol")# + Einstellung 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")# + 0-Version des SHards #topage("0ver")# + Effizienzprobleme #topage("eff")# + Typische Fehler #topage("fehler")# + +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")# +#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 Portierungshandbüchern +für verschiedene Prozessortypen. Dieses bezieht sich auf Rechner mit 8086/ 8088-Prozes +soren. + +Zum Betrieb eines EUMEL-Systems wird dieses Handbuch nicht benötigt! + + + +#b("Referenzliteratur")# +#goalpage("reflit")# + + + "EUMEL Benutzerhandbuch" + + "EUMEL Systemhandbuch" + + "EUMEL Quellcode der insertieren ELAN-Pakete" + + "iAPX 86,88-Users Manual" + intel, 1981 + + + +#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 8086-CPU sollte mit mindestens 2.5 MHz (8088: 4.0 MHz) + arbeiten. Falls die Buszugriffe durch einen CRTC o.ä. ver + langsamt werden, sollte die echte 8086/ 8088-Leistung + durchschnittlich mindestens einem ungebremsten 2.5 MHz (4.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 80 K Byte #ib#Hauptspeicher#ie# + verfügen, besser sind 128 K als Anfangsausrüstung. + + #ib#Hintergrund#ie# Als Hintergrundmedium sind #ib#Floppy#ie#, #ib#Harddisk#ie# und RAM bzw. + ROM denkbar. + + Kapazität: > 300 K, besser > 400 K (Single-User) + > 750 K, besser > 1000 K (Multi-User) + + Zugriff: < 500 ms (Single-User) + < 200 ms (Multi-User) *) +#foot# +#f# +*) Hier ist die durchschnittliche Zugriffszeit auf einen 512 Byte großen Block gemeint. Für Platten und Floppies kann man +sie als Summe der Positionierzeit über die halbe Platte und der Zeit einer halben Umdrehung berechnen.#a##end# + + #ib#Archiv#ie# Als Archivgerät wird meistens eine Floppy eingesetzt. Aber + auch Band oder Kassettenrecorder sind denkbar. Die Anfor + derungen an Kapazität und Geschwindigkeit sind anwen + dungsspezifisch. + + #ib#Bildschirm#ie# Angestrebt werden sollte ein Bildschirm mit 24 Zeilen mit je 80 + Zeichen (oder größer). Kleinere Bildschirme sind anschließbar, + aber mit 40 Zeichen pro Zeile läßt sich nicht mehr komfortabel + arbeiten. + Rollup und freie Cursorpositionierung sind notwendige Vor + aussetzungen, invers-video ist erwünscht, aber nicht not + wendig. Weiterhin werden 'Löschen bis Zeilenende' und 'Lö + schen bis Schirmende' benötigt. Lokale Editierfunktionen sind + überflüssig. + + #ib#Tastatur#ie# An Steuertasten sollten mindestens ESC und die vier Cur + sortasten vorhanden sein. Dabei ist es günstig, wenn die + Cursortasten ergonomisch als Block bzw. Kreuz angeordnet + sind. EUMEL benötigt weitere Steuertasten für HOP, RUBIN, + RUBOUT und MARK. Dafür können beliebige 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 (Floppy, Harddisk) + +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: Basismaschine + + 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 geschrie + ben (siehe "EUMEL Quellcode"). Dementsprechend sind alle Schichten ober + halb der EUMEL-0-Maschine prozessor- und rechnerunabhängig, d.h. + Anpassungen an einen neuen Rechnertyp sind nicht erforderlich. + +#ib#EUMEL 0#ie# 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 8086/ + 8088 Bezug genommen. Bei der Portierung auf einen 8086/8088-Rechner + wird die 8086/8088-EUMEL-0-Maschine ohne Anpassungen (!) übernom + men. + +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 8086/8088- +Rechner angepaßt bzw. neu geschrieben werden muß. Deshalb besteht der größte Teil dieses +Handbuchs aus der Spezifikation des 8086/8088-SHards. + + + +#b("Anlieferung des 8086/8088-EUMEL-Systems")# +#goalpage("anlief")# + +Der Implementierer erhält die EUMEL-Software auf Disketten. Dabei stehen folgende +Standardformate zur Wahl: + + 8", 1D, 77 Spuren, 16 Sektoren (\#0...\#15) � 512 Byte + + 5", 2D, 40 Spuren, 9 Sektoren (\#1...\#9) � 512 Byte *) +#foot# +#f# +*) 48 tpi#a##end# + + +Die Diskettenlieferung enthält + + - Single-User Hintergrund + - Multi-User Hintergrund + - Standardarchive + - Archive mit weiterer Anwendersoftware + +Dabei enthält der Hintergrund auch die EUMEL-0-Software (oft auch als "Urlader" be +zeichnet). + +#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 Hintergrundgerät spezielle Blöcke z.B. für Boot und SHard freigehalten werden +sollen, muß das bei der Abbildung der Hintergrundblocknummern auf die Sektoren der Floppy +bzw. der Harddisk berücksichtigt werden. + +Aufbau des Hintergrundes: + + Block 0 Systemetikett + + Block 10...10+k-1 EUMEL-0-Software (Urlader) + + 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ß Urlader und + Hintergrund kompatibel sind. + 12 FFh ; 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...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 #dx("Standardformate")#: + + + 8", 1D, 77 Spuren, 16 Sektoren (\#0...\#15) � 512 Byte + 8", 2D, 77 Spuren, 16 Sektoren (\#0...\#15) � 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 + + + 5", 2D, 40 Spuren, 9 Sektoren (\#1...\#9) � 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 + + + 5", 2D, 80 Spuren, 9 Sektoren (\#1...\#9) � 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 + + + 5", HD, 80 Spuren, 15 Sektoren (\#1...\#15) � 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 verschie +denen Rechnertypen zu vereinfachen. + +#on("i")#Hinweis: Um den Datenaustausch zwischen verschiedenen Rechnertypen zu vereinfa + chen, sollten möglichst alle der hardwaremäßig möglichen Standardformate (min + destens lesend) unterstützt werden. Dabei sollte SHard sich automatisch auf das + Format der jeweils eingelegten Floppy 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. M0 muß immer vorhanden sein, M1, M2 und M3 nur in speziellen Betriebsarten: + + #dx("M0")# #on("b")#allgemeines #ib#RAM#ie(1,", allgemeines")##off("b")# + Dieser Bereich muß immer vorhanden sein. Bei den meisten Rechnern liegt der + Urlader 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 Pa + gingbereich benutzt. M0 umfaßt deshalb meistens allen verfügbaren Speicher, bis + auf den Platz für SHard, Boot-ROM und Bildwiederholspeicher. + + #dx("M1")# #on("b")#Urlader-#ib#ROM#ie(1,", Urlader")##off("b")# + Gibt es nur bei Rechnern, die den Urlader in einem ROM haben. (M0 wird dann + nur für Tabellen und als Pagingspeicher eingesetzt.) + + #dx("M2")# #on("b")#Hintergrund-#ib#ROM#ie(1,", Hintergrund")##off("b")# + Gibt es nur bei Rechnern, die nicht Floppy oder Festplatte sondern ROM und + RAM als Hintergrundspeicher verwenden. + + #dx("M3")# #on("b")#Hintergrund-#ib#RAM#ie(1,", Hintergrund")##off("b")# + Gibt es nur bei Rechnern, die nicht Floppy oder Festplatte sondern ROM und + RAM oder RAM allein als Hintergrundspeicherverwenden. + +Damit sind drei verschiedene Betriebsarten des EUMEL-Systems möglich: + + #dx("Normalbetrieb")#: M0 (> 80 K) + Hintergrundgerät (Festplatte oder Floppy) + Archivgerät (Floppy) + + Im Normalbetrieb befindet sich der Hintergrund auf einer Festplatte oder Floppy. + RAM wird für den Urlader und zum Paging eingesetzt. Alle mittleren und grö + ßeren Systeme verwenden den Normalbetrieb. + + + #dx("Minibetrieb")#: M0 (> 80 K) + M3 (mindestens 300 K) + Archivgerät (Floppy) + + Im Minibetrieb wird RAM als Hintergrundspeicher eingesetzt. Dieser wird beim + Einschalten über das Archivgerät geladen und beim Abschalten ('shutup') wieder + zurückgeschrieben. + + + #dx("ROM-Betrieb")#: M0 (> 24 K) + M1 (> 45 K) + M2 (> 170 K) + M3 (> 60 K) + Archivgerät (Kassettenrecorder oder Floppy) + + Im ROM-Betrieb stehen Urlader und Standardteil des Hintergrundes im ROM. + Der übrige Hintergrund befindet sich im RAM. + +#page# +#cc("Teil 3: SHard ","Interface Spezifikation")# +#goalpage("shardifc")# + + +#bb("0. ","Vorbemerkungen")# +#goalpage("vor")# + + +#b("Zur Notation")# +#goalpage("not")# + +Im folgenden wird zwischen #dx("0-Routinen")#, die dem SHard vom EUMEL-0-System zur +Verfügung gestellt werden, und #dx("SHard-Routinen")# unterschieden, die der SHard implemen +tieren muß. Damit dieser Unterschied 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ß geschrieben. + +8086/8088-Befehle werden wie in "iAPX 86,88 Users Manual" (intel, 1981) notiert: + + mov al,27 + add ab,bl + +Hexadezimale Zahlen werden durch ein nachgestelltes 'h' gekennzeichnet: + + 12h = 18 + 1Fh = 31 + FFFFh = 65535 + + +#b("Link-Leisten")# +#goalpage("leist")# + +Die Verbindung zwischen SHard und Urlader (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:0 (im Normal- oder Minimodus) bzw. M1:0 (im ROM- +Modus): + + Adresse + + 00h eumel0id db 'EUMEL ' + db 10 dup (?) + 10h eumel0blocks dw + 12h hgver dw + 14h cputype dw 3 ; für 8086 oder kompatible CPU + 16h urver dw + 18h dw + 1Ah shdvermin dw + 1Ch shdvermax dw + 1E dw + 20h systemstart dd + 24h inputinterrupt dd + 28h timerinterrupt dd + 2Ch warte dd + 30h grab dd + 34h free dd + 38h shutup dd + 3Ch info dd + +Hinweis: Die Segmentteile der 'dd'-Addressen in dieser Link-Leiste sind natürlich unde + finiert. Deshalb muß SHard diese auf M0 bzw. M1 setzen. Dazu ist es mindestens + beim ROM-Urlader erforderlich, die 0-Leiste in einen von SHard verwalteten + RAM-Bereich zu kopieren. + + +Für die Gegenrichtung muß SHard der 0-Maschine die "SHard-Leiste" zur Verfügung stel +len: + + Adresse + + 00h SHDID db 'SHARD ' + db 10 dup (?) + 10h SHDVER dw 8 + 12h MODE dw + 14h ID4 dw + 16h ID5 dw + 18h ID6 dw + 1Ah ID7 dw + db 4 dup (?) + 20h OUTPUT dd + 24h BLOCKIN dd + 28h BLOCKOUT dd + 2Ch IOCONTROL dd + 30h SYSEND dd + db 12 dup (?) + 40h M0START dw + 42h M0SIZE dw + 44h M1START dw + 46h M1SIZE dw + 48h M2START dw + 4Ah M2SIZE dw + 4Ch M3START dw + 4Eh M3SIZE dw + + +Dabei ist als 'MxSTART' eine Paragraphenadresse (d.h. Adresse DIV 16) und entsprechend +als 'MxSIZE' die Länge des Bereichs als Bytelänge DIV 16 anzugeben. + + + + +#b("Allgemeine Link-Bedingungen")# +#goalpage("link")# + +In der Regel sind sowohl 0-Routinen als auch SHard-Routinen durch 'call' aufzurufen: + + call dword ptr <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 das F-Re + gister *) - bleiben unverändert. +#foot# +#f# +*) Flags sind i.a. nach dem Aufruf einer Routine undefiniert. Ausnahmen sind natürlich die Flags, die als Ausgangspara +meter in manchen Fällen definiert sind.#a##end# + +Jede SHard-Routine muß also alle Register (bis auf F), die sie verändert und die keine +Ausgangsparameter sind, retten und wiederherstellen. Im Gegenzug braucht SHard beim +Aufruf von 0-Routinen selbst keine Register zu retten. +Das schließt auch die Segmentregister mit ein. Um SHard-eigene Daten über DS zu adres +sieren, muß SHard also DS sichern, neu laden und zum Schluß wiederherstellen. Entspre +chendes gilt für ES. SS darf nicht verändert werden. + + +#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 'call' an 0-Routinen +weiterleiten. +Die Register (bis auf AX und F) werden von den aufzurufenden 0-Routinen selbst gesi +chert. Auch die Segmentregister DS und ES werden von EUMEL-0 geladen. (CS wird +automatisch durch den "far call" gesetzt, SS darf sowieso nicht verändert werden.) Die +normale Interrupt-Sequenz im SHard sieht dann folgendermaßen aus: + + intadr: push ax + mov al,<parameter> + call dword ptr <routine> + ; interrupt level freigeben + pop ax + iret + + + +#bb("1. System ","laden")# +#goalpage("laden")# + +SHard muß die EUMEL-0-Software vor dem eigentlichen Start an den Anfang der Spei +cherregion M0 laden. EUMEL-0 befindet sich normalerweise auf dem Hintergrund von Block +10 ab. Der erste Block (10) enthält am Anfang die 0-Leiste. Dort steht an der Stelle 10h 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 geladen werden. + + Achtung: Zu diesem Zeitpunkt kann SHard die oben aufgeführten 0-Routinen na + türlich 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 der EUMEL-0-Software (Block 10) 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-Urlader) einspielen, indem man ein Hintergrundarchiv vor dem +Systemstart in das Archivgerät legt. Dann wird EUMEL-0 von dort geladen, so daß man den +Hintergrund dann wie im Systemhandbuch beschrieben vom Archiv auf das Hintergrundme +dium kopieren kann.*) +#foot# +#f# +*) Kopiervorgänge (Archiv -> Hintergrund) werden vom EUMEL-0-Urlader 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'). + + #dx("systemstart")# (0-Routine) + + Eingang: DS:BX Adresse der SHard-Leiste + Interrupts disabled + + Aufruf: jmp dword ptr systemstart + + Zweck: Die EUMEL-0-Maschine wird gestartet. Alle notwendigen + Hardwareinitialisierungen (z.B. der Peripheriebausteine) + müssen vorher schon geschehen sein. + + Hinweis: Der Stackpointer und die Segmentregister brauchen nicht + definiert zu sein, da beim Ansprung alle Interrupts maskiert + sein sollten und somit keine Interrupts auftreten können. + EUMEL-0 lädt beim Start CS, SS, SP, DS, ES und läßt In + terrupts zu (STI). Falls jedoch in dieser Zeit ein "Non Maskable + Interrupt" auftreten kann, muß SHard SS und SP "vorläufig" + laden. + + MODE: Über das MODE-Wort in der SHard-Leiste können Optionen + gesetzt werden: + + Bit 0 = 0 EUMEL-0 ist auf dem Hintergrund abge + speichert. Der entsprechende Bereich bleibt + geschützt. (Standard) + + Bit 0 = 1 EUMEL-0 befindet sich nicht auf dem Hin + tergrund. Der entsprechende Bereich steht zur + freien Verfügung für andere EUMEL-Daten. + (Da die EUMEL-0-Software nur beim + Systemstart geladen wird (read only!), kann es + bei Geräten mit kleinem Hintergrund inter + essant sein, diese Blöcke auf dem Hinter + grund anderweitig zu nutzen. Das Systemla + den kann dann z.B. mit Hilfe einer speziellen + Urladediskette vom Archivgerät aus erfolgen.) + + Bit 8 = 0 Beim Systemstart wird der Speicher überprüft. + (Standard) + + Bit 8 = 1 Der Speichertest beim Systemstart unterbleibt. + Man sollte nur bei Rechnern, die beim Ein + schalten schon eigene Speichertests durch + führen, auf den Speichertest des EUMEL + verzichten. + + Bit 9 = 0 Beim Systemstart wird die Vortest-Tapete + ausgegeben und man kann durch Eingabe + eines Zeichens die Vortestmenüs aktivieren (s. + Systemhandbuch). (Standard) + + Bit 9 = 1 Die Vortest-tapete wird unterdrückt. Es gibt + auch keine Möglichkeit, die Vortestfunktionen + aufzurufen. Der Speichertest unterbleibt + ebenfalls. + + + + #d("SYSEND")# + + Parameter: - + + Zweck: Hiermit wird SHard das Ende eines Systemlaufs mitgeteilt. + Somit können evtl. notwendige Abschlußbehandlungen durch + geführt werden. SHard kann mit 'ret' zu EUMEL-0 zurück + kehren, muß aber nicht. Diese Routine kann z.B. dazu benutzt + werden, die Hardware auszuschalten oder in ein umgebendes + System zurückzukehren (EUMEL als Subsystem). In den mei + sten Fällen wird die Routine leer implementiert werden, d.h. + nur aus 'ret' bestehen. + + +#bb("3. ","Speicherverwaltung")# +#goalpage("spver")# + + +#b("Hauptspeicher")# +#goalpage("haupt")# + +Der Hauptspeicher umfaßt die Teile des 8086/8088-Speichers, die EUMEL-0 verwalten +darf, nämlich die Bereiche M0, M1, M2 und M3 (siehe S.#topage("speicher")#). M1, M2 und M3 sind dabei nur +bei speziellen Betriebsarten nötig. Jeder der vier Bereiche wird in der SHard-Leiste durch +die Anfagsadresse MxSTART und seine Länge MxSIZE beschrieben: + + MxSTART Anfang des Bereichs als Paragraphenadresse (Byteadresse DIV + 16) + MxSIZE Größe des Bereichs in Paragraphen (Bytegröße DIV 16) + +Nicht vorhandenen Bereiche werden durch MxSIZE = MxSTART = 0 gekennzeichnet. + + + + + +#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 werden. + +Wenn SHard (z.B. über Interrupt) einen Speicherfehler mitgeteilt bekommt, sollte er wenn +möglich eine entsprechende Meldung ausgeben und das System brutal anhalten: + + rien ne vas plus: jmp rien ne vas plus + + +Wenn Speicherfehler mit Sicherheit bemerkt werden, verhindert diese Reaktion, daß die +Fehler auf dem Hintergrund festgeschrieben werden und evtl. später zu Systemfehlern füh +ren. + +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. + + #dx("timerinterrupt")# (0-Routine) + + Eingang: AL seit letztem Zeitgeberinterrupt vergangene Zeit (in ms) + + Zweck: Wird von EUMEL-0 für interne Uhren und für das Schedu + ling (Zeitscheibenlogik) verwendet. Es werden keine hohen + Genauigkeitsanforderungen an die Zeitangaben bei #on("i")#einzel + nen#off("i")# Interrupts gestellt. Um EUMEL-0 eine genaue Real + zeituhr zu ermöglichen, sollte die so erzeugte Zeitangabe #on("i")#im + Mittel#off("i")# aber möglichst genau sein, d.h. die Summe der in + nerhalb 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. + Die 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 Funk +tion 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 wer + den.#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. + + #dx("inputinterrupt")# (0-Routine)#goalpage("inp")# + + Eingang: AL Kanalnummer (1...15) + CH eingegebenes Zeichen + CL Fehlerbits: + Bit 0 = 1 Mindestens ein Zeichen konnte auf + diesem Kanal nicht empfangen + werden (z.B. weil Interrupts gesperrt + waren). + Bit 1 = 1 Es wurde ein BREAK erkannt (bei + V24). Dieses Ereignis kann nicht + durch ein Sonderzeichen gemeldet + werden, da bei einer 8-bit-Über + tragung schon alle Zeichen vergeben + sind. Daher wird BREAK hier aufge + nommen, obwohl es im eigentlichen + Sinne kein Fehler sein muß. + Bit 2 = 1 Das übergebene Zeichen ist verfälscht + (z.B. Parität falsch). + + Ausgang: AL Zahl der noch freien Bytes im Eingabepuffer von + EUMEL-0. Die Angabe gilt für den Puffer dieses + Kanals nach Eintrag des übergebenen Zeichens. + + Zweck: SHard muß EUMEL-0 durch Aufruf dieser Routine mitteilen, + daß eine Eingabe vorliegt. + + Hinweise: EUMEL-0 puffert die Zeichen. Falls 0 geliefert wird, ist der + Puffer voll und EUMEL-0 ignoriert weitere Eingaben, bis + wieder Platz im Puffer vorhanden ist. (siehe IOCONTROL + "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 Input + quellen regelmäßig abzufragen. Dabei muß man allerdings den + goldenen Mittelweg zwischen zu häufiger (Systemdurchsatz + sinkt) und zu seltener Abfrage (Zeichen gehen verloren) such + en. Man sollte dabei nicht nur an die menschliche Tippge + schwindigkeit sondern auch an die höchste Baudrate denken, + die man für Rechnerkopplungen noch unterstützen will. *) + + Falls SHard Flußkontrolle für den Kanal + ausüben soll, muß er die Rückmeldung in AL + auswerten. Dabei ist mit einem geeigneten + Schwellwert zu arbeiten, da in der Regel die + sendende Gegenstelle einer Sendeunterbrechung + nicht sofort Folge leistet. + +#foot# +#f# +*) Eine weitere Möglichkeit, auf manchen Kanälen ohne Interrupts auszukommen, wird bei der IOCONTROL-Funktion +"weiter" beschrieben (siehe S.#topage("weiter")#).#a##end# + + Achtung: #on("i")#Keinesfalls darf 'inputinterrupt' rekursiv aufgerufen werden. + Normalerweise 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 bestimm + ten Umständen das nächste Zeichen abgeholt werden muß, + bevor die 0-Routine beendet ist, muß SHard einen eigenen + Puffer implementieren:#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 enthält noch + zeichen REP + nimm zeichen aus shard puffer ; + enable interrupt ; + input interrupt ; + disable interrupt + PER ; + input interrupt := false ; + enable interrupt + FI . + + + + #d("OUTPUT")# + + Eingang: AL Kanalnummer (1...15) + CX Anzahl auszugebender Zeichen + DS:BX Adresse der Zeichenkette + Ausgang: CX Anzahl der übernommenen Zeichen + C-Flag gesetzt <=> alle Zeichen übernommen + + Zweck: Ausgabe einer Zeichenkette. Diese ist (möglichst ganz) zwi + schenzupuffern, denn die Ausführung von OUTPUT sollte kein + Warten auf IO enthalten. Der Ausgabepuffer muß mindestens + 50, besser 100 Zeichen fassen können. Durch eine Interrupt + logik oder etwas Äquivalentes ist sicherzustellen, daß dieser + Puffer parallel zur normalen Verarbeitung 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. + + Hinweis: OUTPUT kann mit CX=0 aufgerufen werden. Auch diese leere + Operation muß mit gesetztem C-Flag quittiert werden. + + Achtung: #on("i")#Keinesfalls darf innerhalb von OUTPUT die 0-Routine 'warte' + aufgerufen werden.#off("i")# + + Vorschlag: Falls der Kanal nicht existiert bzw. OUTPUT darauf unsinnig + ist, sollte vorgegaukelt werden, alle Zeichen seien ausgege + ben (CX unverändert und C-Flag gesetzt). + + + +#b("Terminals")# +#goalpage("term")# + +"Normale" #ib#Terminal#ie(1,", normales")#s können ohne weitere Unterstützung des SHards angeschlossen wer +den. 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 gear +beitet 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/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 abgebrochen +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 Umsetztabelle +im System (siehe Konfiguratorbeschreibung) nicht ausreicht bzw. nicht nötig ist (Beispiele: +Terminals, in deren Bildwiederholspeicher direkt gearbeitet wird; Terminals, die soweit pro +grammierbar 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 Pagingmedium 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. AL unterscheidet diese Fälle. Außer beim Paging +(AL=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 Umpufferung +erfolgen. + +Dieser Hauptspeicherbereich darf nur bei BLOCKIN verändert werden. + +SHard darf (anders als bei OUTPUT) erst dann zur Aufrufstelle zurückgeben, wenn die ver +langte Operation abgeschlossen ist. Treten während der Operation Wartezeiten auf, so muß +SHard die 0-Routine 'warte' aufrufen, damit das System andere Prozesse weiterlaufen +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 Parameter in Register CX nur positive Werte (Bit 7 von CH = 0). +Der SHard kann selbst negative Codes einführen. + + + #d("BLOCKIN")# + + Eingang: AL Kanalnummer (0...32) + CX Parameter 1 + DX Parameter 2 + DS:BX Adresse des Hauptspeicherbereichs + Ausgang: AL undefiniert (darf also verändert werden) + CX Rückmeldecode + DS:BX darf verändert werden + + Der Inhalt des Hauptspeicherbereichs (<DS:BX>... <DS: + BX> +511) darf verändert sein. + + Zweck: "Einlesen" von Blöcken. Die genaue Wirkung hängt vom + Parameter und dem Kanal ab. + + Vorschlag: Falls der Kanal nicht existiert bzw. BLOCKIN darauf unsinnig + ist, sollte die Rückmeldung -1 in CX geliefert werden. + + + #d("BLOCKOUT")# + + Eingang: AL Kanalnummer (0...32) + CX Parameter 1 + DX Parameter 2 + DS:BX Adresse des Hauptspeicherbereichs + Ausgang: AL undefiniert (darf also verändert werden) + CX Rückmeldecode + DS:BX 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 + Parameter und dem Kanal ab. + + Vorschlag: Falls der Kanal nicht existiert bzw. BLOCKOUT darauf un + sinnig ist, sollte die Rückmeldung -1 in CX geliefert wer + den. + + + #dx("warte")# (0-Routine) + + Ausgang: Alle Register undefiniert! + + Zweck: Diese Routine ist bei 'blockin' oder 'blockout' dann aufzu + rufen, wenn SHard im Augenblick nichts zu tun hat. Durch den + Aufruf von 'warte' erhalten andere Systemteile die Möglichkeit, + weiter zu arbeiten. 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, + bis auf die Segmentregister CS und SS! SHard muß davon + ausgehen, daß 'warte' seinerseits andere SHard-Kompo + nenten 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")# AL 0 bzw. 31 + CH 0 + CL Blocknummer DIV 65536 + DX Blocknummer MOD 65536 + DS:BX Hauptspeicheradresse + + Der angegebene 512-Byte-Block ist in den Hauptspeicher + ab <DS:BX> einzulesen. + + #on("b")#BLOCKOUT#off("b")# AL 0 bzw. 31 + CH 0 + CL Blocknummer DIV 65536 + DX Blocknummer MOD 65536 + DS:BX Hauptspeicheradresse + + Der Hauptspeicherbereich (<DS:BX>... <DS:BX>+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) + +Zusätzlich zu der Rückmeldung muß bei CX <> 0 in DS:BX die Adresse eines Fehlerstrings +(Längenbyte + Fehlertext) geliefert werden. *) +#foot# +#f# +*) Diese Zusatzrückmeldung ist nur für die BLOCKIN/OUT Aufrufe auf Kanal 0/31 von Bedeutung. Sie wird nur von +EUMEL-0 beim Paging und im Hardwaretest ausgewertet.#a##end# + +#dx("Fehlerwiederholungen")#: 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-System 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. + +#dx("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 Datentrans + port" zu lesen, so daß nur CRC überprüft wird. + +Will SHard weitere Archivlaufwerke zur Verfügung stellen, so kann er dafür Kanalnummern +(30,29..) vergeben. Auf ELAN-Ebene kann die archivierende Task durch 'continue (x)' das +Laufwerk 'x' ansteuern. + +Hinweis: Das System versucht Hintergrund und Archiv parallel zu betreiben, d.h. wenn + SHard bei der Hintergrundbehandlung das UP 'warte' aufruft, kann 'warte' sei + nerseits die Archivbehandlung des SHards aufrufen. Wenn beides z.B. denselben + Floppykontroller benutzt, muß SHard sicherstellen, daß das gut geht (z.B. durch + Semaphoren). + + +Sollen auch #on("b")#Disketten nach #ib#DIN 66 239#ie##off("b")# auf dem Archivkanal gelesen und geschrieben +werden können, müssen auf Kanal 31 zusätzlich Blöcke mit 'deleted data mark' gelesen und +geschrieben werden können. Dafür kann BLOCKIN (beim Lesen einer Diskette) als weitere +Rückmeldung liefern: + + 4 'Deleted data mark' gelesen. + +Ausgabeseitig wird ein entsprechendes BLOCKOUT benötigt: + + #on("b")#BLOCKOUT#off("b")# AL 31 + CH 40h + CL Blocknummer DIV 65536 + DX Blocknummer MOD 65536 + DS:BX Hauptspeicheradresse + + Der Hauptspeicherbereich (<DS:BX>... <DS:BX>+511) ist + mit der Kennung 'deleted data mark' auf den angegebenen + Block zu schreiben. + +Anmerkung: Diese Funktion muß nur implementiert werden, wenn Disketten nach DIN 66 239 + beschrieben können werden sollen. + + + +#b("Block-IO zur MS-DOS-Partition")# +#goalpage("bmsdosp")# + +Auf EUMEL-Rechnern, die mit einer Festplatte ausgerüstet sind, kann man einen Teil der +Platte als MS-DOS-Partition und einen anderen als EUMEL-Partition reservieren. Für den +Datenaustausch auf Dateiebene existiert EUMEL-Software, die über den Kanal 29 auf die +MS-DOS-Partition zugreift. Falls SHard dieses unterstützen will, muß er entsprechende +BLOCKIN/OUT-Operationen zur Verfügung stellen. Diese entsprechen den Operationen auf +Kanal 0: + + #on("b")#BLOCKIN#off("b")# AL 29 + CH 0 + CL Blocknummer DIV 65536 + DX Blocknummer MOD 65536 + DS:BX Hauptspeicheradresse + + Der angegebene 512-Byte-Block ist in den Hauptspeicher + ab <DS:BX> einzulesen. Hier bezieht sich die Blocknummer + auf die MS-DOS-Partition. Dabei muß Block 0 derjenige + sein, der den Urladesektor der MS-DOS-Partition enthält. + (Hier steht der Bios-Parameterblock.) Die weiteren Blöcke + werden genauso wie in der von MS-DOS verwendeten + Numerierung relativ zu diesem Urladesektor adressiert. + + #on("b")#BLOCKOUT#off("b")# AL 29 + CH 0 + CL Blocknummer DIV 65536 + DX Blocknummer MOD 65536 + DS:BX Hauptspeicheradresse + + Der Hauptspeicherbereich (<DS:BX>... <DS:BX>+511) ist + auf den angegebenen Block zu schreiben. Für die Blocknu + merierung gilt das oben beschreibenen. + +Als Rückmeldungen sind zu liefern: + + 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) + + Wichtig: Wird ein Block angesprochen, der nicht zur MS-DOS-Parti + tion gehört, so muß 'Versorgungsfehler' (3) gemeldet werden. + + +Anmerkung: Diese Funktionen müssen nur implementiert werden, wenn Datenaustausch + mit MS-DOS-Partitionen auf Plattenmaschinen unterstützt werden soll. + + +#bb("5.3 ","IO-Steuerung")# +#goalpage("iocontrol")# + +Die IO-Steuerung erlaubt Steuerung und Zustandsabfragen der Kanäle. IO-Steuerung wird +(außer bei Kanal 0) auch durch 'control' in ELAN induziert. + +Der Funktionscode in CX unterliegt denselben Konventionen wie bei Block-IO, d.h. das +System verwendet nur positive Codes. Der SHard-Schreiber kann auch negative Codes für +Sonderzwecke vorsehen. + + + #d("IOCONTROL")# + + Eingang: AL Kanalnummer (0...32) + CX Funktionscode 1 + DX Funktionscode 2 + BX Funktionscode 3 + Ausgang: CX Rückmeldung + AL darf verändert werden, in einigen Fällen zusätzliche + Rückmeldung + C-Flag (in einigen Fällen zusätzliche Meldung) + + Zweck: abhängig von 'Funktionscode 1' (s.u.) + +Das System verlangt folgende Informations- und Steuerleistungen über IOCONTROL: + + #d("IOCONTROL ""typ""")# + + Eingang: AL Kanalnummer (0...31) + CX 1 + Ausgang: CX Kanaltyp + + Zweck: Informiert EUMEL-0, welche IO für den angegebenen Kanal + sinnvoll ist. Die Rückmeldung in CX wird bitweise interpre + tiert: + + Bit 0 gesetzt <=> 'inputinterrupt' kann kommen. + Bit 1 gesetzt <=> OUTPUT ist sinnvoll. + Bit 2 gesetzt <=> BLOCKIN ist sinnvoll. + Bit 3 gesetzt <=> BLOCKOUT ist sinnvol. + Bit 4 gesetzt <=> IOCONTROL "format" ist sinn + voll. + + 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: AL Kanalnummer (1...15) + CX 2 + Ausgang: CX Anzahl Zeichen, die nächster OUTPUT übernimmt + C-Flag gesetzt <=> Puffer leer + + Zweck: Liefert Information über die Belegung des Puffers. Diese + Information wird von EUMEL-0 zum Scheduling benutzt. + + Achtung: #on("i")#Wenn EUMEL-0 längere Zeit kein OUTPUT gemacht hat, + muß irgendwann CX > 49 gemeldet werden.#off("i")# + + Hinweis: Unter Berücksichtigung des oben Gesagten darf "gelogen" + werden. Man kann z.B. immer 50 in CX 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 'Druckerpuffer voll' 0 in CX und 'NC' zurückge + meldet werden. Wenn aber Zeichen übernommen werden + können, sollte 50 in CX und 'C-Flag gesetzt' gemeldet wer + den. + + Vorschlag: Falls der Kanal nicht existiert oder nicht für Stream-IO zur + Verfügung steht, sollten 200 in CX und C-Flag gesetzt zu + rückgemeldet werden. + + + #d("IOCONTROL ""weiter""")# + #goalpage("weiter")# + + Eingang: AL Kanalnummer (1...15) + CX 4 + Ausgang: - + + Zweck: Das System ruft "weiter" für den in AL 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 be + troffene Kanal von sich aus keine Interrupts erzeugt, kann + SHard dies benutzen, um durch Aufruf von 'inputinterrupt' ein + Eingabezeichen zuzustellen. + #on("i")#Diese Betriebsart sollte nicht für normale Terminalkanäle + eingesetzt werden. Denn dann wird die SV-Taste nur an + EUMEL-0 zugestellt, wenn ein Prozeß auf diesem Kanal auf + Eingabe wartet. Somit sind in dieser Betriebsart CPU-inten + sive Endlosschleifen nicht normal abbrechbar!#off("i")# + + + #d("IOCONTROL ""size""")# + + Eingang: AL Kanalnummer (0...31) + CX 5 + DX Schlüssel + Ausgang: CX Anzahl Blöcke MOD 65536 + AL Anzahl Blöcke DIV 65536 + + Zweck: EUMEL-0 ruft 'size' auf, um die Anzahl Blöcke zu erfahren, + die ein Block-IO-Kanal verkraften kann (Größe von Hin + tergrund und Archiven). Bei Archivlaufwerken, die mehrere + Formate bearbeiten können, dient dieser Aufruf auch zum + Einstellen des Formats für die folgenden blockin/blockout- + Operationen anhand des Schlüssels. + + 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. Dabei gibt es die + EUMEL-Standardformate: + + 1 5" 2D-40, Sektor 1..9, 512 Bytes + 2 5" 2D-80, Sektor 1..9, 512 Bytes + 3 5" HD-80, Sektor 1..15, 512 Bytes + 10 8" 1D-77, Sektor 0..15, 512 Bytes + 11 8" 2D-77, Sektor 0..15, 512 Bytes + + Zusätzlich kann man sämtliche Spezialformate angeben: + + 8192 * laufwerkstyp 1: 8" + 2: 5" + 3: 3" + + + 4096 * seiten 0: einseitig + 1: doppelseitig + + + 1024 * dichte 0: single + 1: double + 2: high + + + 256 * spuren 0: 35 + 1: 40 + 2: 77 + 3: 80 + + + 64 * sektorbytes 0: 128 + 1: 256 + 2: 512 + + + 32 * erster sektor 0: \#0 + 1: \#1 + + + sektoren pro spur 0 ... 31 + + So bezeichnet '8762' das Format 8" 1S-77 Sektor 1..26 a + 128 Bytes. + + Anmerkung: SHard sollte alle physisch möglichen EUMEL-Standard + formate unterstützen. Von den Spezialformaten sollten die für + den Datenaustausch wichtigen Formate berücksichtigt werden. + Die EUMEL-Standardformate (1,2,3,10,11) sollten auch über + die entsprechenden analytischen Codes erreicht werden. (Z.B. + bezeichnen 1 und 21929 dasselbe Format.) Die Numerierung + der Blöcke ist in jedem Fall seitenorientiert, d.h. entsprechend + den Standardformaten (siehe S.#topage("arch")#). + + Hinweis: Bei Archiven wird 'size' aufgerufen, nachdem der Archivträ + ger eingelegt 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 (Hintergrund) 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: AL Kanalnummer (0...31) + CX 7 + DX Schlüssel + Ausgang: CX Fehlercode wie bei Archiv-BLOCKOUT (siehe S.#topage("errcod")#) + + Zweck: Dient zum Formatieren einen Mediums. Diese Funktion kann + für jeden Kanal leer implementiert sein ('ret'). Sie sollte aber + "formatierend" (z.B. auf Kanal 31) arbeiten, falls auf diesem + Kanal die "typ"-Abfrage "Formatieren sinnvoll" liefert. Falls + (bei Diskettenlaufwerken) mehrere Formate möglich sind, + bestimmt der Schlüssel das gewünschte Format. + + Schlüssel: wie bei IOCONTROL "size" + + 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 (AL = 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 (AL <> 32), wird le + diglich 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: AL eigener Kanal (1...15 / 32) + CX 8 + DX adressierter Kanal + BX Schlüssel + Ausgang: CX Rückmeldung (0 = ok, 1 = nicht möglich) + + Zweck: Wird diese Routine auf dem Steuerkanal (AL=32) aufgeru + fen, wird die angegebene Baudrate für den durch Register DX + adressierten Kanal eingestellt, falls das möglich ist. + Wird diese Routine auf einem anderen Kanal als 32 aufge + rufen, 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 unter + stützt werden. Bei V.24 Schnittstellen sollten aber minde + stens 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 + (Register BX) vergeben. + + + #d("IOCONTROL ""bits""")# + + Eingang: AL eigener Kanal (1...15 / 32) + CX 9 + DX adressierter Kanal + BX Schlüssel + Ausgang: CX Rückmeldung (0 = ok, 1 = nicht möglich) + + Zweck: Wird diese Routine auf dem Steuerkanal (AL=32) aufgeru + fen, wird die angegebene Zeichenlänge (Bits pro Zeichen) und + Parität für den durch Register DX adressierten Kanal einge + stellt, falls das möglich ist. + Wird diese Routine auf einem anderen Kanal als 32 aufge + rufen, 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 + unterstützt werden. Bei V.24 Schnittstellen sollten aber mög + lichst 1 Stopbit, 7 und 8 Bits pro Zeichen und alle drei Pari + tätseinstellungen zur Verfügung stehen. + + Hinweis: Falls SHard-spezifisch weitere Einstellungen implementiert + werden sollen, darf SHard hierfür negative Schlüsselwerte + (Register BX) vergeben. + + + + +#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 emp +fangen 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 Rückmeldung der 0-Routine +'inputinterrupt' (siehe S.#topage("inp")#), die "stop" signalisieren kann, und die IOCONTROL-Funktion +"weiter" (siehe S.#topage("weiter")#)verwenden: + +Allerspätestens bei der 'inputinterrupt'-Rückmeldung AL=0 muß SHard +auf der V.24-Schnittstelle das Signal 'REQUEST TO SEND' wegnehmen bzw. XON senden +(oder +weiter einlaufenden Input selbst zwischenpuffern). Dadurch wird bei den meisten Fremd +rechnern 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 ensprechenden Kanal wieder empfangen +werden (RTS setzen bzw. XON senden). In der Regel wird SHard schon reagieren müssen, +bevor der EUMEL-Puffer gänzlich gefüllt ist, da die Sendehardware nicht schnell genug +reagieren kann bzw. da noch sich noch Zeichen in Hardwarepuffern befinden können. + +Für die ausgabeseitige Flußkontrolle muß rechnerseitig ebenfalls das Signal 'CLEAR TO +SEND' bzw. der Empfang von XOFF/XON 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 Ausagbe anhalten und XON sie wieder starten. + +Bemerkung: Die meisten Systeme enthalten die CTS-Funktion schon in ihrer Hardware, so + daß im SHard dafür keine Vorkehrungen getroffen werden müssen. + + +Zur Einstellung der gewünschten Flußkontrolle eines Kanals dient die IOCONTROL-Funk +tion "flow". Ähnlich wie "baud" und "bits" wirkt auch "flow" nur auf Kanal 32 #on("i")#einstellend#off("i")# und +auf allen anderen Kanälen lediglich #on("i")#abfragend#off("i")#. + + + #d("IOCONTROL ""flow""")# + + Eingang: AL eigener Kanal (1...15 / 32) + CX 6 + DX adressierter Kanal + BX Modus + Ausgang: CX Rückmeldung (0 = ok, 1 = nicht möglich) + + Zweck: Wird diese Routine auf dem Steuerkanal (AL=32) aufgeru + fen, muß sie den gewünschten Flußkontrollmodus für den + adressierten Kanal einstellen. + Dabei sind folgende Modi festgelegt: + + BX= 0 Keine Flußkontrolle + BX= 1 XON/XOFF (in beide Richtungen) + BX= 2 RTS/CTS (in beide Richtungen) + BX= 5 XON/XOFF (nur ausgabeseitig) + BX= 6 RTS/CTS (nur ausgabeseitig) + BX= 9 XON/XOFF (nur eingabesetig) + BX=10 RTS/CTS (nur eingabeseitig) + + SHard wird hierdurch informiert, wie er auf "Puffer voll" und + "weiter" reagieren soll. Wenn keine Flußkontrolle gewünscht + wird (BX=0), muß SHard "stop" und "weiter" ignorieren; bei + BX=1 oder BX=9 muß bei "stop" XOFF und bei "weiter" XON + geschickt werden; bei BX=2 oder BX=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 BX=1 oder BX=5 müssen empfangene XON/XOFF-Zei + chen, bei BX=2 oder BX=6 das Signal CTS beachtet wer + den. + + Wird diese Routine auf einem anderen Kanal als 32 aufge + rufen, informiert sie den Aufrufer lediglich, ob der geforderte + Flußkontrollmodus auf dem adressierten Kanal einstellbar + wäre. + + Hinweis: Falls SHard-spezifisch weitere Flußkontrollmodi implemen + tiert werden sollen, darf SHard hierfür negative Moduswerte + (Register BX) 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: CX 10 + DX (1=Minute, 2=Stunde, 3=Tag, 4=Monat, 5=Jahr) + gewünscht + Ausgang: CX 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..7, Monat: 1..12, Jahr: 0..99). Die + Rückmeldung muß als BCD-Zahl erfolgen. + + Hinweis: Die Uhr darf zwischen zwei Aufrufen umspringen. Die daraus + resultierende Probleme werden auf höheren Ebenen abge + handelt. + + + + +#bb("6. SHard-","Interface Version")# +#goalpage("shdver")# + +Die #ib#Versionsnummer#ie# der Interface-Spezifikation, auf der SHard aufbaut, muß als 2-By +te-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-Mo +duln geändert werden müssen. + + + +#bb("7. ","ID-Konstanten")# +#goalpage("ID")# + +SHard muß direkt hinter SHDVER vier 2-Byte-Konstanten ablegen. Diese können von den +höheren 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ätzli +che 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 Mul +ti-User) nicht jeder Task zur Verfügung stehen dürfen, müssen über diesen Kanal 32 abge +wickelt werden und dürfen nur dort wirken. + + + PROC blockout (ROW 256 INT CONST para, (* --> DS:BX *) + INT CONST funktion1, (* --> CX *) + funktion2, (* --> DX *) + INT VAR antwort) (* <-- CX *) + + PROC blockin (ROW 256 INT VAR para, (* --> DS:BX *) + INT CONST funktion1, (* --> CX *) + funktion2, (* --> DX *) + INT VAR antwort) (* <-- CX *) + + PROC control (INT CONST funktion1, (* --> CX *) + funktion2, (* --> DX *) + funktion3, (* --> BX *) + INT VAR antwort) (* <-- CX *) + +Hinweis: Der SHard darf für 'funktion 1' (CX) zusätzlich zu den hier beschriebenen Stan + dardcodes 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 (AL='x', CX=-7, BX=13, DX=1200) aufgerufen. Verläßt + SHard 'control' mit CX = 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. + + #dx("info")# (0-Routine) + + Aufruf: call dword ptr info + jr weiter + db ' text' + weiter: + + Zweck: Info wird aufgerufen. Dabei wird 'text' zur Identifikation des + Kontrollereignisses ausgegeben. Der übergebene Text darf + nicht mit 0h beginnen. + + Hinweis: Bei Systemen "ohne Info" (nur solche dürfen an Anwender + ausgeliefert werden) wird nur der Info-Text ausgegeben und + EUMEL-0 angehalten. + + Achtung: Da der Info selbst die hier beschriebenen Stream-IO-Routi + nen benutzt, darf man ihn von diesen Routinen aus (inputin + terrupt, OUTPUT, IOCONTROL "frout", IOCONTROL "weiter") + nicht aufrufen. Wenn die Ein-/Ausgabe auf Terminal 1 inter + ruptgetrieben läuft, dürfen die Interrupts beim Info-Aufruf + natürlich nicht gesperrt sein. + + +Falls SHard für bestimmte Aktionen, die selten durchgeführt werden (z.B. Formatieren), viel +Speicher benötigt, kann er diesen dynamisch anfordern und später wieder freigeben. + + #dx("grab")# (0-Routine) + + Eingang: BX Anfangsadresse des zu reservierenden Bereichs im + Datensegment von EUMEL-0, muß auf 512 Byte + ausgerichtet sein. + CX Länge des zu reservierenden Bereichs in 512-Byte- + Kacheln + Ausgang: CX Rückmeldecode + + Zweck: Wenn möglich wird der zu verlangte Bereich von EUMEL-0 + "leergekämpft" und SHard zur Verfügung gestellt. + Rückmeldecode: 0 ok, Speicher steht zur Verfügung + 1 grundsätzlich nicht möglich + 2 augenblicklich nicht möglich + + Achtung: Der Aufruf von 'grab' wird in der Regel 'warte' und Block-IO + auf Kanal 0 induzieren. + + Hinweis: Es wird empfohlen, Speicher ab 3800h anzufordern, da diese + Adresse stets im frei einplanbaren Paging-Bereich liegt. + + + #dx("free")# (0-Routine) + + Eingang: BX Anfangsadresse des freizugebenden Bereichs im Da + tensegment von EUMEL-0, muß auf 512 Byte ausge + richtet sein. + CX Länge des zu freizugebenden Bereichs als 'Bytes DIV + 512' + + Zweck: Der entsprechende Bereich muß vorher mit 'grab' beschafft + worden sein. Hiermit wird er wieder EUMEL-0 zur freien + Verfügung gestellt. + + +Für spezielle Fehlersituationen steht die 0-Routine 'shutup' zur Verfügung. Damit kann +SHard z.B. bei Netzausfall ein kontrolliertes Systemende erzwingen. Das ist allerdings nur +sinnvoll, wenn durch Batteriepufferung oder Ähnliches sichergestellt ist, daß noch genügend +Zeit bleibt, um alle Seiten auf den Hintergrund zurückzuschreiben. + + #dx("shutup")# (0-Routine) + + Zweck: Erzwingt Rückschreiben aller Seiten und Systemende, d.h. + entspricht der ELAN-Prozedur 'shutup'. + + Achtung: Der Aufruf von 'shutup' wird in der Regel 'warte' und + Block-IO auf Kanal 0 induzieren, abschließend wird 'sysend' + aufgerufen. +#page# +#cc("Teil 4: ","Tips zur Portierung")# +#goalpage("tips")# + + +#b("0-Version des SHards")# +#goalpage("0ver")# + + +Es wird empfohlen, zuerst eine "0-Version" des SHard zu entwickeln, die möglichst einfach +aufgebaut und nicht auf Effizienz und vollständige Ausnutzung der Betriebsmittel ausge +richtet sein sollte. Damit kann man rasch praktische Erfahrung gewinnen, die dann den +Entwurf und die Implementation des eigentlichen SHard erleichtert. Die 0-Version soll +te + + - 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 Floppy- bzw. Plattenzugriff zu grämen. + +Mit dieser 0-Version sollte man dann versuchen, EUMEL zu starten. Da der Hintergrund +beim ersten Mal noch leer ist, muß man das Hintergrund-Archiv (Archivfloppy mit +EUMEL-0 und 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. (Andernfalls +funktioniert die Eingabe nicht richtig!) + +Als nächstes sollte man versuchen, den Hintergrund vom Archiv aus zu laden. (Diese Mög +lichkeit 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 gela +den werden. + +Bei Problemen kann der "Info" (siehe S.#topage("info")#) hilfreich sein. Voraussetzung für seine Ver +wendung 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 verzichten. + + +Im Gegensatz zu der 0-Version sollte man bei der eigentlichen SHard-Implementierung +darauf achten, die Möglichkeiten der Hardware effizient zu nutzen. Der Testverlauf entspricht +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. Hierbei sollte man auch an die Segmentregister denken. + + b) 'call' bzw. 'ret' verändern den Stackpointer. + + c) Fehler bei der Interruptbehandlung führen zu Blockaden ("hängende Interrupts"). + + 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 Zei + chen 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) Fälschlicherweise wird davon ausgegangen, daß DS oder ES konstant bleiben. + + m) Die Stepping-Rate eines Festplattencontrollers wird falsch eingestellt, bezie + hungsweise die Platte wird nicht im 'buffered step mode' betrieben, obwohl + beschleunigend 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. + + n) 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. + + o) Bei schnellem Zeichenempfang, speziell bei gleichzeitiger Ausgabe, gehen Ein + gabezeichen verloren oder werden verfälscht. In der Regel ist das auf Timing + probleme 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 ung + lü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 + natürlich 'busy wait' auch nicht auf Millisekunden ausgedehnt werden. + + + b) Wenn #on("i")##on("b")#Floppies 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 um + gangen werden, da eine halbe Umdrehung immerhin ca. 100 ms kostet. + Falls nur ein Endeinterrupt nach jeder Floppyoperation 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 ver + wendet werden kann. Alle 'warte auf ...' müssen also durch Interrupts realisiert + 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 . + + Hinweis: Solche Systeme sind über V.24 nicht netzfähig, da sie Eingabezeichen + verlieren werden. + + + c) Bei der Ansteuerung von #on("i")##on("b")#Harddisks#off("b")##off("i")# sollte man darauf achten, daß die 0-Rou + tine '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 gewar + tet 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" unterschei +den sich nur im EUMEL-0-Teil (Urlader). 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 Bie +lefeld) 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. + +Bevor das System Infokommandos annimmt, muß mit dem Kommando 'P' ein Paßwort +eingegeben werden. Lediglich dieses Kommando und das Kommando 'g' werden immer +angenommen. Das Paßwort kann mit dem Kommando 'yP' eingestellt werden. + +#b("Info-Format")# +#goalpage("forminf")# + +Der Info ist bildschirmorientiert. Beim Aufruf des Infos und nach den meisten Info-Kom +mandos werden die drei 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 durchgeführt. #a##end# + +#limit(14.0)# +XYY TEXT +F AL AH CL CH DL DH BL BH SI DI SP BP PC DS ES +xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx + +#limit(12.0)# + +wobei + + X den Miniprozeß bezeichnet, der den Übergang in den Info veranlaßt hat (A=Archiv, + E=Elan, L=Lader, M=Müllabfuhr), + + YY den Maxiprozeß (Task) bezeichnet, der gerade durch den Elan-Prozessor bear + beitet wird (YY ist die hexadezimale Tasknummer), + + TEXT den Grund für den Info-Modus anzeigt, + +Die zweite und dritte Zeile zeigen die Inhalte der 8086/8088-Register an. In der untersten +Zeile erscheint 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, falls <zahl> = 0 ist, + sonst der Leitblock der Task mit der Nummer <zahl>. (Nur im ELAN-Miniprozeß). + +'q' Die Task mit der Nummer <zahl> wird nach dem nächsten 'g'-Kommando in den + Info überführt. Dies ist nötig, wenn man sich die Datenräume dieser Task anschauen + will ('s'). + +'s' Dumps werden auf den Datenraum <zahl> eingestellt. (s:=<zahl>) + Auch der Realspeicher kann hiermit in verschiedenen Modi eingestellt werden: + FF absolute Adressierung + 0 CS-relativ + 1 DS-relativ + 2 ES-relativ + 3 SS-relativ + +'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=1). + +'P' Paßworteingabe: P<text>*return* + Erst nach diesem Kommando sind die übrigen Kommandos ausführbar. + +'x' Suchen nach Bytekette: + +--> xc text +--> xh xx 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). + +'r' Freigabe der anderen Miniprozesse. + + Zunächst werden bei Übergang in den Info alle Miniprozesse gesperrt, um eine Ver + fälschung der Fehlersituation zu vermeiden. Bei manchen Kommandos an den Info + müssen aber andere Miniprozesse u.U. aktiv werden (z.B. beim 'k' der Lader). Wenn + dies erforderlich ist, meldet der Info: + 'paging erforderlich'. Man kann dann 'r' geben und das letzte Infokommando wie + derholen, oder mit anderen Kommandos fortfahren, falls man den Fehlerzustand noch + so beibehalten will. + +'y' Zweitfunktion ausführen. + +--> 'yP<text>*return*' + Neues Paßwort einstellen (max. 9 Zeichen). Dieses wird bei 'shutup' (erst + dann!) in Block 0 eingetragen. + +--> 'yt' Block <zahl> von Archiv lesen. Dient zum Test des Archivs. + Es wird eine Kachel freigemacht und der Block mit der Nummer <zahl> + eingelesen. Der Inhalt wird sofort angezeigt (wie Kommando 'k'). + +--> 'yb' Breakpoint an die Adresse <zahl> setzen. Es wird ein INT3 (für Aufruf von + Info) abgesetzt. Info verwaltet gleichzeitig bis zu 10 gesetzte Breakpoints. Die + Breakpointnummer kann man aus der nach jedem Setzen (und Löschen) + angezeigten Breakpoint-Tabelle entnehmen. Breakpoints sind nur im Real + speicher sinnvoll. Ein Aufruf meldet sich mit TEXT= 'break z--xxxx:yyyy' (z + = Breakpointnummer, xxxx = CS, yyyy = PC beim Aufruf des Breakpoints). + Wird Info mit 'g' verlassen, so stellt er zuvor die alten 8086/8088-Befehle + wieder her und führt sie an ihrem originalen Ort aus. Direkt danach wird der + Breakpoint wieder hergestellt. + +--> 'yc' Löscht den Breakpoint an der Adresse <zahl> und stellt die ursprüngli + chen Befehle wieder her. In der Breakpoint-Tabelle muß ein Breakpoint an + dieser Adresse vermerkt sein. + +--> 'yw' Zu anderen Miniprozeß wechseln. Nur sinnvoll, wenn ein anderer Mini unter + 'vor info' aufgeführt ist. + +--> 'yl' Lernmodus ein (wie beim Editor). + +--> 'ye' Ende Lernmodus. + +--> 'ya' Ausführen. Die zwischen 'yl' und 'ye' eingegebenen Zeichen werden dem Info + so vorgesetzt, als kämen sie von der Tastatur. + + Achtung: Rekursion ('ya' im Lernmodus) wird nicht abgefangen. Das Ge + lernte wird nach jedem Kommando, das die ersten drei Zeilen + wiederaufbaut (z.B. *return*), in der Zeile vier angezeigt, wobei + für Steuerzeichen eine Ersatzdarstellung erscheint (%x mit + x=code (code (zeichen) +code ("A")), also z.B. %M für *re + turn*). + +--> 'y *return*' + Wie *return*, jedoch wird der Dump auch beim Ausführen (ya) ausgegeben. + (Ein gelerntes *return* führt im Ausführmodus nicht zum Dump). + +'*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 eingetragen, auf dem der Cursor gerade steht. Dies funktioniert auch + auf beliebigen Datenräumen. Info beantragt dann bei der Speicherverwal + tung einen Schreibzugriff für die entsprechende Datenraumseite, so daß + Änderungen mit der Copy-on-Write-Logik erfolgen, also nur taskspezi + fisch sind (durch 'q' eingestellt). Für diese Task sind die Änderungen aller + dings 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ückschrei + ben des Blockes veranlaßt. + + Achtung: Jede Eingabe, die kein Positionierzeichen und kein gültiges Zahl + zeichen ist, beendet diesen Modus. Das neue Zeichen wird als + Info-Kommando aufgefaßt, wobei <zahl> auf die aktuelle + Adresse gesetzt wird. + (Für 'yc' / 'yb' sinnvoll: Man setzt den Cursor auf die Stelle, an der + ein Break ausgelöst werden soll und gibt 'yc'/'yb'). + Somit wird dieser Änderungsmodus üblicherweise durch *return* + beendet. + +#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 imple +mentationsabhängige Konstanten ein. Diese sind hier aufgeführt. + +Ab 1s100h liegt die 'ktab'. Sie enthält Informationen, welche Blöcke an welcher Stelle des +Arbeitsspeicher liegen: In der Kachel mit der Adresse 512*i befindet sich der Inhalt des +Blockes, dessen Nummer in ktab+i, ktab+100h+i steht. Ferner enthält die Tabelle, zu +welchem Datenraum (drid) und welcher Seite des Datenraums der Inhalt gehört. (Nur rele +vant, wenn die Prozeßnummer <> 255 ist). + +Steuerbits: 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. + + + ktab frei niederwertige Blocknummer + + +80h frei frei Steuerbits + + +100h frei höherwertige Blocknummer + + +180h frei frei Prozeßnummer + + +200h frei frei drid (prozeßspezifisch) + + +280h frei frei Seitennummer (höherw.) + + +300h frei frei Seitennummer (niederw.) + + ^ ^ + -- unbenutzt -- -- Beginn echter Kacheln + -- Beginn der Anforderungen + + +Der 'Beginn echter Kacheln' hängt von der Größe der 8086/8088-Teile ('urlader') ab (i.A. +30h < i < 40h). + +'Beginn der Anforderungen' liegt bei i=2. Es handelt sich um Blocknummern von zu laden +den Blöcken. Ist der höherwertige Teil der Blocknummer gleich FDh, so ist dies keine Anfor +derung. + +Blocknummern > FF00h stehen für Blöcke mit dem Inhalt 512 FFh's und werden nie auf +dem Hintergrundmedium gespeichert. + + + +1sA00h enthält den DR-Eintrag des drdr (siehe Brikett). + + +'musta': Das System fordert Checkpoints und Müllabfuhren über die Zelle 'musta' an. Diese + findet man mit dem Info durch + + xc musta + + (hierfür ist der Text 'musta:' vor der Zelle abgesetzt). + + Die Zelle selbst enthält + + FFh : Keine Müllabfuhr oder Checkpoint + 01h : Müllabfuhr + 02h : Checkpoint + 03h : beides + 04h : Systemendecheckpoint + 0Bh : System auf Archiv schreiben ('save system') + F0h : Müllabfuhr und Checkpoint sind geperrt (nur durch Setzen im Info + möglich) + + Durch Einsetzen der Werte mit dem Info kann die entsprechende Operation ver + anlaßt werden. Beim Einsetzen darf der Info nicht im 'r'-Zustand (siehe Eingabe + 'r') stehen; zum Ausführen der Operation muß 'r' (man bleibt im Info) oder 'g' (Info + verlassen) gegeben werden. + + +1s480h-4FFh: + enthält die Aktivierungstabelle. Ist (480h+i)=01h, so ist die Task i aktiv. Hin + weis: 4FFh enthält immer 01h, ohne daß dieser Zelle eine Task zugeordnet ist. + + +#b("Leitblock")# +#goalpage("pcb")# + +Mit dem 'z'-Kommando wird der Leitblock einer Task dargestellt. Es werden Hexapaare, +gefolgt von einer Bezeichnung, ausgegeben. In der folgenden Beschreibung werden die +Hexapaare durch a,b,c dargestellt. + + a b c icount Der virtuelle Befehlszähler der Task steht auf (cMOD4)* + 10000h+b*100h+a = <ic> im Datenraum 4 dieser Task. + Durch die Eingabefolge: + 4s<ic>w*return* + kann man sich den Code, der ausgeführt werden soll, ansehen. + + Bit 2**7 von c zeigt den Fehlerzustand an. + Bit 2**6 von c zeigt 'disable stop' (siehe Benutzerhandbuch) + an. + Bit 2**4 zeigt vorzeichenlose Arithmetik an (Compilierung). + + a b lbas Die lokale Basis steht auf 10000h+b* 100h+c = <lb> im + Datenraum 4 (Wortadresse). + + a b hptop Der Arbeitsheap geht von 30000h (Byteadr.) bis (aMOD16)* + 10000h+b* 100h+(aDIV16)*10h (Byteadr!). + + a b channel Die Task hängt an Kanal 100h*b+a (Terminalnummer). 0 = + kein Terminal angekoppelt. + + a b taskid Die Tasknummer der betrachteten Task ist a. (b ist die Ver + sionsnummer zum Abdichten von 'send'/ 'wait'). + +Um den Code, auf den der 'icount' zeigt, zu interpretieren, ziehe man das Brikett zu Rate. + + +Hinweis: Wenn der Info einen internen Fehler anzeigt, und auch bei 'ke', ist der durch 'z' + angezeigte Leitblock u.U. nicht aktualisiert. Man kann dies durch die Eingaben 'r', + 'g' erzwingen. (Der Info stellt wegen 'r' dem Interpreter einen Restart zu, der dann + beim 'g' den Leitblock aktualisiert und den Befehl erneut aufsetzt). Tritt dabei der + Fehler nicht wieder auf, handelte es sich um einen transienten Fehler (z.B. der + Codeblock war noch im Einlesen und ist jetzt voll da). So etwas kann z.B. passie + ren, wenn der SHard den Abschluß einer Leseoperation zu früh meldet. + + + + + + + + + + + + diff --git a/doc/porting-8086/8/source-disk b/doc/porting-8086/8/source-disk new file mode 100644 index 0000000..8aeb5a2 --- /dev/null +++ b/doc/porting-8086/8/source-disk @@ -0,0 +1 @@ +porting/portdoc-x86-8.img |