Hallo Besucher, der Thread wurde 2,5k mal aufgerufen und enthält 11 Antworten

letzter Beitrag von Ingo am

Bitmap bei $d000

  • Hallo,


    bin gerade dabei, mir eine Basic-Erweiterung zu basteln.
    Dabei habe ich schon ein paar Grafikbefehle programmiert, die auch soweit funktionieren.
    Der eine Befehl schaltet den Multicolor-Bitmapmodus an. Den Speicherort der Bitmap und des Screenram kann man dabei als Parameter übergeben. Wenn ich allerdings die Bitmap auf $d000 legen will, kommt Grafikmüll raus (die ersten 512 Bytes), auch die Linie, die ich zeichne (mit meinem Line-Befehl) kommt nach unten versetzt raus. Also Bitmap bei $d000 und Screenram bei $cc00.
    $d018 stimmt auch soweit: Hat den Wert $34.
    Wenn ich den Screen auf $d000 lege und die Bitmap z.B. auf $e000, dann funktioniert's.
    Kann man prinzipiell die Bitmap nicht auf $d000 legen?
    Anbei mal screenshots, wie's normal aussehen soll und einmal mit Bitmap bei $d000.

  • Die Bitmap lässt sich nur in $2000-Schritten verschieben, bei $34 wird die 4 leider ignoriert. Am besten mal das hier anschauen:


    http://codebase64.org/doku.php…e:vicii_memory_organizing

  • Kommt auf die Basic-Version drauf an, bei V2(C64) können noch keine Werte direkt übergeben werden, man kann nur über die Speicherstellen 780, 781, 782 die Register A, X, Y vorbelegen.


    S. https://www.c64-wiki.de/wiki/SYS


    EDIT: Ansonsten kann man natürlich den Wert der Variable an eine beliebige Speicherstelle POKEn, und dann in ASM wieder auslesen.

  • Auf der Seite steht unter Beispielen folgendes:


    SYS F1,A$,15In der Variable F1 ist eine Adresse einer Maschinenspracheroutine hinterlegt, die dann auch noch die folgenden Parameter, nämlich ein Zeichenkettenvariable erwartet und eine Zahl auswertet. Beispielsweise als besondere INPUT-Implementierung, die für eine Formulareingabe die freie Cursor-Bewegung einschränkt oder die eingebbaren Zeichen entsprechend sinnvoll einschränkt.


    D.h. man kann Stringvariablen übergeben, aber Felder nicht?

  • Ok, da steht auch:

    Zitat

    Weitere Parameter können angegeben werden, müssen aber vom Maschinenprogramm aus mit Hilfe der entsprechenden Interpreter-Routinen (wie sie auch für BASIC-Erweiterung Verwendung finden) verarbeitet werden.


    D. h. es geht also doch irgendwie, scheint aber etwas komplizierter zu sein. Mit Feldern wirds dann wohl richtig schwierig, aber da muß ich dann passen...

  • Beispiel:

    Code
    1. print 1:sys 49152dingsbums:print 2

    Nach dem "print 1" folgt ein Doppelpunkt; an dieser Stelle weiß der Basic-Interpreter also, dass keine weiteren Parameter folgen. Er kehrt also von PRINT zurück in die Hauptschleife und liest als nächstes das Token für SYS, woraufhin er die Behandlungsroutine für SYS anspringt. Dort wird nun eine Unterroutine zum Einlesen der Einsprungadresse aufgerufen - diese stoppt beim "d" von "dingsbums" und gibt den bisherigen Wert (49152) zurück. Nun werden die Register mit den Werten aus der Zeropage geladen und es erfolgt der Sprung nach 49152.
    --- jetzt ist die eigene Routine aktiv, diese kann tun und lassen, was immer sie will ---
    Springt die eigene Routine nun mit einem RTS zurück, so erwartet der Interpreter das Ende der Anweisung zu finden, also einen Doppelpunkt oder ein Zeilenende. Stattdessen findet er aber das "d" von "dingsbums" vor und erzeugt deshalb einen Syntax Error.


    Wenn nun aber die eigene Routine den Basic-Zeiger so weiterstellt, dass das "dingsbums" überlesen wurde, ist der Rücksprung gar kein Problem. Genau das ist auf der Wikiseite gemeint. Es gibt Interpreter-Routinen für "erwarte ein Komma - wenn es da ist, überlies es; wenn es nicht da ist, erzeuge einen Syntax Error" oder "lies eine Zahl ein" oder "lies einen beliebigen Ausdruck ein" oder "lies einen Variablennamen und such die Variable". Grundsätzlich kann man also alles verarbeiten - Zahlen, Ausdrücke, Strings, Felder, etc. - man muss "nur" die richtigen Routinen aufrufen bzw. die Zeichen aus dem Basic-Text selbst verarbeiten.

  • Ich hab da (noch aus alten Tagen) immer meine Kochrezepte ...


    String einlesen: SYS adr,<String-Ausdruck)>

    Code
    1. JSR $AEFD ; auf Komma prüfen
    2. JSR $AD9E ; Ausdruck auswerten
    3. JSR $B6A3 ; auf String prüfen und Descriptor auslesen


    X,Y String-Adresse (auch in $22/$23)
    A String-Länge
    $64/$65 Zeiger auf String-Descriptor


    16-Bit-Wert einlesen: SYS adr,<nummerischer-Ausdruck>

    Code
    1. JSR $AEFD ; auf Komma prüfen
    2. JSR $AD8A ; nummerischen Ausdruck auswerten
    3. JSR $B7F7 ; in 16-Bit-Wert wandeln (steht in $14/$15 bzw. Y (low), A (high)


    8-Bit-Wert einlesen: SYS adr,<nummerischer-Ausdruck>

    Code
    1. JSR $B7F1 ; auf Komma prüfen und Ausdruck auswerten und auf 0-255 prüfen


    Wert in X bzw. auch in $65


    Damit kann man mal Werte verarbeiten, die aus Variablen kommen oder aber generelle Ausdrücke darstellen.
    Möchte man tatsächlich auf Variablen zugreifen oder Arrays selbst durcharbeiten, dann braucht man den Variablenzeiger.


    Code
    1. JSR $B08B ; Variable suchen


    $47/$48 hat den Zeiger auf den Wert (ja nach Typ ein Float, Integer oder ein String)$45/$46 hält den Variablennamen
    $5F/$60 hält den Zeiger auf den Array-Kopf (wenn > als Zeiger in $2F/$30) oder auf den Variablenwert bei einer einfachen Variable
    $0D Typ-Flag (negativ -> String)
    $0E Typ-Flag (negativ -> Integer)


    Umgekehrt, einen Wert in einen Variable zurückschreiben, z.B. 8-Bit-Wert in Variable R:

    Bit 7 bei den Variablenbuchstaben ist nicht gesetzt -> Float-Variable.