Kleine Hardwarekunde

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

Da Assembler (wird von mir hin und wieder auch ASM abgekürzt) eine sog. Maschinennahesprache ist, sind zumindest grundlegende Einblicke in die Hardware unumgänglich!infoHinweisDie Infos dieser Seite sind, neben den ASM-Befehlen, die Basis für jede weitere Programmentwicklung! Dazu schauen wir uns mal grob an, wie der C64 aufgebaut ist und wie der Speicher unterteilt wird.

 

Das Innenleben des C64

Sehr vereinfacht kann man sagen der C64 besteht nur aus einem Mikroprozessor (CPU), der durch einen Taktgeber angetrieben wird, etwas ROM & RAM und einer Ausgabeeinheit (einfach mal Grafik, Sound, Ports usw. zusammengefasst). Alle Komponenten sind mit mehreren Leitungen verbunden (Bus genannt) um sich austauschen zu können.

Bevor wir das im Detail betrachten, könnt ihr dem folgenden Bild entnehmen, wie das ungefähr aussieht.

Das Innenleben des C64.
Das Innenleben des C64.

Fangen wir links beim Taktgeber an.
Wenn die CPU das Gehirn ist, dann ist der Taktgeber das Herz. Er gibt an, wie schnell die CPU Daten verarbeiten kann. Um diesen Takt zu bilden wird als Basis die  Frequenz des sog. „color carriers„ (Farbträgersignal), der zugrundeliegenden Fernsehnorm, verwendet. Das ist auch der Grund, warum ein amerikanischer (besser gesagt NTSC) C64 schneller läuft als ein europäischer (PAL).
Falls euch die genaue Erklärung interessiert:
Die Frequenz des „color carriers„ Beträgt bei einem PAL-System 4.43361875 MHz (bei NTSC 3.579545 MHz), die Frequenz wird dann mit 4 Multipilziert (da sämtliche Takte im C64 von diesem Ergebnis abgeleitet werden, spricht man auch von „master clock„ / Haupttakt) und anschließend bei PAL durch 18 (bei NTSC durch 14) geteilt. Somit kommt man auf einen Prozessortakt von etwas weniger als 1MHz (ja MHz!) bei PAL nämlich 4.43361875 MHz * 4 / 18 = 985248 Hz und auf etwas über 1MHz bei NTSC (3.579545 MHz * 4 / 14 = 1022727 Hz). Ein NTSC C64 ist also ca. 3,8% schneller als die PAL-Version.

Die CPU (unser Mikroprozessor) ist vom Typ 6510 (wie bereits an anderer Stelle erwähnt eine Abwandlung des damals beliebten 6502). Die CPU führt unser Programm aus und verarbeitet unsere Daten. Sie kann über den 16-Bit breiten Adressbus die anderen Komponenten ansprechen und über den Datenbus Informationen lesen und / oder schreiben. Wer bei den Zahlensystemen aufgepasst hat erkennt, dass man mit den 16-Bit des Adressbusses 65536 verschiedene Zustände bilden kann. Da wir ja Profis sind nehmen wir für 1KB 1024 Bytes (statt 1000 Bytes wie es die Hersteller von Speichermedien machen, damit die Festplatte größer aussieht) so kommen wir auf die bekannten max. 64KB Speicher des C64, dazu unten mehr. Da der C64 ein 8-Bit Rechner ist, beträgt die Breite des Datenbusses ebenfalls 8-Bit, größere Daten könnte er am Stück ja nicht verarbeiten.

