/* NAME pageflip - test hardware page flipping SYNOPSIS pageflip DESCRIPTION pageflip is used to test hardware page flipping on graphic cards supporting standard VGA registers while running an X Server. To obtain meaningful results, a virtual screen must be active with an horizontal resolution set to the double of the viewport horizontal resolution. For example, a 1024x768 viewport with a 2048x768 virtual screen. The application is controlled using these interactive commands: q quit the application 1 set the CRTC Start Address Register to 0 2 set the CRTC Start Address Register to OPTIONS Set the offset value as a number of pixel columns that should correspond to the width of the current viewport. For example 1920 for a 3840x1080 virtual screen. AUTHOR Frédéric Lopez 12 September 2010 */ #include #include #include #include // Define the Address Register for CRTC access #define CRTC_ADDR_REG 0x3D4 // Define the Data Register for CRTC access #define CRTC_DATA_REG 0x3D5 // Set the CRTC Start Adress Register static void set_vga_start(int offset) { // Set the CRTC Start Address Low Register outb(0x0D, CRTC_ADDR_REG); outb(offset & 0xFF, CRTC_DATA_REG); // Set the CRTC Start Address High Register outb(0x0C, CRTC_ADDR_REG); outb(offset >> 8, CRTC_DATA_REG); } int main(int argc, char *argv[]) { int key, offset; char *p; // Test the number of command-line arguments if (argc != 2) { printf("Usage: pageflip \n"); exit(EXIT_FAILURE); } // Test if the argument is an integer errno = 0; offset = strtol(argv[1], &p, 10); if (errno != 0 || *p != 0 || p == argv[1]) { printf("Error: offset value must be an integer!\n"); exit(EXIT_FAILURE); } // Change the I/O privilege level to allow access to VGA registers if (iopl(3) != 0) { printf("Warning: unable to modify the I/O privilege level!\n"); } // Show interactive commands help printf("Quit with 'q'.\n"); printf("Page 1 with '1'.\n"); printf("Page 2 with '2'.\n"); while ((key = getchar()) != 'q') { switch (key) { case '1' : // Set Start Address Register to 0 set_vga_start(0); printf("Page 1.\n"); break; case '2' : // Set Start Address Register to set_vga_start(offset); printf("Page 2.\n"); break; } } // Restore the default I/O privilege level if (iopl(0) != 0) { printf("Warning: unable to restore the default I/O privilege level!\n"); } printf("Done.\n"); return EXIT_SUCCESS; }