www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/03/14/09:56:11

Date: Tue, 14 Mar 1995 09:44:33 -0300
From: acmq AT beta DOT coe DOT ufrj DOT br (Antonio Carlos Moreirao de Queiroz)
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: Interrupt conflict

I am having problems with an interrupt conflict.

I have a program that installs a real-time interrupt handler, and
then enters a loop that can call keyboard functions through int 16.
When these functions are not called, or the interrupt handler is
not installed, the program works correctly.
In normal operation, it crashes after some time, freezing or rebooting
the computer.
Before the crash, some messages saying "Unsupported int 0x2f" appear.
Sometimes also appear "Unsupported int 0x0d", or "Exception 47".
DPMI is not being used.
A version of the same program for Borland C works correctly.

I tried, without noticeable results:
- To clear the registers SS, SP, and FLAGS before the call to int 16,
  as recommended in the FAQ.
- Placing disable() and enable() around the calls to int 16.
- To make the interrupt handler do nothing.
- Disable all the optimizations.

Can an timer interruption inside _go32_dpmi_simulate_int() cause
a crash? Even with the interrupt handler being an empty function or
with interruptions disabled?

Below is a test program that demonstrates the problem.
Save as "testint.c", compile with "gcc testint.c -lpc -o testint",
and run with "go32 testint".
After the initial questions, it should print "121212..." until
ScrollLock is pressed, when it should stop. This only works if
the answer to the first question is "n".
The program was tested with versions 1.15m5 and 1.2m2, with the 
same result.

Some idea?

Antonio C. M. de Queiroz

#include <string.h>
#include <stdlib.h>
#include <dos.h>
#include <stdio.h>
#include <go32.h>
#include <dpmi.h>
#include <gppconio.h>

_go32_dpmi_registers regs,regsint;
_go32_dpmi_seginfo old_handler,new_handler;
int a,connected;

void Interruptor(_go32_dpmi_registers *r)
{
  if (a==-1) a=5000;
}

void Connect_interrupt(void)
{
  if (!connected) {
    _go32_dpmi_get_real_mode_interrupt_vector(0x1C,&old_handler);
    new_handler.pm_offset=(int)Interruptor;
    _go32_dpmi_allocate_real_mode_callback_iret(&new_handler,&regsint);
    _go32_dpmi_set_real_mode_interrupt_vector(0x1C,&new_handler);
    connected=1;
    puts("Connected");
  }
}

void Disconnect_interrupt(void)
{
  /* Disconnects the interrupt handler */
  if (connected) {
    _go32_dpmi_set_real_mode_interrupt_vector(0x1C,&old_handler);
    _go32_dpmi_free_real_mode_callback(&new_handler);
    connected=0;
    puts("Disconnected");
  }
}

void main(void)
{
  char c;

  connected=0;
  puts("Connect interrupt? (y/n)");
  c=getch();
  if (c=='y') Connect_interrupt();
  puts("Enter loop? (y/n)");
  c=getch();
  if (c=='y') {
    puts("Press ScrollLock to exit");
    do {
      fputs("1",stdout);
      fflush(stdout);
      regs.x.ax=0x0100;
      regs.x.ss=regs.x.sp=regs.x.flags=0;
      _go32_dpmi_simulate_int(0x16,&regs);
      fputs("2",stdout);
      fflush(stdout);
      regs.x.ax=0x0200;
      regs.x.ss=regs.x.sp=regs.x.flags=0;
      _go32_dpmi_simulate_int(0x16,&regs);
    }
    while ((regs.x.ax & 0x0010)==0); /* ScrollLock inactive */
  }
  puts(".");
  Disconnect_interrupt();
  puts("End");
}

- Raw text -


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