Keyboard input

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.
SuperGabry64
Posts: 20
Joined: Tue Oct 20, 2020 10:38 am

Re: Keyboard input

Post 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
foliagecanine
Member
Member
Posts: 148
Joined: Sun Aug 23, 2020 4:35 pm

Re: Keyboard input

Post 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.
My OS: TritiumOS
https://github.com/foliagecanine/tritium-os
void warranty(laptop_t laptop) { if (laptop.broken) return laptop; }
I don't get it: Why's the warranty void?
SuperGabry64
Posts: 20
Joined: Tue Oct 20, 2020 10:38 am

Re: Keyboard input

Post 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("    ");
		}
	}
}
foliagecanine
Member
Member
Posts: 148
Joined: Sun Aug 23, 2020 4:35 pm

Re: Keyboard input

Post 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.
My OS: TritiumOS
https://github.com/foliagecanine/tritium-os
void warranty(laptop_t laptop) { if (laptop.broken) return laptop; }
I don't get it: Why's the warranty void?
SuperGabry64
Posts: 20
Joined: Tue Oct 20, 2020 10:38 am

Re: Keyboard input

Post 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?
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: Keyboard input

Post 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.
SuperGabry64
Posts: 20
Joined: Tue Oct 20, 2020 10:38 am

Re: Keyboard input

Post by SuperGabry64 »

I thinked that the meaty skeleton printf could handle it.

I have removed the second printf
SuperGabry64
Posts: 20
Joined: Tue Oct 20, 2020 10:38 am

Re: Keyboard input

Post by SuperGabry64 »

Nevermind, i managed to handle \t and \n and make the key released not printable
User avatar
austanss
Member
Member
Posts: 377
Joined: Sun Oct 11, 2020 9:46 pm
Location: United States

Re: Keyboard input

Post 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!
Skylight: https://github.com/austanss/skylight

I make stupid mistakes and my vision is terrible. Not a good combination.

NOTE: Never respond to my posts with "it's too hard".
User avatar
eekee
Member
Member
Posts: 891
Joined: Mon May 22, 2017 5:56 am
Location: Kerbin
Discord: eekee
Contact:

Re: Keyboard input

Post 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.)
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Keyboard input

Post 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.
Carpe diem!
Post Reply