You are on page 1of 7

Hardware Operations

Address Line 20

A real-mode program can address up to 1MB+64KB. The 8086 processor can not go beyond 1MB so
a wrap around is done for addresses that exceed 1MB. Programs designed for the 8086 processor
always expect this wraparound. To maintain backward compatibility with 8086 programs, the
processor disables addresses above 1MB to emulate the 8086 processor. In-order to use memory
above 1MB, the 21st memory address line (which is address line 20 or A20 for short) has to be
enabled.

Testing A20

When A20 is disabled, the processor wraps addresses above 1MB. In other words, access to address
100000h is the same as access to address 0. To test the A20, a value is written to memory location 0
and a different value is written at address 100000h. If the value at location 0 and the value at address
100000h are the same, then A20 is disabled.

Enabling A20

There are different ways of enabling A20 and these depend on the computer. Following are the most
common operations of enabling A20 cooked up in one procedure:

call TestA20
jnz ea20Done
in al,92h
or al,2
out 92h,al
call TestA20
jnz ea20Done
call KBWriteWait
mov al,0D0h
out 64h,al
call KBReadWait
in al,60h
mov dl,al
call KBWriteWait
mov al,0D1h
out 64h,al
call KBWriteWait
mov al,dl
or al,2
out 60h,al
call TestA20
jnz ea20Done
call KBWriteWait
mov al,0D1h
out 64h,al
call KBWriteWait
mov al,0DFh
out 64h,al
call TestA20
call KBWriteWait
ea20Done:
RET

TestA20:
push ds
pushf
cli
mov ax,Linear
mov ds,ax
mov bx,1325h
mov eax,100000h
xor ecx,ecx
xchg bl,[ecx]
xchg bh,[eax]
popf
cmp byte [ecx],13h
xchg bh,[eax]
xchg bl,[ecx]
pop ds
ret

KBWriteWait:
push ecx
mov ecx,6000h
kbwwLoop:
in al,64h
test al,2
jz kbwwDone
dec ecx
jnz kbwwLoop
inc ecx
kbwwDone:
pop ecx
ret

KBReadWait:
push ecx
mov ecx,6000h
kbrwLoop:
in al,64h
test al,1
jz kbrwDone
dec ecx
jnz kbrwLoop
inc ecx
kbrwDone:
pop ecx
ret

Resetting The Processor

The common way of resetting the processor is transfering control to address 0FFFF0h, which is
0FFFF:0 or 0F000h:0FFF0h in real mode. The processor can be reset by writing a value of 0FEh at
port address 64h. The code may look like this:

MOV AL,0FEh
OUT 64h,AL

Keyboard Operations

The keyboard is easy to access using BIOS functions which are accessed through interrupt 16h.

Wait For Key

INT 16h: AH=0
Returns AL=ScanCode
If AL=0 then AH=ExtendedCode

To pause a program until a key is pressed, interrupt 16h is called with function 0. The scan code of
the pressed key is returned in AL. If AL is 0 then the pressed key is extended and the scancode is in
AH. The code

MOV AH,0
INT 16h

causes a program to pause until a key is pressed.


Check KeyPress

To just check for a keypress, INT 16, function 1 is called. If ZF=0 then a key has been pressed and
awaits processing.

MOV AH,1
INT 16h
JNZ KeyPress
. ;NoKey
.
.
KeyPress:

Get Keyboard Flags

INT 16h: AH=2
Returns AL=Keyboard Flags

Each bit of the flags when set represents the following:

Bit 0 Right shift key is pressed
1 Left shift key is pressed
2 Either of the ctrl keys is pressed
3 Either of the alt keys is pressed
4 ScrollLock is on
5 NumLock is on
6 CapsLock is on
7 Insert is on

The same is achieved by reading a byte at address 417h


Direct Keyboard Operations

The keyboard is connected to IRQ 1. When ever the keyboard has something to say, it generates
IRQ 1 which is installed at interrupt 9 by the BIOS. Inorder to recieve messages from the keyboard
directly, a program can install an IRQ 1 handler.

This code runs in real mode and is not operating system specific:

XOR DI,DI
MOV FS,DI
MOV EAX,FS:[9*4]
MOV CS:[OldInt8],EAX
MOV AX,CS
SHL EAX,16
MOV AX,(Int8Handler)
CLI
MOV FS:[9*4],EAX
STI
JMP $

Int8Handler:
PUSH AX
IN AL,60h
CALL PrintHexByte
MOV AH,1
CMP AL,0E0h
JZ MoreBytes
INC AH
CMP AL,0E1h
JZ MoreBytes
CMP BYTE [RemainChar],0
JZ PrintLF
DEC BYTE [RemainChar]
JNZ OldInt
PrintLF:
MOV AX,0E0Dh
INT 10h
MOV AL,0Ah
INT 10h
JMP OldInt
MoreBytes:
MOV [RemainChar],AH
OldInt:
POP AX
JMP DWORD CS:[OldInt8]

PrintHexByte:
PUSH AX,BX
MOV BL,AL
MOV CL,4
MOV CH,2
MOV AH,0Eh
phbLoop:
ROL BL,CL
MOV AL,BL
AND AL,0Fh
CMP AL,9
SETBE BH
DEC BH
AND BH,7
ADD AL,BH
ADD AL,30h
INT 10h
DEC CH
JNZ phbLoop
MOV AL,20h
INT 10h
POP BX,AX
RET
RemainChar DB 0
OldInt8 DD ?

