Hallo zusammen,
Leider wieder eine Assembler-Noob Frage:
Hat jemand einen Vorschlag wie ich mit wenig Code eine einfache Zeitverzögerung von (ca.) 5 Sec. in mein Programm einbauen kann ? (6502@1MHz) ?
Würde mich über Hilfe freuen.
VG,
Chris
Hallo zusammen,
Leider wieder eine Assembler-Noob Frage:
Hat jemand einen Vorschlag wie ich mit wenig Code eine einfache Zeitverzögerung von (ca.) 5 Sec. in mein Programm einbauen kann ? (6502@1MHz) ?
Würde mich über Hilfe freuen.
VG,
Chris
naj, er fragt doch nach 5 SEKUNDEN , nicht nach Clockcycles. Wobei man das natürlich auch mit solchen Infos hinbekommt.
Für welchen Rechner soll es denn sein ?
Ja nach Hardware kann man natürlich auch eventuell vorhandene Timer benutzen
Es gibt viele Seiten, die sowas diskutieren.
Aber keine ist so schön wie Diese . Ich brauch halt manchmal ein bisschen Nachhilfe
naj, er fragt doch nach 5 SEKUNDEN , nicht nach Clockcycles. Wobei man das natürlich auch mit solchen Infos hinbekommt.
Für welchen Rechner soll es denn sein ?
Für den TIM-1. Ich wollte aber eine allgemeingültige Lösung die nur von der CPU abhängig ist.
Ich probier das aus, Danke !!
Bei 1Mhz sind es (ca.) 1000000 clockcycles pro Sekunde.
Genau.
Und jetzt nimm mal an, daß so ein CMP#$09 oder was sie da hatten 4 Cycles braucht, dann hast Du ein Programm mit 5 mal 250.000 Kommandos. Das paßt doch gar nicht in den Speicher. (/Ironie off)
Ich glaube, daß mit dem Cycle genauen Warten braucht er hier gar nicht. Das ist eher für exaktes I/O oder Rasterspielereien gut. ISt aber 'ne lustige Variante, da ein "non-sense" Compare zu benutzen.
Für solche Fragen ist übrigens (auch wenn das sicher die Meisten eh wissen, aber es gibt ja evtl auch "Neuleser") der Rodney Zaks gut ("Programmierung des 6502") - da stehen nämlich die Taktzyklen zu den Befehlen mit drin (in den allermeisten anderen Maschinensprachbüchern fehlt diese Info). Gibts u.a. bei archive.org
Für den TIM-1. Ich wollte aber eine allgemeingültige Lösung die nur von der CPU abhängig ist.
Das macht es natürlich "schwieriger". Wahrscheinlich bleibt dann wirklich nur die Variante mit der Warteschleife (wie oben gezeigt).
Oder eine modifizierte Variante davon, z.B. mit mehreren Speicherstellen, die man statt der Register runterzählt.
edit: so in der Art hier ( die $05 in Adresse $D0 ist der wesentliche Wert; hier gibt es mit dem Wert $0a so ziemlich 5secs )
Wichtig: wenn man das ein zweites Mal aufruft, steht in $D0 dann eine $00, man muß also vor dem zweiten RUN den gewünschten Wert dort wieder reinschreiben.
Für solche Fragen ist übrigens (auch wenn das sicher die Meisten eh wissen, aber es gibt ja evtl auch "Neuleser") der Rodney Zaks gut ("Programmierung des 6502") - da stehen nämlich die Taktzyklen zu den Befehlen mit drin (in den allermeisten anderen Maschinensprachbüchern fehlt diese Info). Gibts u.a. bei archive.org
Für sowas lohnt immer erstmal ein Blick in die originalen MOS Handbücher. Da ist eine Tabelle drin, die alle notwendigen Informationen zu allen Befehlen enthält. Diese Tabelle war eigentlich alles, was ich zur 6502-Programmierung benötigt habe.
Danke, dass Ihr meine unqualifizierte Antwort korrigiert habt.
Ich mache sowas auch nicht mehr.
Ich habs schonmal ganz am Anfang geschrieben - Du bist einfach manchmal zu schnell "angefaßt", was einfach schade ist. (Gerade in einem Forum, wo nicht immer jeder mitüberlegt, wie denn der andere das nun verstehen könnte, und auch die Metakommunikation ja fehlt (GEsichtsausdruck, Handbewegungen etc.)). Die Antwort war doch qualifiziert und der verlinkte Artikel auch SEHR schön und interessant. Nur eben, wenn es - was wir ja auch nicht genau wissen - einfach nur darum geht, für ein Titelbild beim selbstgebauten Snake Spiel mal 5 Sekunden zu warten, ist es einfach ein wenig overkill.
Meine Variante z.B. hat den Nachteil, daß es schwierig wird, damit "exakt" 5 secs einzustellen (eine LDA/STA Kombi mehr würde das noch verbessern), dafür aber den Charme, daß es auch mal locker 20 secs sein können, oder auch Minuten, wenn man noch einen/einige Zähler ($D3,$D4...) dazusetzt.
Exakter einstellbar ist das die Variante mit der Registerzählschleife. Na und eben hochpräzise wird es dann mit den Taktberechnungen.
Es ist halt einfach die Frage, was genau nun gebraucht wird.
Wenn er es nicht so eingeschränkt hätte (auf die CPU), wäre wahrscheinlich die oben auch schonmal erwähnte Variante mit dem Timer die Schönste. Auf einem C64 o.ä. würde man evtl einfach Rasterstrahlendurchläufe zählen. Das sind dann 50 pro Sekunde oder so - und man kann sich einfach einen kleinen Counter in den Interrupt hängen, der einfach aktiviert wird und nach Ablauf eine Info schickt / aufhört zu zählen. Dann kann man in der Wartezeit sogar noch Sachen vorberechnen oder Arrays vorbelegen etc.
So gesehen: Deine Antwort war doch absolut OK.
Und doch gibt es auch andere Lösungen ...
ThoralfAsmussen Naja, schau mal auf unsere Elisa-Diskussion.
Ich schrieb, "das ist auf Eliza-Niveau - bestensfalls" (oder so ähnlich).
Darauf du: "Ne, Eliza war viel später".
"Häh?" denke ich, "Eliza-Niveau" hat doch gar keinen zeitlichen Bezug. Ich kann doch auch in 100 Jahren noch Programme schreiben, die Eliza-Niveau haben. Aber ich stehe jetzt als der Depp da, der nicht weiß, wann Eliza rauskam. Weil du etwas korrigierst, was ich gar nicht gesagt habe.
Als ich dich darauf hingewiesen haben, hast du dann nochmal nachgesetzt.
Vielleicht solltest du auch mal überlegen, wann deine Beiträge andere User ziemlich blöd aussehen lassen.
Ich hätte "die schlimme Stelle" ja woanders erwartet; nicht gleich beim ersten Kommentar; so kann man sich täuschen. Außerdem liegt da wohl auch noch ein Mißverständnis vor, weil ich eigentlich nicht/nie meinte, daß die Antwort nicht zur Frage paßt - zumindest nicht in dieser absoluten Form. Es ist wohl eher so, daß ich immer noch denke, daß Taktzyklen zählen einfach eine ganz andere "Anwendung" ist - das kann man in der Form, wie es im verlinkten Artikel gezeigt wird, brauchen, wenn man z.B. die Rasterpunkte aus einem Rasterbar raushaben will und muß das dann für jede Zeile optimieren. Da geht es halt aber um Mikrosekunden oder weniger. Nix für ungut ...
Den Artikel selbst gibt es übrigens auch auf deutsch
hochniveau: Clockslide: von der exakten Verschwendung von Taktzyklen auf dem 6502
und ist sehr lesenswert.
zu Eliza: war ja sehr erstaunt, daß das jetzt hier in der Form noch nachgeschoben wird. Ich hätte nie vermutet, daß sich da jemand dermaßen betroffen fühlt, zumal, wenn es gleich im Anschluß um PinUp Girls geht. Thematisch würde ich schon sagen, daß es einen gewaltigen Unterschied zwischen einem zufallsgenerierten Gedicht und einem Programm gibt, was versucht, dem Nutzer quasi vorzugauckeln, es verstünde ihn. Deshalb auch die Erwähnung der Paser, da ist wenigstens ein echter nützlicher Ansatz dahinter.
und zum eigentlichen Thema:
so richtig "gelöst" ist das Problem noch nicht. Zumindest nicht, wenn man es genersich und in wirklich vorgebbaren Sekunden haben will.
Danke für euere Mithilfe,. Manchmal überfordern mich die Webseiten (insb. anderssprachige) und Handbücher noch ein bisschen. Aber es wird besser, nachdem ich jetzt wieder ein paar Befehle mehr verstanden habe und jetzt auch verstanden habe dass man mit den Branch-Befehlen auch rückwärts springen kann.
Der Denkanstoss hat in dem Fall ausgereicht. Das von Cobalt60 verlinkte Beispiel ist ideal für meinen Zweck. da kann ich mit dem Zähler solange rumspielen bis die Zeit passt. Die Zeit muss nicht exakt sein, aber einfach veränderbar.
Habs jetzt so gelöst:
DELAY
INIT 203F LDA A9 14 LDA W/#20 (7-8 sec. delay)
2041 STA 85 03 STA DELAYCount
LOOP3 2043 LDY A0 FF LDY W/#255
LOOP2 2045 LDX A2 FF LDX W/#255
LOOP1 2047 DEX CA X -1
2048 BNE D0 FD Branch to LOOP1 if X NOT 0
204A DEY 88 Y -1
204B BNE D0 F8 Branch to LOOP2 if Y NOT 0
204D DEC C6 03 DELAYCount -1
204F BNE D0 F2 Branch to LOOP3 if DELAYCount NOT 0
Alles anzeigen
Okay, damit hast du eine geschachtelte Verzögerungsschleife realisiert, die eine gewisse Anzahl von Taktzyklen verbrät.
ABER:
Es gibt zwei weitere Faktoren, die du hier nicht beachtest und die die verstrichene Zeit negativ beeinflussen können:
1) Der Videochip: Es gibt Rechner, deren Videochip für die Videoausgabe auf den ROM/RAM-Inhalt zugreifen müssen und dabei den Prozessor für ein paar Taktzyklen anhalten. Wenn ich mir dein Bild im vorigen Post angucke, dann trifft dieser Faktor hier aber wohl nicht auf dich zu. Beim C64 und seinen Verwandten aber schon. Deswegen wäre in einer derartigen Konstellation eine Verzögerung mittels eines Timers die bessere Wahl.
2) Interrupts: Falls Interrupts auftreten (IRQs können gesperrt werden, NMIs sind nicht unterdrückbar), dann unterbricht der Prozessor für eine für dich undefinierte Zeit dein Programm und kehrt erst nach Beendigung des Interrupts zurück, um dein Programm weiter auszuführen. Dies führt ebenfalls zu einer weiteren Verzögerung, so dass deine Verzögerungsroutine nur einwandfrei arbeitet, wenn die Interrupts im Status-Register gesperrt sind und extern keine NMIs auftreten.
Beide Probleme lassen sich durch die Verwendung eines Timers umgehen. Denn der läuft unabhängig von der CPU und würde der CPU den Zeitablauf mittels Interrupt melden.
Gruß
Thomas
Hallo Thomas,
fürs erste reicht mir das "Zeitverbraten" für mein Programm . Wie ich gelernt habe führen viele Wege zum Ziel.
Aber ich behalte das im Hinterkopf. Ich hätte sogar einen Timer im System zur Verfügung. Da muss ich mich tatsächlich noch damit beschäftigen.
Danke & VG
Ich hätte sogar einen Timer im System zur Verfügung.
Rein aus Interesse: Was für ein System ist denn das?
Für den TIM-1