Page 3 of 3

Re: Keyboard input

Posted: Sun Nov 29, 2020 4:04 pm
by SuperGabry64
The fact is that using itoa it returns the right ascii code, but printing the char or directly printing an int (i tried printing 49, the 1 ascii code ) will give a different character

Re: Keyboard input

Posted: Sun Nov 29, 2020 4:50 pm
by foliagecanine
SuperGabry64 wrote:The fact is that using itoa it returns the right ascii code...
I don't get it. What are you using itoa for?
itoa is a function that takes an integer and converts it to a char array ("string") in a certain base.
For example, itoa(192,charrarray,10) would return a char array: {'1','9','2',0} stored in the charrarray variable.
SuperGabry64 wrote:...printing the char or directly printing an int (i tried printing 49, the 1 ascii code ) will give a different character
What character did it produce? If I put a 49 at address 0xB8000 and a 15 in 0xB8001, then it will produce the character '1' in the VGA text buffer.

Also, I don't think you've shared your source code yet. It will help us understand a lot if you choose to share it with us.

Re: Keyboard input

Posted: Sun Nov 29, 2020 5:42 pm
by SuperGabry64

Code: Select all

#include <stdio.h>
#include <stdint.h>
#include <kernel/tty.h>

uint8_t keyconv(uint8_t key)
{
	switch (key)
	{
	case 0x2:
		return '1';
		break;
	case 0x3:
		return '2';
		break;
	case 0x4:
		return '3';
		break;
	case 0x5:
		return '4';
		break;
	case 0x6:
		return '5';
		break;
	case 0x7:
		return '6';
		break;
	case 0x8:
		return '7';
		break;
	case 0x9:
		return '8';
		break;
	case 0xa:
		return '9';
		break;
	case 0xb:
		return '0';
		break;
	case 0xc:
		return '-';
		break;
	case 0xd:
		return '=';
		break;
	case 0xe:
		return -2;
		break;

	default:
		return ' ';
		break;
	}
}

//Port IO
inline void outb(uint16_t port, uint8_t val)
{
    asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) );
}

inline uint8_t inb(uint16_t port)
{
    uint8_t ret;
    asm volatile ( "inb %1, %0"
                   : "=a"(ret)
                   : "Nd"(port) );
    return ret;
}



inline void io_wait(void)
{
    asm volatile ( "outb %%al, $0x80" : : "a"(0) );
}

char* itoa(int val, int base){
	
	static char buf[32] = {0};
	
	int i = 30;
	
	for(; val && i ; --i, val /= base)
	
		buf[i] = "0123456789abcdef"[val % base];
	
	return &buf[i+1];
	
}

// Kernel
void kernel_main(void) {

	terminal_initialize();
	printf("Hello, kernel World!\n");
	uint8_t input = ' ';
	while (1)
	{
		if ((inb(0x64) & 1) != 0)
		{
			input = inb(0x60);
			input = keyconv(input);
			printf("%s", input);
			printf("    ");
		}
	}
}

Re: Keyboard input

Posted: Sun Nov 29, 2020 6:57 pm
by foliagecanine
You aren't using itoa at all in this code. EDIT: Nevermind. You were saying itoa prints the right number.
SuperGabry64 wrote:

Code: Select all

         input = inb(0x60);
         input = keyconv(input);
         printf("%s", input);
         printf("    ");
You're taking the variable "input" and using it as a pointer to a string. This won't work. Perhaps you meant to print the character with %c, like this:

Code: Select all

         input = inb(0x60);
         input = keyconv(input);
         printf("%c", input);
         printf("    ");
What's happening, is you're taking the number 49, and using as a string address. So when it tries to print, it looks at RAM address 49 and prints characters until it encounters a 0.

Re: Keyboard input

Posted: Mon Nov 30, 2020 1:15 am
by SuperGabry64
So, i managed to get the right result, i'm using this table:
foliagecanine wrote:

Code: Select all

