[comp.windows.ms.programmer] MS Win and Interrupt

syau@aludra.usc.edu (Shu-Jye Syau) (04/10/91)

Hi :
    I am trying to use MS window to write a voice card program .
    I need to know how to set the interrupt vector for hardware interrupt .
    ( when voice comes in , ADC interrupt PC to info PC to get 8-bit data)
    Please Help .

    It is BETTER if you can send reply to me , THANKS .


scott
syau@aludra.usc.edu

iam@waikato.ac.nz (Ian McDonald) (04/16/91)

In article <16489@chaph.usc.edu>, syau@aludra.usc.edu (Shu-Jye Syau) writes:
> Hi :
>     I am trying to use MS window to write a voice card program .
>     I need to know how to set the interrupt vector for hardware interrupt .
>     ( when voice comes in , ADC interrupt PC to info PC to get 8-bit data)
>     Please Help .
>
Below is the code I used to set up vectors.  I am using mine for a voice card
as well - A Scott Instruments board.

Sorry I couln't reply by EMail - I have no priveledge to do that.
 
/* winvect.c */

/* A replacement for Microsoft's routines which are not in Windows libraries

   History

   iam 08 Jan 91 Created
*/

#include <windows.h>
#include "winvect.h"

void(_interrupt _far *_dos_getvect(unsigned intnum))() {
  void _far *vect;

  /* Dos function 35 is Get vector function.  Specify the interrupt in al
     and the vector will be returned in es:bx */

  _asm {
    mov ax,intnum
    mov ah,35h
    int 21h
    mov vect+2,es
    mov vect,bx
  }
  return(vect);
}

void _dos_setvect(unsigned intnum,void(_interrupt _far *handler)()) {

  /* Dos function 25 is set vector.  Put interrupt number in al,
     vector in ds:dx */

  _asm {
    push ds
    mov ax,intnum
    mov ah,25h
    lds dx,handler
    int 21h
    pop ds
  }
}

-- 
-------------------------------------------------------------------------
Ian McDonald  |                                           
52 Cook Street|                                             /  /\  /\
Hamilton      |   This space free for advertising !!       /  /  \/  \
New Zealand   |                                           /  /        \
+64-71-563438 |   I can receive mail but can't reply to it.  

iam@waikato.ac.nz (Ian McDonald) (04/26/91)

>From:	IN%"syau%aludra.usc.edu@usc.edu" 19-APR-1991 15:36:07.84
>To:	iam@waikato.ac.nz
>CC:	
>Subj:	Ms win3.0 and interrupt

