Saturday, September 19, 2009

Using the Kernel Level Video Memory

How to use the Video Memory


Here are the ways to use the computer's video memory, I'm first going to show you how to use it from it's address.

Generally, the Video Memory Base Address is 0xB8000. When you want to draw a character, you must set 2 bytes. The first one is is the character, the second is the
attributes. Here's an exemple to understand how to print a character :
mov byte [0xB8000],'A' ;The Character Itself
mov byte [0xB8001],0xF ;Character's Attribute (0xF = 00001111)
Here's defined a black background with a white foreground :

Blinking (H) BackGround (H) Intensity (L) ForeGround (L)
0 000 1 111

The colors are in RGB format, The max value is 1, the minimum is 0
Color
Code
Black
000
Blue
001
Red
100
Green
010
Yellow
110
Purple
101
Cyan
011
White
111


Now that we know the basics, we're going to write our first string !
mov byte [0xB8000],'H'
mov byte [0xB8001],0xF
mov byte [0xB8002],'E'
mov byte [0xB8003],0xF
mov byte [0xB8004],'L'
mov byte [0xB8005],0xF
mov byte [0xB8006],'L'
mov byte [0xB8007],0xF
mov byte [0xB8008],'O'
mov byte [0xB8009],0xF
mov byte [0xB800A],' '
mov byte [0xB800B],0xF
mov byte [0xB800C],'W'
mov byte [0xB800D],0xF
mov byte [0xB800E],'O'
mov byte [0xB800F],0xF
mov byte [0xB8010],'R'
mov byte [0xB8011],0xF
mov byte [0xB8012],'L'
mov byte [0xB8013],0xF
mov byte [0xB8014],'D'
mov byte [0xB8015],0xF
mov byte [0xB8016],' '
mov byte [0xB8017],0xF
mov byte [0xB8018],'!'
mov byte [0xB8019],0xF
Example ran in VirtualBox :




But, typing all this code is odd, and we could write a DrawString function. Let's write it in C :



   #define RAMSCREEN 0xB8000       /* Video Memory */
   #define UCHAR unsigned char
   #define LPUCHAR unsigned char*
   LPUCHAR VideoMemory = (LPUCHAR)RAMSCREEN;
   int strlen(char* text)
    {
    int i = 0;
  
    while(text[i])
    i++;
  
    return i;
    }

    void print(char* text)
    {
    int i;
    int j;
    for(i = 0, j = 0; i < strlen(text); i++, j += 2)
    {
    VideoMemory[j]     =     text[i];
    }
    }
I tried to make it in ASM for you lucky people, but because I'm not a pro, it sucks a bit :


    DrawString:
    xor ebx, ebx
    xor edx, edx
    mov ebx, [ConsolePos]
    draw_start:
    mov al, [ecx]
    cmp al, 0     ; \0 char ?
    je draw_end
    cmp al, 10     ; New Line ?
    je new_line

    ;Print the char
    mov byte [0xB8000 + ebx], al
    add ebx, 2
    inc ecx

    jmp draw_start

    new_line:
    mov edx, [ConsolePos]
    add edx, 160
    mov ebx, edx
    mov [ConsolePos], ebx
    inc ecx
    jmp draw_start
   draw_end:
    ret

    C_SystemLoad     db "Loading Main Kernel...", 10, 0
  
ConsolePos         dd 0
   KernelStart:
    mov ecx, C_SystemLoad
call DrawString
   end:
jmp end

Well I hope you've learnt from this tut, This tutorial was written by me. Thanks to OSDev for their helpful forums/website ;D

No comments:

Post a Comment