//------------------------------------------------------------------- // egademo.cpp // // This program demonstrates "enhanced" PC graphics programming // with 256KB of installed video memory (real address 0xA0000), // supporting 16-colors using four overlapping memory "planes". // (Supported by VGA/SVGA devices for backward compatibility.) // // programmer: ALLAN CRUSE // written on: 07 SEP 2003 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for close() #include // for mman() #include // for iopl() typedef unsigned char u8; u8 *vram = (u8*)0x000A0000; int hres = 640, vres = 350; void set_pixel( int x, int y, int color ) { int posn = y*80 + (x / 8); int mask = 0x80 >> (x % 8); // Using the Graphics Controller's Write Mode 0 ("Direct Write") // 1. Load fill-color into Set/Reset register (index 0) outw( (color << 8)|0, 0x3CE ); // 2. Load 0x0F into Enable Set/Reset register (index 1) outw( 0x0F01, 0x3CE ); // 3. Setup Data-Rotate/Function-Select register (index 3) outw( 0x0003, 0x3CE ); // 4. Program the controller's Bit Mask register (index 8) outw( (mask << 8)|8, 0x3CE ); // 5. Load the latches, then write to vram vram[ posn ] = vram[ posn ]; } void fill_rectangle( int x, int y, int h, int v, int color ) { int minx = x, maxx = x+h-1; int miny = y, maxy = y+v-1; for (y = miny; y <= maxy; y++) for (x = minx; x <= maxx; x++) set_pixel( x, y, color ); } void map_vram( int base, int size ); int main( int argc, char **argv ) { int base = (int)vram; int size = (256<<10); map_vram( base, size ); int minx, midx, maxx, miny, midy, maxy; int x, y, color, radius_squared; //---------------------------------------------- // Demonstrate EGA color graphics (VGA mode 16) //---------------------------------------------- system( "clear ; mode3 16 " ); // 640x350, 16-colors // draw screen border color = 15; // white minx = 0, maxx = hres-1; miny = 0, maxy = vres-1; x = y = 0; do { set_pixel( x, y, color ); ++x; } while ( x < maxx ); do { set_pixel( x, y, color ); ++y; } while ( y < maxy ); do { set_pixel( x, y, color ); --x; } while ( x > minx ); do { set_pixel( x, y, color ); --y; } while ( y > miny ); getchar(); // show the palette of 16-colors int h = 40, v = 40, x0 = 64, y0 = 48; for (color = 0; color < 16; color++) { x = x0 + (color % 8)*64; y = y0 + (color / 8)*64; fill_rectangle( x, y, h, v, color ); } getchar(); // fill circle (unrescaled) midx = hres/2; midy = 23*vres/32; radius_squared = 80*80; color = 6; for (y = 4; y <= maxy-4; y++) for (x = 4; x <= maxx-4; x++) { int dx = x - midx; int dy = y - midy; int dist_squared = dx*dx + dy*dy; if ( dist_squared < radius_squared ) set_pixel( x, y, color ); } getchar(); system( " mode3 3 " ); // standard 80x25 text mode } void map_vram( int base, int size ) { int fd = open( "/dev/mem", O_RDWR ); if ( fd < 0 ) { perror( "/dev/mem" ); exit(1); } int prot = PROT_READ | PROT_WRITE; int flag = MAP_FIXED | MAP_SHARED; void *mm = (void*)base; if ( mmap( mm, size, prot, flag, fd, base ) == MAP_FAILED ) { perror( "mmap" ); exit(1); } close( fd ); }