----------------------------- The BGI Driver Toolkit Creating Device Drivers for the Borland Graphics Interface -------------------------------------- Copyright (c) 1988,89 Borland International Revision 1 May 15, 1989 Introduction ======================= The Borland Graphics Interface (BGI) is a fast, compact, and device-independent software package for graphics development built into the Turbo Pascal, Turbo C, and Turbo Prolog language products. Device independence is achieved via loadable device-specific drivers called from a common Kernel. This document describes basic BGI functionality, as well as the steps necessary to create new device drivers. Accompanying this document are files containing sample code and other pertinent information. File Name File Description BH.C BGI loader header building program source BH.EXE BGI loader header building program DEVICE.INC Structure and macro definition file DEBVECT.ASM Vector table for sample (DEBUG) driver DEBUG.C Main module for sample driver MAKEFILE Build file BUILD.BAT A batch file for MAKE-phobics BGI Run-time Architecture ============================= Programs produced by Borland languages create graphics via two entities acting in concert: the generic BGI Kernel and a device-specific driver. Typically, an application built with a Borland compiler will include several device driver files on the distribution disk (extension .BGI) so that the program can run on various types of screens and printers. Graphics requests (for example, draw line, draw bar, etc.) are sent by the application to the BGI Kernel, which in turn makes requests of the device driver to actually manipulate the hardware. A BGI device driver is a binary image; that is, a sequence of bytes without symbols or other linking information. The driver begins with a short header, followed by a vector table containing the entry points to the functions inside. The balance of the driver comprises the code and data required to manipulate the target graphics hardware. All code and data references in the driver must be near (i.e., small model, offset only), and the entire driver, both code and data, must fit within 64K. In use, the device driver can count on its being loaded on a paragraph boundary. The BGI Kernel uses a register-based calling convention to communicate with the device driver (described in detail below). BGI Graphics Model ======================= When considering the functions listed here, keep in mind that BGI performs most drawing operations using an implicit drawing or tracing color (COLOR), fill color (FILLCOLOR), and pattern (FILLPATTERN). For example, the PIESLICE call accepts no pattern or color information, but instead uses the previously set COLOR value to trace the edge of the slice, and the previously set FILLCOLOR and FILLPATTERN values for the interior. For efficiency, many operations take place at the position of the current pointer, or CP. For example, the LINE routine accepts only a single (x,y) coordinate pair, using the CP as the starting point of the line and the passed coordinate pair as the ending point. Many functions (LINE, to name one) affect CP, and the MOVE function can be used to explicitly adjust CP. The BGI coordinate system places the origin (pixel 0,0) at the upper left-hand corner of the screen. Header Section ======================= The device header section, which must be at the beginning of the device driver, is built using macro BGI defined in file DEVICE.INC. The BGI macro takes the name of the device driver to be built as an argument. For example, a driver named DEBUG would begin as shown here: CSEG SEGMENT PARA PUBLIC 'CODE' ; any segment naming may be used ASSUME DS:CSEG, CS:CSEG ; cs=ds CODESEG INCLUDE DEVICE.INC ; include the device.inc file BGI DEBUG ; declare the device header section The device header section declares a special entry point known as EMULATE. If the action of a device driver vector is not supported by the hardware of a device, the vector entry should contain the entry EMULATE. This will be patched at load time to contain a jump to the Kernel's emulation routine. These routines will emulate the action of the vector by breaking down the request into simpler primitives. For example, if the hardware has the functionality to draw arc, the arc vector will contain the address of the routine to dispatch the arc data to the hardware and would appear as follows: dw offset ARC ; Vector to the arc routine If, as is often the case, the hardware doesn't have the functionality to display arcs, the vector would instead contain the EMULATE vector: dw EMULATE The Kernel has emulation support for the following vectors: BAR Filling 3D rectangles ARC Elliptical arc rendering PIESLICE Elliptical pie slices FILLED_ELLIPSE Filled Ellipses The Driver Status Table ======================= BGI requires that each driver contain a Driver Status Table (DST) to determine the basic characteristics of the device that the driver addresses. As an example, the DST for a CGA display is shown here: STATUS STRUC STAT DB 0 ; Current Device Status (0 = No Errors) DEVTYP DB 0 ; Device Type Identifier (must be 0) XRES DW 639 ; Device Full Resolution in X Direction YRES DW 199 ; Device Full Resolution in Y Direction XEFRES DW 639 ; Device Effective X Resolution YEFRES DW 199 ; Device Effective Y Resolution XINCH DW 9000 ; Device X Size in inches*1000 YINCH DW 7000 ; Device Y Size in inches*1000 ASPEC DW 4500 ; Aspect Ratio = (y_size/x_size) * 10000 DB 8h DB 8h ; for compatibility, use these values DB 90h DB 90h STATUS ENDS The BGI interface provides a system for reporting errors to the BGI Kernel and to the higher level code developed using Borland's language packages. This is done using the STAT field of the Driver Status Table. This field should be filled in by the driver code if an error is detected during the execution of the device installation (INSTALL). The following error codes are predefined in include file GRAPHICS.H for Turbo C and in the Graphics unit for Turbo Pascal. grOk = 0 Normal Operation, No errors grNoInitGraph = -1 grNotDetected = -2 grFileNotFound = -3 grInvalidDriver = -4 grNoLoadMem = -5 grNoScanMem = -6 grNoFloodMem = -7 grFontNotFound = -8 grNoFontMem = -9 grInvalidMode = -10 grError = -11 Generic Driver Error grIOerror = -12 grInvalidFont = -13 grInvalidFontNum = -14 grInvalidDeviceNum = -15 The next field in the Device Status Table, DEVTYP, describes the class of the device that the driver controls; for screen devices, this value is always 0. The next four fields, XRES, YRES, XEFRES, and YEFRES contain the number of pixels available to BGI on this device in the horizontal and vertical dimensions, minus one. For screen devices, XRES=XEFRES and YRES=YEFRES. The XINCH and YINCH fields are the number of inches horizontally and vertically into which the device's pixels are mapped, times 1000. These fields in conjunction with XRES and YRES permit device resolution (DPI, or dots per inch) calculation. Horizontal resolution (DPI) = (XRES+1) / (XINCH/1000) Vertical resolution (DPI) = (YRES+1) / (YINCH/1000) The ASPEC (aspect ratio) field is effectively a multiplier/divisor pair (the divisor is always 10000) that is applied to Y coordinate values to produce aspect-ratio adjusted images (e.g., round circles). For example, an ASPEC field of 4500 implies that the application will have to transform Y coordinates by the ratio 4500/10000 when drawing circles to that device if it expects them to be round. Individual monitor variations may require an additional adjustment by the application. The Device Driver Vector Table ============================== The routines in the device driver are accessed via a vector table. This table is at the beginning of the driver and contains 16-bit offsets to subroutines and configuration tables within the driver. The format of the vector table is shown below. VECTOR_TABLE: DW INSTALL ; Driver initialization and installation DW INIT ; Initialize device for output DW CLEAR ; Clear graphics device; get fresh screen DW POST ; Exit from graphics mode, unload plotter, etc DW MOVE ; Move Current Pointer (CP) to (X,Y) DW DRAW ; Draw Line from (CP) to (X,Y) DW VECT ; Draw line from (X0,Y0) to (X1,Y1) DW EMULATE ; Reserved, must contain Emulate vector DW BAR ; Filled 3D bar from (CP) to (X,Y) DW PATBAR ; Patterned rectangle from (X,Y) to (X1,Y1) DW ARC ; Define ARC DW PIESLICE ; Define an elliptical pie slice DW FILLED_ELLIPSE ; Draw a filled ellipse DW PALETTE ; Load a palette entry DW ALLPALETTE ; Load the full palette DW COLOR ; Set current drawing color/background DW FILLSTYLE ; Filling control and style DW LINESTYLE ; Line drawing style control DW TEXTSTYLE ; Hardware Font control DW TEXT ; Hardware Draw text at (CP) DW TEXTSIZ ; Hardware Font size query DW RESERVED ; Reserved DW FLOODFILL ; Fill a bounded region DW GETPIX ; Read a pixel from (X,Y) DW PUTPIX ; Write a pixel to (X,Y) DW BITMAPUTIL ; Bitmap Size query function DW SAVEBITMAP ; BITBLT from screen to system memory DW RESTOREBITMAP ; BITBLT from system memory to screen DW SETCLIP ; Define a clipping rectangle DW COLOR_QUERY ; Color Table Information Query ; ; 35 additional vectors are reserved for Borland's future use. ; DW RESERVED ; Reserved for Borland's use (1) DW RESERVED ; Reserved for Borland's use (2) DW RESERVED ; Reserved for Borland's use (3) . . . DW RESERVED ; Reserved for Borland's use (33) DW RESERVED ; Reserved for Borland's use (34) DW RESERVED ; Reserved for Borland's use (35) ; ; Any vectors following this block may be used by ; independent device driver developers as they see fit. ; Vector Descriptions =================== The following information describes the input, output, and function of each of the functions accessed through the device vector table. DW offset INSTALL ; device driver installation The Kernel calls the INSTALL vector to prepare the device driver for use. A function code is passed in AL. The following function codes are defined: >>> Install Device: AL = 00 Input: CL = Mode Number for device Return: ES:BX --> Device Status Table (see STATUS structure, above) The INSTALL function is intended to inform the driver of the operating parameters that will be used. The device should not be switched to graphics mode (see INIT). On input, CL contains the mode in which the device will operate. (refer to BGI setgraphmode statement) The return value from the Install Device function is a pointer to a Device Status Table (described earlier). >>> Mode Query: AL = 001h Input: Nothing Return: CX The number of modes supported by this device. The MODE QUERY function is used to inquire about the maximum number of modes supported by this device driver. >>> Mode Names: AL = 002h Input: CX The mode number for the query. Return: ES:BX --> a Pascal string containing the name The MODE NAMES function is used to inquire about the ASCII form of the mode number present in CX. The return value in ES:BX points to a Pascal string describing the given mode. (Note: A Pascal, or _length_, string is a string in which the first byte of data is the number of characters in the string, followed by the string data itself.) To ease access to these strings from C, the strings should be followed by a zero byte, although this zero byte should not be included in the string length. The following is an example of this format: NAME: db 16, '1280 x 1024 Mode', 0 ================================================================== DW offset INIT ; Initialize device for output Input: ES:BX --> Device Information Table Return: Nothing This vector is used to change an already INSTALLed device from text mode to graphics mode. This vector should also initialize any default palettes and drawing mode information as required. The input to this vector is a device information table (DIT). The format of the DIT is shown below and contains the background color and an initialization flag. If the device requires additional information at INIT time, these values can be appended to the DIT. There in no return value for this function. If an error occurs during device initialization, the STAT field of the Device Status Table should be loaded with the appropriate error value. ; ************** Device Information Table Definition ************** struct DIT DB 0 ; Background color for initializing screen DB 0 ; Init flag; 0A5h = don't init; anything ; else = init DB 64 dup 0 ; Reserved for Borland's future use ; additional user information here DIT ends ================================================================== DW offset CLEAR ; Clear the graphics device Input: Nothing Return: Nothing This vector is used to clear the graphics device to a known state. In the case of a CRT device, the screen is cleared. In the case of a printer or plotter, the paper is advanced, and pens are returned to the station. ================================================================== DW offset POST ; Exit from graphics mode Input: Nothing Return: Nothing This routine is used to close the graphics system. In the case of graphics screens or printers, the mode should be returned to text mode. For plotters, the paper should be unloaded and the pens should be returned to station. ================================================================== DW offset MOVE ; Move the current drawing pointer Input: AX the new CP x coordinate BX the new CP y coordinate Return: Nothing Sets the Driver's current pointer (CP) to (AX,BX). This function is used prior to any of the TEXT, ARC, SYMBOL, DRAW, FLOODFILL, BAR, or PIESLICE routines to set the position where drawing is to take place. ================================================================== DW offset DRAW ; Draw a line from the (CP) to (X,Y) Input: AX The ending x coordinate for the line BX The ending y coordinate for the line Return: Nothing Draw a line from the CP to (X,Y). The current LINESTYLE setting is used. The current pointer (CP) is updated to the line's endpoint. ================================================================== DW VECT ; Draw line from (X1,Y1) to (X2,Y2) Input: AX X1; The beginning X coordinate for the line BX Y1; The beginning Y coordinate for the line CX X2; The ending X coordinate for the line DX Y2; The ending Y coordinate for the line Return: Nothing Draws a line from the (X1,Y1) to (X2,Y2). The current LINESTYLE setting is used to draw the line. Note: CP is NOT changed by this vector. ================================================================== DW BAR ; fill and outline rectangle (CP),(X,Y) Input: AX X--right edge of rectangle BX Y--bottom edge of rectangle CX 3D = width of 3D bar (ht := .75 * wdt); 0 = no 3D effect DX 3D bar top flag; if CX <> 0, and DX = 0, draw a top Return: Nothing Fills and outlines a bar (rectangle) using the current COLOR, FILLCOLOR, and FILLPATERN. The current pointer defines the upper left corner of the rectangle and (X,Y) is lower right. An optional 3D shadow effect (intended for business graphics programs) is obtained by making CX nonzero. DX then serves as a flag indicating whether a top should be drawn on the bar. ================================================================== DW PATBAR ; fill rectangle (X1,Y1), (X2,Y2) Input: AX X1--the rectangle's left coordinate BX Y1--the rectangle's top coordinate CX X2--the rectangle's right coordinate DX Y2--the rectangle's bottom coordinate Return: Nothing Fill (but don't outline) the indicated rectangle with the current fill pattern and fill color. ================================================================== DW ARC ; Draw an elliptical arc Input: AX The starting angle of the arc in degrees (0-360) BX The ending angle of the arc in degrees (0-360) CX X radius of the elliptical arc DX Y radius of the elliptical arc Return: Nothing ARC draws an elliptical arc using the (CP) as the center point of the arc, from the given start angle to the given end angle. To get circular arcs the application (not the driver) must adjust the Y radius as follows: YRAD := XRAD * (ASPEC / 10000) where ASPEC is the aspect value stored in the DST. ================================================================== DW PIESLICE ; Draw an elliptical pie slice Input: AX The starting angle of the slice in degrees (0-360) BX The ending angle of the slice in degrees (0-360) CX X radius of the elliptical slice DX Y radius of the elliptical slice Return: Nothing PIESLICE draws a filled elliptical pie slice (or wedge) using CP as the center of the slice, from the given start angle to the given end angle. The current FILLPATTERN and FILLCOLOR is used to fill the slice and it is outlined in the current COLOR. To get circular pie slices, the application (not the driver) must adjust the Y radius as follows: YRAD := XRAD * ASPEC / 10000 where ASPEC is the aspect value stored in the driver's DST. ================================================================== DW FILLED_ELLIPSE ; Draw a filled ellipse at (CP) Input: AX X Radius of the ellipse BX Y Radius of the ellipse Return: Nothing This vector is used to draw a filled ellipse. The center point of the ellipse is assumed to be at the current pointer (CP). The AX Register contains the X Radius of the ellipse, and the BX Register contains the Y Radius of the ellipse. ================================================================== DW PALETTE ; Load a color entry into the Palette Input: AX The index number and function code for load BX The color value to load into the palette Return: Nothing The PALETTE vector is used to load single entries into the palette. The register AX contains the function code for the load action and the index of the color table entry to be loaded. The upper two bits of AX determine the action to be taken. The table below tabulates the actions. If the control bits are 00, the color table index in (AX AND 03FFFh) is loaded with the value in BX. If the control bits are 10, the color table index in (AX AND 03FFFh) is loaded with the RGB value in (Red=BX, Green=CX, and Blue=DX). If the control bits are 11, the color table entry for the background is loaded with the value in BX. Control Bits Color Value and Index 00 Register BX contains color, AX is index 01 not used 10 Red=BX Green=CX Blue=DX, AX is index 11 Register BX contains color for background ================================================================== DW ALLPALETTE ; Load the full palette Input: ES:BX --> array of palette entries Return: Nothing The ALLPALETTE routine loads the entire palette in one driver call. The register pair ES:BX points to the table of values to be loaded into the palette. The number of entries is determined by the color entries in the Driver Status Table. The background color is not explicitly loaded with this command. ================================================================== DW COLOR ; Load the current drawing color. Input: AL The index number of the current drawing color AH The index number of the fill color Return: Nothing The COLOR vector is used to determine the current drawing color. The value in AL is the index into the palette of the new current drawing color. The value in the AH register is the color index of the new fill color. All primitives are drawn with the current drawing color until the color is changed. The fill color is used for the interior color for the bar, polygons, pie slice, and floodfill primitives. ================================================================== DW FILLSTYLE ; Set the filling pattern Input: AL Primary fill pattern number ES:BX If the pattern number is 0FFh, this points to user define pattern mask. Return: Nothing Sets the fill pattern for drawing. The fill pattern is used to fill all bounded regions (BAR, POLY, and PIESLICE). The numbers for the predefined fill patterns are as follows: Code Description 8 Byte fill pattern 0 No Fill 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h 1 Solid Fill 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh, 0FFh 2 Line Fill 0FFh, 0FFh, 000h, 000h, 0FFh, 0FFh, 000h, 000h 3 Lt Slash Fill 001h, 002h, 004h, 008h, 010h, 020h, 040h, 080h 4 Slash Fill 0E0h, 0C1h, 083h, 007h, 00Eh, 01Ch, 038h, 070h 5 Backslash Fill 0F0h, 078h, 03Ch, 01Eh, 00Fh, 087h, 0C3h, 0E1h 6 Lt Bkslash Fill 0A5h, 0D2h, 069h, 0B4h, 05Ah, 02Dh, 096h, 04Bh 7 Hatch Fill 0FFh, 088h, 088h, 088h, 0FFh, 088h, 088h, 088h 8 XHatch Fill 081h, 042h, 024h, 018h, 018h, 024h, 042h, 081h 9 Interleave Fill 0CCh, 033h, 0CCh, 033h, 0CCh, 033h, 0CCh, 033h 10 Wide Dot Fill 080h, 000h, 008h, 000h, 080h, 000h, 008h, 000h 11 Close Dot Fill 088h, 000h, 022h, 000h, 088h, 000h, 022h, 000h 0FFh User is defining the pattern of the fill. In the case of a user-defined fill pattern, the register pair ES:BX point to 8 bytes of data arranged as a 8x8 bit pattern to be used for the fill pattern. ================================================================== DW LINESTYLE ; Set the line drawing pattern Input: AL Line pattern number BX User-defined line drawing pattern CX Line width for drawing Return: Nothing Sets the current line-drawing style and the width of the line. The line width is either one pixel or three pixels in width. The following table defines the default line styles: Code Description 16 Bit Pattern AL = 0 Solid Line Style 1111111111111111B AL = 1 Dotted Line 1100110011001100B AL = 2 Center Line 1111110001111000B AL = 3 Dashed line 1111100011111000B AL = 4 User-defined line style If the value in AL is four, the user is defining a line style in the BX register. If the value in AL is not four, then the value in register BX is ignored. ================================================================== DW TEXTSTYLE ; Hardware text style control Input: AL Hardware font number AH Hardware font orientation 0 = Normal, 1 = 90 Degree, 2 = Down BX Desired X Character (size in graphics units) CX Desired Y Character (size in graphics units) Return: BX Closest X Character size available (in graphics units) CX Closest Y Character size available (in graphics units) The TEXTSTYLE vector is used to define the attributes of the hardware font for output. The parameters affected are the hardware font to be used, the orientation of the font for output, the desired height and width of the font output. All subsequent text will be drawn using these attributes. If the desired size is not supported by the current device, the closest available match to the desired size should be used. The return value from this function gives the dimensions of the font (in pixels) that will actually be used. For example, if the desired font is 8x10 pixels and the device supports 8x8 and 16x16 fonts, the closest match will be the 8x8. The output of the function will be BX = 8, and CX = 8. ================================================================== DW TEXT ; Hardware text output at (CP) Input: ES:BX --> ASCII text of the string CX The length (in characters) of the string. This function is used to send hardware text to the output device. The text is output to the device beginning at the (CP). The (CP) is assumed to be at the upper left of the string. ================================================================== DW TEXTSIZ ; Determine the height and width of text ; strings in graphics units. Input: ES:BX --> ASCII text of the string CX The length (in characters) of the string. Return: BX The width of the string in graphics units. CX The height of the string in graphics units. This function is used to determine the actual physical length and width of a text string. The current text attributes (set by TEXTSTYLE) are used to determine the actual dimensions of a string without displaying it. The application can thereby determine how a specific string will fit and reduce or increase the font size as required. There is NO graphics output for this vector. If an error occurs during length calculation, the STAT field of the Device Status Record should be marked with the device error code. ================================================================== DW FLOODFILL ; Fill a bounded region using a flood fill Input: AX The x coordinate for the seed point BX The y coordinate for the seed point CL The boundary color for the Flood Fill Return: Nothing (Errors are returned in Device Status STAT field). This function is called to fill a bounded region on bitmap devices. The (X,Y) input coordinate is used as the seed point for the flood fill. (CP) becomes the seed point. The current FILLPATTERN is used to flood the region. ================================================================== DW GETPIXEL ; Read a pixel from the graphics screen Input: AX The x coordinate for the seed point BX The y coordinate for the seed point Return: DL The color index of the pixel read from the screen. GETPIXEL reads the color index value of a single pixel from the graphics screen. The color index value is returned in the DL register. ================================================================== DW PUTPIXEL ; Write a pixel to the graphics screen Input: AX The x coordinate for the seed point BX The y coordinate for the seed point DL The color index of the pixel read from the screen. Return: Nothing PUTPIXEL writes a single pixel with the the color index value contained in the DL register. ================================================================== DW BITMAPUTIL ; Bitmap Utilities Function Table Input: Nothing Return: ES:BX --> BitMap Utility Table. The BITMAPUTIL vector loads a pointer into ES:BX, which is the base of a table defining special case-entry points used for pixel manipulation. These functions are currently only called by the ellipse emulation routines that are in the BGI Kernel. If the device driver does not use emulation for ellipses, this entry does not need to be implemented. This entry was provided because some hardware requires additional commands to enter and exit pixel mode, thus adding overhead to the GETPIXEL and SETPIXEL vectors. This overhead affected the drawing speed of the ellipse emulation routines. These entry points are provided so that the ellipse emulation routines can enter pixel mode, and remain in pixel mode for the duration of the ellipse- rendering process. The format of the BITMAPUTIL table is as follows: DW offset GOTOGRAPHIC ; Enter pixel mode on the graphics hardware DW offset EXITGRAPHIC ; Leave pixel mode on the graphics hardware DW offset PUTPIXEL ; Write a pixel to the graphics hardware DW offset GETPIXEL ; Read a pixel from the graphics hardware DW offset GETPIXBYTE ; Return a word containing the pixel depth DW offset SET_DRAW_PAGE ; Select page in which to draw primitives DW offset SET_VISUAL_PAGE ; Set the page to be displayed DW offset SET_WRITE_MODE ; XOR Line Drawing Control The parameters of these functions are as follows: GOTOGRAPHIC ; Enter pixel mode on the graphics hardware This function is used to enter the special Pixel Graphics mode. EXITGRAPHIC ; Leave pixel mode on the graphics hardware This function is used to leave the special Pixel Graphics mode. PUTPIXEL ; Write a pixel to the graphics hardware This function has the same format as the PUTPIXEL entry described above. GETPIXEL ; Read a pixel from the graphics hardware This function has the same format as the GETPIXEL entry described above. GETPIXBYTE ; Return a word containing the pixel depth This function returns the number of bits per pixel (color depth) of the graphics hardware in the AX register. SET_DRAW_PAGE ; Select alternate output graphics pages (if any) This function take the desired page number in the AL register and selects alternate graphics pages for output of graphics primitives. SET_VISUAL_PAGE ; Select the visible alternate graphics pages (if any) This function take the desired page number in the AL register and selects alternate graphics for displaying on the screen. SET_WRITE_MODE ; XOR Line drawing mode control. XOR Mode is selected if the value in AX is one, and disabled if the value in AX is zero. ================================================================== DW SAVEBITMAP ; Write from screen memory to system memory Input: ES:BX Points to the buffer in system memory to be written. ES:[BX] contains the width of the rectangle -1. ES:[BX+2] contains the heigth of the rectangle -1. CX The upper left X coordinate of the rectangle. DX The upper left Y coordinate of the rectangle. Return: Nothing The SAVEBITMAP routine is a block copy routine that copies screen pixels from a defined rectangle as specified by (SI,DI) - (CX,DX) to the system memory. ================================================================== DW RESTOREBITMAP ; Write screen memory to the screen. Input: ES:BX Points to the buffer in system memory to be read. ES:[BX] contains the width of the rectangle -1. ES:[BX+2] contains the heigth of the rectangle -1. CX The upper left X coordinate of the rectangle. DX The upper left Y coordinate of the rectangle. AL The pixel operation to use when transferring the image into graphics memory. Write mode for block writing. 0: Overwrite mode 1: XOR mode 2: OR mode 3: AND mode 4: Complement mode Return: Nothing The RESTOREBITMAP vector is used to load screen pixels from the system memory. The routine reads a stream of bytes from the system memory into the rectangle defined by (SI,DI) - (CX,DX). The value in the AL register defines the mode that is used for the write. The following table defines the values of the available write modes: Pixel Operation Code Overwrite mode 0 Logical XOR 1 Logical OR 2 Logical AND 3 Complement 4 ================================================================== DW SETCLIP ; Define a clipping rectangle Input: AX Upper Left X coordinate of clipping rectangle BX Upper Left Y coordinate of clipping rectangle CX Lower Right X coordinate of clipping rectangle DX Lower Right Y coordinate of clipping rectangle Return: Nothing The SETCLIP vector defines a rectangular clipping region on the screen. The registers (AX,BX) - (CX,DX) define the clipping region. ================================================================== DW offset COLOR_QUERY ; Device Color Information Query This vector is used to inquire about the color capabilities of a given piece of hardware. A function code is passed into the driver in AL. The following function codes are defined: >>> Color Table Size AL = 000h Input: None: Return: BX The size of the color lookup table. CX The maximum color number allowed. The COLOR TABLE SIZE query is used to determine the maximum number of colors supported by the hardware. The value returned in the BX register is the number of color entries in the color lookup table. The value returned in the CX register is the highest number for a color value. This value is usually the value in BX minus one; however, there can be exceptions. >>> Default Color Table AL = 001h Input: Nothing Return: ES:BX --> default color table for the device The DEFAULT COLOR TABLE function is used to determine the color table values for the default (power-up) color table. The format of this table is a byte containing the number of valid entries, followed by the given number of bytes of color information. Device Driver Construction Particulars ====================================== The source code for a sample, albeit unusual, BGI device driver is included with this Toolkit to assist developers in creating their own. The demonstration driver is provided in two files, DEBVECT.ASM and DEBUG.C. This "Debug" driver doesn't actually draw graphics, but instead simply sends descriptive messages to the console screen (via DOS function call 9) upon receiving commands. Instead of simply playing back commands, your own driver would be structured similarly, but would access control ports and screen memory to perform each function. Cookbook ======== 1. Compile or assemble the files required. 2. Link the files together, making sure that the device vector table is the first module within the link. 3. Run EXETOBIN on the resulting .EXE or .COM file to produce a .BIN file. There should be no relocation fixups required. 4. Run program BH (provided with the toolkit) on the .BIN file to produce the .BGI file. The resulting driver is now ready for testing. Examine the file TEST.C for an example of installing, loading, and calling a newly-created device driver. Examples ; To call any BGI function from assembly language, include the ; structure below and use the CALLBGI macro. CALLBGI MACRO P MOV SI,$&P ; PUT OPCODE IN (SI) CALL CS:DWORD PTR BGI_ADD ; BGI_ADD POINTS TO DRIVER ENDM ; e.g., to draw a line from (10,15) to (200,300): MOV AX, 10 MOV BX, 15 MOV CX, 200 MOV DX, 300 CALLBGI VECT ; To index any item in the status table, include the status table ; structures below and use the BGISTAT macro. BGISTAT MACRO P ; GET ES: --> BGI STATUS LES SI, CS:DWORD PTR STABLE ; GET LOCATION OF STATUS TO SI ADD SI, $&P ; OFFSET TO CORRECT LOCATION ENDM ; e.g., to obtain the aspect ratio of a device: BGISTAT ASPEC MOV AX, ES:[SI] ; (AX)= Y/X *10000