Schauen wir uns mal die drei Hauptkomponenten an, mit denen die CPU ‚kommuniziert‚.

  • ROM (Read Only Memorry)
    Dies ist ein Speicher aus dem man nur lesen (read only) kann, daher zeigt in der Grafik der Pfeil nur vom ROM zum Datenbus. Außerdem ist der Speicher nicht flüchtig, d. h. auch wenn der Strom abgeschaltet wird geht der Inhalt nicht verloren. Hier ist z. B. das Betriebssystem gespeichert, damit es nach dem Einschalten sofort zu Verfügung steht.
     
  • RAM (Random Access Memory)
    Dies ist unser eigentlicher Hauptspeicher, der wird auch „Speicher mit wahlfreiem Zugriff„ genannt. Wir können Daten lesen und schreiben (Pfeil zum Datenbus zeigt in beide Richtungen), hier liegen unser Programm und unsere Daten. Allerdings verliert der Speicher bei Stromverlust seinen Inhalt.
     
  • Ein- / Ausgabe (kurz E/A)
    Hiermit sind z. B. der VIC II (Video Interface Adapter / Grafik), SID (Sound) oder auch die Joystick-Ports und die Tastatur gemeint. Also alles was dem Anwender eine Rückmeldung gibt bzw. eine entgegennimmt, daher zeigt auch hier der Pfeil zum Datenbus in beide Richtungen. Wir können damit also unsere Infos auf den Bildschirm bringen oder die zuletzt gedrückte Taste abfragen. Die E/A ist mit einem entsprechenden E/A-Bus verbunden, so kann z. B. auch der Drucker oder die Floppy angesprochen werden.

 

Die CPU im Detail

Nun schauen wir noch etwas tiefer in die Hardware, um genau zu sein, wir schauen in die 6510 CPU. Dieser Absatz ist meiner Meinung nach der wichtigste auf dieser Seite! Ihr braucht dieses Verständnis, um die folgenden Seiten überhaupt verstehen zu können!

Das Innenleben des 6510 Prozessors.
Das Innenleben des 6510 Prozessors.

Der wichtigste Baustein der CPU ist die ALU (Aritmetic Logical Unit). Diese ist für Rechen- und Logik-Operationen zuständig. Die ALU greift dabei auf den Akkumulator zurück und legt das Ergebnis auch dort ab.
Der Akku ist eins von 6 Registern die mit einer Ausnahme jeweils 8-Bit aufnehmen können. Der Akku wird von uns am häufigsten verwendete werden, wir benötigen ihn z. B. zum Rechnen oder für boolsche Operationen.
Neben dem Akku gibt es noch zwei ähnliche Register, das X- & Y-Indexregister. Diese werden häufig für besondere Adressierungsarten (indizierte Adressierung) oder für Schleifen benützt.
Der (Stapel)StackPointer (SP) zeigt auf den zuletzt auf dem Stack (Stapel) abgelegten Wert. Der Stack dient zum kurzfristigen zwischenspeichern von Werten. Ihr könnt ihn euch z. B. als einen Stapel Bücher vorstellen. Das zuletzt oben auf den Stapel gelegte Buch, wird auch immer als erstes wieder entfernt, dies wird LIFO = LastIn/FirstOut-Prinzip genannt. Er hat eine größe von 256 Bytes.
Der ProgramCounter (PC / Programmzähler) ist die eben erwähnte Ausnahme und ist 16-Bit breit. Damit lassen sich die kompletten 64 KByte des C64 adressieren. Er zeigt immer auf die nächste Anweisung, die ausgeführt werden soll. Wie ihr in der Grafik seht, habe ich den Adressbus in ein Low- & High Byte getrennt. Das liegt daran, dass die Adressen in ein ‚hohes‚ und ‘niedriges‚ Byte getrennt werden. LSB (Least Significant Byte) und MSB (Most Significant Byte) sind hier die Begiffe, die uns häufig begenen werden. Werden lsb und msb kleingeschrieben, so bezieht es sich auf Bits statt Bytes. Das LSB wird im Speicher zuerst abgelegt, das sehen wir uns später bei den Befehlen noch genauer an.
Das StatusRegister (SR) ist unsere Informationszentrale, hier können wir z. B. erkennen, ob das Ergebnis einer (Rechen)Operation negativ war. Von seinen 8-Bit werden aber nur sieben benutzt.

Die Wichtigkeit diese Registers kann man daran erkennen, dass es eigene Befehle zum Setzen, Löschen, Prüfen und sogar zum ‚Retten‚ auf dem Stack gibt. Das sehen wir alles gleich bei den Assemblerbefehlen.

