Xref: news2.mv.net comp.os.msdos.djgpp:1587 From: "Markus F.X.J. Oberhumer" 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 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp =============================================================================== Markus F.X.J. Oberhumer 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 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 Visit my homepage http://www.infosys.tuwien.ac.at/Staff/lux/marco