Mail Archives: djgpp/1996/03/02/01:26:18
Xref: | news2.mv.net comp.os.msdos.djgpp:1587
|
From: | "Markus F.X.J. Oberhumer" <markus DOT oberhumer AT jk DOT uni-linz DOT ac DOT at>
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | Interrupts: enable() vs sti ?
|
Date: | Fri, 01 Mar 1996 19:08:30 -0800
|
Organization: | Johannes Kepler University Linz
|
Lines: | 99
|
Message-ID: | <3137BBAE.5D78@jk.uni-linz.ac.at>
|
NNTP-Posting-Host: | pc04.edu.uni-linz.ac.at
|
Mime-Version: | 1.0
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
===============================================================================
Markus F.X.J. Oberhumer <markus DOT oberhumer AT jk DOT uni-linz DOT ac DOT at>
Subject: Interrupts: enable() vs sti ?
===============================================================================
Hello,
I recently posted a question regarding a problem when
using my low-level keyboard library libkb in a Windows DOS box
while everything was working fine when using CWSDPMI or QDPMI:
"... The graphics keeps moving, but the keyboard doesn't respond any more
- even the Windows hot keys are dead - and I have to do a cold boot.
This can occur the first time when I start it, but mostly around
the 5th or 6th time and I've never been able to start it more
than 15 times... "
Charles Sandmann <sandmann AT clio DOT rice DOT edu> responded:
> This sounds like the Windows loses hardware interrupts bug. If you
> mess with the interrupt flag, cli/sti, or dpmi interrupt clear functions,
> Windows sometimes gets confused and leaves interrupts disabled. It looks
> like a Win bug to us, but maybe something in exceptn.S isn't quite right.
libkb installs a protected mode interrupt vector for int 9.
The demo program is running in a loop calling kb_keypress().
Here comes a relevant code fragment from the library source:
....
// These are not volatile because all access outside the
// interrupt handler uses KB_DISABLE().
static unsigned char *_key_buffer_head = _key_buffer_start;
static unsigned char *_key_buffer_tail = _key_buffer_start;
....
// Note: do not call this with interrupts disabled
unsigned kb_keypress(void)
{
unsigned char scan, shift;
unsigned k;
if (!_kb_mode)
return 0;
kb_update();
KB_DISABLE();
if (_key_buffer_head == _key_buffer_tail)
{
KB_ENABLE();
return 0;
}
scan = *_key_buffer_tail++; /* get scan code */
shift = *_key_buffer_tail++; /* get shift code */
if (_key_buffer_tail >= _key_buffer_end)
_key_buffer_tail = _key_buffer_start;
KB_ENABLE();
k = scan | ((unsigned) shift << 8);
return k;
}
Originally I had been using the following defines:
#define KB_DISABLE() disable()
#define KB_ENABLE() enable()
These are just wrappers for __dpmi_get_and_disable_virtual_interrupt_state()
and __dpmi_get_and_enable_virtual_interrupt_state() in djgpp v2.
Inverting Charles' suggestion I tried the following:
#define KB_DISABLE() __asm__ __volatile__("cli \n")
#define KB_ENABLE() __asm__ __volatile__("sti \n" "cld \n")
and now the problem has gone !!!
I would like to release the final beta of libkb in the next days.
Could someone explain me
- why I should not use the new defines above - can there be problems ?
(libkb is working fine with Watcom C/32. The Watcom compiler
generates cli/sti assembler instructions as well.)
- why we use virtual interrupts when we are in a virtual DOS box anyway ?
Best regards,
Markus
Markus F.X.J. Oberhumer <markus DOT oberhumer AT jk DOT uni-linz DOT ac DOT at>
Visit my homepage http://www.infosys.tuwien.ac.at/Staff/lux/marco
- Raw text -