{$I386_INTEL}
USES GO32;
VAR  VideoBuffer : pointer;

 PROCEDURE Pixel(destiny : pointer; x,y : longint; color : byte);
 BEGIN
  if (x<0) or (x>319) or (y<0) or (y>199) then exit;
  ASM
    mov edi,destiny

    add edi,x          { In unserem Videobuffer um x-Bytes weiter }
    mov eax,320
    imul y             { Und um y*320 Bytes weiter }
    add edi,eax

    mov al,color
    mov [edi],al       { Pixel setzen }
  END ['EDI', 'EAX', 'EDX'];
 END;


 PROCEDURE InitVGAMode(mode : word);
  Var regs : trealregs;
 BEGIN

  regs.ax:=mode;
  Realintr($10,regs);

 END;


 PROCEDURE Line(destiny : pointer; x1,y1,x2,y2 : longint; col : byte);
  Var dx,dy,sx,sy,k : longint;
 BEGIN

  sx:=1;
  sy:=1;
  dx:=x2-x1;          { X-Steigung }
  if dx<0 then begin  { Wenn negativ, dann nich X erh”hen sondern erniedrigen (mit SX) }
   dx:=-dx;
   sx:=-1;
  end;
  dy:=y2-y1;          { Y-Steigung }
  if dy<0 then begin  { s.o }
   dy:=-dy;
   sy:=-1;
  end;
  k:=-(dx shr 1);                     { dx shr 1 = dx div 2 }
  pixel(destiny,x1,y1,col);           { 1.Pixel setzen }

  while (x1<>x2) or (y1<>y2) do       { Schleife von x1 nach x2 / y1 nach y2 }
   if (k>=0) and (y1<>y2) then begin  { K”nnen noch Pixel in x-Richtung gesetzt werden? }
    inc(y1,sy);                       { Nope! Also y erh”hen/erniedrigen }
    dec(k,dx);
    pixel(destiny,x1,y1,col);
   end
   else begin
    inc(x1,sx);                       { Yup! Also x erh”hen/erniedrigen }
    inc(k,dy);
    pixel(destiny,x1,y1,col);
   end;

 END;


 PROCEDURE Circle(destiny : pointer; x0,y0,radius : longint; col : byte);
  Var x,y,p : longint;
 BEGIN

  x:=0;
  y:=-radius;
  p:=y shl 1+3;                  { y shl 1 = y*2 }
  while x<=-y do begin
   pixel(destiny,x0+x,y0+y,col); { Die angesprochenen Spiegelungen }
   pixel(destiny,x0-x,y0+y,col);
   pixel(destiny,x0+x,y0-y,col);
   pixel(destiny,x0-x,y0-y,col);
   pixel(destiny,x0+y,y0+x,col);
   pixel(destiny,x0-y,y0+x,col);
   pixel(destiny,x0+y,y0-x,col);
   pixel(destiny,x0-y,y0-x,col);
   if p>=0 then begin
    inc(y);
    inc(p,(x+y)shl 2+6);       { obiges 3 bzw. 6 dienen zur Sch”nheits-Korrektur }
   end else inc(p,x shl 2+6);  { keine Ahnung wie Bresenham gerade auf diese Zahlen kam }
   inc(x);
  end;

 END;



BEGIN

  getmem(videobuffer,64000);
  initvgamode($13);                         { 320x200,256 }

  line(videobuffer,-30,100,160,2,1);        { LINIE IN BUFFER SETZEN }
  circle(videobuffer,160,100,50,2);         { KREIS MIT RADIUS 50 / FARBE 2 }
  dosmemput($a000,0,videobuffer^,64000);    { BUFFER AN $a000:0 KOPIEREN }

  readln;
  initvgamode($3);                          { TEXTMODUS }
  freemem(videobuffer,64000);

END.