INT 10h is the BIOS's video service. On the first PCs it lived in the system BIOS and knew the monochrome (MDA) and CGA cards; an EGA or VGA card brings its own ROM at segment C000h, which takes over the vector at boot and adds the functions from 10h up: palettes, fonts, information about the card. A program puts the function number in AH and the arguments in other registers and executes INT 10h. The same call works whatever card is fitted, which was the whole point.
Registers a function does not return are normally kept, but not every BIOS was careful: some early ones destroy BP in the scroll functions, and a few change AX even where nothing is returned. Do not keep a value across the call in a register you cannot easily reload, or push it first.
Text modes and graphics modes
In a text mode the card stores characters, not pixels. Each cell of the screen is two bytes of video memory, the character code and its attribute (its colours), and the card draws the glyph from a font as it scans the screen; 80 × 25 cells take 4000 bytes. In a graphics mode every pixel is stored, as 1, 2, 4 or 8 bits, and text is something the BIOS draws dot by dot from its font. DOS and its command line run in a text mode, normally mode 03h.
Common modes
| Mode | Kind | Size | Colours | Memory | Card |
|---|---|---|---|---|---|
| 00h | text | 40×25 | 16 (grey on a CGA) | B800h | CGA |
| 01h | text | 40×25 | 16 | B800h | CGA |
| 02h | text | 80×25 | 16 (grey on a CGA) | B800h | CGA |
| 03h | text | 80×25 | 16 | B800h | CGA; the usual DOS mode |
| 04h | graphics | 320×200 | 4 | B800h | CGA |
| 05h | graphics | 320×200 | 4 (grey) | B800h | CGA |
| 06h | graphics | 640×200 | 2 | B800h | CGA |
| 07h | text | 80×25 | mono | B000h | MDA, Hercules |
| 0Dh | graphics | 320×200 | 16 | A000h | EGA |
| 0Eh | graphics | 640×200 | 16 | A000h | EGA |
| 0Fh | graphics | 640×350 | mono | A000h | EGA |
| 10h | graphics | 640×350 | 16 | A000h | EGA |
| 11h | graphics | 640×480 | 2 | A000h | VGA, MCGA |
| 12h | graphics | 640×480 | 16 | A000h | VGA |
| 13h | graphics | 320×200 | 256 | A000h | VGA, MCGA |
Modes 08h–0Ah belonged to the PCjr, and 0Bh and 0Ch were used internally by the EGA BIOS; nothing sets them on an EGA or VGA. A VGA can show every mode in the table. Higher resolutions are VESA modes, reached through INT 10h as well, with AH = 4Fh. DOSBox-X emulates an S3 SVGA card by default, so all of them work there.
The attribute byte
In the colour text modes the second byte of a cell holds its colours: bits 0–3 the foreground, bits 4–6 the background, bit 7 blink. So an attribute is background × 16 + foreground: 07h is the usual light grey on black, 1Fh white on blue, 4Eh yellow on red. A blinking character flashes; INT 10h AH=10h with AL = 03h trades the blink bit for eight more background colours, which most full-screen programs of the time preferred.
| Value | Colour | Value | Colour |
|---|---|---|---|
| 0 | black | 8 | dark grey |
| 1 | blue | 9 | light blue |
| 2 | green | Ah | light green |
| 3 | cyan | Bh | light cyan |
| 4 | red | Ch | light red |
| 5 | magenta | Dh | light magenta |
| 6 | brown | Eh | yellow |
| 7 | light grey | Fh | white |
On a monochrome card in mode 07h the same byte means normal (07h), underlined (01h), bright (0Fh), reverse (70h) or invisible (00h), and bit 7 still blinks.
Pages
Video memory is larger than one screen. In mode 03h an EGA or VGA holds eight pages of 4096 bytes (4000 of them used): page n starts at B800h:n × 1000h, and the card shows one of them, the active page, chosen with INT 10h AH=05h. Every page has its own cursor, and the services that write characters take a page number in BH, so a program can prepare a page out of sight and then flip to it.
The BIOS keeps its state in the BIOS data area at segment 40h, and programs may read it: the mode at 40h:49h, the columns at 40h:4Ah, the page size at 40h:4Ch, the cursor positions of the eight pages from 40h:50h (a word each, column in the low byte), the cursor shape at 40h:60h, the active page at 40h:62h and, on the EGA and later, the number of rows minus one at 40h:84h.
Where video memory lives
Colour text is at segment B800h, monochrome text at B000h, EGA and VGA graphics at A000h. In 80×25 text the cell at row r, column c is at offset (r × 80 + c) × 2: the character at the even offset, the attribute right after it. Mode 13h is the easy graphics mode: one byte per pixel, 320 bytes per line, so the pixel at x, y is at offset y × 320 + x. The 16-colour EGA and VGA modes spread each pixel over four bit planes behind the same addresses and are programmed through the card's registers, and the CGA modes keep the even lines at offset 0 and the odd ones from 2000h.
BIOS or video memory?
The BIOS is portable and simple and takes care of the cursor and scrolling, but every character or pixel is a call, and for pixels that is very slow. Writing to video memory with MOV or STOSW is many times faster, and it is what games and full-screen editors did; the price is that the program must know the mode and its layout, and no cursor moves. A common mix is to set the mode and the cursor through the BIOS and write the contents directly. Here a word goes straight into B800h, on the row where the cursor is:
MOV AH, 03h ; BIOS: where is the cursor? DH = rowMOV BH, 0 ; page 0INT 10hMOV AL, 160 ; 80 cells of 2 bytes per rowMUL DH ; AX = row * 160ADD AX, 60 * 2 ; column 60MOV DI, AXMOV AX, 0B800h ; colour text memoryMOV ES, AXMOV SI, OFFSET TXT1MOV AH, 1Eh ; attribute: yellow on blueCLDNEXT1:LODSB ; AL = next characterOR AL, AL ; 0 ends the textJZ DONE1STOSW ; the character, then the attributeJMP NEXT1DONE1:MOV AH, 09hMOV DX, OFFSET MSG1 ; DOS prints on the same rowINT 21hTXT1 DB "B800h", 0MSG1 DB "Direct to video memory ->", 13, 10, "$"
A program that writes video memory directly should first check the mode with INT 10h AH=0Fh: B000h in mode 07h, B800h in the other text modes, and the active page's offset if it is not page 0. In mode 13h one pixel is one byte:
MOV AX, 0A000h ; mode 13h: a byte per pixel at A000hMOV ES, AXMOV DI, 100 * 320 + 160 ; x = 160, y = 100: the middleMOV BYTE PTR ES:[DI], 4 ; colour 4, red
DOS and the BIOS
DOS writes its console output through the video BIOS, so INT 21h AH=09h text appears at the BIOS cursor and in the current mode, and BIOS and DOS output mix freely on one screen. In the workbench only DOS output is copied to the terminal: anything written with INT 10h or straight into video memory shows only on the DOS screen. DOSBox-X's built-in DOS calls its video routines internally rather than through the vector, so a program that hooks INT 10h does not see DOS's own output there, as it would on a real PC.