delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/01/31/17:17:20

From: Jack Cai <cai AT haas DOT berkeley DOT edu>
Newsgroups: comp.os.msdos.djgpp
Subject: Interrupt using assembly, Please help!!!
Date: Fri, 31 Jan 1997 12:09:39 -0800
Organization: University of California, Berkeley
Lines: 227
Message-ID: <Pine.SOL.3.91.970131120434.14037A-100000@haas.berkeley.edu>
NNTP-Posting-Host: haas.berkeley.edu
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Oh, interrupts :( Please help!!!^M
^M
The compiler version is 2.01^M
^M
My frustration after a week of investigation. I want to use assembly to write^M
protected mode interrupt handler using __dpmi_ calls instead of _go32_ calls. ^M
I found out __dpmi_set_protected_interrupt_vector() is the same as the _go32_^M
except for the second parameter as demonstrated in the first code example.^M
^M
The following codes work, as observed by value of counter changing^M
command to generate: gcc -o tm1.exe tm1.c t1.s^M
--------^M
/* tm1.c */^M
^M
             #include <go32.h>^M
             #include <dpmi.h>^M
             #include <sys/segments.h>^M
             #include <string.h>^M
             #include <dos.h>^M
^M
             _go32_dpmi_seginfo old_handler,my_callback;^M
             __dpmi_paddr new_seg;^M
^M
             int counter;^M
             char *string;^M
extern       void my_int();^M
^M
             void init_handler() {^M
                  int error;^M
                  if ((error = _go32_dpmi_get_protected_mode_interrupt_vector(8,^M
                                      &old_handler)) == -1) {^M
                    printf ("e1\n");^M
                    exit(1);^M
                  }^M
                  my_callback.pm_offset = (unsigned long)my_int;^M
                  _go32_dpmi_allocate_iret_wrapper(&my_callback);^M
                  new_seg.offset32 = my_callback.pm_offset;^M
                  new_seg.selector = my_callback.pm_selector;^M
                  if ((error = __dpmi_set_protected_mode_interrupt_vector(8,^M
                                      &new_seg)) == -1) {^M
                    printf("e2\n");^M
                    exit(1);^M
                  }^M
             }^M
^M
             void done_handler() {^M
                  _go32_dpmi_set_protected_mode_interrupt_vector(8,^M
                                      &old_handler);^M
                  _go32_dpmi_free_iret_wrapper(&my_callback);^M
             }^M
^M
             main() {^M
                  char buffer[80],temp[80];^M
                  int ints;^M
^M
                  counter = 0;^M
                  init_handler();^M
                  ^M
^M
                  printf("Type some text followed by a CR,");^M
                  printf(" or EXIT to quit\n");^M
                  do {^M
                       printf("Counter =%d", counter);^M
                       strcpy(temp, "Hello\n");^M
                       scanf("%s", temp);^M
                       ints = disable(); //clear interrupts^M
                       strcpy(buffer,temp);^M
                       if(ints) enable(); //reenable interrupts^M
                  } while(stricmp(buffer,"EXIT"));^M
^M
                  done_handler();^M
             }^M
^M
###t1.s^M
        .global _my_int^M
^M
        .text^M
t_start_of_text:^M
_my_int:.global _my_int^M
        incl _counter^M
        ret                     ^M
t_end_of_text:^M
--------^M
^M
Then the frustration started....^M
^M
I change tm1.c a bit to use __dpmi calls without the wrapper call, change t1.s^M
 to use iret instead of ret and put a sti before it. No luck!^M
So, I dig into gopint.c to find out what goes on in allocate_wrapper call. ^M
I put^M
the fill around my assembly code, thinking that was it. Guess what, no luck!^M
counter remains 00000000000000....^M
After numerous tries with this seemingly small piece of code, I am posting for ^M
help! Codes follow:^M
^M
command to compile: gcc -o tm2.exe tm2.c t2.s^M
/* tm2.c */^M
#include <go32.h>^M
#include <dpmi.h>^M
#include <string.h>^M
#include <dos.h>^M
#include <sys/segments.h>^M
#include <sys/exceptn.h>^M
^M
__dpmi_paddr old_handler,my_callback;^M
char mystack[1024];^M
int stk_bottom = (int) mystack + 1024;^M
int counter;^M
unsigned short tt_ds;^M
char *string;^M
extern       void my_int();^M
^M
void init_handler() {^M
   int error;^M
^M
   tt_ds = (unsigned short)_my_ds;^M
   printf("my_ds:%d, __djgpp_ds_alias: %d\n", _my_ds, __djgpp_ds_alias);^M
   if ((error = __dpmi_get_protected_mode_interrupt_vector(8,^M
        &old_handler)) == -1) {^M
       printf ("e1\n");^M
       exit(1);^M
   }^M
   my_callback.offset32 = (unsigned long) my_int;^M
   my_callback.selector = (unsigned short)_my_cs;^M
   if ((error = __dpmi_set_protected_mode_interrupt_vector(8,^M
         &my_callback)) == -1) {^M
       printf("e2\n");^M
       exit(1);^M
   }^M
}^M
^M
void done_handler() {^M
    __dpmi_set_protected_mode_interrupt_vector(8,^M
                           &old_handler);^M
}^M
^M
main() {^M
  char buffer[80],temp[80];^M
  int ints;^M
^M
  counter = 0;^M
  init_handler();^M
                  ^M
  printf("Type some text followed by a CR,");^M
  printf(" or EXIT to quit\n");^M
  do {^M
     printf("Counter =%d", counter);^M
     strcpy(temp, "Hello\n");^M
     scanf("%s", temp);^M
     ints = disable(); //clear interrupts^M
     strcpy(buffer,temp);^M
     if(ints) enable(); //reenable interrupts^M
  } while(stricmp(buffer,"EXIT"));^M
 ^M
  done_handler();^M
}^M
^M
#t2.s^M
        .global _my_int^M
^M
        .text^M
t_start_of_text:^M
_my_int:.global _my_int^M
#wrapper code from gopint.c^M
        #save original registers^M
        pushw   %ds^M
        pushw   %es^M
        pushw   %fs^M
        pushw   %gs^M
        pushal^M
        #use current data segment^M
        mov     ___djgpp_ds_alias, %ax^M
        mov     %ax, %ds^M
        mov     %ax, %es^M
        mov     %ax, %fs^M
        mov     %ax, %gs^M
        #use current stack^M
        movl    $bottom, %ebx^M
        cld^M
        #save original esp in ecx^M
        movl    %esp, %ecx^M
        #save original ss in dx^M
        mov     %ss, %dx^M
        #use current data segment as ss^M
        mov     %ax, %ss^M
        #use current stack as esp^M
        movl    %ebx, %esp^M
        #save original ss and esp^M
        pushl   %edx^M
        pushl   %ecx^M
        incl    _counter^M
        #restore ss and esp^M
        popl    %eax^M
        popl    %ebx^M
        mov     %bx, %ss^M
        mov     %eax, %esp^M
        #restore all other registers^M
        popal^M
        popw    %gs^M
        popw    %fs^M
        popw    %es^M
        popw    %ds^M
        iret                    ^M
t_end_of_text:^M
t_start_of_data:        ^M
sss:    ^M
        .fill 100, 1, 0^M
bottom: ^M
        .long 0^M
t_end_of_data:^M
------^M
^M
Please advise to get counter ticking on tm2.c. Many thanks!!!^M
^M
Several related questions about the gopint.c comments. ^M
1) Why does it assume only cs and ss is available, thus the stack swapping^M
and segment register savings? I thought in flat mode, none of the segments ^M
change. ^M
2) Second, there is no sti in the wrapper code, contrary to the FAQ? ^M
^M
        ^M
^M
^M
^M
^M
^M

- Raw text -


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