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 #include #include #include #include #include #include _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,®sint); _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,®s); fputs("2",stdout); fflush(stdout); regs.x.ax=0x0200; regs.x.ss=regs.x.sp=regs.x.flags=0; _go32_dpmi_simulate_int(0x16,®s); } while ((regs.x.ax & 0x0010)==0); /* ScrollLock inactive */ } puts("."); Disconnect_interrupt(); puts("End"); }