To: djgpp AT delorie DOT com Subject: Re: My interrupt handler References: <7fcm2k$31g$2 AT news DOT luth DOT se> <20iuatubeq DOT fsf AT Sky DOT inp DOT nsk DOT su> <7fd7i4$bns$1 AT news DOT luth DOT se> From: Michael Bukin Date: 19 Apr 1999 02:42:07 +0700 In-Reply-To: ams@ludd.luth.se's message of "18 Apr 1999 18:16:36 GMT" Message-ID: <20pv51g1gw.fsf@Sky.inp.nsk.su> Lines: 90 X-Mailer: Gnus v5.5/Emacs 19.34 Reply-To: djgpp AT delorie DOT com ams AT ludd DOT luth DOT se (Martin Str|mberg) writes: > Yes. I tried that first. However as the program reports "New: > selector:offset = 319:5472." and "Old: selector:offset = 59:528." and > it didn't work I just thought it best to really use that (old) > selector. It will try to get jump destination from memory with offset _old_isr in segment pointed by %fs selector. Because this segment does not belong to your program (it belongs to DPMI server), trying to access it for reading will lead to unpredictable results. > > So any ideas? I have tried the following program. It works for me. #include #include #include #include #include __dpmi_paddr old_addr, new_addr; void handler (void); void handler_end (void); __asm__ (".globl _handler _handler: ljmp %cs:_old_addr .globl _handler_end _handler_end: nop"); int main (void) { int selector; __dpmi_paddr tmp_addr; _go32_dpmi_lock_data (&old_addr, sizeof (old_addr)); _go32_dpmi_lock_code (handler, ((unsigned long) handler_end - (unsigned long) handler)); printf ("memory locked\n"); if (__dpmi_get_protected_mode_interrupt_vector (0x31, &old_addr)) { fprintf (stderr, "can not get interrupt\n"); exit (EXIT_FAILURE); } printf ("got interrupt vector\n"); new_addr.selector = _my_cs (); new_addr.offset32 = (unsigned long) handler; if (__dpmi_set_protected_mode_interrupt_vector (0x31, &new_addr)) { fprintf (stderr, "can not set interrupt\n"); exit (EXIT_FAILURE); } printf ("set interrupt vector\n"); selector = __dpmi_allocate_ldt_descriptors (1); if (selector == -1) fprintf (stderr, "can not allocate selector\n"); else __dpmi_free_ldt_descriptor (selector); printf ("allocated LDT descriptor?\n"); while (__dpmi_get_protected_mode_interrupt_vector (0x31, &tmp_addr) || (tmp_addr.selector != new_addr.selector) || (tmp_addr.offset32 != new_addr.offset32) || __dpmi_set_protected_mode_interrupt_vector (0x31, &old_addr)) { fprintf (stderr, "can not restore interrupt\n"); system (""); } printf ("restored interrupt vector\n"); return EXIT_SUCCESS; } -- Michael Bukin