Elméleti háttér:

A paletta: A monitorkártya itt tárolja az aktuális videómód színeit. A paletta egy eleme határoz meg egy színt. A paletta egy eleme (palettaregiszter) tartalmazza a vörös, a kék, és a zöld színösszetevőt (RGB regiszer v. színregiszter) . Ebből a három alapszínből minden szín kikeverhető, ezt a keverék színt látjuk mi a képernyőn. Egy alapszín értékének tárolására 6 bit van fenntartva tehát a maximális értékük 64. Ebből következik, hogy összesen 64*64*64=262144 színt tudunk kikeverni, ebből egyszerre csak 256-ot tudunk ábrázolni, mivel a palettának is 256 eleme van. Ezt a palettát természetesen átállítani is tudjuk: 

Tehát a palettát lehet a VGA BIOS-on keresztül, vagy portokon keresztül átírni/lekérdezni. 
BIOS-sal: A 10h megszakítás 1010h-s funkcióján keresztül:
AX=1010h
BX=a beállítandó palettaregiszter száma
DH=piros összetevő
CH=zöld összetevő
CL=kék összetevő

Na de ez nekünk túl egyszerű és logikus, ezért inkább portokat fogunk macerálni:

A $03c8 portra kiküldjük az átírni kívánt paletta regiszter számát, majd a $03c9 portra kinyomjuk egymás után a piros, zöld, kék (RGB) összetevőt. Miután mind a 3 összetevőt kilöktük, a kártya tök magától megnöveli a $03c8 regiszterben levő értéket. Ettől aztán ha folyamatosan írjuk át a palettát, nem kell mindig újból megadni, hogy melyik színt akarjuk, csak eregetjük ki a $03c9-re az összetevőket.

A plazma effekt: a paletta alapvetően a színek tárolására van kitalálva, de ugye a szerencsétlen  programozó véletlenül sem arra használja, amire éppeszű emberek megalkották. Ha megfelelő képet rakunk a képernyőre, és megfelelő palettát számolunk ki a paletta forgatásával a mozgás illúziója kelthető. Nem rajzoljuk újra a képet, csupán a paletta átírásával ugyanazon képpont mindig más színű lesz. Na, ez a plazma effekt !

Hogy mit jelent az, hogy a "Megfelelő képet", meg hogy a "megfelelő palettát" ? Jó kérdés. Elég sok féle lehet. Akkor megfelelő, ha működik, éspedig akkor működik, ha valami köze van a szögfüggvényekhez. Ez mind a palettára, mind a képre igaz. Ez a rengeteg szögfüggvény pedig maga után vonja azt, amit a forráskód után majd elárulok.

A program: (forrkod1.zip)

