Font
Changes the font of the text mode 8x14 character set. ** Only works on an EGA or better card **
*Description
Changes the font of the text mode 8x14 character set
** Only works on an EGA or better card **
*Programming description
Use the BIOS video interrupt service 11h, subservice 00h
put offset of your bit pattern in es:bp
put in cx, the number of chars to change
put in dx, the starting ascii number to change
put in bh, the amount of bytes per char in your bitmap pattern
Assemble with NBASM
.MODEL tiny
.code
push ds ;
pop es ; make sure ES = DS
mov bp,offset OurFont ;
mov cx,02 ; we'll change just 2 of them
mov dx,65 ; A and B --> our A and B
mov bh,14 ; 14 bytes per char
xor bl,bl ; RAM block
mov ax,1100h ; change font to our font
int 10h ; video interrupt
mov ax,4C00h ; exit to DOS
int 21h ;
OurFont db 00000000b
db 01111111b
db 01100011b
db 01100011b
db 01100011b
db 01111111b
db 01100011b
db 01100011b
db 01100011b
db 01100011b
db 01100011b
db 01100011b
db 00000000b
db 00000000b
db 00000000b
db 01111110b
db 01100110b
db 01100110b
db 01100110b
db 01111111b
db 01100011b
db 01100011b
db 01100011b
db 01100011b
db 01100011b
db 01111111b
db 00000000b
db 00000000b
.end ; End of assembly code
Get the same routine in C from here (2k)
Get the same routine in Pascal from here (3k)
To retrieve the bitmaps of the current character sets used by BIOS you can look at the following memory positions:
If you are in CGA graphics modes 06h (640x200x2) or 04h (320x200x4) (X x Y x bpp) the BIOS keeps the bitmap of the second half of the character set (128 - 255) at the position pointed to by Interrupt Vector 1Fh, which is address 0000:007Ch. The address in this memory position is the address of the character set 8x8 starting with ascii 128.
The EGA+ BIOS will allow you to get the bitmap addresses of the whole character set for 8 different character sets, which include the 8x14 character set mentioned in the above program.
If we use INT 10h, service 11h, sub-service 30h, and tell the BIOS to return the address of the 8x14 character set, we would do the following:
mov ax,1130h ; service 11h, sub-service 30h
mov bh,02h ; BIOS 8x14 character set
int 10h
On return, ES:BP will contain the segment address of the first char in the set (ascii 0).
Since we have the EGA+ BIOS, we can get the contents of the CGA char set mentioned above if we put 01h in BH. (This service does the same thing as getting the address at INT VECT 1Fh, were the CGA BIOS doesn't have this sub-service.)
The following code shows you how to have two different character sets on a DOS text screen at one time.
The example displays regular text and underlined text at the same time.
The code is not very well documented, but maybe with time, I will get back to it.
; Assemble with NBASM
.model tiny
.code
.186
mov ax,0003h ; set screen mode to normal
int 10h ; (80x25) text
mov bh,02h ; get font table information
mov ax,1130h ;
int 10h ;
push es ; make ds=es
pop ds ;
mov si,bp ; make ds:si = offset font table
push cs
pop es
mov di,offset buffer ; make es:di = offset our buffer
mov cx,256 ; 256 chars
LoopIt: movsw
movsw
movsw
movsw ; *** on VGA's we need 16 bytes per char
movsw ; *** if we are on an EGA, delete one of
movsw ; *** the movsw's
lodsw
mov ah,0FFFFh ; make the last one underlined
stosw
movsw
loop LoopIt ; loop 256 chars
; set our new character font
mov bp,offset buffer ; es:bp = offset buffer
xor dx,dx ; start with 0
mov cx,256 ; 256 chars
mov bh,16 ; 16 bytes each char (VGA) (EGA =14)
mov bl,01 ; 'block' 1
mov ax,1100h ; do it
int 10h ;
; select our new character set
mov bx,0100h
mov cx,bx
shl bh,2
or bl,bh
mov ax,1103h
int 10h
mov bx,0F12h
cmp cl,ch
jz short here
mov bh,07h
here: mov ax,1000h ; update registers
int 10h
mov ah,0Fh ; get video page
int 10h
mov ah,03h ; get cursor pos
int 10h
mov bp,offset string1 ; print string with attrb
mov cx,13
mov bl,07
mov ax,1301h
int 10h
mov ah,03 ; get cursor pos
int 10h
mov bp,offset string2 ; print string with attrb
mov cx,17
mov bl,0Fh
mov ax,1301h
int 10h
xor ah,ah ; wait for key press
int 16h
mov ax,0003h ; reset screen mode to normal
int 10h
.exit
string1 db 'Normal Text',0Dh,0Ah
string2 db 'Underlined Text',0Dh,0Ah
buffer:
.end