Page 2 of 2

Re: Trouble detecting keyboard inputs while in a game loop

Posted: Sat Feb 26, 2022 7:10 pm
by Caffeine
alexfru wrote:
Caffeine wrote:
iansjack wrote:No. But failure to do points 3 or 4 that I mentioned would mean that you get just one interrupt.
What do you mean by just get one interrupt?
The interrupt controller and the keyboard need to know that the CPU has finished handling the interrupt before there's another one generated and delivered to the CPU.
Is there a way to figure out if this is the issue? Also I do not know if any of the points you mentioned were done incorrectly. I don't think that they are but I may be missing something.

Re: Trouble detecting keyboard inputs while in a game loop

Posted: Sun Feb 27, 2022 12:31 am
by iansjack
Without seeing your code it's impossible to say. You should provide a link to an online repository.

Re: Trouble detecting keyboard inputs while in a game loop

Posted: Sun Feb 27, 2022 12:10 pm
by Caffeine
iansjack wrote:Without seeing your code it's impossible to say. You should provide a link to an online repository.
Here: https://github.com/zachary-d-r/CaffeineOS

Re: Trouble detecting keyboard inputs while in a game loop

Posted: Tue Mar 01, 2022 2:34 pm
by Caffeine
Octocontrabass wrote:
Caffeine wrote:To confirm - the Keyboard interrupt is not being called. I set up a breakpoint and it is not going off while in the loop.
Have you set EFLAGS.IF?

How and when do you initialize the interrupt controllers? (It should be done before you initialize the keyboard controller.)

