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 -