>Hi :
>     Thanks for your reply on my message . some questions .
>     Do you have to use assembly , can't I just use MS C 6.0 to write the
>     _dos_setvect(int_num , int_handle) ;
I never succeeded :-(

>     Because I design the hardware by myself , and it works not bad under DOS .
>     I use IRQ2 to do interrupt request , so the int_num here under DOS is
>     0x0a , how about in Win3.0  , can I do the same way ?

I presume so.
>
>     And IS it possible I can get the source code from you , then I can
>     entirely understand how you use your voice card . I need that .

At the end of the message I have posted the install, deinstall and the
interrupt routine itself.

>     If you can't e-mail me , would you please post to 
>comp.windows.ms.programmer , I will check that group . Thanks .

OK.  Here it is.  Sorry about the delay

>scott
>USC
>syau@aludra.usc.edu

/*============================================================================
;
; name:        initaudio
;
; function:    installs a new SRB interrupt vector to service 
;              these digital audio routines
;
; arguments:   none
;
; returns:     returns zero if successful, or an AIR error code otherwise
;
;===========================================================================*/
#define I8259_CTL_REG  0x20            /* i/o address of 8259 control reg */
#define I8259_MASK_REG 0x21            /* i/o address of 8259 mask reg */
#define EOI            0x20            /* End of Interrupt to 8259 */

#define IDLE            0       /* audio status when no cmd in progress */


static unsigned char far* *   buflist_ptr; /* ptr to array of far buf ptrs */
static long*                  buflen_ptr;  /* ptr to array of buf lens */
static long                   bufposn;     /* index of current pos in curr buf */
static int                    numbufs;     /* number of buffers */
static int                    bufnum;      /* index of current audio buffer */
static unsigned               int_number=0; /* interrupt number */
static void (interrupt far * old_intvect)();
static int                    aud_status;  /* 0: off; PLAY, IRCD */
static unsigned short         imaskbit;    /* state of my bit in 8259 int mask */

static HANDLE *handle_ptr;
static unsigned char far *data_ptr;
static char audio_filename[MAX_FILENAME_LENGTH];
static Disk_Buffer_Type DiskBuffer[2];
static short act_disk_buf;
static BOOL finishing;
static BOOL buffers_locked;
static HWND hCommandWnd;
static WORD swap_buf_id,end_file_id;
long audio_file_length;
long current_posn;

unsigned int initaudio(void)             /* install audio interrupt vector */
{
   unsigned short imask, pat, i, len;

   if (srb_active < 0)
      return(AIR_SRBE_NOTOPEN);

   if ((srb_interrupt_num < 0x0B)
   ||  (srb_interrupt_num > 0x0F))
      return(AIR_SRBE_INVINTR);     /* invalid interrupt number */

   if (int_number != 0)
      return AIR_RAP_VECTOR;        /* interrupt vector already installed */

#if 0
   if (_dos_getvect(srb_interrupt_num) == audioint)
      return AIR_RAP_VECTOR;        /* interrupt vector already installed */
#endif

   int_number = srb_interrupt_num;              /* save interrupt number */
   old_intvect = _dos_getvect(int_number);      /* save old vector */
   _dos_setvect(int_number, audioint);          /* install the new vector */

   pat =  0x01 << (int_number - 0x08); /* construct mask for intr num */
   imask = inp(I8259_MASK_REG);        /* get current 8259 interrupt mask  */
   imaskbit = imask & pat;             /* state of mask bit for intr num */
   imask &= (~pat);                    /* make new interrupt mask */
   outp(I8259_MASK_REG, imask);        /* write new mask to 8259 */
   return(0);
}
/**/
/*============================================================================
;
; name:        termaudio
;
; function:    uninstalls the vector installed by initaudio()
;              and restores the previous vector
;
; arguments:   none
;
; returns:     returns zero if successful, or an AIR error code otherwise
;
;===========================================================================*/

unsigned int termaudio()            /* restore prev interrupt vector */
{
  unsigned short        imask;
  unsigned long s_killaudio();

   if (s_audiostatus())
      s_killaudio();                /* make sure no play/rec is in progress */

   if (int_number == 0)
      return AIR_RAP_VECTOR;           /* interrupt vector not installed */

#if 0
   if (_dos_getvect(int_number) != audioint)
      return AIR_RAP_VECTOR;           /* interrupt vector not installed */
#endif

  imask = inp(I8259_MASK_REG);         /* get current interrupt mask */
  imask |= imaskbit;                   /* restore prev mask bit */
  outp(I8259_MASK_REG,imask);
  _dos_setvect(int_number, old_intvect);
  int_number = 0;
  return(0);
}

/*============================================================================
;
; name:        win_int
;
; function:    interrupt service routine that deals with interrupts from
;              SRB requesting more data for PLAY, or
;              signaling a full buffer available for RECORD.
;
; arguments:   none
;
; returns:     none
;
;===========================================================================*/
#pragma check_stack(off)
void interrupt far win_int()
{
  long           bytes_rem;
  long           srb_buflen;
  unsigned short words_rem;
  unsigned short srb_bufaddr;
  unsigned short srbctl, srbstat;

  srbstat = rd_srb_statreg();     /* read SRB status reg */

  srbctl = rd_srb_ctlreg();   /* get last value written to SRB ctl reg */
  srbctl &= ~BIOHI;           /* reset BIO to keep TMS from writing to port 0 */
  srbctl &= ~PROG;            /* make sure data memory is selected */
  wr_srb_ctlreg(srbctl);      /* write SRB control register */

  srb_buflen = contab.adbl << 1;            /* srb buf len in bytes */
  bytes_rem = DiskBuffer[act_disk_buf].length - bufposn; /* no. bytes left in curr buf */
  if (getword(contab.hshk) == 1)            /* index of srb buf */
    srb_bufaddr = contab.adb1;
  else
    srb_bufaddr = contab.adb0;

  if (aud_status==PLAY && finishing && bytes_rem < srb_buflen) {
    /*--------------------------------
      finished
    ---------------------------------*/
    srbctl &= ~ENAIAW;                  /* disable SRB interrupts */
    wr_srb_ctlreg(srbctl);
    srb_post(STOP);                     /* tell SRB to terminate audio */

//    if (callback != NULL) {
//      (*callback)();
//    }
    PostMessage(hCommandWnd,WM_COMMAND,end_file_id,0L);
    aud_status = IDLE;
  }
  else {
    if (bytes_rem >= srb_buflen) {
    /* enough bytes left in current buffer to fill srb buf
    */
      if (aud_status == PLAY)
        fputbytes(DiskBuffer[act_disk_buf].lptr+bufposn,srb_bufaddr,contab.adbl);
      else
        fgetbytes(srb_bufaddr,contab.adbl,DiskBuffer[act_disk_buf].lptr + bufposn);
      bufposn += srb_buflen;
    }
    else {
         /* not enough bytes left in current buffer to fill srb buf
         */
      words_rem = bytes_rem / 2;          /* no. words left in current buf */
      if (aud_status == PLAY) {
        fputbytes(DiskBuffer[act_disk_buf].lptr + bufposn,srb_bufaddr,words_rem);
        current_posn+=DiskBuffer[act_disk_buf].length;
        act_disk_buf=!act_disk_buf;                                 /* incr index to next audio buf */
        srb_bufaddr = srb_bufaddr + words_rem;    /* point to curr pos in srb buf */
        words_rem = contab.adbl - words_rem;      /* no. words left in srb_buf */
        fputbytes(DiskBuffer[act_disk_buf].lptr,srb_bufaddr,words_rem);
	PostMessage(hCommandWnd,WM_COMMAND,swap_buf_id,0L);
//        if(diskproc!=NULL) {
//          (*diskproc)();
//        }
      }
      else {    /* assume record */
        fgetbytes(srb_bufaddr,words_rem,DiskBuffer[act_disk_buf].lptr + bufposn);
        act_disk_buf=!act_disk_buf;                                 /* index next audio buf */
        srb_bufaddr = srb_bufaddr + words_rem;    /* point to curr pos in srb buf */
        words_rem = contab.adbl - words_rem;      /* no. words left in srb_buf */
        fgetbytes(srb_bufaddr,words_rem,DiskBuffer[act_disk_buf].lptr);
	PostMessage(hCommandWnd,WM_COMMAND,swap_buf_id,0L);
//	if(diskproc!=NULL) {
//	  (*diskproc)();
//        }
      }
      bufposn = words_rem << 1;                    /* index no. of bytes into new buf */
    }

    srbctl |= BIOHI;              /* set BIO to allow TMS to write port 0 */
    wr_srb_ctlreg(srbctl);
  }
  srbctl |= (PROG & srbstat);      /* restore original state of PROG bit */
  wr_srb_ctlreg(srbctl);

  outp(I8259_CTL_REG, EOI);        /* send End_of_Interrupt to 8259 */
  return;

}

-- 
-------------------------------------------------------------------------
Ian McDonald  |                                           
52 Cook Street|                                             /  /\  /\
Hamilton      |   This space free for advertising !!       /  /  \/  \
New Zealand   |                                           /  /        \
+64-71-563438 |   I can receive mail but can't reply to it.