home *** CD-ROM | disk | FTP | other *** search
-
- /* This is a do-nothing program. It draws a lot of circles and it writes
- a short line of text, to demonstrate how to operate Hercules monochrome
- bit-mapped graphics, including text in graphics mode. */
-
- #include <stdio.h>
-
- void revdot(), writedot(), t_mode(), sleep(), cleardot(),
- g_mode(), clearscreen(), g_write(), g_putch(), sw_scr() ;
- int inkey();
- long sqroot();
-
- #define INDEXPORT 0x3B4
- #define CONTROLPORT 0x3b8
- #define DATAPORT 0x3b5
- #define CONFIGPORT 0x3bf
- #define SCR0 0xb0000 /* Absolute address for page 0. */
- #define SCR1 0xb8000 /* Absolute address for page 1. */
- #define ROMFONT 0xffa6e /* Absolute address of IBM ROM character set. */
- #define GC_WIDTH 10 /* Width in pixels of character plus spacing.
- It can be as small as 8 or as large as you like.*/
-
- char *font; /* Pointer to character font in ROM. */
-
- #define XSTART 270 /* These set the size of the circle, and its */
- #define YSTART 165 /* aspect ratio. */
-
- int gdata[12] = {
- 0x35, 0x2d, 0x2e, 0x7, 0x5b, 0x2, 0x57, 0x57, 0x2, 0x3, 0x0, 0x0
- };
- int tdata[12] = {
- 0x61, 0x50, 0x52, 0xf, 0x19, 0x6, 0x19, 0x19, 0x2, 0xd, 0xb, 0xc
- };
-
- int main()
- {
- long x,y,xs,ys;
- int h1,h2,v;
- long xaxis,yaxis;
- char *abstoptr(); /* Converts absolute address to far pointer. */
- char *screen0addr; /* Compiler-dependent far pointer. */
-
- xaxis= XSTART;
- yaxis= YSTART;
-
- screen0addr=abstoptr(SCR0);
- font=abstoptr(ROMFONT);
-
- clearscreen(screen0addr);
- g_mode();
- g_write("Circles - KITTENSOFT",330,470,screen0addr);
- for(;;){
- if (inkey()) break;
- xs=xaxis*xaxis;
- ys=yaxis*yaxis;
- for(y=(-1*yaxis);y<=(yaxis);y+=1){
- x=y;
- x=( xs - x*x*xs/ys );
- if (x<0) continue;
- x=sqroot(x);
- v=(int)y+174;
- h1=(int)x+300;
- h2=(int)(-1*x)+300;
- revdot(v,h1,screen0addr);
- revdot(v,h2,screen0addr);
- }
- if (xaxis<=8) xaxis--;
- else xaxis-=xaxis/8;
- if (yaxis<=8) yaxis--;
- else yaxis-=yaxis/8;
- xs=xaxis*xaxis;
- ys=yaxis*yaxis;
- for(x=(-1*xaxis);x<=(xaxis);x+=1){
- y=x;
- y=( ys - y*y*ys/xs );
- if (y<0) continue;
- y=sqroot(y);
- v=(int)x+300;
- h1=(int)y+174;
- h2=(int)(-1*y)+174;
- revdot(h1,v,screen0addr);
- revdot(h2,v,screen0addr);
- }
- if (xaxis<=8) xaxis--;
- else xaxis-=xaxis/8;
- if (yaxis<=8) yaxis--;
- else yaxis-=yaxis/8;
- if ((xaxis<1)||(yaxis<1)){
- xaxis=XSTART;
- yaxis=YSTART;
- }
- }
- clearscreen(screen0addr);
- t_mode();
- }
- void g_mode()
- {
- int i;
-
- outportb(CONFIGPORT,3);
- outportb(CONTROLPORT,0);
- for(i=0;i<12;i++){
- outportb(INDEXPORT,i);
- outportb(DATAPORT,gdata[i]);
- }
- outportb(CONTROLPORT,2);
- sleep();
- outportb(CONTROLPORT,10);
- }
- void clearscreen(seg)
- char *seg;
- {
- unsigned off;
-
- for (off=0;off<32768;off++) seg[off]=0;
- }
- void t_mode()
- {
- int i;
-
- outportb(CONTROLPORT,0);
- for(i=0;i<12;i++){
- outportb(INDEXPORT,i);
- outportb(DATAPORT,tdata[i]);
- }
- outportb(CONTROLPORT,53);
- sleep();
- outportb(CONTROLPORT,61);
- outportb(CONFIGPORT,0);
- }
-
- /*
- The following functions write, clear, and reverse individual
- pixels. seg is the location of the beginning of screen memory. off
- is the offset within memory. These functions operate in large model,
- where it is possible to write directly to any address in memory.
- If your compiler does not support large model, you can get the same
- results with the peek() and poke() functions.
- This program uses only page 0. You can use page 1 by passing its
- address to these functions.
- */
-
- void writedot(y,x,seg)
- int x,y;
- char *seg;
- {
- unsigned off;
- unsigned char c,bit;
-
- /* Calculate offset of byte within screen memory: */
- off=(unsigned)( 0x2000 * (y%4) + 90*(y/4) + x/8 );
-
- /* Get byte presently at that location: */
- c=seg[off];
-
- /* or, for compilers without far pointers:
- c=peekb(off,seg); */
-
- /* Calculate which bit within the byte to set: */
- bit = 1<< (7-x%8);
-
- /* Set the bit: */
- c |= bit;
-
- /* Write the altered byte back into memory */
- seg[off]=c;
-
- /* or, for compilers without far pointers:
- pokeb(off,seg,c); */
- }
- void cleardot(y,x,seg)
- int x,y;
- char *seg;
- {
- unsigned off;
- unsigned char c,bit;
-
- off=(unsigned)( 0x2000 * (y%4) + 90*(y/4) + x/8 );
- c=seg[off];
-
- bit = 1<< (7-x%8);
- c &= ((unsigned char)0xff ^ bit);
-
- seg[off]=c;
- }
- void revdot(y,x,seg)
- int x,y;
- char *seg;
- {
- unsigned off;
- unsigned char c,bit;
-
- off=(unsigned)( 0x2000 * (y%4) + 90*(y/4) + x/8 );
- c=seg[off];
-
- bit = 1<< (7-x%8);
- c ^= bit;
-
- seg[off]=c;
- }
- /* inkey will vary from one compiler to the next */
- int inkey()
- {
- int k;
-
- k=bdos(0x600,0xff,0);
- return(k);
- }
- long sqroot(n)
- long n;
- {
- long r1,r2;
- r1=n;
- r2=1;
-
- while (r1>r2){
- r1=(r1+r2)/2;
- r2=n/r1;
- }
- return(r1);
- }
-
- /* This provides a one-second pause. However, it is
- compiler-dependent as clock() does different things under
- different compilers. */
-
- void sleep()
- {
- long a,clock();
-
- a=clock();
- while ( clock()-a < 100 )
- ;
- }
-
- /* v can be from 0 to 347 and h can be from 0 to 719.
- This simple function breaks off if a line of text reaches
- the right hand side of the screen. You can write a more
- intelligent function that will wrap around, or even remember
- a "cursor position" from one call to the next. */
-
- void g_write(s,v,h,seg)
- char *s,*seg;
- int v,h;
- {
-
- while (*s) {
- if (h>712) break;
- g_putch(*s++,v,h,seg);
- h+= GC_WIDTH;
- }
- }
-
- /*
- As with the bit-mapping functions, the following uses large model
- for easier access to the ROM character set. peek() will work
- just as well.
- */
-
- void g_putch(c,y,x,seg)
- int c,y,x;
- char *seg;
- {
- int i,j;
- unsigned char scan_line,mask;
-
- for (i=0;i<8;i++){
- scan_line=font[c*8+i];
- for (mask=128,j=0;j<8;j++,mask>>=1){
- if (scan_line & mask) writedot(y+i,x+j,seg);
- else cleardot(y+i,x+j,seg);
- }
- for (j=8;j<GC_WIDTH;j++)
- cleardot(y+i,x+j,seg);
- }
- }
-
- /* This is not used in this program. It is included for
- reference only. If called, it would toggle the display back
- and forth between screen 0 and screen 1. */
-
- void sw_scr()
- {
- static int scr=0;
-
- scr^=128;
- outportb(CONTROLPORT, 10 | scr);
- }