8-Bit-Breadboard-Computer auf Basis einer 6502-CPU - Erste Schritte mit der CPU
Nun ist meine W65C02-CPU (Hersteller: Western Design Center) endlich aus China angekommen. Es hat zwar ein wenig gedauert, aber so einfach ist es gar nicht, günstig an die Dinger zu kommen. Meiner hat unter 4 Euro mit Versand gekostet.Die Wartezeit habe ich mir ja schon mit der Entwicklung eines Clock-Moduls und eines EEPROM-Lesegerätes vertrieben. Die in diesen Aritkeln besprochenen und gebastelten Breadboard werden aber noch wichtig werden und zum Einsatz kommen. Ich habe nur schon ein wenig vorgegriffen.
Genau genommen habe ich einen W65C02S8P-10 bekommen. Die 8 steht für den Fertigungsprozess, P für das 40-Pin-DIL-Plastikgehäuse und die 10 für eine maximalen Takt von 10 MHz. Mittlerweile habe ich mitbekommen, dass ich mir das 14 MHz-Model auch neu bei Mouser für ca. 7 Euro hätte bestellen können. Egal, die 10 MHz reichen mir vollkommen.
Der W65C02S ist ein moderner Chip, der immer noch hergestellt wird, kompatibel zum MOS 6502 ist, aber ein paar Extra Leitungen und OpCodes hat. Aber das Wichtigste für mich:
Datasheet, Abschnitt 3.8: Phase 2 In (PHI2), Phase 2 Out (PHI2O) and Phase 1 Out (PHI1O)Das heißt, dass ich einen externen sebsterzeugten Takt (eben mit meinem Clock-Modul) benutzen kann und der W65C02 stabil bleibt und sich alle Register und internen Zustände merkt. Das ist beim original MOS 6502 leider nicht so: wird dort der Takt zu langsam, dann wird er instabil. Einzelschritt ist also mit dem MOS 6502 nicht so ohne Weiteres möglich. Mit dem W65C02 aber eben schon.
Phase 2 In (PHI2) is the system clock input to the microprocessor internal clock. During the low power Standby Mode, PHI2 can be held in either high or low state to preserve the contents of internal registers since the microprocessor is a fully static design.
Und Einzelschritt werde ich für die Analyse und das Debugging meiner Maschinensprache-Programme brauchen. Mit dem W65C02 gegenüber dem MOS 6502 verhält es sich ein wenig wir mit SRAM und DRAM: SRAM ist statisch und vergisst nicht und DRAM will immer wieder aufgefrischt werden. Und geschieht dies nicht schnell genug (weil der Takt so langsam ist), dann wird der MOS halt leider vergesslich.
Pinout des W65C02
Einfach nur so in das Breadboard gesteckt funktioniert unser 6502 natürlich nicht. Er braucht schon die richtigen Verbindungen zur Außenwelt. Das geschieht wie immer über die Pins, der 6502 hat gleich 40 davon. Deren Bedeutung will ich hier kurz stichpunktartig notieren. Als genaue Referenz dient natürlich das Datasheet zum W65C02.
Hier noch einmal übersichtlich die Sprung-Vektoren der CPU: Vector Locations (Low Byte, High Byte)
FFFE, F BRK/IRQ Software/Hardware
FFFC, D RES Hardware
FFFA, B NMI Hardware
Nun wissen wir alles, was wir zum Anschluss der CPU wissen müssen. Machen wir uns also daran, den 6502 in ein Breadboard zu drücken und adäquat zu verkabeln.![]() Zuerst bekommt unsere CPU erst einmal Strom über VCC und GND. Dann legen wir ...
Das Clock-Modul-Breadboard und das CPU-Breadboard werden verheiratet, der Strom und das Clock-Signal vom Clock-Modul weitergereicht, das Labor-Netzteil auf eine max. Stromstärke von 300 mA eingestellt (sicher ist sicher), die Spannung noch einmal überprüft und dann die Stromversorgung eingesteckt... ![]() Schauen wir doch mal die einzelnen Zustände der Reihe nach an:
Bei diesem ersten Test waren die Datenbits weder mit Low noch High verbunden und hingen in der Luft (floating). Darum kann in diesen ein zufälliger Wert beim Lesen durch die CPU stehen. Ich erkläre mir das Verhalten der CPU so, dass dadurch des öfteren illegale OpCodes im Datenbyte stehen und ausgeführt werden. Hier bitte einmal auf die gelbe SYNC-LED unten links achten, immer wenn die aufleuchtet, wird ein OpCode geholt und danach ausgeführt. Wenn dann ein OpCode im Datenbyte steht, den es nicht gibt, wird wohl ein Hard-Reset durch die CPU ausgeführt und die Reset-Routine beginnt von Neuem. Beim nächsten Durchlauf der Reset-Routine ist das Ergebnis dann anders, weil das Datenbyte anders (nämlich zufällig) ist. Höchstwahrscheinlich führt das wieder zu einem illegalen OpCode, zu einem Hard-Reset und zu einem neuen Reset-Durchgang. Etwas mehr Ordnung in die Sache können wir bringen, in dem wir der CPU im ersten Schritt einfach einen Speicher vorgaukeln, der an allen Stellen den selben OpCode beinhaltet. Hier habe ich den OpCode 0xEA, in binär 0xb1110 1010 ausgewählt. Der steht für den Assembler-Befehl NOP (No Operation) und tut einfach nichts einen Taktzyklus lang. Unser vorgegaukeltes Programm besteht also nur aus lauter "Tue Nichts"-Befehlen. Da kann doch eigentlich nciht viel kaputt gehen. Also setzen wir das Datenbyte mit ein paar Jumperkabeln hart auf 1110 1010 bzw. HHHL HLHL (von links nach rechts) und starten die CPU durch Reset neu. ![]() Adresse Daten Bedeutung
EA00 EA Reset-Routine
0100 EA ...
01FF EA ...
FFFC EA Low Byte der Vektor-Adresse FFFC/D holen: EA
FFFD EA High Byte der Vektor-Adresse FFFC/D holen: EA
Sprung zur Vektor-Adresse EAEA (Programm-Counter auf EAEA setzen)
EAEA EA Ausführung des OpCodes NOP (EA), Programm-Counter erhöhen
EAEB EA ...
EAEC EA ...
EAED EA ...
EAEE EA ...
EAEF EA ...
EAF0 EA ...
... ...
FFFF
Nach sieben Taktzyklen (siehe Taktsignal-LEDs) wird der Adressbus auf den Vektor für den Programmstart 0xFFFC und 0xFFFD gesetzt, um sich die Start-Adresse für das Programm zu holen. Nicht überraschend bekommt die CPU hier zweimal 0xEA und bastelt sich als Startadresse 0xEAEA zusammen. Zu dieser springt sie dann, um das dort hinterlegte Programm auszuführen. Das tut sie, indem sie den Programm-Counter (PC) auf 0xEAEA setzt.Nun führt die CPU das Programm Befehl für Befehl aus. Es findet bei 0xEAEA den Befehl 0xEA (was ein Zufall!) und führt ihn aus, sprich: dreht eine Runde Däumchen. Danach geht es mit dem nächsten Befehl weiter. Also wieder: PC erhöhen (auf 0xEAEB), den Befehl dort auslesen (ist natürlich wieder 0xEA=NOP) und ausführen. PC erhöhen, NOP, PC erhöhen, NOP, usw. usf. Was in der LED-Anzeige dazu führt, das es wie ein binärer Zähler aussieht. Es wird ja auch der Programm Counter ab 0xEAEA hochgezählt. Okay, die CPU funktioniert schon einmal. Wenn auch leider nicht ganz so, wie erhofft. Bei dem Abschnitt Datasheet, Abschnitt 3.8: Phase 2 In (PHI2), Phase 2 Out (PHI2O) and Phase 1 Out (PHI1O) Phase 2 In (PHI2) is the system clock input to the microprocessor internal clock. During the low power Standby Mode, PHI2 can be held in either high or low state to preserve the contents of internal registers since the microprocessor is a fully static design.hatte ich mir eigentlich vorgestellt, dass auch der Adressbus erhalten bleibt, denn das ist ja das Result aus dem Programm Counter und das ist ja schließlich ein Register. Aber leider verliert mein W65C02S8P-10 aus China nach einer bis zwei Sekunden das Gedächtnis und der Adressbus flackert zuerst und löscht dann alle Bits. Was dann zu einem Zwangsreset führt, sprich: wenn der Takt unter ein Hertz sinkt, dann stürzt die CPU ab und führt einen Zwangs-Reset aus. Nun bin ich mir nicht sicher, ob das daran liegt, dass ich einen alten "-10"-Chip habe, aktuell sind ja "-14"-Chips mit max. 14 MHz Takt und es bei den alten Chips noch nicht das "static design" gab. Oder ob es doch nur ein umgelabelter 6502 ist, den ich da aus China bekommen habe. Oder ob WDC in dem Absatz Werbesprech benutzt und das Design nicht so "static" ist, wie ich das auffasse. Um herauszubekommen, ob ich einen WDC-Chip habe und keinen umgelabelten Rockwell oder sonstigen Hersteller, habe ich einmal den Opcode 0xCB (0b1100 1011) = WAI (Wait for Interrupt), den eigentlich nur der WDC beherrschen sollte, kodiert. Bei einem Original WDC sollte dann auch RDY (Pin 2) auf Low gezogen werden, was die Ready-LED einschalten sollte. Bleibt die LED aus, hab ich wohl einen Fake (oder auch dieses Feature war in der "-10"-Version noch nicht implementiert). ![]() Adresse Daten Bedeutung
CB00 CB Reset-Routine
0100 CB ...
01CF CB ...
01CE CB ...
FFFC CB Low Byte der Vektor-Adresse FFFC/D holen: CB
FFFD CB High Byte der Vektor-Adresse FFFC/D holen: CB
Sprung zur Vektor-Adresse EAEA (Programm-Counter auf EAEA setzen)
CBCB CB Ausführung des OpCodes NOP (EA), Programm-Counter erhöhen
CBCD CB ...
CBCE CB ...
... ...
FFFF
Der OpCode CB wird also als NOP behandelt. Damit ist immer noch nicht raus, ob ich einen Fake oder einfach nur ein altes Modell, das weniger kann, habe. Denn WDC behandelt (in der neueren Version und hat es wahrscheinlich auch in der alten) alle illegalen OpCodes als NOPs.Der Rockwell R65C02 würde den OpCode 0xCB als illegale Instruktion ausführen wollen und wahrscheinlich abstürzen. Hier ein Auszug aus dessen Datenblatt: ![]() Alte Datenblätter von einem "-10"-WDC-Modell habe ich nicht finden können. Entweder existieren sie nicht (weil Fake), oder wurden gelöscht, weil das Produkt abgekündigt wurde. Ich glaube, so richtig Gewissheit bekomme ich nur, wenn ich einen neuen "-14" über den offizielle Distributor Mouser bestelle, was ich dann wohl mal machen werden. Denn jetzt bin ich echt neugierig geworden. Abschließend noch ein Video, in dem ich noch einmal den Anschluss des Prozessors und des Adress- und Datenbuses erkläre: ![]() Oder ich bastle eine Arduino-basierte, nicht so flüchtige Ausgabe. Jedesmal Video machen und "durchblättern" für die Analyse nervt doch ein wenig. Inzwischen ist die Mouser aus den USA bestellte echte WDC W65C02 CPU eingetroffen, die so funktioniert, wie sie soll. |