#pragma option d32
#pragma option stub=dpmi
byte flowers[256000];
byte screen[64000];

:void WAITVSYNC()
{
	DX=0x3DA;
	do{
		inp();
		AL&=8;
	}while(NOTZEROFLAG);
	do{
		inp();
		AL&=8;
	}while(ZEROFLAG);
}

void setrgbpalette(char color,r,g,b);

float const1=0.5;
float const2=1.0;
float const3=1.5;
float const4=2.0;
float const5=90;
float const6=120;
float const7=96;
float const8=192;
float const9=8;
float const10=16;
float const11=0.02;

void main()
long offset1,offset2,offset3;
long x,y;
float time=0;
char c1,c2,c3;
{
  BX=0xA000;
  AX=0x0002;
  $INT 0x31
  ES=AX;
  initflower();
  @SETVIDEOMODE(byte 0x13);
  setcolortable();
  while(!BIOSKEYCHECK()){
    asm{
      fld time
      fmul const1
      fadd const2
      fsin
      fmul const6
      fistp x
//      fwait
    }
    x+=160;
//    x=160+120*sin(time*0.5+1.0);
    asm{
      fld time
      fmul const3
      fadd const4
      fcos
      fmul const5
      fistp y
//      fwait
    }
//    y=100+90*cos(time*1.5+2.0);
    EAX=y+100<<7;
    EBX=EAX<<2;
    offset1=EAX+EBX+x;
    asm{
      fld time
      fmul const2
      fadd const3
      fsin
      fmul const6
      fistp x
//      fwait
    }
    x+=160;
//    x=160+120*sin(time*1.0+1.5);
    asm{
      fld time
      fmul const4
      fadd const1
      fcos
      fmul const5
      fistp y
//      fwait
    }
//    y=100+90*cos(time*2.0+0.5);
    EAX=y+100<<7;
    EBX=EAX<<2;
    offset2=EAX+EBX+x;
    asm{
      fld time
      fmul const3
      fadd const4
      fsin
      fmul const6
      fistp x
//      fwait
    }
    x+=160;
//    x=160+120*sin(time*1.5+2.0);
    asm{
      fld time
      fmul const1
      fadd const2
      fcos
      fmul const5
      fistp y
//      fwait
    }
//    y=100+90*cos(time*0.5+1.0);
    EAX=y+100<<7;
    EBX=EAX<<2;
    offset3=EAX+EBX+x;
    FOR(ECX=0;ECX<200;ECX++){
      EAX=ECX<<7;
      EBX=EAX<<2;
			EDI=EAX+EBX;
      FOR(EDX=0;EDX<320;EDX++,EDI++){
        ESI=EDI+offset1;
        c1=flowers[ESI];
        ESI=EDI+offset2;
        c2=flowers[ESI];
        ESI=EDI+offset3;
        c3=flowers[ESI];
        EAX=ECX<<6;
        EBX=EAX<<2;
        ESI=EAX+EBX+EDX;
        screen[ESI]=c1+c2+c3;
      }
    }
    asm{
      fld time
      fadd const11
      fstp time
    }
    copyvirtualscreen();
  }
  @SETVIDEOMODE(byte 0x3);
  @BIOSREADKEY();
}

void initflower()
long x,y;
long v,u;
{
  EDI=0;
  FOR(y=-200;y<200;y++){
    FOR(x=-320;x<320;x++){
      v=x*x;
      u=y*y+v;
      asm{
        fild u
        fsqrt
        fild x
        fild y
        fpatan
        fld st(0)
        fmul const10
        fcos
        fmul const7
        fxch st(1)
        fmul const9
        fsin
        fmul const8
        faddp st(1)
        fldpi
        fdivp st(1)
        faddp st(1)
        fistp v
        fwait
      }
      flowers[EDI]=v;
      EDI++;
    }
  }
}

void copyvirtualscreen()
{
  @WAITVSYNC();
  EDI=0;
  ESI=#screen;
  ECX=16000;
  $rep
  $movsd
}

void setcolortable()
long i=0;
long c;
{
  do{
    c=i*3/2;
    setrgbpalette(i,63,c,0);
    i++;
  }while (i<43);
  do{
    c=i-43*3/2;
    setrgbpalette(i,63-c,63,0);
    i++;
  }while (i<85);
  do{
    c=i-85*3/2;
    setrgbpalette(i,0,63,c);
    i++;
  }while (i<128);
  do{
    c=i-128*3/2;
    setrgbpalette(i,0,63-c,63);
    i++;
  }while (i<171);
  do{
    setrgbpalette(i,c,0,63);
    i++;
  }while (i<213);
  do{
    c=i-213*3/2;
    setrgbpalette(i,63,0,63-c);
    i++;
  }while (i<256);
}

void setrgbpalette(char color,r,g,b)
{
  DX=0x3C8;
  outp(color,DX);
  DX++;
  outp(r,DX);
  outp(g,DX);
  outp(b,DX);
}
