//------------------------------------------------------------------- // 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.) // // compile using: $ g++ egademo.cpp int86.cpp -o egademo // // programmer: ALLAN CRUSE // written on: 01 SEP 2005 //------------------------------------------------------------------- #include // for printf() #include // for inb(), outw(), etc. #include "int86.h" // for init8086(), int86() #define VRAM_BASE_FOR_EGA 0x000A0000 #define GFXC_INDEX_PORT 0x03CE typedef unsigned char u8; u8 *vram = (u8*)VRAM_BASE_FOR_EGA; struct vm86plus_struct vm; void set_pixel( int x, int y, int color ) { // Using the Graphics Controller's Write Mode 0 ("Direct Write") int posn = y*80 + (x / 8); int mask = 0x80 >> (x % 8); // 1. Load fill-color into Set/Reset register (index 0) outw( (color << 8)|0, GFXC_INDEX_PORT ); // 2. Load 0x0F into Enable Set/Reset register (index 1) outw( 0x0F01, GFXC_INDEX_PORT ); // 3. Setup Data-Rotate/Function-Select register (index 3) outw( 0x0003, GFXC_INDEX_PORT ); // 4. Program the controller's Bit Mask register (index 8) outw( (mask << 8)|8, GFXC_INDEX_PORT ); // 5. Load the latches from vram, then write back to vram vram[ posn ] = vram[ posn ]; } void fill_rectangle( int x, int y, int h, int v, int color ) { int xmin = x, xmax = x+h-1, ymin = y, ymax = y+v-1; for (y = ymin; y <= ymax; y++) for (x = xmin; x <= xmax; x++) set_pixel( x, y, color ); } int main( int argc, char **argv ) { int hres, vres, minx, midx, maxx, miny, midy, maxy; int x, y, color, radius_squared; printf( "\e[H\n" ); // avoids getchar jerk init8086(); // enable BIOS service //---------------------------------------------- // Demonstrate EGA color graphics (IBM mode 16) //---------------------------------------------- vm.regs.eax = 0x0010; // Set Display Mode 16 int86( 0x10, vm ); // invoke BIOS service // draw screen border hres = 640, vres = 350, 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(); // return the display to standard text mode vm.regs.eax = 0x0003; // Set Display Mode 3 int86( 0x10, vm ); // invoke BIOS service printf( "EGA demo is finished\n" ); }