009
27.06.2026, 19:26 Uhr
coignard
|
| Zitat: | | Eine Frage: Du hast ja irgendwo geschrieben, dass du die Z80.h von Andre Weissflog angepasst hast auf den U880. Welche konkreten Abweichungen hast du denn da angepasst? Wann spielen diese Unterschiede eine Rolle? |
Ehrlich gesagt habe ich das hauptsächlich gemacht, weil ich Authentizität erreichen wollte, und nicht, weil ich irgendeine Software hätte, die diese Spezialfälle ausnutzt (mit Ausnahme von Tests wie z80test).
Kurz zu den Unterschieden: Erstens verändern die Block-I/O-Befehle INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR das Carry-Flag (CF) nicht. Das führt dazu, dass z80test fehlschlägt, aber genau das ist das erwartete Verhalten für den U880:
https://github.com/coignard/u880/blob/main/tests/z80test.rs
Alle übrigen Flags (N aus Bit 7 des Bytes, H aus dem Überlauf von t, P/V als Parität von (t&7) XOR B, S/Z/X/Y aus B) sind wie bei Zilog.
Die Datenblätter von Zilog und Mostek sagen, dass CY von diesen Befehlen nicht verändert wird. Das heißt, der U880 hält sich an die Spezifikation, während der echte Zilog einen undokumentierten Nebeneffekt hat. Letztlich haben die MME-Ingenieure den Z80 beim Nachbau also gewollt oder ungewollt verbessert. Das ist übrigens eine Eigenschaft des NMOS-MME-U880 (U880D/UA880D/UB880D). Der spätere CMOS-U84C00 hat das schon nicht mehr.
Zweitens habe ich die undokumentierten Flags X/Y (Bits 3/5) bei SCF und CCF ergänzt:
| Quellcode: | match rev { Revision::Older => f.0 |= a & (Y|X), Revision::Newer => f.0 |= (a | f_in.0) & (Y|X), }
|
Hier ist der Kontext wichtig. Patrik Rak hat schon 2012 gezeigt, dass bei jedem Zilog Z80 (sowohl NMOS als auch CMOS) X/Y bei SCF/CCF als Bits 5/3 von (Q ^ F) | A berechnet werden, wobei Q ein verborgener Zustand der ALU ist: nach einem Befehl, der die Flags nicht verändert, ist Q=0, nach einem Befehl, der sie verändert, ist Q=neues F. Das heißt, beim echten Zilog hängt das Ergebnis von SCF/CCF vom vorherigen Befehl ab. David Banks (2018) hat ergänzt, dass NEC NMOS beide Bits einfach aus A nimmt, und ST CMOS XF aus A, YF nach der Zilog-Formel (Letzteres kann ich allerdings weder bestätigen noch widerlegen).
Der U880 bildet die Zilog-Q-Logik überhaupt nicht nach. Der frühe MME-U880 verhält sich wie NEC (X/Y = A), das ist meine Variante Older. Der späte MME-U880 (und, dem Detektor z80type nach zu urteilen, die verwandten Thesys Z80 und der rumänische MMN 80CPU) hat X/Y = A | F, das ist mein Newer. Witzigerweise sind meine beiden Revisionen genau die zwei Grenzfälle der Zilog-Formel: bei Q=F ergibt sich A, bei Q=0 ergibt sich A|F, nur ist das beim U880 fest an die Revision gebunden und hängt nicht vom vorherigen Befehl ab.
Wichtige Einschränkung: Die-Fotos verschiedener U880-Revisionen habe ich nicht, deshalb habe ich das Verhalten selbst aus den Quellen von z80test und aus dem Detektor z80type übernommen. Den echten Zilog ((Q^F)|A) und ST CMOS emuliere ich bewusst nicht, weil der U880 sich so nicht verhält, ich habe dazu in den Tests einen Hinweis hinterlassen: "SCF (ST) FAILED // ST CMOS not emulated".
Auf echter Hardware sind X/Y während SCF/CCF schlicht instabil (ich habe irgendwo darüber gelesen, entweder hier oder anderswo): derselbe Chip kann je nach Temperatur, Spannung und Taktsignal unterschiedliche Werte liefern, sogar in verschiedenen Maschinen unterschiedlich. Als Referenz habe ich daher dieses beobachtbare stabile Verhalten genommen und modelliere es als feste Revisionen, statt zu versuchen, die Zilog-Q-Logik nachzubilden.
Jetzt zur z80.h. Hier habe ich das Durchsickern von PC_H in X/Y bei den sich wiederholenden Block-Befehlen ergänzt (LDIR/LDDR/CPIR/CPDR/INIR/INDR/OTIR/OTDR): bei der Wiederholung wird PC um 2 verringert, und die Bits 3/5 von PC_H sickern in X/Y durch. Das ist kein spezielles U880-Verhalten, das gab es auch beim Z80. Und um die Contention beim KC 87 korrekt umzusetzen, habe ich die WAIT-Abtastung auf den Daten-T-Zustand der Nicht-M1-Zyklen gelegt: Beim KC 87 / Z 9001 setzt der Videocontroller den echten WAIT-Pin bei Zugriffen auf das Video- bzw. Farb-RAM (adressbasierte Contention über den echten Pin, also weder das RDY des CPC noch der angehaltene Takt des Spectrum). floooh hat bestätigt, dass die Platzierung von WAIT in der z80.h ein Kompromiss zugunsten der Performance ist.
VG René Coignard Dieser Beitrag wurde am 27.06.2026 um 19:27 Uhr von coignard editiert. |