lesmem@cs.vu.nl (Marco Lesmeister) (08/25/87)
Could anyone tell me what the fastest way is to control the screen in, for instance games and simulators? I want to move a C64-sprite like figure as fast as possible across the screen in CGA-mode. I think I need a device driver for this, but maybe there is another fast way to control the screen in C, since that is the language in which I'm writing this program. If someone knows the answer to this question, please write it to the net because I guess there are other people as well, who would like to know how to control the graphics screen as fast as possible. P.S. A fast line-drawing routine is welcome also. Thanks in advance Marco Lesmeister, VU (Free University), Holland. --------------------------------------------------------------------------
perkins@bnrmtv.UUCP (Henry Perkins) (08/26/87)
In article <1096@ark.cs.vu.nl>, lesmem@cs.vu.nl (Marco Lesmeister) writes: > Could anyone tell me what the fastest way is to control the screen in, for > instance games and simulators? I want to move a C64-sprite like figure > as fast as possible across the screen in CGA-mode. If you want to modify a CGA screen, the fastest way to do it is with direct writes to CGA memory, located in B800:0000 to B800:1F40 (even scan lines) and B800:2000 to B800:2F40 (odd scan lines). A device driver would be s l o w . You're trying to do something that IBM really didn't provide for. There is no hardware support for sprites or anything resembling them; you'll have to save the original screen contents so you can restore things when the "sprite" moves, and you'll need to do your own collision calculations. You can't even do color table animation, because the color palettes are fixed with two non-intersecting sets of 3 colors each. Since each byte of memory represents 4 pixels, you'll need to OR and AND with pixel masks for horizontal movement. Vertical movement is harder, because you need to add or subtract your screen memory offset depending on whether you're in an even or odd row. Good luck; you'll need it, plus lots of patience. (I did the animation for Championship Golf, published by Activision's GameStar division.) -- {hplabs,amdahl,ames}!bnrmtv!perkins --Henry Perkins It is better never to have been born. But who among us has such luck? One in a million, perhaps.
lesmem@ark.UUCP (08/27/87)
In article 5194 Henry Perkins writes :
Direct writes to CGA memory are fastest.
I tried to figure this out, but couldn't succeed. My
question is this :
Can somebody post a fast line drawing algorithm that
uses direct memory writes to CGA memory.
Thanks in advance, Marco Lesmeister.
ssnyder@tybalt.caltech.edu (Scott S. Snyder) (08/27/87)
In article <1099@ark.cs.vu.nl> lesmem@cs.vu.nl (Marco Lesmeister) writes: > Can somebody post a fast line drawing algorithm that >uses direct memory writes to CGA memory. I have just sent a simple PC graphics library to comp.sources.misc. I hope that it will answer your question.
psfales@ihlpe.ATT.COM (Pete Fales) (08/28/87)
In article <1099@ark.cs.vu.nl>, lesmem@cs.vu.nl (Marco Lesmeister) writes: > > Can somebody post a fast line drawing algorithm that > uses direct memory writes to CGA memory. > > Thanks in advance, Marco Lesmeister. I won't make any claims about how fast this algorithm is relative to other potential candidates, but it is pretty good. I didn't write it (it was published in the IBM Journal of Research and Development), but I have had several occasions to use it over the years, including some assembly language implementations. It uses only integer arithmetic and multiplications only by powers of 2. ---------------------------- cut here ------------------------------ int xm1[] = { 1, 0, 1, 0,-1, 0,-1, 0 }; int ym1[] = { 0, 1, 0,-1, 0, 1, 0,-1 }; int xm2[] = { 1, 1, 1, 1,-1,-1,-1,-1 }; int ym2[] = { 1, 1,-1,-1, 1, 1,-1,-1 }; /* Bresenham (spelling?) algorithm to draw a line from (x1,y1) to (x2,y2) */ void absline(x1,y1,x2,y2,col) { int m,deltax,deltay,e,cx,savedx,t; m=0; deltax=x2-x1; if ( deltax<0 ) { m=4; deltax = -deltax; } deltay=y2-y1; if (deltay<0 ) { m += 2; deltay = -deltay; } if ( deltax - deltay < 0 ) { m++; t=deltax; deltax=deltay; deltay=t; } deltay *= 2; /* OK, use a shift if you really want speed */ e = deltay-deltax; savedx = deltax; deltax *= 2; for ( cx=savedx+1 ; cx >= 1 ; cx-- ) { scr_wdot(x1,y1,col); if ( e > 0 ) { x1 += xm2[m]; y1 += ym2[m]; e += deltay-deltax; } else { x1 += xm1[m]; y1 += ym1[m]; e += deltay; } } } -- Peter Fales UUCP: ...ihnp4!ihlpe!psfales work: (312) 979-7784 AT&T Information Systems, IW 1Z-243 1100 E. Warrenville Rd., IL 60566
jru@etn-rad.UUCP (John Unekis) (08/29/87)
In article <1099@ark.cs.vu.nl> lesmem@cs.vu.nl (Marco Lesmeister) writes: >... > Can somebody post a fast line drawing algorithm that >uses direct memory writes to CGA memory. I am posting some source code here which I yanked out of my blastcga game. Since no one wanted to buy the source, I figured I would just post it for free. This is not the complete game(sorry , I wrote the game stream-of- consciousness style, and there are no comments in the code, as soon as I find time to put some in I'll post it). Included here are the graphics routines for CGA/EGA boards in mono mode. Some notes: )you MUST compile with the large model (msc /AL) )before you call the vector routines you MUST call graphmode or dismode(6) to put the board into mono graphics mode (only once) )before you call the vector routines you MUST call setxdotyadd() to init the array of screen address offsets (only once) )before you call the rotate routine you MUST call init_cos() to init the sin and cosine arrays (only once) )you should link with a large stack segment (i.e. link /stack:30000 ) This is not a shell archive(sorry , ours is broke) you must pull it apart with vi. Happy hunting. mail questions to {voder | ihnp4}!wlbr!etn-rad!jru figures.h ####################### cut here ########################### /* This is the include file that drives the blastcga game, it includes parameters for the number of monsters and such, as well as screen limits and stuff. It contains structures which allow an object to be stored either as a series of x,y points or as a series of angle and radius polar coordinates */ struct object { int x_vel; int y_vel; int x_pos; int y_pos; int num_vertices; int x[50]; int y[50]; int alive; int state; int angle; }; struct polar_object { int angle[50]; int radius[50]; }; struct object monsters[10]; struct object ship; struct polar_object polar_ship; struct polar_object polar_bent; struct object specials[5]; struct polar_object polar_specials[5]; int monster_moves; int special_moves; int num_monsters; int num_specials; int num_loops; int num_ships; int energy; int delay; struct missile { int x_pos; int y_pos; int x_vel; int y_vel; int running; int state; }; struct missile missiles[20]; int num_missiles; int next_missile; int bounce; int magnet; int sound; int max_missile; int kill_monst; int kill_special; int olden; int gen_monster; int gen_special; #define MAX_MISSILE 20 #define MAX_MONSTER 10 #define MAX_SPECIAL 5 #define MAX_SHIPS 3 #define X_LIMIT1 40 #define X_LIMIT2 600 #define Y_LIMIT1 15 #define Y_LIMIT2 185 #define MON_X_COL 13 #define MON_Y_COL 5 #define SPC_X_COL 12 #define SPC_Y_COL 5 #define ALIVE 999 #define NEW 777 #define BENT 555 #define MONSTER_GEN 50 #define SPECIAL_GEN 100 xorobj.c ####################### cut here ########################### #include "figures.h" /* routine to exclusive or the lines of a figure with screen memory John Unekis 1/18/87 */ xorobj(p) struct object *p; { register int i,j,k; i = (*p).num_vertices - 1; for(j=0;j<i;j++) { /* negative x value means "pen up" */ if ( ((*p).x[j] > 0) && ((*p).x[j+1] > 0)) shortvec((*p).x[j],(*p).y[j],(*p).x[j+1],(*p).y[j+1]); } } shortvec.c ####################### cut here ########################### int yadd[200]; char xdot[8]; struct scrnmem { char scrn[16636]; } ; /* The screen memory when the CGA is in mono mode is organized as one bit per pixel, 80 bytes per line gives 640 pixels per line. The scan lines are taken alternately from two banks of 8K memory each. One block of 8K for even lines, one for odd lines . The screen memory begins at B800:0000 */ struct scrnmem * scrptr; /* this routine puts the physical address offset from the beginning of screen memory for each screen line (in mono mode CGA) into an array indexed by line number. The physical address of a pixel is BASE OF SCREEN MEMORY + yadd[line number] + X ADDRESS /8, and the pixel to set within the byte at that address is X ADDRESS mod 8 */ setxdotyadd() { int i,j,k; char a,b,c; /* start of screen memory */ scrptr = (struct scrnmem *) 0xb8000000; /* offset to each y-line */ for(i=0;i<200;i++) { j = i & 1; j = j * 0x2000; k = i >> 1; k = k * 80; yadd[i] = j + k; } /* for each bit pixel within a byte, create a byte with just that pixel on, to be xor'ed with byte on screen */ for(i=0;i<8;i++) { xdot[i] = 0x01 << (7 - i); } } /* Xor the screen memory with a dot at x,y (upper left is 0,0) */ xordot(x,y) int x,y; { int offst; offst = yadd[y]; offst += x >> 3; scrptr->scrn[offst] ^= xdot[x & 7]; } /* This routine will draw a vector up to 128 pixels long from x1,y1 to x2,y2 on the cga screen in mono mode. It uses a fixed point binary representation for the x and y offsets, where 8 bits is whole number and eight bits is fraction. The algorithm assumes that for any given line either dx/dy is fractional, or dy/dx is fractional. the routine figures out which is which, then if dy/dx is fractional we move x by one each time, and y by dy/dx, otherwise if dx/dy is fractional we move y by one each time, and x by dx/dy. The dot on the screen is xor'ed at the whole number portion of x,y . */ shortvec(x1,y1,x2,y2) int x1,y1,x2,y2; { int dx,dy,deltx,delty,i,j,k; /* the line always moves in the positive direction */ if(x1 > x2) dx = x1 - x2; else dx = x2 - x1; if(y1 > y2) dy = y1 - y2; else dy = y2 - y1; if(dx > dy) { delty = dy << 8; delty = delty / dx; if(y2 > y1) { if(x2 > x1) yfrac(x1,x2,1,y1,delty); else yfrac(x1,x2,-1,y1,delty); } else { if(x1 > x2) yfrac(x2,x1,1,y2,delty); else yfrac(x2,x1,-1,y2,delty); } } else { deltx = dx << 8; if(dy > 0) deltx = deltx / dy; else deltx = 0x0100; if(x2 > x1) { if(y2 > y1) xfrac(x1,deltx,y1,y2,1); else xfrac(x1,deltx,y1,y2,-1); } else { if(y1 > y2) xfrac(x2,deltx,y2,y1,1); else xfrac(x2,deltx,y2,y1,-1); } } } xfrac.c ####################### cut here ########################### int yadd[200]; char xdot[8]; struct scrnmem { char scrn[16636]; }; struct scrnmem * scrptr; /* draw a vector on the cga screen in monochrome mode, assuming that y moves by one each time , and x by fractional dx/dy */ xfrac(xstart,xdelt,ystart,yend,ydelt) int xstart,xdelt,ystart,yend,ydelt; { register int loop,yoff,xrun,xpos; loop = ystart; xrun = 0; while(loop != yend) { xpos = xstart + (xrun >> 8); yoff = yadd[loop]; yoff += xpos >> 3; scrptr->scrn[yoff] ^= xdot[xpos & 7]; loop += ydelt; xrun += xdelt; } } yfrac.c ####################### cut here ########################### int yadd[200]; char xdot[8]; struct scrnmem { char scrn[16636]; }; struct scrnmem * scrptr; /* draw a vector in cga mono assuming that x moves by one each time, and y moves by fractional dy/dx */ yfrac(xstart,xend,xdelt,ystart,ydelt) int xstart,xend,xdelt,ystart,ydelt; { register int loop,yoff,yrun; loop = xstart; yrun = 0; while(loop != xend) { yoff = yadd[ystart+(yrun >> 8)]; yoff += loop >> 3; scrptr->scrn[yoff] ^= xdot[loop & 7]; loop += xdelt; yrun += ydelt; } } laser.c ####################### cut here ########################### #include "figures.h" /* Routine to fire ships laser John Unekis 1/18/87 */ /* this is a long vector drawing routine from the blastcga game, it is used to draw the laser beam. If you ignore the code that checks for hits on the monsters, it shows how to draw a long fast vector , assuming that either dx/dy or dy/dx is fractional. This routine differs from the short vector routines in that it uses 32 bits for dx/dy and dy/dx, with 16 bits fractional and 16 bits whole number. This allows it to draw a line across the whole screen, but it is just a bit slower. */ laser() { int x_start,y_start,x,y,i,j,k,l,m,n; int ptx[1000],pty[1000],pts,hit,incs; int notes; union lll{ int ii[2]; long ll; } il; union lll xrun; union lll yrun; union lll xdelt; union lll ydelt; yrun.ll = 0; xrun.ll = 0; hit = 0; incs = 0; pts = 0; x_start = ship.x_pos; y_start = ship.y_pos; m = ship.angle; i = sin(m); j = cos(m); ydelt.ii[1] = i ; xdelt.ii[1] = j ; if(i > 0) k = i; else k = -i; if(j > 0) l = j; else l = - j; il.ll = 0; if(k > l) il.ii[0] = k; else il.ii[0] = l; xdelt.ll = xdelt.ll / il.ll; ydelt.ll = ydelt.ll / il.ll; yrun.ii[1] = y_start; xrun.ii[1] = x_start; notes = 0; if(sound != 0) high_note('G'); /* we check for hits on objects as we draw the vector */ while (hit == 0) { x = xrun.ii[1]; y = yrun.ii[1]; xordot(x,y); /* draw the point and save the x,y pair for later erasure */ ptx[pts] = x; pty[pts] = y; pts += 1; incs += 1; if(incs >= 8) { incs = 0; if(((x > X_LIMIT2) || (x < X_LIMIT1)) || ((y > Y_LIMIT2) || (y < Y_LIMIT1))) hit = 999; for(i=0;i<MAX_MONSTER;i++) { if(monsters[i].alive == ALIVE) { j = x - monsters[i].x_pos; if(j < 0) j = -j; k = y - monsters[i].y_pos; if(k < 0) k = -k; if((j < MON_X_COL) && (k < MON_Y_COL)) { if(sound != 0) high_note('E'); hit = 999; kill_monst += 1; boom(monsters[i].x_pos,monsters[i].y_pos); xorobj(&monsters[i].x_vel); monsters[i].alive = 0; if(sound != 0) note_off(); } } } for(i=0;i<MAX_SPECIAL;i++) { if(specials[i].alive == ALIVE) { j = x - specials[i].x_pos; if(j < 0) j = -j; k = y - specials[i].y_pos; if(k < 0) k = -k; if((j < SPC_X_COL) && (k < SPC_Y_COL)) { if(sound != 0) high_note('B'); hit = 999; kill_special += 1; boom(specials[i].x_pos,specials[i].y_pos); xorobj(&specials[i].x_vel); specials[i].alive = 0; if(sound != 0) note_off(); } } } } xrun.ll += xdelt.ll; yrun.ll += ydelt.ll; } if(sound != 0) note_off(); /* go back and erase the line by doing a second xor on the points */ for(i=0;i<pts;i++) xordot(ptx[i],pty[i]); } rotobj.c ####################### cut here ########################### #include "figures.h" /* routine to rotate a vector object John Unekis 1/18/87*/ /* This routine requires that an object be represented as both a set of cartesian vectors and as a set of polar (angle and radius vectors). In constructing a cartesian figure from the polar representation, remember two things- The screen has its origin in the upper left corner with increasing y values going down, so that angles are flipped, also , the screen has an aspect ratio which makes each y increment equal to approx. twice the distance of an x increment, so y offsets must be scaled accordingly */ /* No radius of a vector should be > 32 or this algorithm may overflow in the trig functions. To avoid this, one might divide the trig values by 10 before using */ rotobj(p,q,ang) struct object *p; struct polar_object *q; int ang; { register int k,l; int i,j,m,n; int y_off,x_off; (*p).angle += ang; if( (*p).angle < 0 ) (*p).angle += 360; (*p).angle = (*p).angle % 360; n = (*p).num_vertices; for(i=0;i<n;i++) { j = (*q).angle[i] + (*p).angle; k = sin(j); /* trig values scaled by 1000*/ l = cos(j); k = k * (*q).radius[i]; l = l * (*q).radius[i]; (*p).x[i] = (l / 1000) + (*p).x_pos; k = k / 10; k = k * 2; /* scale the y offset, avoiding overflow*/ k = k + 150; k = k / 400; (*p).y[i] = k + (*p).y_pos; } } init_cos.c ####################### cut here ########################### int icos[360]; int isin[360]; /* in the interest of speed, the blastcga game stores the cosin and sin values precalculated in integer arrays. The array is indexed by integer degrees, and the return value is sin or cos , scaled by 1000 */ init_cos() { isin[ 0] = 0 ; icos[ 0] = 1000 ; isin[ 1] = 17 ; icos[ 1] = 999 ; isin[ 2] = 34 ; icos[ 2] = 999 ; isin[ 3] = 52 ; icos[ 3] = 998 ; isin[ 4] = 69 ; icos[ 4] = 997 ; isin[ 5] = 87 ; icos[ 5] = 996 ; isin[ 6] = 104 ; icos[ 6] = 994 ; isin[ 7] = 121 ; icos[ 7] = 992 ; isin[ 8] = 139 ; icos[ 8] = 990 ; isin[ 9] = 156 ; icos[ 9] = 987 ; isin[ 10] = 173 ; icos[ 10] = 984 ; isin[ 11] = 190 ; icos[ 11] = 981 ; isin[ 12] = 207 ; icos[ 12] = 978 ; isin[ 13] = 224 ; icos[ 13] = 974 ; isin[ 14] = 241 ; icos[ 14] = 970 ; isin[ 15] = 258 ; icos[ 15] = 965 ; isin[ 16] = 275 ; icos[ 16] = 961 ; isin[ 17] = 292 ; icos[ 17] = 956 ; isin[ 18] = 309 ; icos[ 18] = 951 ; isin[ 19] = 325 ; icos[ 19] = 945 ; isin[ 20] = 342 ; icos[ 20] = 939 ; isin[ 21] = 358 ; icos[ 21] = 933 ; isin[ 22] = 374 ; icos[ 22] = 927 ; isin[ 23] = 390 ; icos[ 23] = 920 ; isin[ 24] = 406 ; icos[ 24] = 913 ; isin[ 25] = 422 ; icos[ 25] = 906 ; isin[ 26] = 438 ; icos[ 26] = 898 ; isin[ 27] = 453 ; icos[ 27] = 891 ; isin[ 28] = 469 ; icos[ 28] = 882 ; isin[ 29] = 484 ; icos[ 29] = 874 ; isin[ 30] = 499 ; icos[ 30] = 866 ; isin[ 31] = 515 ; icos[ 31] = 857 ; isin[ 32] = 529 ; icos[ 32] = 848 ; isin[ 33] = 544 ; icos[ 33] = 838 ; isin[ 34] = 559 ; icos[ 34] = 829 ; isin[ 35] = 573 ; icos[ 35] = 819 ; isin[ 36] = 587 ; icos[ 36] = 809 ; isin[ 37] = 601 ; icos[ 37] = 798 ; isin[ 38] = 615 ; icos[ 38] = 788 ; isin[ 39] = 629 ; icos[ 39] = 777 ; isin[ 40] = 642 ; icos[ 40] = 766 ; isin[ 41] = 656 ; icos[ 41] = 754 ; isin[ 42] = 669 ; icos[ 42] = 743 ; isin[ 43] = 681 ; icos[ 43] = 731 ; isin[ 44] = 694 ; icos[ 44] = 719 ; isin[ 45] = 707 ; icos[ 45] = 707 ; isin[ 46] = 719 ; icos[ 46] = 694 ; isin[ 47] = 731 ; icos[ 47] = 681 ; isin[ 48] = 743 ; icos[ 48] = 669 ; isin[ 49] = 754 ; icos[ 49] = 656 ; isin[ 50] = 766 ; icos[ 50] = 642 ; isin[ 51] = 777 ; icos[ 51] = 629 ; isin[ 52] = 788 ; icos[ 52] = 615 ; isin[ 53] = 798 ; icos[ 53] = 601 ; isin[ 54] = 809 ; icos[ 54] = 587 ; isin[ 55] = 819 ; icos[ 55] = 573 ; isin[ 56] = 829 ; icos[ 56] = 559 ; isin[ 57] = 838 ; icos[ 57] = 544 ; isin[ 58] = 848 ; icos[ 58] = 529 ; isin[ 59] = 857 ; icos[ 59] = 515 ; isin[ 60] = 866 ; icos[ 60] = 500 ; isin[ 61] = 874 ; icos[ 61] = 484 ; isin[ 62] = 882 ; icos[ 62] = 469 ; isin[ 63] = 891 ; icos[ 63] = 453 ; isin[ 64] = 898 ; icos[ 64] = 438 ; isin[ 65] = 906 ; icos[ 65] = 422 ; isin[ 66] = 913 ; icos[ 66] = 406 ; isin[ 67] = 920 ; icos[ 67] = 390 ; isin[ 68] = 927 ; icos[ 68] = 374 ; isin[ 69] = 933 ; icos[ 69] = 358 ; isin[ 70] = 939 ; icos[ 70] = 342 ; isin[ 71] = 945 ; icos[ 71] = 325 ; isin[ 72] = 951 ; icos[ 72] = 309 ; isin[ 73] = 956 ; icos[ 73] = 292 ; isin[ 74] = 961 ; icos[ 74] = 275 ; isin[ 75] = 965 ; icos[ 75] = 258 ; isin[ 76] = 970 ; icos[ 76] = 241 ; isin[ 77] = 974 ; icos[ 77] = 224 ; isin[ 78] = 978 ; icos[ 78] = 207 ; isin[ 79] = 981 ; icos[ 79] = 190 ; isin[ 80] = 984 ; icos[ 80] = 173 ; isin[ 81] = 987 ; icos[ 81] = 156 ; isin[ 82] = 990 ; icos[ 82] = 139 ; isin[ 83] = 992 ; icos[ 83] = 121 ; isin[ 84] = 994 ; icos[ 84] = 104 ; isin[ 85] = 996 ; icos[ 85] = 87 ; isin[ 86] = 997 ; icos[ 86] = 69 ; isin[ 87] = 998 ; icos[ 87] = 52 ; isin[ 88] = 999 ; icos[ 88] = 34 ; isin[ 89] = 999 ; icos[ 89] = 17 ; isin[ 90] = 1000 ; icos[ 90] = 0 ; isin[ 91] = 999 ; icos[ 91] = -17 ; isin[ 92] = 999 ; icos[ 92] = -34 ; isin[ 93] = 998 ; icos[ 93] = -52 ; isin[ 94] = 997 ; icos[ 94] = -69 ; isin[ 95] = 996 ; icos[ 95] = -87 ; isin[ 96] = 994 ; icos[ 96] = -104 ; isin[ 97] = 992 ; icos[ 97] = -121 ; isin[ 98] = 990 ; icos[ 98] = -139 ; isin[ 99] = 987 ; icos[ 99] = -156 ; isin[ 100] = 984 ; icos[ 100] = -173 ; isin[ 101] = 981 ; icos[ 101] = -190 ; isin[ 102] = 978 ; icos[ 102] = -207 ; isin[ 103] = 974 ; icos[ 103] = -224 ; isin[ 104] = 970 ; icos[ 104] = -241 ; isin[ 105] = 965 ; icos[ 105] = -258 ; isin[ 106] = 961 ; icos[ 106] = -275 ; isin[ 107] = 956 ; icos[ 107] = -292 ; isin[ 108] = 951 ; icos[ 108] = -309 ; isin[ 109] = 945 ; icos[ 109] = -325 ; isin[ 110] = 939 ; icos[ 110] = -342 ; isin[ 111] = 933 ; icos[ 111] = -358 ; isin[ 112] = 927 ; icos[ 112] = -374 ; isin[ 113] = 920 ; icos[ 113] = -390 ; isin[ 114] = 913 ; icos[ 114] = -406 ; isin[ 115] = 906 ; icos[ 115] = -422 ; isin[ 116] = 898 ; icos[ 116] = -438 ; isin[ 117] = 891 ; icos[ 117] = -453 ; isin[ 118] = 882 ; icos[ 118] = -469 ; isin[ 119] = 874 ; icos[ 119] = -484 ; isin[ 120] = 866 ; icos[ 120] = -499 ; isin[ 121] = 857 ; icos[ 121] = -515 ; isin[ 122] = 848 ; icos[ 122] = -529 ; isin[ 123] = 838 ; icos[ 123] = -544 ; isin[ 124] = 829 ; icos[ 124] = -559 ; isin[ 125] = 819 ; icos[ 125] = -573 ; isin[ 126] = 809 ; icos[ 126] = -587 ; isin[ 127] = 798 ; icos[ 127] = -601 ; isin[ 128] = 788 ; icos[ 128] = -615 ; isin[ 129] = 777 ; icos[ 129] = -629 ; isin[ 130] = 766 ; icos[ 130] = -642 ; isin[ 131] = 754 ; icos[ 131] = -656 ; isin[ 132] = 743 ; icos[ 132] = -669 ; isin[ 133] = 731 ; icos[ 133] = -681 ; isin[ 134] = 719 ; icos[ 134] = -694 ; isin[ 135] = 707 ; icos[ 135] = -707 ; isin[ 136] = 694 ; icos[ 136] = -719 ; isin[ 137] = 681 ; icos[ 137] = -731 ; isin[ 138] = 669 ; icos[ 138] = -743 ; isin[ 139] = 656 ; icos[ 139] = -754 ; isin[ 140] = 642 ; icos[ 140] = -766 ; isin[ 141] = 629 ; icos[ 141] = -777 ; isin[ 142] = 615 ; icos[ 142] = -788 ; isin[ 143] = 601 ; icos[ 143] = -798 ; isin[ 144] = 587 ; icos[ 144] = -809 ; isin[ 145] = 573 ; icos[ 145] = -819 ; isin[ 146] = 559 ; icos[ 146] = -829 ; isin[ 147] = 544 ; icos[ 147] = -838 ; isin[ 148] = 529 ; icos[ 148] = -848 ; isin[ 149] = 515 ; icos[ 149] = -857 ; isin[ 150] = 500 ; icos[ 150] = -866 ; isin[ 151] = 484 ; icos[ 151] = -874 ; isin[ 152] = 469 ; icos[ 152] = -882 ; isin[ 153] = 453 ; icos[ 153] = -891 ; isin[ 154] = 438 ; icos[ 154] = -898 ; isin[ 155] = 422 ; icos[ 155] = -906 ; isin[ 156] = 406 ; icos[ 156] = -913 ; isin[ 157] = 390 ; icos[ 157] = -920 ; isin[ 158] = 374 ; icos[ 158] = -927 ; isin[ 159] = 358 ; icos[ 159] = -933 ; isin[ 160] = 342 ; icos[ 160] = -939 ; isin[ 161] = 325 ; icos[ 161] = -945 ; isin[ 162] = 309 ; icos[ 162] = -951 ; isin[ 163] = 292 ; icos[ 163] = -956 ; isin[ 164] = 275 ; icos[ 164] = -961 ; isin[ 165] = 258 ; icos[ 165] = -965 ; isin[ 166] = 241 ; icos[ 166] = -970 ; isin[ 167] = 224 ; icos[ 167] = -974 ; isin[ 168] = 207 ; icos[ 168] = -978 ; isin[ 169] = 190 ; icos[ 169] = -981 ; isin[ 170] = 173 ; icos[ 170] = -984 ; isin[ 171] = 156 ; icos[ 171] = -987 ; isin[ 172] = 139 ; icos[ 172] = -990 ; isin[ 173] = 121 ; icos[ 173] = -992 ; isin[ 174] = 104 ; icos[ 174] = -994 ; isin[ 175] = 87 ; icos[ 175] = -996 ; isin[ 176] = 69 ; icos[ 176] = -997 ; isin[ 177] = 52 ; icos[ 177] = -998 ; isin[ 178] = 34 ; icos[ 178] = -999 ; isin[ 179] = 17 ; icos[ 179] = -999 ; isin[ 180] = 0 ; icos[ 180] = -1000 ; isin[ 181] = -17 ; icos[ 181] = -999 ; isin[ 182] = -34 ; icos[ 182] = -999 ; isin[ 183] = -52 ; icos[ 183] = -998 ; isin[ 184] = -69 ; icos[ 184] = -997 ; isin[ 185] = -87 ; icos[ 185] = -996 ; isin[ 186] = -104 ; icos[ 186] = -994 ; isin[ 187] = -121 ; icos[ 187] = -992 ; isin[ 188] = -139 ; icos[ 188] = -990 ; isin[ 189] = -156 ; icos[ 189] = -987 ; isin[ 190] = -173 ; icos[ 190] = -984 ; isin[ 191] = -190 ; icos[ 191] = -981 ; isin[ 192] = -207 ; icos[ 192] = -978 ; isin[ 193] = -224 ; icos[ 193] = -974 ; isin[ 194] = -241 ; icos[ 194] = -970 ; isin[ 195] = -258 ; icos[ 195] = -965 ; isin[ 196] = -275 ; icos[ 196] = -961 ; isin[ 197] = -292 ; icos[ 197] = -956 ; isin[ 198] = -309 ; icos[ 198] = -951 ; isin[ 199] = -325 ; icos[ 199] = -945 ; isin[ 200] = -342 ; icos[ 200] = -939 ; isin[ 201] = -358 ; icos[ 201] = -933 ; isin[ 202] = -374 ; icos[ 202] = -927 ; isin[ 203] = -390 ; icos[ 203] = -920 ; isin[ 204] = -406 ; icos[ 204] = -913 ; isin[ 205] = -422 ; icos[ 205] = -906 ; isin[ 206] = -438 ; icos[ 206] = -898 ; isin[ 207] = -453 ; icos[ 207] = -891 ; isin[ 208] = -469 ; icos[ 208] = -882 ; isin[ 209] = -484 ; icos[ 209] = -874 ; isin[ 210] = -499 ; icos[ 210] = -866 ; isin[ 211] = -515 ; icos[ 211] = -857 ; isin[ 212] = -529 ; icos[ 212] = -848 ; isin[ 213] = -544 ; icos[ 213] = -838 ; isin[ 214] = -559 ; icos[ 214] = -829 ; isin[ 215] = -573 ; icos[ 215] = -819 ; isin[ 216] = -587 ; icos[ 216] = -809 ; isin[ 217] = -601 ; icos[ 217] = -798 ; isin[ 218] = -615 ; icos[ 218] = -788 ; isin[ 219] = -629 ; icos[ 219] = -777 ; isin[ 220] = -642 ; icos[ 220] = -766 ; isin[ 221] = -656 ; icos[ 221] = -754 ; isin[ 222] = -669 ; icos[ 222] = -743 ; isin[ 223] = -681 ; icos[ 223] = -731 ; isin[ 224] = -694 ; icos[ 224] = -719 ; isin[ 225] = -707 ; icos[ 225] = -707 ; isin[ 226] = -719 ; icos[ 226] = -694 ; isin[ 227] = -731 ; icos[ 227] = -682 ; isin[ 228] = -743 ; icos[ 228] = -669 ; isin[ 229] = -754 ; icos[ 229] = -656 ; isin[ 230] = -766 ; icos[ 230] = -642 ; isin[ 231] = -777 ; icos[ 231] = -629 ; isin[ 232] = -788 ; icos[ 232] = -615 ; isin[ 233] = -798 ; icos[ 233] = -601 ; isin[ 234] = -809 ; icos[ 234] = -587 ; isin[ 235] = -819 ; icos[ 235] = -573 ; isin[ 236] = -829 ; icos[ 236] = -559 ; isin[ 237] = -838 ; icos[ 237] = -544 ; isin[ 238] = -848 ; icos[ 238] = -529 ; isin[ 239] = -857 ; icos[ 239] = -515 ; isin[ 240] = -866 ; icos[ 240] = -500 ; isin[ 241] = -874 ; icos[ 241] = -484 ; isin[ 242] = -882 ; icos[ 242] = -469 ; isin[ 243] = -891 ; icos[ 243] = -453 ; isin[ 244] = -898 ; icos[ 244] = -438 ; isin[ 245] = -906 ; icos[ 245] = -422 ; isin[ 246] = -913 ; icos[ 246] = -406 ; isin[ 247] = -920 ; icos[ 247] = -390 ; isin[ 248] = -927 ; icos[ 248] = -374 ; isin[ 249] = -933 ; icos[ 249] = -358 ; isin[ 250] = -939 ; icos[ 250] = -342 ; isin[ 251] = -945 ; icos[ 251] = -325 ; isin[ 252] = -951 ; icos[ 252] = -309 ; isin[ 253] = -956 ; icos[ 253] = -292 ; isin[ 254] = -961 ; icos[ 254] = -275 ; isin[ 255] = -965 ; icos[ 255] = -258 ; isin[ 256] = -970 ; icos[ 256] = -241 ; isin[ 257] = -974 ; icos[ 257] = -224 ; isin[ 258] = -978 ; icos[ 258] = -207 ; isin[ 259] = -981 ; icos[ 259] = -190 ; isin[ 260] = -984 ; icos[ 260] = -173 ; isin[ 261] = -987 ; icos[ 261] = -156 ; isin[ 262] = -990 ; icos[ 262] = -139 ; isin[ 263] = -992 ; icos[ 263] = -121 ; isin[ 264] = -994 ; icos[ 264] = -104 ; isin[ 265] = -996 ; icos[ 265] = -87 ; isin[ 266] = -997 ; icos[ 266] = -69 ; isin[ 267] = -998 ; icos[ 267] = -52 ; isin[ 268] = -999 ; icos[ 268] = -34 ; isin[ 269] = -999 ; icos[ 269] = -17 ; isin[ 270] = -1000 ; icos[ 270] = 0 ; isin[ 271] = -999 ; icos[ 271] = 17 ; isin[ 272] = -999 ; icos[ 272] = 34 ; isin[ 273] = -998 ; icos[ 273] = 52 ; isin[ 274] = -997 ; icos[ 274] = 69 ; isin[ 275] = -996 ; icos[ 275] = 87 ; isin[ 276] = -994 ; icos[ 276] = 104 ; isin[ 277] = -992 ; icos[ 277] = 121 ; isin[ 278] = -990 ; icos[ 278] = 139 ; isin[ 279] = -987 ; icos[ 279] = 156 ; isin[ 280] = -984 ; icos[ 280] = 173 ; isin[ 281] = -981 ; icos[ 281] = 190 ; isin[ 282] = -978 ; icos[ 282] = 207 ; isin[ 283] = -974 ; icos[ 283] = 224 ; isin[ 284] = -970 ; icos[ 284] = 241 ; isin[ 285] = -965 ; icos[ 285] = 258 ; isin[ 286] = -961 ; icos[ 286] = 275 ; isin[ 287] = -956 ; icos[ 287] = 292 ; isin[ 288] = -951 ; icos[ 288] = 309 ; isin[ 289] = -945 ; icos[ 289] = 325 ; isin[ 290] = -939 ; icos[ 290] = 342 ; isin[ 291] = -933 ; icos[ 291] = 358 ; isin[ 292] = -927 ; icos[ 292] = 374 ; isin[ 293] = -920 ; icos[ 293] = 390 ; isin[ 294] = -913 ; icos[ 294] = 406 ; isin[ 295] = -906 ; icos[ 295] = 422 ; isin[ 296] = -898 ; icos[ 296] = 438 ; isin[ 297] = -891 ; icos[ 297] = 453 ; isin[ 298] = -882 ; icos[ 298] = 469 ; isin[ 299] = -874 ; icos[ 299] = 484 ; isin[ 300] = -866 ; icos[ 300] = 499 ; isin[ 301] = -857 ; icos[ 301] = 515 ; isin[ 302] = -848 ; icos[ 302] = 529 ; isin[ 303] = -838 ; icos[ 303] = 544 ; isin[ 304] = -829 ; icos[ 304] = 559 ; isin[ 305] = -819 ; icos[ 305] = 573 ; isin[ 306] = -809 ; icos[ 306] = 587 ; isin[ 307] = -798 ; icos[ 307] = 601 ; isin[ 308] = -788 ; icos[ 308] = 615 ; isin[ 309] = -777 ; icos[ 309] = 629 ; isin[ 310] = -766 ; icos[ 310] = 642 ; isin[ 311] = -754 ; icos[ 311] = 656 ; isin[ 312] = -743 ; icos[ 312] = 669 ; isin[ 313] = -731 ; icos[ 313] = 681 ; isin[ 314] = -719 ; icos[ 314] = 694 ; isin[ 315] = -707 ; icos[ 315] = 707 ; isin[ 316] = -694 ; icos[ 316] = 719 ; isin[ 317] = -682 ; icos[ 317] = 731 ; isin[ 318] = -669 ; icos[ 318] = 743 ; isin[ 319] = -656 ; icos[ 319] = 754 ; isin[ 320] = -642 ; icos[ 320] = 766 ; isin[ 321] = -629 ; icos[ 321] = 777 ; isin[ 322] = -615 ; icos[ 322] = 788 ; isin[ 323] = -601 ; icos[ 323] = 798 ; isin[ 324] = -587 ; icos[ 324] = 809 ; isin[ 325] = -573 ; icos[ 325] = 819 ; isin[ 326] = -559 ; icos[ 326] = 829 ; isin[ 327] = -544 ; icos[ 327] = 838 ; isin[ 328] = -529 ; icos[ 328] = 848 ; isin[ 329] = -515 ; icos[ 329] = 857 ; isin[ 330] = -500 ; icos[ 330] = 866 ; isin[ 331] = -484 ; icos[ 331] = 874 ; isin[ 332] = -469 ; icos[ 332] = 882 ; isin[ 333] = -453 ; icos[ 333] = 891 ; isin[ 334] = -438 ; icos[ 334] = 898 ; isin[ 335] = -422 ; icos[ 335] = 906 ; isin[ 336] = -406 ; icos[ 336] = 913 ; isin[ 337] = -390 ; icos[ 337] = 920 ; isin[ 338] = -374 ; icos[ 338] = 927 ; isin[ 339] = -358 ; icos[ 339] = 933 ; isin[ 340] = -342 ; icos[ 340] = 939 ; isin[ 341] = -325 ; icos[ 341] = 945 ; isin[ 342] = -309 ; icos[ 342] = 951 ; isin[ 343] = -292 ; icos[ 343] = 956 ; isin[ 344] = -275 ; icos[ 344] = 961 ; isin[ 345] = -258 ; icos[ 345] = 965 ; isin[ 346] = -241 ; icos[ 346] = 970 ; isin[ 347] = -224 ; icos[ 347] = 974 ; isin[ 348] = -207 ; icos[ 348] = 978 ; isin[ 349] = -190 ; icos[ 349] = 981 ; isin[ 350] = -173 ; icos[ 350] = 984 ; isin[ 351] = -156 ; icos[ 351] = 987 ; isin[ 352] = -139 ; icos[ 352] = 990 ; isin[ 353] = -121 ; icos[ 353] = 992 ; isin[ 354] = -104 ; icos[ 354] = 994 ; isin[ 355] = -87 ; icos[ 355] = 996 ; isin[ 356] = -69 ; icos[ 356] = 997 ; isin[ 357] = -52 ; icos[ 357] = 998 ; isin[ 358] = -34 ; icos[ 358] = 999 ; isin[ 359] = -17 ; icos[ 359] = 999 ; } int sin(i) int i; { i = i % 360; return(isin[i]); } int cos(j) int j; { j = j % 360; return(icos[j]); } dmode.c ####################### cut here ########################### /* regardless of argument, put cga into mode 6 (mono) */ graphmode(i) int i; { dismode(6); } /* put cga back to 80 column color mode */ textmode() { dismode(3); } dismode.asm ####################### cut here ########################### ; Static Name Aliases ; ; This routine will call BIOS to change the display mode of the ; cga or ega controller ; ; it is called as dismode(mode) ; ; any IBM manual should give a complete description of the display ; modes ; for now hex 6 is mono graphics 640 x 200 ; hex 3 is 80 column text in color TITLE dismode .287 DISMODE_TEXT SEGMENT BYTE PUBLIC 'CODE' DISMODE_TEXT ENDS _DATA SEGMENT WORD PUBLIC 'DATA' _DATA ENDS CONST SEGMENT WORD PUBLIC 'CONST' CONST ENDS _BSS SEGMENT WORD PUBLIC 'BSS' _BSS ENDS DGROUP GROUP CONST, _BSS, _DATA ASSUME CS: DISMODE_TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP EXTRN __chkstk:FAR DISMODE_TEXT SEGMENT PUBLIC _dismode _dismode PROC FAR push bp mov bp,sp xor ax,ax call FAR PTR __chkstk mov ax,[bp+6] mov ah,00h int 10h mov sp,bp pop bp ret _dismode ENDP DISMODE_TEXT ENDS END