Mail Archives: djgpp/1997/10/18/18:16:44
From: | cknight AT nmt DOT edu (Chris-top-her)
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | Help w/ Interrupts
|
Date: | 17 Oct 1997 22:06:58 GMT
|
Organization: | New Mexico Institute of Mining and Technology, Socorro NM
|
Lines: | 222
|
Message-ID: | <628ni2$dct$1@newshost.nmt.edu>
|
NNTP-Posting-Host: | rust.nmt.edu
|
Summary: | Timer interrupt help needed
|
Keywords: | timer, interrupt, PM, 2.01,
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
hello all,
I'm looking for little help with some code I'm writing.
I'm attempting to implement coroutines using DJGPP, w/ csdpmi as my
dpmi server. I am able to do a manual call to my sched routine and
everything is fine, but if I try to set it as the fn to call when a
timer interrupt happens the program dies on me. The best I've been
able to do is get 1 manual call, and 1 interrupt call to sched. I've
read through the faq on interrupts, and the problem I'm having seems
no clearer. Any help would be appreciated. I include source below.
Thanks,
Chris Knight
cknight AT nmt DOT edu
Note this is not all the code, just what I thought pertainent. If you
need more let me know.
------------------------timer functions ------------------------------
void my_int()
{
sched(); /* this doesn't work */
/* int_counter++; */ /* but this does */
}
void NewTimerInt()
{
_go32_dpmi_get_protected_mode_interrupt_vector(8,&old_handler);
new_handler.pm_offset = (unsigned) my_int;
new_handler.pm_selector = _go32_my_cs();
_go32_dpmi_chain_protected_mode_interrupt_vector(8,&new_handler);
printf("Original 1c = 0x%X\n",old_handler.pm_offset);
printf("New 1c offset = 0x%X\n",new_handler.pm_offset);
printf("New 1c selector = 0x%X\n", new_handler.pm_selector);
printf("Done with NewTimerInt()\n");
}
--------------------- include file ----------------------------
#include <stdio.h>
#include <pc.h>
#include <sys/types.h>
#include <dpmi.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <crt0.h>
#define NUMBEROFROUTINES 10
#define STACKSIZE 1000
/*handler structs for old timer int, and new chained timer int */
_go32_dpmi_seginfo old_handler, new_handler;
volatile int int_counter;
volatile int sched_count;
/* coroutine status */
#define RUNNABLE 1
#define WAITING 0
/*#define DEBUG */
typedef struct Coroutine{
unsigned long sp;
unsigned long bp;
unsigned long ax;
unsigned long bx;
unsigned long cx;
unsigned long dx;
unsigned long si;
unsigned long di;
unsigned long fl;
unsigned short cs;
unsigned short ds;
unsigned short es;
unsigned short fs;
unsigned short gs;
unsigned short ss;
unsigned long *stack;
int status;
} coroutine;
typedef struct Qnode{
coroutine *data;
struct Qnode *next;
} qnode;
extern coroutine* current;
extern qnode* q;
void init_functions();
void exit_init();
void make_runable(coroutine *);
coroutine* new_coroutine(void *);
void sched();
int save();
int resume();
void add_to_queue(coroutine *);
void remove_from_queue(coroutine *);
void my_int();
-----------------------------------------------------------------------
coroutine *new_coroutine(void *coroutine_address)
{
coroutine *new;
disable_ints();
/* printf("here I am in newcoroutine()\n"); */
new = (coroutine *)malloc(sizeof(coroutine));
new->stack = (unsigned long *)malloc(sizeof(unsigned long)*
STACKSIZE);
new->sp = new->bp = (unsigned long) (&new->stack[STACKSIZE]);
new->pc = (unsigned long) coroutine_address;
new->cs = get_cs() ;
new->ds = new->es = new->ss = get_ds() ;
new->fs = get_fs() ;
new->gs = get_gs() ;
new->fl = get_flags() ;
new->status = WAITING;
add_to_queue(new);
enable();
return new;
}
void sched()
{
disable_ints();
if(save()) /* You are expected to understand this
*/
{
sched_count++;
current = next_function();
resume();
enable_ints();
}
enable_ints();
return;
}
int save()
{
if (q != NULL)
return _save();
return 0;
}
int resume()
{
return _resume();
}
---------------------------------------------------------------------------
.global __resume
__resume:
call _disable_ints
pushl %ebp
movl %esp, %ebp # copy stack pointer
movl _current,%eax
movl 0x4(%eax),%esp
pushl 0x24(%eax) # get flags from current
popfl # push them in the right place
movw 0x32(%eax),%ss # dont do any more pushes after this
movw 0x30(%eax),%gs # until we get a new stack
movw 0x2E(%eax),%fs
movw 0x2C(%eax),%es
movw 0x2A(%eax),%ds # save cs for last
movl 0x20(%eax),%edi
movl 0x1C(%eax),%esi
movl 0x18(%eax),%edx
movl 0x14(%eax),%ecx
movl 0x10(%eax),%ebx # screw eax, its a return value (0)
movl 0x8(%eax),%ebp
movl 0x4(%eax),%esp # put new coroutine stack in place
addl $4,%esp # Throw out that stupid return address
pushfl #
pushw 0x28(%eax) # Push the %cs on the stack
pushl 0x0(%eax) # And the return address we want
xorl %eax,%eax # always fail
call _enable
ret
.global __save
__save:
pushl %ebp
movl %esp, %ebp # copy stack pointer
movl _current,%eax # put address of current for filling
pushl 0x4(%ebp) # get return address
popl 0x0(%eax) # put it first in current
movl %esp, 0x4(%eax)
movl %ebp, 0x8(%eax)
movl %eax, 0xC(%eax)
movl %ebx, 0x10(%eax)
movl %ecx, 0x14(%eax)
movl %edx, 0x18(%eax)
movl %esi, 0x1C(%eax)
movl %edi, 0x20(%eax)
pushfl # put flags on stack
popl 0x24(%eax) # now put them in current
movw %cs, 0x28(%eax)
movw %ds, 0x2A(%eax)
movw %es, 0x2C(%eax)
movw %fs, 0x2E(%eax)
movw %gs, 0x30(%eax)
movw %ss, 0x32(%eax)
movl $1,%eax # save always succeeds
movl %ebp, %esp
popl %ebp
ret
- Raw text -