Date: Tue, 04 May 1999 16:53:43 -0500 From: "Miguel A. Ordorica V." Subject: Help with interrupt wrapper, PLEASE = ( To: djgpp AT delorie DOT com Message-id: <001d01be9678$952abac0$f291e994@df1.telmex.net.mx> MIME-version: 1.0 X-Mailer: Microsoft Outlook Express 5.00.2014.211 Content-type: MULTIPART/ALTERNATIVE; BOUNDARY="Boundary_(ID_XytOd57ALm4yiMC+JoShAQ)" X-MSMail-Priority: Normal X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2014.211 X-Priority: 3 Reply-To: djgpp AT delorie DOT com This is a multi-part message in MIME format. --Boundary_(ID_XytOd57ALm4yiMC+JoShAQ) Content-type: text/plain; charset=iso-8859-1 Content-transfer-encoding: quoted-printable Below is the code for an interrupt wrapper I'm trying to get to = work, along with it's setup code. It is a modified version of the interrupt wrapper code from Allegro. In theory, the = wrapper allows for two different functions to be called: one with interrupts disabled and the other one with interrupts enabled. = This is so that very long functions can be associated with an irq without having interrupts disabled long enough to = mess up the program. That's theory, though. The truth is, this thing is WAY too = erratic. I tested it with a couple of simple functions that only set a flag when they were called. Although the functions were = never actually called, the wrapper WAS!! That was one out of every five tries or so, the rest of the time the = program simply died and locked my machine up, and it seems that the farthest EIP ever got was the ljump = instruction below, so I can't tell if the code after that works at all. Please, somebody help me! I don't know what is wrong and there = simply aren't any experienced ASM programmers around here! I've checked it about a hundred times and = cannot find anything wrong. Any help would be greatly appreciated. Miguel Angel. ordorica AT df1 DOT telmex DOT net DOT mx sleeptk AT geocities DOT com P.S. If you think this is not a good approach, please let me know of any = other I could use. .text #define WRAPPER(x) = ; \ .globl __wrapper_isr_inside_##x = ; \ .align 4 = ; \ __wrapper_isr_inside_##x: = ; \ pushw %ds /* save registers */ = ; \ pushw %es = ; \ pushw %fs = ; \ pushw %gs = ; \ pushal = ; \ ; \ .byte 0x2e /* cs: override */ = ; \ movw ___djgpp_ds_alias, %ax = ; \ movw %ax, %ds /* set up selectors */ = ; \ movw %ax, %es = ; \ movw %ax, %fs = ; \ movw %ax, %gs = ; \ = ; \ movl $x, %esi = ; \ movl __stacks(,%esi,4), %ebx = ; \ = ; \ movl %esp, %ecx /* old stack in ecx + dx */ = ; \ movw %ss, %dx = ; \ = ; \ movl %ebx, %esp /* set up our stack */ = ; \ movw %ax, %ss = ; \ = ; \ pushl %edx /* push old stack onto new */ = ; \ pushl %ecx = ; \ ; \ cld /* clear the direction flag */ = ; \ = ; \ movl __addresses_isr_inside(,%esi,4), %eax = ; \ call *%eax /* call the C handler */ = ; \ = ; \ cli = ; \ = ; \ popl %ecx /* restore the old stack */ = ; \ popl %edx = ; \ movw %dx, %ss = ; \ movl %ecx, %esp = ; \ = ; \ orl %eax, %eax /* check return value */ = ; \ jz get_out_##x = ; \ = ; \ popal /* chain to old handler */ = ; \ popw %gs = ; \ popw %fs = ; \ popw %es = ; \ popw %ds = ; \ pushl __flags = ; \ pushl __code_sel = ; \ movl %esi, __temp = ; \ movl $x, %esi = ; \ pushl __addresses_isr_after(,%esi,4) = ; \ movl __temp, %esi = ; \ ljmp %cs:__addresses_old_isr+4*x = ; \ = ; \ get_out_##x: = ; \ popal /* iret */ = ; \ popw %gs = ; \ popw %fs = ; \ popw %es = ; \ popw %ds = ; \ pushl __flags = ; \ pushl __code_sel = ; \ movl %esi, __temp = ; \ movl $x, %esi = ; \ pushl __addresses_isr_after(,%esi,4) = ; \ movl __temp, %esi = ; \ sti = ; \ iret = ; \ = ; \ .globl __wrapper_isr_after_##x = ; \ .align 4 = ; \ __wrapper_isr_after_##x: = ; \ pushw %ds = ; \ pushw %es = ; \ pushw %fs = ; \ pushw %gs = ; \ pushal = ; \ movl $x, %esi = ; \ movl __addresses_isr_after(,%esi,4), %eax = ; \ call *%eax = ; \ cli = ; \ popal = ; \ popw %gs = ; \ popw %fs = ; \ popw %es = ; \ popw %ds = ; \ sti = ; \ iret WRAPPER(0); WRAPPER(1); WRAPPER(2); WRAPPER(3); WRAPPER(4); WRAPPER(5); WRAPPER(6); WRAPPER(7); .globl __wrapper_isr_inside_0_end .align 4 __wrapper_isr_inside_0_end: ret Somewhere else... extern void _wrapper_isr_inside_0(), _wrapper_isr_inside_1(), = _wrapper_isr_inside_2(), _wrapper_isr_inside_3(), _wrapper_isr_inside_4(), = _wrapper_isr_inside_5(), _wrapper_isr_inside_6(), _wrapper_isr_inside_7(), _wrapper_isr_inside_0_end(), _wrapper_isr_after_0(), _wrapper_isr_after_1(), = _wrapper_isr_after_2(), _wrapper_isr_after_3(), _wrapper_isr_after_4(), = _wrapper_isr_after_5(), _wrapper_isr_after_6(), _wrapper_isr_after_7(); dword _flags, _temp, _code_sel; dword _addresses_isr_inside[NO_OF_WRAPPERS], _addresses_isr_after[NO_OF_WRAPPERS], _addresses_old_isr[NO_OF_WRAPPERS]; int _int_numbers[NO_OF_WRAPPERS]; __dpmi_paddr _old_handlers[NO_OF_WRAPPERS]; byte *_stacks[NO_OF_WRAPPERS]; int irq_handling_startup(void) { int counter; for(counter=3D0; counter
        Below is the = code for an=20 interrupt wrapper I'm trying to get to work, along with it's setup code. = It is a=20 modified
version of the interrupt wrapper code from=20 Allegro. In theory, the wrapper allows for two different functions to be = called:
one with interrupts disabled = and the other=20 one with interrupts enabled. This is so that very long functions can=20 be
associated with an irq without = having=20 interrupts disabled long enough to mess up the = program.
        That's = theory,=20 though. The truth is, this thing is WAY too erratic. I tested it with a = couple=20 of simple functions
that only set a flag when they were called. Although = the=20 functions were never actually called, the wrapper = WAS!!
That was one out of every five tries or so, the rest = of the=20 time the program simply died and locked my machine
up, and it seems that the = farthest EIP ever got was the ljump instruction below, = so I can't tell if=20 the code after that
works at all.
 
        Please, = somebody=20 help me! I don't know what is wrong and there simply aren't any=20 experienced
ASM programmers around here! I've checked it about a = hundred=20 times and cannot find anything wrong. Any help would
be greatly appreciated.
 
 
        =    =20     Miguel Angel.
        =    =20     ordorica AT df1 DOT telmex DOT net DOT mx=
        =    =20     sleeptk AT geocities DOT com
 
 
P.S. If you think this is not a good approach, = please let me=20 know of any other I could use.
 
.text
 

#define=20 WRAPPER(x)          &nb= sp;           &nbs= p;            = ;            =          =20 ; \
.globl=20 __wrapper_isr_inside_##x        &= nbsp;           &n= bsp;           &nb= sp;          =20 ; \
   .align=20 4            =             &= nbsp;           &n= bsp;           &nb= sp;           &nbs= p;  =20 ;=20 \
 __wrapper_isr_inside_##x:      &= nbsp;           &n= bsp;           &nb= sp;           &nbs= p;     =20 ; \
   pushw=20 %ds           &nbs= p;            = ;     =20 /* save registers=20 */            = ; ;=20 \
   pushw=20 %es           &nbs= p;            = ;            =             &= nbsp;           &n= bsp; =20 ; \
   pushw=20 %fs           &nbs= p;            = ;            =             &= nbsp;           &n= bsp; =20 ; \
   pushw=20 %gs           &nbs= p;            = ;            =             &= nbsp;           &n= bsp; =20 ; \
  =20 pushal           &= nbsp;           &n= bsp;           &nb= sp;           &nbs= p;            = ;     =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;     =20 ; \
   .byte=20 0x2e           &nb= sp;           &nbs= p;    =20 /* cs: override=20 */            = ;  =20 ; \
   movw ___djgpp_ds_alias,=20 %ax           &nbs= p;            = ;            =         =20 ; \
   movw %ax,=20 %ds           &nbs= p;            = ; =20 /* set up selectors=20 */           ;=20 \
   movw %ax,=20 %es           &nbs= p;            = ;            =             &= nbsp;         =20 ; \
   movw %ax,=20 %fs           &nbs= p;            = ;            =             &= nbsp;         =20 ; \
   movw %ax,=20 %gs           &nbs= p;            = ;            =             &= nbsp;         =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
   movl $x,=20 %esi           &nb= sp;           &nbs= p;            = ;            =           =20 ; \
   movl __stacks(,%esi,4),=20 %ebx           &nb= sp;           &nbs= p;            = ;       =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
   movl %esp,=20 %ecx           &nb= sp;           =20 /* old stack in ecx + dx */      ; = \
  =20 movw %ss,=20 %dx           &nbs= p;            = ;            =             &= nbsp;         =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
   movl %ebx,=20 %esp           &nb= sp;           =20 /* set up our stack=20 */           ;=20 \
   movw %ax,=20 %ss           &nbs= p;            = ;            =             &= nbsp;         =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
   pushl=20 %edx           &nb= sp;           &nbs= p;    =20 /* push old stack onto new */    ; \
   = pushl=20 %ecx           &nb= sp;           &nbs= p;            = ;            =             &= nbsp;=20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;     =20       ; \
  =20 cld           &nbs= p;            = ;           =20 /* clear the direction flag */   ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
   movl __addresses_isr_inside(,%esi,4),=20 %eax           &nb= sp;           &nbs= p;     =20 ; \
   call=20 *%eax           &n= bsp;           &nb= sp;    =20 /* call the C handler */         = ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
  =20 cli           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;       =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
   popl=20 %ecx           &nb= sp;           &nbs= p;     =20 /* restore the old stack */      ; = \
  =20 popl=20 %edx           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
   movw %dx,=20 %ss           &nbs= p;            = ;            =             &= nbsp;         =20 ; \
   movl %ecx,=20 %esp           &nb= sp;           &nbs= p;            = ;            =         =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
   orl %eax,=20 %eax           &nb= sp;           &nbs= p;=20 /* check return value */         = ;=20 \
   jz=20 get_out_##x          &n= bsp;           &nb= sp;           &nbs= p;            = ;          =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
  =20 popal           &n= bsp;           &nb= sp;         =20 /* chain to old handler */       ;=20 \
   popw=20 %gs           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   popw=20 %fs           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   popw=20 %es           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   popw=20 %ds           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   pushl=20 __flags           =             &= nbsp;           &n= bsp;           &nb= sp;          =20 ; \
   pushl=20 __code_sel          &nb= sp;           &nbs= p;            = ;            =         =20 ; \
   movl %esi,=20 __temp           &= nbsp;           &n= bsp;           &nb= sp;           &nbs= p;      =20 ; \
   movl $x,=20 %esi           &nb= sp;           &nbs= p;            = ;            =           =20 ; \
   pushl=20 __addresses_isr_after(,%esi,4)       &= nbsp;           &n= bsp;           &nb= sp;   =20 ; \
   movl __temp,=20 %esi           &nb= sp;           &nbs= p;            = ;            =       =20 ; \
   ljmp=20 %cs:__addresses_old_isr+4*x       &nbs= p;            = ;            =        =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ;=20 \
get_out_##x:         &n= bsp;           &nb= sp;           &nbs= p;            = ;            =     =20 ; \
  =20 popal           &n= bsp;           &nb= sp;         =20 /* iret=20 */            = ;          =20 ; \
   popw=20 %gs           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   popw=20 %fs           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   popw=20 %es           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   popw=20 %ds           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   pushl=20 __flags           =             &= nbsp;           &n= bsp;           &nb= sp;          =20 ; \
   pushl=20 __code_sel          &nb= sp;           &nbs= p;            = ;            =         =20 ; \
   movl %esi,=20 __temp           &= nbsp;           &n= bsp;           &nb= sp;           &nbs= p;      =20 ; \
   movl $x,=20 %esi           &nb= sp;           &nbs= p;            = ;            =           =20 ; \
   pushl=20 __addresses_isr_after(,%esi,4)       &= nbsp;           &n= bsp;           &nb= sp;   =20 ; \
   movl __temp,=20 %esi           &nb= sp;           &nbs= p;            = ;            =       =20 ; \
  =20 sti           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;       =20 ; \
  =20 iret           &nb= sp;           &nbs= p;            = ;            =             &= nbsp;      =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =             &= nbsp; =20 ; \
.globl=20 __wrapper_isr_after_##x        &n= bsp;           &nb= sp;           &nbs= p;           =20 ; \
   .align=20 4            =             &= nbsp;           &n= bsp;           &nb= sp;           &nbs= p;  =20 ; \
  =20 __wrapper_isr_after_##x:        &= nbsp;           &n= bsp;           &nb= sp;           &nbs= p;  =20 ; \
   pushw=20 %ds           &nbs= p;            = ;            =             &= nbsp;           &n= bsp; =20 ; \
   pushw=20 %es           &nbs= p;            = ;            =             &= nbsp;           &n= bsp; =20 ; \
   pushw=20 %fs           &nbs= p;            = ;            =             &= nbsp;           &n= bsp; =20 ; \
   pushw=20 %gs           &nbs= p;            = ;            =             &= nbsp;           &n= bsp; =20 ; \
  =20 pushal           &= nbsp;           &n= bsp;           &nb= sp;           &nbs= p;            = ;     =20 ; \
   movl $x,=20 %esi           &nb= sp;           &nbs= p;            = ;            =           =20 ; \
   movl __addresses_isr_after(,%esi,4),=20 %eax           &nb= sp;           &nbs= p;      =20 ; \
   call=20 *%eax           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =  =20 ; \
  =20 cli           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;       =20 ; \
  =20 popal           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =       =20 ; \
   popw=20 %gs           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   popw=20 %fs           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   popw=20 %es           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
   popw=20 %ds           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  =20 ; \
  =20 sti           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;       =20 ; \
   iret
 

WRAPPER(0);
WRAPPER(1);
WRAPPER(2);
WRAPPER(3);
WRAP= PER(4);
WRAPPER(5);
WRAPPER(6);
WRAPPER(7);
 

.globl=20 __wrapper_isr_inside_0_end
   .align=20 4
__wrapper_isr_inside_0_end:
   ret
 
 
Somewhere else...
 
 
extern void = _wrapper_isr_inside_0(),=20 _wrapper_isr_inside_1(),=20 _wrapper_isr_inside_2(),
       &nb= sp;   =20 _wrapper_isr_inside_3(), _wrapper_isr_inside_4(),=20 _wrapper_isr_inside_5(),
       &nb= sp;   =20 _wrapper_isr_inside_6(),=20 _wrapper_isr_inside_7(),
       &nb= sp;   =20 _wrapper_isr_inside_0_end(),
       = ;    =20 _wrapper_isr_after_0(), _wrapper_isr_after_1(),=20 _wrapper_isr_after_2(),
       &nbs= p;   =20 _wrapper_isr_after_3(), _wrapper_isr_after_4(),=20 _wrapper_isr_after_5(),
       &nbs= p;   =20 _wrapper_isr_after_6(), _wrapper_isr_after_7();
 
 
 dword _flags, _temp,=20 _code_sel;
 dword=20 _addresses_isr_inside[NO_OF_WRAPPERS],
     &= nbsp;=20 _addresses_isr_after[NO_OF_WRAPPERS],
     &n= bsp;=20 _addresses_old_isr[NO_OF_WRAPPERS];
 int  =20 _int_numbers[NO_OF_WRAPPERS];
 __dpmi_paddr=20 _old_handlers[NO_OF_WRAPPERS];
 byte=20 *_stacks[NO_OF_WRAPPERS];
 

int=20 irq_handling_startup(void)
{
 int counter;
 
  for(counter=3D0;=20 counter<NO_OF_WRAPPERS; counter++)
    =20 {
      =20 _addresses_isr_inside[counter]=3DNULL;
     &= nbsp;=20 _addresses_isr_after[counter]=3DNULL;
     &n= bsp;=20 _addresses_old_isr[counter]=3D=3DNULL;
     &= nbsp;=20 _int_numbers[counter]=3D=3DNULL;
       = _stacks[counter]=3D((byte=20 *)malloc(STACK_SIZE))+STACK_SIZE-32;
     &nb= sp;=20 LOCK_ARRAY(_stacks[counter]-STACK_SIZE+32, STACK_SIZE,=20 sizeof(byte));
     }
 
  = _code_sel=3D_my_cs();
 
  __asm__=20 volatile
    (
    =20 "pushfl\n\t
      popl=20 %%eax\n\t
      movl %%eax,=20 __flags\n\t"
      :=20 :
      : "eax", = "memory"
   =20 );
 
 =20 LOCK_FUNCTION(_wrapper_isr_inside_0);
 =20 LOCK_ARRAY(_addresses_isr_inside, NO_OF_WRAPPERS, = sizeof(dword));
 =20 LOCK_ARRAY(_addresses_isr_after, NO_OF_WRAPPERS, = sizeof(dword));
 =20 LOCK_ARRAY(_addresses_old_isr, NO_OF_WRAPPERS, sizeof(dword));
  = LOCK_ARRAY(_int_numbers, NO_OF_WRAPPERS, sizeof(int));
 =20 LOCK_ARRAY(_old_handlers, NO_OF_WRAPPERS, = sizeof(__dpmi_paddr));
 =20 LOCK_ARRAY(_stacks, NO_OF_WRAPPERS, sizeof(dword));
 =20 LOCK_VARIABLE(_temp);
  LOCK_VARIABLE(_flags);
 =20 LOCK_VARIABLE(_code_sel);
 
 return = 0;
}
 
int take_over_irq(int number, = int=20 (*inside)(void), void (*after)(void))
{
 int=20 counter;
 __dpmi_paddr address;
 
   for(counter=3D0;=20 counter<NO_OF_WRAPPERS; counter++)
     =20 {
       =20 if(_addresses_isr_inside[counter]=3D=3DNULL)
    &= nbsp;    =20 goto free1;
      }
 
   return = -1;
 
 free1:
 
  =20 _int_numbers[counter]=3Dnumber;
  =20 _old_handlers[counter].selector=3D_my_cs();
  =20 _addresses_isr_inside[counter]=3D(dword)inside;
  =20 _addresses_isr_after[counter]=3D(dword)after;
 
  =20 switch(counter)
    =20 {
       default: return=20 -1;
       case 0:=20 address.offset32=3D(dword)_wrapper_isr_inside_0;=20 break;
       case 1:=20 address.offset32=3D(dword)_wrapper_isr_inside_1;=20 break;
       case 2:=20 address.offset32=3D(dword)_wrapper_isr_inside_2;=20 break;
       case 3:=20 address.offset32=3D(dword)_wrapper_isr_inside_3;=20 break;
       case 4:=20 address.offset32=3D(dword)_wrapper_isr_inside_4;=20 break;
       case 5:=20 address.offset32=3D(dword)_wrapper_isr_inside_5;=20 break;
       case 6:=20 address.offset32=3D(dword)_wrapper_isr_inside_6;=20 break;
       case 7:=20 address.offset32=3D(dword)_wrapper_isr_inside_7;=20 break;
     }
 
  =20 address.selector=3D_my_cs();
  =20 __dpmi_get_protected_mode_interrupt_vector(number,=20 &(_old_handlers[counter]));
  =20 _addresses_old_isr[counter]=3D_old_handlers[counter].offset32;
 &= nbsp;=20 if(__dpmi_set_protected_mode_interrupt_vector(number,=20 &address))
     return -1;
 
 return = 0;
}
 
--Boundary_(ID_XytOd57ALm4yiMC+JoShAQ)--