char kbdus[] = {
	0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0,
	'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
	'\n', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
	0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
	'*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9',
	'-', '4', '5', '6', '+', '1', '2', '3', '0', '.'
};
/code][/quote]

But i have 3 questions:
- How to check if shift or caps lock is pressed?
- Why does \t and \n give two strange characters similar to the degrees sign(°)? Even when printing the first Hello World it doesn't works
- Why after every character there is a space?

Re: Keyboard input

Posted: Mon Nov 30, 2020 2:12 am
by Octocontrabass
SuperGabry64 wrote:- How to check if shift or caps lock is pressed?
You'll receive a scan code every time a key is pressed or released. You'll have to write code to keep track of shift and caps lock based on when those keys are pressed and released.
SuperGabry64 wrote:- Why does \t and \n give two strange characters similar at the degrees sign(°)? Even when printing the first Hello World it doesn't works
Does your printf() function know how to handle those characters? It sounds like right now it just writes their numeric value to VGA text mode memory, which will display the corresponding code page 437 characters.
SuperGabry64 wrote:- Why after every character there is a space?
You're printing one character for each scan code, but the keyboard will send two scan codes for most keys: one when the key is pressed, and one when the key is released. You also have that last printf that adds more spaces after each character.

Re: Keyboard input

Posted: Mon Nov 30, 2020 2:49 am
by SuperGabry64
I thinked that the meaty skeleton printf could handle it.

I have removed the second printf

Re: Keyboard input

Posted: Mon Nov 30, 2020 5:46 am
by SuperGabry64
Nevermind, i managed to handle \t and \n and make the key released not printable

Re: Keyboard input

Posted: Wed Dec 02, 2020 10:52 am
by austanss
StudlyCaps wrote:
SuperGabry64 wrote:No, i never heard of this
I don't mean to be rude, but how much programming experience do you have? OS development can be very difficult, and you need to know very advanced programming techniques, a lookup table is a quite elementary technique.

Regardless, here is Wikipedia's description of a look up table. https://en.wikipedia.org/wiki/Lookup_table
It should explain the theory.

As for implementation; you get the scancode from your keyboard interface, you use a state machine to keep track of whether the shift key or caps key is down and write something like this to figure out what character to print.

Code: Select all

if(shift_down)
{
    return kbdus_shift[scan_code];
}
else if(caps_enable)
{
    return kbdus_caps[scan_code];
}
else
{
    return kbdus[scan_code];
}
The only issue with this is that you don't take into consideration if the user has caps lock on AND is pressing shift at the same time... which should then shift all non-alphabetical keys, and set all alphabetical keys to lowercase.

Example:

Normal:
yay1

Shifted:
YAY!

Caps lock:
YAY1

Shifted + caps lock:
yay!

Re: Keyboard input

Posted: Thu Dec 10, 2020 3:38 pm
by eekee
rizxt wrote:The only issue with this is that you don't take into consideration if the user has caps lock on AND is pressing shift at the same time... which should then shift all non-alphabetical keys, and set all alphabetical keys to lowercase.
Sure, if you're Microsoft. ;) I always had my Linux machines configured to basically logical-OR caps with shift. But what you're talking about is basically logical-XOR caps with shift, so it's probably not any harder. (I haven't looked at the code.)

Re: Keyboard input

Posted: Thu Dec 10, 2020 9:59 pm
by nullplan
eekee wrote:Sure, if you're Microsoft. ;) I always had my Linux machines configured to basically logical-OR caps with shift. But what you're talking about is basically logical-XOR caps with shift, so it's probably not any harder. (I haven't looked at the code.)
Not really. You end up with some keys being shifted and some not. Since memory is abundant these days, I would just implement this as a new shift level (well, two new shift levels). So you have
  • no modifier
  • Shift
  • Caps Lock
  • Caps Lock + Shift
  • AltGr
  • AltGr + Shift
  • AltGr + Caps Lock
  • AltGr + Caps Lock + Shift
Congratulations, you just invented X11.