Help reading line input from keyboard

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
thumble
Member
Member
Posts: 29
Joined: Thu May 25, 2017 10:41 pm

Help reading line input from keyboard

Post by thumble »

So, I've recently picked up OS development again, and decided to add basic command functionality to my OS.
Here is the code I have so far:

Code: Select all

char buf[1024];
short index;

/* initialize the above variables w/ memset, index=0 */

void kb_irq_handler(struct regs *r) {
    uint8_t scancode = inb(0x60);
    char c = scanToAscii(scancode);
    putchar(c);

    if(index == 1023) {
        print("Buffer overflow!");
        memset(&buf, '\0', 1024);
        index = 0;
        return;
    } else if(c == '\n') {
        buf[index] = '\0';
        test();
        index = 0;
        memset(&buf, '\0', 1024);
    } else {
        buf[index] = c;
        index++;
    }
}

void test() {
    char* str = &buf;
    writestring(buf);
    writestring("\n$ ");
}
This code is meant to read a line and print that out again, but it doesn't work that way, and I'm reasonably sure it's not actually reading a line. Using the QEMU monitor, I printed out the data at buf; it seems to be just junk data. I'm quite sure there's a dumb mistake in my code, but not sure where it is. Could someone help point out where I'm blundering?
thumble
Member
Member
Posts: 29
Joined: Thu May 25, 2017 10:41 pm

Re: Help reading line input from keyboard

Post by thumble »

EDIT:
It turns out that somehow index was incremented twice..?
By adding another conditional I fixed it.
I'm not too sure how this works, but here is the updated function (with much omitted code):

Code: Select all

if(index == 1023) {
    print("Buffer overflow!");
    ...
} else if(c == '\n') {
    buf[index] = '\0';
    ...
} else if(c == '\0') {
    buf[index] = ' ';  /* ?? fixed  it */
} else {
    buf[index] = c;
    ++index;
}
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Help reading line input from keyboard

Post by Brendan »

Hi,
thumble wrote:So, I've recently picked up OS development again, and decided to add basic command functionality to my OS.
Here is the code I have so far:

Code: Select all

char buf[1024];
short index;

/* initialize the above variables w/ memset, index=0 */

void kb_irq_handler(struct regs *r) {
    uint8_t scancode = inb(0x60);
    char c = scanToAscii(scancode);
    putchar(c);

    if(index == 1023) {
        print("Buffer overflow!");
        memset(&buf, '\0', 1024);
        index = 0;
        return;
    } else if(c == '\n') {
        buf[index] = '\0';
        test();
        index = 0;
        memset(&buf, '\0', 1024);
    } else {
        buf[index] = c;
        index++;
    }
}

void test() {
    char* str = &buf;
    writestring(buf);
    writestring("\n$ ");
}
This code is meant to read a line and print that out again, but it doesn't work that way, and I'm reasonably sure it's not actually reading a line. Using the QEMU monitor, I printed out the data at buf; it seems to be just junk data. I'm quite sure there's a dumb mistake in my code, but not sure where it is. Could someone help point out where I'm blundering?
For a random estimate; I'd say that for about 85% of the bytes the keyboard can send it's impossible to convert them to ASCII. Some are control bytes ("resent", "BAT response"), almost half are "key released", a lot are special keys (like "shift key pressed" or "F3 key pressed" or "PageUp key pressed"), and a lot are just pieces of a multi-byte scancode.

For all of these bytes that are impossible to convert to ASCII, you convert them to ASCII.

Note: Building command functionality inside the keyboard IRQ handler is a massive mistake most often caused by implementing a keyboard driver before you have the necessary framework (memory management, event handling, etc).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
thumble
Member
Member
Posts: 29
Joined: Thu May 25, 2017 10:41 pm

Re: Help reading line input from keyboard

Post by thumble »

Duly noted. Thank you.
thumble
Member
Member
Posts: 29
Joined: Thu May 25, 2017 10:41 pm

Re: Help reading line input from keyboard

Post by thumble »

Oh, now I know why the fix works!
In scanToAscii(), a non-ASCII value sets a boolean for it and returns a null that shouldn't be printed! This prematurely terminates the string.
[facepalm]
Post Reply