Tastatur

Aus C64-Wiki
Zur Navigation springenZur Suche springen
Ur-C64: orange Funktionstasten
C64: graue Funktionstasten
Aldi-C64: hellgraue Funktionstasten
C64C / C64G: Beschriftung komplett oben

Die Tastatur ist das wichtigste Eingabegerät eines Computers. Der Benutzer kann damit alle verfügbaren Zeichen eingeben. Bestimmte eingegebene Zeichenfolgen werden vom Computer als Befehle wie z.B. LIST, RUN, LOAD, SAVE erkannt. Durch eine Aneinanderreihung (siehe Programmierung) von Befehlen oft in Kombination mit Zeilennummern entstehen Programme, die dann bearbeitet, ausgeführt, abgespeichert oder geladen werden können.

Der C64 ist ein Tastaturcomputer, also ein Computer, der die Tastatur in sein Gehäuse integriert hat und mit dieser optisch zu einer Einheit verschmilzt. Zu dieser Gattung gehören auch andere Heimcomputer wie der Commodore VC 20, C16, C116, C128, Plus/4, Amiga oder Atari ST.
Die Tastatur ist das Haupteingabegerät des C64.

Hardware[Bearbeiten | Quelltext bearbeiten]

Die Tastatur des C64 wurde größtenteils von Mitsumi hergestellt.[1]

Aufbau[Bearbeiten | Quelltext bearbeiten]

Tastatur-Platine, links die Aussparung für die Shift-Lock-Taste, im unteren Bereich sind die Anschlüsse an die Kabel, welche auf der Rückseite angebracht sind.

Die C64-Tastatur besitzt 66 Tasten.

  • Shift Lock  ist mechanisch rastend und ist parallel zum linken Shift  geschaltet.
  • RESTORE  wirkt direkt über ein Monoflop auf den NMI-Eingang des Prozessors.
  • Die restlichen 64 Tasten sind in einer 8×8-Matrix zusammen geschaltet (siehe Schaltung weiter unten).

Funktionsweise der Matrix:

Wurde z.B. A  gedrückt, so besteht eine leitende Verbindung zwischen den Leitungen PA1 und PB2 der CIA 1.

Abfrage[Bearbeiten | Quelltext bearbeiten]

Die Funktionsweise der Tastaturabfrage, wie sie im KERNAL implementiert ist:

  • Die Initialisierung der I/O-Ports erfolgt bei $FDA3:
    1. Die Portbits PB0-PB7 des CIA 1 werden als Eingänge programmiert ($DC03=0).
    2. Ohne Tastendruck liegt auf den Eingängen wegen der im Portbaustein integrierten Pull-Up-Widerstände ein High-Pegel.
    3. Die Portbits PA0-PA7 des CIA 1 werden als Ausgänge programmiert ($DC02=255).
  • Die eigentliche Keyscan-Routine bei $EA87 macht folgendes:
    1. Es wird eine 0 (Low-Pegel) durch die Portbits PA0-PA7 geschoben ($DC00=254,253,251,247,239..., siehe KERNAL $EAA3 und $EAD6).
    2. Werden Nullen bei den Eingangs-Portbits PB0-PB7/$DC01 festgestellt (KERNAL $EAAB), so sind die entsprechende(n) Taste(n) gedrückt.

