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