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 »

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', '.'
};
char kbdus_shift[] = {
   0, 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', '.'
};
char kbdus_caps[] = {
   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', '.'
};

char keyConv(char rawinput)
{
   if(rawinput == (char)'\x12')
   {
      return kbdus_shift[(int)rawinput];
   }
   else if(rawinput == (char)'\x58')
   {
      return kbdus_caps[(int)rawinput];
   }
      else
   {
      return kbdus[(int)rawinput];
   }
}
This is my code at the end, it compiles but doesn't work
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Keyboard input

Post by iansjack »

SuperGabry64 wrote:The fact is that the only programming i've done is object oriented, so something like ansi c or assembly is completely new to me
Forget OS development for the time being. Get a good book on C and learn how to program with simple user programs. Also, do the same for assembler. Then read the Intel Programmer's Manual so that you understand the processor. Then you will be in a position to attempt simple OS development.

You need to become proficient with your tools before you can build a fine piece of furniture.

As a matter of interest, what language did you use for object-oriented programming?
SuperGabry64
Posts: 20
Joined: Tue Oct 20, 2020 10:38 am

Re: Keyboard input

Post by SuperGabry64 »

I programmed in c# java python, but i did a little of c++ and javascript
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Keyboard input

Post by iansjack »

SuperGabry64 wrote:I programmed in c# java python, but i did a little of c++ and javascript
In that case I'm extremely surprised that you have any problems with C.

But, my advice is still the same.
PeterX
Member
Member
Posts: 590
Joined: Fri Nov 22, 2019 5:46 am

Re: Keyboard input

Post by PeterX »

SuperGabry64 wrote:

Code: Select all

char keyConv(char rawinput)
{
   if(rawinput == (char)'\x12')
   {
      return kbdus_shift[(int)rawinput];
   }
   else if(rawinput == (char)'\x58')
   {
      return kbdus_caps[(int)rawinput];
   }
      else
   {
      return kbdus[(int)rawinput];
   }
}
You are using the same char for deciding if shift/caps is pressed and as the "main" char. That makes no sense.

Greetings
Peter
User avatar
bloodline
Member
Member
Posts: 264
Joined: Tue Sep 15, 2020 8:07 am
Location: London, UK

Re: Keyboard input

Post by bloodline »

PeterX wrote:
SuperGabry64 wrote:

Code: Select all

char keyConv(char rawinput)
{
   if(rawinput == (char)'\x12')
   {
      return kbdus_shift[(int)rawinput];
   }
   else if(rawinput == (char)'\x58')
   {
      return kbdus_caps[(int)rawinput];
   }
      else
   {
      return kbdus[(int)rawinput];
   }
}
You are using the same char for deciding if shift/caps is pressed and as the "main" char. That makes no sense.

Greetings
Peter
Ok, SuperGabry64 I really do commend your dedication to this task, but you really need a lower level understanding of computer systems.

A char is a basic type, it’s 8 bits in length and is for most purposes the smallest unit of information you will interact with, if it has the value of 0x12 that’s the only information it contains, you cannot pass it to a function and expect there to be any more information there. Your code is treating the char as a single unit and expecting there to be both a shift key press and another key press to be encoded in that 8bit value, thus your code cannot work... Now things are going to get bumpy...

This does get a bit tricky with old hardware like the PS/2 controller as they will encode information in the various bit positions. Bit 7 is special when receiving data from the keyboard, in order to use the information you need to mask out the bits you aren’t interested in and then split the information out to use it. You will use the basic logical operations (& | ! ^)for this.

With a keyboard your driver might best be implemented as a state machine where your transitions can be triggered by the values you receive. If you don’t know what a state machine is then you have some fun homework tonight.

-edit- also you need to read about “casting” because you do it a lot in your code for no reason!
CuriOS: A single address space GUI based operating system built upon a fairly pure Microkernel/Nanokernel. Download latest bootable x86 Disk Image: https://github.com/h5n1xp/CuriOS/blob/main/disk.img.zip
Discord:https://discord.gg/zn2vV2Su
SuperGabry64
Posts: 20
Joined: Tue Oct 20, 2020 10:38 am

Re: Keyboard input

Post by SuperGabry64 »

However, i really need to know what is my mistake and how to implement it
User avatar
bloodline
Member
Member
Posts: 264
Joined: Tue Sep 15, 2020 8:07 am
Location: London, UK

Re: Keyboard input

Post by bloodline »

SuperGabry64 wrote:However, i really need to know what is my mistake and how to implement it
I tired to be as explicit as possible in my previous post.

I think the biggest issue you have is that your programming experience is with very high level languages. At the Operating System level, you have almost no support from the programming language (though once you have set up a stack, C does a lot of heavy lifting for you with respect to data structures and structured programming).