Das wären also die ‚wichtigsten‚ Bestandteile unseres C64, schauen wir uns nun den Speicheraufbau an.

 

Speicheraufbau des C64

Den Speicher können wir uns zunächst als eine Straße mit 65536 Hausnummern (von 0 bis 65535) vorstellen. Jedes Haus steht dabei für ein Byte des Speichers. Es gibt hier allerdings nicht nur eingeschossige Häuser, sondern auch welche mit zwei oder gar drei Etagen. So wie wir eine Adresse benötigen, um ein bestimmtes Haus in einer Strasse zu finden, so benötigen wir auch die (Speicher)Adresse, um z. B. etwas ins RAM zu schreiben oder um von dort zu lesen. Da unser Computer nur eine Strasse hat, reicht uns als Adresse die Hausnummer.

Sehen wir uns den Aufbau einfach mal an:

Speicheraufbau des C64
Speicheraufbau des C64 – Die Speicheradressen geben immer den Beginn des jeweiligen Blocks an, es sei denn sie stehen ganz rechts am Ende. Bei Bedarf sind auch von / bis Angaben zufinden.

Ganz oben in hellblau seht ihr den kompletten Adressraum des C64 (64 KBytes). Die gesamten 64 KByte des C64 werden in sog. Pages (Seiten) zu je 256 Byte unterteilt. Die Pages sind von 0 bis 255 durchnummeriert und beginnen mit der sog. „Zero Page„. Wir kommen somit also auf 256 Pages x 256 Bytes = 65536 Bytes = 64 KBytes. Der Speicher sieht zunächst schön ‚glatt und einfach‚ aus, aber er steht uns normalerweise nicht vollständig zur eigenen Verfügung. Die bunten Kästchen im unteren Teil der Grafik zeigen, was sich wo befindet, da ist dann schon mehr los.

Die Adressen werden im Laufe der Zeit sehr wichtig, weil wir festlegen müssen wo unser Programm und unsere Daten gespeichert werden oder wo wir z. B. den Bildschirmspeicher finden, um einen Text auszugeben.

Da wir in Assembler programmieren, werde ich ab jetzt nur noch die hexadezimale Schreibweise für die Adressen verwenden.

$0000 – $03FF: Das erste KByte ist für die CPU reserviert und beginnt, wie eben erwähnt, mit der Zero-Page ($0000 – $00FF). Hier lässt sich das Verhalten des C64 beeinflussen und lassen sich aktuelle Status abfragen. In Page-1 ($0100- $01FF) legt der Stack seine Daten ab. Wir sollten also sehr vorsichtig sein, wenn wir im ersten KByte unsere Programme oder Daten  ablegen wollen.

$0400 – $07FF: Hier liegt (sofern er nicht verschoben wurde) der Bildschirmspeicher. Den haben wir z. B. im BASIC- <=> Assemblervergleich benutzt. Der Bildschirm besteht bekanntlich aus 40 Zeichen x 25 Zeilen, also 1000 Bytes. Das KByte für den Bildschirmspeicher wird ab $07F8 durch acht Register für die Sprites vervollständigt, dort wird der Speicherbereich für die Spritedaten eingetragen (vgl. BASIC-Demo: Sprites).

$0800 – $9FFF: Dort befindet sich das BASIC-RAM, also der Speicher in dem unsere eingetippten BASIC-Programme und -Daten landen. Da BASIC normalerweise nicht auf den freien RAM-Bereich von $C000 – $CFFF zugreifen kann, wisst ihr nun auch, wie die Meldung 38911 BASIC BYTES FREE nach dem Einschalten des C64 zustande kommt. Den Bereich des BASIC-RAMs können wir durchaus für unsere Assembler-Programme benutzen, das macht z. B. das ASM-Programm aus dem BASIC- <=> Assemblervergleich. Es speichert ab $0801 den BASIC-Kopf (2013 SYS 2064) und das eigentliche ASM-Programm beginnt dann bei ($0810 => 2064). Würden wir nach dem Laden des Programmes z. B. noch weitere BASIC-Zeilen eintippen, so würde unser Programm wieder überschrieben werden.

