WhiteFalcon wrote on 2024-05-07, 11:24:
I have narrowed it down to one line, surprisingly its nothing to do with the store/restore or interrupts per se, its this line:
while (inportb(0x60) != 1) oldKeyHandler();
I didn't look into this before. This feels very wrong.
First - you can't (or rather shouldn't) spin any long task in the interrupt handler. Everything locks up, not being able to execute anything or trigger hardware events.
Second - you can't treat old handler as a function to call freely at any time. Probably Borland wraps up things for you, so IRET in the original handler is treated as far return with popf (I see pushf before doing far call into old handler). But the old handler also talks to PIC, repeatedly acknowledging interrupts no matter what those are.
Instead you should flag the new state in some variable, and restore the screen the next time you enter the interrupt handler and you see ESC scancode.
If you want to take controls away from the programs, you should not call the old handler at all, but then you must acknowledge the IRQ with PIC yourself.
The buzz you hear is likely the BIOS screaming the keyboard buffer is full, as you call the interrupt (i.e. event) handler repeatedly when there are no actual keypress events.
Normally you get handler called when the keyboard IRQ signaled there is a _new_ scancode. But now you spin in the loop, calling the original handler, which will see the same last scancode, regardless if the key was pressed or not, spamming the keyboard buffer.
WhiteFalcon wrote on 2024-05-07, 11:24:
Apparently DOS, unlike DOSBox, doesnt like the keyboard port to be hammered, even by a read.
It's not DOS, it's hardware. You abuse the PIC by repeatedly calling original handler, and you do not do so on actual keypress events.