/****************************************************************************
*
* (C) 2000 by BECK IPC GmbH
*
*  BECK IPC GmbH
*  Garbenheimerstr. 38
*  D-35578 Wetzlar
*
*  Phone : (49)-6441-905-240
*  Fax   : (49)-6441-905-245
*
* ---------------------------------------------------------------------------
* Module        : IPC@Chip SC12: PKTDRV.C
* Function      : Packet driver interface enables access to the ethernet of SC12 
*                 Required memory model: Large
*
* Author        : Bartat
* Date          : 10.10.00
* ---------------------------------------------------------------------------

$Header: PKTDRV.C, 6, 16.01.2002 11:45:05, Christoph Stoidner$

$Log:
 6    IPC@CHIP  1.5         16.01.2002 11:45:05  Christoph Stoidner add starteam
      directives
 5    IPC@CHIP  1.4         16.01.2002 11:04:49  Christoph Stoidner add some
      comments

 4    IPC@CHIP  1.3         14.12.2001 12:15:49  Markus Bartat   added
      set_rcv_mode functions
 3    IPC@CHIP  1.2         17.09.2001 11:19:41  Markus Bartat   added new
      functions for wildcard and multicast api calls
 2    IPC@CHIP  1.1         19.06.2001 13:35:06  Markus Bartat   start: Added
      comments to the c functions
 1    IPC@CHIP  1.0         14.02.2001 16:09:33  Christoph Stoidner
$

* History       :
*
*  Vx.yy                 Author  Changes
*
*             10.10.00   mb      Create
*             12.09.01   mb       added multicast and wildcard_access  functions
*             06.12.01   mb       added set_rcv_mode functions
/************************************************************************/
//       		INCLUDES
/************************************************************************/
#include <DOS.H>
#include "pktdrv.h"
/************************************************************************/
// 		driver installed: SC12 serviceint 0xA0  0x16
/************************************************************************/
unsigned char PktDriver_Installed(void)
{

   union  REGS  inregs;
   union  REGS  outregs;


   inregs.h.ah = 0x16;
   int86(0xA0,&inregs,&outregs);

   //check bit3 of dx
   if(outregs.x.dx & 0x08)
      return 1;

   return 0;

}

/************************************************************************/
//       		Get Driver Info
/************************************************************************/
unsigned char Get_Driver_Info(Driver_Info * drv_info )
{

    union  REGS  inregs;
	 union  REGS  outregs;

     inregs.h.ah = DRIVER_INFO;
     inregs.h.al = 0xff;

     int86(PKTVECT,&inregs,&outregs);

     if(outregs.x.cflag) return outregs.h.dh;

     drv_info->version = outregs.x.bx;
     drv_info->_class  = outregs.h.ch;
     drv_info->type    = outregs.x.dx;
     drv_info->number  = outregs.h.cl;
     drv_info->basic   = outregs.h.al;
     return 0;
}
/************************************************************************/
//       		get ethernet-address
/************************************************************************/

unsigned char Get_Eth_Address(unsigned char *buffer, unsigned int len)
{
   union  REGS  inregs;
	union  REGS  outregs;
	struct SREGS sregs;

	inregs.h.ah      = GET_ADDRESS;
   inregs.x.cx      = len;
	inregs.x.di      = FP_OFF(buffer);
	sregs.es         = FP_SEG(buffer);
	int86x(PKTVECT,&inregs,&outregs,&sregs);


   if(outregs.x.flags&0x01)
	{
	  return outregs.h.dh;
	}
	return 0;
}

/************************************************************************/
//       		send packet
/************************************************************************/
unsigned char Send_Packet(unsigned char * buffer, unsigned int len)
{

    union  REGS  inregs;
    union  REGS  outregs;
    struct SREGS sregs;

    inregs.h.ah      = SEND_PKT;
    inregs.x.cx      = len;
    inregs.x.si      = FP_OFF(buffer);
    sregs.ds         = FP_SEG(buffer);
    int86x(PKTVECT,&inregs,&outregs,&sregs);


    if(outregs.x.flags&0x01)
    {
      return outregs.h.dh;
    }
    return 0;

}

