{$N+,A+,G+,F+,D-,E+,L-,R-,S-,Q-,Y-,I-}

{ The effect was coded especially for Demoded }
{ Code: bitl/7dump 2025 }

function rad(i:integer):single;
begin
    rad:=i*0.01745329;
end;

procedure WaitVR; Assembler;
asm
  mov  dx, 3DAh
@w1:
    in   al, dx
    test al, 8h
  jnz  @w1
@w2:
    in   al, dx
    test al, 8h
  jz   @w2
end;

procedure setonecolor(c,r,g,b:byte);assembler;
asm
  mov dx,3c8h
  mov al,c
  out dx,al
  inc dx
  mov al,r
  out dx,al
  mov al,g
  out dx,al
  mov al,b
  out dx,al
end;

Procedure LoadPalette(Filename:string);
var
fr:file;
c,n:byte;
b:array[0..2] of byte;
begin
Assign(fr, filename);
Reset(fr, 1);
for c:=0 to 255 do begin
   for n:=0 to 2 do BlockRead(fr, b[n], 1);
   SetOneColor(c, b[0],b[1],b[2]);
end;
Close(fr);
end;



CONST
VGA = $a000;

var
Aantal, T1: longint;
Timer: longint ABSOLUTE $0040:$006C;

q: word;
YValue, vdi, n, x,y,xx,yy :integer;
dx1,dx2,dx3, dy1,dy2,dy3 :integer;

SinTable: array [0..511] of integer;
XValues : array [0..319] of integer;
XValues_ofs,XValues_seg :word;
dither1, dither2:longint;

begin


XValues_seg:=seg(XValues);
XValues_ofs:=ofs(XValues);

{create sinus table}
For x:= 0 to 511 Do SinTable[x] := round(sin(rad(x*2)/512*360)*512);

asm
mov ax, 13h
int 10h
end;

{for n:=0 to 255 do SetOneColor(n,round(sin(n/20)*31+32),round(sin(n/20+1)*31+32),round(sin(n/20+2)*31+32));{}
LoadPalette('plasma.pal');

q:=0; Aantal:=0; T1:=Timer;

repeat

q := q + 1;

dx1:=24; dx2:=32; dx3:=40;
dy1:=25; dy2:=35; dy3:=20;

xx:=round(cos(q/64)*256);
yy:=round(sin(q/64)*256);

for x := 0 to 319 do {precals x-table for current frame}
     XValues[x] :=
     dx1 * SinTable[(x shr 1 + q)            and 511]+
     dx2 * SinTable[(x       + q shl 1)      and 511]+
     dx3 * SinTable[(x shr 1 + q shr 2 + xx) and 511];

vdi:=0;


WaitVR;{}


for y := 0 to 99 do
begin

    if y and 1 = 0 then begin
          dither1:=$0A020800; {0,8,2,10}
          dither2:=$060E040C; {12,4,14,6}
    end
    else begin
          dither1:=$09010B03; {3,11,1,9}
          dither2:=$050D070F; {15,7,13,5}
    end;

    YValue:= dy1 * SinTable[(y + q      )            and 511]+
             dy2 * SinTable[(y + q shl 2)            and 511]+
             dy3 * SinTable[(y shl 1 + q shr 1 +yy ) and 511];

    asm
    push ds
    push bp

    mov ax, VGA
    mov es, ax

    mov di, vdi

    mov ax, YValue
    mov dx, ax
    db $66; shl dx, 16
    mov dx, ax

    {dither pattern for current lines}
    db $66; mov si, word ptr dither1
    {---------------self-modify---------------}
    db $66; mov ax, word ptr dither2
    db $66; mov cs:[offset @dither2+3], ax
    jmp @clear_prefetch; @clear_prefetch:
    {-----------------------------------------}

    mov bx, XValues_ofs
    mov ds, XValues_seg

    mov bp, 80
    @x:
           db $66; mov ax, ds:[bx+4]
           db $66; add ax, dx
           db $66; shr ax, 8
           mov ah, al
           db $66; shl ax, 8

           db $66; mov cx, ds:[bx]
           db $66; add cx, dx
           mov al, ch
           db $66; shr cx, 16
           mov ah, ch
           db $66; mov cx, ax

           db $66;   add ax, si                      {+dither1}
           @dither2: db $66; add cx, 1234h; dw 5678h {+dither2}

           db $66; mov es:[di],     ax
           db $66; mov es:[di+320], cx

           add di, 4
           add bx, 8
    dec bp
    jnz @x

    pop bp
    pop ds
    end;

    vdi:=vdi+640;
 end;

Inc(Aantal);

until port[$60]=1;

asm
mov ax, 3h
int 10h
end;

T1:=timer-T1;
WriteLn(Aantal/(T1/18.2):2:1,' Frames per second');


end.