Warten von bestimmten Milisekunden/Mikrosekunden

Es gibt 6 Antworten in diesem Thema, welches 1.734 mal aufgerufen wurde. Der letzte Beitrag (26. September 2015 um 14:39) ist von daybyter.

  • Hallo,

    ich werde ein Programm schreiben, was am Userport an einem Ein-/Ausgang eine bestimmte 1- und 0-Folge schreiben soll. Diese beiden Zustände müssen aber unterschiedlich lang im Milisekundenbereich oder sogar Mikrosekunden anliegen. Was mir aktuell fehlt: wie kann ich in ASM eine Routine schreiben, die das o. g. Warten erzeugt? Kann ich das ausrechnen? Dann als Counterschleife?

    So soll es sein:

    Oder so ähnlich :D .

    Im Moment weiß ich nicht weiter. Ich bin für Ideen dankbar ^^ .

    Marco

  • Das schöne am C64 ist, dass die Zeitdauer der Befehle exakt vorherbestimmbar ist. Bitte melde dich an, um diesen Link zu sehen.listet die Zyklen pro Befehl auf (die hängen nicht nur von den Befehlen sondern auch von der Adressierungsart ab, bei Branches auch davon, ob gebrancht wird oder nicht, und dann gibt es noch in paar Superspezialfälle). Damit lässt sich ein exaktes Timing mit etwas Fleißarbeit ausrechnen. Allerdings gibt es noch zwei Dinge zu beachten: IRQs unterbrechen das Programm und müssen je nachdem wie exakt das Timing sein muss deaktiviert werden. Außerdem unterbricht der VIC die CPU in den Badlines für 42 Zyklen. Wenn es also genauer als das sein soll, musst Du entweder den Bildschirm abschalten oder die zeitkritischen Dinge irgendwie zwischen den Badlines machen, oder die 42 Zyklen mitberücksichtigen (wann die Badlines kommen ist auch klar vorhersagbar).

    ────────────────────────────────────────────────────────────
    Bitte melde dich an, um diesen Link zu sehen. - Bitte melde dich an, um diesen Link zu sehen.
    ────────────────────────────────────────────────────────────

  • Moin.

    Heißt das, dass wenn der PAL C=64 985248Hz als CPU-Frequenz hat und ein Befehl z. B. NOP 2 Zyklen braucht, ich 2/985248 rechne, und somit auf eine Dauer von 0,00000203 Sekunden pro NOP komme? Also 2,03µs oder 0,002 ms? Müsste so sein, oder?!

    Ich benötige z. B. eine Wartezeit von 350µs. Demnach wäre die Rechnung 350/2,03=172,413793103. Also 172 mal das NOP. Jetzt nur mal als Beispiel.

    Jetzt weiß ich nicht: gibt es einen Timer/ein Register, den/welches ich auf 0 setzte kann, und ich dann bei 350 wieder raus aus der Pause kann? Aber das geht in Richtung IRQ. Da war ich '85 schon mal. Heute nach 30 Jahren ist das etwas schwierig wieder hineinzukommen ?( .

    Marco

  • Ich würde die CIA-Timer nehmen. Dort kann man exakt einstellen, wie viele Zyklen sie herunterzählen sollen.

  • Am Userport kämen evtl. auch noch die beiden seriellen Schieberegister der CIAs in Frage; deren Bitrate wird über Timer-Unterläufe gesteuert. Dann muss man keine Warteschleifen programmieren, sondern kann acht Bits mit festgelegtem Timing automatisch senden lassen.

    Yes, I'm the guy responsible for the Bitte melde dich an, um diesen Link zu sehen. cross assembler. And some Bitte melde dich an, um diesen Link zu sehen..

  • Deine Rechnung ist richtig! Statt 172 NOPs kannst Du Dir eine Schleife bauen:

    Code
    ldx #69 ; 2 Zyklen
    wait:
    dex     ; 69*2 Zyklen
    bne wait ; 68*3 (es wird gebrancht) + 2 (beim letzten Mal wird nicht mehr gebrancht) 
    ; hier sind also 2+69*2+68*3+2=346 Zyklen verbraucht, fehlen noch 4, wenns exakt sein soll
    nop ; 2 Zyklen
    nop ; 2 Zyklen TADA: genau 350 Zyklen sind um

    Wenn Du nur eine Handvoll verschiedener Längen brauchst, würde ich entsprechende Subroutinen bauen (da natürlich jsr und rts Zyklen berücksichtigen). Wenn die Verzögerungen zur Laufzeit verändert werden sollen oder es viele verschiedene gibt, ist evtl. ein Timer-IRQ besser.

    EDIT: viel zu langsam :evil:

    ────────────────────────────────────────────────────────────
    Bitte melde dich an, um diesen Link zu sehen. - Bitte melde dich an, um diesen Link zu sehen.
    ────────────────────────────────────────────────────────────

  • Du solltest vielleicht noch checken, ob es ein PAL c64 ist. Nicht das ein NTSC User Dein Programm startet.