Manipulating the BIOS Font

Adok/Hugi

Recently Nucleon has asked in de.comp.lang.assembler.x86 how to manipulate the BIOS font in order to create new characters in text mode. Since this can be interesting to other beginners, too, I decided to write a short article about it.

First let's clear how the characters are stored in the BIOS RAM.

The BIOS font has either the width 8 or 9 and the height 8, 14, or 16. In the usual text mode, mode 3, this height is 16.

For each line in a single character, the matrix is therefore stored in one byte for the charsets with a width of 8 pixels. For example, the character Z of the font with a height of 16 pixel is stored as:

                    binary value            displayed matrix

                      11111110b                  ллллллл
                      11000110b                  лл   лл
                      00001100b                      лл
                      00011000b        ==>          лл
                      00110010b                    лл  л
                      01100110b                   лл  лл
                      11111110b                  ллллллл
                      00000000b

Concerning the charsets with a width of 9 pixels, only the first 8 pixels per line are stored. The 9th pixel corresponds with the lowest (rightmost) bit. Therefore we don't have to care whether we are working with an 8xXX or 9xXX font because it's the same.

In the BIOS font RAM, all ASCII characters are stored after another, i.e first ASCII 0, then ASCII 1,... till ASCII 255.

So, how do we manipulate the font? It's simple! First we have to store our customized font or the customized characters somewhere in the memory like the characters in the BIOS font are stored. Then we only have to call Interrupt 10h function 11h sub-function 0. Parameters:

         AX = 1100h (function 11h, sub-function 0)
         BH = height of the font (e.g. 16)
         BL = memory block in the BIOS font RAM (active font = 0)
         ES = segment that contains your own characters/font
         BP = offset of your own characters/font
         DX = first character that should be manipulated (whole font: 0)
         CX = number of characters that should be manipulated (whole font: 256)

So, if the variable fntheight contains the height of your font and the modified font starts at the label fntram, you could activate your font in the following way:

         mov bh,fntheight
         xor bl,bl
         mov ax,seg fntram
         mov es,ax
         mov bp,offset fntram
         mov cx,256
         xor dx,dx
         mov ax,1100h
         int 10h

That's all. If you encounter any problems check out the example programs.

- adok^hugi