Ich hatte vor geraumer Zeit etwas ausführlicher mit einem Z80 zu tun. Dabei habe ich mir den Spaß gemacht und per 40-Kanal-Logikanalayser das folgende Programm untersucht: RAM Code Label ASM-Code Kommentar 0x1000 06 02 LA1000: LD B,0x02 B=2 0x1002 10 FE LOOP: DJNZ LOOP B-- und Loop bis B=0 0x1004 18 FA JR LA1000 relativer Sprung Die Idee hinter dem Test: Im ersten DJNZ-Durchlauf wird B=1 sein, also muss (zu LOOP) gespungen werden. Im M1-Zyklus (4 Takte) des DJNZ wird der DJNZ erkannt und damit auch, dass im Speicher noch der 1-Byte-Wert (in 0x1003) der relativen Sprungweite folgt. Demnach wird der PC (Programcounter) auf aktuellerPC+2=0x1004 gesetzt. Danach liest er, weil er springen muss, den Parameter 0xFE = -2 ein und springt entsprechend relativ zu PC-2, also zu 0x1002. Soweit klar. Im zweiten DJNZ-Durchlauf wird B=0 gelten, also wird nicht gesprungen und das Programm bei PC=0x1004 fortgesetzt werden. Ich wollte nun herausfinden, ob der Prozessor dennoch die in 0x1003 gespeicherte Sprungweite auslesen wird oder nicht. Genau das wollte ich mit dem Analyser herausfinden. Und zur Hölle noch mal, er tut es tatsächlich! Er legt 0x1003 auf den Adressbus, setzt das RD-Signal und erhält den Inhalt 0xFE über den Datenbus geliefert. Warum tut er das? Wenn der Prozessor schon so intelligent ist und unterscheiden kann, ob er springen muss oder nicht, warum liest er dann Parameter vom Speicher, die er gar nicht braucht? Der PC wird schon im M1-Zyklus, also bevor die relative Sprungweite vom Speicher gelesen wird, auf 0x1004 geändert. Es ist also nicht nötig irgendwelche Zeit zu verplempern oder auf etwas zu warten, er könnte am Ende des M1 sofort bei 0x1004 weitermachen. Zur Info: Mit Sprung brauch DJNZ 13 Takte, ohne Sprung nur 8. Es ist also sowieso unterschiedlich, da könnte man doch den 8-Takt-Teil deutlich bis zu einem DEC B reduzieren, der nur 4 Takte braucht, da ein DJNZ bei Nichtsprung nicht mehr ausführen muss als ein DEC B. Also warum nicht 13 Takte mit Sprung und 4 ohne? Kann es mir jemand erklären?
Andi $nachname schrieb: > Warum tut er das? Weil der Z80 ein Design aus den 70-er Jahren ist und damals Dinge wie Branch Prediction noch unbekannt waren? Weil damals Siliziumfläche teuer war? Weil man damals einen Van Neumann Zyklus (Befehl holen - Befehl dekodieren - Befehl ausführen) noch ernst nahm und Befehls-Pipelining noch in den Kinderschuhen steckte? > Also warum nicht 13 Takte mit Sprung und 4 ohne? Weil ein Vergleich auf 0 auch Takte benötigt? Warum hat ein Original Fiat 600 keine elektrischen Fensterheber?
Karl Heinz Buchegger schrieb: > Andi $nachname schrieb: > >> Warum tut er das? > > Weil der Z80 ein Design aus den 70-er Jahren ist und damals Dinge wie > Branch Prediction noch unbekannt waren? Ich kenne das auch nicht und mir ist die Übrlegung auch nur durch "gesunden Sachverstand" in den Sinn gekommen. Da müssten doch Prozessordesigner/-entwickler auch in den 70er schon so clever gewesen sein, dass ihnen das auffallen würde! > Weil damals Siliziumfläche teuer war? Man könnte den 8-Takt-Bereich stattdessen weglassen, würde vermutlich sogar Silizium sparen. > Weil man damals einen Van Neumann Zyklus (Befehl holen - Befehl > dekodieren - Befehl ausführen) noch ernst nahm und Befehls-Pipelining > noch in den Kinderschuhen steckte? Mit Pipelining hat das, ich bin da Laie, ja mal gar nichts zu tun! >> Also warum nicht 13 Takte mit Sprung und 4 ohne? > > Weil ein Vergleich auf 0 auch Takte benötigt? Wann erfolgt denn der Vergleich, im M1 oder später?
Und warum war am ersten Computer, an dem ich gearbeitet habe, ein 256k-Speicher ein 2m hoher 19-Zoll-Schrank mit kleinen magnetischen Ringen? Gewisse Fortschritte hat es seither schon gegeben, so kannst du z.B. deinen Z80-Code heute auf einem Zilog-eZ80 viel effektiver ausführen. Gilt auch für anderes Urgestein wie z.B. 8051er-Architektur, vom 8086er garnicht zu reden. Gruss Reinhard
Andi $nachname schrieb: > Karl Heinz Buchegger schrieb: >> Andi $nachname schrieb: >> >>> Warum tut er das? >> >> Weil der Z80 ein Design aus den 70-er Jahren ist und damals Dinge wie >> Branch Prediction noch unbekannt waren? > > Ich kenne das auch nicht und mir ist die Übrlegung auch nur durch > "gesunden Sachverstand" in den Sinn gekommen. Da müssten doch > Prozessordesigner/-entwickler auch in den 70er schon so clever gewesen > sein, dass ihnen das auffallen würde! In der Zeit war man froh, wenn man einen µP hatte, den man verkaufen konnte! Jaaaa, das ist alles noch nicht so lange her und jaaaaa, damals steckte noch vieles in den Kinderschuhen! Das waren die 'Sturm und Drang' Jahre. Denkst du echt, das hätte irgendjemanden interessiert, ob ein DJNZ jetzt in einem speziellen Fall 6 (oder 4) statt 8 Takten gebraucht hätte? Ein durchschittliches Programm wäre dadurch noch nicht einmal um 1 tausendstel Prozent schneller geworden. Die Taktfrequenz von 2.4Mhz auf 3Mhz steigern zu können (was technologisch schon eine Herausforderung war), bringt viel mehr. Und zwar ohne dass der Chefentwickler die Befehlsauwertung überarbeiten muss, an der er vorher 2 Jahre gesessen ist.
Andi $nachname schrieb: > Also warum > nicht 13 Takte mit Sprung und 4 ohne? Kannst du so gar nicht rechnen, da der PC in jedem Falle erhöht werden muss, dass ist schon ein zusätzlicher Rechenschritt auch bei B=0. Wie Karl Heinz schon schrieb hat man sich da in den 70ern gerne die extra Schaltung gespart und halt was gelesen und verworfen. Es gibt, falls dich das näher interessiert, von Zilog eine Beschreibung der M- und T-Zyklen und was da im Einzelnen passiert. Hättest übrigens gar nicht nachmessen müssen ;-) http://www.z80.info/z80ins.txt Mark
Ehe nun über die dummen Ingenieure der 70er gelästert wird: Damals hatte ein guter Z80 Computer 48kBytes RAM (KILOBYTES, kein Schreibfehler) und in diesen 48k lagen das Disketten-Betriebssystem und eine Textverarbeitung, die automatische Silbentrennung, Blocksatz und Drucken im Hintergrund konnte. Als extra Schmankerl brauchte man für jeden Befehl nur maximal 2 Tasten, so dass man 10-Finger-blind schreiben konnte. Und die Kiste war so schnell, dass ich den Tastaturpuffer nicht überschreiben konnte.
Meine Doktorarbeit habe ich damals auf einem Apple II+ kompatiblen Rechner mit Word 1.0/2.0? im "what you see, is what you get" Modus geschrieben. Tabellen dafür mit Multiplan. Man konnte im Prinzip alles damit machen, was man heute auch diesbezüglich machen kann. Und das alles mit den o.a. Hardwareparametern, allerdings "nur" mit einem tollen Bernsteinmonitor(monochrom) und nicht in Farbe und ohne das ganze Makeup, welches heute scheinbar nötig zu sein scheint.
Andi $nachname schrieb: > Und zur Hölle noch mal, er tut es tatsächlich! Das ist nicht weiter erstaunlich. Der Befehl wird in M1 geladen und dekodiert. Danach ist zunächst nur bekannt, dass dieser Befehl ein Displacement hat. Es ist aber noch nicht bekannt, ob gesprungen wird oder nicht. Diese Entscheidung fällt während dem Fetch vom Displacement. Details zum internen Aufbau und dem Ablauf beim Z80: http://www.msxarchive.nl/pub/msx/mirrors/msx2.com/zaks/z80prg02.htm
> Und die Kiste war so schnell, dass ich den Tastaturpuffer nicht > überschreiben konnte. Ja, waren schoene Zeiten damals. Heute geht das leider nicht mehr. Es passiert mir gelegentlich das ich schneller tippe wie Word(Microscheisse) auf Betriebssystem Win7(Microscheisse++) mit laufenden Virenscanner. Aber das ist nicht so schlimm wie es jetzt klingt. Heute kann ja kaum noch einer mit 10Fingern tippen und es gibt sogar Leute die nehmen ihre Haende bei der Textverarbeitung von der Tastatur um eine Maus zu bedienen. :-D Olaf
Andi $nachname schrieb: > irgendwelche Zeit zu verplempern oder auf etwas zu warten, er könnte am > Ende des M1 sofort bei 0x1004 weitermachen. Geht nicht. Der PC kann in der Implementierung von Zilog nur um 1 inkrementiert werden, nicht um 2.
Olaf schrieb: > und es gibt sogar Leute die nehmen ihre > Haende bei der Textverarbeitung von der Tastatur um eine Maus zu > bedienen. :-D Die wurde ja auch erfunden, damit auch Leute, die sich mit dem Computer nicht auskennen, damit arbeiten können. Heute arbeiten alle mit der Maus ... Mein Opa hat mich damals™ gefragt, wozu ich einen Computer brauche, ich wäre doch keine Firma ... ;-) @TO: Entwirf einen Prozessor, der besser ist und der damals machbar gewesen wäre. Dann darfst Du wieder kommen und meckern. Gruß Jobst
Überflussige Abläufe waren damals völlig normal. Ein 16-Bit Zeitgenosse der Z80 CPU, die 9900 von Texas Instruments, hat den Ablauf von im Format gleichen MOV und ADD Befehlen auch völlig gleich gestaltet. Dies sah folglich ungefähr so aus: temp1 = destination memory location temp2 = source memory location temp3 = temp1 <op> temp2 destination memory location = temp3 Bei einem ADD ist das in Ordnung, aber der MOV Befehl hat dadurch völlig überflüssig den überhaupt nicht verwendeten und ohnehin gleich überschrieben Zieloperand erst aufwendig gelesen. Das geschah einzig zur Reduzierung des Aufwands. Er ersparte eine komplexere Ablaufsteuerung. Busleitungen zur Auswahl des zu schreibenden Byte vom Bus wurden überflüssig, da dieser Ablauf bei Byteoperationen das andere Byte schlicht durchreicht.
A. K. schrieb: > Das geschah einzig zur Reduzierung des Aufwands. Er ersparte eine > komplexere Ablaufsteuerung. Genau das war's auch beim Z80. Es gab noch kein Microcode ROM für die Befehle und daher wurde Orthogonalität im Ablauf jedweder Ausnahme vorgezogen.
WIMNI hat der Z80 eine 4-Bit ALU, braucht also allein für den Decrement schon 2 Takte.
Andi $nachname schrieb: > Zur Info: Mit Sprung brauch DJNZ 13 Takte, ohne Sprung nur 8. Es ist > also sowieso unterschiedlich, da könnte man doch den 8-Takt-Teil > deutlich bis zu einem DEC B reduzieren, der nur 4 Takte braucht, da ein > DJNZ bei Nichtsprung nicht mehr ausführen muss als ein DEC B. Also warum > nicht 13 Takte mit Sprung und 4 ohne? Weil auch der DEC B eigentlich 6 Taktzyklen braucht. Nur: beim DEC B wird während den letzten beiden Taktzyklen bereits mit dem Lesen des nächsten Befehls begonnen. Diese beiden Taktzyklen "verschwinden" hinter den ersten beiden Taktzyklen des nächsten Befehls (siehe bei http://www.msxarchive.nl/pub/msx/mirrors/msx2.com/zaks/z80prg02.htm, Abbildung 2.25). Beim DJNZ läuft in den Taktzyklen 5 und 6 der DEC B-Anteil, gleichzeitig wird in den Taktzyklen 5 bis 8 der Offset gelesen. Wurde B durch das DEC zu 0, so war es das, und der nächste Befehl wird gelesen. Wurde B nicht 0, wird in den Taktzyklen 9 bis 13 der PC-Wert nach dem Sprung berechnet. Dieses Überlappen von Prefetch und Execute entspricht im übrigen einer Pipeline der Länge 1 und ist auch heute noch aktuell - sowohl die AVR- wie die PIC-Prozesssoren verfahren heute noch so....
Hi Heutige Architekturen (insbesondere die mit ganz viel Rechen- und Wärmeleistung) führen noch viel mehr "unnötige" Befehle und Speicherzgriffe durch. Alles um die Pipeline immer schön gefüllt zu halten. Matthias
Ein Leo schrieb: "WIMNI hat der Z80 eine 4-Bit ALU". Ich kenne zwar keinen WIMNI aber Du irrst dich hier. Der Z80 hat(te) eine 8-Bit ALU. WIMNI setzen sechs. Der Z80 war zu seiner Zeit "State of the Art", Heutige Prozessoren werden in 40 Jahren auch nur belächelt werden. Sowas nennt man allgemein Fortschritt der Technik. RIP (Rest in peace) Z80!
> Es gab noch kein Microcode ROM für die Befehle und daher wurde > Orthogonalität im Ablauf jedweder Ausnahme vorgezogen. Es gab keinen Microcode mehr. Das war ja der Geschwindigkeitsvorsprung des Z80 zum 8080/85, der mit Microcode lief. Bei Z80 war alles festverdrahtet. Da der Z80 die IX und IY-Befehle per Prefix auf die HL-Befehle gelegt hat, war es auch möglich, die eigentlich offiziell nicht zugreifbaren 8-Bit-Bestandteile vonn IX/IY über die Befehle mit H bzw. L zu machen. War halt einfach unvollständig ausdekodiert...
Μαtthias W. schrieb: > Heutige Architekturen (insbesondere die mit ganz viel Rechen- und > Wärmeleistung) führen noch viel mehr "unnötige" Befehle und > Speicherzgriffe durch. Aber die tun es um schneller zu sein. Die damaligen wurden dadurch langsamer.
Georg A. schrieb: > Es gab keinen Microcode mehr. Das war ja der Geschwindigkeitsvorsprung > des Z80 zum 8080/85, der mit Microcode lief. Bei Z80 war alles > festverdrahtet. Microcode war im Kontext der 70er und 80er nicht notwendigerweise langsamer als hardwired. 68000 und Z8000 kamen ungefähr zur gleichen Zeit. Die 68000 war in 2 Ebenen microcoded, die Z8000 hardwired. Die 68000 war schneller. Bist du sicher, dass 8080/85 microcoded waren?
Leichenschänder schrieb: > Ich kenne zwar keinen WIMNI aber Du irrst dich hier. Der Z80 hat(te) > eine 8-Bit ALU. Belege? Ich neige eher dazu, jenen Leuten zu glauben, die das Ding konstruiert haben: "One-phase clock instead of two-phase clock, and 4-bit arithmetic instead of 8-bit arithmetic unit.", "At first I introduced the pipeline 4-bit ALU." (Shima) http://archive.computerhistory.org/resources/access/text/Oral_History/102658073.05.01.acc.pdf
A. K. schrieb: > Andi $nachname schrieb: >> irgendwelche Zeit zu verplempern oder auf etwas zu warten, er könnte am >> Ende des M1 sofort bei 0x1004 weitermachen. > > Geht nicht. Der PC kann in der Implementierung von Zilog nur um 1 > inkrementiert werden, nicht um 2. Da ich in diversen Z80-Büchern schon sehr großen Mist gelesen habe und es auch Professoren gibt, die diesen Mist zitieren, frage ich lieber mal nach: Gibt es das irgendwo mal an einer offiziellen Quelle, keine Fan-Seite, zu lesen, dass der PC nur auf PC+1 aktualisiert werden kann? Das würde im Umkehrschluss ja auch heißen, dass der PC auf ein Datenfeld (beim DJNZ die relative Sprungweite) zeigen kann und er somit auch dort (in Daten) etwas ausführen könnte. Der Z80 müsste ja ein weiteres Register/Flag mitführen um zu wissen, ob der PC gerade PC ist oder ob der PC gerade DP (Datapointer). Nicht? Klar kann ich selber den PC manipulieren und damit in ein Datenfeld springen, aber ein Prozessor sollte das doch nie tun. Andererseits würde das begründen, warum der Z80 bei DJNZ die Sprungweite liest, denn scheinbar ist er "zu blöd" ohne Datenlesen den PC zu aktualisieren. A. K. schrieb: > Georg A. schrieb: >> Es gab keinen Microcode mehr. Das war ja der Geschwindigkeitsvorsprung >> des Z80 zum 8080/85, der mit Microcode lief. Bei Z80 war alles >> festverdrahtet. > > Microcode war im Kontext der 70er und 80er nicht notwendigerweise > langsamer als hardwired. 68000 und Z8000 kamen ungefähr zur gleichen > Zeit. Die 68000 war in 2 Ebenen microcoded, die Z8000 hardwired. Der 6502, ein Jahr vor Z80, war doch hardwareverdrahtet, was ihn, man beachte die Takte pro Befehl, doch sehr schnell machte. Dafür war er etwas eingeschränkt, was die Registervielfalt betrifft, aber irre gut, was die Adressierungsmöglichkeitne betraf. Habe ich zumindest so in Erinnerung.
Andi $nachname schrieb: > Das würde im Umkehrschluss ja auch heißen, dass der PC auf ein Datenfeld > (beim DJNZ die relative Sprungweite) zeigen kann und er somit auch dort > (in Daten) etwas ausführen könnte. Ich verstehe nicht, was du damit sagen willst. Der Z80 war ja eine von Neumann-Archtektur, er unterscheidet also überhaupt nicht zwischen Programm- und Datenspeicher. Selbstverständlich kann Programmcode im (einzigen) RAM ausgeführt werden, siehe Betriebssysteme wie CP/M, und das ist bei DOS heute noch so. Nur Harvard-Prozessoren müssen Klimmzüge dafür machen. Gruss Reinhard
Andi $nachname schrieb: > Fan-Seite, zu lesen, dass der PC nur auf PC+1 aktualisiert werden kann? Das übliche überall verbreitete Blockdiagramm der internen Struktur enthält einen 16-Bit Inkrementer/Dekrementer. Mit +/-1. > Der Z80 müsste ja ein weiteres > Register/Flag mitführen um zu wissen, ob der PC gerade PC ist oder ob > der PC gerade DP (Datapointer). Nicht? Bisschen seltsam formuliert. Es gibt natürlich eine state machine für den internen Ablauf, aus der sich ergibt, ob er grad dabei ist, das Opcode-Byte reinzuziehen, oder irgendwas dahinter. In der von mir oben bereits gezeigten verlinkten Seite ist das klar beschrieben. > Andererseits würde das begründen, warum der Z80 bei DJNZ die Sprungweite > liest, denn scheinbar ist er "zu blöd" ohne Datenlesen den PC zu > aktualisieren. Bei deinem Ansatz würde er mit dem Laden vom Displacement solange warten, bis er weiss, dass er es benötigt. Andernfalls einmal leer inkrementieren. Folge: Der bei diesem Befehl viel wichtigere Fall, nämlich der dass er springt, würde verlangsamt. Nutzeffekt dieser "Optimierung": langsamere Programmausführung. > Der 6502, ein Jahr vor Z80, war doch hardwareverdrahtet, was ihn, man > beachte die Takte pro Befehl, doch sehr schnell machte. Irgendwie muss jemand mal in den Köpfen mancher Leute festgelegt haben, dass Mikroprogrammierung langsam zu sein hat. Wenn die Realität dem widerspricht, dann umso schlimmer für die Realität. Mikroprogrammierung ist - im Kontext 8086/68000/Z8000 betrachtet - in erster Linie eine Richtung in der Abwägung zwischen minimalem Chipstate und minimalem Entwicklungsaufwand. Hardwired reduziert die Anzahl Gatter und Transistoren gegenüber einer mikroprogrammierten Lösung, erhöht aber ohne leistungsfähige Synthetisierungs-Software den Entwicklungs- und Debugging-Aufwand erheblich. Die Dinger wurden damals von Hand gebaut und layoutet. Zilogs Entscheidung, eine CPU der Komplexität der Z8000 hardwired zu entwickeln, war mitentscheidend für deren Misserfolg. Es hat die Entwicklung erheblich verzögert und ursprünglich geplante Features wie ein Instruction-Trace fielen dem zum Opfer (ich hatte mal ein Zilog-Dokument, da stand der noch drin). Zwar ist deren Aufwand, in Transistoren gemessen, weit geringer als 8086 und erst recht 68000, aber andererseits sind stark regelmässige Mikroprogrammstrukturen weit dichter auf dem Silizium, als aufwendige unregelmässige Steuerungslogik. Ich habe übrigens vorhin im Web keinerlei Indiz dafür finden können, dass auch nur irgendeine CPU der 8080/8085/6800 Klasse mikroprogrammiert implementiert wurde. Das Die-Photo der 8080 spricht auch dagegen.
Andi $nachname schrieb: > Der 6502, ein Jahr vor Z80, war doch hardwareverdrahtet, was ihn, man > beachte die Takte pro Befehl, doch sehr schnell machte. Nicht schneller als 6800 im Ablauf, aber einfacher und insbesondere billiger. Und die 6502 war praktikabler - die 6800 hatte ein paar Schwächen im Befehlssatz, die die Programmierung erschwerten.
Wieder mal ein Thread, wo an die Zeit der 8bit-CPUs erinnert wird, als man Computer auch als einfacher Anwender noch voll- ständig verstehen konnte. Wäre doch gut, wenn es so ein Gerät wieder geben würde, vielleicht in mancher Hinsicht ein wenig moderner. Wer diese Ansicht teilt, klicke auf meine Benutzer- seite. Wer mich schon kennt und für aufdringlich hält, braucht es ja nicht zu tun.
Josef G. schrieb: > Wieder mal ein Thread, wo an die Zeit der 8bit-CPUs erinnert > wird, als man Computer auch als einfacher Anwender noch voll- > ständig verstehen konnte. Wäre doch gut, wenn es so ein Gerät > wieder geben würde, Gibt es doch! Mikrocontroller wie PIC, AVR oder MSP430 haben ziemlich exakt die Komplexität diese damaligen Systeme - die PICs erinnern zudem in ihrer etwas eigenwilligen ISA auch an bizarre Prozessorarchitekturen wie SC/MP oder 1802 (die PIC ISA ist ja im Kern ebenso alt wie diese). Nur ist der Kram eben nicht auf einen viertel Quadratmeter Platinenfläche mit vielen einzelnen ICs verstreut, sondern es ist alles auf einem einzigen Chip. Der Unterschied ist eigentlich nur, dass man damals den Kram einzeln aufbauen konnte (musste) und damit ein Verständnis des Aufbaus gewann. Während heute viele den Kram als Blackbox betrachten, ohne die interne Struktur zu kennen. Andererseits kann man heute solche Erkenntnisse mit FPGAs gewinnen und sich mit geringem Aufwand eigene ISAs designed, was damals ziemlich aufwendig war.
A. K. schrieb: > Und die 6502 war praktikabler - die 6800 hatte ein paar > Schwächen im Befehlssatz, die die Programmierung erschwerten. Am schönsten aber war der 6809.
Reinhard Kern schrieb: > Andi $nachname schrieb: >> Das würde im Umkehrschluss ja auch heißen, dass der PC auf ein Datenfeld >> (beim DJNZ die relative Sprungweite) zeigen kann und er somit auch dort >> (in Daten) etwas ausführen könnte. > > Ich verstehe nicht, was du damit sagen willst. Der Z80 war ja eine von > Neumann-Archtektur, er unterscheidet also überhaupt nicht zwischen > Programm- und Datenspeicher. Es geht nicht um von Neumann oder Harvard, sondern einfach darum, dass ein Prozessor in meinen Augen einen PC und einen DP haben sollte. Ich bin bisher davon ausgegangen, dass das jeder Prozessor, unabhängig von der Architektur, hat, auch wenn D und P im gleichen Arbeitsspeicher liegen. Um bei meinem Beispiel (siehe ersten Beitrag) zu bleiben: Der PC würde in meinen Augen nur auf 0x1000, 0x1002, 0x1004 und 0x1006 (letzteres genau dann, wenn der PC aktualisiert wird, bevor der Sprung zu 0xFA = -6 ausgeführt wird) zeigen, weil nur dort eine Programmausführung (Einsprung) möglich ist. Der DP würde dagegen nur auf 0x1001, 0x1003 und 0x1005 zeigen können, wenn die "Daten" vom Prozessor angefordert und geladen werden. Ich muss dazu ergänzen, dass ich in meiner Jugend 6502 (bekantlich von Neumann) in Assembler programiert habe, mich aber dabei nicht mit den Zeigern beschäftigt habe. Später habe ich einen 8051 (bekanntlich Harvard) programmiert, da kann ich mich noch recht genau an die unterschiedlichen D- und P-Befehle erinnern. Beim Z80, mit dem ich mich in diesem Frühjahr beschäftigen musste, wollte ich das jetzt mal genauer wissen. Ich bin davon ausgegangen, dass der PC nur einmal (im M1) und das relativ weit am Anfang der Befehlsausführung aktualisiert wird. Zu dem Schluss bin ich gekommen, weil es beim Z80 I/O-Befehle gibt und ich der Meinung bin, dass er dafür nicht den PC missbrauchen kann, sondern eben der DP dafür, für reien Daten und für alle Opcode-Parameter Verwendung findet. Ansonsten müsste der PC gesichert werden, um die I/O-Anfrage durchzuführen (da muss ja auch eine Adresse angelegt werden, auch wenn sie nur 8 Bit hat) und anschließend muss der PC wiederhergestellt werden, um den nächsten Befehl ausführen zu können. Irre ich mit meinen Vermutungen zum DP beim Z80? Ich bitte um Aufklärung. Kann mir noch jemand sagen, bei genau welchen Takten des DJNZ-Nichtsprungs (8 Takte) der PC aktualisiert wird? Nach den Ausführungen hier im Thread sollte das zwei Mal passieren.
> Es geht nicht um von Neumann oder Harvard, sondern einfach darum, dass > ein Prozessor in meinen Augen einen PC und einen DP haben sollte. Du glaubst garnicht was manche Prozessoren alles nicht hatten. http://de.wikipedia.org/wiki/Texas_Instruments_TMS9900 Olaf
Andi $nachname schrieb: > Reinhard Kern schrieb: >> Andi $nachname schrieb: >>> Das würde im Umkehrschluss ja auch heißen, dass der PC auf ein Datenfeld >>> (beim DJNZ die relative Sprungweite) zeigen kann und er somit auch dort >>> (in Daten) etwas ausführen könnte. >> >> Ich verstehe nicht, was du damit sagen willst. Der Z80 war ja eine von >> Neumann-Archtektur, er unterscheidet also überhaupt nicht zwischen >> Programm- und Datenspeicher. > > Es geht nicht um von Neumann oder Harvard, sondern einfach darum, dass > ein Prozessor in meinen Augen einen PC und einen DP haben sollte. Mir ist absolut nicht klar, was du mit einem DP meinst. Über den PC wird ein Byte eines Befehls geladen. Punkt. Mehr gibt es dazu nicht zu sagen. Besteht der Befehl aus mehreren Bytes, dann wird mit dem PC sukzessive 1 Byte nach dem anderen geladen, bis der Befehl vollständig ist. > Um bei meinem Beispiel (siehe ersten Beitrag) zu bleiben: Der PC würde > in meinen Augen nur auf 0x1000, 0x1002, 0x1004 und 0x1006 (letzteres > genau dann, wenn der PC aktualisiert wird, bevor der Sprung zu 0xFA = -6 > ausgeführt wird) zeigen, weil nur dort eine Programmausführung > (Einsprung) möglich ist. Der DP würde dagegen nur auf 0x1001, 0x1003 und > 0x1005 zeigen können, wenn die "Daten" vom Prozessor angefordert und > geladen werden. Das setzt vorraus, das alle Befehle gleiche Länge oder zumindestens ein Vielfaches dieser gleichen Länge haben. Haben sie aber beim Z80 nicht. Es gibt 1Byte, 2Byte, 3Byte lange Befehle. > Kann mir noch jemand sagen, bei genau welchen Takten des > DJNZ-Nichtsprungs (8 Takte) der PC aktualisiert wird? Nach den > Ausführungen hier im Thread sollte das zwei Mal passieren. Also: Ich hab wirklich viel in Z80 programmiert. Aber das hat mich nun wirklich kein einziges mal interessiert. Die CPU muss ihre Befehle ausführen und wie sie das intern macht, ist ihr Bier. Viel wichtiger ist es, dass man sich merkt welcher Befehl welche Flags beeinflusst.
>>wie sie das intern macht, ist ihr Bier.
...und ich habe mich immer gewundert wofür der kleine Schraubverschluß
sein sollte..;-)
Trotz Gefahr, mich unbeliebt zu machen, weil ich mich nochmal einmische: Anstelle des DJNZ beim Z80 gibt es bei meiner CPU die Möglichkeit, zum Start einer Schleife die Startadresse der Schleife zu sichern, und es gibt Repeat-Befehle mit Zähler- Dekrementieren und Adresse-Inkrementieren/Dekrementieren, die nur einen Vollzyklus dauern.
Andi $nachname schrieb: > weil es beim Z80 I/O-Befehle gibt und ich der Meinung bin, dass er dafür > nicht den PC missbrauchen kann, sondern eben der DP dafür Nein. Die meistverwendeten I/O-Befehle sind "immediate" adressiert, die I/O-Adresse folgt dem Opcode. Kein Register wird dadurch verändert. Gruss Reinhard
A. K. schrieb: >> Wieder mal ein Thread, wo an die Zeit der 8bit-CPUs erinnert >> wird, als man Computer auch als einfacher Anwender noch voll- >> ständig verstehen konnte. Wäre doch gut, wenn es so ein Gerät >> wieder geben würde, > > Gibt es doch! Mikrocontroller wie PIC, AVR oder MSP430 haben ziemlich > exakt die Komplexität diese damaligen Systeme - die PICs erinnern zudem > in ihrer etwas eigenwilligen ISA auch an bizarre Prozessorarchitekturen > wie SC/MP oder 1802 (die PIC ISA ist ja im Kern ebenso alt wie diese). > Nur ist der Kram eben nicht auf einen viertel Quadratmeter > Platinenfläche mit vielen einzelnen ICs verstreut, sondern es ist alles > auf einem einzigen Chip. Witzig, daß Du das sagst. Ich hab mich schon öfter darüber geärgert, daß viele µCs mit ihrer Harvard-Architektur keinen Code aus dem RAM ausführen können und man daher keine Programme "laden" kann. Sonst könnte man mit einem AVR einen richtigen kleinen Homecomputer bauen.
Karl Heinz Buchegger schrieb: > Andi $nachname schrieb: >> Es geht nicht um von Neumann oder Harvard, sondern einfach darum, dass >> ein Prozessor in meinen Augen einen PC und einen DP haben sollte. > > Mir ist absolut nicht klar, was du mit einem DP meinst. Datapointer. > Über den PC wird ein Byte eines Befehls geladen. Punkt. Mehr gibt es > dazu nicht zu sagen. Besteht der Befehl aus mehreren Bytes, dann wird > mit dem PC sukzessive 1 Byte nach dem anderen geladen, bis der Befehl > vollständig ist. Also gibt es keinen DP beim Z80? >> Um bei meinem Beispiel (siehe ersten Beitrag) zu bleiben: Der PC würde >> in meinen Augen nur auf 0x1000, 0x1002, 0x1004 und 0x1006 (letzteres >> genau dann, wenn der PC aktualisiert wird, bevor der Sprung zu 0xFA = -6 >> ausgeführt wird) zeigen, weil nur dort eine Programmausführung >> (Einsprung) möglich ist. Der DP würde dagegen nur auf 0x1001, 0x1003 und >> 0x1005 zeigen können, wenn die "Daten" vom Prozessor angefordert und >> geladen werden. > > Das setzt vorraus, das alle Befehle gleiche Länge oder zumindestens ein > Vielfaches dieser gleichen Länge haben. Quatsch! RAM Code Label ASM-Code Kommentar 0x1000 06 02 LA1000: LD B,0x02 B=2 0x1002 10 FE LOOP: DJNZ LOOP B-- und Loop bis B=0 0x1004 xx NOP 00 oder FF, weiß es gerade nicht 0x1005 18 F9 JR LA1000 relativer Sprung Der PC würde auf 0x1000, 0x1002, 0x1004, 0x1005 und 0x1007 zeigen, der DP auf 0x1000, 0x1003, 0x1006. Die Überlegung ist aber hinfällig, wenn es keinen DP gibt, weil das alles der PC machen muss. >> Kann mir noch jemand sagen, bei genau welchen Takten des >> DJNZ-Nichtsprungs (8 Takte) der PC aktualisiert wird? Nach den >> Ausführungen hier im Thread sollte das zwei Mal passieren. > > Also: > Ich hab wirklich viel in Z80 programmiert. Aber das hat mich nun > wirklich kein einziges mal interessiert. Mich interessiert es aber. Aber du bist da nicht der einzige Desinteressierte, heutige Informatikstudenten interessieren sich auch nur noch für diesen ganzen Prozeduralquark und nicht mehr für das Darunter. Hauptsache die App läuft, ganz egal wie.
Bronco schrieb: > man daher keine Programme "laden" kann. Das kommt drauf an - es geht natürlich nur, wenn Daten und Befehle gleich gross sind, also üblicherweise ein Byte. 12bit-Opcodes kann man eben nicht in den Datenspeicher laden. Beim 8051 geht das, meine 8051-Leiterplatten hatten deshalb einen Umschalter Harvard <-> von Neumann, der (bei v.N.) beide Speicherzugriffe veroderte. Gruss Reinhard
Andi $nachname schrieb: > Karl Heinz Buchegger schrieb: >> Andi $nachname schrieb: >>> Es geht nicht um von Neumann oder Harvard, sondern einfach darum, dass >>> ein Prozessor in meinen Augen einen PC und einen DP haben sollte. >> >> Mir ist absolut nicht klar, was du mit einem DP meinst. > > Datapointer. > >> Über den PC wird ein Byte eines Befehls geladen. Punkt. Mehr gibt es >> dazu nicht zu sagen. Besteht der Befehl aus mehreren Bytes, dann wird >> mit dem PC sukzessive 1 Byte nach dem anderen geladen, bis der Befehl >> vollständig ist. > > Also gibt es keinen DP beim Z80? Wozu soll der gut sein. Ich sehe in deinen bisherigen Argumenten keinen Grund dafür. Die Registerpärchen BC, DE, HL, mit welchen man indirekt laden kann, wirst du ja wohl nicht als Datapointer bezeichnen. >> Um bei meinem Beispiel (siehe ersten Beitrag) zu bleiben: Der PC würde >>> in meinen Augen nur auf 0x1000, 0x1002, 0x1004 und 0x1006 (letzteres >>> genau dann, wenn der PC aktualisiert wird, bevor der Sprung zu 0xFA = -6 >>> ausgeführt wird) zeigen, weil nur dort eine Programmausführung >>> (Einsprung) möglich ist. Ein LD b, (nn) ist ein 3 Byte Befehl. Steht er an der Adresse 0x1000, dann ist der nächste Befehl an 0x1003 > Der DP würde dagegen nur auf 0x1001, 0x1003 und >>> 0x1005 zeigen können, wenn die "Daten" vom Prozessor angefordert und >>> geladen werden. Beim besagten Befehl, steht 0x1000 Opcode 0x1001 Adresse Low Byte 0x1002 Adresse High Byte Wie bringst du das jetzt mit deinem Datapointer in Einklang, der laut deiner Aussage nur 0x1001 bzw. 0x1003 sein kann? Und wie liest der PC von 0x1003 den nächsten Befehl, wenn der doch nur 0x1000, 0x1002 oder 0x1004 sein kann? Ein unbenutztes Byte zwecks Alignment zwischenzuschalten war damals noch keine Lösung. Meine ersten 64 Kilobyte hab ich fpr 120DM gekauft. Speicher war damals schweineteuer so dass jedes Byte wichtig war. >> >> Das setzt vorraus, das alle Befehle gleiche Länge oder zumindestens ein >> Vielfaches dieser gleichen Länge haben. > > Quatsch! > > RAM Code Label ASM-Code Kommentar > 0x1000 06 02 LA1000: LD B,0x02 B=2 > 0x1002 10 FE LOOP: DJNZ LOOP B-- und Loop bis B=0 > 0x1004 xx NOP 00 oder FF, weiß es gerade nicht > 0x1005 18 F9 JR LA1000 relativer Sprung Du musst schon die richtigen Befehle nehmen! Das man mit einer entsprechenden Befehlsauswahl so ziemlich jedes Argument belegen kann, ist trivial. Aber die CPU hat ja noch mehr Befehle, die auch alle irgendwie funktionieren müssen und die in dein 'allgemeines' Schema passen müssen. Ausserdem: sagtest du weiter oben nicht, dass der PC nur auf geraden Adressen sein kann. WIe passt da der JR an 0x1005 dazu?
Karl Heinz Buchegger schrieb: > Andi $nachname schrieb: >> Also gibt es keinen DP beim Z80? > > Wozu soll der gut sein. Ein 8051 kann ihn doch auch gebrauchen. Ja ich weiß dass er eine andere Architektut hat. Ja und, das ist ein Grund aber kein Hindernis einen DP sinnvoll einzusetzen. > Ich sehe in deinen bisherigen Argumenten keinen Grund dafür. Ich habe auch zu wenig Ahnung davon, deshalb habe ich den Thread doch schließlich eröffnet. > Ein > > LD b, (nn) > > ist ein 3 Byte Befehl. Steht er an der Adresse 0x1000, dann ist der > nächste Befehl an 0x1003 > > Beim besagten Befehl, steht > > 0x1000 Opcode > 0x1001 Adresse Low Byte > 0x1002 Adresse High Byte > > Wie bringst du das jetzt mit deinem Datapointer in Einklang? PC erst auf 0x1000, nachdem ein 3-Byte-Opcode erkannt worden ist dann auf 0x1003. DP wird auf 0x1001 gebogen, um L laden zu können, dann auf 0x1002, um H laden zu können. Das klingt für mich plausibel. > Das man mit einer entsprechenden Befehlsauswahl so ziemlich jedes > Argument belegen kann, ist trivial. Aber die CPU hat ja noch mehr > Befehle, die auch alle irgendwie funktionieren müssen und die in dein > 'allgemeines' Schema passen müssen. Allerdings. Scheinbar ist dem so und ich habe eine falsche Vorstellung von der Befehlsabarbeitung beim Z80 bzw. bei von Neumann. > LOL. sich wegen 2 Takten einen abbrechen und dann NOP zwecks Alignment > einführen. Es geht ums Verständnis der Befehlsabarbeitung, falls es dir noch nicht aufgefallen ist.
Der PC wurde direckt durch den Programmablauf gesteuert. Um Daten zu adressieren, standen mehere Register(IX,IY, oder auch die zusammengefassten BC,DE,HL) zur Verfügung. Der Stack wurde durch das Register SP verwaltet. Alle Register konnten jeden Wert zwichen 0 und 65536 enthalten. Bernd
Andi $nachname schrieb: > Karl Heinz Buchegger schrieb: >> Andi $nachname schrieb: >>> Also gibt es keinen DP beim Z80? >> >> Wozu soll der gut sein. > > Ein 8051 kann ihn doch auch gebrauchen. Ja ich weiß dass er eine andere > Architektut hat. Ja und, das ist ein Grund aber kein Hindernis einen DP > sinnvoll einzusetzen. Doch ist es. Wenn aus CPU Sicht nicht zwischen Programmspeicher und Datenspeicher unterschieden wird, braucht kein Mensch einen dezidierten Datenpointer in der CPU der die Datenbytes eines Befehls nachlädt. Er macht die Dinge nur komplizierter, ohne das man etwas dafür bekommt.
> PC erst auf 0x1000, nachdem ein 3-Byte-Opcode erkannt worden > ist dann auf 0x1003. DP wird auf 0x1001 gebogen, um L laden zu können, > dann auf 0x1002, um H laden zu können. Das klingt für mich plausibel. Na die Logik möcht ich aber nicht in Silizium giessen müssen. Da muss also bei jedem Zyklus erst mal der DP auf den Wert PC+1 gesetzt werden. Nur damit man dann über den DP die Teile des Befehls nachladen kann, von einer Adresse die man sowieso schon hat, wenn man den PC einfach nach jedem Ladevorgang um 1 erhöhen würde.
>>Wie bringst du das jetzt mit deinem Datapointer in Einklang? Bein Z80 gibt es dafür die Indexregister IX,IY die machen das was ein Datenpointer ist und noch mehr. sich stur an irgendwelche Namen zu klammer bringt nichts, damals hat das jeder so genannt wie er es für richtig erachtete und um sich von den anderen zu unterscheiden. >>Mich interessiert es aber. dann mal Kieser/Meder zu rate ziehen. Da wird Ihnen geholfen. Mit Gruß Pieter
Bernd59 schrieb: > Um Daten zu > adressieren, standen mehere Register(IX,IY, oder auch die > zusammengefassten BC,DE,HL) zur Verfügung. Darum geht es überhaupt nicht. Du bist viel zu weit oben. > Der Stack wurde durch das > Register SP verwaltet. Wen interessiert das hier? > Alle Register konnten jeden Wert zwichen 0 und > 65536 enthalten. Nein wirklich!? Ich stelle hier Fragen die kurz vor der Transistorenebene sind und du willst mir jetzt erklären, dass 2^16 = 65536 gilt. Also manche hier in dem Forum rauschen schon sehr merkwürdiges Zeug.
Pieter schrieb: >>>Wie bringst du das jetzt mit deinem Datapointer in Einklang? > > Bein Z80 gibt es dafür die Indexregister IX,IY die machen das was ein > Datenpointer ist und noch mehr. Diese Aussage ist falsch, soviel Ahnung habe ich davon schon noch! IX und IY sind nicht zwingend nötig für die Abarbeitung von (allen) Befehlen. Edith: Im Beitrag darüber meinte ich natürlich "rauchen".
Karl Heinz Buchegger schrieb: >> PC erst auf 0x1000, nachdem ein 3-Byte-Opcode erkannt worden >> ist dann auf 0x1003. DP wird auf 0x1001 gebogen, um L laden zu können, >> dann auf 0x1002, um H laden zu können. Das klingt für mich plausibel. > > Na die Logik möcht ich aber nicht in Silizium giessen müssen. > Da muss also bei jedem Zyklus erst mal der DP auf den Wert PC+1 gesetzt > werden. Nur damit man dann über den DP die Teile des Befehls nachladen > kann, von einer Adresse die man sowieso schon hat, wenn man den PC > einfach nach jedem Ladevorgang um 1 erhöhen würde. Darf ich mal folgendes Fazit aus dem Thread ziehen: Es gibt kein DP-Register oder irgend so was ähnliches beim Z80. Der PC ist für alle 16-Bit-Adresszugriffe zuständig und er wird immer nur um 1 inkrementiert. Richtig?
Andi $nachname schrieb: > Es geht ums Verständnis der Befehlsabarbeitung, falls es dir noch nicht > aufgefallen ist. Dann schau doch mal in den Zaks. Link wurde oben schon gepostet. A. K. schrieb: > Details zum internen Aufbau und dem Ablauf beim Z80: > http://www.msxarchive.nl/pub/msx/mirrors/msx2.com/zaks/z80prg02.htm Wenn Du dann noch Fragen hast...
Andi $nachname schrieb: > Darf ich mal folgendes Fazit aus dem Thread ziehen: Es gibt kein > DP-Register oder irgend so was ähnliches beim Z80. Der PC ist für _alle_ > 16-Bit-Adresszugriffe zuständig den Terminus "16 Bit Adresszugriff" würde ich streichen. Jeder Opcode wird komplett über den PC geladen, egal aus wievielen Bytes er besteht. > und er wird immer nur um 1 > inkrementiert. Richtig? Genau. (Ausser natürlich bei Jumps, Calls und Returns. Aber das ist ja ohnehin klar)
Andi $nachname schrieb: > Ich stelle hier Fragen die kurz vor der Transistorenebene sind und du > willst mir jetzt erklären, dass 2^16 = 65536 gilt. Nicht so pampig, du bist derjenige der sich hier verrannt hat - du klammerst dich mit wachsender Verzweiflung an einen DP, den du dir ausgedacht hast, den es aber schlichtweg nicht gibt - was du beschreibst, ist der Adressbus, der bezieht seine Werte aber aus ganz verschiedenen Quellen wie dem PC, dem Stackpointer, den Indexregistern oder bei indirektem I/O auch dem Register B. In dem Fall wird eben einfach der Inhalt von B auf die Adressausgänge A0..A7 geschaltet, was soll da ein Datapointer? Nach deiner Theorie müsste der Z80 zum Lesen eines I/O-Befehls den DP auf PC+1 setzen, um die I/O-Adresse zu lesen, dann den DP auf den eben gelesenen Inhalt um den Port zu adressieren, was für ein wirres Durcheinander und wie soll das gehen, den Wert, den der DP adressiert, in den DP lesen? Die Z80-Entwickler haben da weit logischer gedacht. Gruss Reinhard
Leo C. schrieb: > Andi $nachname schrieb: >> Es geht ums Verständnis der Befehlsabarbeitung, falls es dir noch nicht >> aufgefallen ist. > > Dann schau doch mal in den Zaks. Link wurde oben schon gepostet. Er redet von etwas ganz anderem. Es geht um die innere Funktionsweise der CPU. Aus irgendeinem Grund ist er der Meinung, es wäre vernünftig neben dem PC noch einen DP zu haben, mit dem die Operandenbytes eines Opcodes geladen werden sollen. Ich hab keine Ahnung was er sich davon verspricht.
>>Der PC ist für alle 16-Bit-Adresszugriffe zuständig
NEIN!!!!!
Der PC wird für das Lesen des OP-Codes und der eventuell dazugehörenden
Daten verwendet.
16-Bit-Adresszugriffe können auch mit BC,DE,HL,IX,IY,SP gemacht werden.
MfG
Pieter
>Richtig?
NEIN !
Richtig ist lediglich, daß der Z80 kein "DP" Register hat.
Er hat den PC (Program Counter), das ist der Zeiger auf den aktuellen
bzw. nächsten auszuführenden Befehl.
Und er hat ganz viele Register, die bei 8-Bit-Registern entweder
paarweise (BC) (DE) (HL) oder bei 16-Bit-Registern (IX) (IX) als Zeiger
auf Datenzugriffe verwendet werden können. Betrachte doch alle diese als
deinen vermissten "DP" !
Und um von diesen Trivialitäten wegzukommen, solltest du dich mal mit
den wirklich interessanten Dingen am Z80 befassen:
= LDI, LDD, LDIR, LDDR
= EX (SP),HL auch als EX (SP),IX bzw. IY
= RLD
Und (viel) später kommen wir dann noch zur Funktionalität des IM2 Modes,
das sind diese Dinge welche die Fa. intel bis heute nicht kapiert hat.
Soweit die Technologie von 1976.
Karl Heinz Buchegger schrieb: >> und er wird immer nur um 1 >> inkrementiert. Richtig? > > Genau. > (Ausser natürlich bei Jumps, Calls und Returns. Aber das ist ja ohnehin > klar) Und wenn man sich die Blockschaltbilder ansieht, dann findet sich meistens ein Inkrementierer als eigenständige Baugruppe von der es unter anderem Leitungen zum PC gibt. D.h. das Inkrement des PC kann stattfinden, während das erste Opcode Byte in der Befehlsdekodierung ist. D.h. das ist kein Zeitverlust und es vereinfacht das Design. Die Ladesteuerung lädt das Byte über den PC und erhöht ihn um 1. Das ist alles was sie zu tun hat.
Karl Heinz Buchegger schrieb: > Er redet von etwas ganz anderem. > Es geht um die innere Funktionsweise der CPU. Ich glaube, Du mußt Deinen Zaks auch noch lesen. :-) Genau diese Funktionsweise ist dort Schritt für Schritt erklärt. Mit Grafiken für jeden Zwischenschritt. Zaks animiert den Leser sogar dazu, sich das interne CPU-Modell auf Papier aufzumalen, und dann Objekte (Büroklammern, Radiergummi, etc), die die Daten repräsentieren sollen, darin zu verschieben, um die Funktionsweise im Wortsinne "nachzuvollziehen".
Erich schrieb: > Und um von diesen Trivialitäten wegzukommen, solltest du dich mal mit > den wirklich interessanten Dingen am Z80 befassen: Vor allen Dingen weg von den Dingen, die er sowieso nicht beeinflussen kann. Die CPU funktioniert so wie sie funktioniert und wie sie damals gebaut wurde. Das mag durchaus interessant sein, aber ohne Studium der exakten inneren Funktionsweise wird man heute nicht mehr rausfinden können, warum bei einem DJNZ der Offset noch gelesen wird bzw. was man hätte ändern müssen, damit das nicht passiert. Da die Ingenieure damals keine Trottel waren, denke ich, dass es dafür einen guten Grund gibt, warum man derartige Sonderfälle nicht implementiert hat sondern lieber dem immer gleichen Durchlaufen des Zykluses den Vorzug gegeben hat.
Leo C. schrieb: > Karl Heinz Buchegger schrieb: >> Er redet von etwas ganz anderem. >> Es geht um die innere Funktionsweise der CPU. > > Ich glaube, Du mußt Deinen Zaks auch noch lesen. :-) > Genau diese Funktionsweise ist dort Schritt für Schritt erklärt. > Mit Grafiken für jeden Zwischenschritt. So so. Im Zaks kann man also erfahren, warum beim DJNZ das Offsetbyte auch dann noch geladen wird, wenn der Sprung gar nicht genommen wird. Ist zwar schon lange her, dass ich den Rodney gelesen habe, aber an derartige Details kann ich mich nicht erinnern. > Zaks animiert den Leser sogar dazu, sich das interne CPU-Modell auf > Papier aufzumalen, und dann Objekte (Büroklammern, Radiergummi, etc), > die die Daten repräsentieren sollen, darin zu verschieben, um die > Funktionsweise im Wortsinne "nachzuvollziehen". Hier gehts aber nicht um die grobe Funktionsweise sondern um die Funktion kurz vor der Transistorebene. Deine Büroklammern erklären mir nicht, welches Gatter in der CPU genau wann, warum und für wie lange durchgeschaltet wird. Es geht darum, warum der Sprengring auf der unteren Achse des 6 Gang Getriebes genau den Lochabstand hat den er hat und warum eine der 12 Stück M8 Schrauben im Gehäuse um 3 Millimeter kürzer ist. Das kannst du nicht mehr mit einem knackigem Blockschaltbild ergründen.
Karl Heinz Buchegger schrieb: > Das kannst du > nicht mehr mit einem knackigem Blockschaltbild ergründen. Zaks beschränkt sich aber nicht auf ein "knackiges Blockschaltbild". Er beschreibt für einige ausgewählte Befehle den kompletten Datenfluß. Insbesondere, wie und an welchem Punkt in der Abarbeitung, Daten von den Registern zum Daten- und Adressbus kommen, und umgekehrt. Auch wo und warum Zwischenregister, die im Benutzermodell der CPU nicht zu sehen sind, vorhanden sind, wird erklärt. Mmn genau das, was der Frager hier wissen möchte.
Wenn wir schon bei PCs und DPs sind: Es gab in dieser Ära mit dem CDP1802 einen Prozessor der nicht nur einen DP hatte, sondern 16 DPs, und nicht nur einen einzigen PC, sondern 16 PCs. Und zwei 4-Bit Register, mit denen bestimmt wurde, welches von 16 16-Bit Registern die Rolle von PC und welches die von DP übernimmt. Irgendwelche Stacks oder Befehle für Unterprogrammaufrufe existierten nicht. Man mag sich nun ausmalen, wie ein Unterprogrammaufruf bei so einer Architektur aussieht.
Andi $nachname schrieb: > Darf ich mal folgendes Fazit aus dem Thread ziehen: Es gibt kein > DP-Register oder irgend so was ähnliches beim Z80. Korrekt. Möglicherweise gibt es ein Adressregister zwischen dem internen Bus und den externen Adressleitungen. Aber das ist dann auch kein DP. > Der PC ist für alle 16-Bit-Adresszugriffe zuständig Nein. Er ist nur für Zugriffe auf den Code mitsamt darin enthaltener Operanden, Displacements und Konstanten zuständig. > und er wird immer nur um 1 inkrementiert. Richtig? Richtig.
Andi $nachname schrieb: > > Darf ich mal folgendes Fazit aus dem Thread ziehen: Es gibt kein > DP-Register oder irgend so was ähnliches beim Z80. Der PC ist für _alle_ > 16-Bit-Adresszugriffe zuständig Nein. Der PC liefert die Adresse für jeden M1 Zyklus der CPU. > und er wird immer nur um 1 inkrementiert Wenn man von Sprüngen, Unterprogrammaufrufen und Returns absieht, dann wird der PC in jedem M1 Zyklus auch inkrementiert. Und zwar wird er während der Ausführung des M1-Zyklus inkrementiert. Schön daran zu sehen, daß ein Displacement von 0 bei relativen Sprüngen den gleichen Effekt hat als wäre da kein Sprung gewesen. Da ein Befehl beim Z80 eine variable Länge hat, muß es intern eine Statemachine geben, die aus dem ersten Opcode-Byte bestimmt, wieviele weitere Bytes (ergo: M1 Zyklen) noch folgen. Und die werden immer durchgezogen. Auch dann, wenn die weiteren Befehlsbytes eigentlich gar nicht gebraucht werden. Was z.B. beim genannten DJNZ oder auch bei bedingten Sprüngen der Fall sein kann. z.B. wird JPNZ 1234 in 3 Bytes codiert (Opcode, L-Teil Ziel, H-Teil Ziel). Aber auch wenn das Z-Flag gesetzt ist - also nicht gesprungen wird - werden alle 3 Bytes gelesen. Die Vereinfachung aus Sicht der CPU-Designer besteht darin, daß der PC danach auf die richtige Stelle zeigt (den Befehl nach dem JPNZ) ohne daß dazu irgendeine zusätzliche Magie nötig wäre. Heutzutage mag das anachronistisch erscheinen und mancher mag denken, daß die CPU nach dem ersten Byte ja schon "weiß" daß die Bedingung nicht erfüllt ist und einfach die Länge des Befehls von der State-Machine erfragen kann, um den PC direkt auf den nächsten Opcode nach dem Operanden für JPNZ zu setzen. Nur ist sowas in Silizium viel schwerer hinzubekommen als das sture "wir lesen immer alle Befehlsbytes und inkrementieren den PC dazwischen immer nur um 1". XL
Axel Schwenke schrieb: > Da ein Befehl beim Z80 eine variable Länge hat, muß es intern eine > Statemachine geben, die aus dem ersten Opcode-Byte bestimmt, wieviele > weitere Bytes (ergo: M1 Zyklen) noch folgen. Der M1 Zyklus ist reserviert für das erste Byte eines Befehls. Die weiteren Ladezyklen eines Befehls sind keine M1 Zyklen. Sondern M2, M3, ... Wobei nicht unbedingt jeder M<n> Zyklus ein Byte des Befehls läd. Auch Datenzugriffe sind M<n>-Zyklen, mit n >= 2. M-Zyklen sind einfach nur Speicherzugriffe. Egal wohin und wodurch. Wiederum siehe http://www.msxarchive.nl/pub/msx/mirrors/msx2.com/zaks/z80prg02.htm
A. K. schrieb: > Axel Schwenke schrieb: >> Da ein Befehl beim Z80 eine variable Länge hat, muß es intern eine >> Statemachine geben, die aus dem ersten Opcode-Byte bestimmt, wieviele >> weitere Bytes (ergo: M1 Zyklen) noch folgen. > > Der M1 Zyklus ist reserviert für das erste Byte eines Befehls. Die > weiteren Ladezyklen eines Befehls sind keine M1 Zyklen. Sondern M2, M3, Oops. Hätte ich doch mal erst nachschlagen sollen und nicht aus dem Gedächtnis zitieren :) Ich versuche mal eine Korrektur: für jeden Lesezugriff für ein Befehlsbyte (egal ob Opcode oder Operand) liefert der PC die Adresse. Der PC wird implizit und sofort inkrementiert (im zweiten Takt: T2) und es werden immer alle Befehlsbytes in genau aufsteigender Reihenfolge gelesen. > Wobei nicht jeder M<n> Zyklus ein Byte des Befehls läd. Auch > Datenzugriffe sind M<n>-Zyklen, mit n >= 2. Aber IIRC werden Datenzugriffe (sofern der Befehl solche auslöst) immer strikt nach dem Lesen aller Befehlsbytes ausgeführt und niemals mit diesen gemixt. Korrekt? Es wäre zum Zweck der Diskussion hilfreich, wenn Speicherzugriffe für Opcodes/Operanden irgendwie anders genannt würden als Zugriffe auf Daten (und Stack und I/O etc). Es durchgängig alles M-States zu nennen ist für das Verständnis nicht hilfreich. > Einmal mehr siehe > http://www.msxarchive.nl/pub/msx/mirrors/msx2.com/zaks/z80prg02.htm Schick. XL
Axel Schwenke schrieb: > Aber IIRC werden Datenzugriffe (sofern der Befehl solche auslöst) immer > strikt nach dem Lesen aller Befehlsbytes ausgeführt und niemals mit > diesen gemixt. Korrekt? Weiss ich grad nicht, aber es gibt wohl keinen Befehl, in dem eine andere Reihenfolge einen Sinn ergibt. Einen prinzipiellen Zusammenhang sehe ich in dieser Festlegung hingegen nicht. Allerdings ist etwas Ansichtssache. Wenn man Blockbefehle wie LDIR als einen Befehl ansieht, nicht als Folge desselben Befehls ohne Fortschritt des PCs, dann geht das ziemlich durcheinander. Diese Befehle bilden tatsächlich keine interne Schleife, sondern werden stets aufs Neue ausgeführt, M1 inklusive. Für den HALT-Befehl gibt das übrigens auch, der hält nicht etwa den Prozessor an, sondern bloss den PC-Inkrementer (wird zum Dekrementer), und wird folglich in schneller Folge immer wieder ausgeführt. > Es durchgängig alles M-States zu nennen ist für > das Verständnis nicht hilfreich. Sich von Zilogs Konvention abzuwenden ist weniger hilfreich. Man muss einfach akzeptieren, dass Zilog unter einen M<n> Zugriff einen Speicherzugriff jedweder Art versteht und <n> sich aus der Abfolge im Befehle ergibt. Mit der Besonderheit, dass der M1 Zyklus auf dem Bus etwas anders funktioniert als M2++.
A. K. schrieb: > ausgeführt, M1 inklusive. Für den HALT-Befehl gibt das übrigens auch, > der hält nicht etwa den Prozessor an, sondern bloss den PC-Inkrementer > (wird zum Dekrementer), und wird folglich in schneller Folge immer > wieder ausgeführt. Interessant. Wusste ich nicht. Wo an dieser Stelle werden eigentlich die Zyklen für den Refresh vom dynamischen RAM eingefügt? Weiß das zufällig wer auswendig? Ich denke, das müsste auch irgendwann während eines M1 Zykluses passieren. (Den der spielt da ja auch noch rein. Ist ja nicht so, dass da nur der PC am Bus rumfuhrwerkt)
Karl Heinz Buchegger schrieb: > Wo an dieser Stelle werden eigentlich die Zyklen für den Refresh vom > dynamischen RAM eingefügt? Weißt das zufällig wer auswendig? Immer T3 + T4 von M1.
Karl Heinz Buchegger schrieb: > Wo an dieser Stelle werden eigentlich die Zyklen für den Refresh vom > dynamischen RAM eingefügt? Weiß das zufällig wer auswendig? Ich denke, > das müsste auch irgendwann während eines M1 Zykluses passieren. M1 = 2 Takte Speicherzugriff, danach 2 Takte Refresh. Mn = 3 Takte Speicherzugriff, n > 1. Das Timing von M1 ist folglich etwas anders und etwas knapper. Eben deshalb funktionieren die Blockbefehle und HALT so wie eben beschrieben. Weil so der Refresh erhalten bleibt, ohne dafür noch zusätzlich Aufwand einzubauen.
Karl Heinz Buchegger schrieb: > Interessant. Wusste ich nicht. Das lernt man, wenn man untersucht, wie der genial simplifizierte Minimalrechner Sinclar ZX80 funktioniert. Netterweise gab es den mit Schaltbild.
A. K. schrieb: > M1 = 2 Takte Speicherzugriff, danach 2 Takte Refresh. > Mn = 3 Takte Speicherzugriff, n > 1. Dachte mir schon, dass es wohl sowas sein würde. > Eben deshalb funktionieren die Blockbefehle und HALT so wie eben > beschrieben. Weil so der Refresh erhalten bleibt, ohne dafür noch > zusätzlich Aufwand einzubauen. Und schon macht das Verhalten Sinn, auch wenn es erst etwas befremdlich wirkte :-)
A. K. schrieb: > Karl Heinz Buchegger schrieb: >> Interessant. Wusste ich nicht. > > Das lernt man, wenn man untersucht, wie der genial simplifizierte > Minimalrechner Sinclar ZX80 funktioniert. Netterweise gab es den mit > Schaltbild. :-) Den HALT (0x76) kenn ich nur noch daher, weil das der erste Befehl war, den mein Eigenbau Z80 ausgeführt hat. Im EEPROM Sockel mit Drähten den Opcode gesteckt und sich daran erfreut, dass der Halt Pin den Befehl auch visuell (mittels Test-Led) anzeigte. (Hab den ganzen Rechner mittels einer LED debuggt und in Betrieb genommen - Student, kein Geld für Oszi)
> Bist du sicher, dass 8080/85 microcoded waren? Immer diese Gewissensfragen ;) Ich dachte es jedenfalls. Das Foto vom 8085 Die (zB. http://micro.magnet.fsu.edu/chipshots/intel/images/intel8085dielarge.jpg) zeigt rechts auch eine riesige und vor allem feinkörnig regelmässige Struktur, die sehr an ein ROM erinnert. Es muss ja kein voll horizontales Microcodeformat mit >40Bits sein, vmtl. gibts da eher Opcodes für weitere Statemachines, da reichen dann eine Handvoll Bits. Der Z80 (http://tiggerfox.tibsfox.com/zylog_z80_cpu.jpg) hat "oben" nur einen relativ kleinen Bereich, der aufgrund der Unregelmässigkeit eher nach Decoder aussieht. Gibt da auch nur 10 Zeilenleitungen (Befehl+Prefix/Phase oder so?), die Spalten sind vermutlich die one-hot-Befehlsflags. Direkt drunter wird das wohl wieder tw. zusammengeodert. Die Registerbänke sind wohl die Teile links, sehen bei beiden Chips fast identisch aus...
Karl Heinz Buchegger schrieb: > Den HALT (0x76) kenn ich nur noch daher, weil das der erste Befehl war, > den mein Eigenbau Z80 ausgeführt hat. Es war kein Zufall, dass der HALT Befehl mit dem ZX80 Zeichencode für Zeilenende identisch war. Der ZX80 verwendete das RAM für Bildschirmrefresh, aber ohne feste Zeilenlänge im RAM. Bei 2KB Speicher musste man etwas haushalten, wenn man den Bildschirm vollschrieb wurde es im Speicher enger als bei eher leeren Zeilen. ;-) Die CPU sprang dazu als "DMA-Controller für Arme" an den Anfang einer Daten(!)-Zeile, aber in einem Spiegeladressraum des RAMs, in dem jeder Zugriff bei der CPU als NOP ankam. Ausser es war der Code von HALT (genauer: 0x40-0x7F, die anderen Codes in diesem Bereich durften folglich nicht verwendet werden), der kam durch. Beim HALT, also dem Ende des genutzen Teils der Zeile, drehte die CPU dann mit exakt gleichem Timing wie NOP Däumchen, bis eine an den Interrupt zurück geführte Adressleitung dem ein Ende machte. Da die CPU die Interrupt-Leitung im Refresh-Teil von M1 abfragt, definierte der Inhalt vom Refresh-Counter folglich die gesamte Zeilenlänge. Die eigentlichen in der ersten Hälfte von M1 geladenen Daten landeten für die zweite Hälfte vom M1 gemuxt in der Adresse vom System-EPROM, das auf diese Art nebenbei als Pixelgenerator für den Bildschirm diente. Auf eine solche Idee muss man erst einmal kommen. Und man muss die Z80 CPU verdammt gut kennen.
Es ist eh ein Wahnsinn, dass beim zx81 der Basicinterpreter mit stackbasierter FPU und Zeichensatz in 8KB gepasst haben. War nicht mal ganz voll... Bzw: wo hattest du 2KB RAM? Mein zx81 hatte nur eins... ein vollständig schwarzer Bildschirm war damit gar nicht möglich...
A. K. schrieb: > Georg A. schrieb: >> Bzw: wo hattest du 2KB RAM? > > Hast Recht, es war nur 1KB. Moment. ZX80 oder ZX81 Den 81 gabs auch mit verschiedenen RAM Versionen laut Wiki. Standard waren wohl 2114. Aber anscheinend wurden auch 4118 bzw 6116 verbaut. 2114 war SRAM, 4118 war DRAM und 6116 müsste irgendwas mit CMOS gewesen sein? Ja der Sinclair war schon genial. Ein Kumpel von mir hatte einen. 2114 hatte ich auch noch in Verwendung. Die erste größere Anschaffung war aber ein Satz 4164, die noch ein Vermögen kosteten. Von meiner ersten 5 1^/4 Zoll Floppy red ich erst mal nicht. Um das Geld kriegt man heute (fast) einen kompletten PC.
Karl Heinz Buchegger schrieb: > ZX80 oder ZX81 ZX80. Aber mit externer Speichererweiterung in Eigenbau. Ich hatte den allerdings nicht für mich besorgt. Mir war der zu arg limitiert. Der ZX81 war etwas schwerer zu analysieren, weil da an Stelle diverser TTLs ein Customchip draufsass.
DRAM hatte der 81er intern nie. Das war immer nur SRAM. Entweder 8bit oder 2*4bit. Die externe 16KB Erweiterung hatte DRAM, war 4116.
Karl Heinz Buchegger schrieb: > und 6116 müsste irgendwas mit CMOS gewesen > sein? 6116 ist ein statisches 2kx8-SRAM im 24poligen Gehäuse, mit JEDEC-artigem Pinout (also weitestgehend pinkompatibel zum EPROM 2716). Großer Bruder davon war 6264 mit 8kx8 im 28poligen Gehäuse, wieder mit JEDEC-artigem Pinout. Davon wiederum war 62256 der größere Bruder, 32k8, gleiches Gehäuse. Je nach Hersteller wurden auch andere Bezeichnungen verwendet; 6116 war, wenn ich mich nicht irre, eine Hitachi-Bezeichnung (jedenfalls habe ich einige 6116 von Hitachi selbst verbaut).
A. K. schrieb: > Der ZX81 war etwas schwerer zu analysieren, weil da an Stelle diverser > TTLs ein Customchip draufsass. Der ZX97lite ist ein ZX81 als TTL-Grab. Da ist die Funktion sehr schön erklärt: http://www.user.dccnet.com/wrigter/index_files/ZX97lite.htm
Vielen Dank für die vielen Antworten. Ironisch an dem Thread ist ja auch, dass ich nicht der einzige bin, der hier Irrtümern unterliegt und was gelernt hat. Ich muss noch einmal nachfragen. Nehmen wir mal 0x1000 3A CD AB LD A,(ABCD) 0x1003 ... mit seinen 13 Takten. Im M1 steht der PC auf 0x1000, 3A wird von 0x1000 gelesen und der PC wird auf 0x1001 inkrementiert, was mit Refresh-Zyklus 4 Takte dauert. Das gleiche passiert auch mit den zwei Byte danach im M2 bzw. im M3, was jeweils 3 Takte dauern sollte und der PC müsste auf 0x1003 zeigen. Da sind noch 3 Takte übrig, um auf 13 zu kommen. Jetzt müsste im M4 mit 3 Takten der Inhalt von 0xABCD gelesen werden und in A abgelegt werden. Der PC bleibt unverändert. Das wäre ja jetzt DER ideale Einsatz für mein DP-Register (Datapointer), welches ja nun aber bei dieser von Neumann Architektur nicht existiert. Nun sind doch Prozessoren permanent an Register gebunden, die machen doch nie etwas ohne. Also müsste doch ein internes 16-Bit-Register existieren, welches kurzzeitig mit ABCD geladen wird, um dessen Inhalt zu lesen. Der PC wird es doch kaum sein. Weiß dazu jemand was? BTW: Kann mir mal jemand eine Eselsbrücke nennen, wie ich die beiden Architekturen von Neumann und Harvard auseinanderhalten kann. Ich kenne die Merkmale zwar, kann mir aber nie merken, welche der beiden welche ist.
Andi $nachname schrieb: > BTW: Kann mir mal jemand eine Eselsbrücke nennen, wie ich die beiden > Architekturen von Neumann und Harvard auseinanderhalten kann. Ich kenne > die Merkmale zwar, kann mir aber nie merken, welche der beiden welche > ist. ich hab als Eselsbrücke: es ist immer umgekehrt ;-)) Harvard: Name ein Wort - zwei Adressräume von Neumann: Name zwei Worte - ein Adressraum oder so ähnlich interpretieren.
Karl Heinz Buchegger schrieb: > Weil man damals einen Van Neumann Zyklus (Befehl holen - Befehl > dekodieren - Befehl ausführen) noch ernst nahm und Befehls-Pipelining > noch in den Kinderschuhen steckte? In Mikroprozessor hatte ich für den 8051 noch einen echten Professsor, wenn auch der heute 80 ist. Der hielt 8085, 8048 und 8051 noch für echte Prozessoren ohne Pipelining. Obwohl, ja, das Pipelining mußte ich selbst erst mal verstehen lernen. Und ganz doof, bei ARM-µC wie LPC2xxx, die ARM oder THUMB Mode können. Ich machte für den ARM trotzdem funktionierenden Assemblercode, der ist an manchen Stellen da nötig. Nicht nur an den Interruptvektoren. Aber besonders auch. Ein Tutorial zu ARM LPC2000 dazu fand ich wo??? Na, China. Die können es.
Andi $nachname schrieb: > Nun sind doch Prozessoren permanent an Register gebunden, die machen > doch nie etwas ohne. Also müsste doch ein internes 16-Bit-Register > existieren, welches kurzzeitig mit ABCD geladen wird, um dessen Inhalt > zu lesen. Der PC wird es doch kaum sein. Weiß dazu jemand was? In hier nun schon zum ca. 4 Mal verlinkten http://www.msxarchive.nl/pub/msx/mirrors/msx2.com/zaks/z80prg02.htm findest du ein weiteres 16-Bit Register analog zu HL&Co, dort WZ genannt. Dieses für den Programmierer unsichtbare Register dient als temporäres Register. Beispielsweise für den vor dir grad beschriebenen LD-Befehl. Dort ist auch dein LD a,(nn) detailliert beschrieben. Wie wärs denn, wenn du dieses Dokument ENDLICH MAL LIEST?
Andi $nachname schrieb: > Also müsste doch ein internes 16-Bit-Register > existieren, welches kurzzeitig mit ABCD geladen wird, um dessen Inhalt > zu lesen. Der PC wird es doch kaum sein. Weiß dazu jemand was? Ja natürlich. So etwa im Prinzip. Bei allen Prozessoren, die eine Datenbreite von nur 8 Bit, aber eine variable Befehlslänge haben wie der Z80, muß es CPU-interne Register geben, die die Befehlsbytes eben zwischenspeichern. Teile davon fungieren dann in bestimmten Befehlen eben als das, was du hier "DP" genannt hast. Die ganze obige Diskussion über einen Datapointer war schlichtweg müßig, weil alle aneinander vorbei geschrieben haben. Einen dem Programmierer zugänglichen und somit im Code benutzbaren DataPointer gibt es nicht, wohl aber diverse CPU-interne Puffer-Register für unterschiedlichste Zwecke. Also: am Adreßausgang des Z80 sitzt ein Multiplexer, der wahlweise unterschiedliche Registerausgänge auf den Adressbus legen kann. Entweder PC oder HL oder DE oder A und I/O-Adresse oder den Refreshcounter oder eben zwei prozessorinterne Puffer-Register zu je 8 Bit, die bei Dreibyte-Befehlen nacheinander mit dem 2. und 3. Befehlsbyte befüllt worden sind. Die sind in dem von dir gemeinten Sinn hier mal der "DP", wenngleich sie auch für andere Maschinenbefehle anders verwendet wurden. So, alles Klaro? W.S.
Hallo! > Also: am Adreßausgang des Z80 sitzt ein Multiplexer, der wahlweise > unterschiedliche Registerausgänge auf den Adressbus legen kann. Entweder > PC oder HL oder DE oder A und I/O-Adresse oder den Refreshcounter oder > eben zwei prozessorinterne Puffer-Register zu je 8 Bit, die bei > Dreibyte-Befehlen nacheinander mit dem 2. und 3. Befehlsbyte befüllt > worden sind. Zeigt schon deutlich die Vielfältigkeit, obwohl es noch mehr Möglichkeiten gibt: SP für PUSH/POP, Interruptvector, bei I/Os auch manchmal BC
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.