200 likes | 385 Views
Graphics Bitmaps. Drawing alphabetic characters and multicolor patterns. Finding 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
E N D
Graphics Bitmaps Drawing alphabetic characters and multicolor patterns
Finding 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 registers
Example # AT&T assembly language syntax mov $0x11, %ah # char. gen. services mov $0x30, %al # get font information mov $2, %bh # 8x14 font address int $0x10 # request BIOS service # the font address is returned in ES:BP # (and count of scanlines should be in CX)
Interface for Linux • No C++ syntax to access CPU registers • Software interrupt is privileged operation • Must call kernel to obtain BIOS services • How to do it isn’t very clearly documented • SVGALIB Project: includes ‘LRMI’ wrapper • An acronym for Linux Real-Mode Interface • Idea: make it easy to invoke BIOS calls
How LRMI is used • C program needs: #include “lrmi.h” • Needs to do initialization: LRMI_init(); • Declares: struct LRMI_regs reg = {0}; • Code-example: reg.eax = 0x1130; reg.ebx = 0x0200; LRMI_int( 0x10, ® ); int font_address = reg.ebp + 16*reg.es;
Link with ‘lrmi.o’ object-module • Need to precompile ‘lrmi.c’ source-text: gcc –c lrmi.c • For C++ you need overriding prototypes: extern “C” int LRMI_init( void ); # etc. #include “lrmi.h” # this comes after • To compile and link your C++ program: g++ drawtext.cpp lrmi.o -o drawtext
Acknowledgement • The author of ‘LRMI’ is Josh Vanderhoof • His code is part of the SVGALIB package • Full package can be downloaded from: http://www.svgalib.org • Downloaded as a compressed ‘.tar’ file: Example: svgalib-1.4.3.tar.gz • Use the ‘tar’ command to ‘expand’ it: tar -xvzf svgalib-1.4.3.tar.gz
Copying 8x14 ROM font • Need to memory-map the ROM region • ‘mmap()’ requires map to be 4K-aligned • Size of mapped region: 0x1000 (256*16) • Need to allocate a local array in RAM: static unsigned char glyph[256][16]; for (c = 0; c < 256; c++) for (r =0; r < 14; r++) glyph[ c ][ r ] = *font_addr++;
Drawing a character (in mode 19) • Must memory-map the VRAM window • Physical base-address is 0x000A0000 • Size of VRAM window is 64K: (64<<10) • Use the ascii-code as a glyph-table index • Specify the character’s ‘foreground color’ • Use x,y coordinates for character location • So your function prototype could be: void draw_char( int ascii, int color );
Implementing ‘draw_char()’ int hres = 320, vres = 200; unsigned char *dstn = 0x000A0000; dstn += ( y * hres + x ); # where to start drawing for (r = 0; r < 14; r++) # 14-rows high { for (w = 0; w < 8; w++) # 8-pixels wide if ( glyph[ ascii ][ r ] & (0x80>>w) ) dstn[ w ] = fgcolor; dstn += hres; # drop to next screen row }
Some comparisons text mode • ‘character generator’ imposes a fixed grid • All characters from a common glyph-table • Character backgrounds always solid color graphics mode • You can freely mix numerous font styles • You can place characters at any positions • You can draw against backgound patterns
Using bitmap ‘patterns’ • You can create interesting backgrounds • Fill screen regions with a copied pattern 0xFF 0x80 0x80 0x80 0xFF 0x08 0x08 0x08 foreground color background color
Algorithm for ‘tiling’ (mode 19) unsigned char pat[ 8 ]; # 8x8 2-color bitmap unsigned 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; }
Automating pattern-creation • Try these standard runtime functions; #include <stdlib.h> int rand( void ); void srand( unsigned int seed ); • Can make new 8x8 patterns like this: for (k = 0; k < 8; k++) pat[ k ] = rand(); fgcolor = rand(); bgcolor = rand();
Esthetics • Use a ‘brighter’ color in the foreground • Use a ‘darker’ color in the background • To implement this discipline we need to know how the ‘color-table’ is arranged • In mode 19 there are 256 default colors • Among these are 24 color-groups: • 3 intensity-levels plus 3 saturation-levels
The ‘default’ colors (mode 19) • Range for the 72 brightest colors: 32–103 • Range for the 72 midlevel colors: 104-175 • Range for the 72 darkest colors: 176-247 • Colors 0-15 are the standard EGA colors • Colors 16-31 are sixteen grayscale colors • Colors 248-255 are solid black (default) • (But all of these are fully ‘programmable’)
Choosing a random color-pair • foreground color (from the ‘bright’ range): fgcolor = ( ( rand() & 0xFF ) % 72 ) + 32; • Background color (from the ‘dark’ range): bgcolor = ( ( rand() & 0xFF ) % 72 ) + 104;
Using patterns with more colors • Same concepts can be extended • But need a larger pattern-bitmap • Example: use 2 bits-per-pixel (4 colors) • An 8x8 pattern that using 4 colors: unsigned short pat2bpp[ 8 ]; unsigned char palette4[ 4 ]; for (r = 0; r < 8; r++) pat2bpp[ r ] = rand(); for (c = 0; c < 4; c++) palette4[ c ] = rand();
Tiling with a 4-color bitmap for (y = 0; y < hres; y++) { unsigned short bits = pat2bpp[ y % 8 ]; for (x = 0; x < hres; x++) { int i = ( bits >> ( x % 8 )&3; int color = palette4[ i ]; vram[ y*hres + x ] = color; } }
Automating an ‘art show’ • Can use a standard C runtime function: #include <stdlib.h> void sleep( int seconds ); • User views your screen for fixed duration: while ( !done ) { draw_next_scene(); sleep(1); }