Assembler - Projekt in Basic realisieren

  • Hallo liebe C-64 Gemeinde!


    Ich verstehe etwas Assembler-Programmierung, aber trotzdem tauchen bei mir einiger Verständnisfragen auf. Ist der folgende Assemblercode auch in Basic umsetzbar?
    Natürlich spielt erst mal die Geschwindigkeit erst mal keine Rolle. Es geht um die Ansteuerung eines Roland MPU-401 Interface. Es ist ein Midi-Interface, das mit Hilfe eines Interface über den Expansionsport mit dem C-64 angesteuert werden kann. Ich habe mir bezüglich ein pdf-Handbuch downgeladen in dem einige Assemblerprogramme als Beispiel aufgeführt werden. Zum Beispiel soll die folgende Routine einen Befehl an die Roland - MPU schicken nach folgenden Prinzip :



    1. [tt]test DRR (bit 6) of STATPORT.
    2. [tt]if bit 6 = 1, then goto step 1.
    3. [tt]disable interrupts.
    4. send command to COMPORT of the MPU-401.
    5. test DSR (bit 7) of STATPORT.
    6. if bit 7 = 1, then goto step 5.
    7. read DATAPORT.
    8. if data = acknowledge ($FE), then step 9. else no acknowledge. so:
    a. all interrupt service routine. using software interrupt (machine dependent).
    b. goto step 5.
    9. enable interrupts.
    10. return to caller



    Habe ich das richtig verstanden, dass beim Punkt 8 a ein entsprechender eigender Software Interrupt umgesetzt werden muss. Im konkreten Fall für den C-64?


    Wenn man das jetzt in Assember umsetzen will, dann wäre das ja dieser Assember-Code:


    DATAPORT equ $C080+no; n=slot
    COMPORT equ $C081+n0; n=slot
    STATPORT equ $C081+n0; n=slot


    Ist das jetzt ein Fehler, dass die Adressen vom Comport und Statport identisch sind. Was bedeuten die slots? Sind damit die Adressen des C-64-User-Ports gemeint?


    DSR: equ $80
    DRR: equ $40


    TEMP ds 1
    combfr ds 1
    ack equ $FE
    int1 equ fixed_entry ; in the section 8 ; send command thru combfr


    Sn.Cmd: lda STATPORT; get status
    and #DRR; test bit 6
    bne Sn.Cmd; if bit 6 = 1 then keep tryiing
    sei; mask interrup
    lda combfr; get comand
    sta COMPORT; send to the MPU-401


    in Basic würde ich diesen Teil jetzt so umsetzen wollen:


    10 DATAP = 49280 [ Ich weiss natürlich nicht, was diese slots zu bedeuten haben. Die Adressen des C-64 Expasionsports?. Die müssen ja dann anscheinend noch zu den Wert hinzuaddiert werden ]
    20 COMP = 49281
    30 st = Peek (COMP)


    Ich wüsste jetzt nicht, wie ich das Bit 6 in Basic testen könnte. Eine Idee wäre, dass ich mit Hilfe von AND das Bit maskiere und anschließend prüfe, ob es 1 ist.


    40 bit = st AND 32
    50 if bit = 32 THEN GOTO 40
    60 ? Wie kann ich von Basic aus den Interrup maskieren?
    70 com = 1
    80 Poke COMP,com


    Bin ich da auf den richtigen Weg? Oder, ist das Blödsinn :cursing:


    Der Assemblercode geht noch weiter, aber wäre die erste Basic-Umsetzung schon ok?


    VG :winke:

  • Ohne das Programm jetzt im Detail verstanden zu haben: IRQ in Basic ausschalten ist wohl schwierig bis unmöglich. Insbesondere sehe ich das Problem, dass der IRQ vermutlich aus Timinggründen ausgeschaltet werden soll, und in Sachen Timing hat man in Basic natürlich ganz schlechte Karten, weil jeder Befehl 1000e Zyklen braucht.


    Wenn Du das ganze von Basic aus benutzen willst, müsste man vermutlich die zeitkritischen Routinen in Maschinensprache behalten und per SYS aufrufen.

    ────────────────────────────────────────────────────────────
    Time of Silence - Time of Silence 2 Development Blog
    ────────────────────────────────────────────────────────────

  • IRQ in Basic ausschalten ist wohl schwierig bis unmöglich.

    Nö, das ist doch mit einem POKE zu CIA1 erledigt.

    Insbesondere sehe ich das Problem, dass der IRQ vermutlich aus Timinggründen ausgeschaltet werden soll, und in Sachen Timing hat man in Basic natürlich ganz schlechte Karten, weil jeder Befehl 1000e Zyklen braucht.

    This. Der Pseudocode da oben sieht nach Bitbanging-Interface aus, bei dem der Sender den Takt vorgibt (DATAPORT muss gelesen werden, sobald auf DSR ein Low-Taktbit hereinkommt)... Damit das funktioniert, muss der Empfänger schnell genug sein. Wie schnell genau, müsste im PDF stehen.

  • Nö, das ist doch mit einem POKE zu CIA1 erledigt.

    Argh, natürlich :platsch: . Ich dachte an sei und an die cli's die munter im ROM verteilt sind, aber so geht es natürlich auch.

    ────────────────────────────────────────────────────────────
    Time of Silence - Time of Silence 2 Development Blog
    ────────────────────────────────────────────────────────────

  • Was sind denn diese slots?

    Der Beispielcode läuft auf dem AppleII. Hier wird das Interface über die AppleII-spezifischen Slots und deren Softswitches eingebunden. Prinzipiell kannst Du aber den Code übernehmen, sofern Du weißt, welche Speicherstellen Du am C64 abfragen mußt. Da das Gerät am Expansionsport angeschlossen wird, würde ich (als Nichtexperte von externen Geräten) vermuten, daß irgendwo zwischen $de00 und $dfff Speicheradressen sind, die analog zu den Softswitches beim AppleII funktionieren. Hast Du vielleicht eine nähere Beschreibung für den C64, aus der man dies entnehmen kann?

    beim Punkt 8 a ein entsprechender eigender Software Interrupt umgesetzt werden muss

    Im Handbuch auf Seite 58 finden sich an dieser Stelle lediglich die Befehle CLI und RTS, d. h. das Programm springt ergebnislos, aber auch ohne jegliche Fehlermeldung zurück. Meiner Meinung nach dürfte es sich um einen Fehler handeln, wenn das Interface nicht mit ACK reagiert, z. B. weil keins angeschlossen ist. Wie das Programm darauf reagiert, liegt aber im Ermessen des Programmierers. Das mit dem Software-Interrupt ist mißverständlich ausgedrückt. Ich denke, es soll soviel bedeuten wie "Mache jetzt erst einmal irgendwas anderes und wiederhole den Vorgang später noch einmal." Der AppleII hatte von Natur aus keinen Interrupt. (Die verwendeten SEI und CLI sind sicherheitshalber eingefügt, falls eine externe Karte interruptfähig sein sollte.) Wollte man trotzdem quasi parallele Vorgänge abwickeln wie z. B. die Tastaturbehandlung, so mußte man diese Routinen immer wieder zwischendurch aufrufen. Dies wird hier wohl als "Software Interrupt" bezeichnet, hat aber mit den Interrupts am C64 nichts zu tun. Wie gesagt, was Dein Programm an dieser Stelle machen soll, liegt ganz bei Dir. Du kannst einfach warten, bis es irgendwann klappt (und dabei für den C64 die Interrupts wieder erlauben) oder mit einer Fehlermeldung zurückspringen.

  • Vielen Dank M.J.!


    Deine Ausführungen haben mir sehr geholfen. Ich war etwas irritiert wegen diesen Slots? Aber jetzt ist mir auch einiges klar.
    Leider habe ich keine weitere Beschreibung von der eigentlichen Iterface-Karte MIF-C64: Für den Commodore 64. Die Beschreibung fehlt mir, dann wäre alles auch einfacher.
    Mir liegt nur diese technische Beschreibung vom Roland MPU-401 vor.


    Das Problem mit dem Interrupt habe ich mir auch so gedacht, wie Du das beschrieben hattest.


    Ich wollte eigentlich nur in Basic das ganze mal testen, um überhaupt raus zu bekommen, ob die ganze Hardware noch funktioniert.
    Wollte das Interface in den Normal Midi Mode setzten und einfach mal eine Note spielen lassen per Midi. Mit einem einfachen Midi-Interface hatte ich das schon gemacht und es hat super funktioniert von Basic aus.
    Ich wollte jetzt keine Applikation in reinen Basic schreiben. Aber ich werde wahrscheinlich die eigentliche GUI in Basic gestalten und die zeitkritischen Routinen in Assembler umsetzten.


    Nochmals Danke! :)


    VG :winke: