Friday, June 15, 2007

The Globician

Our monitor is much like a magic globe which we have been dreaming of long long ago! Today programmers are the magicians of this Globe. I met a magician of globe; The Globician who told me what I am telling you.

The front of monitor is coated on the inside with phosphorous which glows when electron strike it. On the rear end, it is equipped with 3 electron guns, red, green, and blue! electrons from respective guns produce the respective glow. These guns fire electrons on the instructions they receive. The instructions consists of the color as well as the position on which the color is to be produced.

For historical reasons, there are different modes in which you can display what you want on the monitor screen. The table summarizes these modes:

Mode Type Max Colors Text Resolution Graphics Resolution Max Pages Base Address
00 Text 16 40 × 25   8 B8000H
01 Text 16 40 × 25   8 B8000H
02 Text 16 80 × 25   4,8 B8000H
03 Text 16 80 × 25   4,8 B8000H
04 Graphics 4 40 × 25 320 × 200 1 B8000H
05 Graphics 4 40 × 25 320 × 200 1 B8000H
06 Graphics 2 80 × 25 640 × 200 1 B8000H
07 Text mono 80 × 25   1,8 B0000H
08 Graphics 16 20 × 25 160 × 200 1 B0000H
09 Graphics 16 40 × 25 320 × 200 1 B0000H
0A Graphics 4 80 × 25 640 × 200 1 B0000H
0D Graphics 16 40 × 25 320 × 200 8 A0000H
0E Graphics 16 80 × 25 640 × 200 4 A0000H
0F Graphics mono 80 × 25 640 × 350 2 A0000H
10 Graphics 16 80 × 25 640 × 350 2 A0000H
11 Graphics 2 80 × 25 640 × 480 1 A0000H
12 Graphics 16 80 × 25 640 × 480 1 A0000H
13 Graphics 256 40 × 25 320 × 200 1 A0000H

These are the basic video modes. Now how to set the video mode?

For video tasks, we have to use interrupt 10h.

The service number 0h allows you to change the video mode.

Here is the simple code to set the video mode to 13.

mov AL, 13h
mov AH, 0h,
int 10H

When we set the video mode, the computer display is calibrated horizontally and vertically in rows and columns. For mode 13, we have 320 columns and 200 rows. Each intersection of rows and columns gives a small square or rectangular area of screen which is known as pixel.

You can see your screen as an xy-plane. Rows are calibrated on y-axis and columns on x-axis. The pixels represents the points in xy-plane. The point to remember is that point (0, 0) is top-left corner of your screen, not bottom left.

Now that we have set the video mode, we want to draw something. Images you may know are in fact collection of colored dots. Here, we have dots (pixels) and we can color them as well. So, like an artist, we have to color the pixels in such a way that they represent images. How can I color a single pixel?

Service number 0CH of int 10H is the key. Put the color value in AL, column number in CX and row number in DX.

What color? How many color do we have in mode 13? 256! Which means 0 to 255 are the color numbers. Now which color number is your one? Playing with colors is the most easy way I can tell you. Lets set pixel (200, 100) to color 12.

mov AL, 12
mov AH, 0ch
mov CX, 200
mov DX, 100
mov BH, 0
int 10H

Well done me! Why did I set BH to 0? Its the page number. Lets put it aside for some time and continue with its value 0.

Well, we have put a colored pixel on the screen, what not can we do now! Start by painting a line, a horizontal line. Keep the value of row same and change the value of column in a loop and dont forget to call the interrupt each time. It will give you a simple line. Let see:

mov CX, 100
mov DX, 100
mov AL, 12
mov AH, 0ch
mov BH, 0
start:
int 10H
loop start

Here, I set CX and DX to 100 so the dot is positioned at (100, 100). AL has got the value of color, AH has service number and BH is 0. Now execution enters the loop where int 10H is called. This places a dot on the screen. The loop directive decrements the value of CX and it becomes 99. Now it checks the value of CX which not zero so it jumps to start. Again int 10H is called to print the dot. But this time the dot is at (99, 100)! CX is decremented! Try it!

Now that we have put a line on screen, we can draw different shapes as well. But what exactly happens when we draw things? In the table above, we have a base address in front of each mode. It is base address of the display memory. Our display commands are stored in memory and the computer screen shows whatever we put in the display memory.

For example in mode 13, the base address is A0000H. We have to display 256 different colors for each pixel. So we can have 8 bits to store a color number between 0 to 255; that is 1 byte. At a resolution of 320 × 200 we need 64000 such locations. So, starting from A0000H, all the 64000 bytes represent 64000 pixels in the screen. The BIOS interrupt calculates the byte number itself for you when you provide row and column number. How?

Pixel number = row number × number of pixels per row + column number

For example in mode 13, location (100, 100) would be:

100 × 320 + 100 = (32100)10 = 7D64H

This is the pixel number; the offset address. And the segment address is A000H. Thats how you put colors on the screen. If you directly put the colors on memory, this is called Direct Memory Access (DMA). Lets see the code for putting a dot on screen at (200, 100) of color 12 in both ways.

BIOS Version

.model small
.stack 100h
.data
.code
main:

; Change the video mode
mov ah, 0h ; Service number
mov al, 13h ; Mode number
int 10h ; Interrupt

; Put a dot on screen
mov AL, 12 ; Color Number
mov AH, 0Ch ; Service Number
mov CX, 200 ; Column Number
mov DX , 100 ; Row Number
mov BH, 0 ; Page Number
int 10H ; Interrupt

; Dot is on the screen, want to see it? Wait then!
mov ah, 01h ; With single character input
int 21h

; Change the video mode back to correct one
mov ah, 0h
mov al, 03h
int 10h

; Exit
mov ah, 4ch
int 21h

end main

DMA version

.model small
.stack 100h
.data
.code
main:

; Set the segment address to 0A000H
mov ax, 0A000H
mov ds, ax

; Change the video mode
mov ah, 0h ; Service number
mov al, 13h ; Mode number
int 10h ; Interrupt

; Put a dot on screen

; Column number = 200
; Row Number = 100
; Pixel Number = 100 × 320 + 200 = 32200

mov bx, 32200 ; Offset Address

; Put color on that location
mov al, 12
mov [bx], al

; Dot is on the screen, want to see it? Wait then!
mov ah, 01h ; With single character input
int 21h

; Change the video mode back to correct one
mov ah, 0h
mov al, 03h
int 10h

; Exit
mov ah, 4ch
int 21h

end main

No comments: