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$>
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.

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()
  new_handler.pm_offset = (unsigned) my_int;
  new_handler.pm_selector = _go32_my_cs();
  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 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;

  /*  printf("here I am in newcoroutine()\n"); */

  new = (coroutine *)malloc(sizeof(coroutine));
  new->stack = (unsigned long *)malloc(sizeof(unsigned long)*
  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;
  return new;

void sched()

    if(save())                /* You are expected to understand this
      current = next_function(); 

int save()
  if (q != NULL)
	return _save();
  return 0;

int resume()
  return _resume();
.global __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

.global __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

- Raw text -

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