home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_06_06 / v6n6082a.txt < prev    next >
Text File  |  1989-09-28  |  7KB  |  289 lines

  1.  \NLETTER\6.6\HERCULE.COD 
  2. /* This is a do-nothing program. It draws a lot of circles and it writes
  3. a short line of text, to demonstrate how to operate Hercules monochrome
  4. bit-mapped graphics, including text in graphics mode. */
  5.  
  6. #include <stdio.h>
  7.  
  8. void revdot(), writedot(), t_mode(), sleep(), cleardot(), 
  9.      g_mode(), clearscreen(), g_write(), g_putch(), sw_scr() ;
  10. int  inkey();
  11. long sqroot();
  12.  
  13. #define INDEXPORT 0x3B4
  14. #define CONTROLPORT 0x3b8
  15. #define DATAPORT 0x3b5
  16. #define CONFIGPORT 0x3bf
  17. #define SCR0 0xb0000 /* Absolute address for page 0. */
  18. #define SCR1 0xb8000 /* Absolute address for page 1. */
  19. #define ROMFONT 0xffa6e /* Absolute address of IBM ROM character set. */
  20. #define GC_WIDTH 10 /* Width in pixels of character plus spacing. 
  21.            It  can  be as small as 8 or as  large  as  you like.*/
  22.  
  23. char *font; /* Pointer to character font in ROM. */
  24.  
  25. #define XSTART 270  /* These set the size of the circle, and its */
  26. #define YSTART 165  /* aspect ratio.                             */
  27.  
  28. int gdata[12] = { 
  29.      0x35, 0x2d, 0x2e, 0x7, 0x5b, 0x2, 0x57, 0x57, 0x2, 0x3, 0x0, 0x0 
  30. };
  31. int tdata[12] = { 
  32.      0x61, 0x50, 0x52, 0xf, 0x19, 0x6, 0x19, 0x19, 0x2, 0xd, 0xb, 0xc 
  33. };
  34.  
  35. int main()
  36. {
  37.      long x,y,xs,ys;
  38.      int h1,h2,v;
  39.      long xaxis,yaxis;
  40.      char *abstoptr(); /* Converts absolute address to far pointer. */
  41.      char *screen0addr; /* Compiler-dependent far pointer. */
  42.      
  43.      xaxis= XSTART;
  44.      yaxis= YSTART;
  45.      
  46.      screen0addr=abstoptr(SCR0);
  47.      font=abstoptr(ROMFONT);
  48.      
  49.      clearscreen(screen0addr);
  50.      g_mode();
  51.      g_write("Circles - KITTENSOFT",330,470,screen0addr);
  52.      for(;;){
  53.           if (inkey()) break;
  54.           xs=xaxis*xaxis;
  55.           ys=yaxis*yaxis;
  56.           for(y=(-1*yaxis);y<=(yaxis);y+=1){
  57.                x=y;
  58.                x=( xs - x*x*xs/ys );
  59.                if (x<0) continue;
  60.                x=sqroot(x);
  61.                v=(int)y+174;
  62.                h1=(int)x+300;
  63.                h2=(int)(-1*x)+300;
  64.                revdot(v,h1,screen0addr);
  65.                revdot(v,h2,screen0addr);
  66.           }
  67.           if (xaxis<=8) xaxis--;
  68.           else xaxis-=xaxis/8;
  69.           if (yaxis<=8) yaxis--;
  70.           else yaxis-=yaxis/8;
  71.           xs=xaxis*xaxis;
  72.           ys=yaxis*yaxis;
  73.           for(x=(-1*xaxis);x<=(xaxis);x+=1){
  74.                y=x;
  75.                y=( ys - y*y*ys/xs );
  76.                if (y<0) continue;
  77.                y=sqroot(y);
  78.                v=(int)x+300;
  79.                h1=(int)y+174;
  80.                h2=(int)(-1*y)+174;
  81.                revdot(h1,v,screen0addr);
  82.                revdot(h2,v,screen0addr);
  83.           }
  84.           if (xaxis<=8) xaxis--;
  85.           else xaxis-=xaxis/8;
  86.           if (yaxis<=8) yaxis--;
  87.           else yaxis-=yaxis/8;
  88.           if ((xaxis<1)||(yaxis<1)){
  89.                xaxis=XSTART;
  90.                yaxis=YSTART;
  91.           }
  92.      }
  93.      clearscreen(screen0addr);
  94.      t_mode();
  95. }
  96. void g_mode()
  97. {
  98.      int i;
  99.      
  100.      outportb(CONFIGPORT,3);
  101.      outportb(CONTROLPORT,0);
  102.      for(i=0;i<12;i++){
  103.           outportb(INDEXPORT,i);
  104.           outportb(DATAPORT,gdata[i]);
  105.      }
  106.      outportb(CONTROLPORT,2);
  107.      sleep();
  108.      outportb(CONTROLPORT,10);
  109. }
  110. void clearscreen(seg)
  111. char *seg;
  112. {
  113.      unsigned off;
  114.      
  115.      for (off=0;off<32768;off++) seg[off]=0;
  116. }
  117. void t_mode()
  118. {
  119.      int i;
  120.      
  121.      outportb(CONTROLPORT,0);
  122.      for(i=0;i<12;i++){
  123.           outportb(INDEXPORT,i);
  124.           outportb(DATAPORT,tdata[i]);
  125.      }
  126.      outportb(CONTROLPORT,53);
  127.      sleep();
  128.      outportb(CONTROLPORT,61);
  129.      outportb(CONFIGPORT,0);
  130. }
  131.  
  132. /* 
  133. The following functions write, clear, and reverse individual 
  134. pixels. seg is the location of the beginning of screen memory. off
  135. is the offset within memory. These functions operate in large model,
  136. where it is possible to write directly to any address in memory.
  137. If your compiler does not support large model, you can get the same
  138. results with the peek() and poke() functions.
  139. This program uses only page 0. You can use page 1 by passing its 
  140. address to these functions.
  141.  */
  142.  
  143. void writedot(y,x,seg)
  144. int x,y;
  145. char *seg;
  146. {
  147.      unsigned off;
  148.      unsigned char c,bit;
  149.      
  150. /* Calculate offset of byte within screen memory: */
  151.      off=(unsigned)( 0x2000 * (y%4) + 90*(y/4) + x/8 );
  152.  
  153. /* Get byte presently at that location: */
  154.      c=seg[off];
  155.  
  156. /* or, for compilers without far pointers:
  157.      c=peekb(off,seg); */
  158.  
  159. /* Calculate which bit within the byte to set: */     
  160.      bit = 1<< (7-x%8);
  161.  
  162. /* Set the bit: */
  163.      c |= bit;
  164.  
  165. /* Write the altered byte back into memory */
  166.      seg[off]=c;
  167.  
  168. /* or, for compilers without far pointers:
  169.      pokeb(off,seg,c); */
  170. }
  171. void cleardot(y,x,seg)
  172. int x,y;
  173. char *seg;
  174. {
  175.      unsigned off;
  176.      unsigned char c,bit;
  177.      
  178.      off=(unsigned)( 0x2000 * (y%4) + 90*(y/4) + x/8 );
  179.      c=seg[off];
  180.      
  181.      bit = 1<< (7-x%8);
  182.      c &= ((unsigned char)0xff ^ bit);
  183.      
  184.      seg[off]=c;
  185. }
  186. void revdot(y,x,seg)
  187. int x,y;
  188. char *seg;
  189. {
  190.      unsigned off;
  191.      unsigned char c,bit;
  192.      
  193.      off=(unsigned)( 0x2000 * (y%4) + 90*(y/4) + x/8 );
  194.      c=seg[off];
  195.      
  196.      bit = 1<< (7-x%8);
  197.      c ^= bit;
  198.      
  199.      seg[off]=c;
  200. }
  201. /* inkey will vary from one compiler to the next */
  202. int inkey()
  203. {
  204.      int k;
  205.      
  206.      k=bdos(0x600,0xff,0);
  207.      return(k);
  208. }
  209. long sqroot(n)
  210. long n;
  211. {
  212.      long r1,r2;
  213.      r1=n;
  214.      r2=1;
  215.  
  216.      while (r1>r2){
  217.           r1=(r1+r2)/2;
  218.           r2=n/r1;
  219.      }
  220.      return(r1);
  221. }
  222.  
  223. /* This provides a one-second pause. However, it is 
  224. compiler-dependent as clock() does different things under
  225. different compilers. */
  226.  
  227. void sleep()
  228. {
  229.      long a,clock();
  230.      
  231.      a=clock();
  232.      while ( clock()-a < 100 )
  233.           ;
  234. }
  235.  
  236. /* v can be from 0 to 347 and h can be from 0 to 719.
  237. This simple function breaks off if a line of text reaches
  238. the right hand side of the screen. You can write a more
  239. intelligent function that will wrap around, or even remember
  240. a "cursor position" from one call to the next. */
  241.  
  242. void g_write(s,v,h,seg)
  243. char *s,*seg;
  244. int v,h;
  245. {
  246.      
  247.      while (*s) {
  248.           if (h>712) break;
  249.           g_putch(*s++,v,h,seg);
  250.           h+= GC_WIDTH;
  251.      }
  252. }
  253.  
  254. /*
  255. As with the bit-mapping functions, the following uses large model
  256. for easier access to the ROM character set. peek() will work
  257. just as well.
  258.  */
  259.  
  260. void g_putch(c,y,x,seg)
  261. int c,y,x;
  262. char *seg;
  263. {
  264.      int i,j;
  265.      unsigned char scan_line,mask;
  266.      
  267.      for (i=0;i<8;i++){
  268.           scan_line=font[c*8+i];
  269.           for (mask=128,j=0;j<8;j++,mask>>=1){
  270.                if (scan_line & mask) writedot(y+i,x+j,seg);
  271.                else cleardot(y+i,x+j,seg);  
  272.           }
  273.           for (j=8;j<GC_WIDTH;j++) 
  274.                cleardot(y+i,x+j,seg);
  275.      }
  276. }
  277.  
  278. /* This is not used in this program. It is included for 
  279. reference only. If called, it would toggle the display back
  280. and forth between screen 0 and screen 1. */
  281.  
  282. void sw_scr()
  283. {
  284.      static int scr=0;
  285.      
  286.      scr^=128;
  287.      outportb(CONTROLPORT, 10 | scr);
  288. }
  289.