//------------------------------------------------------------------- // quikcopy.cpp // // This program shows how a graphics application written in C++ // can call an external procedure written in assembly language. // // compile: g++ quikcopy.cpp int86.cpp copypage.o -o quikcopy // // programmer: ALLAN CRUSE // written on: 03 DEC 2003 // revised on: 06 OCT 2005 -- replaced svgalib with 'int86()' //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for lseek() #include // for tcgetattr(), tcsetattr() #include // for mmap() #include "int86.h" // for init8086(), int86() extern "C" void copypage( int src_pgno, int dst_pgno, int pagesz ); unsigned char *vram = (unsigned char*)0xA0000000; const int vesa_mode = 0x4101, hres = 640, vres = 480; struct vm86plus_struct vm; void draw_rectangle( int x, int y, int h, int v, int color ) { int minx = x, miny = y, maxx = x+h-1, maxy = y+v-1; do { vram[ y*hres + x ] = color; ++x; } while ( x < maxx ); do { vram[ y*hres + x ] = color; ++y; } while ( y < maxy ); do { vram[ y*hres + x ] = color; --x; } while ( x > minx ); do { vram[ y*hres + x ] = color; --y; } while ( y > miny ); } void fill_rectangle( int x, int y, int h, int v, unsigned char *pat ) { int minx = x, miny = y, maxx = x+h-1, maxy = y+v-1; for (y = miny; y < maxy; y++) for (x = minx; x < maxx; x++) vram[ y*hres + x ] = pat[ ((y/4) % 4)*4 + ((x/4) % 4) ]; } int main( int argc, char **argv ) { // memory-map the display-memory into user-space int fd = open( "/dev/vram", O_RDWR ); if ( fd < 0 ) { perror( "/dev/vram" ); return -1; } int size = lseek( fd, 0, SEEK_END ); int prot = PROT_READ | PROT_WRITE; int flag = MAP_FIXED | MAP_SHARED; if ( mmap( (void*)vram, size, prot, flag, fd, 0 ) == MAP_FAILED ) { perror( "mmap" ); return -1; } // enable non-canonical keyboard input struct termios otty; tcgetattr( 0, &otty ); struct termios tty = otty; tty.c_lflag &= ~( ICANON | ECHO | ISIG ); tty.c_cc[ VMIN ] = 1; tty.c_cc[ VTIME ] = 0; tcsetattr( 0, TCSAFLUSH, &tty ); // enter graphics mode init8086(); vm.regs.eax = 0x04F02; vm.regs.ebx = vesa_mode; int86( 0x10, vm ); // draw border rectangle int color = 15; draw_rectangle( 0, 0, hres, vres, color ); getchar(); //----------------------------------------------------------- // draw rectangle on page 1, then copy from page 1 to page 0 //----------------------------------------------------------- color = 14; draw_rectangle( 0, vres, hres, vres, color ); copypage( 1, 0, hres*vres ); //<-- call external function getchar(); //----------------------------------------------------------- //----------------------------------------------------------- // draw a pattern on page 1, then copy from page 1 to page 0 //----------------------------------------------------------- unsigned char pattern[ 16 ]; // for 4x4 bitmap pattern for (int i = 0; i < 16; i++) pattern[ i ] = random(); fill_rectangle( 4, vres+4, hres-8, vres-8, pattern ); color = 6; draw_rectangle( 2, vres+2, hres-4, vres-4, color ); copypage( 1, 0, hres*vres ); //<-- call external function getchar(); //----------------------------------------------------------- // leave graphics mode vm.regs.eax = 0x0003; int86( 0x10, vm ); // restore canonical keyboard input tcsetattr( 0, TCSAFLUSH, &otty ); printf( "finished\n" ); }