www.delorie.com/archives/browse.cgi   search  
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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019