Hallo,
ich hab nach längerem Suchen keine Antwort finden können oder ich
sehe/verstehe sie nicht richtig.
Wie genau adressiert ein (uralter) Z80 seine Peripherie? Er hat ja ein
16 Bit Adressbus, aber über dem läuft doch auch der Zugriff auf
Daten/Programmspeicher.
Wie wähle ich aus welches Endgerät am Bus ich ansprechen will? Oder
teilen die sich alle den 2^16 Adressraum? Das würde ja dann heißen je
mehr I/O Karten, desto weniger Programmspeicher, aber das kann ich mir
nicht vorstellen.
Was genau verstehe ich nicht?
Ich hoffe die alte Technik ist bei dem ein oder anderem noch bekannt.
Gruß,
Kristian
Naja. Beim Z80 war/ist zusätzlich das /IORQ-Bit herausgeführt, das
zusammen mit dem M1-Signal anzeigt das ein I/O-Zugriff erfolgen soll.
Die IN/OUT Instruktionen haben einen 8 Bit Literal-Operanden und
zusätzlich wird der Akkumulator-Inhalt im Moment der Ausführung des I/O
Befehls auf die Adressbits 8 bis 15 gelegt.
Es gibt da zwei Varianten beim OUT Befehl für Adressen grösser als 255
und solche kleiner als 255.
Details kannst DU hier:
http://datasheets.chipdb.org/Zilog/Z80/Z-80_Microcomputer_Handbook.PDF
und hier:
http://www.z80.info/zip/zaks_book.pdf
nachlesen.
Alles habe ich leider auch nicht mehr im Kopf. :-)
Allerdings war Memory Mapped I/O zu diesen guten alten Zeiten (TM)
durchaus nicht unüblich. Zum Beispiel beim 6502. Der hatte keine
dedizierten I/O-Befehle.
Normalerweise kam man aber mit ein paar Dutzend Adressen aus, so das der
Speicher nicht wirklich merklich verringert wurde.
Peripherie
2^8 Adressraum
/IORQ
Speicher
2^16 Adressraum
/MREQ
Bei den Peripherie Befehlen die Registerinhalte auf A8 - A15 legen kann
jeder seine eigene Phantasie ausleben (mit /IORQ).
Man kann auch /MREQ 2^16 Adressraum für eigene Peripherie verwenden, und
Bankumschaltung für den Adressraum.
Es giebt kein Befehl für Peripherie Adressen grösser als 255.
Hmm schrieb:>>Es giebt kein Befehl für Peripherie Adressen grösser als 255.>> Das ist so nicht richtig. Siehe die von mir verlinkten Dokumente.
Bei den I/O Befehlen die Registerinhalte auf A8 - A15 legen kann jeder
seine eigene Phantasie ausleben (mit /IORQ).
>Bei den I/O Befehlen die Registerinhalte auf A8 - A15 legen kann jeder>seine eigene Phantasie ausleben (mit /IORQ).
Was hat das Thema mit Phantasie zu tun? Nichts.
Darüber kann man ganz sachlich ohne Träume oder Visionen schreiben.
Entweder es gibt I/O-Befehle mit denen die Bereiche oberhalb von 255
angesprochen werden können oder es gibt sie nicht.
Die Dokumentation sagt Ersteres. Mit Phantasie hat das nichts zu tun.
Hmm schrieb:> Entweder es gibt I/O-Befehle mit denen die Bereiche oberhalb von 255> angesprochen werden können oder es gibt sie nicht.
Tertium datur. Es gibt Dinge, die existieren, obwohl niemand sie bewusst
erschaffen hat.
Da Zilog die Welt nicht frisch erfunden hatte, sondern Intels
Architektur übernahm und erweiterte, war wie bei 8080 ein I/O-Adressraum
vom 256 Bytes vorgesehen, also A0-A7 als I/O-Adressbits. Dass bei den
I/O-Befehlen auf A8-A15 nicht die Wettervorhersage, sondern
reproduzierbarer und bei indirekter Adressierung auch nutzbarer Inhalt
auftauchte, darf als Schmutzeffekt der Implementierung anzusehen sein.
Konkret also: Per Architektur- und Prozessorspezifikation ist offiziell
nur die Nutzung von A0-A7 als I/O-Adressbits definiert.
A. K. schrieb:> Konkret also: Per Architektur- und Prozessorspezifikation ist offiziell> nur die Nutzung von A0-A7 als I/O-Adressbits definiert.
Falsch. "Z80 Programming Reference", Seite 4, IN (C) beschreibt den
Zugriff auf den 16Bit IO Adressraum. Im ProgrammierhandbuchSeite 58
stehen die Details. Wer kompatibel zum 8080 programmieren wollte, durfte
aber nur 256 Ports verwenden.
Es gab auch nicht dokumentierte Befehle im Z80. Aber die IO Sachen waren
teil der Spec.
Georg G. schrieb:> Falsch. "Z80 Programming Reference", Seite 4, IN (C) beschreibt den> Zugriff auf den 16Bit IO Adressraum.
Andererseits führt das Diagramm des "Zilog Data Book" von damals im
I/O-Zyklus nur A0-A7 auf. So gesehen müsste man sagen: Es gibt zwar die
Befehle, offiziell aber nicht den passenden Bus zu den Befehlen. ;-)
> Wie genau adressiert ein (uralter) Z80 seine Peripherie? Er hat ja ein> 16 Bit Adressbus, aber über dem läuft doch auch der Zugriff auf> Daten/Programmspeicher.>> Wie wähle ich aus welches Endgerät am Bus ich ansprechen will? Oder> teilen die sich alle den 2^16 Adressraum? Das würde ja dann heißen je> mehr I/O Karten, desto weniger Programmspeicher, aber das kann ich mir> nicht vorstellen.
Es gibt IN* und OUT* Befehle um die I/Os anzusprechen,
dabei wird die Steuerleitung IORQ input/output request aktiv,
neben den Adressen (ja, alle 16, das was Absicht von Faggin)
während bei Speicherzugriffen IORQ inaktiv bliebt und
stattdessen MRQ aktiv ist.
damit sind die Adressräume getrennt, beide sind 65536 gross,
und manche ganz üblichen Designs haben sogar Speicher in den
I/O Adressraum gelegt um mehr als 64k zu bekommen, z.B. bei
Videospeicher der den Hauptspeicher nicht zerstören sollte.
A. K. schrieb:> Andererseits führt das Diagramm des "Zilog Data Book" von damals im> I/O-Zyklus nur A0-A7 auf.
Dann nimm dir das Zilog Buch (meine Ausgabe ist Vol 1 von 1992) und sieh
dir die Befehlsbeschreibungen der "Input and Output Group" an. Dort
steht unter "Comments", wie die obere Bus Hälfte bedient wird. Die
Schwarte ist mir zu groß und zu vergilbt für einen Scan, glaub es bitte.
Es gibt ja Zilog noch, und hier auf Seite 71 -
http://www.zilog.com/docs/z80/um0080.pdf
oder alt und als scan ohne Datumsangabe auf Seite 20:
http://datasheets.chipdb.org/Zilog/Z80/
+ B to A8..A15
> (..) In all register indirect>input output instructions, including block I/O transfers, the content of>register C is transferred to the lower half of the address bus (device>address) while the content of register B is transferred to the upper>half of the address bus.
Mich etwas verwirrend, denn B wird in den block-IO-Commands auch als
Zähler verwendet ...
Georg G. schrieb:> Dann nimm dir das Zilog Buch (meine Ausgabe ist Vol 1 von 1992)
Das Foto oben war aus Zilogs Original, von Ende der 70er. Nicht
vergilbt, aber etwas ramponiert. ;-)
In der aktuellen Version von Zilog steht auch A0-15 drin.
> Schwarte ist mir zu groß und zu vergilbt für einen Scan, glaub es bitte.
Aber ich glaube es dir doch, und auch dass es so funktioniert. Es war
allerdings den meisten Leuten herzlich egal, weil Intels 256 Adressen
reichten. Im PC reichten ja die implementierten 1024 auch recht lang.
bko schrieb:> Mich etwas verwirrend, denn B wird in den block-IO-Commands auch als> Zähler verwendet ...
Eben. Das war einfach nur ein in der detallierten Befehlsbeschreibung
dokumentierter Schmutzeffekt der realen Implementierung. Nicht etwa ein
besonderes Feature. Intels 8 Bits mussten funktionieren, der Rest war
eigentlich egal.
Da bei Adressierung über Register aufgrund der Bus- und Ablaufstruktur
sowieso immer die ganzen 16 Bits des Registerpaars auf dem Adressbus
aufkreuzten, war das bei den indirekten I/O-Operationen auch nicht
anders. Bei den direkten I/O-Operationen war aus irgendeinem internen
Grund eben der Akkuinhalt auf A8-15, was beim OUT Befehl nicht wirklich
viel bringt.
Wow, ich hab nicht gedacht dass überhaupt wer antwortet. Vielen Dank
erstmal für die Infos und die neuen Links, die ich doch zum Teil noch
nicht kenne.
Wie ist das Programmiertechnisch dann geregelt? Gibt es dann andere
Befehle um I/O per /IORQ anzusprechen? Wie genau ändere ich den Wert
dieses Pins?
Danke schonmal,
Kristian
Kristian schrieb:> Befehle um I/O per /IORQ anzusprechen? Wie genau ändere ich den Wert> dieses Pins?
Missverständnis! Der Z80 hat einen Bus, keine GPIO-Pins, die du selbst
ansteuern musst. Wenn ein Output-Befehl ausgegeben wird, gehen die
Signale /IOREQ und /WR auf low, während Daten auf dem Datenbus und
Adressen auf dem unteren Adressbus liegen - und das ganz von selbst. Die
jeweiligen Zyklen sind im Manual genau beschrieben, falls du die
Hardware entwerfen musst, ist das die Grundlage. Wenn die Hardware
existiert, musst du dich nach dieser richten: ist ein
Peripherie-Register auf die I/O-Adresse 31H dekodiert, kannst du es nur
mit einem I/O-Befehl an diese Adresse ansprechen.
Sind I/Os als Memory angeschlossen (wofür es beim Z80 eigentlich keinen
Grund gibt), so ist statt Input oder Output ein LD-Befehl zu verwenden,
der bewirkt dann, dass /MEMREQ und /RD bzw. /WR low getaktet werden.
Von jedem Gefrickel mit inoffiziellen Befehlen ist abzuraten, ausser zu
reinen Spasszwecken. Das gilt auch für angebliche 16-Bit-I/O-Befehle -
dekodiert man die vermeintliche 16bit-Adresse, funktionieren die
Block-Befehle wie INI, INIR usw. nicht mehr. Im Zilog-Handbuch ist von
16bit-I/O auch nicht die Rede: C ist die Adresse, B der Zähler, jeweils
von 0..255.
Es gibt noch unzählige weitere inoffizielle OPcodes, die sich rein
zufällig bei der Implementierung ergeben haben, garantiert ist nichts
davon.
Gruss Reinhard
Nebenbei: Die erste zur Z80 softwarekompatible CMOS-Implementierung war
die NatSemi NSC800 CPU. Bei der waren auf beiden Bushälften
gleichermassen die Adressbits 0-7 zu finden. Grund: Der Bus war
gemultiplext und so konnten I/O-Bausteine direkt die nicht gemuxten
Leitungen A8-A15 als A0-A7 verwenden/dekodieren, ohne demuxen zu müssen.
I/O-Adressbits 8-15 hat es da also nicht einmal inoffiziell gegeben.
> funktionieren die Block-Befehle wie INI, INIR usw. nicht mehr
Im Gegenteil, die kann man dann wunderbar verwenden, um ganze
Speicherbereiche aus dem Hauptspeicher in einen mit IORQ
angesprochenen Bildschirmspeicher zu übertragen, das geht
nur weil B auf dem Bus liegt.
MaWin schrieb:> das geht> nur weil B auf dem Bus liegt.
und von den mit C adressierten 255 Bytes benutzt du halt 254 nicht.
Einfach nur genial.
Gruss Reinhard
Es gibt nette Tricks die man mit der Z80 CPU anstellen kann.
Beispielsweise kann man eine Adressleitung mit dem Interrupt-Eingang
verbinden, um gezielt nach N Befehlen (M1 Zyklen) unterbrochen zu
werden. Das gehört zu den Tricks, mit denen die Sinclair ZX80/81 den
Bildschirmcontroller und -speicher gleich ganz einsparten.
> und von den mit C adressierten 255 Bytes benutzt du halt 254 nicht.
Sicher doch, im nächsten Blockmove.
Jedes C ist eine Zeile, jedes B sind die 80 Zeichen darin,
und im Graphikmode gab es 256 Zeilen.