myoung@ingr.UUCP (Mark Young) (01/02/88)
Good News (for me it was good news) ! for a while now, I've watched several requests get battered back and forth about information on the hercules graphics card. I kept waiting for some kind soul to fill me in on the why and wheres of programming the darn thing. well, this last week I mentioned it to a friend who steered me to a copy of "Micro Cornucopia", issue #39, Jan-Feb 1988. It has an article in it that seemed to cover most of my questions. sooo, if you were looking for the info too, look here. it may answer some of your questions too! ...myoung --- ingr!myoung!myoung@uunet.uu.net | mark allan young | where {uunet,ihnp4}!ingr!myoung!myoung | intergraph corp, cr1105 | do I WARNING: all postings from this node | one madison industrial pk | put the are monitored, so I guess I have to | huntsville, al 35807 | usual be responsible (hi dave...;-) | (205) 772-6094 | disclaimer
jsin@CS.UCLA.EDU (01/05/88)
In article <1866@ingr.UUCP> myoung@ingr.UUCP (Mark Young) writes: > >well, this last week I mentioned it to a friend who steered me to a copy of >"Micro Cornucopia", issue #39, Jan-Feb 1988. It has an article in it that >seemed to cover most of my questions. > I've spent some time typing this into my computer. It seems to work pretty well with my Herc-compatible clone card. If anyone wants a copy, send me e-mail. John (Jonghoon) Sin UCLA SEASnet Facilities InterNet: jsin@seas.ucla.edu 2567 Boelter Hall UUCP: ...!{ihnp4,ucbvax,{hao!cepu}}!ucla-cs!jsin Los Angeles, CA. 90025 VoiceNet: (213) 206-6864
jsin@CS.UCLA.EDU (01/06/88)
Hi Folks! I've received enough request for this, so I'm posting it on the net. I also included the Mandelbrot function which appeared in the same issue of MC. I thought of posting this on one of the 'sources' newsgroup, but decided against it. Sorry if that causes problem for you. Anyway, Here it is, enjoy and have fun! John Sin ------------------------------------------------------------------ /* * Graphics Routine for the Hercules Graphics Card * * Following routines were obtained from the article _A Hercules Primer_, * by Larry Fogg. (Micro Cornucopia, Issue No. 39, Jan/Feb 1988, pp 24-29.) * * Entered and Modified by John Sin, January 1988. * * * ---> 6845 Registers <--- * * Register Function Settings in Hex * (Text) (Graphics) * * 0 Total Horizontal characters 61 35 * 1 Displayed horizontal characters 50 2d * 2 Horizontal sync position 52 2e * 3 Sync width 0f 07 * 4 Total Vertical rows 19 5b * 5 Vertical total adjust 06 02 * 6 Vertical rows displayed 19 57 * 7 Vertical sync position 19 57 * 8 Interlace mode and skew 02 02 * 9 Maximum scan line address 0d 03 * 10 Cursor's starting scan line 0b 00 * 11 Cursor's ending scan line 0c 00 * * * ---> Hercules Card Ports <--- * * Register Function * * 3b8 Mode Control * 3ba Status * 3bf Configuration * 3b4 CRTC Index Register * 3b5 CRTC Data Register * */ #include <stdio.h> #include <stdlib.h> #include <dos.h> #define boolean char #define yes 1 #define no 0 #define index 0x3b4 /* 6845 ports */ #define data 0x3b5 #define mode 0x3b8 /* Herc ports */ #define status 0x3ba #define config 0x3bf /* char attributes for direct memory screen writes */ const char normal = 0x07; const char reverse = 0x70; const char under_line = 0x01; const char normal_blink = 0x87; const char reverse_blink = 0xf0; const char under_blink = 0x81; const int page0 = 0xb000; /* base address of video page */ const int page1 = 0xb800; const int text_base = 0xb000; /* base address of text pages */ const int max_col = 719; const int max_row = 347; const int screen_size = 0x800; /* bytes per page */ int page_drawn, page_viewed; /* current drawing and viewing pages */ void init() /* set initial values for global variables */ { page_drawn = page0; page_viewed = page1; } boolean herc_there() /* test for presence of Herc card */ { int i; geninterrupt (0x11); if ((_AX & 0x30) == 0x30) /* check for mono card presence */ for (i=0; i<0x800; i++) /* is it Herc Card? */ if (inportb(status) & 0x80) /* watch bit 7 */ return (yes); return (no); } void screen_off() { outportb(mode, 2); } void set_page_viewed (int page) { if (page == page0) outportb (mode, 0x0a); else outportb (mode, 0x8a); page_viewed = page; } void set_page_drawn (int page) { page_drawn = page; } void clear_gr_scr (int page) { int i; if (page_viewed == page) screen_off(); /* turn off screen if page is displayed */ for (i=0; i<0x3fff; i++) poke (page, 2*i, 0); /* reset all bits in page */ if (page_viewed == page) /* turn screen on again */ set_page_viewed (page); } void clear_txt_scr () { int i; for (i=0; i<=0x3fff; i++) /* fill text page with nuls & attribute 7*/ poke (text_base, 2*i, 0x0700); } void scr_write (int X, int Y, char str[81], char attrib) { /* direct memory write of text */ int i, offset; i = 0; offset = 2 * (80 * Y + X); /* find memory offset of first char in str */ while (str[i] != '\0') { /* poke each char/attrib pair */ pokeb (text_base, offset, str[i]); pokeb (text_base, ++offset, attrib); i++; offset++; } } void set_graphics () { char i; char params[12] = {0x35, 0x2d, 0x2e, 0x07, 0x5b, 0x02, 0x57, 0x57, 0x02, 0x03, 0x00, 0x00}; outportb (config, 3); /* allows both graphics pages */ screen_off (); for (i=0; i<12; i++) { /* program 6845 registers for graphics */ outportb (index, i); outportb (data, params[i]); } clear_gr_scr (page0); /* clear and turn on screen */ clear_gr_scr (page1); } void set_text() { char i; char params[12] = {0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c}; outportb (config,0); /* lock out graphics mode */ outportb (mode, 0); /* set text mode and blank screen */ for (i=1; i<12; i++) { /* program 6845 for text */ outportb (index, i); outportb (data, params[i]); } clear_txt_scr(); outportb (mode, 0x28); /* enable blink and turn on screen */ } void save_screen (char fname[13], int page) { /* write to disk */ FILE *f; char far *screen; screen = page*0x10000; /* weird, but it works */ f = fopen (fname, "w"); fwrite (screen, screen_size, 1, f); fclose (f); } void get_screen (char fname[13], int page) { /* read from disk */ FILE *f; char far *screen; screen = page*0x10000; f = fopen (fname, "r"); screen_off(); fread (screen, screen_size, 1, f); set_page_viewed (page); /* turn the screen back on */ fclose (f); } void draw_point (int col, int row, boolean fill) { int byte_ofs; /* offset within page for byte containing the point */ char mask; /* locates point within the byte */ mask = 1 << (7 - (col % 8)); byte_ofs = 0x2000 * (row % 4) + 90 * (row/4) + (col/8); if (fill) /* draw the point */ pokeb (page_drawn, byte_ofs, peekb (page_drawn, byte_ofs) | mask); else /* erase the point */ pokeb (page_drawn, byte_ofs, peekb (page_drawn, byte_ofs) & ~mask); } void draw_line (int X1, int Y1, int X2, int Y2, boolean on) { /* use Bresenham's algorithm to draw a line */ boolean pos_slope; int dX, dY, /* vector components */ row, col, final, /* final row or col number */ G, /* used to test for new row or column */ inc1, /* G increment when row or column doesn't change */ inc2; /* G increment when row or column does change */ dX = X2 - X1; dY = Y2 - Y1; /* find vector component */ pos_slope = (dX > 0); /* is slope positive? */ if (dY < 0) pos_slope = !pos_slope; if (abs(dX) > abs(dY)) { /* shallow line case */ if (dX > 0) { /* determine start point and last column */ col = X1; row = Y1; final = X2; } else { col = X1; row = Y2; final = X1; } inc1 = 2*abs(dY); /* determine increments and initial G */ G = inc1 - abs(dX); inc2 = 2 * (abs(dY) - abs(dX)); if (pos_slope) while (col<=final) { /* step thru cols. checking for new row */ draw_point (col, row, on); col++; if (G >= 0) { /* it's time to change rows */ row++; G+= inc2; /* positive slope, so inc thru rows */ } else /* stay at the same row */ G += inc1; } /* while */ else while (col<=final) { /* step thru cols, check for new row */ draw_point (col, row, on); col++; if (G > 0) { /* time to change the rows */ row--; G+= inc2; /* negative slope, dec thru rows */ } else G += inc1; /* stay at the same row */ } /* while */ } /* if |dX| > |dY| */ else { if (dY > 0) { /* steep line case, angle > 45 degree */ col = X1; row = Y1; final = Y2; /* find start point and last row */ } else { col = X2; row = Y2; final = Y1; } inc1 = 2 * abs(dX); /* determine increments and initial G */ G = inc1 - abs(dY); inc2 = 2 * (abs(dX) - abs(dY)); if (pos_slope) while (row <= final) { /* step thru rows - check for new column */ draw_point (col, row, on); row++; if (G >= 0) { /* it's time to change columns */ col++; G+= inc2; /* pos. slope, increment thru cols. */ } else G += inc1; /* stay at the same column */ } /* while */ else while (row <= final) {/* step thru rows, checking for new column */ draw_point (col, row, on); row++; if (G > 0) { /* it's time to change columns */ col--; G+= inc2; /* neg slope, so decrement thru columns */ } else G += inc1; /* stay at the same column */ } /* while */ } /* if |dY| > |dX| */ } /**************************************************************************/ /* Subroutine MANDEL() from the same issue */ #define sqr(x) (x*x) #define MAX_ITERATIONS 100 #define MAX_SIZE 4 const int max_colors = 2; void mandel (float Pmax, float Pmin, float Qmax, float Qmin) { int color, row, col; float P, Q, modulus, deltaP, deltaQ, Xcur, Xlast, Ycur, Ylast; deltaP = (Pmax - Pmin) / (max_col - 1); deltaQ = (Qmax - Qmin) / (max_row - 1); for (col = 0; col <= max_col; col++) for (row = 0; row <= max_row; row++) { P = Pmin + col * deltaP; Q = Qmin + row * deltaQ; Xlast = Ylast = modulus = 0.0; color = 0; while ( (modulus < MAX_SIZE) && (color < MAX_ITERATIONS) ) { Xcur = sqr (Xlast) - sqr (Ylast) + P; Ycur = 2 * Xlast * Ylast + Q; color++; Xlast = Xcur; Ylast = Ycur; modulus = sqr (Xcur) + sqr (Ycur); } /* while */ draw_point (col, row, (color % max_colors)); } /* for */ } /* mandel */ /****************************************************************************/ John (Jonghoon) Sin UCLA SEASnet Facilities InterNet: jsin@seas.ucla.edu 2567 Boelter Hall UUCP: ...!{ihnp4,ucbvax,{hao!cepu}}!ucla-cs!jsin Los Angeles, CA. 90025 VoiceNet: (213) 206-6864
awylie@pyr1.cs.ucl.ac.uk (01/18/88)
This posting is appalling. Your routines contain some horrendous bugs. It will not even compile under Microsoft-C. Initialization of automatic arrays!!! What broken compiler accpets this??? Even if you did somehow compile it, several of the routines could never work - set_text has incorrect loop index : try to go from graphics mode back to text and KABLAM REBOOT TIME get_screen and save_screen do an illegal trick to convert the screen address to a long pointer ("weird" is your comment) but my compiler complains that the pointer is converted to short again when the memcpy (or memmove, I forget) routine is called to do the dirty work. These two routines also do not bother checking that fopen has been successful. There are other horrors in there which I will not mention. Stylistically the whole thing is a mess too, eg capital letters in non-preprocessor variables. Anyone who would like to get a working version of this mess, with also a routine to display text whilst in graphics mode, send me an e-mail. ------------------------------------------------------------ Andrew Wylie, University of London Computer Centre, 20 Guilford Street, London WC1N 1DZ, England. JANET: andrew@uk.ac.ulcc.ncdlab UUCP: ..!mcvax!ukc!cs.ucl.ac.uk!awylie ARPA: awylie@cs.ucl.ac.uk BITNET: andrew%uk.ac.ulcc.ncdlab@ac.uk If replying via satnet please give a UUCP path from mcvax to your site.
jsin@CS.UCLA.EDU (01/20/88)
In article <39500005@pyr1.cs.ucl.ac.uk> awylie@pyr1.cs.ucl.ac.uk writes: > >This posting is appalling. Your routines contain some horrendous bugs. >It will not even compile under Microsoft-C. Initialization of automatic It was probably my fault not mentioning that it was written for the Turbo C compiler version 1.0. I assumed everyone knew from previous postings that it was from a magazine article, and that only thing I did was put it on my floppy. >There are other horrors in there which I will not mention. Stylistically >the whole thing is a mess too, eg capital letters in non-preprocessor >variables. You may want to mention this to Larry Fogg yourself, by writing to MICRO CORNUCOPIA P.O. BOX 223 BEND, OREGON 97709 > >Anyone who would like to get a working version of this mess, with also a >routine to display text whilst in graphics mode, send me an e-mail. I think the Article was pretty good beginning point for people to learn about the innards of the Hercules card. I knew as I typed the program that I would modify it extensively, if I was going to write a program using those routines. However, since I had no idea before how the Hercules board works, I was pretty happy with it as is. Also, I'd like to clarify that I NEVER type in the actual article on my PC. I apologize if I didn't make myself clear. Send further flames to > /dev/null or pipe it to MicroCornucopia Inc. John Sin John (Jonghoon) Sin UCLA SEASnet Facilities InterNet: jsin@seas.ucla.edu 2567 Boelter Hall UUCP: ...!{ihnp4,ucbvax,{hao!cepu}}!ucla-cs!jsin Los Angeles, CA. 90025 VoiceNet: (213) 206-6864
broehl@watdcsu.waterloo.edu (Bernie Roehl) (01/26/88)
I found the posting quoted below so obnoxious I felt I should say something about it: In article <39500005@pyr1.cs.ucl.ac.uk> awylie@pyr1.cs.ucl.ac.uk writes: >This posting is appalling. Your routines contain some horrendous bugs. Not having seen the posting awylie@pyr1 is referring to, I can't argue about whether it has bugs or not. However, anything posted to the net is posted "as-is". I'm sure that the posting in question is neither the first nor the last to have some bugs in it. >It will not even compile under Microsoft-C. Initialization of automatic >arrays!!! What broken compiler accpets this??? A great many C compilers that I have used support this feature. The fact that Microsoft lacks it is unfortunate, but is certainly not the fault of the original poster. >There are other horrors in there which I will not mention. What "horrors" are these, pray tell? And why *not* mention them, since the person who originally posted the source would doubtless like to know about them? (and more importantly, has a *right* to know about them; see below) >Stylistically the whole thing is a mess too, eg capital letters in >non-preprocessor variables. To each their own coding style. >Anyone who would like to get a working version of this mess, with also a >routine to display text whilst in graphics mode, send me an e-mail. This is far and away the most irresponsible thing I've seen anyone do on the net in many, many years. Take source posted by someone else, publicly attack them because you don't like the way they code, and then redistribute their program so you can take credit for "fixing" it. Yuck. >------------------------------------------------------------ >Andrew Wylie, University of London Computer Centre, >20 Guilford Street, London WC1N 1DZ, England. Is this sort of behaviour *sanctioned* by the U of London Computing Centre? -- Bernie Roehl, University of Waterloo Electrical Engineering Dept Mail: broehl@watdcsu.waterloo{.edu,.csnet,.cdn} BangPath: {allegra,decvax,utzoo,clyde}!watmath!watdcsu!broehl Voice: (519) 745-4419 [home] (519) 885-1211 x 2607 [work]