//------------------------------------------------------------------- // sinedemo.cpp // // This program shows the graphs of successive approximations // to the sine function by the sequence of Taylor Polynomials // of increasing degrees around zero (Maclaurin polynomials). // // compile using: $ g++ sinedemo.cpp int86.cpp -o sinedemo // // programmer: ALLAN CRUSE // written on: 04 DEC 2005 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for lseek() #include // for sin(x) #include // for mmap() #include // for inb(), outb(), etc. #include "int86.h" // for init8086(), int86() #define PI 3.14159 unsigned char *vram = (unsigned char*)0xA0000000; int vesa_mode = 0x4105, hres = 1024, vres = 768; struct vm86plus_struct vm; int polynomial_degree = 0; double sineterm( int n, double x ) { double fact = 1.0; double term = 1.0; for (int k = 1; k <= n; k++) { fact *= k; term *= x; } term /= fact; if ( ( n % 2 ) == 0 ) return 0.0; if ( ( n % 4 ) == 3 ) term *= -1.0; return term; } double polynomial( double x ) { double y = 0.0; for (int n = 0; n <= polynomial_degree; n++) y += sineterm( n, x ); return y; } void draw_pixel( int x, int y, int color ) { if (( x <= 1 )||( x >= hres-2 )) return; if (( y <= 1 )||( y >= vres-2 )) return; vram[ y * hres + x ] = color; } void draw_curve( double function( double ), int color ) { double scaleX = 42, scaleY = -42; double transX = hres/2, transY = vres/2; double xmin = -4*PI, xmax = 4*PI, xinc = PI/720; for (double x = xmin; x <= xmax; x += xinc) { double y = function( x ); int h = (int)(x * scaleX + transX); int v = (int)(y * scaleY + transY); draw_pixel( h, v, color ); } } int main( int argc, char **argv ) { // memory-map the display-memory into user-space int vd = open( "/dev/vram", O_RDWR ); if ( vd < 0 ) { perror( "/dev/vram" ); exit(1); } int size = lseek( vd, 0, SEEK_END ); int prot = PROT_READ | PROT_WRITE; int flag = MAP_FIXED | MAP_SHARED; if ( mmap( (void*)vram, size, prot, flag, vd, 0 ) == MAP_FAILED ) { perror( "mmap" ); exit(1); } // enter graphics mode init8086(); vm.regs.eax = 0x4F02; vm.regs.ebx = vesa_mode; int86( 0x10, vm ); // draw screen border int x = 0, y = 0, color = 15; do { vram[ y * hres + x ] = color; ++x; } while ( x < hres-1 ); do { vram[ y * hres + x ] = color; ++y; } while ( y < vres-1 ); do { vram[ y * hres + x ] = color; --x; } while ( x > 0 ); do { vram[ y * hres + x ] = color; --y; } while ( y > 0 ); getchar(); // draw coordinate axes y = vres/2; for (x = 0; x < hres; x++) draw_pixel( x, y, 7 ); x = hres/2; for (y = 0; y < vres; y++) draw_pixel( x, y, 7 ); getchar(); // draw the sine curve color = 14; draw_curve( sin, color ); getchar(); // draw the Taylor Polynomial color = 11; polynomial_degree = 1; for (int i = 0; i < 15; i++) { draw_curve( polynomial, color ); getchar(); draw_curve( polynomial, 0 ); polynomial_degree += 2; } // leave graphics mode vm.regs.eax = 0x0003; int86( 0x10, vm ); printf( "\n" ); }