Hello, Guest the thread was called10k times and contains 106 replays

last post from WTE at the

Basic / Maschinensprache

  • Hallo Freunde !


    Ich habe mal ein paar Fragen zu Maschinensprache. Zwar habe ich mal meine Bücher gewälzt und kann Sachen wie "A9 00..." übersetzen in " LDA #$00", usw.
    aber ich verstehe das ganze nicht wirklich !! Indiziert, indirekt indiziert...Häää? Sorry. Daher mal die Frage , die einfache POKE-Anweisung POKE 56577,A - wie
    würde man das in Maschinensprache schreiben...? Der Hintergrund : ich möchte ein Programm, das immer und immer wieder eine Variable z.B. "A" in die Adresse
    56577 schreibt , so modifizieren, dass ich diese Anweisung als Maschinenprogramm ablege (am Anfang des PRG) und dann per SYS aufrufe, wenn ich einen Wert
    für A übergeben will. Wie müsste ich das umsetzen ? Ich möchte die Anweisungen wie LDA,STA, usw. per DATA am Anfang des PRG in den Speicher schreiben, z.B.
    ab Adresse 21248 oder so...dann später SYS 21248, usw...


    Bitte die Antworten wirklich nur auf das beschränken, was ich machen möchte, ansonsten wird es für mich zu schwierig...


    LG
    Cat
    (hrine)

  • Für absolute Anfänger dürften POKEs am einfachsten sein: POKE250,A:SYS21248. Das Maschinenprogramm würde den Wert dann aus Speicherzelle 250 lesen. Alternativ gibt es noch die USR()-Funktion, deren Argument an genau definierter Stelle in der Zeropage landet - allerdings als Float-Wert.
    Der nächstkompliziertere (aber auch komfortablere) Weg wäre dann so etwas wie SYS21248,A. Hier würde das Maschinenprogramm als erstes ein paar Betriebssystemroutinen aufrufen, die das Komma überlesen und den folgenden Basic-Ausdruck auswerten.
    Dein ursprüngliches Problem habe ich übrigens nicht verstanden - was versprichst Du Dir davon, den einen POKE in Maschinensprache statt in Basic durchzuführen? Oder soll es "immer wieder" passieren, während das Basic-Programm etwas ganz anderes tut? In letzterem Fall bräuchtest Du nämlich eine Interrupt-Erweiterung...

  • Hi !


    Es ist noch etwas mehr : ich habe mir eine Porterweiterung gebaut, bei der ich 7 A und 1 E habe, die (natürlich) je 8-Bit breit sind.
    Nun muss per Poke zunächst der entsrechende A oder der E gewählt werden und dann übergibt man den Wert (der Variablen) in Form von
    8 Bit. Dies passiert ständig. Es ist eine Schaltung ähnlich 64xAussenwelt von 64'er (SH 67 oder 84 ?) Ich möchte halt die Variable "A" oder "XY" (wie auch immer)
    per Maschinensprache steuern, weil ich sonst in Basic durch die ständige Schleife ewig brauche, um nacheinander alle 8 Ports zu durchlaufen. Ich habe aber keine
    Peilung von Assembler oder MSE um mir das komplett in MAschinensprache zu bauen. Ich möchte nur den Teil, der die VAriable übergibt (oder liest) auslagern.
    Ich muss sonst immer per Gosub zu den Ports springen , schreiben/ lesen und zurück


    Das mit "POKE 250,A..." verstehe ich schon nicht...


    Es gibt doch ganz einfache Befehle wie "LDA" usw. die dem Poke entsprechen. Aber wie ich eine Variable hinbringe verstehe ich nicht
    Es wäre ja sonst (angenommen A wäre mal festgelegt auf 255) .5300 LDA #$FF STA $DD01 --- also .5300 A9 FF 85 DD 01 (oder? ) ??


    Würde bei SYS 21248 ja quasi Poke 56577,255 entsprechen ?


    Gruss Cat

  • Ich habe das mal angehangen.
    Diese Sache möchte ich jeweils (pro Port) auslagern und jeweils per SYS aufrufen...
    Die GOSUB 9000/9200 bitte nicht beachten (fallen weg) !!!
    Jeweils 1 Port soll ein SYS-Block sein !
    READY.
    1000 REM
    1005 REM ------------------------------
    1007 REM
    1010 REM ******************
    1020 REM * PORT 0 EINGANG *
    1025 REM ******************
    1027 REM
    1030 POKE 56576,PEEK(56576) AND 255-4
    1040 POKE 56590,PEEK(56590) OR 64
    1050 POKE 56334,PEEK(56334) OR 64
    1060 GOSUB 9000:POKE56579,0
    1065 EIN=PEEK(56577):POKE 56579,255
    1067 GOSUB 9200
    1070 POKE 56576,PEEK(56576) OR 4
    1080 POKE 56590,PEEK(56590) AND 255-64
    1090 POKE 56334,PEEK(56334) AND 255-64
    1100 REM
    1105 REM
    1110 REM ***********
    1120 RETURN:REM * ZURUECK *
    1130 REM ***********
    1140 END
    1150 REM ------------------------------
    2000 REM
    2010 REM ******************
    2020 REM * PORT 1 *
    2030 REM ******************
    2040 REM
    2050 POKE 56576,PEEK(56576) OR 4
    2060 GOSUB 9000
    2070 POKE 56577,AUS:GOSUB 9200
    2080 POKE 56576,PEEK(56576) AND 255-4
    2100 REM
    2110 REM ***********
    2120 RETURN:REM * ZURUECK *
    2130 REM ***********
    2140 END
    2150 REM ------------------------------
    3000 REM
    3010 REM ******************
    3020 REM * PORT 2 *
    3030 REM ******************
    3040 REM
    3050 POKE 56590,PEEK(56590) AND 255-64
    3060 GOSUB 9000
    3070 POKE 56577,AUS:GOSUB 9200
    3080 POKE 56590,PEEK(56590) OR 64
    3100 REM
    3110 REM ***********
    3120 RETURN:REM * ZURUECK *
    3130 REM ***********
    3140 END
    3150 REM ------------------------------
    4000 REM
    4010 REM ******************
    4020 REM * PORT 3 *
    4030 REM ******************
    4040 REM
    4050 POKE 56576,PEEK(56576) OR 4
    4060 POKE 56590,PEEK(56590) AND 255-64
    4065 GOSUB 9000
    4070 POKE 56577,AUS:GOSUB 9200
    4080 POKE 56576,PEEK(56576) AND255-4
    4090 POKE 56590,PEEK(56590) OR 64
    4100 REM
    4110 REM ***********
    4120 RETURN:REM * ZURUECK *
    4130 REM ***********
    4140 END
    4150 REM ------------------------------
    5000 REM
    5010 REM ******************
    5020 REM * PORT 4 *
    5030 REM ******************
    5040 REM
    5050 POKE 56334,PEEK(56334) AND 255-64
    5060 GOSUB 9000
    5070 POKE 56577,AUS:GOSUB 9200
    5090 POKE 56334,PEEK(56334) OR 64
    5100 REM
    5110 REM ***********
    5120 RETURN:REM * ZURUECK *
    5130 REM ***********
    5140 END
    5150 REM ------------------------------
    6000 REM
    6010 REM ******************
    6020 REM * PORT 5 *
    6030 REM ******************
    6040 REM
    6050 POKE 56576,PEEK(56576) OR 4
    6060 POKE 56334,PEEK(56334) AND 255-64
    6065 GOSUB 9000
    6070 POKE 56577,AUS:GOSUB 9200
    6080 POKE 56576,PEEK(56576) AND 255-4
    6090 POKE 56334,PEEK(56334) OR 64
    6100 REM
    6110 REM ***********
    6120 RETURN:REM * ZURUECK *
    6130 REM ***********
    6140 END
    6150 REM ------------------------------
    7000 REM
    7010 REM ******************
    7020 REM * PORT 6 *
    7030 REM ******************
    7040 REM
    7050 POKE 56590,PEEK(56590) AND 255-64
    7060 POKE 56334,PEEK(56334) AND 255-64
    7065 GOSUB 9000
    7070 POKE 56577,AUS:GOSUB 9200
    7080 POKE 56590,PEEK(56590) OR 64
    7090 POKE 56334,PEEK(56334) OR 64
    7100 REM
    7105 REM
    7110 REM ***********
    7120 RETURN:REM * ZURUECK *
    7130 REM ***********
    7140 END
    7150 REM ------------------------------
    8000 REM ******************
    8010 REM * PORT 7 *
    8015 REM ******************
    8020 REM
    8030 POKE 56334,PEEK(56334) AND 255-64
    8040 POKE 56590,PEEK(56590) AND 255-64
    8050 POKE 56576,PEEK(56576) OR 4
    8055 GOSUB 9000
    8060 POKE 56577,AUS:GOSUB 9200
    8070 POKE 56576,PEEK(56576) AND 255-4
    8080 POKE 56590,PEEK(56590) OR 64
    8090 POKE 56334,PEEK(56334) OR 64
    8100 REM
    8110 REM ***********
    8120 RETURN:REM * ZURUECK *
    8130 REM ***********
    8140 END
    8150 REM ------------------------------

  • Wenn Deine Variable nur 8 Bit braucht, kannste die doch vor Aufruf des Assemblerparts irgendwo in den Speicher schreiben und danach wieder auslesen. Das meinte Mac Bacon auch mit POKE250,A. Keine Ahnung, was Du daran jetzt nicht verstehst, bzw. was man daran nicht verstehen könnte.
    Dein Listing lässt sich astrein in Assembler umschreiben.

  • Quote

    Diese Sache möchte ich jeweils (pro Port) auslagern und jeweils per SYS aufrufen...
    Die GOSUB 9000/9200 bitte nicht beachten (fallen weg) !!!


    Hm, irgendwie habe ich das so verstanden, dass Du mit "Diese Sache" Dein Listing meinst. Wenn Du den Teil meinst, der bei 9000/9200 dann wegfallen soll, wäre es vielleicht schlau, eben diesen Teil zu posten.


    Ich denke übrigens, dass Du, wenn Du das in Basic verstehst, dieses auch in Assembler verstehen würdest.

    Code
    1. POKE ADRESSE1, WERT


    wird zu

    Code
    1. LDA #WERT
    2. STA ADRESSE1


    und

    Code
    1. POKE ADRESSE1, PEEK(ADRESSE2) AND WERT


    wird zu

    Code
    1. LDA ADRESSE2
    2. AND #WERT
    3. STA ADRESSE1


    analog: OR WERT entspricht dann ORA #WERT

  • @CotS: Was ich bis jetzt verstanden zu haben glaube, ist:
    1. Du hast ein Basic-Programm und willst kleine Teile davon in Maschinensprache umwandeln.
    2. Dafür brauchst Du irgend eine Form der Parameterübergabe, damit Werte zwischen Basic und Assembler ausgetauscht werden können.
    3. Dir fehlen noch ein paar Grundlagen, sonst würden wir nicht so ratlos aneinander vorbei diskutieren. ;)


    Also: Basic-Variablen wie Deine "EIN" und "AUS" sind Hochsprachenkonstrukte, die es in Maschinensprache so nicht gibt. Der Basic-Interpreter sucht für diese Variablen freien Speicher und legt sie dort ab. Jedes Mal, wenn im Basic-Programm die Variable EIN benutzt wird, durchsucht der Interpreter erst all seine Variablen nach der mit dem richtigen Namen und kann erst dann auf den Wert zugreifen.
    Der Prozessor dagegen greift immer nur auf Speicherzellen zu, es gibt also keine Assemblerbefehle, die auf Basic-Variablen zugreifen könnten. Zwar kann man natürlich die Routinen des Basic-Interpreters aufrufen, welche Basic-Variablen suchen, anlegen oder benutzen, aber das ist hier nicht sinnvoll (tm). Wenn Du den Wert einer Basic-Variablen in einer Assembler-Routine benutzen willst, dann solltest Du Dich für eine der in Post #3 genannten Methoden entscheiden.


    Möglicherweise ist es sinnvoll, wenn Du einmal das Programm auflistest, wie es Dir so vorschwebt, also mit SYS-Aufrufen an den entsprechenden Stellen (auch wenn die ins Leere gehen, weil noch keine Assemblerroutinen existieren). Die Übergabe eines Wertes an eine Assemblerroutine sähe dann so aus: "sys ROUTINE, WERT, NOCH_EIN_WERT" und die Rückgabe so: "sys ROUTINE:VARIABLE = peek(IRGEND_EINE_SPEICHERZELLE)".


    Dann wird vielleicht auch klar, was genau Du Dir eigentlich von den Assemblerroutinen versprichst, denn signifikant schneller oder übersichtlicher wird Dein Programm dadurch nicht werden (dazu müsste man größere Teile konvertieren als nur eine Handvoll POKEs). Aber vielleicht fällt dann jemandem eine andere/bessere Lösung ein, wie man das eigentliche Problem lösen könnte.

  • wobei SYS ja schon von sich aus A/X/Y aus 780/81/82 holt und wieder dahin zurückschreibt.

    Quote

    Dann wird vielleicht auch klar, was genau Du Dir eigentlich von den Assemblerroutinen versprichst, denn signifikant schneller oder übersichtlicher wird Dein Programm dadurch nicht werden (dazu müsste man größere Teile konvertieren als nur eine Handvoll POKEs). Aber vielleicht fällt dann jemandem eine andere/bessere Lösung ein, wie man das eigentliche Problem lösen könnte.


    jau, sinn würde es vmtl erst dann machen wenn man den ganzen "treiber" da komplett nach asm übersetzt

  • http://www.c64-wiki.de/index.p…cht_6502-Assemblerbefehle


    Die Befehle in ASM sind sehr einfach beim C64er gehalten. Und in der Tabelle so gut erklärt, daß sogar ich es verstehe.


    Was Dich da verwirrt ist einfach erklärt:


    Der C64er-Prozessor erlaubt grundlegende 16-Bit Zeigeroperationen. So kannst Du zu so einem Zeiger eine 8-bit Zahl hinzuaddieren und einen Wert in die Speicherzelle einprägen, auf die der Zeiger sodann gerichtet sein würde:


    sta (zeiger16),y


    Zu beachten ist noch, daß der höherwertige Wet einer 16-bit-Zahl hinten steht. Also auch eines Zeigers.
    Und der Zeiger muß eine Adresse $00xx haben, sonst gibt es eine Fehlermeldung Range.

  • Wenn Du den Teil meinst, der bei 9000/9200 dann wegfallen soll, wäre es vielleicht schlau, eben diesen Teil zu posten.


    Nein, das soll hier nur nicht beachtet werden...ich habe es nicht aus dem Listing gestrichen.


    Zum Rest Deines Postings :


    Genauso meinte ich es ... Das habe ich auch so grade verstanden.
    Ich möchte dann im Programm per DATA's den Maschinencode erzeugen.


    Z.B. POKE 56579,255 (Datenrichtungsregister=Ausgabe)


    Ich habe es mal so eingegeben :


    10 FOR I= 21248 TO 21252
    20 READ N
    30 POKE I,N
    40 NEXT I
    100 DATA 169,255,133,221, 3


    Wäre das richtig ? Die Adresse 56579 muss ich splitten in 221 für "DD" und 3 für "03" , weil 56579 ja DD03 EHX ist, oder ist das falsch ?

  • Andersherum; das Lowbyte kommt zuerst. Also DATA 160,255,133,3,221,96. Die 96 ist der Opcode für RTS, also den Rücksprung.


    Auweia - siehste...das ist schon so ein Problem und verursacht mir Knoten im Kopf.


    Jetzt die Masterfrage zum probieren am Cevi :


    wenn ich Jetzt die Befehlsfolge POKE 56579,255:POKE56577,2 darstellen möchte, aber sagen wir mal jeweils als Block (Nur zum Üben)
    Also ich möchte mit einem SYS POKE 56579,255 hervorrufen und mit einem 2. SYS POKE 56577,2


    Dann so (?) :


    10 FOR I= 21248 TO 21259
    20 READ N
    30 POKE I,N
    40 NEXT I


    100 DATA 169,255,133, 3,221, 96, 169, 2,133, 1,221,96


    SYS 21248 wäre dann POKE56579,255 und SYS 21254 POKE56577,2 ??

  • Cool ,ich habe doch was verstanden !! Ich hatte das nämlich grade fragen wollen, denn $DD03 ($DD01) ist ja eine Adresse und kein Wert,
    also muss dass "absolut" sein und nicht "unmittelbar" (mit # für Werte), richtig !?


    Ist denn die Methode so anwendbar ? mit den beiden SYS-Blöcken, wie ich es geschrieben habe :


    10 FOR I= 21248 TO 21259
    20 READ N
    30 POKE I,N
    40 NEXT I
    100 DATA 169,255,141, 3,221, 96, 169, 2,141, 1,221,96




    SYS 21248 wäre dann POKE56579,255 und SYS 21254 POKE56577,2 ??

  • PS :ich habe mich entschieden die Übergabe der Variablen einfach weiter im Basicprogramm vorzunehmen.


    ich werde nur die Portauswahl per SYS regeln. Ich habe die gerade geübten Zeilen probiert am Cevi direkt und es
    geht gut...!


    Also mache ich es so :



    10 ...(irgendwelche Progammteile)
    20 ....
    30 SYS "YXZ" (Aufruf PORT 1)
    40 POKE 56577,AUS
    50 ...
    60 SYS "UVW" (Aufruf Port 2)
    70 POKE 56577,AUS
    ....


    Zum Beispiel....


  • Ich danke Dir sehr, aber das verstehe ich wirklich kaum.
    Sorry - ich habe da wohl eine Lernschwäche (logikschwäche)
    Oder das Alter ? Oder beides...


    :-(

  • Quote

    Zitat


    Ich danke Dir sehr, aber das verstehe ich wirklich kaum. Sorry - ich habe da wohl eine Lernschwäche (logikschwäche)


    daran liegt es nicht. halte dich an das was mac bacon sagte.


    Das klappt soweit !


    Übungsmässig mal 3 Blöcke geschrieben - entsprechend DDR auf AUS, PB0-7 irgendeinen Wert und DDR wieder auf EIN, usw...
    Userport Monitorstecker (LED'S) rein-klappt !


    LG & Dank Cat
    -bin für jeden weiteren Tipp natürlich dankbar.