Probleme[Bearbeiten | Quelltext bearbeiten]

  • Da u.a. die Joysticks die gleichen Leitungen benutzen (jede Bewegung zieht eine der Leitungen fest auf Masse bzw. 0 V), gibt es diverse Nebenwirkungen.
  • Bei der KERNAL-Implementierung der Tastaturabfrage fällt das bei Joystick 1 am stärksten auf (Zeichen erscheinen ohne Tastendruck), aber auch Joystick 2 stört die Abfrage der Tastatur (Tasten werden nicht mehr oder falsch erkannt).
  • Alternative Tastaturabfragen (in eigenen Programmen oder Spielen) können zwar verhindern, dass Joystick-Bewegungen als Tastendruck erkannt werden (keine CIA-Leitung auf Low gesetzt, liest jedoch trotzdem Low aus => Joystick wird bewegt), jedoch trotzdem nicht alle Tasten der Tastatur (sicher) auslesen, wenn ein Joystick bewegt wird.
    • Mit entsprechenden Routinen lassen sich wenigstens die Tasten zuverlässig auslesen, die an nicht mit den Joysticks geteilten Leitungen liegen (PA5-7 und PB5-7), also die Tasten C= , = , : , Q ,  , @ , RUN/STOP , /  und , .
  • Beim Drücken von mindestens drei Tasten gleichzeitig werden teilweise weitere Tasten fälschlich als gedrückt erkannt. Dies kann man z.B. testen, indem man beide Cursor-Steuertasten gedrückt hält und dabei die linke Shift-Taste auf und ab bewegt. Es erscheinen Zeichen wie bei Shift-"A". In der Matrix unten im Artikel sieht man, dass, wenn man ein gedachtes Rechteck mit der linken Shift-Taste und den beiden CRSR-Tasten als drei Ecken bildet, die vierte Ecke auf der Taste "A" liegt. Nach derselben Methode kann man bei anderen Kombinationen von drei Tasten herausfinden, ob und welche weiteren Tasten fälschlich erkannt werden. Dieser Effekt wird von Emulatoren bisher (2008) nicht emuliert. Dioden in der Tastaturmatrix hätten dieses Problem verhindert, wurden jedoch nicht eingesetzt.
  • Aus C64-Sicht lassen sich manche Kombinationen von Input-Signalen prinzipiell nicht auseinanderhalten. So kann z.B. zwischen
    • Joystick 2 hoch + F1 und
    • Joystick 2 hoch + Joystick 1 Feuer
nicht unterschieden werden.

RESTORE-Taste[Bearbeiten | Quelltext bearbeiten]

Die RESTORE-Taste ist direkt über einen Kondensator mit der NMI-Hardware der CPU verbunden. Da dieser jedoch zumindest bei frühen Brotkasten-C64s zu klein dimensioniert ist, muss man die Taste sehr heftig (=schnell) anschlagen, damit sie anspricht. Abhilfe schafft das Ersetzen bzw. die parallele Beschaltung des Originalbauteils (51 pF, C38) durch einen 1nF-Kondensator.

Schaltung[Bearbeiten | Quelltext bearbeiten]

ACHTUNG! Bei der VC-20-Tastatur-Matrix sind die Spalten 0 und 7 sowie die Zeilen 3 und 7 vertauscht!

C64 / VC20
Tastaturmatrix
CIA#1 PORT A - Register 56320 / $DC00
PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0
Spalte 7 Spalte 6 Spalte 5 Spalte 4 Spalte 3 Spalte 2 Spalte 1 Spalte 0
CIA#1
PORT B
-
Register
$DC01
56321
PB0 Zeile 0 1  £  +  9  7  5  3  DEL  Icon Port1.pngIcon joystick.png Joystick nach vorne
PB1 Zeile 1   *  P  I  Y  R  W  RETURN  Icon Port1.pngIcon joystick.png Joystick zurück
PB2 Zeile 2 CTRL  ;  L  J  G  D  A  CRSR ⇒  Icon Port1.pngIcon joystick.png Joystick nach links
PB3 Zeile 3 2  HOME  -  0  8  6  4  F7  Icon Port1.pngIcon joystick.png Joystick nach rechts
PB4 Zeile 4 SPACE  R.SHIFT  .  M  B  C  Z  F1  Icon Port1.pngIcon joystick.png Feuerknopf drücken
PB5 Zeile 5 C=  =  :  K  H  F  S  F3 
PB6 Zeile 6 Q    @  O  U  T  E  F5 
PB7 Zeile 7 RUN/STOP  /  ,  N  V  X  L.SHIFT  CRSR ⇓ 
Icon Port2.pngIcon joystick.png
Feuerknopf drücken
Icon Port2.pngIcon joystick.png
Joystick nach rechts
Icon Port2.pngIcon joystick.png
Joystick nach links
Icon Port2.pngIcon joystick.png
Joystick zurück
Icon Port2.pngIcon joystick.png
Joystick nach vorne


Und hier die Anschlussbelegung im C64:

KBD C64.png

Ersatztasten[Bearbeiten | Quelltext bearbeiten]

  1. Commodore-Tastaturen: C128; C+4; C232; C264; C364; SX-64; C65; C64GS
  2. Amiga-Tastaturen: A500; A500+; A600 (auch in schwarz); A1000; A1200; A1500; A2000; A2500; A3000; A4000; SX-500; CDTV (schwarz); CD32 (schwarz)
  3. Mitsumi AT-Tastatur KKR-E99AC
  4. Mitsumi AT-Tastatur KKR-E99AC-9
  5. Mitsumi Amiga-Tastatur (mit MOS Technology 6570-036 – 6500/1 Mikrocontroller auf der Tastaturplatine im Amiga 500)

