200 likes | 218 Views
Explore how to locate, access, and utilize ROM fonts in 8086 real-mode using standard BIOS services. Learn to draw multicolor patterns and characters in graphics mode, including automating pattern creation and utilizing color tables. Discover LRMI interface for Linux and SVGALIB project for easier BIOS calls.
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); }