On Thu, Jul 21, 2011 at 07:51:12PM +0300, Nikolay Nikolov wrote:
On 07/21/2011 03:51 AM, Kevin O'Connor wrote:
asm volatile ("int $0x1B":::"memory");
Can this use call16_simpint() instead? If not, calling an interrupt should probably backup/restore the register state.
I'm not sure if the registers need to be saved for int 1Bh. I don't know what the "spec" says about it. MS-DOS and FreeDOS by themselves certainly don't need it - they don't change any of the registers on return from their int 1B handlers. Also, the BIOSes I checked didn't seem to care about saving any registers before calling int 1B. On the other hand, potentially any DOS application might want to install its own int 1B handler and we don't know if some of them destroy the values in some registers but still happens to work with the most common BIOSes (by accident or otherwise).
Right - no sane 1B handler would alter register state, but it would be safer to do a backup/restore.
But saving all registers adds an extra overhead on the stack that may turn out to be unnecessary? What happens if we tell gcc in that inline asm block that all registers may be destroyed. Will it increase the overhead on the stack or will it just generate slightly less efficient code?
There is a tool in SeaBIOS which attempts to calculate stack usage:
objdump -m i386 -M i8086 -M suffix -d out/rom16.o | tools/checkstack.py
A full backup can be done with:
asm volatile ( "pushl %%ebp\n" "sti\n" "int $0x1B\n" "cli\n" "cld\n" "popl %%ebp" : : : "eax", "ebx", "ecx", "edx", "esi", "edi", "cc", "memory");
Replacing just the above in your patch does seem to increase stack usage a bit. However, I was able to play with it (use tail-recursion, use "noinline") to the point where I suspect it's possible to do the backup with no additional stack usage.
enqueue_key(0, 0);
RBIL implies the 0000 should be added to the keyboard buffer before the int 0x1B - though I'm not really familiar enough to say which is really correct.
I have tested this on several BIOSes and most of them add it after int 0x1B. These include:
an AWARD BIOS on a GA-K8NF9 mainboard Insyde H2o BIOS on a Sony VAIO laptop Microsoft Windows NT/2000/XP/Vista/7's dos box (NTVDM.EXE) MS-DOS 6.22's own keyb.exe driver, which replaces the BIOS' int 09h handler.
I have also found at least one BIOS, that adds it *before* int 0x1B. It's an IBM ThinkPad R30 laptop, with an IBM branded BIOS. Anyhow, I assumed that adding it after int 1B is more "standard", because it appears to be more common and at least that's what Microsoft does.
Okay thanks. After is fine.
-Kevin