C128-Anschluss[Bearbeiten | Quelltext bearbeiten]

Der C128 hat drei zusätzliche Tastaturmatrixspalten (K0...K2), die über den VIC-IIe ($D02F) angesteuert werden.[2]

  1. Masse
  2. X
  3. NMI
  4. VCC
  5. Row3
  6. Row6
  7. Row5
  8. Row4
  9. Row7
  10. Row2
  11. Row1
  12. Row0
  13. COL0
  14. COL6
  15. COL5
  16. COL4
  17. COL3
  18. COL2
  19. COL1
  20. COL7
  21. K0
  22. K1
  23. K2
  24. 40/80
  25. CAPLK SENSE

C16-Timing[Bearbeiten | Quelltext bearbeiten]

c16timing.jpg

PS/2-Tastatur am Datasettenanschluss[Bearbeiten | Quelltext bearbeiten]

Adapter und Software zum Anschluss deutsch englisch

Tastenbelegung[Bearbeiten | Quelltext bearbeiten]

Siehe C64-Tastaturtabelle für die konkreten Codes.

Typisch bei Commodore ist die Abweichung der sonst von ASCII abweichenden Zeichenordnung auch beim Einlesen von der Tastatur. Speziell bei der Groß-/Kleinschreibung korrespondieren die Tastaturcodes des GET-Befehls (CHRIN: $FFCF oder GETIN: $FFE4) nicht mit der ASCII-Ordnung. Bezogen auf den Font 2 (mit Groß- und Kleinschreibung):

  • Die Codes der Kleinbuchstaben entsprechen im ASCII-Code den Bereich für Großbuchstaben (65 bis 90).
  • Die Codes der Großbuchstaben haben keine Entsprechung im ASCII-Code, haben das Bit 7 gesetzt. Erst wenn dieses gelöscht ist, stimmen sie erst mit den ASCII-Codes für Großbuchstaben (65 bis 90) überein.

Programmierung[Bearbeiten | Quelltext bearbeiten]

Die Tastaturabfragen können mit den BASIC-Befehlen INPUT, GET oder PEEK erfolgen oder über entsprechende Maschinenspracheprogramme (Assembler).

Direkte Tastenabfrage in Assembler[Bearbeiten | Quelltext bearbeiten]

Das Abwarten nach dem STA $DC00 und das Entprellen sind nicht in jedem Fall nötig, sorgen aber in bestimmten Fällen (lange Tastaturleitungen, lange Joystick-Leitungen und so weiter) für stabilere Funktion. Zu beachten ist auch, dass die Joysticks einige Leitungen von PA und PB auf Masse ziehen können. Um sicher (nur) Tasten zu erkennen, muss man also z.B. vor und nach der Tastenabfrage sicherstellen, dass die Joysticks in Ruhestellung sind (nach Setzen von $DC00 auf $FF muss auf $DC01 und $DC00 ebenso $FF gelesen werden).

                         ; Dieses Programm wartet bis die Taste "S" gedrückt wurde. Programmstart mit SYS 49152

*=$c000                  ; Startadresse des Programms
 
start    sei             ; Interrupts sperren (IRQ-Routine abschalten, um Überschneidungen mit alter Tastaturabfrage zu vermeiden)
 
         lda #%11111101  ; Spalte 1 (COL1) der Matrix testen (Port-Leitung PA1=0)
         sta $dc00       ; Spaltenregister schreiben
         bit $dc00       ; Dummy-Befehl: Warten, bis PB-Leitungen neuen Spannungspegel haben
         bit $dc00       ; Nochmal etwas warten
  
loop     lda $dc01       ; Zeilenregister auslesen
         cmp $dc01       ; Entprellen:
         bne loop        ; Warten bis PB stabil
         and #%00100000  ; Zeile 5 (ROW5) ausmaskieren (Port-Leitung PB5)
         bne loop        ; Warte bis "S" gedrückt (Akku = 0)

         cli             ; Interrupts wieder zulassen
ende     rts             ; Rücksprung BASIC

Programm im Speicher:

.c000  78         sei
.c001  a9 fd      lda #$fd
.c003  8d 00 dc   sta $dc00
.c006  2c 00 dc   bit $dc00
.c009  2c 00 dc   bit $dc00
.c00c  ad 01 dc   lda $dc01
.c00f  cd 01 dc   cmp $dc01
.c012  d0 f8      bne $c00c
.c014  29 20      and #$20
.c016  d0 f4      bne $c00c
.c018  58         cli
.c019  60         rts