As I pointed out previously, the PS/2 controller encodes information at the bit level, you will need to learn about bitwise operations, and how to implement them with masks and combinatorial logic... this forum is not about teaching basic programming skills like this, but I’m happy to point you in the right direction.
CuriOS: A single address space GUI based operating system built upon a fairly pure Microkernel/Nanokernel. Download latest bootable x86 Disk Image: https://github.com/h5n1xp/CuriOS/blob/main/disk.img.zip
Discord:https://discord.gg/zn2vV2Su
pranavappu007
Member
Member
Posts: 91
Joined: Mon Apr 20, 2020 11:02 am

Re: Keyboard input

Post by pranavappu007 »

SuperGabry64 wrote:The fact is that the only programming i've done is object oriented, so something like ansi c or assembly is completely new to me
Even though I've heard you can build kernels with C++, I think it's gonna be hard to simultaneously learn C to advanced level, assembly to intermediate level and operating systems and x86 architecture.

I recommend first get really familiar with C and ok with assembly. Also, you might need to check the wiki for basic functioning of CPU and other systems.

Also, I don't know how much you understand the code in the tutorial(I haven't read it yet). I actually recommend building it from scratch as it will give you more experience that editing a template. First, just write a boot loader yourself and print something. Then, use the BIOS to do basic function. When you are OK with assembly, move on to 32-bit and communicate using ports and memory I/O. If you got C running with your boot loader, actually you can write anything and run it(excluding C lib functions). The fact that I am just implementing IDT after a text editor, interface and even half working interpreter means it's not that hard to write simple C programs and work it in your computer( although I don't recommend you do the same as it can affect your design decisions).


Also, you'll need to write substitutes for C library functions on your own. And some things is easier(for me) to do in assembly than C. So you may also learn how C works inside, to properly communicate with assembly code.
A beginner developer/student. Likes to know stuff. Don't have an OS to put here.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Keyboard input

Post by iansjack »

Write your keyboard handling function as a simple user program to which you can input key codes. Run it under a debugger and watch what happens.

This really shouldn't be necessary - the error in your code has already been pointed out to you and is a very, very basic programming mistake.

My advice remains unchanged, You need to learn more about programming and simple data structures before you are ready to attempt OS development.
SuperGabry64
Posts: 20
Joined: Tue Oct 20, 2020 10:38 am

Re: Keyboard input

Post by SuperGabry64 »

1. Yes, i know that my experience is only with high level languages, in fact i'm learning c
2. Thank, i don't thinked of running in a debugger
User avatar
austanss
Member
Member
Posts: 377
Joined: Sun Oct 11, 2020 9:46 pm
Location: United States

Re: Keyboard input

Post by austanss »

I'm here just to post on what you would want to do in the future. When you implement an IDT, you want your IRQ1 interrupt handler to read from the keyboard port [0x60] and then use a function to convert it to a character.

If you need references, I have some source code I can share.

My keyboard driver source code:
https://github.com/microNET-OS/microCOR ... rc/kbd.cxx

My interrupts:
https://github.com/microNET-OS/microCOR ... rc/idt.cxx

Keep in mind that at the moment these functions do not work in my OS, my interrupts are broken after converting to 64-bit. So you may need to modify this in various ways that I am unsure of.
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".
SuperGabry64
Posts: 20
Joined: Tue Oct 20, 2020 10:38 am

Re: Keyboard input

Post by SuperGabry64 »

Ok, i managed (by learning some c) to convert to ascii characters, even using the itoa provided in the osdev site it show that the input correspond to the right ascii code, but when not using the itoa the printf prints a different character

This is my code for the conversion (for now it only conver the keys from 1 to backspace):

Code: Select all

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;
	}
}
rdos
Member
Member
Posts: 3297
Joined: Wed Oct 01, 2008 1:55 pm

Re: Keyboard input

Post by rdos »

bloodline wrote:With a keyboard your driver might best be implemented as a state machine where your transitions can be triggered by the values you receive. If you don’t know what a state machine is then you have some fun homework tonight.
State machines are the absolutely worst concepts used in older software and should be avoided at all costs. :-)
foliagecanine
Member
Member
Posts: 148
Joined: Sun Aug 23, 2020 4:35 pm

Re: Keyboard input

Post by foliagecanine »

SuperGabry64 wrote:This is my code for the conversion (for now it only conver the keys from 1 to backspace):

Code: Select all

uint8_t keyconv(uint8_t key)
code...
case 0xe:
      return -2;
      break;
code...
SuperGabry64, do note that uint8_t stands for Unsigned 8-bit Integer. So returning -2 will actually return the unsigned version of -2, which is 254 (0xFE). Your compiler probably gave you a warning.

And the switch might not be the best method versus a lookup table for the characters. For example, in this case you could simply do:

Code: Select all

uint8_t keyboard_lookup_table[] = {' ', ' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0xFE};

uint8_t keyconv(uint8_t key)
{
    if (key>0xE)
        return ' ';
    return keyboard_lookup_table[key];
}
I recommend you continue learning the programming language, and pay attention to compiler warnings. Often there is a way to resolve those warnings even if it is already working as intended.

Good luck!
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?
Post Reply