$A000 – $FFFF: Diesen Speicherbereich können wir ebenfalls nutzen, allerdings beginnen hier auch die Häuser mit zwei oder drei Etagen.
Die in diesen Bereich einblendbaren Komponenten sind:

  • $A000 – $BFFF: Hier wird das BASIC ROM (nicht mit dem BASIC-RAM ab $0800 verwechseln) eingeblendet. Es enthält fast das komplette BASIC des C64, da das BASIC mehr als 8 KBytes benötigt, finden wir den Rest ab $E000 im Kernal ROM.
  • $C000 – $CFFF: Endlich ein freier Speicherbereich, den wir unter ASM einfach verwenden können, das BASIC kann hierauf nur mit PEEK & POKE zugreifen.
  • $D000 – $DFFF: Die Ein- / Ausgabe teilt sich diesen Speicherbereich mit dem Zeichen ROM s. nächster Hauptpunkt. Wie die Grafik zeigt, teilen sich mehrere Ein- / Ausgaben diesen Speicher.
    • $D000 – $D3FF: Die Register für den Grafikchip VIC II sind hier zu finden. Wir haben diese schon bei den Sprites verwendet, einige Register stehen als Kommentar in den REM-Zeilen des Abschluß-Listings. Da es insg. ‘nur‚ 46 Register gibt, ist der Bereich von $D02F – $D3FF unbenutzt.
    • $D400 – $D7FF: Der Soundchip SID hat hier sein Zuhause. Auch hier werden nur wenige Speicherstellen (nämlich die ersten 28) vom Standard C64 benutzt.
    • $D800 – $DBFF: Um den Zeichen auf dem Bildschirm eine Vordergrundfarbe zuzuweisen, wird das hier beheimate Farb-RAM verwendet. Da wir ja wissen, dass der Bildschirm (BS) nur 1000 Zeichen (40 x 25) benötigt, erkennen wir direkt, dass 24 Bytes unbenutzt sind. Für die Vordergrundfarbe setzten wir das ‚untere‚ Nibble. Die Hintergrundfarbe lässt sich nicht für jedes einzelne Zeichen setzen. Man kann diese Farbe nur für je 64 Zeichen seperat angeben.
    • $DC00 – $DCFF: Der C64 besitzt zwei CIA-Chips (Complex Interface Adapter). Der erste wird als CIA-1 (wat ne Überraschung) bezeichnet. Seine Register sind hier zu finden. Der CIA-1 kümmert sich z. B. um die Tastatur, Joysticks, Datasette, Userport, IRQ-Steuerung (Interrupts) und Paddles.
    • $DD00 – $DDFF: Die Aufgaben des CIA-2 sind z. B. die RS-232-Schnittstelle, der Userport, die NMI-Steuerung und die VIC-II Speicheradressierung.
    • $DE00 – $DFFF: Dieser Bereich ist frei und für Erweiterungen gedacht.
  • $D000 – $DFFF: Es ist kein Tippfehler, dieser Speicherbereich ist tatsächlich dreifach vergeben: RAM, E/A und das CHAR (Zeichen) ROM, hier sind die beiden Standard-Zeichensätze des C64 hinterlegt. Jeder Zeichensatz besteht aus 256 Zeichen, jedes Zeichen aus 8×8 Pixeln (Bildpunkten), also ein Byte je Zeile. Somit kommen wir auf die 4 KByte (2 x 256 x 8), die hier belegt sind.
  • $E000 – $FFFF: Das Kernal ROM ist vergleichbar mit dem BIOS von PCs. Hier finden wir die Kernel-Routinen (Systemroutinen), die wir von Assembler direkt anspringen können und die uns das Leben leichter machen können. Außerdem ist hier alles zufinden, was der Rechner z. B. nach dem Einschalten oder nach einem RESET machen soll. Wie erwähnt, ist zunächst der Rest des BASIC-ROMs von $E000 – $E4D2 gespeichert, ab $E4D3 bis $FFFF kommen dann die Kernel-Routinen.