/*************************************************************************/
//       	       set access type
/*************************************************************************/
unsigned int Set_Access_Type(Driver_Info * drv_info, fpFktPtr Receiver, int * pkt_type, int *handle)
{


	union  REGS  inregs;
	union  REGS  outregs;
	struct SREGS sregs;


	inregs.h.dl = drv_info->number;   /* Number */
	sregs.ds    = FP_SEG(pkt_type);	 /* Packet type template, pkt_type is a global varia */
	inregs.x.si = FP_OFF(pkt_type);
	inregs.x.cx = sizeof(int);
	sregs.es    = FP_SEG(Receiver);	 /* Address of receive handler */
	inregs.x.di = FP_OFF(Receiver);
	inregs.x.bx = drv_info->type;		 /* Type */
   inregs.h.ah = ACCESS_TYPE;			 /* Access_type() function */
	inregs.h.al = drv_info->_class;	 /* Class */
	int86x(PKTVECT,&inregs,&outregs,&sregs);

	if(outregs.x.cflag)
	{
	   return  outregs.h.dh;
	}
	else
	{
	   *handle = outregs.x.ax;
	   return 0;
	}

}
/************************************************************************/
//    Release type
/************************************************************************/
unsigned int Release_Type(unsigned int handle)
{

  union  REGS  inregs;
  union  REGS  outregs;

  inregs.x.bx = handle;
  inregs.h.ah = RELEASE_TYPE;
  int86(PKTVECT,&inregs,&outregs);
  if(outregs.x.cflag)
	return outregs.h.dh;
  return 0;
}





/*************************************************************************/
//Set/del multicast address !=0: set address 0: delete address
/*************************************************************************/
unsigned int Set_Multicast(unsigned char * mac_addr, int set)
{


	union  REGS  inregs;
	union  REGS  outregs;
	struct SREGS sregs;



	sregs.es    = FP_SEG(mac_addr);	  /* Packet type template, pkt_type is a global varia */
	inregs.x.di = FP_OFF(mac_addr);
	inregs.x.cx = 6;

  if(set)
  {
  	 inregs.h.ah = SET_MULTICAST;		  /* Access_type() function */
  }
  else
  {
    inregs.h.ah = DEL_MULTICAST;      /* Access_type() function */
  }
  int86x(PKTVECT,&inregs,&outregs,&sregs);

  if(outregs.x.cflag)
  {
	   return  outregs.h.dh;
  }
  else
  {
	   return 0;
  }
}




/*************************************************************************/
//       	       set wildcard access type
/*************************************************************************/
unsigned int Set_WildcardAccess_Type(Driver_Info * drv_info, fpFktPtr Receiver, int * pkt_type, int *handle)
{


	union  REGS  inregs;
	union  REGS  outregs;
	struct SREGS sregs;


	inregs.h.dl = drv_info->number;   /* Number */
	sregs.ds    = FP_SEG(pkt_type);	 /* Packet type template, pkt_type is a global varia */
	inregs.x.si = FP_OFF(pkt_type);
	inregs.x.cx = sizeof(int);
	sregs.es    = FP_SEG(Receiver);	 /* Address of receive handler */
   inregs.x.di = FP_OFF(Receiver);
   inregs.x.bx = drv_info->type;		 /* Type */
	inregs.h.ah = INSTALL_WILDCARD;	 /* Access_type() function */
	inregs.h.al = drv_info->_class;	 /* Class */
	int86x(PKTVECT,&inregs,&outregs,&sregs);

	if(outregs.x.cflag)
	{
	   return  outregs.h.dh;
	}
	else
	{
	   *handle = outregs.x.ax;
	   return 0;
	}

}


/************************************************************************/
//    Get receive mode
/************************************************************************/
unsigned int Get_Receive_Mode(unsigned char * error)
{

  union  REGS  inregs;
  union  REGS  outregs;

  *error=0;
  inregs.h.ah = GET_RCVMODE;
  int86(PKTVECT,&inregs,&outregs);
  if(outregs.x.cflag)
  {
	*error=outregs.h.dh;
	return 0;
  }
  return outregs.x.ax;
}


/************************************************************************/
//    Set receive mode , possible only receive all
/************************************************************************/
unsigned int Set_Receive_Mode(unsigned int mode,unsigned char * error)
{

  union  REGS  inregs;
  union  REGS  outregs;

  *error=0;
  inregs.h.ah = SET_RCVMODE;
  inregs.x.cx = mode;

  int86(PKTVECT,&inregs,&outregs);
  if(outregs.x.cflag)
  {
	*error=outregs.h.dh;
	return 0;
  }
  return outregs.x.ax;
}


/************************************************************************/
//end pktdrv.c
/************************************************************************/