graphics bitmaps drawing alphabetic characters and multicolor patterns
TRANSCRIPT
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
0xFF0x800x800x800xFF0x080x080x08
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);
}