Microsoft KB Archive/60854

Calling MASM to Create a User-Defined Character Font

PSS ID Number: Q60854 Article last modified on 05-01-1990

3.00 3.00a MS-DOS

Summary: The EGA and VGA video cards can use a different character set than the default one stored in their ROM. An interrupt can be called to tell the card to look at a specific area in RAM, rather than its own ROM, to get the definitions for its character set. This interrupt cannot be called directly from COBOL because it requires the modification of the ES and BP registers; COBOL can only change AX, BX, CX, and DX. However, COBOL can call an assembly language routine that calls the interrupt. When the default ROM font is to be used again, COBOL can call another interrupt to do this. This interrupt only requires the AX and BX registers to be modified, so it can be called directly from COBOL. This information applies to Microsoft COBOL Compiler Versions 3.00 and 3.00a for MS-DOS. For more information on calling interrupts from COBOL, see Pages 8-4 and 8-5 of the “Microsoft COBOL Compiler 3.0: Operating Guide.” For more information on calling assembly language routines, query on the word COB2MASM. For more information on Interrupt 10 Hex, Function 11 Hex as it pertains to this article, see Pages 518 to 520 in “Advanced MS-DOS Programming, 2nd Edition” by Ray Duncan (Microsoft Press, 1988).

More Information: The interrupt that causes the video card to use a font defined in RAM is Interrupt 10 Hex, Function 11 Hex, Subfunction 00 Hex. Before calling the interrupt, the following registers must be set up: AH (high byte of AX) = function number (11H) AL (low byte of AX) = subfunction number (00H) BH (high byte of BX) = bytes per character (16 for VGA, 14 for EGA) BL (low byte of BX) = block (0) CX = number of characters to redefine DX = starting ASCII code to redefine ES:BP = segment:offset of font table For example, if you wanted to redefine ASCII 88 to 90, 88 would be stored in DX, the first character in the sequence, and 3 would be stored in CX because three total characters are being redefined. Any characters you do not redefine will use the default ROM definition. The ES and BP registers will hold the segment and offset, respectively, of the data structure that contains the character definitions you pass to the assembly language routine. This structure is called the “font table.” The most convenient way to store a character definition is with a table of type PIC 99 COMP-X. The table would be as many bytes long as the character definition, 16 for VGA and 14 for EGA. A different table could be used for each character definition, the tables themselves being elements of a group item. It is the far address of this group item (the font table) that the interrupt will use. Interrupt 10 Hex, Function 11 Hex, Subfunction 04 Hex for VGA (or 01 Hex for EGA) switches the card back to using the ROM font. Before the interrupt is called, the following registers must be set up: AH (high byte of AX) = function number (11H) AL (low byte of AX) = subfunction number (04H for VGA, 01H for EGA) BL (low byte of BX) = block (0) The following program (USERFONT.CBL) illustrates how to use user-defined text fonts with COBOL. It redefines ASCII 88, 89, and 90, which by default are the characters “X,” “Y,” and “Z.” USERFONT.CBL does this by calling an assembly language routine (LOADFONT.ASM) and passing to it the far address of the font table, which is a group item containing three PIC 99 COMP-X tables. After viewing the changed characters, the program switches the video card back to the ROM character definitions.

USERFONT.CBL
$SET LITLINK $SET ANS85 * This program will only run in 25-line mode IDENTIFICATION DIVISION. PROGRAM-ID. USERFONT.CBL DATA DIVISION. WORKING-STORAGE SECTION. *  This group item consists of the three tables that hold the *  three character definitions. For EGA, change the length *  of the tables to 14 bytes. 01 FONT-TABLE. *     This table defines a solid, rectangular character 05 ASCII-88  PIC 99 COMP-X OCCURS 16 TIMES VALUE 255. *     This table defines a thinner, rectangular character 05 ASCII-89  PIC 99 COMP-X OCCURS 16 TIMES VALUE 15. *     This table defines a single line in the middle 05 ASCII-90  PIC 99 COMP-X OCCURS 16 TIMES VALUE 8. *  Specifies interrupt 10H 01 INTERRUPT    PIC X VALUE X&quot;10&quot;. *  Loads registers with CALL X&quot;84&quot; parameters 01 FLAG         PIC X VALUE X&quot;FF&quot;. 01 AX. *     Specifies function 11H 05 A-H       PIC X VALUE X&quot;11&quot;. *     Specifies subfunction 04H, change to X&quot;01&quot; for EGA 05 A-L       PIC X VALUE X&quot;04&quot;. 01 BX. 05 B-H       PIC X.  *   Specifies block 0 05 B-L       PIC X VALUE X&quot;00&quot;. 01 CX. 05 C-H       PIC X.      05 C-L        PIC X.   01 DX. 05 D-H       PIC X.      05 D-L        PIC X.   01 A-KEY         PIC 99 COMP-X. PROCEDURE DIVISION. *   Clear the screen CALL X&quot;E4&quot;. DISPLAY &quot;X     Y      Z&quot; AT LINE 11 COLUMN 32. DISPLAY &quot;Hit 'c' to change font&quot; AT LINE 13 COLUMN 30. *   Poll keyboard until 'c' is hit PERFORM UNTIL A-KEY = 99 CALL X&quot;83&quot; USING A-KEY END-PERFORM. *   Call assembly language routine. ASCII 88, 89, 90 will be *    changed to the definitions contained in FONT-TABLE CALL &quot;LOADFONT&quot; USING FONT-TABLE. DISPLAY &quot;Hit 'b' to change font back&quot; AT LINE 13 COLUMN 30. *   Poll keyboard until 'b' is hit PERFORM UNTIL A-KEY = 98 CALL X&quot;83&quot; USING A-KEY END-PERFORM. *   Call interrupt to bring the ROM font back. ASCII 88, 89, *   and 90 will be changed back to &quot;X&quot;, &quot;Y&quot;, and &quot;Z&quot; CALL X&quot;84&quot; USING INTERRUPT, FLAG, AX, BX, CX, DX. STOP RUN. The following is the assembly language routine that calls the Interrupt 10 Hex, Function 11 Hex, Subfunction 00 Hex: .MODEL LARGE .CODE PUBLIC LOADFONT LOADFONT PROC PUSH BP MOV BP, SP ;Make BP the frame pointer MOV AX, 1100H ;Set function and subfunction number MOV BX, 1000H ;Set bytes per character and block, ;for EGA use 0E00H MOV CX, 3 ;Set number of characters to redefine MOV DX, 88 ;Set first ASCII character to redefine MOV ES, [BP+8] ;Set segment address of font table MOV BP, [BP+6] ;Set offset address of font table INT 10H ;Call the interrupt POP BP ;Restore registers RET 4 ;Take 4 bytes (table address) off stack LOADFONT ENDP END To compile the COBOL program, enter the following: COBOL USERFONT; To assemble the MASM routine, enter the following: MASM LOADFONT; To link the two together, enter the following: LINK USERFONT LOADFONT;

Copyright Microsoft Corporation 1990.