In playing with framebuffer drawing efforts, something interesting came up.
In brief (so as not to bore everyone) the same draw program and unit works differently between fpc and gpc. But neither work.
I suspect it is in the rewrite and/or blockwrite functions. I'm using 16bit pixels so I'm dealing with converting 16 bit to byte writes.
Anyway, for a simple red horizontal line on a solid background. Fpc gives me two red lines on a clean blue background. While gpc gives me a single red line on a spotted blue background.
Also, gpc gave me the proper error code for using blockwrite on a typed file.
Conclusion; a bad program performs differently on fpc and gpc.
Rick Engebretson wrote:
In playing with framebuffer drawing efforts, something interesting came up.
In brief (so as not to bore everyone) the same draw program and unit works differently between fpc and gpc. But neither work.
I suspect it is in the rewrite and/or blockwrite functions. I'm using 16bit pixels so I'm dealing with converting 16 bit to byte writes.
Anyway, for a simple red horizontal line on a solid background. Fpc gives me two red lines on a clean blue background. While gpc gives me a single red line on a spotted blue background.
Also, gpc gave me the proper error code for using blockwrite on a typed file.
Conclusion; a bad program performs differently on fpc and gpc.
Which is not surprising in general. :-)
Without seeing your code, I doubt anyone here can tell you much more.
What I can say is a problem I had when I played with fb was the palette. The fb console doesn't set up a palette as usual (in particular in 32 bit pixel mode). So you better set your palette first in any case. You might want to look at my fgv.pas for an example.
Frank
Frank Heckenbach wrote:
Rick Engebretson wrote:
In playing with framebuffer drawing efforts, something interesting came up.
In brief (so as not to bore everyone) the same draw program and unit works differently between fpc and gpc. But neither work.
I suspect it is in the rewrite and/or blockwrite functions. I'm using 16bit pixels so I'm dealing with converting 16 bit to byte writes.
Anyway, for a simple red horizontal line on a solid background. Fpc gives me two red lines on a clean blue background. While gpc gives me a single red line on a spotted blue background.
Also, gpc gave me the proper error code for using blockwrite on a typed file.
Conclusion; a bad program performs differently on fpc and gpc.
Which is not surprising in general. :-)
Without seeing your code, I doubt anyone here can tell you much more.
What I can say is a problem I had when I played with fb was the palette. The fb console doesn't set up a palette as usual (in particular in 32 bit pixel mode). So you better set your palette first in any case. You might want to look at my fgv.pas for an example.
Frank
Here is a roughed in interface for SVGAlib without the SVGA. Rick.
Unit DrawPrimitives;
INTERFACE
PROCEDURE pixel (int X, int Y);
PROCEDURE line (int X1, int Y1, int X2, int Y2);
PROCEDURE line_pattern (unsigned int P_Bit_Mask);
PROCEDURE polygon (int P_Num_Pts, int *P_Pt_Array);
PROCEDURE set_loc_abs (int X, int Y); { Set current drawing location in absolute screen coordinates }
PROCEDURE set_loc_rel (int X, int Y); { Set new drawing location relative to current drawing location}
PROCEDURE line_to_abs (int X, int Y); {Draw line from current location to point (X,Y) make point (X,Y) new current location }
PROCEDURE line_to_rel (int X, int Y); { draw line from current location to point X pixels and Y pixels from the the current location. Make the location the new current location.}
PROCEDURE circle (int X_center, int Y_center, int Radius); { draw a circle with radius Radius, centered on point (X_Center,Y_Center) }
PROCEDURE ellipse (int X_center, int Y_center, int r1, int r2); {Draw an ellipse, with radii r1 and r2, centered on point (X_Center, Y_Center) }
PROCEDURE arc (int X_center, int Y_center, int Radius, int St_Angle, int End_Angle);
PROCEDURE set_fill_pattern(unsigned char P_FillPattern[8]);
PROCEDURE set_border_color (unsigned char P_Red, unsigned char P_Green, unsigned char P_Blue);
PROCEDURE get_border_color (unsigned char *P_Red, unsigned char *P_Green, unsigned char *P_Blue);
PROCEDURE get_pixel (int X, int Y, unsigned char *P_Red, unsigned char *P_Green, unsigned char *P_Blue);
PROCEDURE fill_rectangle (int X1, int Y1, int X2, int Y2);
PROCEDURE fill_ellipse (int X_center, int Y_center, int r1, int r2);
PROCEDURE floodfill (int X, int Y);
PROCEDURE polyfill (int P_Num_Pts, int *P_Pt_Array);
The conversion of a minimal set of SVGAlib drawing routines to pascal, for the Linux graphics framebuffer, is going OK. Converting to Objects is helpful. The Bresenham pixel plotting algorithm is clever. Once the base draw routines really work, anybody can adapt add on interfaces.
Another Linux project will be the General SCSI interface. The SCSI interface is made for pascal. SCSI is far more versatile than just drive controllers.
I know many GPC programmers like other OS's, but Pascal on Linux is wide open opportunity.
Rick Engebretson wrote:
Frank Heckenbach wrote:
Rick Engebretson wrote:
In playing with framebuffer drawing efforts, something interesting came up.
In brief (so as not to bore everyone) the same draw program and unit works differently between fpc and gpc. But neither work.
I suspect it is in the rewrite and/or blockwrite functions. I'm using 16bit pixels so I'm dealing with converting 16 bit to byte writes.
Anyway, for a simple red horizontal line on a solid background. Fpc gives me two red lines on a clean blue background. While gpc gives me a single red line on a spotted blue background.
Also, gpc gave me the proper error code for using blockwrite on a typed file.
Conclusion; a bad program performs differently on fpc and gpc.
Which is not surprising in general. :-)
Without seeing your code, I doubt anyone here can tell you much more.
What I can say is a problem I had when I played with fb was the palette. The fb console doesn't set up a palette as usual (in particular in 32 bit pixel mode). So you better set your palette first in any case. You might want to look at my fgv.pas for an example.
Frank
I now think the difference is due to FPC defines "word" integers as 16 bit. GPC defines "word" integers as 32 bit. I declared the colors as "word" integers in the code. When I wrote the GPC "word" integers to the framebuffer, I got 16 bits of blank "spots". So it does work. Sorry, again my mistake. Looking through older manuals, there seems to be no common integer types between FPC and GPC ??
Rick Engebretson wrote:
I now think the difference is due to FPC defines "word" integers as 16 bit. GPC defines "word" integers as 32 bit. I declared the colors as "word" integers in the code. When I wrote the GPC "word" integers to the framebuffer, I got 16 bits of blank "spots". So it does work. Sorry, again my mistake. Looking through older manuals, there seems to be no common integer types between FPC and GPC ??
For interfacing to C in GPC use the C compatible types (see manual). For fixed size types use `Integer attribute (Size = 32)' or `Cardinal attribute (Size = 32)' etc. I don't know what FPC has.
Frank
Frank Heckenbach wrote:
Rick Engebretson wrote:
I now think the difference is due to FPC defines "word" integers as 16 bit. GPC defines "word" integers as 32 bit. I declared the colors as "word" integers in the code. When I wrote the GPC "word" integers to the framebuffer, I got 16 bits of blank "spots". So it does work. Sorry, again my mistake. Looking through older manuals, there seems to be no common integer types between FPC and GPC ??
For interfacing to C in GPC use the C compatible types (see manual). For fixed size types use `Integer attribute (Size = 32)' or `Cardinal attribute (Size = 32)' etc. I don't know what FPC has.
Frank
I'm not interfacing to C. I'm rewriting everything in Pascal. Tedious, but well worth it for me.
Another divergence between FPC and GPC will be FPC:TCollection object or GPC:ConformantArray. The conformant array is far more appropriate to store pixel coordinates, but the only real documentation is the demo program. Still, the learning process is fun and important.
Rick Engebretson wrote:
Frank Heckenbach wrote:
Rick Engebretson wrote:
I now think the difference is due to FPC defines "word" integers as 16 bit. GPC defines "word" integers as 32 bit. I declared the colors as "word" integers in the code. When I wrote the GPC "word" integers to the framebuffer, I got 16 bits of blank "spots". So it does work. Sorry, again my mistake. Looking through older manuals, there seems to be no common integer types between FPC and GPC ??
For interfacing to C in GPC use the C compatible types (see manual). For fixed size types use `Integer attribute (Size = 32)' or `Cardinal attribute (Size = 32)' etc. I don't know what FPC has.
I'm not interfacing to C. I'm rewriting everything in Pascal. Tedious, but well worth it for me.
When interfacing to hardware directly (via memory mapped I/O), the remarks about fixed sizes apply.
Another divergence between FPC and GPC will be FPC:TCollection object or GPC:ConformantArray. The conformant array is far more appropriate to store pixel coordinates, but the only real documentation is the demo program. Still, the learning process is fun and important.
I think (hope) there isn't much more to say about it. Just declare the parameter [const|[protected][var]] Foo: array [m .. n: IndexType] of SomeType and use `Foo', `m' and `n' as expected. If you have more questions, feel free to ask.
Frank
Frank Heckenbach wrote:
Rick Engebretson wrote:
Frank Heckenbach wrote:
Rick Engebretson wrote:
I now think the difference is due to FPC defines "word" integers as 16 bit. GPC defines "word" integers as 32 bit. I declared the colors as "word" integers in the code. When I wrote the GPC "word" integers to the framebuffer, I got 16 bits of blank "spots". So it does work. Sorry, again my mistake. Looking through older manuals, there seems to be no common integer types between FPC and GPC ??
For interfacing to C in GPC use the C compatible types (see manual). For fixed size types use `Integer attribute (Size = 32)' or `Cardinal attribute (Size = 32)' etc. I don't know what FPC has.
I'm not interfacing to C. I'm rewriting everything in Pascal. Tedious, but well worth it for me.
When interfacing to hardware directly (via memory mapped I/O), the remarks about fixed sizes apply.
Another divergence between FPC and GPC will be FPC:TCollection object or GPC:ConformantArray. The conformant array is far more appropriate to store pixel coordinates, but the only real documentation is the demo program. Still, the learning process is fun and important.
I think (hope) there isn't much more to say about it. Just declare the parameter [const|[protected][var]] Foo: array [m .. n: IndexType] of SomeType and use `Foo', `m' and `n' as expected. If you have more questions, feel free to ask.
Frank
I've now tried polymorphic linked-list objects (virtual methods,etc.), intended as dynamic containers for pixel data (coordinates, color). This standard approach (same code) seems to work nicely on both FPC and GPC. But GPC gives me far better debug information. Excellent, advanced compilers, both. (Yours truly, the programmer, mostly copied someones book.)
Time, now, to neaten up these various Pascal constructs. Then I'll post it on your dart board.
Sincere thanks, Rick.
I have an old book;
"The PASCAL Handbook" by Jacques Tiberghien Sybex, 1981.
It covers the pascal language on DEC, CDC, Apple, HP, and USCD platforms.
It is remarkable how little the base language has changed.
Similarly, the drawing algorithms of Bresenham from the 1960s are still the standard.
I've been confused enough by turbo and iso stuff. I'm thinning this framebuffer drawing interface to old and simple.
Rick Engebretson wrote:
I have an old book;
"The PASCAL Handbook" by Jacques Tiberghien, Sybex, 1981. It covers the pascal language on DEC, CDC, Apple, HP, and USCD platforms.
It is remarkable how little the base language has changed.
Not at all. This is the power of standards. Similarly, C is virtually unchanged since about 1989, when the ANSI standard was issued. The firms and groups named above were aware of and largely observed the draft standards or their predecessor, Jensen & Wirths "Pascal User Manual and Report". Some of the original people still monitor comp.lang.pascal.ansi-iso, especially including John Reagan of DEC.
Unfortunately Borland thumbed its nose at the standard and was a large enough ox in the Pascal world to get away with it. This is, IMO, at the root of the non-popularity of Pascal today, and incidentally the reduction of Borland from a major software power to a minor player.
The following is from ISO10206, the Extended Pascal Standard, which is compatible with ISO7185 covering standard Pascal
"The resolution to form JPC clarified the dual function of the single joint committee to produce a dpANS and a proposed IEEE Pascal standard, identical in content. ANSI/IEEE770X3.97-1983, American National Standard Pascal Computer Programming Language, was approved by the IEEE Standards Board on September 17, 1981, and by the American National Standards Institute on December 16, 1982. British Standard BS6192, Specification for Computer programming language Pascal, was published in 1982, and International Standard 7185 (incorporating BS6192 by reference) was approved by ISO on December 1, 1983. Differences between the ANSI and ISO standards are detailed in the Foreword of ANSI/IEEE770X3.97-1983. (BS6192/ISO7185 was revised and corrected during 1988/89; it is expected that ANSI/IEEE770X3.97-1983 will be replaced by the revised ISO 7185.)"
CBFalconer wrote:
Rick Engebretson wrote:
I have an old book;
"The PASCAL Handbook" by Jacques Tiberghien, Sybex, 1981. It covers the pascal language on DEC, CDC, Apple, HP, and USCD platforms.
It is remarkable how little the base language has changed.
Not at all. This is the power of standards. Similarly, C is virtually unchanged since about 1989, when the ANSI standard was issued. The firms and groups named above were aware of and largely observed the draft standards or their predecessor, Jensen & Wirths "Pascal User Manual and Report". Some of the original people still monitor comp.lang.pascal.ansi-iso, especially including John Reagan of DEC.
Unfortunately Borland thumbed its nose at the standard and was a large enough ox in the Pascal world to get away with it. This is, IMO, at the root of the non-popularity of Pascal today, and incidentally the reduction of Borland from a major software power to a minor player.
The following is from ISO10206, the Extended Pascal Standard, which is compatible with ISO7185 covering standard Pascal
"The resolution to form JPC clarified the dual function of the single joint committee to produce a dpANS and a proposed IEEE Pascal standard, identical in content. ANSI/IEEE770X3.97-1983, American National Standard Pascal Computer Programming Language, was approved by the IEEE Standards Board on September 17, 1981, and by the American National Standards Institute on December 16, 1982. British Standard BS6192, Specification for Computer programming language Pascal, was published in 1982, and International Standard 7185 (incorporating BS6192 by reference) was approved by ISO on December 1, 1983. Differences between the ANSI and ISO standards are detailed in the Foreword of ANSI/IEEE770X3.97-1983. (BS6192/ISO7185 was revised and corrected during 1988/89; it is expected that ANSI/IEEE770X3.97-1983 will be replaced by the revised ISO 7185.)"
Thanks for the friendly response.
Yes, Units, Pointers, the New procedure are all there in 1981.
Here is a draft of a draw routine. It is intended to set up linked lists for draw primitives such as circles and squares. While not a working draft, it compiles and runs the little test. And the logic is readable in Pascal.
Program DrawList;
Uses DrawUnit, BresenhamAlgorithm ;
var aPixelptr : pPixel ; aPixel : TPixel ;
begin aPixel.x := 50 ; aPixel.y := 50 ; aPixel.color := 50 ;
aPixelptr := NewPixel(aPixel); Writeln ('went OK' ); end.
UNIT DrawUnit;
INTERFACE
USES BresenhamAlgorithm ;
FUNCTION NewPixel ( pixel : TPixel) : pPixel ; { Creates a New Pixel } PROCEDURE ErasePixel ( ThisPixel : pPixel ) ;
FUNCTION NewLine ( pixel1, pixel2 : TPixel ) : pListElement ; { Creates a New LinkedPixelList. } PROCEDURE EraseLine ( ThisLine : pListElement ) ;
(*=========================================================*)
IMPLEMENTATION
Function NewPixel ( pixel : TPixel ) : pPixel;
var ThisPixel : pPixel;
begin ThisPixel := New(pPixel) ; { This Pixel is a start pointer } ThisPixel^.x := pixel.x ; ThisPixel^.y := pixel.y ; ThisPixel^.color := pixel.color ; { DrawPixel( ThisPixel^ ) ;} NewPixel := ThisPixel ; end; { NewPixel }
Procedure ErasePixel( ThisPixel : pPixel ) ;
begin ThisPixel := nil ; end; { ErasePixel }
Function NewLine ( pixel1, pixel2 : TPixel ) : pListElement;
var ThisLine : pListElement ;
begin ThisLine := New(pListElement); { ThisLine is the start pointer for the Linked List } DrawLine( pixel1, pixel2, ThisLine ); NewLine := ThisLine ; end; { NewLine }
Procedure EraseLine ( ThisLine : pListElement ) ;
begin ThisLine := nil ; end;
begin end.
UNIT BresenhamAlgorithm; (* A Linked List of Pixels is created. *)
INTERFACE
TYPE pPixel = ^TPixel; TPixel = Record x, y, color : longint; end; { TPixel }
pListElement = ^PixelListElement; { The List Handle } PixelListElement = Record ListIndex : longint; Pixel : TPixel; NextPixel : pListElement; end;
PROCEDURE DrawLine( pt1, pt2 : TPixel ; pLineElement : pListElement );
(*=========================================================*)
IMPLEMENTATION
VAR i, p, dx, dy, d2x, d2y : longint ; slope: real;
PROCEDURE SwapEndPoints( var pt1, pt2 : TPixel ); Var temp : longint ;
BEGIN temp := pt2.x; pt2.x := pt1.x; pt1.x := temp;
temp := pt2.y; pt2.y := pt1.y; pt1.y := temp; END ; { SwapEndPoints }
PROCEDURE SlopeEqualsInfinity( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN
if (dy<0) then SwapEndPoints(pt1, pt2);
for i := pt1.y to pt2.y do begin pt1.y := i; pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex ); end ;
END; { SlopeEqualsInfinity }
PROCEDURE SlopeEqualsZero( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN
if (dx<0) then SwapEndPoints(pt1, pt2);
for i:=pt1.x to pt2.x do begin pt1.x := i ; pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex ); end ;
END ; { SlopeEqualsZero }
PROCEDURE SlopeZeroToOne( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN { SlopeZeroToOne }
if ( pt2.x < pt1.x ) then SwapEndPoints(pt1, pt2);
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
p := d2y - dx ; Inc( pt1.x );
while ( pt1.x < pt2.x ) do begin {while} if (p>0) then begin p := p + ( d2y - d2x ); Inc( pt1.y ); end { if }
else p := p + d2y ;
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
Inc( pt1.x );
end; {while}
END ; { SlopeZeroToOne }
PROCEDURE SlopeGreaterThanOne( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN { SlopeGreaterTanOne }
if ( pt2.y < pt1.y ) then SwapEndPoints (pt1, pt2);
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
p := d2x - dy; Inc( pt1.y );
while ( pt1.y < pt2.y ) do begin {while} if (p>0) then begin p := p + ( d2x - d2y ); Inc(pt1.x); end { if }
else p := p + d2y ;
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
Inc( pt1.y );
end; { while }
END ; { SlopeGreaterThanOne }
PROCEDURE SlopeNegOneToZero ( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN { SlopeNegOneToZero }
if ( pt2.x < pt1.x ) then SwapEndPoints (pt1, pt2);
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
p := d2y + dx; Inc( pt1.x );
while (pt1.x < pt2.x ) do begin {while} if (p>0) then begin p := p - ( d2y + d2x ); Dec(pt1.y); end { if }
else p := p - d2y;
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
Inc(pt1.x);
end; { while }
END ; { SlopeNegOneToZero }
PROCEDURE SlopeLessThanNegOne ( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN { SlopeLessThanNegOne }
if ( dy < 0 ) then SwapEndPoints ( pt1, pt2 );
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
p := d2x + dy; Inc(pt1.y);
while ( pt1.y < pt2.y ) do begin if (p>0) then begin p := p - (d2x + d2y ); Dec(pt1.x); end { if }
else p := p - d2x;
pLineElement^.NextPixel := New( pListElement ); Inc( pLineElement^.ListIndex );
Inc( pt1.y );
end; { while }
END ; { SlopeLessThanNegOne }
(*=========================================================*)
PROCEDURE DrawLine( pt1, pt2 : TPixel ; pLineElement : pListElement ); BEGIN { DrawLine}
i := 0 ; pLineElement^.ListIndex := 0 ;
dx := pt2.x - pt1.x ; dy := pt2.y - pt1.y ; d2x := 2* dx ; d2y := 2* dy ; slope := dy /dx ;
If ( dx = 0) then SlopeEqualsInfinity( pt1, pt2, pLineElement )
else if ( dy = 0 ) then SlopeEqualsZero( pt1, pt2, pLineElement )
else if (slope > 1.0) then SlopeGreaterThanOne ( pt1, pt2, pLineElement )
else if (slope > 0.0) then SlopeZeroToOne ( pt1, pt2, pLineElement )
else if (slope < -1.0) then SlopeLessThanNegOne ( pt1, pt2, pLineElement )
else SlopeNegOneToZero ( pt1, pt2, pLineElement ) ;
END ; { DrawLine() }
(*=========================================================*) { Initialize Unit }
BEGIN
END .
{ End of Unit }
Rick Engebretson wrote:
Here is a draft of a draw routine. It is intended to set up linked lists for draw primitives such as circles and squares. While not a working draft, it compiles and runs the little test. And the logic is readable in Pascal.
I don't know what your design goals are, but allocating a linked list node for each pixel is a bit of overhead. It may be fine for some applications, but maximum speed probably isn't one of them. (At least it's an interesting contrast to the numerous postings in c.l.p.b -- at least some years ago when I read it -- with hand-written assembler putpixel routines ;-).
TYPE pPixel = ^TPixel; TPixel = Record x, y, color : longint; end; { TPixel } pListElement = ^PixelListElement; { The List Handle } PixelListElement = Record ListIndex : longint; Pixel : TPixel; NextPixel : pListElement; end;
BTW, why LongInt? This it 64 bit on most targets. For the coordinates surely 32 or even 16 bit are sufficient, i.e. plain `Integer' should do. For the colors you may need 32 bits, so `Integer' may be too small on a few 16 bit platforms, but you may want to use a separate type (e.g. `TColor') as e.g. GRX does which could be declared as `Integer attribute (Size = 32)' or so.
Anyway, I suggest to avoid the overhead of extra-large integers (which can be considerable) unless really needed. Perhaps your application is entirely time-uncritical, but for graphics applications that's not always so.
Frank
Frank Heckenbach wrote:
Rick Engebretson wrote:
Here is a draft of a draw routine. It is intended to set up linked lists for draw primitives such as circles and squares. While not a working draft, it compiles and runs the little test. And the logic is readable in Pascal.
I don't know what your design goals are, but allocating a linked list node for each pixel is a bit of overhead. It may be fine for some applications, but maximum speed probably isn't one of them. (At least it's an interesting contrast to the numerous postings in c.l.p.b -- at least some years ago when I read it -- with hand-written assembler putpixel routines ;-).
TYPE pPixel = ^TPixel; TPixel = Record x, y, color : longint; end; { TPixel }
pListElement = ^PixelListElement; { The List Handle } PixelListElement = Record ListIndex : longint; Pixel : TPixel; NextPixel : pListElement; end;
BTW, why LongInt? This it 64 bit on most targets. For the coordinates surely 32 or even 16 bit are sufficient, i.e. plain `Integer' should do. For the colors you may need 32 bits, so `Integer' may be too small on a few 16 bit platforms, but you may want to use a separate type (e.g. `TColor') as e.g. GRX does which could be declared as `Integer attribute (Size = 32)' or so.
Anyway, I suggest to avoid the overhead of extra-large integers (which can be considerable) unless really needed. Perhaps your application is entirely time-uncritical, but for graphics applications that's not always so.
Frank
Actually, the linked list is the design goal and is standard pascal and is exceedingly efficient for working with pixel sets. Check out the Bresenham C routines in SVGAlib.
The longint is certainly inappropriate and is irrelevant to the design. It just works on both GPC and FPC. Also, the color is not right for the same reason, as you say.
I've looked over tons of assembler and want pure pascal. This is only part of the rewrite of SVGA lib. The elegance of pascal is clear. My design goal is to create a stable, readable alternative to SVGAlib. The circle is actually simpler than the line using Bresenham's methods with pascal. Again, this is not a working draft and does not include the framebuffer screen array.