Ich habe mir eine Schaltung mit einem alten 6502 uP aufgebaut und wollte damit ein paar einfache Programme laufen lassen. An sich funktioniert auch alles, nur bei jedem Rücksprung aus einem Interrupt hängt sich der uP auf. Den Signalen nach passt aber alles. Die Aufzeichnung des Logikanalysers beginnt in Zeile 30 des Quellcodes. Man sieht wie der uP den JSR Befehl läd, den Adresszähler auf den Stack legt (= in den SRAM schreibt), das Unterprogramm ausführt und dann den Rücksprungwert vom Stack holt. Danach macht er aber seltsamerweise an irgendeiner anderen Stelle im Programm weiter. Das angeschlossene LCD initialisiert und zeigt "Hallo" an.
Ich kriege Programm, Text und Schaltbild nicht in Deckung. - Im Text wird ein Interrupt erwähnt. Im Listing kann ich aber nichts davon erkennen. - Im Listing wird ein LCD angesprochen, dass wiederum im Schaltbild nicht auftaucht. Ist hoffentlich ein 6502A, sonst keine 2MHz.
Zur Schaltung: Traditionell wird beim 6502 der andere Takt, also phi2 (Pin 39), als Strobe verwenden, nicht phi1 (Pin 3). So steht's auch im Rockwell Datasheet.
Der uC hängt sich bei jedem Rücksprung auf, egal ob Interrupt oder normale Subroutine. Ja, es ist ein 6502A, der allerdings langsamer getaktet ist, damit das LCD auch ohne Busy Abfrage initialisiert. Aber auch mit 1MHz habe ich diesselben Probleme, nur das zusätzlich auf dem LCD eben nichts erscheint. A0 vom LCD ist A0, RW ist RW und Enable ist eine NAND Verknüpfung des CS (=Pin11 des HC139) mit phi1. Ich hatte Anfangs phi2 verwendet, dieses Signal invertiert (da es Low aktiv sein muss) und dann in den HC139 eingespeist, aber da der uP das Signal ja bereits invertiert liefert, habe ich den Inverter weggelassen.
> ZPDATA = $8000 ;zero-page data area
Ist das zur gezielten Verwirrung des Lesers gedacht? Den Anfang vom ROM
als data area und dann auch noch also zeropage zu bezeichnen?
Wenn das LCD ein üblicher HD44780 ist, dann fehlen im Code sämtliche
Delays - der braucht ja 50µsec pro Zeichen und einiges mehr in der
Initialisierung.
Damit dieser Code ohne Delays funktioniert, müsste die CPU mit 1KHz (1000Hz) oder so getaktet werden. Was wiederum ausserhalb des erlaubten Bereichs liegt.
Wenn das 0067 FFFC *= $fFFC;Rest Vektor 0068 .DB $00 0069 .DB $80 0070 .DB 12 0071 .DB 13 Reset- und Interrupt-Vektor sein sollen, das landet der Interrupt auf Adresse $0D0C. Ist das korrekt?
Ich weiß, laut Datenblatt muss der 6502 mit mindestens 50kHz laufen. Der 6502 lief für diese Aufzeichnung mit 400Hz. Allerdings scheint das kein Problem zu sein, ich hatte auch schonmal ein LED Display angeschlossen das langsam hochzählte, und da lief der 6502 mit 5Hz. Ich habe dasselbe aber auch mit 100kHz gemacht, mit Delays da passiert genaus dasselbe: der uC macht den Rücksprung irgendwo dahin, wo kein Code steht. Nur die Aufzeichnung ist dann als Bild keine 3400 Pixel breit, sondern irgendwas >50000, und das kann ich hier wohl kaum posten... Das mit zeropage ist noch ein Rest vom alten Programm, das mit Unterprogrammen wie PutString arbeitet. Der ROM beginnt bei $8000 und das ist eigentlich das einzig wichtige, das der Assembler auch richtig umsetzt: .org $8000 0067 FFFC *= $fFFC;Rest Vektor 0068 .DB $00 0069 .DB $80 0070 .DB 12 0071 .DB 13 FFFC ist der Reset Vektor $00 und $80 sind die Startadresse des eigentlich Programms, das der uC auch richtig startet 12 und 13 sind nur Testwerte, um zu sehen ob der uC nicht diese Adresse beim Rücksprung läd. Den Interrupr verwende ich erstmal nicht, (vielleicht später einmal wenn der uP richtig läuft...) Aus genau demselben Grund habe ich auch hinter RTS ein paar weitere Werte geschrieben, um zu sehen ob der 6502 einfach weitermacht. .DB 10 .DB 11 .DB 12 .DB 13
> nur bei jedem Rücksprung aus einem > Interrupt hängt sich der uP auf. > Den Interrupr verwende ich erstmal nicht Lies: Beim Rücksprung aus dem nicht verwendeten Interrupt hängt er sich auf. Hmm.
Ich hatte doch zuvor schon geschrieben, dass er sich bei jedem Rücksprung aufhängt, also nicht nur beim Interrupt, den ich daher blockiert habe, da es das sichere Ende des Programms wäre, wenn ein Interrupt auftritt.
Schoen kurios. RTS ok, kriegt auch die richtigen Daten, landet aber an $E1Fx. Kann ja nur heissen, dass der die Daten nicht korrekt verdaut. Hänge doch mal OE vom SRAM direkt an die R/W Leitung - evtl. Hold-Time Problem. Was für ein 6502 ist es den wirklich genau? Ggf BE bedienen, falls das einer ist der damit was anfängt.
> Hänge doch mal OE vom SRAM direkt an die R/W Leitung
Naja, Inverter muss schon sein. Will aber den Takt mal da weg haben.
Was ist das für ein RAM?
Wie kommst du darauf, dass er an $E1Fx springt ? Ich würde eher sagen, er springt an $FC35, was aber genauso falsch ist. Der uP läd 00 als Befehl, das ist BRK. Daher schiebt er wiederrum den Programmcounter auf den Stack und springt zu der an FFFE und FFFF angegeben Adresse, in meinem Fall $8100 Dahin habe ich ein RTI geschrieben. Auch bei diesem Rücksprung ändert sich wieder die Adresse... Jedesmal wenn ich das Programm laufen lasse, springt er andere Werte an. Wirklich seltsam.
Die Idee mit dem RW direkt an OE war goldrichtig ! Damit gehts. Aber nur wenn RW über einen Inverter alleine am SRAM liegt. Hänge ich auch OE des EPROMs (eigentlich auch ein SRAM das von einem uC mit Daten geladen wird) dran, geht es wieder nichtmehr...
Wenn ich weiterraten soll, dann musst Du mal mit konkreten exakten Bezeichnungen rausrücken. Von CPU,RAM,"ROM".
uP: MOS6502AD, 42.KW 1985 (läuft im Moment mit 60kHz) SRAM: IDT7164S EPROM Simulator: CL63C256 über 74HC245 in den Daten, Adress und Steuerleitungen. Jetzt bleibt der uC nur noch beim Lesen des Busy Flags vom LCD hängen, da dieses genauso gelesen wird, wie der SRAM. Ich habe noch die komplette Schaltung mit LCD angehängt, so wie sie im moment aufgebaut ist.
Wäre mal interessant, mit einem Oszi die Phasenbeziehung zwischen phi1 und phi2 zu ermitteln. Wie schon gesagt, alles aus den 68xx und 65xx Familien benutzt phi2 (aka E bei 68xx - rate mal warum das beim LCD so heisst). Phi1 wurde bei den 65xx kaum je verwendet. Das Datasheet ist an dieser Stelle auch nicht grad deutlich, nur bei den extern versorgten Versionen 651x sind die Phasen genau spezifiziert.
So wie ich das Datenblatt verstanden habe, werden die Daten genau am Ende des Taktzyklus gelesen (also genau dann, wenn OE\ schon wieder auf High Pegel geht, d.h. mein Speicher ist zu schnell) Benötige ich eigentlich überhaupt den Takt Phi x als Bestandteil des WR oder RD Signals ? Bei dieser Schaltung wird der Takt garnicht verwendet: http://www.hytherion.com/beattidp/comput/x65tools/diy6502/diy6502.gif
Die Speicher-Ansteuerung von meinem alten AIM65: Die ROMs haben kein OE, CS leitet sich ausschliesslich von den Adressen ab. Das war bei 65xx/68xx durchaus üblich. Bei den RAMs (2114) ist ein invertiertes phi2 am enable vom CS-Dekoder, WE ist einfach nur ein gepufferted R/W. Also CS controlled write. OE gibt's nicht. Freilich: die RAMs sind "etwas" langsamer als dein IDT, hold time Problem sind schon deswegen ausgeschlossen.
OK, dann werde ich alle OE\ ohne Takt laufen lassen (Adresse dekodieren und an CS\, RW invertiert an OE\, RW mit Phi1 verknüpft an WE\) Lege ich den dekodierten CS an Enable des LCDs und RW an RW, dann läuft alles, aber so wirklich gefällt mir die Lösung nicht... Mir wäre irgendein Schutz lieber, denn für einigen 10ns sind die Adressen sowie RW undefiniert.
> Benötige ich eigentlich überhaupt den Takt Phi x als > Bestandteil des WR oder RD Signals ? Nicht zwingend. Die Schaltung im Link ist ziemlich typisch für einfache Systeme. Bei leidlich kurzem Kabel dürfte auch der Treiber vor dem LCD nicht notwendig sein. Das war ja der Charme vom 6502 in den Hobby-Microcontrollern der 80er. Fast keine glue logic. 6504,6532,EPROM, 1 Inverter fürs CS vom ROM, 2 weitere Inverter für den Taktoszillator und fertig war ein Controller mit 4KB EPROM, 128 Bytes RAM, 16 I/Os und 1 Timer. Nebenwirkung diese etwas eigentümlichen Busses: Es finden ab und zu auch Lese-Zugriffe auf falsche Adressen statt. Weil: es gibt keinen Zyklus ohne Zugriff, und wenn die Adressrechnung einen Übertrag produziert, dann gibt's erst einmal den falschen (Lese-)Zugriff, dann den richtigen.
> Nicht zwingend. Die Schaltung im Link ist ziemlich typisch für > einfache Systeme. Wobei da allerdings an RAMs von 250-450nsec gedacht war. Keine übrig gebliebenen Cache-RAMs die jeden Glitch zum kompletten Zyklus erklären. WE sollte also schon mit phi2 verknotet sein. > Mir wäre irgendein Schutz lieber, denn für einigen 10ns sind die > Adressen sowie RW undefiniert. Nur relevant für Peripherie, die ein "zerstörendes Lesen" kennt. Ansonsten: na und?
Danke für die Hilfe ! Ich habe die Schaltung jetzt mit OE\ ohne Takt und WE\ mit Takt umgebaut. CS\ wird durch die Adresse bestimmt. Damit läuft die Schaltung mit dem LCD jetzt auch bei 2MHz.
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.