[SOLVED] Keyboard interrupt printing twice on single key press

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
BrickSigma
Posts: 3
Joined: Fri Jul 18, 2025 3:43 am
Libera.chat IRC: Brick Sigma

[SOLVED] Keyboard interrupt printing twice on single key press

Post by BrickSigma »

Hello there, I've recently started my OSDev journey by following the Babysteps tutorial for making a basic bootloader, and I've just finished the 5th part of it for implementing the keyboard interrupt handler.

[SOLUTION]: it has nothing to do with the interrupt, I setup my own version of scrolling the VGA text buffer when the y position of the cursor went beyond 25 rows, and forgot to clear the last row after shifting the buffer up. That was the main issue as to why it appeared to be printing twice, when in reality it printed and shifted the cells up, but didn't clear the last row.

[ORIGINAL POST]
One issue that I'm running into is that after a few key presses, a single key press results in the scan code being printed twice, for instance if I hit key A, 001E is printed twice rather than once. The first few key presses work fine and only print once though. I am aware that two interrupts are usually fired on a key press, one for the key going down and one for it being released, but I've added a condition in my interrupt handler to skip the print for key releases.

My interrupt handler is identical to the code provided in the tutorial as shown below:

Code: Select all

keyhandler:
    inb $0x60, %al  # Get key data
    mov %al, %bl  # Save it
    mov %al, port60

    inb $0x61, %al  # Keyboard control byte
    mov %al, %ah
    or $0x80, %al  # Disable bit 7
    outb %al, $0x61  # Send it back
    xchgb %al, %ah  # Get the original value and send it back
    outb %al, $0x61

    mov $0x20, %al  # Send the EOI (End of Interrupt signal) for the master controller
    outb %al, $0x20

    and $0x80, %bl  # Skip any scan codes indicating a key release
    jnz done

    # Print out the scan code in hexadecimal
    mov port60, %ax
    mov %ax, reg16
    call printreg16

done:
    iret

port60: .word 0
I've tried searching to see if other people have the same issue but haven't found any with the same issue. I've also tested the bootloader on physical hardware and it experiences the same issue when running in QEMU.

This is also the github link: https://github.com/BrickSigma/ChippyOS. It might be work noting that I'm building this in Linux using my system's installation of AS and LD for compiling the code, and I'll be switching to a cross compiler once I start programming it in C.

Thanks in advance and have a great day.
Octocontrabass
Member
Member
Posts: 5905
Joined: Mon Mar 25, 2013 7:01 pm

Re: Keyboard interrupt printing twice on single key press

Post by Octocontrabass »

BrickSigma wrote: Fri Jul 18, 2025 10:07 amfollowing the Babysteps tutorial
Keep in mind most tutorials - even ones on the wiki - have bugs.
BrickSigma wrote: Fri Jul 18, 2025 10:07 am

Code: Select all

keyhandler:
    inb $0x60, %al  # Get key data
Interrupts can happen while other code is running, so you probably need to save some registers at the beginning of your ISR so you can restore them before you return.
BrickSigma wrote: Fri Jul 18, 2025 10:07 am

Code: Select all

    inb $0x61, %al  # Keyboard control byte
    mov %al, %ah
    or $0x80, %al  # Disable bit 7
    outb %al, $0x61  # Send it back
    xchgb %al, %ah  # Get the original value and send it back
    outb %al, $0x61
Port 0x61 doesn't have anything to do with the keyboard outside of the original 8088-based PC and XT (and clones of those).
BrickSigma
Posts: 3
Joined: Fri Jul 18, 2025 3:43 am
Libera.chat IRC: Brick Sigma

Re: [SOLVED] Keyboard interrupt printing twice on single key press

Post by BrickSigma »

Thanks for the input, I'll definitely be more cautious with tutorials. Also thanks for the reminder about saving the register values, I can definitely see that becoming and issue later without addressing it.

As for port 0x61, is it then safe to leave that block of code out completely? I've been trying to read on it's exact usage but have only found a small reference about its bit field under the NMI section of the OSDev wiki...
Octocontrabass
Member
Member
Posts: 5905
Joined: Mon Mar 25, 2013 7:01 pm

Re: [SOLVED] Keyboard interrupt printing twice on single key press

Post by Octocontrabass »

BrickSigma wrote: Fri Jul 18, 2025 12:03 pmAs for port 0x61, is it then safe to leave that block of code out completely?
Yes.
BrickSigma wrote: Fri Jul 18, 2025 12:03 pmI've been trying to read on it's exact usage but have only found a small reference about its bit field under the NMI section of the OSDev wiki...
Bits 0 and 1 control timer 2 and the speaker connected to timer 2. On AT-compatibles, bits 2 and 3 enable and acknowledge NMIs for two kinds of hardware errors, bits 4 and 5 report outputs from two different timers, and bits 6 and 7 report which hardware error caused an NMI.

Bits 2-7 have different behavior on PC and XT, but you can read the technical references if you care about those.

Micro Channel PS/2 works like AT-compatibles, except bit 7 is also used to acknowledge IRQ0 without running the ISR.
BrickSigma
Posts: 3
Joined: Fri Jul 18, 2025 3:43 am
Libera.chat IRC: Brick Sigma

Re: [SOLVED] Keyboard interrupt printing twice on single key press

Post by BrickSigma »

Thanks for explaining and the link! Have a great day.
Post Reply