Graphics BitmapsLimitations of BIOS routinesBuilt-in character bitmapsLayout of 8x16 glyph-tableThe 8086 physical memoryFinding the ROM fontsExampleInvoking BIOS from LinuxDrawing a character (in mode 18)Using VGA Write Mode 3IllustrationImplementation detailsDraw_char() (continued)Draw_char() (concluded)Our ‘drawtext.cpp’ demoHow ‘Write Mode 0’ worksAlgorithm to ‘tile’ screen-areaDesigning bitmap ‘patterns’Algorithm for ‘tiling’ (mode 19)In-class exerciseGraphics BitmapsDrawing characters glyphs and multicolor patternsLimitations of BIOS routines•Last time we used a ROM-BIOS routine to draw a text message on a graphics screen (i.e., the so-called ‘write_string’ service) •But some limitations were apparent:–String-location had to conform to a cell-grid–Background color pattern was obliterated•We can overcome both these limitations if we draw the character-glyphs ourselvesBuilt-in character bitmaps•The ROM-BIOS has full sets of bitmaps for the images of all the ASCII characters in several sizes (e.g., 8x8, 8x14 and 8x16)Example: An 8-by-8 glyph for the letter ‘H’Layout of 8x16 glyph-table•The Glyph-Table is an array of bit-images•Each bit-image is 16-bytes in length•Each ascii-code serves as array-index‘@’ ‘A’ ‘B’ ‘C’ ‘D’ ‘E’ ‘F’0x40 0x41 0x42 0x43 0x44 0x45 0x46 etcThe 8086 physical memoryBoot ROMVideo ROMVRAMRAMReserved for add-ins0x000000xA00000xC00000xF0000VECTORSBIOS DATAEBDA1-MBThe VGA firmware Character-Glyph tables are located in this region A built-in BIOS function will report each of the glyph-table start-locationsFinding the ROM fonts•Standard BIOS service locates ROM fonts•Designed to execute in 8086 real-mode•Normal service-call protocol is followed: –Parameters are placed in CPU registers–Software interrupt instruction is executed–ROM-BIOS code performs desired service–Parameters may be returned in registersExample# AT&T assembly language syntaxmov $0x11, %ah # char. gen. services mov $0x30, %al # get font informationmov $6, %bh # 8x16 font addressint $0x10 # request BIOS service# the font address is returned in ES:BP# (and count of scanlines should be in CX)Invoking BIOS from Linux•Include our “int86.h” header-file•Define ‘struct vm86plus_struct’ object: vm•Initialize necessary register-fields of ‘vm’– vm.regs.eax = 0x1130; – vm.regs.ebx = 0x0600;•Call our function: int86( 0x10, vm );•Retrieve the returned parameters from vm– e.g., from ‘vm.regs.es’ and ‘vm.regs.ebp’Drawing a character (in mode 18)•Must enable I/O and 1-MB memory-map•Virtual address of VRAM is 0x000A0000•Use any ascii-code as a glyph-table index•Use x,y coordinates for character location•Specify the character’s ‘foreground color’ •Thus your function-call could look like: draw_char( x, y, color, ascii );Using VGA Write Mode 3•To preserve the background pattern when a character-glyph is drawn, you can use a ‘Masked Write’ operation (‘Write Mode 3’)•To position the character at an arbitrary horizontal pixel position, use Data-Rotate•The foreground color goes in ‘Set/Reset’•The Bit Mask register prevents unwanted pixels from being drawn when rotationIllustrationAdjacent bytes on the screenLeft-hand Right-hand Bit Mask Bit MaskCharacter-glyph is right-rotatedAfterward this rotated glyph gets ‘masked’Implementation details void draw_char( int x, int y, int fg, int ascii ) { int which = y * hres + x; int where = which / 8;int shift = which % 8; int left_mask = 0xFF >> shift; int right_mask = ~(left_mask);char *glyph = (char*)fontbase + 16*ascii;Draw_char() (continued)outw( 0x0305, GCPORT ); // use Mode 3outw( color<<8, GCPORT ); // Set/Reset// first-pass draws glyph’s left portionoutw( (left_mask<<8) | 8, GCPORT );for (int row = 0; row < 16; row++) { char temp = vram[ where + row*80 ]; vram[ where + row*80 ] = glyph[ row ];}Draw_char() (concluded) if ( shift == 0 ) return; // we can do an early exit // else second-pass draws glyph’s right portion ++where; // location of the adjacent byte outw( (right_mask<<8) | 8, GCPORT ); // Bit Mask for (int row = 0; row < 16; row++) { char temp = vram[ where + row*80 ]; vram[ where + row*80 ] = glyph[ row ];} }Our ‘drawtext.cpp’ demo•We used an 8-by-8 bitmap to generate the patterned background for drawing text on0x000x000x330x330x000x000x330x33Background color0001 (binary)Foreground color1001 (binary)How ‘Write Mode 0’ works0 0 1 1 0 0 1 10 0 1 1 0 0 1 1Latch plane 30 0 0 0 0 0 0 0Latch plane 20 0 0 0 0 0 0 0Latch plane 11 1 1 1 1 1 1 1Latch plane 0Data from CPUx0010111 ENABLESET/RESET SET/RESETByte from pattern-glyphScreen Pixel (planar)VRAM byteAlgorithm to ‘tile’ screen-area // Use Write Mode 0 (“Direct Write”) // Data-Rotate = 0, Function-Select is ‘copy’ // Bit Mask is 0xFF (e.g., all pixels writable) // Enable Set/Reset is 0x7, Set/Reset is 0x1 // pattern-glyph described by array of 8-bytes for (y = ymin; y < ymax; y++) for (x = xmin; x < xmax; x++)vram[ y * 80 + x ] = glyph[ y % 8 ];Designing bitmap ‘patterns’•You can create interesting backgrounds•Fill screen regions with a copied pattern0xFF0x800x800x800xFF0x080x080x08foreground colorbackground colorAlgorithm for ‘tiling’ (mode 19)unsigned char pat[ 8 ]; # 8x8 2-color bitmapunsigned char *vram = 0x000A0000, color;for (int y = 0; y < vres; v++)for (int x = 0; x < hres; x++){int r = y % 8, k = x % 8;color = ( pat[ r ] & (0x80>>k) ) ? fg : bg;vram[ y*hres + x ] = color;}In-class exercise•Take a look at our ‘brickpat.cpp’ demo•It tiles the screen with a brick-wall pattern•But it executes in mode 19 (256-colors)•Can you revise this demo so that it will work in a ‘planar’ mode (i.e., 16-colors)?•Hint: Apply the principles of Write Mode 0 in a manner similar to ‘drawtext.cpp’ demo•Can you write text against your
View Full Document