How and when do you initialize the keyboard controller? (Usually you don't need to initialize much - just empty the output buffer.)
I believe I've se EFLAGS.IF. I've looked at the multiboot specification examples and am not sure if I did it right. I started with Brans Kernel Development tutorial and have not changed boot.asm since, so this is almost entirely copy and pasted from there.

Here I am setting constants for the multiboot header:

Code: Select all

; Declare constants for the multiboot header.
MAGIC equ 0x1BADB002
FLAG_VIDEO_MODE equ (1 << 2)
FLAGS equ FLAG_VIDEO_MODE
CHECKSUM equ -(MAGIC + FLAGS) & 0xFFFFFFFF
HEADER_ADDR equ 0 ; if flags[16] is set
LOAD_ADDR equ   0 ; if flags[16] is set
LOAD_END_ADDR equ   0 ; if flags[16] is set
BSS_END_ADDR equ 0 ; if flags[16] is set
ENTRY_ADDR equ 0 ; if flags[16] is set
MODE_TYPE equ 0 ; if flags[2] is set
WIDTH equ 0 ; if flags[2] is set
HEIGHT equ 0 ; if flags[2] is set
DEPTH equ 0x20 ; if flags[2] is set
And here is the .multiboot section:

Code: Select all

section .multiboot
align 4
	dd MAGIC
	dd FLAGS
	dd CHECKSUM
	dd HEADER_ADDR
	dd LOAD_ADDR
	dd LOAD_END_ADDR
	dd BSS_END_ADDR
	dd ENTRY_ADDR
	dd MODE_TYPE
	dd WIDTH
	dd HEIGHT
	dd DEPTH
And here is the keyboard code (after creating the scan code stuff to identify the key), also almost entirely copy and pasted from Brans Kernel Development Tutorial.

Code: Select all

int shiftPressed = 0;  // To check if shift is pressed

// Handles the keyboard interrupt
void keyboardHandler(struct regs *r) {
    unsigned char scancode;  // The scancode from our keyboard
    scancode = inportb(0x60);  // Read from the keyboards data register which is at 0x60

    // If the top bit of the byte we read from the keyboard is set, then a key has just been released
    if (scancode & 0x80) {
        // Use this to see if the user released the shift, alt or control keys
        switch (scancode) {
          case 0xaa: shiftPressed = 0; break;
        }
    }

    // Here a key was just pressed. Holding down a key means you will get repeated key press interrupts
    else {

        /* Just to show you how this works, we simply translate
        *  the keyboard scancode into an ASCII value, and then
        *  display it to the screen. You can get creative and
        *  use some flags to see if a shift is pressed and use a
        *  different layout, or you can add another 128 entries
        *  to the above layout to correspond to 'shift' being
        *  held. If shift is held using the larger lookup table,
        *  you would add 128 to the scancode when you look for it */

        switch (scancode) {
          // Arrowkeys
          // case 0x4b: moveCursorRealative(-1, 0); scroll();  break;
          // case 0x4d: moveCursorRealative(1, 0);  scroll(); break;
          // case 0x48: moveCursorRealative(0, -1); scroll();  break;
          // case 0x50: moveCursorRealative(0, 1);  scroll(); break;

          case 0x2a: shiftPressed = 1; break;  // Check if left shift is pressed
          case 0x36: shiftPressed = 1; break;  // Check if right shift is pressed

          default: { keyboardControll(getInput(kbdus[scancode], shiftPressed)); break; }
        }

    }
}

void installKeyboard() {
    installIrqHandler(1, keyboardHandler);
}
getInput returns the character depending on whether or not shift is pressed.

Re: Trouble detecting keyboard inputs while in a game loop

Posted: Tue Mar 01, 2022 4:57 pm
by Octocontrabass
Caffeine wrote:I believe I've se EFLAGS.IF. I've looked at the multiboot specification examples and am not sure if I did it right.
According to the Multiboot specification, EFLAGS.IF will always be clear when the bootloader passes control to your kernel, so it doesn't matter what you put in your multiboot header.

If you don't have any code elsewhere to set EFLAGS.IF, you'll never receive interrupts. If EFLAGS.IF is not set while your game loop is running, your game loop won't receive interrupts. You can check EFLAGS.IF in your debugger.

Re: Trouble detecting keyboard inputs while in a game loop

Posted: Wed Mar 02, 2022 11:46 am
by Caffeine
Octocontrabass wrote:
Caffeine wrote:I believe I've se EFLAGS.IF. I've looked at the multiboot specification examples and am not sure if I did it right.
According to the Multiboot specification, EFLAGS.IF will always be clear when the bootloader passes control to your kernel, so it doesn't matter what you put in your multiboot header.

If you don't have any code elsewhere to set EFLAGS.IF, you'll never receive interrupts. If EFLAGS.IF is not set while your game loop is running, your game loop won't receive interrupts. You can check EFLAGS.IF in your debugger.
Here is EFLAGS when in the GNU OS selection screen:

Code: Select all

(gdb) info reg eflags
eflags         0x2                 [ IOPL=0 ]
Here is is after I select my OS:

Code: Select all

(gdb) info reg eflags
eflags         0x200202            [ ID IOPL=0 IF ]
And here it is after I launch pong:

Code: Select all

(gdb) info reg eflags
eflags         0x200016            [ ID IOPL=0 AF PF ]
To be honest, I'm not sure what exactly all of this means, but is there a problem here?

And if there is, how do I set EFLAGS.IF in the game loop?

Re: Trouble detecting keyboard inputs while in a game loop

Posted: Wed Mar 02, 2022 12:01 pm
by iansjack
I wonder if you need to do a little more learning before progressing. I get the feeling that you have copied a lot of code without really understanding it or the basics of the processor operation. You are asking some very basic questions (What does EFLAGS mean? How do I set the interrupt enable flag?)

The Intel or AMD Programmer's Manuals are pretty essential reading for anyone interested in OS development.

Re: Trouble detecting keyboard inputs while in a game loop

Posted: Wed Mar 02, 2022 3:05 pm
by Caffeine
iansjack wrote:I wonder if you need to do a little more learning before progressing. I get the feeling that you have copied a lot of code without really understanding it or the basics of the processor operation. You are asking some very basic questions (What does EFLAGS mean? How do I set the interrupt enable flag?)

The Intel or AMD Programmer's Manuals are pretty essential reading for anyone interested in OS development.
Okay, so I have done some reading and I am able to set the interrupt enable flag:

Code: Select all

eflags         0x200216            [ ID IOPL=0 IF AF PF ]
But it still does not detect keyboard interrupts. The PIC is working now! What I did is I cleared EFAGS.IF and the set it again. Now I need to be able to detect keyboard interrupts.

Re: Trouble detecting keyboard inputs while in a game loop

Posted: Thu Mar 03, 2022 12:22 pm
by Caffeine
I figured it out! The keyboard is never sending an EOI because I called loadPong() before the function returns.