Page 1 of 1
Help reading line input from keyboard
Posted: Mon Oct 30, 2017 9:31 pm
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?
Re: Help reading line input from keyboard
Posted: Mon Oct 30, 2017 10:06 pm
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;
}
Re: Help reading line input from keyboard
Posted: Mon Oct 30, 2017 10:07 pm
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
Re: Help reading line input from keyboard
Posted: Mon Oct 30, 2017 10:27 pm
by thumble
Duly noted. Thank you.
Re: Help reading line input from keyboard
Posted: Mon Oct 30, 2017 11:14 pm
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]