Tastenabfrage in BASIC[Bearbeiten | Quelltext bearbeiten]

10 INPUT "Geben Sie bitte etwas ein"; A$
20 PRINT "Sie gaben ein: "; A$
Anmerkung: Hierbei muss eine Bestätigung der Tastatureingabe mit RETURN  erfolgen, um das Programm fortzusetzen. Die Tastatureingabe befindet sich nach der Eingabe in der Variable A$.

  • Mit dem BASIC-Befehl GET
10 PRINT "Druecken Sie bitte eine Taste:"
20 GET A$: IF A$="" THEN 20
30 PRINT "Sie drueckten die Taste: "; CHR$(34);A$;CHR$(34)
Anmerkung: Wenn keine Taste gedrückt wird, ist die Rückmeldung der Variable A$ eine leere Zeichenkette. Um einen Wartezustand zu realisieren, muss A$ geprüft werden, und wenn A$ leer ist, muss erneut auf den GET-Befehl verwiesen werden.

  • Tastaturpuffer kombiniert mit BASIC-Befehl GET
POKE 198,0: WAIT 198,1: GET A$
Anmerkung: Es wird zuerst der Tastaturpuffer geleert, mittels WAIT auf eine Änderung der Anzahl der Zeichen im Tastaturpuffer gewartet und dann das Zeichen mit GET ausgelesen. Man erspart sich hier die zeilennummernabhängige Schleifenkonstruktion.

  • Mit dem BASIC-Befehl PEEK
10 KL=245: KH=KL+1: REM Zeiger der Tastencodetabellenadresse
20 AZ$=CHR$(34): REM Anfuehrungszeichen
30 IF PEEK(197)<>64 THEN 30: REM Warten bis keine Taste mehr gedrueckt
40 PRINT CHR$(14);"Druecke Sie bitte eine Taste ..."
50 T=PEEK(197): IF T=64 THEN 50
60 TB=PEEK(KL) + PEEK(KH)*256: REM TB: Adresse auf Tastencodetabelle
70 PRINT "Sie drueckten die Taste ";AZ$;CHR$(PEEK(TB+T));AZ$;","
80 PRINT "Tastencode";T;"in Tabelle @";TB
90 POKE 198,0: REM Tastaturpuffer leeren
Anmerkung: Die Tastatureingabe erfolgt durch Auslesen der Speicheradresse 197 ($00C5).
Der Tastencode wird in der Variable T abgelegt. Wenn keine Taste gedrückt wird, ist die Rückmeldung immer der Wert 64. Um hier einen Wartezustand zu realisieren, muss daher T auf diesen Wert geprüft werden. Beträgt der Rückgabewert 64, so muss erneut der Tastaturcode mit PEEK ausgelesen werden. Die Steuertasten CTRL , SHIFT  und C=  verändern den Zeiger in den Speicherstellen 245 und 246. Dieser Zeiger wird in der IRQ-Routine je nach Kombination dieser Tasten auf eine andere Tastencodetabelle gesetzt. An dieser Stelle hat das BASIC-Programm allerdings eine sogenannte Race-Condition (programmlaufabhängige Inkonsistenz): Wenn zwischen den beiden PEEK-Befehlen eine Unterbrechungsbehandlung (IRQ) passiert, die den Zeiger verändert, passen die Werte der beiden PEEK-Befehle nicht mehr zusammen und TB enthält daher keine Adresse auf eine Tastaturtabelle, weshalb ein falsches Ergebnis berechnet wird. Da dies ausgesprochen selten passieren dürfte, ist dieser Umstand im Programm nicht berücksichtigt.

  • Per BASIC-Befehle GET ASCII-Codes ermitteln
10 GET A$: IF A$="" THEN 10
20 A=ASC(A$): B = A AND 31
30 IF (A AND 224) = 64 THEN IF B AND B < 27 THEN A=A OR 32
40 IF (A AND 224) = 192 THEN  IF B AND B < 27 THEN A=A AND 127
50 PRINT A;
60 GOTO 10
Anmerkung: Variable B enthält einen Hilfswert, um in einem 32er-Bereich den Buchstabenbereich von 1 bis 26 leichter eingrenzen zu können. Aus Laufzeitgründen wird eine IF-Kaskade verwendet, statt einen einzigen langen Ausdruck mit AND zu bilden.
Ausgegeben wird der per ASC-Funktion ermittelte PETSCII-Code somit als ASCII-Code. Das Zeichen wird per CHR$ ausgegeben, stellt sich aber damit hinsichtlich Groß-/Kleinschreibung "verdreht" dar.

