AVIO text is used by GRE to draw characters in DOS or OS/2 window sessions. The S3 driver implements this functionality with eddv_CharStr (in EDDVCSTR.C), eddv_CharRect (in EDDVCREC.C), eddv_ScrollRect (in EDDVSREC.C), and eddv_UpdateCursor (in EDDVUPDC.C). The four basic functions that comprise AVIO text are: drawing a string of characters at a location in the window, drawing a rectangle of characters, scrolling a rectangle, and displaying a text cursor in the window.
In addition to the cursor, the fundamental operation employed in AVIO text is drawing a rectangle of characters. The GRE passes the AVIO functions to a string of characters and attributes, and a rectangle that describes the shape that those characters are to be drawn into. For instance, the string "The Quick Brown Fox" could be rendered as:
The Quick Brown Fox or: T h e Q u i c k B r o w n F o x or even: The Qui ck Brow n Fox
This approach allows portions of the DOS or OS/2 window session to be refreshed efficiently, even if they are partially occluded by other windows. The presentation display driver has to support both horizontal strings of characters and rectangular blocks of characters. The S3 driver calls the same functions to actually render the characters in either case. These functions are CGATextBlock and MFITextBlock. The following is the calling hierarchy for eddv_CharString and eddv_CharRect:
eddv_CharString (eddvcstr.c) CheckAVIOFontsCached (eddvsubr.c) if cell_size == 2 CGAText else MFIText eddv_CharRect (eddvcrec.c) CheckAVIOFontsCached (eddvsubr.c) if cell_size == 2 CGAText else MFIText CGAText (eddvsubr.c) update_cache_char_rect2 (eddhavio.asm) CGATextBlock (eddhavio.asm) MFIText (eddvsubr.c) update_cache_char_rect4 (eddhavio.asm) MFITextBlock (eddhavio.asm)
There are similarities in the actual source for eddv_CharRect and eddv_CharString. The eddv_CharString function is a special case of eddv_CharRect. AVIO fonts are cached in off-screen VRAM in the S3 driver. CheckAVIOFontsCached, update_cache_char_rect2, and update_cache_char_rect4 call the same code in the EDDNCACH.C as does eddt_CharStringPos. When fonts are cached correctly for the presentation desktop text, they will also be cached correctly for AVIO.
CGAText and MFIText ensures the font is cached, and then makes a call to either CGATextBlock or MFITextBlock. These latter two routines perform the work. CGATextBlock handles text that is formatted as two-byte character, attribute pairs, which is exactly how color text is stored on a real CGA. The CGA stored text is one-byte of attribute (foreground and background color) and a one-byte character. (MFI, Main Frame Interactive, is used to support main frame terminal emulation.) MFI Text uses four-byte characters, and includes extended attributes such as underlined characters, and inverse video. Otherwise, MFITextBlock and CGATextBlock are similar to each other.
CGATextBlock takes two arguments, a pointer to a FONTDETAILS structure, and a pointer to an AVIOINFO structure, which is taken from the device context. In addition, CGATextBlock takes parameters from the AIxfer block, and even a few things from the Scatch Pad (Spad). The AVIOINFO structure holds two useful pieces of information: the X and Y starting coordinates of the window and the size of each character cell. Many of the other parameters are given in units of character cells. The AIxfer block holds several useful pieces of information. AIxfer.bRow and AIxfer.bColumn are the starting row and column for this operation. Multiplying them by pAvioInfo.bCellHeight and pAvioInfo.bCellWidth and adding in pAvioInfo.sXoffset and pAvioInfo.sYoffset yields the starting location for the first character on the screen. AIxfer.bDown is the height of the character rectangle, in characters. AIxfer.bAcross is the width of the character rectangle in units of character cells.
Changing CGATextBlock results in the upper and lower 16-bits of various registers that are used to hold different loop counters. The code uses a macro called swap when it needs to access something in the high-order 16-bits of a register. As new code is added, a register can easily be locked up if it is set up and used a distance away from the new code. The high 16-bits of the "ecx" registers hold the count of clipping rectangles that must be iterated through. Register cl holds AIxfer.bDown. Register ch holds AIxfer.bAcross. Later in the code, the "ecx" register is pushed on the stack, and cx holds the current character and attribute pair. The "ebx" register holds a pointer to the string of attributes and characters, and is also pushed onto the stack and then holds the code-point (which is an index into the cache structures so the characters' location in the VRAM cache can be obtained). The "eax" register holds the base address of the glyph definition, and after being pushed, as a repeat count. (CGATextBlock detects multiple copies of the same character, and performs less setup on subsequent renderings of the character. Much of what is drawn into an AVIO window is space characters.) The usage of registers changes depending on where you are located in the code. Locating these changes is probably the single most difficult aspect of changing this code. The actual operation being performed is a monochrome-expansion BitBlt. Often, it is difficult to determine which registers are actually available for use.
CGATextBlock performs clipping a bit differently. Unlike eddh_DrawText, it uses the 8514/A scissoring registers. (In fact, few of the hardware-dependent routines in the S3 driver use the hardware scissoring registers.)
AVIOScroll, also in EDDHAVIO.ASM, is used as part of the process of scrolling an AVIO window. It is a simple screen-to-screen hardware BitBlt. AVIOCursor, in the same file, draws a solid block on the display using whatever colors and raster operations have been set up in the TransferShadowRegisters structure.