Vorweg: Man spare sich die Arduino ist alles Sch***. Ich nutze es und
bin zufrieden! Und ich werde nicht mehr wechseln. Entweder es geht damit
oder eben nicht.
Worum gehts. Ich möchte ein Arduino Uno als IO Gerät (nur lesend hier!)
an ein 8085 Computer/Bus dran bringen.
Wenn /IOW (IO-write) auf Low geht, soll ein Adress Nibble (4-bit A7..A4)
und das Datenbyte (geht am UNO an 2 Ports als High+Low Nibble) vom Bus
gelesen werden.
Wenn das Adress-Nibble passt, soll das Datenbyte weiter verwendet werden
(hier zum Test serielle Ausgabe).
Was ich bisher probiert hatte:
Einfaches pollen von /IOW ging gar nicht. Die /IOW Impulse müssen wohl
so kurz gewesen sein, bzw. das Arduino 'Framework' so langsam, das sie
das gar nicht mitbekommen haben.
Danach hatte ich /IOW auf PIN 2 gelegt und eine Interupt Service Routine
drauf gelegt, aber dann auch nur einen Trigger definiert und wollte
Adress-Nibble und Datenbyte in der Loop Routine lesen - Ergebnis war:
Trigger ging, aber zum Zeitpunkt der Loop Verarbeitung war Adresse bzw.
Datenbyte schon wieder etwas anderes (8085 System war schon woanders..)
= also auch zu langsam. Bis hierhin hatte ich auch digitalRead etc.
verwendet.
Nun möchte ich:
1. Lesen des Adress-Nibble UND Datenbyte in der ISR erledigen
2. Direkte Postzugriffe nutzen, wegen der höheren Geschwindigkeit
3. Die 'Weiterverarbeitung' soll dann nur noch in der Loop Routine
erfolgen
Leider verursachen diese Bitmanipulationen bei mir 'Kopfschmerzen' ;-)
Quelle:
http://www.netzmafia.de/skripten/hardware/Arduino/Programmierung/portmanipulation.html
Daher könnte ggf. mal einer der das schon öfter gemacht hat über meinen
Code mal drüber schauen:
1
// Trigger is /IOW from 8085 - goes to PIN 2 and generated interupt on falling
2
// address nibble A7..A4 goes to PINs A3..A0 on (PortC) at UNO
3
// data byte high nibble is on PINs D11..D8 on (PortB) at UNO
4
// data byte low nibble is on PINs D7..D4 on (PortD) at UNO
5
// way of working:
6
// 1. at /IOW falling, trigger interrupt
7
// 2. read address nibble and combined/complete data byte in isr
8
// 3. if my adress, raise a flag (state=HIGH)
9
// 4. in arduino loop, just check/wait for flag an serial print data byte
Peter S. schrieb:> void iow() {> // trigger only if adr nibble = MYADR> adr = (PINC & B00001111);> data=(((PINB & B00001111) << 4) + ((PIND & B11110000) >> 4));> if (adr == MYADR) state = HIGH;> }
Aus Geschwindigkeitsgründen solltest Du auf sämtliche Manipulationen der
Werte in der ISR verzichten, sondern nur die drei I/O-Ports einlesen und
die Rohdaten aufheben, um sie in Deiner "loop" o.ä. zu verarbeiten. Die
Adressauswertung und das Erzeugen Deines "state"-Flags muss ebenfalls
dort erfolgen.
Warum ist "data" auf zwei Ports (B und D) verteilt? Verdrahte das
anders, lege alle acht Bits gleich in der richtigen Reihenfolge an einen
Port dann kannst Du Dir einen kompletten Portzugriff und die Schieberei
sparen.
Denn es geht hier um Geschwindigkeit. Der 8085 wird mit ein paar MHz
Takt arbeiten; zwar braucht er mehrere Taktzyklen für einen
Prozessorbefehl, aber er ist halt doch recht flott, und Du hast nur
wenige AVR-Prozessortakte Zeit.
Manche Dinge löst man besser in Hardware. Die Signale aus einem anderen
Prozessor auszulesen ist sehr zeitkritisch. Ich denke, mit zwei
Logikbausteinen hast Du das schneller gelöst, und der Arduino kann dan
ganz in Ruhe sein Ding machen.
Der 74377 hat ein 8-bit Register, dass den Datenbus für Dich
zwischenspeichert bis Dein Arduino ihn auslesen kann. Das gleiche kannst
Du natürlich auch für den Adressbus machen. Jetzt noch einen 4-bit
Komparator (7485 oder sogar 74688), und Dein Arduino hat Luft zu Atmen.
Sobald der Komparator eine Adresse erkennt, die für Dich interessant
ist, triggert er die Register, die dann den Status des Datenbusse und
des Adressbusses speichern. Gleichzeitig löst Du den Interrupt aus.
Jetzt hat der Arduino Zeit bis zum nächsten Adressevent, die Register
auszulesen.
Es gibt noch einen anderen Weg: der 8085 hat einen READY Eingang. Wenn
deine Hardware das verträgt, dann kann Dein Arduino den RAEDY Eingang
auf 0 legen und ganz in Ruhe den Bus auslesen. Der 8085 wartet geduldig,
bis der READY Eingang wieder auf 1 ist.
Peter S. schrieb:> Vorweg: Man spare sich die Arduino ist alles Sch***. Ich nutze es und> bin zufrieden!
Nun, der Rest deines Postings spricht ja wohl doch von einer gewissen
Unzufriedenheit, mindestens ja wohl bezogen auf die konkrete Anwendung.
;o)
> Und ich werde nicht mehr wechseln. Entweder es geht damit> oder eben nicht.
Na dann eben nicht.
Der UNO hat keinen ganzen freien Port.
Siehe Link. Im PortD sind D0+D1 belegt durch die serielle Schnittstelle.
Daher muss es wohl dabei bleiben, zwei Nibble zu lesen.
Ich denke ich muss die seriellen Pins und ISR Pin 2 auch noch richtig
mit DDRD setzen.
Mit vorgeschalteten 7485 und 8255 habe ich schon am laufen. Jetzt möchte
ich sehen, ob es auch ohne - nur mit einem Arduino geht.
Das mit dem Ready Eingang klingt auch interessant.
Peter
Peter S. schrieb:> Jetzt möchte ich sehen, ob es auch ohne - nur mit einem Arduino geht.
Dann probier' halt aus, Deine drei Werte zu lesen, aber mach' sämtliche
Manipulationen in der loop.
Wenn das nicht funktioniert, wirst Du entweder die serielle
Schnittstelle durch Soft-Serial ersetzen müssen, um PortD als 8-Bit-Port
nutzen zu können, oder aber die von Mathias angesprochene Ready-Leitung
verwenden müssen.
(angenommen, sie ist an Pin3 angeschlossen, d.h. PortD.3)
Damit sähe Deine ISR so aus:
(Ich hab' jetzt keine Ahnung, welche Polarität das Ready-Signal des 8085
hat; das musst Du notfalls umdrehen).
Durch Vertauschen von Port B und Port D kannst Du das ganze allerdings
noch etwas flotter bekommen, dann musst Du die Nibbles nicht in Software
vertauschen und kannst Dir damit die Shift-Operationen sparen:
Moin, -
ich kenne den 8085 nicht sehr gut, aber der Weg ueber den Ready-Eingang
waere sehr einfach und stabil hinzubekommen. Du merkst Dir den Zugriff
auf das IO-Geraet mit einem Flip-Flop, der vom Arduino zurueckgesetzt
wird.
Die Idee ist nicht von mir (ist mit einer Z80):
https://hackaday.io/project/19000-a-4-4ics-z80-homemade-computer-on-breadboardhttps://github.com/SuperFabius/Z80-MBC
Und es gibt auch andere Arduinos als den UNO: Ich benutze einen Mega
fuer solche Aufgaben (5V-kompatibel, viele 8-bit Ports). Und durch
das Konstrukt Wait / Un-Wait hast Du wenig Timing-Probleme (wenn die
8085 lange warten kann).
Liebe Gruesse
Th.
Peter S. schrieb:> Die /IOW Impulse müssen wohl> so kurz gewesen sein
Vermutungen helfen da nicht. Das genaue Timing eines IO-Zugriffs kann
man ganz einfach dem Datenblatt entnehmen. Das enthält alle nötigen
Timingdiagramme.
Selbst in Assembler und wenn keine Interrupts enabled sind, wird das
Timing zu sportlich sein für einen AVR.
Für eine ähnliche Anwendung hatte ich mal den 74HC646 benutzt. Eine
Seite schreibt was rein und die andere Seite kann es später auslesen und
umgekehrt. Der 74F543 ist auch geeignet.
Peter S. schrieb:> Worum gehts. Ich möchte ein Arduino Uno als IO Gerät (nur lesend hier!)> an ein 8085 Computer/Bus dran bringen.
Dafür hast du das falsche Mittel.
Es hilft auch nicht viel, den Takt des 8085 herunterzuschrauben, denn
wenn ich mich recht erinnere, sind einige Teile in diesen alten
Prozessoren dynamisch gemacht, so daß sie das Anhalten des Taktes
einfach nicht vertragen.
Allenfalls könnte man eventuell mit etwas externer Logik den 8085 dazu
bringen, Waitzyklen einzulegen, bis der Arduino aus dem Knick gekommen
ist.
W.S.