Hilfreiche PEEKs & POKEs[Bearbeiten | Quelltext bearbeiten]

Eine Erklärung der benutzten Speicherstellen findet sich unter Zeropage.

Autorepeat: Die Eingabe liefert einen

POKE 650,128 führt dazu, dass jede Taste automatisch wiederholt wird, solange man die Taste gedrückt hält.
POKE 650,0 hebt diese Funktion wieder auf.

Tastatursperre:

POKE 649,0 blockiert Eingaben von der Tastatur, weil Tastaturpuffer auf die Länge 0 gesetzt wird.
POKE 649,10: POKE 808,237 lässt die Eingabe wieder zu.
oder

POKE 655,71 Abändern des Zeigers auf die Dekodiertabelle, ebenfalls Tastatursperre
POKE 655,72 Tastatursperre aufheben.

oder

POKE 56322,224 schaltet die Tastatur ebenfalls ab, hierbei wird das Datenrichtungsregister des CIA 1 verändert. Dieser POKE wird deshalb gerne während der Joystickabfrage verwendet, da sich die Joysticksignale teilweise mit der Tastatur überschneiden.
POKE 56322,255 aktiviert die Tastatur wieder.

oder durch Abschaltung des Interrupts (Ausnahme: RUN/STOP +RESTORE ) oder der E/A-Logik.

Behandlung einzelner Tasten deaktivieren:

  • RUN/STOP : POKE 788,52 - wieder aktivieren mit POKE 788,49 - biegt den IRQ-Vektor von $EA31 auf $EA34 um, sodass Flag $91 in der Zeropage beim Drücken von RUN/STOP  nicht mehr gesetzt wird und der BASIC-Interpreter somit nicht mehr unmittelbar auf die Taste reagiert. TI wird als Nebeneffekt auch nicht mehr weitergezählt.
  • RESTORE : POKE 792,193 - wieder aktivieren mit POKE 792,71 - biegt den NMI-Vektor von Standard $FE47 auf $FEC1 um. Das RTI dort beendet die NMI-Behandlung und macht RESTORE  somit funktionslos. Da die Taste nicht Teil der Tastaturmatrix ist, kann sie so auch nicht mehr abgefragt werden.

RUN/STOP  lässt sich nach oben genanntem POKE im Programm abfragen und beispielsweise für die Menüführung oder als Abbruchbedingung für Aktionen verwenden. Das folgende Programm wartet darauf, dass der Benutzer die Taste drückt, und gibt vor dem Ende noch eine Meldung aus:

10 PRINT "PRESS RUN/STOP": POKE788,52
20 GET A$: IF A$<>CHR$(3) THEN 20
30 PRINT "YEAH! RUN/STOP DETECTED"

Tastaturpuffer: Die Speicherstellen 631-640 dienen als Tastaturpuffer, der maximal 10 Zeichen umfassen kann. Er kann mit Hilfe von PEEK ausgelesen werden, aber es kann auch mit Hilfe von POKE Tastendrücke simuliert werden. Dies kann zum Beispiel dazu benutzt werden, um

  • BASIC-Zeilen, etwa mit Funktionsdeklarationen via DEF FN, dynamisch über Benutzereingaben erstellen zu lassen oder
  • einen fehlerbedingten Abbruch samt Rückkehr zum Direktmodus abzufangen (vergleiche TRAP oder ON ERROR).

Mit entsprechend aufbereitetem Bildschirm (Programmzeilen), positioniertem Cursor und fingierten Tastendrücken im Tastaturpuffer ist das auf solch einem Umweg realisierbar.

Ein POKE 198,0 löscht den Tastaturpuffer. Dies ist besonders bei Beginn einer neuen Eingabe nützlich, wenn verhindert werden soll, dass etwaige zuvor getätigten Tastenanschläge, die im Tastaturpuffer gespeichert wurden, unerwünschterweise als Eingabe erscheinen.

Quellen[Bearbeiten | Quelltext bearbeiten]

  1. Thema: Qualität der C64-Tastaturen auf Forum64.de
  2. C128-Schaltpläne zur Tastatur (82.gif und 84.gif) auf zimmers.net

Weblinks[Bearbeiten | Quelltext bearbeiten]

WP-W11.png Wikipedia: Tastatur

Mustread 32.gif Dieser Artikel wurde in die Liste der Lesenswerten Artikel aufgenommen.