Date: Tue, 04 May 1999 23:19:06 -0500 From: "Miguel A. Ordorica V." Subject: Help with interrupt wrapper, PLEASE (corrected) To: djgpp AT delorie DOT com Message-id: <003601be96ae$6b24c3c0$fc8426c8@df1.telmex.net.mx> MIME-version: 1.0 X-Mailer: Microsoft Outlook Express 5.00.2014.211 Content-type: MULTIPART/ALTERNATIVE; BOUNDARY="Boundary_(ID_4CFTEQZABfI8KWexlhzEpg)" 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_4CFTEQZABfI8KWexlhzEpg) Content-type: text/plain; charset=iso-8859-1 Content-transfer-encoding: quoted-printable /*Earlier today, I posted this same message but It somehow came out all = messed up. I hope it's right this time, sorry.*/ =20 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
/*Earlier today, I posted this same message = but It=20 somehow came out all messed up. I hope it's right this time,=20 sorry.*/
 
        Below is = the code=20 for an interrupt wrapper I'm trying to get to work, along with it's = setup code.=20 It is a modified version of the interrupt = wrapper code from Allegro. In theory, the wrapper allows for = two=20 different functions to be called: one with = interrupts=20 disabled and the other one with interrupts = enabled. This is=20 so that very long functions can be associated with = an irq without having interrupts = disabled long enough=20 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=20 called. Although the functions were never actually called, = the wrapper=20 WAS!! That was one out of every five tries or so, = the rest=20 of the time the program simply died and locked my machine up, and it seems that the farthest EIP ever got=20 was the ljump instruction below, so I can't tell if the code = after=20 that works at all.
 
        Please, = somebody=20 help me! I don't know what is wrong and there simply aren't any = experienced=20 ASM programmers around here! I've checked it about = a hundred=20 times and cannot find anything wrong. Any help would be=20 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;        =20 ;=20 \
 __wrapper_isr_inside_##x:      &= nbsp;           &n= bsp;           &nb= sp;           =20 ; \
   pushw=20 %ds           &nbs= p;            = ;     =20 /* save registers */       ; = \
  =20 pushw=20 %es           &nbs= p;            = ;            =             &= nbsp;       =20 ; \
   pushw=20 %fs           &nbs= p;            = ;            =             &= nbsp;       =20 ; \
   pushw=20 %gs           &nbs= p;            = ;            =             &= nbsp;       =20 ; \
  =20 pushal           &= nbsp;           &n= bsp;           &nb= sp;           &nbs= p;           =20 ;=20 \
           &n= bsp;   =20             &= nbsp;           &n= bsp;           &nb= sp;           &nbs= p;   =20 ; \
   .byte=20 0x2e           &nb= sp;           &nbs= p;    =20 /* cs: override */         ;=20 \
   movw ___djgpp_ds_alias,=20 %ax           &nbs= p;            = ;            =   =20 ; \
   movw %ax,=20 %ds           &nbs= p;            = ; =20 /* set up selectors */     ; \
   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;            = ;            =         =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;            = ;            =         =20 ; \
   movl %esp,=20 %ecx           &nb= sp;         =20   /* old stack in ecx + dx */; \
   movw %ss,=20 %dx           &nbs= p;            = ;            =             &= nbsp;   =20 ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =         =20 ; \
   movl %ebx,=20 %esp           &nb= sp;           =20 /* set up our stack */     ; \
   = movw=20 %ax,=20 %ss           &nbs= p;            = ;            =             &= nbsp;    ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =          ;=20 \
   pushl=20 %edx           &nb= sp;           &nbs= p;   =20 /* push old stack onto new*/; \
   pushl=20 %ecx           &nb= sp;           &nbs= p;            = ;            =         ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;     =20            =    =20 ; \
  =20 cld           &nbs= p;            = ;         *=20 clear the direction flag */ ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =          ;=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;            = ;            =          ;=20 \
  =20 cli           &nbs= p;            = ;            =             &= nbsp;           &n= bsp;  ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =          ;=20 \
   popl=20 %ecx           &nb= sp;           &nbs= p;     =20 /* restore the old stack */; \
   popl=20 %edx           &nb= sp;           &nbs= p;            = ;            =          ;=20 \
   movw %dx,=20 %ss           &nbs= p;            = ;            =             &= nbsp;    ;=20 \
   movl %ecx,=20 %esp           &nb= sp;           &nbs= p;            = ;            =    ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =          ;=20 \
   orl %eax,=20 %eax           &nb= sp;           &nbs= p;=20 /* check return value */   ; \
   jz=20 get_out_##x          &n= bsp;           &nb= sp;           &nbs= p;            = ;     ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =          ;=20 \
  =20 popal           &n= bsp;           &nb= sp;         =20 /* chain to old handler */ ; \
   popw=20 %gs           &nbs= p;            = ;            =             &= nbsp;         ;=20 \
   popw=20 %fs           &nbs= p;            = ;            =             &= nbsp;         ;=20 \
   popw=20 %es           &nbs= p;            = ;            =             &= nbsp;         ;=20 \
   popw=20 %ds           &nbs= p;            = ;            =             &= nbsp;         ;=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;          ;=20 \
   movl __temp,=20 %esi           &nb= sp;           &nbs= p;            = ;            =  ;=20 \
   ljmp=20 %cs:__addresses_old_isr+4*x       &nbs= p;            = ;            =   ;=20 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =          ;=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;         ;=20 \
   popw=20 %fs           &nbs= p;            = ;            =             &= nbsp;         ;=20 \
   popw=20 %es           &nbs= p;            = ;            =             &= nbsp;         ;=20 \
   popw=20 %ds           &nbs= p;            = ;            =             &= nbsp;         ;=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;          ;=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 \
           &n= bsp;           &nb= sp;           &nbs= p;            = ;            =          ;=20 \
.globl=20 __wrapper_isr_after_##x        &n= bsp;           &nb= sp;           &nbs= p;      ;=20 \
   .align=20 4            =             &= nbsp;           &n= bsp;           &nb= sp;         ;=20 \
  =20 __wrapper_isr_after_##x:        &= nbsp;           &n= bsp;           &nb= sp;         ;=20 \
   pushw=20 %ds           &nbs= p;            = ;            =             &= nbsp;        ;=20 \
   pushw=20 %es           &nbs= p;            = ;            =             &= nbsp;        ;=20 \
   pushw=20 %fs           &nbs= p;            = ;            =             &= nbsp;        ;=20 \
   pushw=20 %gs           &nbs= p;            = ;            =             &= nbsp;        ;=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;         ;=20 \
   popw=20 %fs           &nbs= p;            = ;            =             &= nbsp;         ;=20 \
   popw=20 %es           &nbs= p;            = ;            =             &= nbsp;         ;=20 \
   popw=20 %ds           &nbs= p;            = ;            =             &= nbsp;         ;=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_4CFTEQZABfI8KWexlhzEpg)--