Simple programming of VGA cursor

44 Views Asked by At

While writing a simple VGA driver for a simple kernel , i found problems configuring the vga cursor , those are the common routine i used :

static uint8_t __InByte(uint16_t);
typedef uint8_t(*pFunc1)(uint16_t); 
/*
 *compiler optimization optimize the call to __InByte and makes only one call to it in __GetCurso
 * because it thinks that the function will give the same result since it has been passed the same
 * param
 */
volatile pFunc1 __pInByte = __InByte;

#ifdef __DEBUG
static uint16_t __GetCursor(void) ;

typedef uint16_t (*pFunc2)(void);
volatile pFunc2 __pGetCursor = __GetCursor;
#endif
static uint8_t __InByte(uint16_t port){
    uint8_t result ;
    __asm__("in %%dx , %%al" : "=a" (result) : "d" (port));
    return result ;
}


static void __OutByte(uint16_t port , uint8_t data){
    __asm__("out %%al , %%dx" : : "a" (data) , "d" (port));
}
static uint16_t __GetCursor(){
    int offset = 0 ;
    __OutByte(VGA_CONTROL_REGISTER , VGA_OFFSET_LOW);
    offset  +=__pInByte(VGA_DATA_REGISTER);
    __OutByte(VGA_CONTROL_REGISTER , VGA_OFFSET_HIGH);
    offset +=__pInByte(VGA_DATA_REGISTER) << 8;
    return offset;
}

static void __CursorSet(uint16_t offset){
    __OutByte(VGA_CONTROL_REGISTER , VGA_OFFSET_LOW) ;
    __OutByte(VGA_DATA_REGISTER , (uint8_t)(offset && 0xff)) ;
    __OutByte(VGA_CONTROL_REGISTER , VGA_OFFSET_HIGH);
    __OutByte(VGA_DATA_REGISTER , (uint8_t)(offset >> 8));
}

I used a simple function terminal_writestring for writing a string , this function makes calls to terminal_putchar , the problem is that the string is well written and each time a character is written i set the cursor to the next position , but the cursor got stack in offset 1 . I suspect that the problem is in the __SetCursor , but it worked for terminal initialization where is did __SetCursor(0) , and when printing hello world the cursor stop at the letter 'e' of hello , Here are the other functions for writing the string

uint16_t *videomem ;
void __InitializeTerminal(void){
    __SetCursor(0);
    // ----Snip----
}
static  void terminal_putentryat(uint8_t c, uint8_t color , uint8_t x, uint8_t y){
    if (check_special_char(c)){ // It just check if the character is a new line
        return ;
    }
    #ifdef __DEBUG
    uint16_t offset  = __pGetCursor();
    #else
    uint16_t offset  = __GetCursor();
    #endif
    size_t index = y*MAX_COLS +x ;
    videomem[index] = vga_entry(c , color);
    terminal_column++; 
        __CursorSet(++offset);
}

void terminal_putchar(char c){
    terminal_putentryat(c , terminal_color , terminal_column , terminal_row);
}

static void terminal_write(const char *data , size_t size){
    for(size_t i = 0 ; i < size ; i++){
        terminal_putchar(data[i]);
    }
}

void terminal_writestring(const char *data){
    terminal_write(data , strlen(data));
}

Ive tried debuggint the kernel using gdb , but everythin looks fine if im understanding well.

This is the first time im asking on stackoverflow , i hope i make my question clear .Thank you

0

There are 0 best solutions below