undocumented/illegal OpCodes im Z80

  • Moin,


    im Z80 und offenbar auch in der Revision Z80A sind eine Reihe nicht-dokumentierter OpCodes. Dazu hätte ich zwei Fragen:


    1. Bei Wikipedia lese ich, dass solche OpCodes bei anderen Prozessoren (etwa der MOS-65XX-Reihe) in späteren Revisionen gern mal entfernt wurden und Programme, die darauf zugriffen, dann nicht mehr funktionierten. (Im Wiki-Text wird der 6502 im Apple II genannt). Sind die undocumented OpCodes in späteren Z80-Revisionen (B, ...) ebenfalls entfernt worden - oder vielleicht sogar "offizilialisiert" worden?


    2. Könnt ihr mir Anwendungen (insb. Spiele) auf Z80-Plattformen (am liebsten natürlich für den CPC) nennen, in denen solche Opcodes benutzt wurden?


    Ich bin gespannt ...
    Stefan

  • Hier reden sie - was den Z80B betrifft - ja leider aneinander vorbei.

  • Mir ist nicht bekannt, daß eine der Z80-Revisionen undokumentierte Opcodes nicht mehr beherrscht. Der Z80A sowieso und auch der Z80B (verwendet im SamCoupe) beinhalten sie noch alle.
    Gerade die 8bit-Befehle, die sich auf die Index-Register IX und IY beziehen, sind eigentlich kaum noch wegzudenken, wenn man sie erst einmal für sich entdeckt hat. Man bekommt immerhin mal eben 4 neue 8bit Register geschenkt (manche CPUs müssen mit insgesamt gerade mal 3 auskommen :mrgreen: ). Sie werden wahrscheinlich von so ziemlich jedem fortgeschrittenen Z80-Programmierer verwendet, und Du kannst daher davon ausgehen, daß sie in fast jedem besseren Spiel verwendet werden. Die etwas verrückteren Schiebebefehle und anderes Zeug kommen dagegen seltener zum Einsatz (da auch meistens nicht so nützlich und weniger kompatibel bei Z80-Nachfolgern).


    Bei den (teil)kompatiblen Nachfolge-CPUs des Z80 sieht es mit den illegalen/undokumentierten Opcodes unterschiedlich aus:
    - der Z180 unterstützt keine illegalen Opcodes mehr; während der Z80 noch fest verdrahtet ist, kommt beim Z180 erstmals Mikrocode zum Einsatz, weshalb dieser sich wie eine moderne CPU verhält und bei unbekannten Befehlen eine Exception auslöst (über die man dann übrigens illegale Opcodes wiederum emulieren kann - ist dann nur ganz schön langsam)
    - beim Z280 wurden sie wieder eingeführt, zumindest die 8bit Befehle für IX und IY; gleiches gilt meines Wissens nach auch für den eZ80; scheinbar hat man beim Z180 mit dem Einsparen der Opcodes schlechte Erfahrungen gemacht
    - der Z80-Nachbau von Sharp im Gameboy unterstützt keine illegalen Opcodes; der hat aber sowieso einen leicht modifizierten Befehlssatz
    - der R800 dagegen unterstützt neben neuen Multiplikationsbefehlen wiederum viele der undokumentierten Opcodes (alle 8bit IX,IY); diese CPU wurde als Z80-Ersatz im MSX TurboR verbaut und läuft mit ihrer höheren Taktzahl und der viel schnelleren Abarbeitung von Opcodes wie ein mit ca. 30MHz getakteter Z80A; somit ist der TurboR der schnellste jemals in Serie gebaute Z80-basierte Homecomputer


    CU,
    Prodatron

  • Die 4 neuen 8-Bit-Register sind auch bei mir die am meisten verwendeten dieser Opcodes.


    Mal als Seitenfrage: Wie unterscheidet sich die Implementierung der Opcodes bei festverdrahteten und Microprogramming-gesteuerten Prozessoren? Letztere stellen doch auch auf irgend einer Ebene eine physikalische Verbindung zwischen den Transistoren (durch Verdrahtung?) her.


    Ach ja: Vielen Dank für deine mal wieder sehr ausführliche Antwort! Ich lerne und lerne ...

  • Mal als Seitenfrage: Wie unterscheidet sich die Implementierung der Opcodes bei festverdrahteten und Microprogramming-gesteuerten Prozessoren? Letztere stellen doch auch auf irgend einer Ebene eine physikalische Verbindung zwischen den Transistoren (durch Verdrahtung?) her.


    Ich ziehe die Frage nach der Lektüre dieser PDF wieder zurück. :D


    Aber Z80 komplett hard-wired? Das ging wohl nur wegen der noch recht geringen Zahl von Transistoren. Aber macht ihn das damit nicht irgendwie zum RISC-Prozessor?

  • Lustig, genau das PDF hatte ich vorhin auch gefunden :) Müßte ich mir mal genauer ansehen, bisher hab ich noch nie solchen Mikrocode zu Gesicht bekommen.
    Der Z80 ist zwar hard-wired, aber trotzdem erfüllt er ja nicht die Kriterien eines RISC-Prozessors (jeder Befehl ist gleich breit und wird [meistens?] in nur einem Takt abgearbeitet usw.).
    Weiß gar nicht, ob man den Z80 schon in die eine oder andere (CISC) Kategorie schieben kann?


    CU,
    Prodatron

  • Aber Z80 komplett hard-wired? Das ging wohl nur wegen der noch recht geringen Zahl von Transistoren. Aber macht ihn das damit nicht irgendwie zum RISC-Prozessor?


    -> http://en.wikipedia.org/wiki/Random_logic :D


    Ist wohl so, dass die Prozessoren mit Random-Logik (Z80, 65XX, und wenige andere frühe 8-Bit-Prozessoren) so eine Art Zwischending zwischen Microcode-programmierten CISCs und festverdrahteten RISCs bilden. Schneller als erstere aber eben im Befehlssatz deutlich eingeschränkter; langsamer als zweitere aber mit breiteren und deshalb auch mehr Befehlen.

  • Moin,


    Der Z80 ist zwar hard-wired,


    ich hatte ein spannendes Restwochenende mit dem Thema!


    Ich habe mich mit einem Kollegen unterhalten, der der festen Überzeugung ist, dass der Z80 microprogrammiert ist. Ein paar Quellen im Netz sprechen stimmen dir allerdings zu, dass da "random logik" im Spiel ist. Hast du eine stabilere Quelle als bloß Internetseiten, die den Z80 als festverdrahtet beschreibt?


    Ich hab gestern Abend auch noch Federico Faggin gemailt, der es wissen muss, weil er das Ding erfunden hat. Allerdings lassen die Antworten bei ihm (wohl altersbedingt) immer etwas auf sich warten. Sobald er mir schreibt, quote ich das hier mal.

  • Ich hab gestern Abend auch noch Federico Faggin gemailt, der es wissen muss, weil er das Ding erfunden hat.


    :thumbsup:


    Ok, das dürfte natürlich die Topquelle in solchen Fragen sein. :anbet:
    Wie heisst doch das Sprichwort: Warum zum Schmiedchen gehen wenn man auch zum Schmied gehen kann :D


    Viele Grüße
    Andreas

  • ...eine kurze Frage hierzu: Warum wurden denn diese nicht dokumentiert? Gibt es hierzu einen Grund?
    (Ich schließe "vergessen" einfach mal aus. :) )

  • ...eine kurze Frage hierzu: Warum wurden denn diese nicht dokumentiert? Gibt es hierzu einen Grund?
    (Ich schließe "vergessen" einfach mal aus. :) )


    Was wird nicht dokumentiert? Die OpCodes aus der Ausgangsfrage?

  • HAL6128: Manche nennen sie "undocumented" manche "illegal". Im Grunde ist es beides das selbe, auch wenn es Leute gibt, die behaupten, daß es hier eine Unterscheidung gibt (z.B. würden beim Z80 die 8bit IX/IY als "undocumented" gelten, während die schrägeren Befehle "illegals" sind). In beiden Fällen sind das aber halt Befehle, die offiziell nicht dokumentiert und vorgesehen sind, daher nicht zur Spezifikation der CPU gehören und somit tatsächlich bei neueren Versionen oder vollkompatiblen Nachfolgern weggelassen werden könnten.


    Microprofessor: Da bin ich ja mal gespannt! :) Ein Kumpel von mir meinte jetzt auch, daß der Z80 eigentlich schon Microcode haben müßte (wegen den teilweise sehr komplexen Befehlen, die viele Takte benötigen), allerdings kann man den wohl nicht mit dem von späteren CPUs wie dem 68000er vergleichen. Vielleicht es so ein Zwischenschritt wie Random Logic und State Machine. Aber so ganz klar ist mir das noch nicht. Ich hab zugegebenerweise auch nur indirekt auf hard-wired geschlossen, da ich erstens nichts von Microcode-Hinweisen für den Z80 gefunden habe und zweitens halt beim Z180 geschrieben wird, daß erst dieser der erste mit Microcode wäre.


    CU,
    Prodatron

  • Faggin hat noch nicht geantwortet, aber ich habe (leider) schon ganz viele seriöse Hinweise gefunden, dass der Z80 microcoded ist. Seltsamerweise ist der nachfolgende 16-Bitter Z8000 dann aber mit "random logic" aufgebaut.


    Ich werde mich in der kommenden Woche mal ransetzen und schauen, wo da welche historischen Konzepte eingemündet sind: Mitt der 70er erscheinen jedenfalls ganz viele unterschiedliche Prozessoren mit ganz unterschiedlichen Designs (der 6800 mit random logic, der "6502" ebenfalls, der Z80 microcoded, der 6809 random logic usw.)


    Sobald Faggin antwortet, poste ich das hier mal.


    Ich würde ihn dann auch mal fragen, was es mit den undocumented opcodes auf sich hat. Es ist mir einigermaßen verständlich, dass es bei einem hard-wired Design zu "Querverbindungen" zwischen Transistoren kommen kann, die die Ingenieure nicht eingeplant und deshalb auch nicht dokumentiert haben und die man durch Ausprobieren später aber entdecken kann. Wenn aber eine ROM-basierte Softwarezwischenschicht eingezogen ist (Microcode), in der Mnemonics als Tabelle angelegt sind, dann frage ich mich, wie sich da "unbemerkt" ein Mnemonic wie "LD Xh,d" einschleusen konnte - es sei denn, die Designer waren zeitweise betrunken. :D


    (Es könnte jedoch sein, dass ich irgend etwas falsch verstehe: die undocumented opcodes werden ja wohl offenbar durch Hex-Sequenzen aufgerufen - und die Mnemonics könnten erst durch spätere Assemblierer dazugekommen sein, die die undocumented Opcodes schon kannten und ihnen dann eben Namen (Mnemonics) gegeben habe.)

  • Antwort habe ich noch nicht bekommen, aber mittlerweile so viele Quellen gefunden, die besagen, dass der Z80 microcoded ist, dass davon auszugehen ist. Die "illegalen Opcodes" sind damit also bloß "nicht dokumentierte Opcodes". Allein, wenn man an die Fülle der Transistoren beim Z80 denkt und die Menge an Opcodes, dann liegt es nahe, dass das nicht festverdrahtet sein kann.


    Hintergrund: Faggin hat nach den Erfahrungen mit dem Intel 4004 (der hardwired war) den 4040 gebaut, der lediglich 14 neue Opcodes bekommen konnte (die Anzahl der Opcodes ist bei festverdrahteten Prozessoren von den Möglichkeiten/Kombinationen der Verdrahtung abhängig). Beim 8080 hat er sich dann des seit Anfang der 1950er-Jahre bekannten Verfahren der Microprogrammierung besonnen und das auf den Microprozessor übertragen.

  • So, und nach allem, was ich mittlerweile zum Thema in Fachbüchern aus Mikroelektronik, Computerarchitektur und Informatik gelesen habe, ist die Antwort von Faggin ziemlich überraschend:


  • Ah, schön, daß er geantwortet und für Aufklärung gesorgt hat! Schon cool! :)
    Dann stimmt es also doch, daß Microcode erst mit dem Z180 kam. Der 8080 wird ja dann auch noch keinen gehabt haben.
    Nächste Fragen: Was ist der Unterschied zwischen CISC und Random Logic, und was war mit dem 6502? :mrgreen:


    CU,
    Prodatron

  • Du meinst den Unterschied zwischen RISC und Random Logic?


    Den habe ich bislang so verstanden, dass bei RISC eben jeder Opcode eine feste Verdrahtung hat, wohingegen bei CISC-Random-Logic Opcodes auch aus mehreren Verschaltungen bestehen können. (Aus letzteren erklärt sich auch, warum die zum Abgearbeitetet werden unterschiedlich lange Taktzeiten benötigen, glaube ich.)


    Microcode kam natürlich schon vor dem Z180 - allerdings wohl nicht im Microprocessor. Die Überlegung Maschinenbefehle über eine Tabelle kodiert in der Maschine abzulegen stammt aus dem Jahre 1952: http://www.computer.org/portal…i/10.1109/MAHC.1986.10035


    (Falls der Volltext interessiert, kann ich den gern mal "langzitieren". :-D

  • Sorry, ja, ich meinte Risc und Random Logic...
    Und das mit dem Z180 meinte ich jetzt Zilog-spezifisch.


    Dann gibt es also quasi 3 verschiedene Techniken:
    - RISC
    - CISC mit Random Logic
    - CISC mit Microcode


    Der 6502 ist dann wohl so ein Zwischending zwischen 1 und 2, wobei er definitionsmäßig wohl eher zu 2 gehört (http://en.wikipedia.org/wiki/M…502#Technical_description: "[...] The 6502 is technically not a RISC design [...] the 6502 has been credited as being inspirational to RISC processors [...]").


    CU,
    Prodatron

  • Der 6502 ist in der Tat ein wichtiger Schritt hin zur RISC-Architektur. Ich weiß nicht, ob es aus der Not (d.h. den Kosten) heraus geboren wurde, dass das Teil so enorm wenige Opcodes verdrahtet hat, aber deshalb waren die Ingenieure gezwungen, die Funktionen (vor allem die Register) so vielseitig/orthogonal anzulegen. Das ist im Prinzip schon die Philosophie von RISC ... wenn dann noch pipelining dabei wäre!


    Anfangs hat man (bei Intel9 ja geglaubt, es sei gut, so viele Register wie möglich zu haben. Die CISC-Idee ist im Prinzip aus technischer Verschwendung heraus geboren worden: Als der 4004, der 4040 und auch noch der 8008 gebaut wurden, war auf den Chips noch viel Platz nach Unterbringung der Hauptfunktionen, dass die Ingenieure sich gedacht haben, den müsse man mit Register auffüllen. Wenn ich mich richtig erinnere, führte das beim 4040 dazu, dass zu den schon 16 vorhandenen Registern des 4004 noch eine Extrabank mit ebenso vielen Registern hinzugefügt wurde. Das hat den Chip natürlich enorm ausgebremst.

  • Meines Erachtens gibt es aber auch im Z80 einiges, was die RISC-Philosophie schon vorausdeutet: Etwa die Tatsache, dass man Opcodes für wichtige Funktionen (wie das Löschen des C-Flag) einspart und diese Funktionen anderen Opcodes quasi als Nebenwirkung mitgibt (C-Flag löschen durch Logik-Operationen) Ich schaue immer mal wieder, wo ich im Z80 noch weitere solcher pseudo-orthogonalen Opcodes entdecke. Viele gibt es aber nicht.

  • Aber was ist denn an vielen Registern schlecht? Je mehr Register desto besser (machts schneller und die Programmierung weniger umständlich).
    Register zu adressieren kostet ja auch viel weniger Logik auf dem Chip als zig-verschiedene Opcodes zu implementieren. Gerade bei RISC-Prozessoren hat man ja Register ohne Ende.


    Mich hat der Register-Mangel beim 6502 immer abgeschreckt, allerdings hab ich auch noch nie auf dem programmiert und hab daher keine praktische Erfahrung mit seiner Alternative namens "Zero-Page", die ja quasi aus der Registern-Not geboren wurde. Besonders dolle find ich die Lösung im Vergleich zum Z80 aber trotzdem nicht, weil so Sachen wie Multitasking mit diesen starren Strukturen trotzdem nicht vernünftig realisiert werden können (vergleiche auch den auf feste 256 Bytes beschränkten Stack, bei dem Hochsprachen einen solchen per Software emulieren müssen, weil er zu klein ist - Performancekiller).


    CU,
    Prodatron

  • Meines Erachtens gibt es aber auch im Z80 einiges, was die RISC-Philosophie schon vorausdeutet: Etwa die Tatsache, dass man Opcodes für wichtige Funktionen (wie das Löschen des C-Flag) einspart und diese Funktionen anderen Opcodes quasi als Nebenwirkung mitgibt (C-Flag löschen durch Logik-Operationen) Ich schaue immer mal wieder, wo ich im Z80 noch weitere solcher pseudo-orthogonalen Opcodes entdecke. Viele gibt es aber nicht.


    Laß mal überlegen :)


    LD HL,0: ADD HL,SP -> entspricht LD HL,SP
    XOR A -> entspricht schnellem LD A,0 (früher hatte ich immer SUB A verwendet, weil das eher einleuchtet; weil das aber auf dem x86 langsamer als XOR A ist, hab ich mir XOR A angewöhnt)
    OR A -> entspricht CF=0 bzw. schnellem CP 0
    Gibt natürlich noch mehr, und viele definieren sich hier gerne Assembler-Macros, um solche "Befehle" dann direkt eingeben zu können.


    Dann gibt es so Sachen wie die 16bit Additionsbefehle oder den NEG-Befehl:
    - ADD HL,reg reicht meistens, wenn man nicht mit 32bit-Werten arbeitet. Es setzt allerdings das Zero-Flag nicht, ADC HL,x schon, weshalb es dann manchmal so Konstruktionen wie OR A:ADC HL,reg geben muß.
    - NEG kann man eigentlich auch mit CPL:INC A machen. Ist beides gleich schnell und braucht 2 Bytes. Allerdings manipuliert NEG die Flags, so daß man danach auch den DAA-Befehl für BCD-Zahlen verwenden kann.


    Z80 macht einfach Spaß :mrgreen:


    CU,
    Prodatron

  • Aber was ist denn an vielen Registern schlecht? Je mehr Register desto besser (machts schneller und die Programmierung weniger umständlich).
    Register zu adressieren kostet ja auch viel weniger Logik auf dem Chip als zig-verschiedene Opcodes zu implementieren. Gerade bei RISC-Prozessoren hat man ja Register ohne Ende.


    So wie ich das verstanden habe, bedeutet jedes Register auf CISC-Architektur, dass alle Opcodes, die die nutzen können, einen eigenen Eintrag in der Microcode-Tabelle benötigen (bzw. eine eigene Festverdrahtung). Es ist ja nicht wie in anderen Sprachen, dass LD A,B und LD A,C dieselbe Struktur nutzen könnten, nur weil es sich um Ladebefehle handelt. Willst du bspw. 25 Opcodes für 2 Register verfügbar machen, dann brauchst du dafür mind. 50 interne Strukturen (Microcodes oder Wires). Bei 4 sind es 100 und bei 14 sind es 350. Und wenn es dann aber noch mehr als 25 Opcodes sein sollen, steigt die Zahl entsprechend. Und irgendwann brauchst du schon allein deshalb Opcodes, die länger als 2 Byte sind, weil sich so viele Kombinationsmöglichkeiten gar nicht mehr in 2 Bytes abbilden lassen. Dass das zu Lasten der Performance geht, kann ich mir schon vorstellen.

  • Beim Anblick dieser Grafik ist mir aufgefallen, dass es zwei Weitere Registerpaare zu geben scheint: W/Z und W'/Z'.


    Hier steht: "The forgotten registers W and Z are only used for internal operations in the processor, like jump to new addresses. (The CPU can only transfer 8 bits at a time, so to transfer (load) a 16-bit address, it will first store it in WZ)."


    Lassen sich diese Register mit Opcodes auslesen/beschreiben?


    Was heißt da oben im Text "forgotten"? Wer hat die vergessen?

  • Quote

    Lassen sich diese Register mit Opcodes auslesen/beschreiben?


    Was heißt da oben im Text "forgotten"? Wer hat die vergessen?


    Nein, die lassen sich nicht auslesen, beschrieben werden sie indirekt, wenn du bestimmte Befehle ausführst.


    So etwa bei LD A,(adresse). Nach dem der Z80 den Opcode gelesen hat, "weiß" er, dass er eine Speicherstelle auslesen und den Inhalt in A ablegen soll. Die nächsten zwei Bytes des Befehls bilden diese Adresse.
    Der Z80 kann nun aber den Speicher nur byteweise lesen und benötigt zur Bildung dieser 16-Bit-Speicheradresse daher ein Register(-paar), wo diese Werte abgelegt werden können, bevor beide 8-Bit-Werte die Adresse bilden können, aus welcher der Wert für das A-Register gelesen werden soll.
    Dafür kommt kein vorhandenes Register in Frage, und der PC darf in dieser Zeit auch nicht geändert werden, sonst verändert er sich, bevor er das zweite Adressbyte lesen kann.


    Wo werden W und Z verwendet? Überall dort, wo eine Adresse gebildet werden muss, aber kein herkömmliches Registerpaar die Adresse bildet - wie etwa bei ld (hl), a. Wenn ich über die Befehlsliste drüberfliege, sehe ich da auf die Schnelle:


    ld (NN),dd
    ld dd,(NN)
    ld (NN),a
    ld a,(NN)
    out (N),a
    in a,(N)


    NN = 16-Bit-Adresse
    dd = HL, DE, BC, SP


    Zudem gehören dazu noch alle ret-Befehle (ret, ret c, reti, retn), alle call-Befehle, alle jp-Befehle außer wahrscheinlich jp (hl), vermutlich alle jr-Befehle und rst-Befehle sowie djnz.


    Wahrscheinlich habe den einen oder anderen Befehl übersehen.


    Im übrigen steht das in etwas ausführlicher Form in der "Programmierung des Z80" von Rodney Zaks. Der legt seinen Beispielen allerdings den 8080 zugrunde, was als Vorgänger zum Z80 zwar passt. Leider gibt es keine genaue vollständige interne Darstellung des Z80. Deswegen hoffe ich auf das Visual6502-Projekt, das ja auch den Z80 mal komplett entschlüsseln wird.


    "forgotten" steht hier nur dafür, dass diese Register für die Z80-Programmierung keine Rolle spielen und daher schnell vergessen wird, sie zu erwähnen.


    MaV

  • Danke für die ausführliche Antwort. Bei Zaks muss ich das übersehen haben - zumindest die Diagramm-Darstellung mit W/Z. Ich schaue nachher gleich mal nach. Hast du eine Ahnung, wofür W und Z als Abkürzungen stehen könntent? (Einige der anderen 16-Bit-Adressen scheinen ja einer Nomenklatur zu unterliegen: HL=HighLow, BC=ByteCount, DE=?)


    Auf die Visualisierung des Z80 bin ich auch sehr gespannt. Steht dort ja (neben anderen) auf der To-Do-Liste.

  • Gerne!


    Ich glaube, dass die Art von Menschen, die Prozessoren entwickeln, nicht so viel Wert auf gezielte Nomenklatur legen.
    A für Akkumulator ist naheliegend, bei HL hatten sie vielleicht auch noch and High/Low gedacht, SP für Stack Pointer und PC für Program Counter sind naheliegend.


    Darüberhinaus werden sie wohl eher in Reihenfolge des Alphabets gegangen sein, bzw. Lücken soweit möglich aufgefüllt haben.


    Also:
    A, B, C, D, E, F für Flag, G ausgelassen, H, L. Dann IX für IndeX und IY - also I plus den nächsten Buchstaben nach X im Alphabet - für das zweite Index-Register.


    Für W und Z würde ich annehmen, dass sie die letzten Buchstaben des Alphabets ins Auge gefasst haben. X und Y ist durch Verwechslung mit IX und IY ausgefallen, also blieben Z als letzten Buchstaben und W als nächstbesten davor übrig.


    MaV

  • Deine Annahme klingt plausibel.Die beiden "vergessenen" Register W und Z zu nennen, könnte aber auch durch spätere Beschreibungen hinzugekommen sein, denn sie zu dokumentieren wäre angesichts ihrer "Unerreichbarkeit" für den Programmierer ja sinnlos. Ich könnte mir noch vorstellen, dass W vielleicht für "Word" (also hier eine 16-Bit-Zahl) steht ...


    . X und Y ist durch Verwechslung mit IX und IY ausgefallen, also blieben Z als letzten Buchstaben und W als nächstbesten davor übrig.


    Zudem sind X und Y über undokumentierte Opcodes (also festverdrahtete Verbindungen) ja sowieso schon als 8-Bit-Register adressierbar.


    In der Tat hat sich Faggins Team wohl aber beim Z80 sehr genau überlegt, was da im Detail besser beschrieben werden soll als beim 8080. Bei meiner nächsten Mail an ihn werde ich ihn mal fragen. (Ich versuche gerade genau solche Dinge über den Z80 herauszufinden, die eigentlich keinen praktizierenden Programmierer interessieren, um dem Chip auch seine scheinbar unbedeutenden Geheimnisse noch zu entlocken.)