{$G+} {286-os utasítások is lesznek} Program Plazma; Uses Crt; var i,j : Integer; paletta: Array[0..764] of byte; {itt lesz tárolva a paletta} buff : Array[0..2] of byte; {átmeneti buffer} Procedure SetRGB(colnum,Red,Green,Blue:byte); Assembler; {a paletta colnum.-dik elemének átírása } Asm {red,green,blue színösszetevőkre}
mov dx,$3c8 mov al,colnum {kiválasztjuk a módosítani kívánt elemet,} out dx,al {úgy,hogy a $3c8 portra kiküldjük az elem számát} inc dx mov al,red out dx,al {a $3c9 portra egymás után kinyomatjuk a három
színösszetevőt}
mov al,green out dx,al mov al,blue out dx,al {ha rögtön a következő elemet is át akarnánk
írni, nem kellene újból kiválasztani a következő elemet a $3c8- al a 3 színösszetevő kilökése után a VGA automatikusan növeli az aktuális elemet (majd a paletta mozgatásánál lesz ennek szerepe)}
End;
Procedure palettaszamit; {kikeverjük a paletta színeit szögfüggvények alapján, hogy szép } var r,g,b:byte; {szivárványos legyen} Begin
for i:=1 to 255 do {255 színt írunk át, a nullát nem} Begin
{a színösszetevők kiszámítása, és eltárolása egy
tömbben}
r:=32+round(30*sin( i*pi*2/255 )); paletta[3*i-3]:=r; g:=32+round(30*cos( i*pi*2/255 )); paletta[3*i-2]:=g; b:=32+round(30*sin( -i*pi*2/255 )); paletta[3*i-1]:=b; SetRGB(i,r,g,b); {ha már kiszámoltuk azt a nyomoronc színt, a VGA paletta i.-dik elemére letesszük}
End;
End;
Procedure Plot(X,Y:word;Z:byte);Assembler; {Egy z színű pont kirakása x,y pozícióba} Asm {a képernyőmemória direkt írásával}
mov ax,$a000 {a képernyőmemória szegmenscíme es-be} mov es,ax mov ax,320 {az offset kiszámítása} mul y {offset=y*320+x} mov di,x add di,ax {offset di-be} mov al,Z {szín al-be} cmp al,0 {a nullát nem rakjuk ki, helyette 255-öt} jnz @nemnulla dec al @nemnulla: stosb {es:di-re kirakjuk az al színű pontot}
End;
Function F(x,y: Real): Real; {x,y koordinátához kiszámoljuk a színt} Begin
F:=128+128*(cos(x*x*y/1000000)+sin(y*y*x/1000000)); {ehun van e ni a képlet} {bárki szabadon próbálkozhat az átírásával} {szebb képet is össze lehet hozni}
End;
Procedure Graph;Assembler; {320X200X256- os módba vált} Asm
mov ax,$13 int $10
End;
Procedure Backtotext;Assembler; {vissza szöveges módba} Asm
mov ax,$3 int $10
End;
Procedure Palanim; {A paletta mozgatása } Begin
move(paletta,buff,3); {az első szín buff-ba} move(paletta[3],paletta,762); {minden szín egyel lejjebb
kerül}
move(buff,paletta[762],3); {az utolsó szín helyére
visszajön az első}
{Minden színt egyel lejjebb toltunk, az első, pedig hátra csorgott miután a tömbünkben már meg van az új paletta, nem árt a kártyáét is átállítani} asm
cld mov dx,$3c8 {az első elem kiválasztása} mov al,1 out dx,al lea si,paletta inc dx {az összes szín átírása} mov cx,255*3 rep outsb
end;
End;
BEGIN
Graph; {320X200X256- os módba vált} palettaszamit; For i:=0 to 319 do {Kép kiszámítása}
For j:=0 to 199 do Plot(i,j,trunc(F(i,j)));
repeat { Palettaanimáció }
palanim; delay(10);
until keypressed;
backtotext; {vissza szöveges módba}
END.

Mielőtt még valakit nagy meglepetés érne, elárulom, hogy a számítás nagyon lassan megy a szögfüggvények miatt. Figyelem: Azt a szörnyű dolgot tapasztaltam, hogy az illető (nem minősítem) nem várja meg míg befejeződik a számítás, hanem veri a gombokat, hogy mi van már ez nem nagy szám. Ettől aztán nem fog látni semmit, mert a gombnyomás hatására a program kilép.(Nem azt hívják plazma effektnek, amikor jönnek lefelé a csíkok, hanem ami utána lesz). 

Ja, és a megjegyzéseket nehogy valaki szószerint begépelje, én is majd belegebedtem.

Ha már itt vagyunk, nézzük meg, mit tudunk tenni a számítás gyorsítása érdekében:

  • Elintézzük, hogy reál helyett single-ben számoljon a program. Ez a koprocesszorral rendelkező gépeken igen figyelemreméltó eredményt hoz. Ha viszont nincs koproci (ilyen elég ritkán van), akkor azt értük el, hogy kétszer olyan lassú lesz.

  • Mivel az idô leginkább azzal megy el, hogy szögfüggvényeket számolgatunk, elintézzük, hogy ne kelljen számolnunk. Letároljuk egy tömbben az összes fokhoz tartozó szögfüggvényértékeket. Így a sebességgel nem lesz bajunk, viszont a kép nem lesz igazán Kodak minőségű.

  • Ha a félmegoldásokból már elegünk lett, talán tegyünk valami teljesen formabontót. GONDOLKODJUNK. Nosza! Úgy másfél óra megfeszített szellemi munka után felötlik az emberben :  ‘Francba ezzel a ..... számolással'. Hát hiszen ez a megoldás ! Valamivel úgy végezhetünk a leggyorsabban , hogy meg se csináljuk. - néha magam is meglepődöm mennyi eszem van - Tároljuk el a képet pontról pontra. És ha már itt tartunk tároljuk el a palettát is. Heuréka! Egy kanyi számolás sincs a programunkban, és gyors mint a villám. forrkod2.zip

Kérdéseket, javaslatokat nyugodtan írhattok. Az E-mail címem úgyse mondom meg.