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.