This code causes the computer to display what happens at port 60h when each key is pressed. The
code takes over interrupt 9 which is initially the IRQ 1 interrupt vector. When a key is pressed, the
code is placed at port 60h. The interrupt handler reads the key pressed from port 60h and handles the
key. The BIOS handles key messages, that is how it provides INT 16h. When a key is pressed, the
code is sent with bit 7 clear. When a key is released, the code is sent with bit 7 set.

Switching Keyboard LEDs

Changing the state of the keyboard LEDs is achieved by either writing to a byte memory address
417h or by using I/O. The format of the byte at 417h is the same as the byte returned by INT 16
function 2. The direct method is to write a byte of 0EDh at port 60h, followed by writing a byte with the
following format:

Bit 0 NumLock
1 ScrollLock
2 CapsLock
7:3 Reserved(0)

The code may appear like this to turn all the LEDs on:

MOV AL,0EDh
OUT 60h,AL
MOV AL,7
OUT 60h,AL

Video Operations

Video operations can be classified into two: text mode operations and graphic operations.
Unfortunately there are many video graphics cards with different designs, so only a few functions can
really be done directly. First lets look at how to switch between modes.

Switching Modes

Switching to text mode is not much of a problem. This can be achieved by calling the BIOS interrupt
10h with a function of 0, that is AH = 0. AL contains the video mode to switch to. The modes that run
on most computers are 3 (color) and 7 (mono). At this point, lets do a switch to text mode:

MOV AX,0003 ;Replace 3 with 7 for monochrome
INT 10h

This must set the display to 80x25 mode.

Writing A Character

To write a character to screen, we use function 0Eh with the character to be written in AL. To write 'A'
to the screen we can write something like:

MOV AX,0E41h
INT 10h

This must display a character on the screen. The following code writes a string pointed by ESI.

PrintStr:
MOV ESI,(_TextAddr)
MOV AH,0Eh
CMP BYTE [ESI],0
JZ psDone
psLoop:
LODSB
INT 10h ;INT 10 does not modify AH no need to reload it.
CMP BYTE [ESI],0
JNZ psLoop
psDone:
RET
_TextAddr DB "Hello World",13,10,0

Video Memory

Above you have learnt that we can communicate with hardware through memory mapped I/O. The
video memory is an example of memory mapped I/O address space.. The video memory is at
addresses 0A0000h to 0BFFFFh. Text memory starts at address 0B0000h for monochrome or
0B8000h for color adaptors. The video hardware shows the contents of the video memory on screen.
Each character displayed on screen occupies two bytes in video memory. The first one is for the
character to be displayed and the second one is for color. This short program (real and protected)
directly writes the text memory:

MOV AX,0B800h ;Real Mode
MOV ES,AX
XOR EDI,EDI
MOV AX,0741h
STOSW

or

MOV EDI,0B8000h ;Assume ES is a linear selector protected mode
MOV AX,0741h
STOSW

This program must show a character on the corner of the screen. The BIOS does all the hardwork for
the programmer.

Text Pages

Lets say we change into 80x25 mode. The memory that the whole screen would occupy is
80 * 25 * 2=4000 bytes. What about the remaining ((BFFFFh-B8000h)-4000) bytes? The text memory
is divided into sections such that at the each section starts at a boundary aligned to 4096 bytes. Each
section is called a page and can be displayed on screen. In 80x25 text mode, 8 different pages can
be displayed on screen, one at a time. This is an advantage in that, while displaying one page, the
program may be working on another page, after it is done, it instantly shows the other page.
To change from one text page to another, function 5 is called with AL=pagenumber.

MOV AX,3
INT 10h ;Initially the text page is 0
MOV ESI,(_Hello0Msg)
CALL PrintStr
MOV AH,0 ;Wait for keypress
INT 16h
MOV AX,501h ;Change to page 1
INT 10h
MOV ESI,(_Hello1Msg)
CALL PrintStr
MOV AH,0 ;Wait for keypress
INT 16h
MOV AX,500h ;Change to page 0.
INT 10h
.
.
.
PrintStr:
MOV AH,0Eh
CMP BYTE [ESI],0
JZ psDone
psLoop:
LODSB
INT 10h ;INT 10 does not modify AH no need to reload it.
CMP BYTE [ESI],0
JNZ psLoop
psDone:
RET

_Hello0Msg DB "Hello From Page 0",13,10,0
_Hello1Msg DB "Hello From Page 1",13,10,0

This code print while in page 0 then switches to page 1 then prints then switches again to page 0. The
contents of a page are not changes even if pages are changed.

Text Scrolling

If a program displays text until it reaches the bottom line, anymore writes cause the second line to the
last line to move up by one line removing the first line, so that a blank line can be inserted at the
bottom. This is called scrolling. When a program print on the screen using BIOS calls, the BIOS
scrolls automatically. This is one disadvantage of directly printing to screen, you have to handle the
scrolling too.

Changing The Cursor Location

When an interrupt to write a character is called, the character is written on the cursor position and the
cursor moves.

INT 10: AH=2
DH,DL=Cursor Row,Column
Sets a new cursor position.

You might also like