Diese bisher ausgeklammerte Ein-/Ausgabe ist nun aber das einzige das noch verbleibt. Als die nächsten Vorträge sind damit verschiedenste Varianten dazu an der Reihe, und hier wird ein erster Ausschnitt davon nachgeholt, mitsammt einiger genereller Grundlagen dazu. Verbleiben tun dann nur noch, mehrere/weitere Varianten nachzuliefern.
Die Frage welchen Teil der vielen Varianten den Anfang macht beantwortete gleich das VCFe Thema, welches dieses mal Kommunikation ist. Also habe ich das als Auswahlkriterium genommen, und bringe diesmal all das an Ein-/Ausgabe was zwecks CPU zu CPU Kommunikation benutzt wird, im Gegensatz zu Benutzer Ein-/Ausgabe. Nebenbei passt aber auch noch abgespeicherte und verzögert wiedergebene Kommunikation hier gut mit hinein, und damit die Verfahren für Band und Disk beschreiben und (zurück-)lesen.
Weggelasen werden damit alle Benutzer Ein-/Ausgaben, ausser dem Teil davon der mit den Peripherigeräten kommuniziert. Also sind Daten von einer Tastatur empfangen hier, aber nicht wie diese die Tasten einliest und zu Daten macht, ebenso sind Daten zum Drucker senden hier, aber nicht wie dieser dann diese zu Bilder ausdruckt. Ebenso kommen keine Datencodierungen oder Datenformate hier, weil die nur für deren Wandlung relevant sind, nicht für die Übertragung.
Dieser Vortrag ist der dritte Teil zu zwei früheren Vorträgen, der erste 2006.05.01 - Rechnen mit Bauklötzchen - Rechnergrundlagen und deren Implementationen und der zweite 2008.04.26 - 8008 8080/8085 und Z80/U880 - Maschinencode und Assembler. Darin wurden bisher im ersten die Bits und ihre Implementation in Hardware als Gatter und daraus zusammengebaut Speicher und Prozessor gezeigt, sowie im zweiten die ganzen Prozessordetails wie Register und Rechnen und Befehle und Programmierung in Maschinencode und Assembler.
Daneben wurde schon bisher in einem weiteren Vortrag 2009.05.01 - Softe Hardware - Emulation von hochintegrierten Chips auf Mikrocontrollern neben dem Mikrocontroller auch minimalste PIO Ein-/Ausgabe für das SoftVGA Video generieren eingeführt. Also dient diese wiederholen gleich als Ausgangspunkt für diesen Vortrag.
Entscheidenstes für jegliche Digitallogik implementieren ist, dass man die beiden Bitzustände 0 und 1 auf eine unverwechselbar unterscheidbare Art representieren muss, welche dazu geeignet ist einen Mechanismus zu beeinflussen, der Bits kombinieren kann und dann wieder das Resultat davon auf die selbige Art representiert abgeben kann, zum weitere Mechanismen beeinflussen. Dazu werden in elektronischer Digitallogik üblicherweise 2 Spannungen genommen, oder seltener Stromstärken oder -richtungen. (In TTL Logik werden 0..0.8V für 0 und 2.4..5V für 1 genommen, in RS232 +/-5..25V für 0 und 1. Für ASR33 Fernschreiber werden 0 und 20mA für 0 und 1 genommen.)
Für Rechner verstehen reicht dazu bereits, dass man dazu nur einmal eine universelle Schaltung entwirft und diese dann ohne ihre Details weiter zu berücksichtigen beliebig oft benutzt, soweit Platz, Stromversorgung und Geld ausreichen. Hier müssen nun aber Signale in die Welt hinaus, bzw von der Welt herein. Dabei könnte man theoretisch genau die selbigen Signale nehmen, wenn diese nicht auf Geschwindigkeitsmaximierung und Kostenminimierung ausgelegt wären, statt auf Stabilität, und damit nur für kleine Distanzen ausreichen.
Sobald man über ein paar Meter gehen will, werden die Leitungsverluste relevant, und damit der Energieverlust der Signale. Mit längerem Kabel als Antenne werden Störungen eingefangen, und mit genug hoher Spannung ist auch Abstrahlung davon relevant. Auch Kurzschlüsse sind zu erwarten, sobald man das sichere Rechnergehäuse verlässt. Also muss man für längere Leitung andere Signale generieren, und dafür andere Schaltungen haben. Und zum diese bauen werden auch die normalen Hardwaredetails wieder relevant, zum sie kompatibel varieren. Also werden diese hier teils repetiert (für die vollen Details siehe den ersten Vortrag in der Serie).
Die einfachsten Logikformen dort sind bei bipolaren Transistoren DTL und bei MOSFET Transitoren NMOS Logiken:
Strom Spannung ------------>-------. | | voll voll .-. .-. | | W3 | | W1 | | | | Da `-' D3 `-' T2 gross T2 klein --|<--+-->|--. |------ fast voll fast nichts | | |.-' --|<--' `---| T2 (npn-Bipolar, nur Verstärker/Inverter Db |`>. ergibt erst mit der Da u Db Logik DTL) | | nichts nichts --------------------' Strom Spannung ------------>-----. voll=5V voll=5V | .-. | | W1 | | `-' T2a UND T2b kl T2a ODER T2b gr |------- fast nichts=0.5V fast voll=3.5V |---' -------------|| T2a (n-MOSFET, ergibt NMOS Logik) |->-. | |---' -------------|| T2b (n-MOSFET, ergibt NMOS Logik) |->-. | | ------------------' nichts=0V nichts=0V
Kennzeichnend für diese beiden ist, dass nach 5V hinauf nur ein Widerstand ist, von normalerweise über 1kOhm. Der hat einige Auswirkungen auf die Schaltung, aber vor allem dass jeder Wechsel von 1 nach 0 schnell ist (da zieht der gut leitende offene Transitor), während Wechsel von 0 nach 1 langsam sind (da muss der Widerstand den Strom liefern zum die Leitungskapazität auffüllen).
Bei Logik hat das nur den einen Effekt: Langsamer. Bei Ausgaben hat es einen zweiten: Das Gatter kann nur wenig Strom von 5V her liefern, kann aber anderseits viel Strom nach 0V hin versenken. Dadurch entsteht die überraschende Eigenschaft, dass Gatterausgänge zwar Daten abgeben, aber Strom aufnehmen. Beim Bau von Ausgabeschaltungen muss man daher die folgenden Schaltungen darauf auslegen, dass sie auf Strom abziehen reagieren!
Einfaches Beispiel dafür ist eine Leuchdiode (LED) ansteuern. Eine LED vom Gatterausgang (als Stromversorgung und Schalter) nach 0V verdrahtet, was die meisten Leute naheligend machen würden, resultiert im Versuch der LED ihren Strom aus dem Widerstand zu beziehen, was dieser auf viel zu niedrig limitieren wird (so ca 2mA), was wenig Licht abgibt. Man muss also die LED von 5V (Versorgung) zum Gatterausgang (Schalter und Erde) verdrahten, weil der Transistor dann ordentlich Strom durchlässt und so ausreichend Licht erzeugt wird.
Nebeneffekt davon ist aber, dass nicht 1 = 5V = Strom = Licht = ein entsteht, sondern 0 = 0V = Strom = Licht = ein (und 1 = 5V = kein Strom = Dunkel = aus), also die Anzeige "verkehrt herum" darstellen wird, das nennt man inverse Ausgabe. Also muss man dazu die Daten "vorkorrigieren", durch zuvor in der Logik (oder zumeist in der Software!) invertieren. Solche komischen Effekte, die man berücksichtigen muss, sind für Ein-/Ausgabe sehr typisch.
Ein weiterer Effekt ist, das auch so der maximale Strom limitiert ist. Schliesslich werden Logiktransistoren ja auf viele und billig hin ausgelegt, und somit ein Gatterausgang auf etwa max 10 Gattereingänge anzusteuern, die je 0.2..2mA wollen, und der Ausgang somit auch nur etwa 2..20mA aufnehmen kann, und somit keine grossen Lasten. Will man mehr machen, braucht man ohnehin einen Leistungsverstärker nachschalten. Entweder ist das ein Leistungstransistor, der selber ein zweites mal invertieren wird (also auch nicht mehr vorkorrigieren), oder ein Relais das je nach Verdrahtung invertiert oder nicht, oder gar beide hintereinander. Der Programmierer muss also immer abklären, wieherum die aktuelle Hardware reagieren wird.
Bereits bei Logik haben wir gesehen, dass es weitaus schneller geht mit Komplementärschaltungen, also mit 2 Transistoren, je einer zu 0V und 5V. Bei bipolaren Transistoren ergab das TLL und bei MOSFET Transistoren CMOS Logik. Das erlaubt nicht nur schnell Strom abziehen beim 1 zu 0 Wechsel sondern auch schnell Strom liefern beim 0 zu 1 Wechsel. Damit entfällt theoretisch auch dieser obige Effekt.
Als Schutz vor Kurzschlüssen haben aber TTL Logiken zusätzlich zum oberen Transistor auch noch einen (einiges kleinen) Widerstand drin, so 50..150Ohm. Also behält man die obigen Methoden bei, ausser man kommt mit sehr kleinen Strömen zurecht (z.B. 3mA für klein-LEDs, z.B. in einem Parallelport Logiktester, wo vorkorrigieren die zu beobachtende Funktion verfälschen würde, und invers darstellen fehleranfällig wäre). Man bemerke, dass das nur bei Kurzschluss zu 0V (oder Erde) hilft, beim den selteneren Kurzschluss zu 5V ist dann doch kaputt.
CMOS Logiken kommen üblicherweise ohne Kurzschlusschutz daher, bzw haben von sich aus im Transistor (weitaus kleinere) unvermeidbare Widerstande drin. Sie haben daher im Gegensatz zu TTL auch Ausgangsspannungen viel näher zu 0V und 5V. Und werden auch von den Herstellern als fähig beworben auch stärkere LEDs direkt anzusteuern, und in beide Richtungen. Da liegen in beiden Richtungen zweistellige mA drin (z.B. bei einem ATmega32 40mA). Das macht CMOS weitaus einfacher zu benutzen. Auch die SoftVGA nutzte genau diese Eigenschaft des AVR PIOs aus, mit den CMOS 5V Spannungen direkt durch Widerstände (als Spannungsteiler) und dann aufaddiert verwenden, zum die 3*2 RGB Farbcodebits in 3 4-Level Analog Signale im Bereich 0V..0.7V wandeln, wozu ohnehin ganze 6.2+3.1mA ausreichten.
Neben der Ausgabe ist die Eingabe dann etwas harmloser: Nicht nur dass die DTL Gatterausgänge nur Strom aufnehmen (und TTL bevorzugt aufnehmen). Alle DTL und auch TTL Gattereingänge sind als Folge davon auch ausgelegt, dass man ihnen Strom abnehmen muss. Daher wäre ein Taster oder Schalter von 5V nach Eingang genauso verkehrt, und man muss einen Taster oder Schalter von Eingang nach 0V verwenden. Dabei ist wiederum Invertierung vorhanden, weil hier ein = zu = 0V = 0 (und aus = offen = 5V = 1) gilt. Was dazu auch noch fehlt ist, dass der Eingang für 1 eine Verbindung nach 5V erwartet. Dafür addiert man dann zumeist einfach einen DTL-artigen Widerstand nach 5V hinauf. Der Wert ist unkritisch, 1..10kOhm. Invertierung muss wieder die Logik dahinter (oder die Software) machen, oder man nimmt einen umschaltenden Taster oder Schalter und verdrahtet ihn "verkehrt", so dass ein = offen und aus = zu ist.
Das ist anderseits bei beiden NMOS und CMOS kein Problem, da dort auf den Gattereingängen ohnehin kein Strom fliesst, weil das MOSFET Transistoren sind, in denen nur Spannung gemessen wird. Man kann also hier all das ignorieren, bis auf die Eigenheit, dass manche Chips eingebaute (und oft ab-/zuschaltbare) DTL Widerstände an den Eingängen haben, und diese aus Tradition oft nur nach 5V gehen.
Ein-/Ausgabe besteht aus 2 Teilen, dem digitalen der mit dem Prozessor verbunden ist, und dem analogen der mit der Aussenwelt verbunden ist. Diese sind direkt an einander gekoppelt. Der letzte Abschnitt behandelte einfachere häufige analoge Effekte die in letzterem auftreten. Dieser Abschnitt (auch im letztjährigen Vortrag drin) beschreibt nun die Details des generischen digitalen Teils, anhand der minimalistischen PIO Ein-/Ausgabe.
Jeder Rechner kann Speicher beschreiben und danach wieder auslesen. Technisch tut er beim Schreiben nur einem von den vielen Speicherworten per Speicheradresse auswählen und die dortigen Flipflops mit einer Kopie von den 0 oder 1 in einem Register beschreiben. Beim Lesen tut er wieder per Speicheradresse eines der Speicherworte auswählen und ein Register im Prozessor mit einer Kopie der Flipflops beschreiben. PIO verwendet nun nichts anderes als einen Seiteneffekt davon, nämlich dass die 0 und 1 in dem Speicher drin elektrischen Spannungen entsprechen, traditionell 0V und 5V.
Parallele Ausgabe verwendet Chips mit einigen wenigen speziell präparierten Speicherzellen, deren 0V/5V Zustand per herausgeführten Leitungen die Aussenwelt beeinflussen kann, z.B. obige Leuchtdiode mit Strom versorgen damit sie leuchtet, oder einen Transistor oder Relais auslösen für grössere Lampen oder Motoren schalten, oder ein Servo anpulsen zum etwas verschieben. Oder beliebiges anderes. Ein normaler Satz von Flipflops (z.B. 74374, 1Adresse a 8bit) reicht bereits für normale PIO Ausgabe. Generell ist man nur durch die Möglichkeiten der nachgeschalteten Analogtechnik und/oder Leistungselektronik und/oder Mechanik limitiert, sowie durch die Anzahl Bits, und die Geschwindigkeit (und Präzision) mit denen diese vom Prozessor schaltbar sind. Letzteres erweitern ist der Hauptgrund für speziellere Ausgabe Schaltungen neben PIO.
Parallele Eingabe ist auch analog. Dazu werden einfach statt Speicherzellen ihre Daten (also Spannungen) auswählen beliebige Signale ihre Spannungen ausgewählt, per hineingeführte Leitungen von der Aussenwelt genommen, auch üblich 0V/5V (die Testgrenze darf ja im Bereich 0.8-2.4V liegen), und das als 0 oder 1 in den Prozessor kopiert. Dazu kann wiederum externe Analogtechnik ein beliebiges Signal, von einem beliebgen Sensor auf diese Spannungen aufbereiten. Ein normaler Satz von Tristate Gattern (z.B. 74244, 2 mal 1Adresse a 4bit) reicht dazu. Generell ist man wieder nur durch die Möglichkeiten der vorgeschalteten Analogtechnik und/oder Sensoren limitiert, sowie die Anzahl Bits, und die Geschwindigkeit (und Präzision) mit denen diese vom Prozessor lesbar und verarbeitbar sind. Letzteres erweitern ist wiederum der Hauptgrund für speziellere Eingabe Schaltungen neben PIO.
Man kann auch als Eingabe das Signal nehmen, das von einer obigen Parallel Ausgabe her kommt, damit das wieder einlesbar ist. Damit ist die Aus+Ein Kombination nebenbei auch ein Speicher.
Diese speziellen präperierten Speicherstellen werden Ports genannt. Bei einem 8bit Prozessor können beim Speicher 8bit aufs Mal geschrieben oder gelesen werden, und folglich auch maximal 8bit auf einem Port ausgegeben oder von einem Port eingelesen werden. "Maximal" deshalb, weil man auch einen teilweisen Port machen kann, bei dem nur ein Teil der Bits gespeichert und ausgegeben werden (der Rest wird vergessen und damit fortgeworfen), oder nur ein Teil der Bits geliefert werden (der Rest bekommt Zufallswerte, welche die Software dann ignorieren muss).
Da speichern und (Wieder-)Eingabe als Ergänzung bei Ausgabe erwünschenswert ist (und man dafür mehrere Chips bräuchte), und man oft teilweise Ports Ausgabe und Rest nur Eingabe haben will (und man dafür sonst separate Ports braucht), oder gar umschaltbare Ein- oder Ausgabe (und man dafür Umschalteinrichtungen braucht), und man oft mehrere Ports braucht (und dafür alles obige mehrfach), gibt es dazu Spezialchips. Diese beliebig nutzbaren Spezialchips werden wiederum PIO (Parallel Input Output) oder seltener PIA (Parallel Interface Adaptor) genannt. (Jeder Prozessor Hersteller hat seit der Mitte 1970ern PIO Chips im Angebot, z.B. die 8255 und Z80PIO/U855 und 6820 und 6520/6522/6526 und 6530/6532. Und wie letztes Jahr gezeigt hat auch jeder Mikrocontroller die meisten seiner Pins mit solche belegt, inkl 8048/8051 und PIC und AVR, z.B. beim ATmega32 40pin AVR 4*8=32bit davon, auf 32 Pins, und damit 4/5 aller Pins.)
Alle diese PIO Chips haben mehrere konfigurierbare Ports, zumeist eine feste Eingabe und dazu noch eine ein-/ausschaltbare Ausgabe. Dazu hat es neben einem Satz Flipflops für potenzielle Ausgabedaten auch einen zweiten Satz von Flipflops zum die Ausgabe freigeben bzw sie verhinden zum die Eingabe sehen, welche damit die Richtung vorgeben. Oft wird mit Bit 0 = Eingabe (weil nach Reset 0 und Eingabe keinen Schaden anrichten kann) und 1 = Ausgabe gearbeitet. Letztlich tut eine 1 (5V) ein weiteres Tristate Gatter zwischen dem Datenausgabe Flipflop und dem Anschlusspin aufmachen. (Bei den meisten dieser Chips hat es pro Portbit und Pin eine Richtungswahl. Aber die Intel 8255 PIO ist eigenartig, indem es nur 4 Bits hat, je eines für den ganzen Port A und ganzen Port B und jede Hälfte von Port C. Ebenso ist der Intel 8051 Mikrocontroller (und sein 8048 Vorgänger) eigenartig, dass seine PIOs gar keine Richtungswahl haben, sondern Daten 0 schalten immer auf Ausgang, Daten 1 bleiben nur kurz Ausgang (für Komplementär schnell sein sein) aber werden danach abgeschaltet und nur noch per Widerstand gehalten, was eine allfällige Nutzung als Eingangssignal dann einfach übersteuern kann. Es gibt aber auch noch querere Sachen, z.B. die Intel 4004 Rechner, wo jeder 4001 256x8bit ROM Chip ein 4bit PIO eingebaut hatte (bei dem aber die Richtungsbits auch ROM waren!), und jeder 4002 64x4bit RAM Chip einen 4bit nur-Ausgang Port drin hatte (keine Richtungsbits), dafür gab es dort gar keine weiteren IO Chips irgendwelcher Art. Intel gewinnt hier ganz klar nach Eigenartigkeitspunkten.)
Manche neueren Chips (vor allem Mikrocontroller) haben sogar zuschaltbare Widerstände nach 5V, damit man simple Schalter nutzen kann ohne externe Widerstände. Da sie dabei im Eingabemodus sind, werden dafür zum Teil einfach die Ausgabe Flipflips missbraucht.
Man muss aber bereits hier dafür sorgen, dass Program und Monitor synchron bleiben, weil sonst das Bild "durchläuft". Dazu muss man für den Monitor die H uns V Synchronisationssignale generieren, welcher dessen Timing steuern, kann danach aber einfach synchron dazu drauflosschiessen.
Das wird aber anderst, und aufwendiger, wenn auf der anderen Seite eine weitere CPU steckt, mit einem eigenen Program das abläuft, dem man mehrere separate Daten schicken will. Dieses kann durchaus noch gar nicht bereit sein für Daten annehmen, oder aber bereits wartend sein auf Daten, wenn man selber nicht bereit zum senden war. Wann kann die empfangende CPU nun damit rechnen, dass jetzt gültige (und neue!) Daten da sind, bzw wann kann die sendende CPU damit rechnen dass die alten Daten jetzt abgenommen worden sind und neue folgen dürfen?
Sender Empfänger Speicher CPU Port Port CPU Speicher ROM+RAM aus ein ROM+RAM (Speicher) (Tristate) .---. .---. .---. .---. .---. .---. | | | | | |===========7======| | | | | | | | | | | |=====Daten=>======| | | | | | | |====| |===| |===========0======| |===| |====| | | |=<>=| |=>=| | | |=>=| |=<>=| | | |====| |===| |-----Strobe->-----| |===| |====| | | | | | | | | | | | | | | | | | | |--<-Acknowledge---| | | | | | `---' `---' `---' `---' `---' `---'
Der Ablauf ist nun, dass:
Damit sind die Strobe und Acknowlege Leitungen aber sehr kritisch auf selbst kleine Störimpulse, wenn die in einem ungünstigen Augenblick einen Datentransfer vorgaukeln. Es ist daher üblich diese deaktiviert auf 5V zu halten, und aktiviert auf 0V herunterzuziehen. Das ist ein weiteres in der Datenkommunikation oft benutztes Verfahren, das man low aktiven Betrieb nennt. Aber es wird ja auch von Prozessor zu Speicher verwendet für die Chip Select (/CS) Signale, aus gleichem Grund. Nebenbei ist 0V aber auch dann wenn Strom fliesst, vom Empfänger zum Sender, und damit wirkt als Nebeneffekt ein ausgestecktes Kabel als deaktivierte Handschaking Leitungen.
Zudem müssen die Ports auf beiden Seiten Speicher haben zum senden und Tristate haben zum empfangen, und beide mit einer weiteren Ausgangstristate Stufe zwischen Sender und Leitung ausgestattet werden, weil ohne diese beide gleichzeitig senden würden, was man dann als Kollision bezeichnet.
Der Ablauf wird nun leicht geändert:
Damit ist der Normalzustand aber, dass keiner am Daten senden ist, beide ihre Tristate ausgeschaltet haben, und die Datenleitungen folglich nicht mit Strom versort werden, was man als schwebende Leitungen bezeichnet. Diese erzeugen aber bei jedem elektrischen Störimpuls Einflüsse auf die Eingangsports, weil sie nun als Antennen wirken. Um das zu verhindern müssen die Datenleitungen mit einem Satz Widerständen nach 5V verbunden werden, analog zu bei DTL Logik. Diese müssen nur die Leitungen halten, nicht antreiben, und können daher gross sein. Auch da ist der Wert unkritisch, 10..100kOhm.
Für die 2 oder 4 Handshakeleitungen reichen auch beliebige PIO Anschlüsse. Diese müssen sogar erst noch nur in einer Richtung laufen. Anderseits sind diese ein paar wenige Einzelbits verschiedener Richtung, was man aber mit bitweise richtungsumschatbaren PIOs lösen kann, oder aber einzelne Bits von 2 verschiedenen Richtungen Ports nehmen. Den ganzen Ablauf kann man, da er Schritt für Schritt gesichert abläuft, in ganz gewöhnlicher Software implementieren. Das ist auch das normale Verfahren (und zumeist das einzige Verfahren bei einem Mikrocontroller, wie den 8048/8051 oder PIC oder AVR).
Man kann aber auch das ganze Handshaking in spezieller Hardware implementieren. Dazu werden dann die Handshakesignale als Nebeneffekt durch die Portzugriffe ausgelöst, genauer von den Port schreiben und lesen Adressauswahlsignalen abgeleitet. Dies ermöglicht es aber auch "dummen" Peripheriegeräten (= ohne Mikroprozessor oder Mikrocontroller darin) einen Parallelport zu benutzen. Das geht dann so:
Die meisten separaten PIO Chips bieten derartige Features an. Diese fast immer 40pin grossen Chips haben stets neben 2*8bit PIOs auch 2..8 weitere Leitungen für Handshaking, welche aber auch als generische Einzelbits nutzbar sind, dann aber oft nur in einer festen Richtung. (Der 8255 hat einen weiteren dritten vollen 8bit PIO Port C, von dem 2+2 Leitungen mit Port A (für bidirektional) und 2 Leitungen mit Port B (nur unidirektional) benutzt werden können. Der Z80PIO/U855 und die 6820 und 6520 und 6522 haben 4 spezialisierte Leitungen, von denen je 2 für jeden Port A und B unidirektional da sind, welche aber beim Z80PIO/U885 auch als 2+2 zusammengelegt für Port A bidirektional benutzbar sind, während 6820 und 6520/22 dann gezielt die Richtung umgeschaltet werden muss (man also die Richtung des nächsten Datentransfers im Voraus wissen muss). Der 6526 hat ohnehin nur 2 spezialisierte Leitungen, die dem Port B zugeordnet sind. Die 6530 und 6532 haben gar keine Handshakeleitungen, wie bei Mikrocontrollern (die 6530 ist ja eigentlich ein CPU-loser und 6532 dazu noch ROM-loser Teilmikrocontroller).)
Polling ist einfach zu machen, aber ineffizient, falls man während dessen andere Arbeit machen könnte. Bei einem Peripheriegerät (erst recht einem "dummen") ist oft nichts sinnvolleres zu tun, als auf die nächsten Daten zu warten. Bei einem Rechner dagegen schon, und sei das auch nur weitere Tastendrücke entgegennehmen, während man immer noch als Folge der bisherigen am etwas rechnen ist, und in einen Zwischenspeicher (den nennt man Tastaturbuffer) ablegen, oder weiterrechnen während noch alte Daten auf den Drucker ausgegeben werden (das nennt man Druckerspoolen). Das gilt auch für Datenkommunikation entgegennehmen während alte noch am bearbeiten ist, oder einen Block Daten absenden und schon einen neuen erzeugen.
Die primitivste Lösung für einen Rechner ist, nur dann zu pollen wenn man vom Hauptprogramm aus Daten transferieren will. Das geht einigermassen für Senden, es gibt nur Wartezeit bis vorherige Daten abgenommen sind und man die aktuellen nachschieben kann. Das ist aber problematisch für Empfangen, denn inzwischen ankommende Daten gehen unbemerkt verloren. Etwas besser ist, die Arbeit ab und zu zu unterbrechen, und kurz pollen, und dann weitermachen. Das kostet aber einiges an Programmieraufwand zum immer wieder unterbrechen, in jeder längeren Aktion, kostet Zeit in all den Fällen wo kein Datentransfer ansteht, und hat kein garantiertes unterbrechen (z.B. bei ungeplanten langen Aktionen wie z.B. Endlosschlaufen).
Für diesen häufigen Anwendungsfall haben die meisten Prozessoren einen speziellen Hinweismechanismus eingebaut. Dieser besteht darin, dass man eine separate Leitung von der zu überwachenden Handshakeleitung zum Prozessor legt (analog wie bei manchen "dummen" Geräten), welche bei Datenabgang oder -ankunft den Prozessor davon informiert. Der Prozessor wiederum ist derart verdrahtet, dass er im Befehlsdecoder vor dem Holen des nächsten Befehles in Hardware nebenbei auf Aktivierung dieser Leitung testet, ohne Programmieraufwand oder Testzeit Kosten, und nach erkannter Aktivierung dann ein spezielles Unterprogram aufruft. Dabei wird das normal ablaufende Hauptprogram unterbrochen, wesshalb man das ganze einen Interrupt (Unterbrechung) nennt, und die spezielle Leitung zum anfordern eine Interruptanforderungsleitung (INT oder IRQ), und das spezielle Unterprogram eine Interruptserviceroutine (ISR).
Wie der Prozessor die ISR auswählt, also an welche Speicheradrese er springt zum eine ISR ausführen, kann sich sehr gross unterscheiden. Zumeist hängt dies auch zusammen mit dem Verfahren wie der Prozessor seinen Reset am Anfang macht, manche Prozessoren erachten sogar Reset schlicht als einen Spezialfall von Interrupt.
Die INT oder IRQ Leitung ist nur ein Hinweis dass etwas draussen passiert ist, das nach einer Aktion verlangt. Sie besagt aber nicht was passiert ist, weil sie nur eine generische Leitung ist. Die ISR muss daher als erstes die Ursache ermitteln und dann die passende Datentransaktion ausführen. Als einfachster Weg wird einfach jetzt einmal gezielt jedes Gerät gepollt. Dazu haben viele Geräte ein Statusregister in dem ein Bit anzeigt ob einen Interrupt wollen, oft Bit 7 weil das mit einem Vorzeichen-bedingten Sprung testbar ist.
Weiterhin haben aber einige Prozessoren Möglichkeiten mehrere Interruptquellen zu separieren (z.B. Daten von/zu verschiedenen Geräten), und für jedes automatisch eine andere spezifische ISR aufzurufen, was aber das ganze nochmals verkompliziert und noch mehr verschieden macht. Bei letzteren können auch in Hardware verschiedene Prioritäten beachtet werden, also wichtigere Interrupts zuerst behandelt werden, oder gar unwichtigere Interrupts wiederum von einem wichtigeren unterbrochen werden. Ich bespreche nun ein paar der vielen möglichen Methoden:
Aber auch mit grundsätzlich erlaubten Interrupts will man oft einzelne blockieren, z.B. den den man gerade am abarbeiten ist, oder einer dessen spezifischen Datenstrukturen man ändert ohne alle anderen blockieren zu wollen. Das kann man zumeist in den einzelnen Ein-/Ausgabechips machen, wo jede einzelne ihrer Interruptquellen (und oft auch alle summarisch) einen eigenen Interrupt erlauben oder maskieren (verhindern) Flag haben.
Interrupts erlauben parallel zu rechnen und Daten übertragen, haben aber pro Interrupt abarbeiten einen ziemlich grossenen Overhead an Prozessorstatus abspeichern und Interruptquelle ermitteln, und danach wieder Interrupt aufsetzen und Prozessorstatus restaurieren. Daher ist es üblich, nur bei zu erwartender längerer oder unbekannter Wartezeit einen Interrupt aufzusetzen und zum Rechnen zurückzukehren (und dann bei Datenfortsetzung vom Interrupt unterbrochen zu werden). Für einen grösseren und schnellen Block an vorhersehbaren Daten wird ebenfalls der spezifische Interrupt ausgeschatet und dann nur das Gerät gepollt. Dazu kann fast jeder Interruptfähige Chip auch den Anforderungsstatus (Interrupt Request) "vor der Blockierung" auslesen.
ISRs richtig schreiben, all die kleine Details beachten, ohne subtile Timing Bugs und Abstürze zu erzeugen, auch nicht durch andere Interrupts blockieren und verzögern, ist ziemlich schwierig, und gilt daher auch zurecht als die Königsdisziplin in der Programmierung. Schliesslich läuft das ganze auf mehrere/einige parallel ablaufende und in kurzen Abschnitten aufgeteilte Programme hinaus, welche zur richtigen Zeit und in richtiger Reihenfolge ihre Daten an einander und die Hardware übergeben müssen, ohne dabei je Daten zu überschreiben oder unendlich auf nie kommende Daten zu warten, oder gehindert werden. Und dazu noch das ganze auch noch genug schnell zum mit einer nicht auf einem wartenden Welt zurecht zu kommen. Und das ganze noch im Grenzgebiet von Hardware/Ingenieur und Software/Programmierer, wo man beide Denkweisen/Fachkenntnisse haben muss. Daher ist auch Treiberprogrammierung so schwierig, weil es sehr oft auf Interrupts bearbeiten hinausläuft. Dazu nützliche Programmiertechniken sind Coroutinen und Semaphoren, auf die ich hier in einem Hardwarevortrag nicht mehr näher eingehen werde, ausser diesen Verweis auf sie zu machen.
Centronics war in den 1970ern ein grosser Hersteller von (relativ) billigen schnellen Druckern. Diese waren im vor-Mikroprozessor Zeitalter logischerweise alles "dumme" in Hardware implementierte Geräte. Daher war ein simpler paralleler Port mit unidirektionalem Handshaking das naheliegende. Centronics hat dann den Wechsel zu Mikroprozessoren und damit zu weit billiger implementierten Druckern (z.B. von Epson und Seikosha) komplett verschlafen, und ist daran untergegangen.
Centronics verwendete einen 36pin Stecker, den selbigen den man auch heute am Druckerende des Kabels findet. Dieser hat 18 Pinpaare mit je einem Leitungspaar dahinter, also sind die unteren 18 Pins alle 0V, und nur die oberen 18pins Signale. IBM meine dass der Druckeranschluss auf die selbige Karte wie die Monovideoausgabe gehört (das wurde bei Farbvideo dann aufgegeben), und hatte dann keinen Platz mehr für den grossen Centronics Stecker. Also haben sie den kleineren DB25(f) LPT Stecker genommen, mit nur 17 Signalen und 8 0V Anschlüssen, letztere genau neben den 8 Datensignalleitungen liegend. (Bereits mitte 1990er war dies in der PC Welt soweit standard, dass ein der Techgeschichte ignoranter Donglefirmen Werbeschrieber den original Centronics Stecker als "Japanstandard" bezeichnete, weil er nur noch dort in den NEC PCs im Gebrauch war.)
Verwendet wird genau obiges Verfahren, 8 Datenleitungen (für 8bit, trotzdem dass ASCII 7bit ist und damals keine 8bit Erweiterung im Drucker war) und 2 (Strobe und Acknowlege) Handshakeleitungen und 8 (bzw IBM noch 7) Zusatzleitungen. Letztere sind z.B. für Rückmeldungen wie "Drucker ausgeschaltet/offline" (SEL-OUT) oder "Drucker beschäftigt" (BUSY) oder "Papier zu Ende" (PE) oder "sonstiger Fehler" (ERROR), und für Kommandos wie "Drucker aktivieren" (SEL-IN), "Drucker reseten" (RESET), "Seitenvorschub" (FEED) signalisieren. Erstere werden nicht mit bidirektionalen Daten gemacht, und zweitere nicht mit Steuerkommandos in den Daten, weil eben dazumals "dumme" Hardware war wo dies zu teuer gewesen wäre, oder um extern mit ebenfalls einfacher Hardware Druckerumschalter/-auswähler zu bauen.
Das alles erscheint beim PC pro Druckeranschluss (max 3 davon) als einen 3er Satz von Ports (und damit 3 Adressen), für jeweils Daten (DATA) 8bit aus+ein und Steuerung (CTRL) 4bit aus(+ein) und Status (STATUS) 5bit nur-ein. Wobei anfangs Data nur-aus war, erst mit den PS/2 wurde das bidirektional schaltbar (als ganzer Block). Steuerung war immer beides, aber man muss dort aus=1 setzen zum einlesen können (wie bei einem 8048/8051, es hat keine Richtungsschaltbits). Eines der Bits in Steuerung ist das bei der PS/2 addierte Schaltbit für die Datenleitungen, das (im Gegensatz zu den anderen) aus Kompatibilitätsgründen nicht einlesbar ist.
Für das Handshaking den Strobe generieren wird rein in Software durchgeführt, aber für Acknowledge bearbeiten ist neben einem Tristate für Software auch ein Interrupt vorgesehen, aber oft wird der nicht benutzt.
Der LPT Port ist damit auch (mit Einschränkungen) als beliebiger Port für externe Sachen ansteuern missbrauchbar, und daher auch als Geekport bekannt. Siehe auch den AVR Programmieradaptor vom letzten Vortrag. Er wurde auch mit dem IEEE-1284 Standard offiziell erweitert, für Scanner oder Band-/Disklaufwerke oder gar Ethernet Interfaces anhängen. Leider fehlt dem LPT Port eine 5V Leitung, was sehr nützlich wäre zum kleinere externe Sachen mit Strom versorgen. Also braucht man immer ein externes Netzteil, oder muss den Strom beim Tastaturanschluss "abzweigen", oder wie beim AVR Adaptor Strom von der AVR Schaltung hernehmen. Rein zum Eingabeschalter nach 5V hinaufziehen kann man aber auch Widerstände von auf 5V geschalteten ansonsten unbenutzten Ausgabepins benutzen.
Alternative für mehrere Geräte anschliessen ist sie an einem einzelnen Port anzuschliessen, mit einem Kabel dass durch alle hindurchgeht. Dies funktioniert solange man nur mit einem Gerät aufs mal Daten austauschen will, weil das ganze eine Erweiterung des bidirektionalen Vorgehens ist. Das ganze nennt man einem Peripheriebus. Das sieht dann so aus:
======================================0-7=========== .. ============= ================================Bus====H============ .. ============= =======================================Z============ .. ============= ||||| ||||| ||||| ||||| ||||| .---------. .---------. .---------. .---------. .---------. | Gerät 0 | | Gerät 1 | | Gerät 2 | | Gerät 3 | | Gerät n | | Rechner | | Periphe | | Periphe | | Periphe | | Periphe | `---------' `---------' `---------' `---------' `---------'
Die Geräte müssen dabei dann wissen, ob sie oder jemand anderst momentan aktiv ist, damit sie nicht alle auf Daten vom Rechner reagieren, oder alle mit zugleich Daten zum Rechner senden sich gegenseitig stören oder den gerade sendenden Rechner (Kollision). Man braucht dafür logischerweise neben den Datenleitungen und Handshakeleitungen noch weitere Zusatzsignale (und deren Leitungen) zum eines der Geräte auswählen. Dazu werden Geräteadressen übertragen, welche durch geeignete Signale von Daten unterschieden werden müssen. Dazu müssen noch am Anfang per Bus Reset Signal alle Geräte inaktiv geschaltet werden, und dann jeweils einer im Betrieb ausgewählt werden, während sich der Rest nicht angesprochen fühlen und nicht reagieren oder gar sprechen darf.
Gerade solche Zusatzleitungen, aber auch manchmal die Handshakeleitungen, müssen in manchen Situationen von mehreren Geräten gleichzeitig benutzt werden. Das geschieht einerseits bei Geräteauswahlsituationen, oder Geräteabfragen, aber auch beim Acknowledge wenn mehrere empfangende Geräte gleichzeitig da sind. Dazu werden die betroffenen Leitungen in DTL-artiger Logik betrieben. Diese Leitungen haben wie bei DTL nur einen Widerstand nach 5V, und in den Geräten nur Transistoren nach 0V. Damit kann kein Kurzschluss und Schaden entstehen wenn einer 0V und jemand anderst 5V will (das 0V dominiert einfach). Das ergibt nebenbei eine NICHT-ODER Verknüpfung der einzelnen Geräten ihrer Signale, welche oft auch Wire-OR genannt wird. Diese Leitungen sind damit aber auch nur nach 0V ziehbar (= aktivierbar), und sind nur 5V wenn keiner zieht (= inaktiv). Daher müssen solche Leitungen auch als low aktiv betriebene Signale definiert werden. Auch das ist wiederum weit verbreitet in der Datenkommunikation über Busse.
Der Hewlett-Packard Interface Bus (HP-IB) wurde ursprünglich von der Firma erfunden zum mehrere Messgeräte (dazumals auch "dumme" Geräte, später mit Prozessor) an ihren 2116A Instrumentensteuerungsrechner anzuschliessen. Das war dazu gedacht, diese zu steuern (Messanschluss wählen, Messbereich einstellen, Messung auslösen) und auslesen (Messdaten bekommen), zwecks Laborautomation von lange dauernden Versuchen mit regelmässiger Datennaufnahme (z.B. eine Woche lang alle 5 Minuten die Spannungen von 3 Messfühlern messen und aufzeichnen, sowie alle 4 Stunden einen Einflussfaktor varieren). HP war ja ursprünglich eine Signalgenerator- und Messgerätefirma (diese Abteilung wurde später als Agilent ausgelagert). Das ganze wurde dann unter dem Namen General Purpose Interface Bus (GPIB) verallgemeinert und herstellerunabhängig und zum IEEE-488 Standard erhoben, und später auch als IEC625 leicht variert.
Der Stecker ist ähnlich aussehend wie oben bei Centronics, aber nur 2*12=24 Pins und einiges kleinerer Pinabstand. Es hat mehr als 12 Signale, und daher ist das Kabel zwar ein 12*2 Leitungspaar, aber 4 der Paare bestehen aus je 2 Datenleitungen(!), 1 Paar aus 2 Zusatzsignalen, 6 Paare aus Signal+Erdung und 1 Paar aus Schirmung und 0V bestehen. Der Stecker ist stapelbar (= jeder Stecker hat eine Buchse auf der Hinterseite), zum den Bus machen mit nur einer Buchse pro Gerät, was zur Folge hatte, das die Stecker und damit auch die Kabel sehr teuer waren (es wird auch behauptet weil nur ein Hersteller weil Patentmonopol). Die IEC625 Variante unterscheidet sich genau nur darin, einen billigeren DB25(f) Stecker zu benutzen, und 2 Buchsen an jedem Gerät zu haben.
Die Datenübertragung ist eine erweiterte Variante von obigem Parallel+Handshaking Verfahren, mit 8 Bits Datenleitungen und 3(!) Handshakeleitungen, sowie 5 weitere Zusatzleitungen. Alle Handshake und Zusatzleitungen sind hier als low aktiv definiert, also Ruhezustand 5V und 0V wenn aktiv.
Die 3 Handshakeleitungen sind ein normaler Strobe vom Sender (Data Valid genannt, DAV) sowie zwei Acknowledges von den mehreren möglichen Empfängern (Not Ready For Data, NRFD, und Not Data Accepted, NDAC). Letztere beiden sind in DTL Logik. Den NDAC kann damit jeder Empfänger nach 0V ziehen auf Not Data Accepted (was auch der Ruhezustand ist), und es geht damit erst auf 5V wenn alle Geräte die Daten angenommen haben (was dann einem Achnowlege setzen entspricht). Den "Rückweg" zu 0V (für das Acknowledge löschen) würde aber bereits anzeigen, sobald ein erstes Gerät dies macht, und damit zu früh. Daher muss dieser zweite Wechsel ignoriert werden. Statt dessen ist dafür die dritte Leitung zuständig. Der NRFD ist in Ruhezustand 5V und wird 0V sobald der erste es zieht (womit die Empfänger erst nach NDAC = 5V anfangen dürfen), und wird erst wieder 5V (und gültig) wenn alle wieder bereit sind (was sie erst nach ihrem eigenen NDAC wieder auf 0V setzen machen dürfen).
Eines der 5 Zusatzleitungen ist Remote ENable (REN), das die (Mess-)Geräte in den fernsteuerbaren Modus schaltet, sonst reagieren sie überhaupt nicht auf den Bus, sondern auf ihre eigenen lokalen Steuerelemente. Nach einem zweiten Leitung, Interface Clear (IFC), muss ein Reset aller Geräte ihrer Businterfaces (nicht Reset der Geräte selber) passieren, bei dem alle Geräte den Bus loslassen müssen. Ein drittes ist dann Attention (ATN), das besagt dass jetzt eine Adresse statt Daten über den Bus geht, mit der dann wieder einzelne Geräte aktiviert werden können. Diese Adresse besteht aus:
Ein direkt folgendes zweites Byte mit ebenfalls ATN und den beiden Bits 5+6 gesetzt erlaubt es, eine Sekundäradressen (SECOND) zu übertragen. Diese sind Unteradressen zum z.B. in einem Gerät drinen einen der Messkanäle auszuwählen, oder eine spezifische Funktion auslösen.
Für die Auslösung von REN und IFC und ATN ist ein einzelnes Gerät am Bus zuständig, der Controller genannt wird. Das wird üblicherweise der Rechner sein. Der muss aber an der Datenübertragung nicht notwendigerweise selber beteiligt sein, kann also auch 2 anderen Geräeten je ein LISTEN und ein TALK geben kann, z.B. Daten direkt von einem Messgerät oder Disklaufwerk zu einem Drucker schicken, oder von einem Disklaufwerk zu einem anderes Disklaufwerk kopieren, ohne dass diese durch den Rechner hindurchzugehen müssen. Das Ende der Übertragung erkennt der Controller daran, dass der Sender mit dem letzten Datenwort das End-or-Identify (EOI) Signal benutzt (in seiner End Funktion).
Andere Geräete müssen auf Aufträge vom Controller warten, können diesen aber mit der Service Request (SRQ) Leitung dazu auffordern, analog zu einem Interruptrequest. Diese Leitung ist daher ebenfalls wie bei DTL Logik nur auf 0V ziehbar, mit Widerstand nach 5V (das ist auch bei Interruptleitungen oft so). Zum ermitteln welches Gerät den SRQ ausgelöst hat, und was man folglich als Datentransfer(s) ausführen sollte, wird dann ein Pollingverfahren verwendet (ähnlich wie bei Interrupts). Dazu gibt es 2 Methoden:
Neben den offensichtlichen HP Systemen, von denen die Tischrechner keine traditionellen Disklaufwerke hatte, und so gut erweitert wurden, hat auch Commodore für ihre "grossen" 2000/3000/4000/8000er 8bit Rechner IEEE-488 benutzt. Als Folge davon haben sie auch die Geräteadressen zur Basis ihres ganzen 8bit Betriebssystems gemacht, was dann im Basic das ganze LOAD "Filename",8 Zeugs ergab. Zum auf den Geräten DIP-Schalter sparen wurden nur Konstante (oder eine geringe Auswahl) Adressen geboten, mit den Rechner-internen Schnittstellen als 0..3 (fest Tastatur 0, Band 1, RS232 2, Bildschirm 3) und externes als 4..30 (mit Drucker nur 4..5 und Plotter nur 6..7 und Disks nur 8..11). Alle Commodore IEEE-488 Geräte hatten ihren eigenen Mikroprozessor drin, womit der Bus zu einem parallelen CPU zu CPU(s) Netzwerk/LAN mit nur einen Client wurde. Die Disklaufwerke beinhalteten daher auch das komplete Filesystem, und waren damit eigentlich primitive Fileserver, die mit File open/write/read/close angesprochen wurden (und nicht etwa mit Block read/write). Zum zwischen einem OPEN "Filenamen" Kommando oder Filedaten schreiben oder einem CLOSE Kommando (das sind auf dem Bus je eine ATN LISTEN 8..11 + ATN SECOND + Busdaten + ATN LISTEN 31 Sequenz) unterscheiden wird die Sekundäradresse benutzt, auf eine ziemlich clevere Art. Diese besteht aus:
SASI/SCSI verwendet wie Centronics immer Leitungspaare, nur ein Signal pro Paar, wobei diese entweder wie bei Centronics Signal+0V sind (singelended SCSI, SE) oder ein (+Signal)+(-Signal) Komplementärpaar (differential signaling SCSI, DS) oder gar letzteres mit auf 3.3V reduzierter Spannung (low voltage differential signal SCSI, LVDS). Daher hat es hier auch mit 2*25=50pin (8bit) bzw 2*34=68pin (16bit) soviele Pins am Stecker. Es gibt aber auch für 4MByte/a 8bit ein für den Macintosh reduziertes externes SCSI mit 25pin DB25(f) Stecker, also wie bei LPT und IEC625 reduziert, sogar immer der gleiche Steckertyp (und damit auch verwechselbar).
SASI/SCSI war anfangs für 4MHz (und damit 4MByte/s) definiert (gegenüber GPIB etwa max 1MHz), und wurde dann auf schneller erweitert auf 10,20,40,80,160MHz (und damit 10,20,40,80,160MByte/s). Dazu kam dann noch neben dem 8bit Narrow-SCSI auch eine seltene 2-Kabel 50+68pin 8+24=32bit Variante, und später ab 20MHz auch die 1-Kabel 68pin 16bit Wide-SCSI (mit dann 40,80,160,320Mbyte/s).
Bei derart hohen Frequenzen werden die Signallaufzeiten im Kabel, und deren Echos zu einem störenden Effekt. Daher müssen an beiden Kabelenden "Signalverschlucker" sein, die kein Echo zurückgeben, sogenannte Terminatoren. Die meisten SCSI Versionen sehen dazu in jedem Gerät einen Terminator vor, der abschaltbar/entfernbar ist. Diese müssen auch in der bei SCSI vorgeschriebenen Variante neben 0V auch mit 5V Strom versorgt werden, weil sie nebenbei auch für die DTL Logik Leitungen auf 5V ziehen zuständig sind. Für die 5V ist eine Leitung (TERMPWR) vorhanden, welche mindestens von einem (aber maximal von vier!) Geräten auf dem Bus Strom versorgt werden muss, üblicherweise vom SCSI Interface. Das alles macht SCSI schwierig und damit fehleranfällig zum konfigurieren. (Am besten hat wohl DEC dieses Durcheinander gebändigt. Der Rechner hat einen festen Terminator eingebaut dann das SCSI Interface und dann nur 1 Anschluss, er liefert auch als einziger den Terminatorstrom (für beide Enden), und wird mit einem auf den Anschluss aufsteckbaren "Block" mit dem damit externen zweiten Terminator drin geliefert. Das ergibt zusammen einen "fixfertigen" Bus, nur ohne Geräte. Jedes Gerät (z.B. eine Diskbox) hat einen ersten Anschluss (zum Rechner), dann die Controller/Laufwerke, dann einen zweiter Anschluss (zu weiteren Geräten), und liefert niemals Terminatorstrom, und wird mit einem Kabel (zum Rechner) und ohne Terminatoren geliefert. Das Kabel "verdrängt" den Terminator vom Rechner (oder vorherigem Gerät) seinen Anschluss, und dieses "wandert" zum Zweitanschluss des neuen/letzten Gerätes. Leider hat so gut wie niemand diese sinnvolle Anordnung kopiert.)
SASI/SCSI ist praktisch nur ein vereinfachtes und beschleunigtes GPIB. Es ist immer 8bit (ausser Wide-SCSI 16bit). Der grösste Unterschied ist, dass es keinen Controller kennt, und damit auch keine LISTEN oder TALK von diesem. Statt dessen kann jedes Gerät (Initiator genannt) eine Datenübertragung direkt auslösen, indem es den Bus "in Beschlag nimmt" und dann die Adresse der gewünschten Gegenstation (Target genannt) ausgibt, mitsammt 2bit Angabe ob er Daten gar nicht oder nur senden oder nur empfangen oder beides will, und der genauen Aktion. Mangels Controller muss die ganze Entscheidung, wer den Bus nutzen darf, verteilt entschieden werden, was Arbitration genannt wird, und an dem sich alle jeweils gerade am Bus benutzen interessierten beteiligen. Dazu warten alle Interessenten bis der Bus (wieder) frei ist, geben dann ein SRQ artiges Signal ab, gefolgt von einem parallel Poll mit als Poll Bit dasjenige mit der Nummer der SCSI ID des gerätes, welche zugleich auch die Adresse zum angesprochen werden ist. Daher gibt es auch max 8 (bzw bei Wide-SCSI 16) Pollbits und SCSI-IDs und Adressen und Geräte am Bus. Gerät 7 (bzw bei Wide-SCSI 15) hat Vorrang, daher wird diese ID oft für den Rechner genommen. Die Adressen müssen ebenfalls am Gerät eingestellt werden. Sie werden üblicherweise mit 3 (bzw 4) DIP-Schalter oder Jumper eingestellt, bzw bei einer Diskbox zu jedem Diskslot von der Backplane angeliefert.
Neben den eigentlichen (Controller)-Adressen gibt es auch die Logical Unit Number (LUN) Unteradressen, mit denen bis zu 8 Disks an einem Controller ausgewählt werden können, oder bis zu 8 CDs in einem CD Laufwerk mit eingebautem CD Wechsler. Die entsprechen den IEEE-488 Sekundäradressen.
Weil SASI als Bus für Diskcontroller ansprechen erfunden wurde, werden Disks blockweise angesprochen, nur Block read/write Operationen. Die Controller (und Laufwerke mit Controller drin) haben kein Filesystem drauf. Also läuft das Filesystem auf dem Rechner, wie bei anderen (MFM oder ATA/IDE) Laufwerken. SCSI Disks erscheinen daher auch im PC als normale BIOS INT 13 0x80 und 0x81 Laufwerke, und sind normal bootbar. PC SCSI Interface BIOS Erweiterungen verlangen daher auch oft, dass Disks die SCSI IDs 0 und 1 haben müssen, falls diese als BIOS Disks zum booten erscheinen sollen. ID 2 wird traditionell für Bandlaufwerk reserviert, und ID 3 dann für erstes CD-ROM/DVD genommen.
Wie GPIB wurde SCSI auch neben für Disks (auch Floppy, CD-ROMs, Optodisks) für einiges anderes benutzt, auch Drucker und Plotter, ebenfalls Scanner, Multi-RS232 Interfaces, und selbst bei einem Apple Powerbook Modell als Anschluss für einen externen Monitor mit eingebauter Graphikkarte benutzt. (Der extremste Missbrauch den ich selber gemacht habe war ein 4MHz/8bit SCSI mit einem Mac IIci als Adresse 0, dessen interne HD als 1 (beides die Mac Standardanordnung), einer externen Syquest Wechselplatte (für Backups) als 3, und einen 486er PC (der auch auf die Syquest backupt) als 7, alle 4 gleichzeitig angeschlossen! Logisch nur Mac oder PC aufs Mal die Syquest nutzend.)
Nebenbei: Das USB Mass Storage (= Disk/Floppy/CD/DVD/Stick) Protokoll wurde scheints direkt vom SCSI Disk Protokoll adaptiert, wesshalb diese unter Linux auch als SCSI Disks (/dev/sd*) erscheinen. Die ATAPI Erweiterung zu ATA/IDE für CD-ROMs und DVDs ist auch eine SCSI Disk Variation, welche aber unter Linux als ATA/IDE (dev/hd*) erscheint.
Also wird hier sehr oft eine weitere schnellere Technik eingesetzt, bei dem des SCSI Interface (oder auch ein direkt angeschlossener Diskcontroller) die Daten direkt in die CPU ihren Speicher schreibt. Das wird Direct Memory Access (DMA) genannt. Dazu hat das Interface ein eigenes Adressregister, das der Prozessor nach der Geräteauswahl und vor der Aktivierung des Disklaufwerkes auf den Zielort im Speicher setzt. Danach läuft das ganze dann so ab:
Dafür braucht es aber leider einen grossen Hardwareaufwand im Prozessor und dem Interface, insbesondere auch wenn mehrere Geräte DMA benutzen wollen, und das auch noch quer durcheinander, was dann komplett in Hardware abgehandelte Prioritätsentscheidungen braucht, was DMA Arbitration genannt wird. Und DMA ist anfällig auf Bandbreite Kollisionen wenn mehrere Geräte es gleichzeitig benutzen wollen, was bis zu Problemen mit Datenverlusten ausarten kann. (Intel hat den Hardwareaufwand teilweise entschärft, indem sie den 8237 DMA Controller Chip anboten, der für bis zu 4 Geräte die Adressregister und Prioritäten und Busabwicklung mit dem Prozessor anbietet. Dafür musste man dann aber im PC neben den INTs auch noch die DMARQ/BUSRQs und DMAAK/BUSAKs auf den Karten jumpern, was diese Karten hochgradig unbeliebt machte, wesshalb dies fast nur für den Floppycontroller genutzt wurde. Erstaunlich fehlt die Blocklänge zählen und dann Interrupt auslösen im Angebot. Das Adaptec 1540/1542 SCSI Interface verwendete daher den traditionellen Ansatz, der aber erst ab PC/AT möglich war, und auch nur für eine Karte (und hatte dafür seinen eigenen Z80 Prozessor). Der Amiga hat seine ganze DMA (für Floppy aber auch für Video und Sound) im Agnus/Agnes Chip eingebaut, und limitiert auf die untersten 512k bzw 2M Adressraum, die als Chip-RAM bekannt waren. Schon davor hatten die meisten Homecomputer nur-Video DMA. IBM Grossrechner gehen noch viel weiter, indem sie DMA Services anbieten, die ein eigenes Program abarbeiten, das dann mehrere Datenblöcke mit vorgegebener Länge in beide Richtungen schicken (z.B. Diskblock bestelen und entgegennehmen), und dann erst interrupten. Diese Spezialprozessoren werden Input/Output Processor (IOP) genannt, oder zusammen mit dem Bus dahinter auch Channels. Dahinter sitzen auf den Channels Disk oder Terminal Controller mit eigenen Prozessoren. Das alles ist der Hauptunterschied von Grossrechnern zu anderen Rechnern)
Aber auch ohne den DMA Aufwand kann man schnell sein ohne zu pollen, indem das Interface für die Blockdaten einen eigenen RAM Buffer benutzt, und dann die Daten wiederum mit nur einem einzelnen Interrupt vor bzw nach dem Bustransfer mit voller Geschwindigkeit vom Prozessor zum bzw vom RAM Buffer (block-)kopiert werden. Und all das ohne jegliches DMA, ohne Arbitration, und ohne blockieren des Busses und ohne warten. Und da jedes Gerät seinen eigenen Buffer hat, fallen auch jegwelche Bandbreitenkollisionen und ihre Probleme weg. Da der Speichertransfer nur vor/nach (nicht während) dem Disktransfer passiert ist nicht für den Buffer DMA nötig, man kann sogar für beide Operationen das selbige Adressregister für das Buffer RAM (wieder-)benutzen. (Die PC Harddiskcontroller (zumindest vor PCI und ATA UDMA Modi) und manche besseren Ethernetcontroller verwendeten dies. Aber auch die ganzen PC Videokarten (zumindest bevor das on-Motherboard Video direkt aus dem Chipsatz erschien). Ebenso hatten der in den TI-99/4A und MSX Homecomputern verwendete TMS9918 Chip separaten RAM Speicher. Der TI-99/4A hatte allerdings dann seine Basic Programme und Variablen im 9918 Videospeicher abgelegt, und nur 256Bytes an Prozessor RAM, für den Basicinterpreter Status, was dann den Rechner doch wieder ausbremste.)
Daten müssen aber anderseits oft gar nicht derart schnell ans Ziel, und die Handshake Zeit abwarten dominiert oft ohnehin wie lange es braucht. Daher kann man einiges einsparen, wenn man die Daten bitweise über nur eine Datenleitung schickt. Nur eine Leitung für Daten, plus dazu eine weitere für den Bitclock als Handshake pro Bit. Letzterer entweder vom Sender geschickt (und braucht ein anderes Signal als Byte Handshake), oder vom Empfänger erzeugt und damit die Bits "abgeholt", und damit auch gleich (mit Bits gezählt) als Byte Handshake nutzbar. Auch wenn es schnell sein soll, ist heute ein sehr schneller Treiber inzwischen einfacher als die Leitungen von einander entkoppeln, siehe PCI-E oder SATA oder USB. Parallel wird daher nur bis wenige Meter benutzt (und auch das abnehmend), ab dann läuft es nur noch mit Seriell.
Als technisch einfachste Form werden hier zuerst einmal die synchrone Serialisierung betrachten, bei der neben der einen Datenleitung noch eine separate Bitclockleitung benötigt wird.
Parallele sequenzielle Logik, für n=4bit 4 Eingaben ------->--.----------------. .----------. Bit 3 | kombinatorisch |-->------| Flipflop |-->----------- .-->--`----------------' /""`----------' | 4 Ausgaben sofort | | | ------->--.----------------. | .----------. | Bit 2 | | kombinatorisch |-->------| Flipflop |-->--+-------- |-->--`----------------' |/""`----------' | | | | ------->--.----------------. | .----------. | Bit 0 | | kombinatorisch |-->------| Flipflop |-->--+-------- |-->--`----------------' |/""`----------' | | | | ------->--.----------------. | .----------. | Bit 1 | | kombinatorisch |-->------| Flipflop |-->--+-------- |-->--`----------------' |/""`----------' | | | | `-------------------------------------<-----------' | 1 Takt 4 Leitungen Clock Feedback
Bei serieller sequenzieller Logik gibt es zwar gleich viele Flipflops, damit die Bits alle gespeichert werden können, aber nur eine kombinatorische Logik zum sie erzeugen, die nur mit einem Bit (dem ersten) seinem Flipflop verbunden ist und auch nur ein Bit (das letzte) schickt Daten weiter an die einzelne nachfolgende Logik. Dazwischen werden die Bits jeweils direkt ohne Logik von einem Flipflop zum nächsten weitergereicht, die alle auch einen gemeinsamen Clock haben, der aber nun pro Bit einmal getacktet werden muss.
Serielle sequenzielle Logik, für n=4bit 1 Eingabe ------->--.----------------. .----------. Bit 3 | kombinatorisch |-->------| Flipflop |-->--. .-->--`----------------' /""`----------' | | | .------<-----------' | | | .----------. Bit 2 | | `-| Flipflop |-->--. | |/""`----------' | | | .------<-----------' | | | .----------. Bit 1 | | `-| Flipflop |-->--. | |/""`----------' | | | .------<-----------' | | | .----------. Bit 0 | | `-| Flipflop |-->---------- | |/""`----------' | 1 Ausgabe später | | | `-------------------------<-----------<-----------' | 4 Takte 1 Leitung Clock FeedbackEs ergibt sich damit, dass parallel n Logiken/Leitungen + n FF + 1 Clock braucht und seriell 1 Logik/Leitung + n FFs in Serie + n Clocks, also dass Logiken/Leitungen/Platz gegen Clocks/Zeit ausgetauscht werden.
Mit diesen Theoriehintergrund können wir nun ein paar verbreitete synchrone serielle Schnittstellen anschauen gehen.
Für die genauen Details wie die Signale aussehen, und was man damit anstellen kann, siehe die Keyboardbabel Vorträge an den letzten paar VCFe. Hier bringe ich nur Spezielles in diesem Kontext von Kommunikation und Schaltungen dazu, vor allem die Implementierung und die Historie (wie entstanden).
Wie in den Vorträgen gezeigt wurde, ist es einfach genug zum die Signale mit einem PIO und Software zu senden und empfangen. Das ist auch in den Tastaturen in allen Modellen und Klonen immer so gemacht worden. Das andere Ende beim PC variert dagegen, und das werde ich hier behandeln.
Die Ur-PC und PC/XT hatten die Tastaturen zwar einen 8048 drin, aber der Rechner lediglich eine 8bit SIPO Hardware (ein 74LS322) gefolgt von einem einzelnen Flipflop (halber 7474) drin (zum es auf 9bit verlängern). Deren Bits wurden alle beim Booten vom BIOS gelöscht (auf 0 gesetzt). Die Tastatur schickt nun eine 1 gefolgt von 8bit Daten, mit je einem Bitclock Impuls. Die 1 geht damit seriell durch den ganzen SIPO hindurch in das 9te Flopflop, und die 8 Bits dahinter landen inzwischen im SIPO drin. Wenn das Flopflop damit zu 1 wird löst das den Tastaturinterrupt aus. Das erste 1 Bit wird damit quasi der Byte Strobe der Tastatur zum PC. Das BIOS holt dann die Daten parallel aus dem SIPO und löscht danach alles wieder (was alles wieder für die nächste Taste empfangen bereit macht), inklusive dem Flipflop (was auch die Interruptanforderung beseitigt). Das ist quasi der Acknowlede des PCs an die Empfangsschaltung (aber nicht an die Tastatur, die nur auf den tippenden Benutzer achtet!). Diese primitive Hardware definierte das Format der Signale, der Rest seither baut darauf auf.
Für den PC/AT (und in der PS/2 beibehalten) wollte IBM dann eine bidirektionale Kommunikation zur Tastatur, zum die neu hinzugekommenen 3 LEDs ansteuern können. Einen weiteren Satz Leitungen zur Tastatur wollte IBM aber nicht spendieren (die LEDs werden ja selten geändert), also mussten die selbigen Leitungen bidirektional laufen. Das Signalformat wurde dabei aber nicht etwa durch etwas neues ersetzt, sondern lediglich ganz leicht umdefiniert. Die Tastatur legt nun neu anfangs eine 0 statt der 1 auf die Datenleitungen, und zieht erst nach einer Weile den Clock erstmalig. Nun wurde addiert, dass der PC anderseits die Clockleitung auf 0 ziehen darf zum die Richtung wechseln, aber nur solange noch keine 0 auf der Datenleitung ist (oder gar schon danach Daten unterwegs sind). Daher mussten beide Leitungen auch DTL-artig ausgelegt werden, mit 1 als Ruhezustand, und 0 als Startzeichen. Die Tastatur testet nach dem Daten auf 0 setzen, ob der Clock immer noch 1 ist (der Normalfall) und macht danach wie gewohnt weiter. Sieht sie aber den Clock bereits auf 0 gegangen kommen bald Daten vom PC, und sie lässt die Datenleitung los (wieder auf 1) macht kurz eine Sendepause bis die Daten empfangen sind, und danach wieder einen Sendeversuch. Zum dieses kompexere System PC-seitig implementieren, bekam auch das Leitungsende einen weiteren Mikrocontroller spendiert (einen 8042), womit jedes PC Motherboard seit den 286ern einen zweiten Prozessor drauf hat.
Das selbige gilt auch für die PS/2 Maus, deren zweites PS/2 Interface ab den gleichnamigen Rechnern dazukam. Nur dass dort, mangels LEDs, nur ein reduziertes PC/AT System benutzt wird, ohne bidirektional und DTL Logik, aber auch mit erstes Datenbit 0. Das ist auch Grund warum bei manchen Rechnern (z.B. die SGI Indy und O2, die auch PS/2 benutzen) eine Maus am Tastaturanschluss funktioniert, aber umgekehrt eine Tastatur am Mausanschluss nicht.
Dieser Bus hat ebenfalls nur eine Datenleitung, auch bidirektional (weil jedes Gerät darauf senden und empfangen muss), sowie die dazugehörige Clockleitung. Wieder beide DTL-artig, trotzdem dass nur einer aufs mal sie antreibt. Es hat interessanterweise keinerlei Handshakeleitungen sondern es wird blind gesendet ohne Bestätigungen, einfach genug langsam (und leider sehr langsam), dass die andere Seite sicher folgen kann. Dazu kommt genau noch der minimale IEEE-488 Zusatzleitungssatz IFC+ATN+SRQ sowie 0V, insgesammt also 6 Pins. IFC heisst aber neu RES und ist immer ein voller Geräte Reset. Die Datenrichtung wird wie gehabt vom mit ATN gesendeten Adressbyte gegeben. SRQ ist zwar eine Leitung vorhanden, wird aber vom Betriebssystem nicht mal ausgewertet. Von Disk direkt zu Drucker geht, aber danach soll angeblich der Bus abgestürzt sein und braucht einen RES. Die Ursache dafür ist mir unbekannt, und mangels Drucker hab ich das auch nie ausprobiert oder bestätigt, ich vermute aber den Mangel eines EOI als Grund.
Die Hardware des Serialbusses ist etwas ziemlich abenteuerlich, und auch der Grund warum der so berüchtigt langsam ist, und dazu noch beim neueren C64 einiges langsamer als beim VC-20. Dazu gibt es ein nettes Stück Geschichte zum erzählen: Eigentlich hätten die im VC-20 und 1540 (und später 1541) verbauten je 2 Stück 6522VIA Chips volle PIPO Schieberegister drin (diese und der Timer zum den Clock dafür generieren sind der Unterschied zum 6520). Dieser PIPO hat nur einen Datenpin, der aber entweder Ein oder Aus ist, per Tristate umschaltbar wie ein PIO Pin. Im Sendemodus ein Byte ins 6522 schreiben erzeugt 8 Bits (MSB zuerst) und ihre Clockimpulse, und dann einen Interrupt sofern nicht bereits inzwischen ein zweites Byte eingeschrieben wurde. Im Empfangsmodus werden 8 Bits (auch MSB zuerst) nach ihren Clockimpulsen aufgezeichnet, und dann ein Interrupt ausgelöst, und man muss auslesen bevor die nächsten 8 Bits alle drin sind. Dieses Schieberegister kann mit Shift-Clock = CPU-Clock/4 = 250kbit/s = 30kByte/s laufen, also ca Floppylaufwerk Bitrate, und selbst ein VC-20 Vollausbau (32k) Speicher wäre in etwa 1s voll, bzw ein C64 64k in 2s. Hätte Commodore das so benutzt, wäre das Teil genial gewesen, billig und schnell. Aber der 6522VIA sein Clock Anschluss ist im Empfangsmodus kaputt implementiert, er verliert ab und zu ein Clockimpuls (wenn dieser zeitlich zu nahe zu einem CPU Taktimpuls ankommt) und damit ab und zu ein Bit. Das kann man zwar extern flicken, aber der Flick kostet, erst recht wenn man beide Richtungen nutzen will, was einen aufwendigeren Flick braucht. Das war dem Billigheimer Commodore zuviel, also wurde der VC-20 Bus mit PIO Pins in Software gemacht, und somit einiges langsamer. Beim C64 ist der Bug eigentlich geflickt im 6526CIA Chip der den 6522VIA ersetzt. Die Leitungen dafür waren im Design sogar Vorgesehen. Aber für die richtige Software hatte Commodore auch keine Zeit (der C64 wurde sehr überhastet auf den Markt geworfen) und nahm schnell die VC-20 PIO+Software Routinen. In der Serieenproduktion wurden dann die "unbenutzten" PIPO Leiterbahnen im Rechner weggespart, und somit war das ganze auch nicht mehr durch schnell neue Software laden aktivierbar. Dies ist hier umso ärgerlicher, weil der C64 wegen des VIC-II seiner vielen DMA Speicherzugriffe jede achte Videozeile (die sogenannten Badlines) für 40us Pause machen muss, und deswegen die Bitrate Disk zu C64 noch gesenkt werden musste (das ist der einzige Unterschied vom 1540 zum 1541 Laufwerk), damit der C64 noch mit Empfangen nachkommt. Das ergab noch langsameres laden (unter 1kByte/s), was dann bei bis zu 64k sehr lange (über einer Minute) dauern kann. Die ganzen nur-Software "Turbo-Lader", die alle den Bildschirm abschalteten, waren nur optimierte wartefreie PIO+Software Serialbus Routinen, wieder auf den beim VC-20 möglichen Standard hinauf.
I2C basiert auf einem PIPO Schieberegister mit einem gemeinsamen Datenpin für beide Richtungen, sowie einem Clockpin, wie beim 6522/6526. Daher hat er auch nur ein Data+Clock Leitungspaar, und sonst gar nix, die beide wie bei allen Bussen bidirektional benutzt werden. Im Gegensatz zum VC-20/C64 Serialbus, der ein reduzierter GPIB artiger Bus ist, ist hier eher ein reduzierter SCSI artiger Bus vorhanden. Die Datenrate war anfangs 100kBit/s, später (und heute üblich) 400kBit/s, und neuer (und selten) auch ein paar schnellere Raten.
Jedes Adress und Datenbyte hat ein neuntes Bit, das der Empfänger (Slave genannt) als Bestätigung abgeben muss, und bei fehlendem adressierten Slave ausbleibt und somit dem Sender (Master genannt) als "kein Slave da" Fehlermeldung gilt. Der Slave kann auch den Clock im Aktivzustand "in die Länge" ziehen, also das Clock-Ende verzögern, zum die Übertragung ausbremsen damit er nachkommt, was als Bit-Acknowledge des Slaves, zusammen mit dem Clock-Anfang als Bit-Strobe vom Master, ein volles bitweises Handshaking erlaubt (so etwas hätte auch das C64 Badlines Problem entschärfen können). Es kostet aber auch Hardware, zum den Clock garantiert "fassen", auch wenn der Rest-Slave dann in PIO+Software ist. Damit haben wir aber dann auch Clock+Strobe+Acknowledge auf einer Leitung, neben schon allen Daten auf einer anderen Leitung, und so nur noch 2 Leitungen (und 0V) nötig, sehr elegant. Beide Leitungen werden daher wieder mal DTL-artig angetrieben, und brauchen daher je einen Widerstand nach 5V.
I2C Geräte haben relativ grosse Adressen von 7bit. Dieser grosse Adressraum wird daher oft als 4+3bit Klasse+ID aufgeteilt, zumindest bei hartverdrahteten Chips, wo die 4bit Klasse fest eingebaut ist, und nur die 3bit ID durch 3 Pins S0..S2 an jedem Slave dran eingestelt werden, statt dafür 7 Pins zu benötigen. Das ist also wie bei den Commodore IEEE-488 und Serialbus Geräten. Natürlich gibt es mehr als 16 Sorten von Geräten, daher haben manche Sorten duplikate Klassennummern. Es müssen einfach alle Geräete dieser Gruppe an Sorten die 3bit/8Geräte teilen, was als Summe aller dieser Geräte dieser Sorten max 8 erlaubt. Bei softwaredefinierten Chips, z.B. einem Mikrocontroller, können logischerweise die ganzen 7bit per Software (und damit per Flash) gegeben werden, und damit "Löcher" im Adressraum ausgenutzt werden. Adresse 0 ist "an alle", und alle Adressen Hex F0..FF sind reserviert (und wurden für die ebenfalls seltene 11bit Adresserweiterung benutzt).
Das achte Bit der Adresse ist ein 1bit read/write Modus. Damit kann derjenige der Master auch vorgeben ob er zum Slave Daten schicken oder von ihm welche empfangen will. Der Master ist dann auch für das Generieren des Clocks zuständig, egal welcher Richtung. Und muss daher auch wie bei SCSI selber ein Ende der Übertragung sein. Ein reiner nur-Slave Chip kann daher auch komplett ohne Taktversorgung auskommen, nur durch den I2C Bus angetrieben. Das ist z.B. bei den I2C benutzenden seriellen EEPROM und Flash Chips der 24C((x)x)xx Serie der Fall, in 8pin Gehäusen mit nur 5V+0V + Daten+Clock + S0..S2 + Schreibschutz Pins.
I2C hat auch keinen Controller, und damit auch keine ATN Leitung. Jeder kann Master werden. Dazu müssen wie bei SCSI die Interessenten auf einen (wieder) freien Bus warten, und dann unter einander aushandeln wer als nächster an der Reihe ist. Es hat aber auch keine SRQ artige Leitung. Vielmehr wird ausgenutzt, das normalerweise keine Datenleitungsänderungen während der Clock aktiv ist geschehen. Genau eine solche wird nun absichtlich erzeugt als START Signal (Daten 1->0) zum den Bus bekommen, und wieder als STOP (Daten 0->1) zum ihn freigeben, aber auch dazwischen als REPEATED START (auch Daten 1->0) zum ohne den Bus abgeben gleich mit einem anderen Gerät (oder dem selbigen in die andere Richtung) Daten auszutauschen. Nach einem START versuchen die Interessenten die anvisierte Slave Adresse abzugeben, bei der sie auch die Datenleitung wieder einlesen. Sobald ein Master eine 1 abgibt und gleichzeitig ein anderer Master eine 0, sehen beide die resultierende 0, und erkennt der mit der 1 dies als "verlieren" (= Null gewinnt), und muss sofort "aussteigen", ohne auch nur ein weiteres Bit zu senden. Ausser mehrere Master wollen gerade gleichzeitig auf das gleiche Gerät los, und in gleicher Datenrichtung mit diesem, ist damit schon während der Adressübermitlung die Entscheidung gelaufen, wer jetzt dran ist. Ansonsten geht das einfach mit den Datenbytes weiter, solange bis eine Abweichung auftritt (wieder Null gewinnt). Wenn 2 Master die genau selbige ganze Transaktion machen wollen, werden sie nie merken, dass der andere parallel mitlief und auch befriedigt wurde. Gerade alles das ist weitaus näher bei SCSI als bei IEEE-488 oder beim VC-20/C64 Serialbus.
SPI basiert ebenfalls auf einem PIPO Schieberegister wie bei 6522/6526 und I2C, aber hat für beide Richtungen je ein separaten Pin, und ist daher auch ein Interface und kein Bus. Daten gehen von Master Out zu Slave In Pins (beide MOSI genannt) und von Slave Out zu Master In (beide MISO genannt, nicht SOMI). Zusammen mit dem gemeinsamen Clock (SCK) sind es daher 3 Pins und Leitungen statt 2 auf einem Bus oder 2*2=4 für 2 komplett separate serielle Systeme. Der Datentransfer ist damit auch gleichzeitig in beide Richtungen, also eigentlich ein 2*8bit Datenaustausch mit 8 Clock Pulsen, bzw ein 2*8bit Ring um 8bit herumdrehen. Es gibt damit auch keinen Sender und Empfänger (beide sind immer beides), und keine Richtungsbits, nur die Clockrichtung definiert wieder einen Master und Slave.
Es können mehrere Slave Geräte an einem Master hängen, aber SPI kennt keinerlei Adressen. Vielmehr läuft ausserhalb der Datenleitungen eine private Slave Select Leitung (/SS) zu jedem Slave, genauso wie die privaten Chip Select Leitungen (/CS) zu Speicherchips. Der Slave der sein /SS aktiv hat reagiert auf Clockimpulse und darf auch die MISO Leitung antreiben, während der Rest nichts macht und MISO per Tristate abschalten muss, zum nicht den aktiven Slave stören, wieder genauso wie bei Speicherchips. Zum die /SS antreiben hat es beim Master eine Adressausgabe gefolgt von einem normalen Adressdecoder, oder eine direkte Ausgabe der decodierten einzelnen /SS Signale (letzteres zumeist der Fall bei einem Mikrocontroller, normale PIO Pins dafür nutzend). /SS anwählen resetet und aktiviert beim Slave das Interface, daher kann man auch /SS kurz deaktivieren und wieder aktivieren als Signal für eine neue Transaktion anfangen benutzten.
Das alles ergibt einfachste Hardware, aber erlaubt nur einem einzelnen Gerät Master zu sein, weil nur er die ganzen /SS Leitungen treiben kann. Damit kann aber auch der Datentransfer nur vom Master aus getrieben werden, weil Slaves keine Master werden können, und der Programmierer muss damit auch Daten abholen gehen, und auch wissen wann. Einen SRQ gibt es aber auch keinen zum den Master anstossen, und ebenso keine Verfahren zum Slaves unterscheiden. Aber man kann dies auch ausserhalb der Datenleitungen mit separaten normalen IRQ Leitungen und Tests auf welche es war lösen (auch diese gehen nur zu einem Master).
SPI ist so simpel, dass es von einigen 8bit Mikrocontrollern benutzt wird, zum sie programmieren (also ihr internes Flash mit Software füllen), z.B. bei den AVRs. Sie agieren dabei als SPI Slaves, mit ihrem Resetsignal als (Programmier-)Slave Select, neben der normalen Resetfunktion, den unprogrammierten Chip zu stoppen. Der gezeigte AVR 10pin Programmierstecker vom letzten Vortrag ist nichts anderes als 5V+0V + SPI + Reset + Debug Erweiterungen.
Zumeist können solche Mikrocontroller dann auch gleich die vorhandene SPI Schaltung im laufenden Betrieb für Daten nutzen, als Master oder Slave. Für ersteres benutzen sie nur die 3 Daten/Clock Leitungen (und mehrere PIO Pins zum die /SS generieren), für zweiteres wird auch ein weiteres in Hardware abgefragtes (Daten-)Slave Select benutzt. Daher kann auch ein Mikrocontroller weitere Hilfsmikrocontroller sowohl programmieren wie auch mit Daten benutzen, je nachdem welches /RESET oder /SS er ansteuert, mit 2 separaten PIO Pins (oder Adressen falls Adressdecoder).
SPI ist auch genug einfach zum sie auch ohne PIPO Schieberegister Hardware zu benutzen, mit nur normalen PIO Pins und Software, zumindest als Master. Es ist lediglich langsamer auf diese Weise. Z.B. wird dies vom PC LPT Port aus gemacht, so auch der Parport AVR Programmadaptor.
Der wichtigste Unterschied war die potentiell vielen Master /SS Pins einsparen. Sonst wäre pro Chip ein /SS nötig, was beim Master (= dem Testsystem), und damit auch an den Steckeranschlüssen und am Kabel von diesem zu den Testobjekten, eine eventuell sehr grosse und vor allem undefinierte Anzahl Anschlüsse ergibt, was im Widerspruch zu Steckern und ihren festen und limitierten Pinzahlen steht. Weil /SS fehlt, und muss es daher durch ein Adressiersystem ersetzt werden. Externe Adressdecoder, z.B. per ein Schiftregister mit allfälligem Adressdecoder zu /SS dahinter, hätten mehr Chips und Kosten addiert, also musste die Adressdecodierung in den ohnehin schon vorhandenen Chips hinein.
Dazu werden die TAPs als erweiterten Multichip Ring verdrahtet. Die Daten gehen von Master seinem Test Data Out (TDO) zum ersten Chip seinem Test Data In (TDI), weiter von ersten Chip TDO zum zweiten Chip TDI, usw, bis zum letzten Chip dessen TDO erst zum Master seinem TDI zurückgeht. Auch jeder Chip hat wiederum intern einen (oder mehrere parallele) Serien von Bits in diesem Ring (z.B. eben die Pinzustände), zumeist mehr als nur 8bit. Der Clock ist wie gehabt, vom Master zu allen Slaves, als Test Clock (TCK).
Zum das ganze steuern ist nun ein einzelner weiterer Test Mode Select (TMS) Pin vorhanden, über den (auch mit TCK) kurze Kommandos an alle Chips gehen, eines davon ein Reset. Bei Reset treibt der Master seinen TDO umgekehrt zu allen Chips ihren TDOs. Damit kann der erste Chip im Ring seine Position an seinem TDI Zustand erkennen und aktiv werden. Diesem kann nun auch ein Kommando geschickt werden, sein TDO umzuschalten (und inaktiv zu gehen), woraufhin der nächste (Teil-)Reset den nächsten Chip adressiert und aktiviert, usw, bis der Master vom letzten Chip ein umgeschaltetes TDO sieht.
JTAG kann aber neben auf Pins auch auf beliebiges anderes in einem Chip zugreifen, seien das Register oder Speicher oder gar interne Leitungen. Es wird daher auch benutzt zum chipinterne Logik auf Herstellungsfehler testen, aber auch zum im laufenden Systemen remote Debuggen von Software (als In Circuit Emulator bekannt, ICE), aber auch zum Flash mit der fertigen Software programieren. JTAG ist aber auch danach nützlich, zum Schaltungen und ihre Software zwecks Reverse Engineering analysieren, oder zum neu Flashen nachdem man die Firmware bei einem Upgrade kaputtgeschossen hat (das ist als "bricking" bekannt, weil das Gerät danach so dumm wie ein Backstein ist, und die Rettung des Gerätes ist als "de-bricking" bekannt). Bei ARM und MIPS Mikrocontrollern und SoCs (z.B. in Mobiltelephonen oder WLAN APs benutzt) ist JTAG der offizielle Standard zum sie programmieren, mitsammt vorgeschriebener Steckerform und Pinbelegung. Diese ist oft dann gegenüber normalem JTAG noch erweitert, bei ARM als ETM und MIPS als EJTAG. Aber auch bei Mikroprozessoren kann man via JTAG die Adress- und Datenpins antreiben zum externe Flash Chips programmieren.
Den JTAG Master gibt es ebenfalls in PC LPT Port und Software Ausgabe, als der Wiggler JTAG Adaptor, der aber wegen den oft vielen zu übertragenden Bits dementsprechend langsam ist.
Also muss man ohne separate Clockleitung auskommen. Aber damit haben wir dann wieder ein Bitclock Handshake Problem, und diesmal keine eigene Leitung mehr dafür. Dazu müssen die Bitgrenzen aus dem Datensignal extrahiert werden. Dazu müssen die Daten dann speziell formatiert werden, zum darin die Bits erkennen, auch wenn 2 Nullen oder 2 Einer hintereinander kommen. Und für den Anfang davon müssen wir nun erstaunlich weit in die Vergangenheit zurück, mehr als ein halbes Jahrhundert, zum Fernschreiber!
Aber der Fernschreiber offerierte frühen Computeristen einiges: Drucken als Ausgabe (sowie eine Ping Glocke wenn fertig) und Tastatur als Eingabe, sowie zusammen mit Lochstreifen Ausstanzen als Abspeicherung und Einlesen als Ladevorgang, und all das als ein einzelnes, relativ billiges und fixfertig vorhandenes Gerät, wenn auch alles langsam, und laut, und nicht gerade benutzerfreundlich (wer je auf einer ASR33 getippt hat weiss wo seine Fingerspitzen sind).
Nebenbei: Der Meteologe Eduard Lorenz hat zum derartige Tipperei am Fernschreiber seiner LGP-30 sparen seine 6-stellig ausgegebenen Daten zum weiterrechnen nur 3-stellig eingetippt und stellte danach zeitlich zunehmende Abweichungen von der 6-stellig genau fortgesetzten ersten Rechnung fest, und entdeckte dadurch den mathematischen Effekt des deterministischen Chaos in nichtlinearen Systemen.
Daher wurden Fernschreiber relativ früh an CPUs angehängt und benutzt, und viele einfache Rechner (z.B. obige LGP-30) bestanden aus nur CPU und Speicher und Fernschreiberanschluss, und sonst gar nix. Damit wurde ein Fernschreiberanschluss zur Standardschnittstelle und damit weitherum implementiert. Später war sie dann, als die überall vorhandene Schnittstelle, ideal geeignet zum Datenaustausch zwischen verschiedenen Rechnern, und wurde damit zur ersten CPU zu CPU Kommunikation überhaupt. Damit wird sie auch interessant für diesen Vortrag, zumal auch das heutige RS232 sowie die Modems direkt von ihr abstammen.
Die ursprüngliche Hardwareanordnung war Fernschreiber -Distanz- Zentrale(n) -Distanz- Fernschreiber. Die Daten müssen also 2 mal über Distanz, oft mehrere oder gar einige km. Es gab damals keine Elektronik, nicht mal analoge, und daher waren 2 separate Richtungsleitungen erst noch unvermeidbar. Die Kabel wurden dadurch teuer (und die Kanäle zum sie darin verbuddeln auch), daher wurde eine minimale Leitungszahl nötig. Clockleitungen lagen da nicht mehr drin.
Zum die Bits die Zeichen beschreiben seriell über eine Leitung zu schicken, mit nur Elektromechanik, wurden sie zuerst mechanisch erfasst, durch Taste drücken und dabei einen Hebel an der diese befestigt ist bewegen. Dieser Hebel hat den Zeichencode (eine Binärzahl) in Form von Kerben eingeschnitten, welche dafür sorgen, dass eine Gruppe paralleler Bitleitungen entweder Strom bekommen oder nicht. Nebenbei wird eine "bekommt immer Strom" Leitung geführt, die als Strobe agiert. Acknowledge macht bei einer Tastatur ohnehin keinen Sinn, und fehlt. Damit haben wir eine klassiche Parallelschnittstelle. Diese hat 5 (Baudot) oder 6 (Flexowriter) oder 7 (Teletype, ASCII) Bits pro Zeichen.
Dieser Zeichencode muss nun zum über die Leitung gehen serialisiert werden, was also ein PISO braucht, und das ohne Elektronik. Dazu warten ein Elektromotor und ein von diesem kreisförmig bewegter Schleifer. Sobald eine Taste betätigt wird, und damit der Strobe aktiv wird, fäehrt der Motor los, für genau eine Schleiferumdrehung bei der der Kontakt am Schleifer alle Bitleitungen nacheinander mit der Leitung zur Gegenstelle verbindet. Die Bits sind damit elektromechanisch serialisiert worden.
Das Signal auf der Leitung ist ein Strom für Ruhe (und dabei auch der Zentrale anzeigen dass das Gerät läuft) sowie für die 1 Bits, bzw kein Strom für die 0 Bits. Dieser ist 20mA bei neueren Geräten wie die ASR33 bzw 60mA bei älteren Geräten. Der Ruhe/1 Zustand wird Mark genannt, und der 0 Zustand Space, nach der Linie bzw nicht-Linie beim Morsegerät, wo Strom einen Stift auf das laufende Papierband zieht.
An der Gegenstelle wartet ein Drucker, der bitgesteuert ein Zeichen auswählen kann (durch einen Druckkopf rotieren und auf/ab bewegen) und dieses dann aufs Papier schlagen kann (durch den Druckkopf nach vorne bewegen), sobald er die Bits und einen Strobe zu sehen bekommt.
Dazu müssen die Bits aber wieder zuerst parallelisiert werden, also braucht es ein SIPO, wieder ohne Elektronik. Dazu hat es pro Bit ein Relais, anfangs alle gelöscht/0, und danach jedes nur dann gesetzt/1, wenn zu seinem Zeitpunkt (bzw Zeitfenster) eine 1 (und damit Strom) über die Leitung kommt. Zum dies steuern/verteilen ist wieder ein Elektromotor mit einem Schleifer da, der zu den jeweiligen Zeitpunkten die Leitung mit dem relevanten Relais verbindet, und nach dem letzten dann den Druckkopf mit einem Strobe auslöst. Die Bits sind damit wieder elektromechanisch parallelisiert worden.
Beide Elektromotoren, beim Sender und Empfänger haben die gleiche Drehzahl, normalerweise um 10 Umdrehungen pro Sekunde, was daher auch max 10 Zeichen pro Sekunde ergibt, wenn keine Pausen da sind. Das Problem ist dann nur, dafür zu sorgen, dass sie beide gleichzeitig loslaufen, wonach die restlichen Zeiten zum die Bits zur Leitung bzw die Leitung zu den Relais schalten dann nur noch Winkelanordnungen der Kontakte der beiden Schleifern sind.
Dies, wird auf folgende Art erreicht: Der Sender Schleifer steht auf einem "vollen" (= 20mA = 1 = Mark) Winkel. Nach dem Strobe von der Tastatur läuft er los, zuerst über einen "toten" Winkel der immer 0mA = 0 = Space ist und das Startbit genannt wird, und erst danach die Winkel der Datenbits, gefolgt von wieder dem selbigen vollen Winkel der immer 20mA = 1 = Mark ist und das Stopbit genannt wird, wo dann auch der Motor gestoppt wird. Der Leitungsübergang von 20mA = 1 zu 0mA = 0 startet nun dem Empfänger seinen Motor, der dann auch nach dem Ende des Startbits weiterläuft, und dabei die Datenbits zu ihren Relais gibt, und dann erst seinen Winkel zum stoppen erreicht, nachdem der Sender auch am Stopbit ist (und mit dem auch den Empfänger Stop zulässt), und dort dann wieder auf ein neues Startbit wartet. Damit werden also quasi zuerst der Strobe und dann die Daten und dann ein anti-Strobe über die einzelne Leitung geschickt, aber keine Bitclocks (weil keine zweite Leitung für diese da ist), und der Empfänger generiert seine eigenen lokalen synchronen Bitclocks, mit vom Strobe Übergang ausgehender (Dreh-)Zeit.
Der Rest ist dann nur noch eine Frage der Bitclock Synchronität, und damit der Drehzahlgenauigkeit der beiden Elektromotoren. Und da der Strobe für jedes Zeichen wieder neu gesendet wird (und damit wieder neu synchronisiert wird), wozu auch das Stopbit oft 1.5 oder 2bit lang ist (zum dem Empfänger genug Zeit zu lassen), dürfen die Drehzahlen bei 1Start + (5..7)Daten + (1..1.5..2)Stop = 7..11bit um zusammen 1/7..1/11 = 14.3%..9.1% auseinander liegen. Bei 10 Zeichen/s, und damit genau 1/5 von 50Hz bzw 1/6 von 60Hz, und damit mit Netzfrequenz und einer 1:5 bzw 1:6 Motorwicklung kann dies locker garantiert werden.
Mit den üblichen 10 Zeichen pro Sekunde, und 5..8 Bit pro Zeichen, und 1 Startbit und 1..1.5..2 Stopbits, ergeben sich dann die typischen 10*(1+5+1.5)=75 (Baudot) bis 10*(1+8+2)=110 (Teletype) bit/s.
Daher wird oft externe Hardware zur Hilfe genommen. Minimal ist nur ein Interrupt wenn die Eingabe auf 0 wechselt, da Interrupts ja genau für zeitlich unerwartete externen Sachen überwachen und auf sie reagieren da sind. Dieser wird dann gefolgt von entweder mit schon laufendem senden mit empfangen zu kombinieren (zumeist bis fertig empfangen, erst dann nächstes senden anfangen), oder vom laufenden rechnen umschalten auf nur empfangen (und erst wenn fertig empfangen weiterrechnen). Etwas einfacher zu programmieren ist dazu noch ein Timer verwenden, der extern an die Sende und Empfangssroutinen die Zeit vorgibt. Noch besser ist wenn wiederum dieser Timer Interrupts erzeugt für jedes Bit das raus oder rein muss. (Der C64 z.B verwendet dies, mit beiden Interruptsorten (erstes 0 Bit und Timer) an dem 6502 seinen NMI Interrupt, was bis max 2400bit/s bidirektional geht. Ohne dem C64 seine VIC-II Badlines ihre 40us Pausen haben andere Rechner das auch in Software bis auf 9600bit/s hinauf geschafft.)
Man kann aber auch die ganze Geschichte in Hardware lösen. Dazu werden logischerweise PISO (senden) und SIPO (empfangen) Schieberegister benutzt. Die Startbits können mit einem weiteren PISO Bit im Sender erzeugt werden, das fest mit 0 geladen wird, die Stopbits und Ruhe mit dem SI Anschluss fest mit 1 füttern. Für die Bitclocks kann man auch die elektronisch geteilte Netzfrequenz nehmen, oder üblicherweise die elektronisch per Timer (weit mehr) geteilte CPU Frequenz. Problem ist nur noch das Motor loslaufen und stoppen nachzubilden. Dazu hat man dann stoppbare Frequenzteiler. Den Sender Bitclock starten macht wieder ein Tastaturstrobe, und stoppen ein Bitzähler. Den Empfänger starten wieder der 1 zu 0 Übergang, und stoppen sein eigener Bitzähler. Erst nach vollstängigem Empfang wird ein Interrupt ausgelöst, ebenso nach vollständigem Senden. (Bei einem Timesharing Rechner (z.B. einem Minicomputer) musste dies ohnehin alles in Hardware passieren, zum die CPU für anderen laufenden Programme freizuhalten (er ist immer im rechnen Zustand wenn etwas ankommt). Die ganzen DEC Minicomputer hatten daher Multiport Hardware Serialschnittstellen als eines ihrer Standardperipheriekarten (damit der Prozessor nicht pro Bitclock einen Interupt bearbeiten muss und dabei ersäuft). DEC ihre PDP-10 Grossrechner missbrauchten sogar eine Gruppe von PDP-8 oder PDP-11 Minicomputer dafür, welche zugleich auch die Zeileneditoren waren (damit der Hauptprozessor nicht pro User*Taste einen Interupt bearbeiten muss und dabei ersäuft, sondern nur pro User*Zeile), und auch fakultativ mehrere entfernte Schnittstellen auf eine Leitung zum Hauptrechner bündelten.)
Nach dem Empfangs-SIPO wird dann oft ein zweites Register (Buffer genannt) addiert, zum die letzten angekommenen Daten speichern bis sie abgeholt werden, während bereits weitere Daten ankommen. Damit wird der CPU mehr Reaktionszeit gegeben, ohne Gefahr dass die Daten durch folgende überschrieben werden. Bei grossen Datenmengen wird anstelle eines einzelnen Buffers eine ganze Serie davon eingesetzt, was einen First In First Out (FIFO, oder in DEC Benamsung ein Silo) Buffer ergibt. Einerseits lässt das langsam reagierende CPUs zu (z.B. 286..486 PC mit Windows), anderseits lässt es auch eine reduzierte Menge an Interrupts zu, wenn erst nach halber (minimaler) Bufferfüllzeit ein Interrupt kommt, und die CPU dann auf ein mal Buffer/2 Daten abholen kann. Wenn nur ab und zu einzelne Daten kommen ist das lediglich eine kleine Verzögerung und dann doch ein Interrupt pro Daten, was aber bei der Seltenheit dann nicht mehr stört.
Dieses ganze kann man auch in einem einzelnen Spezialchip bekommen, welches Universal Asynchronous Reciever and Transmitter (UART) genannt wird. Die beiden seriellen Pins werden dabei stets TxD (Transmit/Senden Daten) und RxD (Recieve/Empfang Daten) genannt. (Zu den 8080 und 8085 gibt es den 8250 (der auch in den PC COM Ports landete) und den 8251 (Kleinausgabe ohne Timer drin). Der 16450 ist ein beschleunigter 8250, der 16550 ist ein 16450 mit 16 Bytes FIFO. Zum Z80 gibt es die Z80SIO und Z80DART und Z80SCC (von letzteren dann 2 Stück in den Ur-Macs für Tastatur und Maus bzw Drucker und Modem zuständig waren, ersterer später ab Mac Plus für ADB und zweiterer für LocalTalk und Geoport benutzt). Zum 6800 und 6809 gibt es den 6851, und zum 6502 den 6551. Heute hat selbst jeder bessere Mikrocontroller einen (oder gar mehrere) solche drin, zumeist mit Buffer aber ohne FIFO, z.B. ab dem 8051 (aber nicht im 8048), und in den AVR ATmega (aber nicht den ATtiny). Beim AVR sind die TxD und RxD Signale sogar für Debugausgaben (und -eingaben) auf dem erweiterten Programmierstecker drauf. Beim 8051 werden oft die TxD und RxD zum das Flash programmierne benutzt.)
Mit dem 8052 (erweiterter 8051) addierte Intel einen Busmodus zum UART hinzu, den Multi Processor Communication Mode (MPCM), der damit der dritte Konkurrent zu I2C und SPI ist. Dabei werden Daten mit normalem 0-Datenbits-1 übertragen, Adressen aber als 0-Adressbits-0-1. Letzteres Fehlen der erwarteten 1 nennt an einen Framebreak. Beim Master/Sender wird für eine Adresse senden kurzzeitig der 9-Datenbit Modus aktiviert (die UART Chips können normalerweise einstellbar 5..9bit) und dann mit Bit9=0 gesetzt. Beim Slave/Empfänger wird auf 8bit gelassen, aber der normale "Daten angekommen" Interrupt ausgeschaltet, und nur der "ein Framebreak ist passiert" Interrupt eingeschaltet gelassen. Der Empfänger vergleicht in letzterem Fall das angekommene Byte mit seiner Adresse (die per seiner Software gegeben wird) und schaltet falls adressiert den "Daten angekommen" Interrupt ein, solange bis wieder eine andere Adresse mitsammt Framebreak ankommt und ihn deselektioniert. Ebenfalls wird nur in dem selektionierten Slave der TxD per Tristate eingeschaltet, und in allen anderen ausgeschaltet, zum den selektionierten Slave nicht zu stören (wie auch beim MISO des SPI). Ebenfalls wie bei SPI ist auch nur ein Master möglich, weil dessen TxD zu allen Slaves ihren RxD geht (wie die SPI MOSI), und alle deren TxD zum Master seinem RxD (wie die SPI MISO). Lediglich die Datentransfers sind unabhängig und beide ohne Clock, also kann der aktive Slave (aber nur der) von sich aus etwas schicken und der Master auf den Dateninterrupt warten. Und es wird adressiert, statt viele /SS benutzt, was näher bei JTAG TAP ist. Aber all das wie bei I2C mit nur 2 Leitungen.
Neben den neuen Audio Signalen auf der Telephonleitung wurde aber auch die Separierung von Fernschreiber/Terminal/etc und Modem eingeführt. Daher musste neben den Leitungssignalen/-tönen auch ein zweiter Satz digitaler Signale zwischen den beiden definiert werden, die RS232 Schnittstelle.
Das älteste Modulationsverfahren ist, für 0 und 1 zwei verschiedene Frequenzen zu senden, und beim Empfänger das lautere der beiden als Bitzustand anzuschauen. So etwas nennt man generell differenzielle Signalcodierung, und bei 2 Frequenzen spezifischer Frequency Shift Keying (FSK). Wegen den 2 Richtungen mal 2 Frequenzen ist die unterste der 4 relativ niedrig. Dazu müssen die Frequenzen noch so gewählt werden, dass die Oberwellen der unteren die obigen nicht stören. Und wegen des geringen Abstand eines Frequenzpaares, und der Filterlimiten kann man auch noch mit der Bitfrequenz nicht bis an diese Wellenfrequenzen heran, wesshalb je nach Zuverlässigkeitsanforderungen bei etwa 300..600bit/s Schluss gibt. In den 1970ern bezeichneten manche "Experten" (zumeist nur Nachplapperer ohne wirkliches Sachverständnis) dies als "nahe am theoretischen Maximum" einer Telephonleitung (statt als nahe am Maximum des FSK Verfahrens). (Bell 103 Modems (USA) verschickten 0/1 als 1070/1270Hz (Anrufender, Originator) bzw 2025/2225Hz (Angerufener, Answerer). CCITT V.21 Modems (International/Europa) verschickten 0/1 als 980/1180 (Anrufer) bzw 1650/1850 (Angerufener).)
Obiges sind zwar mehr als die Fernschreiber 110bit/s, aber weit unter normalen Terminals mit 1970er 2400bit/s oder gar 1980er 9600bit/s. Ein Weg das etwas zu beschleunigen ist asymetrische Geschwindigkeit. Strikte hat eine Richtung ja fast die doppelte Wellenfrequenz, die man auch ausnutzen kann, für 600..1200bit/s. Das kann man für die zumeist viel grössere Ausgabedatenmenge (von Rechner zu Terminal) nutzen, zumal netterweise die Angerufenen/Answerer höhere Frequenzen haben. Das kann man aber auch optimieren, indem man zwei hohe Frequenzen mit viel Abstand nutzt, und damit die Filter wirksamer werden, und für die viel langsamere getippte Eingabedatenmenge (von Terminal zu Rechner) zwei von obigen weiter entfernte sehr niedrige Frequenzen nimmt. Das erlaubte zuverlässig 1200bit/s Ausgabe (immerhin mal 2..4) und je nach Anforderungen immer noch 75..110..150..300bit/s Eingabe. (CCITT V.23 Modems verschickten 0/1 als 390/450Hz (Anrufender) zum viel Platz geben für die 1300/2100Hz (Angerufener).)
Noch extremer ist nur eine Richtung aufs mal senden, schnell und ungestört, und die Modems schalten hin und her. Das erlaubt beiden Richtungen die maximale Geschwindikeit, was bei Terminals mit lokalen Speichermedien nützlich ist. Es erlaubt aber nur einen aufs mal, was aber auch bei Rechner/Program Eingabe-Verarbeitung-Ausgabe Verhalten erstaunlich gut funktioniert, und bei Medien lesen oder schreiben sowieso. So etwas nennt Halbduplex Betrieb, oder auch weniger formell Ping-Pong, im Gegensatz zum normalen dauernd bidirektionalen Betrieb (das man Vollduplex nennt), oder einem immer nur in einer Richtung laufenden Betrieb (das man Simplex nennt). (Bell 202 Modems sind Halbduplex und verschicken 0/1 als 2200/1200Hz.)
Weiter hinauf als das versagen dann simple analoge Frequenzschalter, und man muss zu digital generierten Wellenformen als Modulation greifen, welche dann auch synchron zu den Bits generierbar sind, und damit auch unkritischer sind, und näher an die Wellenfrequenz gehen erlauben. Aber auch diese können aber nur eine niedrige Wellenfrequenz haben, und damit nur maximal mit einen Teil dieser Frequenz geschaltet werden. Sie erlauben es aber auch, die Frequenz auf mehr als 2 Arten "verbiegen", zum mehrere Bits pro Umschaltung zu übertragen. Dabei gibt es dann auch folglich neu 2 Geschwindigkeitsmasse, bit/s für die übertragenen Bits, und baud für die Anzahl Umschaltungen. Für 4 Zustände (und damit 2 bit/baud) verwendet man Phasensprünge (Signalverzögerungen) von 0/90/180/270grad, wesshalb man das auch Phase Shift Keying (PSK) nennt. Für 16 Zustände (und damit 4 bit/baud) muss kann zusätzlich zur Phase auch noch die Amplitude (Lautstärke) varieren, wesshalb man das dann Quadratur Amplituden Modulation (QAM) nennt. (CCITT V.22 (= Bell 212) Modems verwenden Frequenzen von 1200Hz (Anrufender) und 2400Hz (Angerufener), reduzieren die Oberwellenstörungen per Echocanceling (eigenes Sendesignal invertiert ins Empfangssignal mischen), und schalten diese 600 mal pro Sekunde (=600baud), und verwenden dabei obige 4 Schaltzustände, was dann 1200bit/s ergibt, in beiden Richtungen, gleichzeitig. Die V.22bis Erweiterung definiert bei den selbigen Frequenzen und Baudrate ein 16 Zustände QAM, was dann 2400bit/s ergibt. Damit sind wir schon bei 8 mal den 300bit/s, und bei ganz ordentlich brauchbaren 240 Zeichen/s.)
Darüber hinaus muss man zwangsläufig die Frequenz erhöhen (was nur noch eine Frequenz zulässt, beide benutzen diese und stöeren sich damit gegenseitig, das muss man mit verbessertem Echocanceling mit Eigensignal Verzögerung ausgleichen), und die Baudrate nahe an oder gar über die Wellenfrequenz erhöhen (das geht bei synchronen Phasenshiebern, was aber das ganze nochmals anfälliger macht). Das ganze ist fast nur noch mit einem Digitalen Signalprozessor (DSP) im Modem lösbar. (CCITT V.32 verwendet nur noch 1800Hz, genau in der Mitte des Frequenzbereiches, bidirektional, mit 2400baud und 16QAM, was dann sogar 9600bit/s ergibt. Damit sind wir dann bei 32 mal den 300bit/s, und einem bei standard 1970er Terminal, und halbes 1980er Terminal.)
Für noch mehr hilft nur noch mehr bit/baud codieren (was noch mehr Zustände benötigt, was ebenfalls noch verwechselbarer und anfälliger ist). Zum dabei wenigstens noch eine Chance haben werden die Bitgruppen pro Baud mit einen Zusatzbit erweitert, was zwar die Anzahl Zustände weiter verdoppelt, aber bereits eine gewisse Fehlererkennung bei jeder Bitgruppe erlaubt (die Hälfte der Zustände sind ungültig) und danach wieder die Korrektur durch nochmals senden anfordern. Das ganze wird dann Trellis Code Modulation (TCM) genannt. (CCITT V32 Trellis hat weiterhin 1800Hz und 2400baud, aber mit 4+1bit und damit 32 Zustände TCM, und damit immer noch 9600bit/s aber sicherer. V.33 hat dann 6+1bit und 128 Zustände TCM, und damit dann 14400bit/s. Für höhere Raten (16800,19200,..,28800,..,33600) sind mir die genauen Details dann nicht mehr bekannt. Ab 14400kbit/s kann man auch Internet machen, mit real nutzbaren File und Mail Transferraten von etwa 1kByte/s.)
Die eigentliche UART Hardware arbeitet ohnehin mit TxD und RxD Leitungen die 0V/5V digital sind, egal ob 20mA oder 12V erwünscht ist, was dann mit externer analoger Hardware angepasst wird, mit Spannungswandler oder Stromwandler dahinter. Für die 12V wurden aber bald Spezialchips entwickelt. Ursprünglich die 1488 (5V zu 12V) und 1489 (12V zu 5V), wobei ersterer mit +12V und -12V vom Netzteil her versorgt werden muss (was kein Problem ist in einem PC). Heute gibt es aber auch die ganze MAX232 Familie, die beide Richtungen beinhalten, und auch einen 5V zu 10V Spannungsverdoppler und einen 10V zu -10V Spannungsinverter, und damit nur 5V vom Netzteil brauchen (praktisch wenn man in einem Mikrocontroller Projekt nur ein 5V Steckernetzteil hat). Es ist aber auch möglich, die 12V von der Gegenseite ihren Handshake Leitungen herzunehmen. Und oft werden auch einfach 2 UARTs direkt mit 5V mit einander verschaltet. Es gibt aber auch jede Menge 5V TxD+RxD + 5V+0V 4pin Konsole/Debug UART Anschlüsse in WLAN APs, zum auf einem externen Modul dann in 12V zu wandeln.
Eigentlich würden obige 2 TxD und RxD (und 0V) Leitungen ausreichen für die Kommunikation Endstation-Modem-Zentrale-Modem-Endstation, was man dann auch als <>3-Draht RS232 bezeichnet. Aber RS232 definiert noch eine Menge weiterer Leitungen, vor allem für die Kommunikation Endstation-Modem, ohne über die Telephonleitung zu gehen, welche man Steuersignale nennt. Daher hat es auch so einen grossen 25pin Stecker. Und daher sind auch 2 Varianten davon definiert, den Data Terminal Equipement (DTE, Endstation) mit DB25(m) Stecker, trotz des Namens für Rechner und Terminal, und den Data Carrier Equipement (DCE, Datenträger) mit DB25(f) Stecker, für das Modem (das kann man sich gut merken als "Ma Bell", Amerikanischer Slang für die Telephongesellschaft, weiblich, daher Modem weibcher Stecker). Die Signale drauf sind unter anderem:
Da RTS und CTS nicht (primitiv-)modemtauglich sind hat man dafür einen Ersatz gesucht. Man schickt statt dessen zumeist die beiden ASCII Steuerzeichen Device Control 3 (DC3, ASCII 19, Ctrl-S, auch XOFF genannt) und Device Control 1 (DC1, ASCII 17, Ctrl-Q, auch XON genannt) als Stop und Start über die Leitung.
Zum die Sekundären TxD und RxD einsparen und statt dessen die Primären nutzen, muss anfangs im Wählgerätemodus aufgestartet werden, und dann nach der Verbindung Aufbauen in den Leitungsmodus umgeschaltet werden. Das macht das Modem automatisch. Lediglich zum die Verbindung abbrechen wird es dann problematisch, weil man wieder von Leitungsmodus zum Wählgerätemodus wegschalten muss, aber das nicht plötzlich unabsichtlich passieren darf (was als Inband Signaling Problem bekannt ist). Danach kann man logischerweise nicht nur auflegen, sondern auch anderes im Modem machen und wieder zum Leitungsmodus zurückkehren und weitermachen. Dazu gibt es 2 Verfahren:
Das war auch lange (und ist heute teils immer noch) das standard Datenaustauschmedium schlechthin, wenn keine Floppys oder Ethernet oder USB Sticks da sind.
Genauso wie beim Ur-PC LPT Port, wo IBM der Platz für den Centronics Stecker fehlte, und sie daher den kleineren DB25(f) Stecker genommen haben, ging ihnen beim PC/AT wieder der Platz aus für dem COM Port DTE DB25(m) Stecker, und sie haben dafür einen kleineren DE9(m) Stecker genommen. Das konnten sie weil ohnehin viele der 25 Pins leer waren. Das ergab dann obig beschriebene Pinauswahl (minus Schirmung). Erstaunlicherweise wurden nicht etwa Pins 2-8 beibehalten und dann 20+22 auf 1+9 gelegt, sondern die Signale wurden verwürfelt, insbesondere sind TxD und RxD in DCE(!) Anordnung. Neben IBM haben auch jede Menge andere Hersteller eigene spezielle Stecker genommen, zumeist zum noch mehr Platz sparen, z.B. beim HP 100LX/200LX Taschencomputer einen 10pin IDC, oder gar bei den HP 48S/48SX/etc Tachenrechner einen 4pin IDC mit nur 3-Draht RS232 drauf, oder bei Cradles zum Telephone oder MP3 Player reinlegen komplete Eigendesigns.
Manchmal war aber auch nur schlichte Inkompetenz am Werk. Sei das DTE und DCE verhuddelt, z.B. Ur-Amiga DTE mit DB25(f) Stecker aber auch einige fehldesignte Fernost Billig Nullmodem Geräte mit 1 DTE und 1 DCE. Oder sei das schlicht die Signale falsch implementiert. Das ergab dann oft Leitungschaos, gerade auch beim Handshake, was dann oft verweigerte Datenübertragung produzierte. Daher wurden RS232 Tester erfunden zum die Leitungen beobachten, mit pro Signalleitung eine 2-Farb LED, wobei als Konvention gilt dass +12V = grün und -12V = rot ist. Zum reparieren, nachdem klar ist was falsch ist, gab es dann Gender Changer (einfach ein Paar DTE bzw DCE Stecker zum falsche Stecker korrigieren) und Breakoutboxen (zum falsche Pinanordnungen umarrangieren) oder als die finale Lösung dann Spezialkabel löten.
Damit ergibt sich ein beschreibbarer und wiedereinlesbarer magnetischer Datenspeicher/Massenspeicher, der analog zum Lochstreifen stanzen und lesen beim Fernschreiber benutzbar ist, aber wie ein Terminal schneller und lärmloser und komfortabler ist. Es braucht dazu lediglich einfache analoge modemartige Spannungs- und Signalwandler davor und danach, zum Logiksignale zu und von Audiosignalen verwandeln. Das ist die ganze Grundlage der Datenspeicherung auf Band und Disk (sowohl auf Floppydisk wie auch auf Harddisk).
Dieses erlaubt grundsätzlich die selbigen Audioverfahren wie bei Modems. Nur hat es hier eine breitere Frequenzbandbreite nach oben (wegen Musik nötig), aber auch so kommt eine Limite von dem Frequenzbereich der Bandaufzeichnung. Als Ton liegen auch hier wegen der Analogelektronik keine 0Hz drin, also muss moduliert werden. Weil nur einer sendet (abspeichert) oder danach gesendetes empfangt (einliest), und das ganze ohne Handshake, ist Halbduplex bzw sogar Simplex ausreichend, was noch mehr Frequenz und Bandbreite ermöglicht. Ausserdem ist kein Wählen nötig, und damit keinerlei Modusumschaltung, dafür ist aber Bandlaufwerks Motorsteuerung nötig.
Als Hardware braucht man dazu lediglich Wandlung von seriellen Daten zu Mikrophonsignal und von Kopfhörersignal zu seriellen Daten. Das ist einfache simple Analogelektronik, nur Spannungswandler. Dabei werden zum senden/speichern die 0V/5V zu den unter 1mV eines Mikrophons reduziert, und zum empfangen/einlesen die einige 10mV eines Kopfhöhrers auf 0V/5V verstärkt. Es braucht ja keinen Umweg über die +/-12V vom RS232. In keinem mir bekanten Fall wird dazu ein Spezialchip verwendet, oder auch nur eine UART zweckentfremdet. Immer wird einfach ein PIO und Software verwendet, zum die Daten serialisieren und modulieren, bzw demodulieren und parallelisieren. (Beim Apple I ist das ganze Kassetteninterface eine kleine Platine mit nur 2 Klinkenbuchsen, 10 Widerstände, 1 Kondensator, 1 Leuchtdiode, 2 Transistoren, 1 Op-Amp Verstärker, 3 TTL ICs, sowie 2 256x4bit PROMs (für 256bytes an Treibern und deren Kommandointerpreter).)
Für die Signale wurden statt 1950er/1960er Modem Analogtechnik aber von Anfang an wegen ohnehin vorhandener CPU Digital moduliert, und damit synchron, ohne pro-Byte Start-/Stopbits, wie erst ab den PSK Modems. Anfangs wurde aber trotzdem oft digitales FSK mit 1200/2400Hz benutzt, was hier Frequenzmodulation (FM) genannt wird. Darauf wurden anfangs sehr bescheidene 300bit/s gesetzt, trotz synchroner Frequenz. Das nannte man dann Computer User Tape Standard (CUTS). Sehr schnell erschien aber die offensichtliche Erweiterung auf 1200bit/s. Verbesserte Modulationsverfahren konnten dann einiges mehr an Daten verpacken:
Das c't SuperTape Format schaffte es auf vielen anfangs 1980ern verbreiteten Rechnern, und mit jedem Bandgerät und Band, 3600kbit/s zu erreichen. Auf teils Rechnern (das war abhängig von der PIO Hardware und CPU), mit gutem Bandgerät und Band, lagen sogar 7200bit/s drin, mit reiner Software digitaler Erzeugung, mit immer nur 1 bit/baud.
Einfach Bits aufs Band schreiben würde Probleme machen mit dem erste Bit finden. Daher werden die Daten als Blöcke gespeichert. Wegen dieser Blockbildung werden Daten zuerst in einem Blockbuffer angesammelt und erst wenn dieser voll ist auf Band geschrieben, bzw in diesen zurückgelesen und erst wenn er leergearbeitet ist mehr geholt. Ausnahme ist Basic Programme abspeichern, bei der eine bereits fertige Datenmenge bekannter Grösse (das Program im Speicher) direkt als einen riesigen Block abgespeichert wird. Die Blöcke bestehen auf Band aus einem Einlauf (zumeist viele Wechsel mit der höchsten Frequenz, gefolgt von einem Loch), einem Blockheader mit Verwaltungsdaten (z.B. Menge Daten im Block), den eigentlichen Daten (ohne Start-/Stopbits, da synchron), eine CRC Prüfsumme zum Datenfehler erkennen, sowie möglicherweise einen Auslauf (wie dem Einlauf). Nach einem Block folgt zumeist eine Pause, zum Zeit geben zum Band anhalten, Daten verarbeiten und dann Band weiterlaufen lassen, bevor dann der Einlauf des nächsten Blocks kommt.
Was jetzt nur noch fehlt ist die Bandmotorsteuerung. Für Empfang/Lesen muss man verhindern dass Bits schon "vorbei" sind bevor der Rechner liest. Dafür also den Rechner auf Empfangsbereit stellen bevor man das Band startet und dann Daten kommen. Es ist damit zuerst ein "leeres" Signal da, das aber keine Ählichkeit mit einem Blockeinlauf hat. Der Rechner wartet einfach bis er so einen sieht. Für Senden/Schreiben muss dagegen das Band laufen bevor der Rechner Bits sendet, sonst werden welche "fallengelassen". Dabei wird einfach "leer" aufgezeichnet, was beim Lesen genauso wirkt wie noch stehendes Band.
Während das für Programme ausreicht, gibt das Probleme mit Daten, welche Blockweise bearbeitet werden. Dazu muss man zusätzlich auch ein Motor Relais vorsehen, mit dem der Rechner das Band stoppen kann. Dazu wird der Mikrophonfernschalter Anschluss beim Bandgerät benutzt. Dumme Rechner lassen den auf default aus, womit man zum Band spulen den Stecker ausziehen muss, intelligentere schalten nur bei Pausen aus. Mit Motorsteuerung kann man auch blockweise von einem Band lesen und verarbeiten und auf ein anderes Band schrieben. Dazu braucht man 2 Bandgeräte, und dafür 2 Anschlüsse, mit 2 Relais, aber nur einem gemeinsamen analogen Datenteil, da man nur ein Band aufs mal benutzt wird.
Diese Scheibe wird im Kreis gedreht, mit 360RPM (1/6s) oder 300RPM (1/5s), was quasi sehr kurze kreisförmige Endlosbänder ergibt, die schnell umlaufen (verpasstes kommt in Sekundenbruchteilen wieder vorbei), und daher immer in nur einer Richtung drehen.
Ebenso wird die Scheibe in mehrere "Bänder" (Spuren genannt) aufteilt, indem man den Schreib-/Lesekopf mit einem Schrittmotor radial zur Scheibe verschiebt zum auf eine Spur zugreifen. Dieser Spurwechsel läuft ebenfalls in Sekundenbruchteilen ab, so 80..200ms. Zumeist ist der Minimalradius (innerste Spur) in etwa halber Maximalradius (äusserste Spur). Dabei hatte man anfangs 35 Spuren und später 77. Mit besserer Mechanik wurden diese auf 40 bzw 80 Spuren erweitert. Anfangs hatte man nur einen Kopf und musste die Disk wenden (und dazu ein zweites Schreibschutzloch ausschneiden), später kamen Laufwerke mit 2 Köpfen die automatisch schaltend beide Seiten nutzen konnten, wobei die Daten der zweiten Seite dann die umgekehrte Richtung als bei gewendeten Disks hatten.
Daten werden wieder in Blöcken geschrieben, mit sehr ähnlichem Blockformat. Anderst ist, dass es keine Längenangabe hat, weil alle Blöcke immer die selbige Länge haben müssen. Dieser ist dann auch ein Winkelausschnitt einer Diskumdrehung, und wird der daher Sektor genannt. Dafür hat es dazu jeweils abwechselnd einen Headerblock (mit Angaben der Blocknummer/Sektornummer und oft auch der Spurnummer) und dann einen Datenblock. Das ist so, damit die Header fix am Ort bleiben, und die Daten dann relativ zu dem Ort überschrieben werden. Die Header werden nur einmal geschrieben, ohne etwas zu lesen, beim formatieren der Disk.
Die Daten wurden anfangs bei Single Density (SD) mit 125kbit/s (5 1/4" mit 300RPM) oder 250kbit/s (8" mit 360PRM) geschrieben, etwa 100 mal schneller als bei Kassettenband. Dazu wurden zwecks Vermeidungs von Runs abwechslungsweise ein konstanter Impuls gefolgt von einem Datenimpuls geschickt, was auch FM genannt wurde (dieses hat aber nur eine Frequenz (250/500kHz), mit Daten-0 als eine ausgelassene Welle), und damit auch sehr ineffizient war. (Dies erlaubte bei IBM 3740 8" 360RPM+250kbit/s (gibt rohe 41666bit/Spur) dann mit 26 128Byte/1024bit Sektoren (26624bit/Spur genutzt) sowie 1Kopf * 77Spuren dann 250kByte pro Disk.)
Dies wurde mit Double Density (DD) beschleunigt auf 250kbit (5 1/4" mit 300RPM) oder 500kBit (8" mit 360PRM), aber auf Kosten von höherer Komplexität. Dazu werden die Datenimpulse "zwischen" den 250/500kHz Positionen hineingestellt, und die "konstanten" Impulse weggelassen wenn davor und danach ein Datenimpuls da ist. Das nennt man dann Modified FM (MFM). (Die Ur-PC Laufwerke sind 5 1/4" 300RPM+250kbit/s (gibt 50kbit/Spur) was dann mit 8oder9 512byte/4096bit Sektoren (32oder36kbit/Spur genutzt) sowie 1oder2Kopf * 40Spuren dann 160/180/320/360kByte ergibt. Die späterem PC/AT "HD" Laufwerke sind 360RPM+500kbit/s bzw in Ur-PC Emulation 360RPM+300kbit/s (gibt 83333bit/Spur bzw 50kbit/Spur) was dann mit 15 512byte/4096bit Sektoren (60kbit/Spur genutzt) sowie 2Kopf * 80Spuren dann 1200kByte ergibt. Die heutigen "HD" 3.5" sind 300RPM+500kbit/s (gibt 100kbit/Spur) was dann mit 18 512byte/4096bit Sektoren (72kbit/Spur genutzt) sowie 2Kopf * 80Spuren die 1440kByte ergibt. Die seltenen "ED" sind dann genau verdoppelt, 1Mbit und 36 Sektoren und 2880kByte.)
Einfacher als MFM, und doch fast so gross (+60% statt +100% Platz) kann man es bekommen, indem man nur Datenimpulse aufzeichnet, und die komplexe "wann Konstanter Impuls" Schaltung ganz einspart, aber dazu zum Runs verhindern wieder GCR einsetzt. Inserts ist nicht möglich, weil das Timing fester Disk Datenblocklängen keine variable Zeit erlaubt. Daher sind dann bei MFM 16Pulse/Byte, bei MFM 8Pulse/Byte und bei GCR 10Pulse/Byte. (Die Apple ][ und Commodore 8bit Laufwerke verwenden alle GCR. Wozniac kommentierte, dass ein normaler (FM oder MFM?) Diskcontroller 60-70 TTL Chips braucht, und sein GCR nur 10 TTL Chips, dieser aber mehr könne (also war das wohl FM als Vergleich). Anfangs war jede Spur gleich lang (wie bei FM und MFM heute noch), später wurden äussere Spuren mit etwas höherer Bitrate beschrieben. Das erlaubte Commodore ihre 170k (300RPM+256kbit/s 35Spuren * (17..21)Sektoren zu je 256Byte/2048bit) vs Apple ihre nur 110oder143k (300RPM+256kbit/s 35Spuren * 13oder16Sektoren zu je 256Byte/2048bit) Disks.)
Alte FM und MFM Floppycontroller waren zumeist viel TTL Logik. Für MFM in PCs wurden aber sehr bald fast ausschliesslich Floppydiskcontroller (FDC) Spezialchips verwendet, mit alles in einem, und extern nur etwas wenige Analogschaltungen zum als Datenseparator die Datenimpulse von den konstanten Impulsen trennen. (Die Apple und Commodore GCR Controller waren immer nur etwas wenig TTL zusammen mit einem Mikroprozessor, bei Apple der 6502 des Rechners, bei Commodore der 6502 des Floppylaufwerkes (im 1540/1541) oder ein zusätzlicher 6504 des Floppylaufwerkes (in den IEEE-488 Laufwerken).)
Diese Controllers konnten üblicherweise max 4 Laufwerke 00..11) bearbeiten. (Aber IBM hat beim PC das auf 01 und 10 reduziert, und fix auf 10 gejumperte Laufwerke benutzt, an ein gerades (10, BIOS 0x01, MS-DOS B:) oder verdrehtes (01, BIOS 0x00, MS-DOS A:) Kabel angeschlossen.)
Diese Controller verwenden teils DMA direkt in den Speicher (IBM PC), und teils einen blockgrossen RAM oder FIFO Buffer, und teils muss bei primitiven Chips (und den Apple und Commodore GCR wenig-TTL Teilen) der Rechner die Daten vorzu abholen (was bei 250000/8=31250Byte/s nicht gerade harmlos ist).
Mit genug RAM kann man aber auch eine ganze Spur aufs Mal schreiben und wieder einlesen. Mit Schreiben kann man einfach sofort anfangen, ohne Blockheader suchen (und damit im Schnitt eine halbe Diskumdrehung Wartezeit einsparen), nicht anderst als wenn man die Spur am formatieren wäre (weil man genau das macht, nur mit den richtigen Nutzdaten darin). Und die restlichen Blöcke sind nach einer Umdrehung auch bereits geschrieben, also alle in der Durchschnittlichen Zeit von 2. Damit wird auch nie ein einzelner Sektor überschrieben, und damit ist die Aufteilung in separate Header und Daten, sowie die Blockabstände überflüssig und einsparbar. Das erlaubt mehr Datenblöcke pro Spur, und damit weniger Spuren pro Daten, was wieder etwas schneller ist. Zum Lesen muss man nur einmal den nächsten beliebigen Sektoranfang abwarten, und dann alles reinziehen. Weitere Blöcke der selbigen Spur sind dann bereits im Speicher drin, was diese Floppys dann sehr schnell macht. (Das ist alles der Fall bei den Amiga 880k Floppys, die eigentlich genau das selbige sind wie eine PC 720k 250kbit/s DD MFM Floppy wäre (also 360k verdoppelt mit 80 statt 40 Spuren), nur eben mit 11 statt 9 512Byte/4096bit Sektoren/Spur, und damit 44 statt 36kbit der 50kbit rohen Platzes genutzt. Mit 500kbit/s HD MFM geht der Amiga auf 22 statt 18 Sektoren, und damit auf 1760k statt 1440k hinauf. Auch in der PC Welt gibt es auf 21 Sektoren/Spur gepackte 500kbit/s HD MFM "nur einmal schrieben" Überkapazitätsfloppys, welche aber nur für Software verteilen und installieren benutzt werden, und die dann 1680k haben, oder gar mit 2*82 Spuren beschreiben auf 1722k kommen.)
Wie man sieht, benutzen Harddisks also nichts anderes als eine 10..300 mal (Bitrate) bzw 10..30 mal (Drehzahl) beschleunigte Floppy Technologie, aber mit 1000mal mehr Spuren/Präzision gefertigt/betrieben für die grosse Kapazitätszunahme. Die Floppy war wiederum nichts anderes als eine Sammlung von per Kopfbewegung schaltbaren Spuren, die wiederum nur viele Stück 100e mal beschleunigte kurze Endlosbänder in Scheibenform waren. Die linearen Bänder wiederum waren nur aufgezeichnete bitsynchron digital generierte Modemsignale, analog zum Lochstreifen als aufgezeichnete gestanzte Bits. Bitsynchrone (PSK und später) Modems waren wiederum nur eine präzisere und schnellere Form der alten analogen FSK Modems. Und Modems waren auch nur eine Fernschreiber/RS232 Verpackung zur Übertragung über Sprach-/Audiosignal Telephonleitungen. Die Fernschreiber selber wiederum waren auch nur die Kombination von elektrischer/elektromechanischer Schreibmaschine als Interface mit den Telegraphenleitungen der Morsezeit, die bereits eine asynchrone serielle Kommunikation mit variabler Zeichenlänge (und damit primitiver Datenkomprssion) benutzten.
Damit gibt es von Morse in der ersten Hälfte der 1800ern bis heute eine mehr als 150 Jahre durchgehende Entwicklung. Das ist Geschichte der Technologieentwicklung vom feinsten, schrittweise von Erfindung zu Erfindung weiter aufbauend, Technologie als grosse Kulturleistung. Solches zu entdecken ist das, was Technologiegeschichte als Beschäftigung so interessant macht.
Diese Seite ist von Neil Franklin, letzte Änderung 2010.05.05