//------------------------------------------------------------------- // twofonts.cpp // // This program illustrates the simultaneous use of two glyph- // tables by the VGA's text-mode character-generator mechanism // after reprogramming the Attribute Controller's 'Color Plane // Enable' register to disable Color Plane 3 (intense colors). // // compile using: $ twofonts.cpp int86.cpp -o twofonts // // programmer: ALLAN CRUSE // written on: 08 SEP 2005 //------------------------------------------------------------------- #include // for printf() #include // for strlen() #include // for STDIN_FILENO #include // for inb(), outb(), etc. #include // for tcgetattr(), tcsetattr() #include "int86.h" // for init8086(), int86() #define VRAM_BASE_FOR_CGA 0x000B8000 typedef unsigned char u8; typedef struct { unsigned char character, attribute; } CELL; CELL *vram = (CELL*)VRAM_BASE_FOR_CGA; struct vm86plus_struct vm; int main( int argc, char **argv ) { // setup the keyboard for 'non-canonical' input struct termios orig_tty; tcgetattr( STDIN_FILENO, &orig_tty ); struct termios work_tty = orig_tty; work_tty.c_lflag &= ~(ICANON | ECHO ); work_tty.c_cc[ VTIME ] = 0; work_tty.c_cc[ VMIN ] = 1; tcsetattr( STDIN_FILENO, TCSAFLUSH, &work_tty ); // set the CRT Start_Address to zero init8086(); // enable BIOS access vm.regs.eax = 0x0003; // Set Display Mode 3 int86( 0x10, vm ); // invoke BIOS service CELL *dstn = vram; // address top of screen // create text-cells for directly writing to video memory char message1[] = "Hello, folks!"; char message2[] = "This is a VGA character generator demonstration"; CELL font[ 512 ]; // for showing 512-glyphs for (int i = 0; i < 512; i++) { font[ i ].character = (i & 0xFF); font[ i ].attribute = (i < 256) ? 0x07 : 0x0F; } // copy text-cells directly to video memory dstn += 80; for (int i = 0; i < strlen( message1 ); i++) dstn[ i ].character = message1[ i ]; dstn += 80; for (int i = 0; i < strlen( message2 ); i++) dstn[ i ].character = message2[ i ]; getchar(); dstn += 2*80; for (int i = 0; i < 512; i++) { if ( ( i % 32 ) == 0 ) dstn += 80; dstn[ 2*(i % 32) + 8 ] = font[ i ]; } getchar(); // invoke BIOS function to load a different font-table vm.regs.eax = 0x1102; // Load 8x8 font-table vm.regs.ebx = 0x0001; // into generator map 1 int86( 0x10, vm ); // invoke BIOS service getchar(); // switch to new font-table as the Primary Font vm.regs.eax = 0x1103; // Select the Active Maps vm.regs.ebx = 0x0001; // 1 Primary, 0 secondary int86( 0x10, vm ); // invoke BIOS service getchar(); // set intensity-bit of alternating cells in top four rows for (int i = 0; i < 320; i++) vram[ 2*i+1 ].attribute |= 0x08; getchar(); // Attribute Controller Color Plane Enable register (index 0x12) inb( 0x3DA ); // reset the controller's flip-flop outb( 0x12, 0x3C0 ); // select Color Plane Enable register outb( 0x07, 0x3C0 ); // write new Color Plane Enable value outb( 0x20, 0x3C0 ); // set Index bit #5 (reenable screen) getchar(); // restore canonical keyboard-input and reinitialize text-mode tcsetattr( STDIN_FILENO, TCSAFLUSH, &orig_tty ); vm.regs.eax = 0x0003; // Set Display Mode 3 int86( 0x10, vm ); // invoke BIOS service printf( "\n" ); // advance to new line }