jfh@rpp386.cactus.org (John F. Haugh II) (03/13/90)
I wrote a TPLOT -> Hercules converter some time ago, and now that I have entered the 1980's and purchased a used EGA board and display [ Yes, I am somewhat behind the times ... ], I am interested in writing a TPLOT -> EGA converter. What I would like very much is a collection of algorithms for converting a random (x, y) coordinate in (r, g, b) color into an actual point on the screen. The goal is to use this code as the lowest level routine ala point() from the tplot library. I am graphics adapter illiterate, but a good explanation of the mapping and general scheme of the EGA adapter in some reasonable mode should suffice. The results of this project will be posted to some newsgroup. Possibly along with the latest incarnation of the Hercules TPLOT filter, which works nicely with GNUPLOT when I use both monitors ;-) In the meantime, if anyone can point me at a GIF viewer for SCO 2.2.3, I'd be happy. I've discovered the joy of 30 hour ray tracings and I'd like to see what they look like, in color rather than the lousey mono hack job I've been playing with [ Yuck! ]. -- John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh Ma Bell: (512) 832-8832 Domain: jfh@rpp386.cactus.org
chip@chinacat.Lonestar.ORG (Chip Rosenthal) (03/14/90)
jfh@rpp386.cactus.org (John F. Haugh II) writes: >I wrote a TPLOT -> Hercules converter some time ago, and now that I have >entered the 1980's and purchased a used EGA board and display [ Yes, I am >somewhat behind the times ... ], I am interested in writing a TPLOT -> >EGA converter. This gets nasty when you get above CGA resolution. CGA and below it's real easy - you just do an ioctl to get a shared memory segment located at the video memory, and twiddle bits from there. A little magic goes into encoding the memory bit positions into color plane and pixel location, but no real big deal. I severly hacked on the glplot program posted to comp.sources.misc a while back. I ported the CGA stuff to XENIX and added EGA capabilities. The code which did the CGA pixel write looks something like: /* * Lookup tables to convert pixel number to byte position. Uses * 2 bits/pixel, first pixel is most significant 2 bits. */ static int pix2byte[] = { 0xC0, 0x30, 0x0C, 0x03 }; /* * Lookup tables to convert color number to bit pattern - 2 bits/pixel. */ static int color2byte[] = { 0x00, 0x55, 0xAA, 0xFF, }; row = ( y >> 1 ); col = ( x >> 2 ); mask = ( color2byte[GL_color&03] & pix2byte[x&03] ); if ( y & 01 ) video_memory_page2[row][col] |= mask; else video_memory_page1[row][col] |= mask; break; However, at EGA and higher resolutions it gets ugly. The memory segment is no longer a direct map of the video screen. Instead you need to take three steps. First, you write to the video controller to set the color planes you want to write. Second, you write to the video controller to say which pixel(s) within a group of eight to write. Finally, you do a dummy write to the shared memory region to place the octet of pixels you are writing. Here is the ugliness I used to write EGA memory: #include <sys/machdep.h> #define GDR_SEL 0x3CE /* graphics data registers - select */ #define GDR_DATA 0x3CF /* graphics data register - data */ #define GDR_BIT_MASK 8 /* bit mask */ static struct port_io_struct io_mask_ctrl[4] = { { OUT_ON_PORT, GDR_SEL, GDR_BIT_MASK }, { OUT_ON_PORT, GDR_DATA, 0x00 }, { IN_ON_PORT, 0, 0 }, { IN_ON_PORT, 0, 0 }, }; /* * Lookup tables to convert pixel number to byte position. Uses * 1 bit/pixel, first pixel is most significant bit. */ static int pix1byte[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; row = ( y ); col = ( x >> 3 ); mask = pix1byte[ x & 07 ]; io_mask_ctrl[1].data = mask; (void) ioctl(0,CONSIO,io_mask_ctrl); video_memory[row][col] |= 0xFF; Note that this is assuming that your color is already set, so it is only doing the last two steps: writing the video controller to select the pixel within the group of eight, and then a dummy memory write to place the octet. Here lies the problem: you are doing a system trap *per pixel*! I got gnuplot running with this stuff, but it was a real pig. To improve things a bit, I played some games caching up the pixels within an octet, and doing a write only when you moved to a different octet. This helped, and it made drawing sine curves very dramatic. With high dy/dx (e.g. around y = 0) it drew very slow, but at low dy/dx (at the tops & bottoms) it would move at a nice clip because you'd hit lots of groups of adjacent pixels. Never the less, the performance was still suboptimal. >What I would like very much is a collection of algorithms for converting >a random (x, y) coordinate in (r, g, b) color into an actual point on the >screen. The goal is to use this code as the lowest level routine ala >point() from the tplot library. I am graphics adapter illiterate, but a >good explanation of the mapping and general scheme of the EGA adapter in >some reasonable mode should suffice. I guess I'm trying to keep anybody from running down the blind alley I did. Direct screen control works fine at low resolutions, but the overhead of an ioctl() per pixel makes it unusable at higher resolutions. Were I to do it over again (and I probably will), I would look into using the CGI routines. If that fails, then I think you are stuck having to write a device driver to do console graphics output. There was a lot of hacking and trial and error and aggravation in figuring out the above. The screen(HW) man page documents the necessary ioctl's and the (struct port_io_struct), but it gives no information on the video display architecture, most notably the video controller register set. I ultimately figured it out by looking through a peecee graphics book to get the information on the video system, and figuring out the ioctl() implementation which would replace their BIOS calls. Unfortunately, I do not recall the title or author of this book. -- Chip Rosenthal | Yes, you're a happy man and you're chip@chinacat.Lonestar.ORG | a lucky man, but are you a smart Unicom Systems Development, 512-482-8260 | man? -David Bromberg
ron@mlfarm.uucp (Ronald Florence) (03/14/90)
In article <18134@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes:
In the meantime, if anyone can point me at a GIF viewer for SCO 2.2.3,
I'd be happy. I've discovered the joy of 30 hour ray tracings and I'd
like to see what they look like, in color rather than the lousey mono
hack job I've been playing with [ Yuck! ].
I can't help with a GIF viewer, but I do have a hack to GNUPLOT that
drives the SCO CGI devices. Works fine with an EGA, VGA, Laserjet,
HP7470a, or Deskjet. If there's interest, I'll post it, although I'm
not sure I can create proper diff files at this point. And with
GNUPLOT 2.0 coming Real Soon Now, maybe we should all wait.
--
Ronald Florence ron@mlfarm.uu.net
{yale,uunet}!hsi!mlfarm!ron
ron@mlfarm.uucp (Ronald Florence) (03/15/90)
This is going to make a semi-Indian-giver out of me... I've received a number of requests for my hack of GNUPLOT to the SCO CGI drivers. If someone will be so kind as to send me the following files from the original GNUPLOT distribution Makefile, command.c, misc.c, plot.c, plot.h, term.c I will prepare and post a proper patch. Thanks. -- Ronald Florence ron@mlfarm.uu.net {yale,uunet}!hsi!mlfarm!ron