RE: Microwindows for Hercules
: The code in devdraw.c is very naiive. It assumes pixel plotting is the underlyin : op. On many cards line slices are the underlying operation, horizontal or : vertical. What you probably want to do is generate a series of : : draw_horizontal(x,y,l) : : or : draw_vertical(x,y,l) : : calls for most things : That's a good idea. This would certainly speed up diagonal lines on systems with a fast horizontal line draw. The vertical doesn't add much, as most video planes aren't optimized for vertical line drawing. Currently, there aren't any applications that draw diagonal lines though, so the speed issue is mute. : > This might be useful when bitblt is implemented though... : : Having 32K of offscreen memory is always useful. : Definitely. I plan on adding offscreen drawing memory, but it requires some big architecture changes. Greg
Re: Microwindows for Hercules
> No need. MicroWindows handles the Bresenham algorithm in the mid > level code in devdraw.c. It uses successive calls to drawpixel to make it work. > In this way, people like you and me don't have to rewrite bresenham for every > card someone wants The code in devdraw.c is very naiive. It assumes pixel plotting is the underlyin op. On many cards line slices are the underlying operation, horizontal or vertical. What you probably want to do is generate a series of draw_horizontal(x,y,l) or draw_vertical(x,y,l) calls for most things > This might be useful when bitblt is implemented though... Having 32K of offscreen memory is always useful. Alan
RE: Microwindows for Hercules
: Actually there's semi-standard 800x600x16 support that works on most : SVGA controllers using the same VGA16 code; that requires 800 * 600 / : 2 = 240,000 bytes memory, but it's mapped into 800 * 600 / 8 = 60,000 : bytes memory at one bit per pixel with the VGA16 code. : Speaking of this, what would be *really* cool would be to add SVGA bios support to my scr_bios driver, so that we could support the higher than 640x480 modes Any volunteers? Greg
RE: Microwindows for Hercules
A good idea, almost. The BOGL library performs this for the packed pixel :modes, but the VGA requires OUT instructions inbetween memory accesses, :so it can't run on a generalized bit-depth algorithm in planes mode. (The VGA :design has to be seen/studied to be believed, I've never seen such a complicated :piece of hardware for something kinda-conceptually simple) : : Although it would still require special case code, I believe that a : line-drawing routine for VGA16 would be relatively simple, since each : pixel is the same color. It's been a couple months since I've written : any VGA16 code, but IIRC writing a number of pixels all in one color : can be done with a specialized write mode that makes it easier. This is what we need. This special case code is already in the driver scr_bios.c under VGA_drawhline(). It calls either the C entry point in vgaplan4.c or the asm implementation in asmplan4.s called ega_drawhline. This code isn't optimized for multiple pixels with the same color, yet, and would most likely tremendously increase speed on slow systems like ELKS 8086's. Greg :
RE: Microwindows for Hercules
: > The place where nano-X and microwindows spend at *least* 95% of their : > pixel-pushing code is in drawing horizontal lines. All the demos but one : > *never* draw a diagonal line, the only case where bresenham is used. I had : > completed test cases to prove this... : : OK, granted. Nevertheless, does this mean it has to be slow? Suppose in : the future someone writes a drawing program for ELKS, using the XOR algo : to draw lines (and erase them again as the mouse pointer moves). Yes, microwindows is ready for this, the code is already commented out, waiting for somebody to add it. I just hadn't heard complaints about the diagonal line drawing speed yet. (check out devdraw.c, and you'll see that *if* the clipping routines see that the line can be drawn full speed with no clipping, then a commented out low level routine can be called to perform the function at blinding speed.) : Hmm then that's something that could be checked for in between STOSB : instructions (or the like). We could for example use something like this : (just an idea), where ? is a flag that isn't used (maybe the carry flag?): : : PUSH flags register : CLI (we don't want to draw lines with interrrupts off) : ... : {If out needed} ST? : ... : {Bresenham} : ... : STOSB {or something like that, like OR} : LOOPN? : JN? :End : ... : {Perform OUT} : ... : LOOP : ... : : :End : ... : POP flags register : : We could of course also use something else than a flag, like a register, : if Bresenham doesn't already use all of them... : Just an idea, I never did VGA 4 bit programming, I always used mode 13h. : Generally, it would be nice to have everything in asm for blinding speed. I've already done this with microwindows and nano-X, see the file asmplan4.s.. I also have everything written in C so that it's easily understandable, and portable. Why don't various people play with this code, and maybe it should be part of the standard make? Greg
RE: Microwindows for Hercules
On Fri, 16 Jul 1999, Greg Haerr wrote: > From: Greg Haerr <[EMAIL PROTECTED]> > Subject: RE: Microwindows for Hercules > > > : Hmm. A 8086 isn't quite a PC on which you want to loose performance. And > : that's exactly what you're doing here. PutPixel is a short routine and you > : loose way to much time if you don't inline it... > > The place where nano-X and microwindows spend at *least* 95% of their > pixel-pushing code is in drawing horizontal lines. All the demos but one > *never* draw a diagonal line, the only case where bresenham is used. I had > completed test cases to prove this... OK, granted. Nevertheless, does this mean it has to be slow? Suppose in the future someone writes a drawing program for ELKS, using the XOR algo to draw lines (and erase them again as the mouse pointer moves). > : > In this way, people like you and me don't have to rewrite bresenham for every > : > card someone wants > : > : You wouldn't have to rewrite it for every -CARD-, you would have to re- > : write it for every BIT-DEPTH. Which isn't that much work anyway. > : > A good idea, almost. The BOGL library performs this for the packed pixel > modes, but the VGA requires OUT instructions inbetween memory accesses, > so it can't run on a generalized bit-depth algorithm in planes mode. (The VGA > design has to be seen/studied to be believed, I've never seen such a complicated > piece of hardware for something kinda-conceptually simple) Hmm then that's something that could be checked for in between STOSB instructions (or the like). We could for example use something like this (just an idea), where ? is a flag that isn't used (maybe the carry flag?): PUSH flags register CLI ... {If out needed} ST? ... {Bresenham} ... STOSB {or something like that, like OR} LOOPN? JN? :End ... {Perform OUT} ... LOOP ... :End ... POP flags register We could of course also use something else than a flag, like a register, if Bresenham doesn't already use all of them... Just an idea, I never did VGA 4 bit programming, I always used mode 13h. Which may be more of a problem is if we would use res > 320x200x256. These don't fit in one page, and we would have to do page swapping. (Except if we got a linear framebuffer). But there won't be many 8088-80286 that sup- port those res anyway.. Chipzz AKA Jan Van Buggenhout (Sorry for the rusty asm ;-) ) -- UNIX isn't dead - It just smells funny [EMAIL PROTECTED] --
RE: Microwindows for Hercules
: Hmm. A 8086 isn't quite a PC on which you want to loose performance. And : that's exactly what you're doing here. PutPixel is a short routine and you : loose way to much time if you don't inline it... The place where nano-X and microwindows spend at *least* 95% of their pixel-pushing code is in drawing horizontal lines. All the demos but one *never* draw a diagonal line, the only case where bresenham is used. I had completed test cases to prove this... : : > In this way, people like you and me don't have to rewrite bresenham for every : > card someone wants : : You wouldn't have to rewrite it for every -CARD-, you would have to re- : write it for every BIT-DEPTH. Which isn't that much work anyway. : A good idea, almost. The BOGL library performs this for the packed pixel modes, but the VGA requires OUT instructions inbetween memory accesses, so it can't run on a generalized bit-depth algorithm in planes mode. (The VGA design has to be seen/studied to be believed, I've never seen such a complicated piece of hardware for something kinda-conceptually simple) Greg
RE: Microwindows for Hercules
: I got the VGA mode 13h Bresenham line code here (in asm), which I got from : SWAG (SourceWare Archival Group, Pascal Code). I don't know if it's of any : use, but I can post it here. If anyone is interested, there is some asm : Bresenhams circle code out there too. SWAG is not copyrighted. : Just let me know if you're interested. : I would be interested in seeing the circle code... Also, some very fast non-bresenham horizontal line code would be interesting to look at for the various pc video adapters. (I have included one asm version in microwindows for reference, but it's not normally compiled in) Greg
RE: Microwindows for Hercules
> No need. MicroWindows handles the Bresenham algorithm in the mid > level code in devdraw.c. It uses successive calls to drawpixel to make it work. Hmm. A 8086 isn't quite a PC on which you want to loose performance. And that's exactly what you're doing here. PutPixel is a short routine and you loose way to much time if you don't inline it... > In this way, people like you and me don't have to rewrite bresenham for every > card someone wants You wouldn't have to rewrite it for every -CARD-, you would have to re- write it for every BIT-DEPTH. Which isn't that much work anyway. Chipzz AKA Jan Van Buggenhout -- UNIX isn't dead - It just smells funny [EMAIL PROTECTED] --
Re: Microwindows for Hercules
On Thu, 15 Jul 1999, Jakob Eriksson wrote: > From: Jakob Eriksson <[EMAIL PROTECTED]> > Subject: Re: Microwindows for Hercules > > Excellent! > > I have examples on how to draw fast lines horizontal, vertical and > (x1, y1) -> (x2, y2) using Bresenham. I got the VGA mode 13h Bresenham line code here (in asm), which I got from SWAG (SourceWare Archival Group, Pascal Code). I don't know if it's of any use, but I can post it here. If anyone is interested, there is some asm Bresenhams circle code out there too. SWAG is not copyrighted. Just let me know if you're interested. Chipzz AKA Jan Van Buggenhout -- UNIX isn't dead - It just smells funny [EMAIL PROTECTED] --
RE: Microwindows for Hercules
: Obviously it would be smart to fill it in. However you must set it to NULL : in the driver because of symbol resolution. : : As long as the device driver header file version matches with the one that : the microwin server uses, the offsets are known. : : Locating the symbols inside the driver is the hard part. : : Perhaps a separate file, created via an external program, which contains : this structure, is the better way to go. This way when the structure changes, : you don't have to go around recompiling all the drivers that have been : distributed, you just need a program to fixup your jumptable files. Currently this is all overkill, since the drivers are compiled into the microwin binary. Also, due to inkd of a neat design, we don't have the problems that require the driver symbol to be NULL. : : Does anyone know if code exists to hunt for symbols inside a binary? Does : bcc generate any symbol information? Sure, you can run nm86 on .o and a.out files. : : If bcc doesn't generate any symbol info, then I would suggest that each driver : be an archive of object files, with a manifest. You would need the code from : the linker to search the archive and something to read the manifest. : : > : > struct driver herc_card[]={ : > herc_hline, : > herc_vline, : > generic_line, : > }; : > : > or it can be done in a function that examines the structure at load : > time and patches up any NULLs with real function pointers. This is a : > good way to reduce the special cases. All this would be solved with Al's DLL stuff, which he's working on. Then we'd having dynamically linked libraries, of which each driver would be one. Greg : >
RE: Microwindows for Hercules
: : If someone's really going to take that approach (I assumed something : like this was already being done), then I recommend modifying it a : little for speed. Instead of leaving NULL in the table and having to : test it each time the function is being called, replace the NULL with : a function pointer. This can either be done in the device driver : directly: : : struct driver herc_card[]={ : herc_hline, : herc_vline, : generic_line, : }; : Good idea, Ben. We certainly take that approach now, if the sources are checked out. Before everybody gets the idea that this all needs rewriting, please look at device.h, devdraw.c, and the drivers subdirectory. The current design has had a lot of thought put into it, and is preparing for the day when bitblt will be added. For instance, the mid level performs *all* clipping, not the low level. Thus, the low level can't replace the upper level, because there's no access to the clipping functions. Certain drivers, namely scr_bogl and scr_bios have commented out generic functions that will come online in the way above described when the speed/size tradeoff merits. A close look at devdraw.c will show commented out functions, like low level bresenham, that will also come to play. Greg
RE: Microwindows for Hercules
: Why not take the approach that Linux takes with the module: : : Create the driver structure, have the primitives referenced in the : driver structure. If the driver doesn't implement a primitive, set : the structure member to NULL, and the driver loader will take care : to use the builtin function. EG: : : That way you can have driver optimized primitives or rely on the default, : which just calls write_pixel. : Yes, that's the general idea I was going to use. However, my plan was to add required functionality first, and optimize later. So far, the only driver speed issue identified is that the text output may be too slow. Otherwise, most speed issues are the 8086 itself. The other factor is keeping the code size very small, so that there's room for applications to be linked with the library... Greg
Re: Microwindows for Hercules
> >sounds good. >how much would it take to change/add microwin? That, I don't know, Greg? > > If someone's really going to take that approach (I assumed something > like this was already being done), then I recommend modifying it a > little for speed. Instead of leaving NULL in the table and having to > test it each time the function is being called, replace the NULL with > a function pointer. This can either be done in the device driver > directly: Obviously it would be smart to fill it in. However you must set it to NULL in the driver because of symbol resolution. As long as the device driver header file version matches with the one that the microwin server uses, the offsets are known. Locating the symbols inside the driver is the hard part. Perhaps a separate file, created via an external program, which contains this structure, is the better way to go. This way when the structure changes, you don't have to go around recompiling all the drivers that have been distributed, you just need a program to fixup your jumptable files. Does anyone know if code exists to hunt for symbols inside a binary? Does bcc generate any symbol information? If bcc doesn't generate any symbol info, then I would suggest that each driver be an archive of object files, with a manifest. You would need the code from the linker to search the archive and something to read the manifest. > > struct driver herc_card[]={ > herc_hline, > herc_vline, > generic_line, > }; > > or it can be done in a function that examines the structure at load > time and patches up any NULLs with real function pointers. This is a > good way to reduce the special cases. > -- > "...dans ce pays-ci il est bon de tuer de temps en temps un amiral > pour encourager les autres." > --Voltaire, _Candide_ > --Perry -- Perry Harrington Linux rules all OSes.APSoft () email: [EMAIL PROTECTED] Think Blue. /\
Re: Microwindows for Hercules
On Thu, 15 Jul 1999, Perry Harrington wrote: > Why not take the approach that Linux takes with the module: > > Create the driver structure, have the primitives referenced in the > driver structure. If the driver doesn't implement a primitive, set > the structure member to NULL, and the driver loader will take care > to use the builtin function. EG: > > struct driver { > ptr_t hline > ptr_t vline > ptr_t bline > ... > } DRIVER; > > struct driver herc_card[]={ > herc_hline, > herc_vline, > NULL > }; > > That way you can have driver optimized primitives or rely on the default, > which just calls write_pixel. sounds good. how much would it take to change/add microwin? Jakob
Re: Microwindows for Hercules
> If using writepixel, there need be 16 writes to videomemory. > When using the native HGC linedraw, there need be only 4 writes to videomem. > > Also, the algo. uses an incrementing form of bresenham. Very standard, > yes. But the incrementing scheme takes into account the bizarre > HGC memory layout. > > Regards, > Jakob Eriksson > > Why not take the approach that Linux takes with the module: Create the driver structure, have the primitives referenced in the driver structure. If the driver doesn't implement a primitive, set the structure member to NULL, and the driver loader will take care to use the builtin function. EG: struct driver { ptr_t hline ptr_t vline ptr_t bline ... } DRIVER; struct driver herc_card[]={ herc_hline, herc_vline, NULL }; That way you can have driver optimized primitives or rely on the default, which just calls write_pixel. --Perry -- Perry Harrington Linux rules all OSes.APSoft () email: [EMAIL PROTECTED] Think Blue. /\
RE: Microwindows for Hercules
: That is fine for normal cards, but since Hercules cards are so ... strange... The VGA is *far* stranger, believe me, because of it's requiring more than 64k of video memory... : the algo is very optimized for the Hercules. : Example: : : : : : : If using writepixel, there need be 16 writes to videomemory. : When using the native HGC linedraw, there need be only 4 writes to videomem. : : BYTEBYTE : 7654321076543210 : : : : : : The benefit increases the more horizontal the line is. : : Also, the algo. uses an incrementing form of bresenham. Very standard, : yes. But the incrementing scheme takes into account the bizarre : HGC memory layout. : Calculating a byte address and bit offset for a given X, Y is rather : costly, whatever way you do it. : But when drawing a line you know a lot of stuff already, so you are : not solving the problem (X, Y) ---> (byte address, bit offset), : you are only drawing a line. Yep, you're right. But currently, very few applications require bresenham, so it's still in the mid level. Far more often is drawing rectangles, which consist mostly of horizontal lines. This is the code that *must* be fast. The bresenham code doesn't have to be fast, since it's rarely called for non-scientic apps (the graphd3d demo code that I've written for microwindows for instance is too large for ELKS...) : > The fast line draw that we need is the one that calculates the : > *bit* starting position in a starting scan line byte, and the end *bit* position. : > The bits in between the begin and end are then filled with ones. For the bytes : > inbetween, this is ridculously easy, just set them to 0xff. For the begin and : > end, use a mask to set those bits... : : I am not sure about what you mean here. : You mean we need an algo that returns BYTEADDRESS, BITSTART and BITEND? Yes, it's already done in HERC_drawpixel. The HERC_drawhline code will want to precalc each of those for one line, rather than pixel-by-pixel. Take a look at the hercules driver, and you'll see what I mean. : I was rather thinking of a solution not visible to above layers, but : maybe that was not a good idea... :-) : (A hack.) : Nothing wrong with that, except that the low level code for nano-X and microwindows is only interfaced (currently by design) thru a very few entry points: readpixel drawpixel drawhline drawvline fillrect This was purposely designed so that I or someone else could actually write a working driver for a new card in one evening... We can add speed stuff later, once we find people who actually use it and want the improvement. Later, I plan on adding a fast text out primitive for Al's work on scrolling text for ELKS. Greg : Regards, : Jakob Eriksson : :
RE: Microwindows for Hercules
On Thu, 15 Jul 1999, Greg Haerr wrote: > : I have examples on how to draw fast lines horizontal, vertical and > : (x1, y1) -> (x2, y2) using Bresenham. > : These are in a book in asm. so I don't know about their copyright but > : I think they are intended to be used, ie public domain. > : Bresenham on Hercules is a little tricky. > > No need. MicroWindows handles the Bresenham algorithm in the mid > level code in devdraw.c. It uses successive calls to drawpixel to make it work. > In this way, people like you and me don't have to rewrite bresenham for every > card someone wants That is fine for normal cards, but since Hercules cards are so ... strange... the algo is very optimized for the Hercules. Example: If using writepixel, there need be 16 writes to videomemory. When using the native HGC linedraw, there need be only 4 writes to videomem. BYTEBYTE 7654321076543210 The benefit increases the more horizontal the line is. Also, the algo. uses an incrementing form of bresenham. Very standard, yes. But the incrementing scheme takes into account the bizarre HGC memory layout. Calculating a byte address and bit offset for a given X, Y is rather costly, whatever way you do it. But when drawing a line you know a lot of stuff already, so you are not solving the problem (X, Y) ---> (byte address, bit offset), you are only drawing a line. If someone wants asm code I can write it down from the book. > The fast line draw that we need is the one that calculates the > *bit* starting position in a starting scan line byte, and the end *bit* position. > The bits in between the begin and end are then filled with ones. For the bytes > inbetween, this is ridculously easy, just set them to 0xff. For the begin and > end, use a mask to set those bits... I am not sure about what you mean here. You mean we need an algo that returns BYTEADDRESS, BITSTART and BITEND? > : If I don't remember wrong, there are two buffers on a Hercules (2 * 32k mem) > : so you can even doublebuffer changes. Now that would be cool to work into > : the driver. > : If you other people fix it into working order, I can fix double buffering. > > Neither nano-X or microwindows require or use double buffering currently, > This might be useful when bitblt is implemented though... I was rather thinking of a solution not visible to above layers, but maybe that was not a good idea... :-) (A hack.) Regards, Jakob Eriksson
RE: Microwindows for Hercules
: I have examples on how to draw fast lines horizontal, vertical and : (x1, y1) -> (x2, y2) using Bresenham. : These are in a book in asm. so I don't know about their copyright but : I think they are intended to be used, ie public domain. : Bresenham on Hercules is a little tricky. No need. MicroWindows handles the Bresenham algorithm in the mid level code in devdraw.c. It uses successive calls to drawpixel to make it work. In this way, people like you and me don't have to rewrite bresenham for every card someone wants The fast line draw that we need is the one that calculates the *bit* starting position in a starting scan line byte, and the end *bit* position. The bits in between the begin and end are then filled with ones. For the bytes inbetween, this is ridculously easy, just set them to 0xff. For the begin and end, use a mask to set those bits... : If I don't remember wrong, there are two buffers on a Hercules (2 * 32k mem) : so you can even doublebuffer changes. Now that would be cool to work into : the driver. : If you other people fix it into working order, I can fix double buffering. Neither nano-X or microwindows require or use double buffering currently, This might be useful when bitblt is implemented though... Greg
Re: Microwindows for Hercules
On Thu, 15 Jul 1999, Greg Haerr wrote: > : I am not really up to writing the driver myself because I have never writen a > : driver before, but I will test it for you. I have 2 8086's with herc cards > : in. > > Well, last night I took Jacob's hercules code samples and wrote k :-) > a complete hercules graphics driver for MicroWindows and Nano-X. I wrote > all the driver entry points, but since I don't have a hercules card, I can't test it. > Basically, the hercules card appears to use 32k of graphics ram for 720x350 mono > pixels starting at segment b000. Each "screen ram line" corresponds to 4 physical > scan lines, and there's one bit per pixel. There's a sequence of OUT instructions > to turn the card from text to graphics modes and back, and I use int10 to get > the bios rom's character set map. > > The files mwin/src/drivers/scr_herc.c are the hercules driver and > mwin/src/drivers/elksutil.c are some support functions to read/write far data, etc. > > I'm looking for volunteers to test, I think this baby should run pretty >quickly. > It will be slow, since I've implemented hline by calling drawpixel. This > needs to be sped up by drawing a scan line directly. I didn't want to do that > until I knew drawpixel() works. Excellent! I have examples on how to draw fast lines horizontal, vertical and (x1, y1) -> (x2, y2) using Bresenham. These are in a book in asm. so I don't know about their copyright but I think they are intended to be used, ie public domain. Bresenham on Hercules is a little tricky. If I don't remember wrong, there are two buffers on a Hercules (2 * 32k mem) so you can even doublebuffer changes. Now that would be cool to work into the driver. If you other people fix it into working order, I can fix double buffering. Jakob
Microwindows for Hercules
: I am not realy up to writing the driver myself because I have never writen a : driver before, but I will test it for you. I have 2 8086's with herc cards : in. Well, last night I took Jacob's hercules code samples and wrote a complete hercules graphics driver for MicroWindows and Nano-X. I wrote all the driver entry points, but since I don't have a hercules card, I can't test it. Basically, the hercules card appears to use 32k of graphics ram for 720x350 mono pixels starting at segment b000. Each "screen ram line" corresponds to 4 physical scan lines, and there's one bit per pixel. There's a sequence of OUT instructions to turn the card from text to graphics modes and back, and I use int10 to get the bios rom's character set map. The files mwin/src/drivers/scr_herc.c are the hercules driver and mwin/src/drivers/elksutil.c are some support functions to read/write far data, etc. I'm looking for volunteers to test, I think this baby should run pretty quickly. It will be slow, since I've implemented hline by calling drawpixel. This needs to be sped up by drawing a scan line directly. I didn't want to do that until I knew drawpixel() works. The files are all incorporated in microwindows 0.83, due on my site in about fifteen minutes... Greg