So nun wissen wir, wie der Speicher aussieht, aber was soll dass mit der Doppelt- oder gar Dreifach-Belegung?
Hier kommen wir endlich auf den Hauptunterschied zwischen dem 6502 und unserem 6510. Diese Mehrfachbelegung, von Speicherbereichen, beherrscht nur der 6510. Über das zweite Byte der Zero-Page (an der Adresse  $01) lassen sich die einzelnen Speicherbereiche umschalten (bankswitching).
Auch das erste Byte (Adr. $00 / 6510 On-Chip I/O Data Direction Register) findet man in dieser Form nur beim 6510. Auf die Zero-Page werden wir später zurück kommen, sie spielt bei der Programmierung dieser Prozessoren ein besondere Rolle.

Da es so schön zum Thema passt, hier ein Leserbrief (zum Unterschied zwischen dem 6502/6510) aus der ‚Compute!‚, einem ‚alten‚ US-Magazin:

Compute! #52
Compute! #52, September 1984, Seite 18

Über die Zero-Page, an der Adresse $0001, lassen sich die einzelnen ROMs  oder das RAM in den entsprechenden Speicherbereich einblenden.

Ihr könnt euch also durch ein „POKE 1, PEEK(1) AND 252″ das gesamte RAM des C64 sichern, nur geht dann leider gar nichts mehr, ein RESET ist fällig, aber bis dahin gehören die 64 KByte euch 😉 .
Um mal wieder auf die Zahlensysteme zu verweisen (ja ich nerve, aber ich kann es nicht oft genug betonen: Die sind immens wichtig!): Wie kann uns der gesamte Speicher gehören, wenn wir doch nur die Bits 0 und 1 auf Null setzen und somit nur BASIC und KERNAL-ROM ausblenden? Dies liegt daran, dass das E/A-ROM auch automatisch ausgeblendet wird, sobald man die ersten beiden Bits auf 0 setzt. Nur der Vollständigkeit wegen, auch wenn Bit 1 offiziell nur das KERNAL-ROM ausblendet, wird automatisch ebenfalls das BASIC ROM deaktiviert.
Was nützt es uns nun, diese ROMs auszublenden, wenn man dann doch nichts mehr mit dem Rechner anfangen kann? Nun wir müssen nur dafür sorgen, dass das entsprechende Programm auch ohne die ROMs auskommt oder wir können z. B. vor dem Abschalten das ROM ins darunterliegende RAM kopieren. Dies eröffnet uns dann zusätzlich die Möglichkeit die Kopierten ROM-Inhalte (die liegen jetzt ja im RAM und sind somit nicht mehr ‘schreibgeschützt‚) zu verändern, wir können aber auch nicht benötigte Teile überschreiben, um mehr Speicherplatz zu haben.

Ich hoffe ihr bleibt weiter am Ball, denn als Nächstes legen wir endlich mit dem Programmieren los und schauen uns in Ruhe alle Assemblerbefehle (Mnemonics) an. Aber keine Angst, es wird keine Trockenübung!! Wir werden viele Beispiele im Emulator unter die Lupe nehmen.


Schrott!!Naja...Geht so...Ganz gut...SUPER! (33 Bewertungen | Ø 4,70 von 5 | 93,94%)

Loading...


 

<<< zurück | weiter >>>

 

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

2 Gedanken zu „Kleine Hardwarekunde“

  1. Im Speicheraufbau steht, wenn ich das richtig sehe, eine falsche Adresse für den Beginn der Spritesteuerung. Dort steht ab $07E8 beginnt der acht Byte breite Bereich. Es müsste aber wohl $07F8 sein.
    Das hat mich erst etwas verwirrt, daher der Hinweis zur Korrektur.

Schreibe einen Kommentar


Beachtet bitte, dass ich eure Kommentare erst manuell freigegeben muß, bevor sie auf der Seite erscheinen! Da ich nicht pausenlos am Rechner sitze, kann es schon mal etwas dauern, bis ein Kommentar für alle sichtbar ist.

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

Protected by WP Anti Spam