Commodore 64/128 mit PC verbinden, Teil 3

im dritten Teil dieser Serie will ich auf die Internas der RS-232 Schnittstelle auf dem Commodore 64 eingehen, da hierzu die Dokumentation mit praktischen Umsetzungsbeispielen im Internet immer weniger wird. Für den Commodore 128 können die Informationen 1:1 übertragen werden, eventuell ist lediglich ein anderer CIA-Chip (siehe unten) verbaut.

Zum besseren Verständnis empfehle ich sehr, beim weiteren Lesen das Buch „Mapping The Commodore 64“ in digitaler Form zur Seite zu haben. Darin lassen sich z.B. Adressen wie „$DD02“ und deren Funktion schnell nachschlagen.

Der C64 hat für Eingabe-/Ausgabe-Operationen zwei Chips vom Typ MOS 6526 (Complex Interface Adapter (CIA)) auf der Hauptplatine verbaut. Für unsere Experimente mit der RS-232 Schnittstelle ist der zweite CIA-Chip (#2) von Interesse, der über den Userport eine RS-232 Schnittstelle mit TTL-Logik zur Verfügung stellt:

Manche der Pins des 6526 sind direkt mit dem Userport verbunden, wie im obigen Bild zu erkennen ist. Die RS-232 Kommunikation wird dabei über zwei Data Ports A und B des 6526 realisiert, deren Bits (mit Ausnahme der Leitung RI – Ring Indicator) entweder geschrieben oder gelesen werden können. Im obigen Bild wird dies durch die Pfeilrichtung symbolisiert. Diese Data Ports sind im Hauptspeicher (RAM) an Adresse $DD00 und $DD01 zu finden.

Die Datenflussrichtung wird dabei über zwei Register im 6526 bestimmt: Data Direction Register A und B, jeweils an Adresse $DD02 und $DD03 zu finden. Um zu bestimmen, dass am Data Port A die Sendeleitung TxD nur geschrieben und nicht gelesen wird, muss im Data Direction Register A das zweite Bit auf „1“ stehen. Damit am Data Port B die Empfangsleitung RxD nur gelesen und nicht geschrieben wird, muss im Data Direction Register B das nullte Bit auf „0“ stehen.

In meinem Fall steht in Speicheradresse $DD02 der binäre Wert 0011 1111, somit ist das zweite Bit korrekt auf „1“ eingestellt. In Adresse $DD03 haben ich den Wert 000 0110 wiedergefunden. Auch hier steht korrekterweise das nullte Bit auf „0“.

Im ersten Artikel der Serie haben wir die Empfangsleitung RxD (Userport C) zusätzlich mit der FLAG-Leitung (Userport B) verbunden. Der Grund dafür lässt sich leicht erklären: Um der CPU anzuzeigen, dass Daten empfangen wurden, wird die FLAG-Leitung auf Null gezogen, was einen Non-maskable Interrupt (NMI) auslöst:

Diesen Zustand kann man mittels Adresse $DD0D („Interrupt Control Register“) und dessen Bit 4 überprüfen. Eine logische Eins (1) bedeutet, dass der NMI ausgelöst wurde. Eine andere Variante ist über die Adresse „RS-232 Interrupts Enabled“, $2A1. Sobald man im Terminal-Programm des PCs die Return-Taste drückt und damit Daten empfangen werden, geht Bit 1 auf eine logische Eins.

Nun ist es an der Zeit, die auf der Leitung RxD empfangenen Daten zu verarbeiten, zum Beispiel in Basic. Der Basic-Befehl OPEN <logische Dateinummer>,2,0,<Parameter> setzt über die Übergabe der <Parameter> nicht nur die beiden Control und Command Register, sondern initialisiert auch die beiden Data Direction Register und reserviert zwei 256-Byte Speicherbereiche am Ende des User Data-Bereichs im Hauptspeicher:

Mit der Reservierung der beiden Speicherbereiche wird der maximal verfügbare Speicher für Basic um 2*256 Bytes reduziert. Dies kann man an dem Zeiger an Adresse $38 auf die höchste von Basic benutzbare Adresse minus Eins sehen:

  • Vor dem OPEN-Befehl: $38 = 160 => 160 *256 – 1 = 40960 = $9FFF
  • Nach dem OPEN-Befehl: $38 = 158 => 158 * 256 – 1 = 40447 = $9DFF

Der Speicherbereich für zu sendende Daten liegt im Adressbereich $9DFF bis $9EFE, der Speicherbereich für empfangene Daten im Adressbereich $9EFF bis $9FFF. Diese beiden Puffer sind als „Ring Buffer“ implementiert, was bedeutet, dass empfangene und gesendete Daten in diesem Bereich mit Überlauf fortgeschrieben werden. Dadurch werden alte Daten und Datenblöcke mit mehr als 256 Byte laufend überschrieben.

Pro Puffer gibt es zwei Zeiger, die jeweils auf den Start und das Ende der aktuellen Daten zeigen. Der Zeiger für den Start der gesendeten Daten ist in Adresse $29C zu finden, der Zeiger an das Ende der gesendeten Daten in Adresse $29B. Der Zeiger für den Start der empfangenen Daten ist in Adresse $29E zu finden, der Zeiger an das Ende der empfangenen Daten in Adresse $29D.

Am konkreten Beispiel: Ich habe vom PC aus über die Terminalsoftware die Zeichenkette „XXX“ an den C64 gesendet. Diese finde ich mittels eines Speicher-Monitors wie SMON im Adressbereich $9F35 bis $9F37 wieder:

Die Zeichenkette befindet sich damit im Bereich des Receive Ring Buffers, allerdings nicht am Anfang. Der Zeiger auf den Start der Zeichenkette an Adresse $29E enthält den Wert 54 ($36). $9EFF + $36 = $9F35, also genau die Adresse mit dem ersten empfangenen „X“. Der Zeiger an Adresse $29D auf das Ende der empfangenen Daten wird mit jedem empfangenen „X“ von 54 an hochgezählt und steht nach drei empfangenen „X“ auf dem Wert 56. Werden nun die von der RS-232 Schnittstelle empfangenen Zeichen mit dem Basic-Befehl GET#<logische Dateinummer>, <Variable> einer Variablen zugeordnet, so werden beide Zeiger $29E und $29D auf den Wert 57 ($39) gesetzt. Ab jetzt gelten die Daten aus Sicht des Betriebssystems als gelesen. Mit $9EFF + $39 = $9F38 sind die Zeiger auf den nächsten verfügbaren Speicherbereich im Ring-Puffer gesetzt worden. $29E = $29D bedeutet, dass von der RS-232 Schnittstelle noch keine neuen Daten empfangen wurden.

Man erkennt, dass man zwischen von der RS-232 Schnittstelle und damit vom 6526 empfangene bzw. gesendete Daten unterscheiden muss und solchen, die per PRINT# / GET# aus Sicht des Betriebssystems als empfangen bzw. gesendet gelten. Auch muss man beachten, dass die RS-232 Schnittstelle bitweise arbeitet, in den beiden Puffern gesendete bzw. empfangene Daten dann aber zur leichten Verarbeitung durch den Anwender in Form von Bytes vorliegen.

Ganz einfach, oder? 😉

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


Der Zeitraum für die reCAPTCHA-Überprüfung ist abgelaufen. Bitte laden Sie die Seite neu.