C64 Videospeicher im Bitmap-Grafikmodus

  • C64 Videospeicher im Bitmap-Grafikmodus

    Hallo!

    Ich beschäftige mich gerade mit der Grafikprogrammierung des C64, im Moment mit dem monochromen Bitmap-Modus mit der Auflösung 320 x 200.
    Allerdings ist mir die Aufteilung des Videospeichers in diesem Modus nicht so ganz klar. Ich hab ja grundsätzlich 40 x 25 Kästchen wobei jedes in 8 Zeilen unterteilt ist, deswegen ergibt sich ja die Auflösung (40 x 8 = horizonzal 320 Punkte, 25 * 8 = vertikal 200 Punkte)

    Jedes Kästchen besteht aus 8 Zeilen und jede dieser Zeilen wird durch ein Byte im Speicher repräsentiert.
    Speicheradresse 8192 (so steht's zumindest in dem Text den ich da vorliegen habe) stellt also die Punkte mit den Koordinaten x von 0 bis 7 und y=0 dar.
    Adresse 8193 die Punkte mit den Koordinaten x von 0 bis 7 und y=1.
    Und Adresse 8199 dann die Punkte mit x von 0 bis 7 und y=7

    Dann geht's weiter mit Adresse 8200 welche die Punkte mit x von 8 bis 15 und y=0 darstellt.

    Hab ich das soweit richtig verstanden oder läuft das komplett anderes mit der Aufteilung?

    lg, Markus
  • Jo. Der Vollständigkeit halber: Du landest bei 8192+320, also 8512 bei dem Byte, das für Y=8 und X=0..7 zuständig ist.

    Die Anordnung läßt sich dann in einer Adreßfunktion zusammenfassen, welche für jede X- und Y-Koordinate die richtige Adresse liefert:

    AD=8192+8*INT(X/8)+320*INT(Y/8)+(Y-8*INT(Y/8))

    Bei "Y-8*INT(Y/8)" handelt es sich um die Restwertbildung zu einer 2er-Potenz, und die läßt sich boolsch mit der Und-Verknüpfung vereinfachen und Du erhältst dann:

    AD=8192+8*INT(X/8)+320*INT(Y/8)+(YAND7)

    Die Klammern um YAND7 sind in BASIC notwendig, da AND nicht so stark bindet wie "+".

    Weiterhin kann man auch noch 8*INT(X/8) etwas vereinfachen - im Prinzip wird hier der Wert 3 Binärstellen nach rechts, und dann wieder 3 Binärstellen nach links verschoben. Das hat einfach den Effekt, daß die untersten 3 Bits gelöscht werden, und das kann man auch mit der Und-Verknüpfung handhaben:

    AD=8192+(XAND-8)+320*INT(Y/8)+(YAND7)

    Wobei -8 = %.....111111000 in 2-Komplement-Darstellung ist. ;)

    Zuguterletzt kann man den gleichen Trick auch noch auf 320 = 40*8 anwenden, und dann sind wir alle lästigen Divisionen im Ausdruck los:

    AD=8192+(XAND-8)+40*(YAND-8)+(YAND7)


    Edit: ich hab' gerade spaßeshalber mal alle vier Ausdrücke in eine doppelt geschachtelte Schleife mit X=0..319 und Y=0..199 gesteckt und die Zeit genommen. Ergebnis: 130324, 109894, 97565 und 87908 Jiffies.

    Steckt man dann noch 8192 in eine "frühe" Variable, spart man noch etwas: 72144 Jiffies. ^^

    Macht man das gleiche noch mit der 40, geht's runter auf 67847 Jiffies, aber damit dürfte in etwa das Ende der Fahnenstange erreicht sein.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Mike ()

  • Mike schrieb:

    Macht man das gleiche noch mit der 40, geht's runter auf 67847 Jiffies, aber damit dürfte in etwa das Ende der Fahnenstange erreicht sein.
    Ich hab' gerade das hier noch ausprobiert:

    Quellcode

    1. 1 DIMAD(199):FORY=0TO199:AD(Y)=8192+40*(YAND-8)+(YAND7):NEXT
    2. 2 T1=TI:FORY=0TO199:FORX=0TO319:AD=AD(Y)+(XAND-8):NEXT:NEXT:T2=TI
    3. 3 PRINTT2-T1
    35702 Jiffies. 8\|
  • Ein Jiffy ist der für den Computer "übliche" Zeittakt. Gängig sind 60 Jiffies pro Sekunde, man findet aber auch z.B. 100 oder 1000 Jiffies pro Sekunde oder sogar so krumme Werte wie 18,2 Jiffies pro Sekunde - letzteren bei PCs.

    Auf dem C64 entsprechen 60 Jiffies etwa einer Sekunde - der Takt wird intern aus einem CIA Timer generiert und ist nicht sehr genau (bezogen auf 1/60 Sekunde als tatsächliche Zeitspanne). Für Vergleichsmessungen reicht es aber allemal, dazu liest man mit TI die Jiffy-Clock unmittelbar vor und nach einem zu messenden Code-Stück und druckt die Differenz aus.

    de.wikipedia.org/wiki/Jiffy