17
« am: 11. August 2004, 12:08 »
Hi,
ich hab mir aus Spaß und Interesse eine kleine Grafikdemo im Real-Mode gebastelt. Dazu hab ich den Grafik-Modus 13h (320*200, 256 Farben) benutzt. Mein Ziel war es einen Interpolationseffekt zu erzeugen. Für alle die nicht wissen was ich meine, erklär ich es mal. Ich hab die Farbpalette über Ports mit 240 Farben belegt, wobei Eintrag 0 schwarz ist und die Palette mit aufsteigenden Einträgen dunkelrot, hellrot, gelb und bei Eintrag Nummer 240 schließlich mit weiß belegt ist. Wenn ich jetzt ein weißes Objekt zeichne und der Interpolationseffekt anwende, entsteht eine Art Feuereffekt. Ist keine neue Sache, aber ich wollte es halt mal machen.
Mein Problem ist die Geschwindigkeit der Interpolationsroutine. Ich habe vor Jahren den gleichen Algorithmus mit Pascal umgesetzt und es lief auf einem 60 MHz - Rechner recht gut. Jetzt mit NASM und auf einem 2,7 GHz - Rechner, kann ich die Durchgänge fast mitzählen. Vielleicht hab ich irgendwas verhauhen. Hier ist der Quelltext des Interpolationsalgorithmus:
.start:
mov ax, 0a000h ; Segment-Adresse vom Bildschirmspeicher
mov es, ax ; nach es schreiben
mov si, 0 ; si auf null setzen -> Anfang des Bildschirmspeichers
mov cx, 64000 ; Zähler auf 64000 -> jeder Punkt
.loop:
xor dx, dx ; dx auf null setzen
xor ax, ax ; ax auf null setzen
mov al, [es:si-1] ; Farbwert des linken Punktes nach al
mov dl, [es:si+1] ; Farbwert des rechten Punktes nach al
add ax, dx ; Beide Werte addieren, Ergebnis in ax
mov dl, [es:si-320] ; Farbwert des oberen Punktes nach dl
add ax, dx ; und zu ax addieren
mov dl, [es:si+320] ; Farbwert des unteren Punktes nach dl
add ax, dx ; und zu ax addieren
shr ax, 2 ; Summenfarbwert in ax durch 4 teilen
or ax, ax ; Flags setzen
jz .zero ; Wenn ax = 0, springe zu .zero
dec ax ; Wenn ax nicht null, um eins erniedrigen
.zero:
mov [es:si], al ; neuen Farbwert setzen
inc si ; si erhöhen -> nächster Punkt
dec cx ; Zähler erniedrigen
jnz .loop ; Solange Zähler nicht 0, springe zu .loop
mov ah, 01h ; Funktion zur Überprüfung des Tastaturpuffers
int 16h ; Wenn ZF = 1 dann ist kein Zeichen vorhanden
jz .start ; Wenn kein Taste gedrückt, dann nächster Durchgang
Noch mal zur Erklärung: Der Algorithmus berechnet für jeden der 64000 Bildpunkte den Farbwert aus den 4 angrenzenden Punkten, indem ein Mittelwert ihrer Farbwerte gebildet wird und dieser um eins erniedrigt wird.
thx for your help!!