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