My Implementation of getchar...

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
TheLittleWho
Member
Member
Posts: 51
Joined: Sun Mar 01, 2015 7:58 am

My Implementation of getchar...

Post by TheLittleWho »

Maybe this is a very stupid post, but I will post it anyway :))

I am trying to create a getchar function:

Code: Select all

int getchar()
{
	for (;;) {
		if (kb_interrupt) { // check if a keyboard interrupt was received, if yes,break infinite loop
			break;
		}
	}
	int c = ((uint8_t*)stdin)[in_size - 1]; // read last char from 'stdin', is my stdin version, i know it is different from its Unix definition
	putchar(c); // put the char
	kb_interrupt = 0; // set the keyboard interrupt check variable to 0
	
	return c;
}
The keyboard handlers:

Code: Select all

void keyboard_interrupt_handler(__attribute__ ((unused)) registers_t regs)
{
	uint8_t scancode = inb(0x60);
	int special = 0;
	
	if (scancode & 0x80) {
		scancode &= 0x7F;
		if (scancode == KRLEFT_SHIFT || scancode == KRRIGHT_SHIFT) {
			shift = 0;
			special = 1;
		}
	} else {
		if (scancode == KRLEFT_SHIFT || scancode == KRRIGHT_SHIFT) {
				shift = 1;
				special = 1;
		}
		
		if (shift) {
			kb_buffer[last++] = ascii_S[scancode];
		} else {
			kb_buffer[last++] = ascii_s[scancode];
		}
		
		if (special != 1) {
			cli();
			read_kb_buff(kb_buffer, last);
			sti();
		}
		
		if (last == KEYBOARD_BUFFER_SIZE) {
			last = 0;
		}
	}
}

void read_kb_buff(uint8_t *buf, uint16_t size) 
{
	((uint8_t*) stdin)[in_size] = buf[size - 1];
	in_size++;
	kb_interrupt = 1;
}
If I call getchar in my kernel main function, the getchar infinite loop never breaks so the char never get returned and printed on the screen. But I observed, If I print something in the getchar infinite loop, It works, so I created a 'nothing escape character' ('\g'), that print nothing, but makes getchar works.

New getchar code:

Code: Select all

int getchar()
{
	for (;;) {
		putchar('\g');
		if (kb_interrupt) {
			break;
		}
	}
	int c = ((uint8_t*)stdin)[in_size - 1];
	putchar(c);
	kb_interrupt = 0;
	
	return c;
}


So, why is this happening, why I need to print something in the getchar loop to make it works?

PS Kernel code at: https://github.com/JustBeYou/MyOS/tree/devel/src

Thanks!
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: My Implementation of getchar...

Post by Techel »

Make kb_interrupt volatile to prevent the compiler to optimize the loop to an infinity loop.
TheLittleWho
Member
Member
Posts: 51
Joined: Sun Mar 01, 2015 7:58 am

Re: My Implementation of getchar...

Post by TheLittleWho »

Solved! Thanks a lot!
Post Reply