How to make a scanf() type function in a 32bit os in c?

477 views Asked by At

I am trying to make an os in c and assembly in 32-bits protected mode. I am trying to create a scanf() type function which gets the keyboard input until the enter button is pressed. I have a basic keyboard IRQ handler setup which prints anything typed and i want to implement a scanf() function but i have problems to return the value from the keyboard Handler to the main kernel.

Heres the code for the keyboard handler.

unsigned int shift_key = 0;

unsigned int caps_key = 0; 

int counter = 0;

char *sbuf;

int scan = 1;

void keyboard_handler(registers_t regs)
{ 

// monitor_write("handler called");

unsigned char scancode; 
scancode = get_scancode();
if(scancode == 0x2A )     
{   
    shift_key = 1;//Shift key is pressed

    //monitor_write("Shift + ");

}      

else if(scancode == 0xAA)   

{   

     shift_key= 0;//Shift Key is not pressed

    //  monitor_write("Unshift");

}  



else if(scancode == 0x3A && caps_key == 1)     
{   

    caps_key = 0;//Caps key is pressed

//  monitor_write("Shift + ");

}      
else if(scancode == 0x3A && caps_key == 0)     

{   

    caps_key = 1;//Caps key is pressed

//  monitor_write("Shift + ");

}  

//Left arrow    

else if(scancode == 0x4B)

{

    move_cursor_LR(1,0);

}

//right Arrow

else if(scancode == 0x4D)

{

    move_cursor_LR(0,1);

}

else    

{          

    if (shift_key == 1 && caps_key == 0)    

    {   

        // int shiftaltctrl = 1;//Put anything to see what special keys were      pressed

        monitor_put(Kkbdus[scancode]);      

        if (scan == 1 && Kkbdus[scancode] != '\n')

        {

        sbuf[counter] = Kkbdus[scancode];       

        counter++ ;

        }

    }       

    if (caps_key == 1 && shift_key == 0)    

    {   

        // int shiftaltctrl = 1;//Put anything to see what special keys were pressed

        monitor_put(Kkbdus[scancode]);      

        if (scan == 1 && Kkbdus[scancode] != '\n')

        {

        sbuf[counter] = Kkbdus[scancode] ;      

        counter++ ;

        }

    }        

    if(shift_key == 0 && caps_key == 0)

    {    

        monitor_put(kbdus[scancode]); //Prints the character which was pressed         

        if (scan == 1 && kbdus[scancode] != '\n')

        {

        sbuf[counter] = kbdus[scancode];        

        counter++ ;

        }

    }   

    if( caps_key == 1 && shift_key == 1)

    {

        monitor_put(kbdus[scancode]);

        if (scan == 1 && kbdus[scancode] != '\n')

        {

            sbuf[counter] = kbdus[scancode];        

            counter++ ;

        }

    }

    if(scan == 1 && kbdus[scancode] == '\n') 

    {



        scan = 0;

        sbuf[0] = '\0';

    }

    if(kbdus[scancode] == '\t')

    {

        monitor_write(sbuf);

    }   

  }

}

I am using the scan variable as a bool to put the chars in an array when the irq is called. but i cant get a way to return it to the main file from which i call it.

1

There are 1 answers

0
Arnav Jain On

I thought of this and tried a piece of code which worked. What i did was made a function in the keyboard driver which would keep the last char typed. and when i want to get the char i would just call getch(); which would return the char. and i made the main scanf(); in the main file which would collect the chars and first set them to 0 so that the same char does not get repeated and then it goes through a while loop which would verify for the enter key to be pressed. and would add the char to a char* if it is not = 0 and if the buffch variable is set to 1 if it is set to 0 it will not print it.That was the theory.

Here is the code:

in keyboard driver: added getch and getchter wich would get the char and set it to 0 respectively.

char getch()
{
    char buf = sbuf; // clone the buffer
    getchter();      // set the sbuf to 0 so that the same char is not repeated
    return buf;      // return buff.
}

void getchter()
{
    sbuf = 0;       // setting sbuf to 0
}

and here is the scanf() function which goes in the main kernel file.

char* scanf() //scanf() is called
{
    char* buff;      //make a buffer
    char key = '/0'; // make a single char buffer
    int i = 0;       //counter
    int n = 100;     // counter the number is the limit of chars to input
    int buffch = 1;
    while(i < n)  //until the max char limit is reached
    {
        buffch = 1;  // buffch used as bool to buffer or not buffer the char we 
        key = getch(); // get the last char typed
        if(key == '\n') // if enter is pressed stop
        {
            break;
        }       
        if(key == '\b') if key is a backspace 
        {
            //! dont buffer this char
            buffch = 0;

            if (i > 0)  // if the count is more than 0 then
            {
                //! go back one char in buffer
                i--;
            }  
        }
        //! only add the char if it is to be buffered
        if (buffch == 1)
        {
            if (key != 0) // insure that it is not a 0 ie if it is repeated it will be = 0 
            {
                buff[i++] = key; // add the char to the buffer
            }
        }

    }
    buff[i] = '/0'; in the last set the string to be null terminated
    return buff; // return the buff
}

I hope this helps other people :)