/****************************************************************************/
/*                                                                          */
/*    Fossil.c      :Fossil routines for MaxMail                            */
/*                                                                          */
/****************************************************************************/

#include "MaxMail.h"
#include <Bios.h>


/* Higher level fossil routines */

union REGS r;
struct SREGS sr;

#define  COUNTDOWN  1024 * 40

/* Initialize fossil */
int _pascal FossilInit(void)
{

  r.h.ah = 0x4;
  r.x.dx = Pport;
  r.x.bx = 0;

/*  r.x.cx = FP_OFF(&break_flag);
  sr.es = FP_SEG(&break_flag); */

  int86x(0x14,&r,&r,&sr);		/* Call Fossil */

  if (0x1954 != r.x.ax)
    return FALSE;
  else if (r.h.bl < 0x18 || r.h.bh < 5) {
    logit("Level 5 FOSSIL req'd",'!');
    return FALSE;
  }
  else {		/* Diddle the handshaking stuff */
   r.h.al = (byte) (prm.handshake_mask | 0xf0);
   r.h.ah = 0x0f;
   r.x.dx = Pport;
   int86(0x14,&r,&r);		/* Call Fossil */
   return TRUE;
  }
}

/* De-initialize fossil */
void _pascal FossilDeInit(void)
{
   _asm  {
      mov   ah,05
      mov   dx,Pport
      int   14h
   }
}


/* Purge Fossil buffer. If Mode is TRUE, purge input buffer, FALSE
    purge outout buffer */

void _pascal FossPurgeBuff(int mode)
{

   if (mode) {		/* purge input buffer */
      _asm  {
         mov   ah,0ah
         mov   dx,Pport
         int   14h
      }
   }
   else {		/* Purge output buffer */
      _asm  {
         mov   ah,09h
         mov   dx,Pport
         int   14h
      }
   }

/* Turn on break */

   FossBreak(10);
   delay_s(1);
}

void _pascal FossFlow(byte mask)
{
   _asm  {
      mov   ah,0fh
      mov   dx,Pport
      mov   al,mask
      int   14h
   }
}

/* Toggle DTR, if mode = TRUE, raise DTR. If mode = FALSE lower DTR */
void _pascal FossDtr(int mode)
{
   _asm  {
      mov   dx,Pport
      mov   ax,mode
      mov   ah,06h
      int   14h
   }
}

unsigned _pascal FossMdmStatus(void)
{
   int   x;

   _asm {
      mov   ah,03
      mov   dx,Pport
      int   14h
      mov   x,ax
   }
   return(x);
}

/* Return a keystroke. Check local keyboard first, then fossil */
unsigned _pascal FossGetCh(void)
{
   int   x;

   _asm {
      mov   ah,01h
      int   16h
      jz    start1
      mov   ah,0h
      int   16h
      jmp   leave1

   start1:
      mov   ax,0ffffh
      test  [IsLocal],-1
      jnz   leave1

      mov   ah,0ch
      mov   dx,Pport
      int   14h
      cmp   ax,0ffffh
      je    leave1
      mov   ah,2
      mov   dx,Pport
      int   14h

   leave1:
      mov   x,ax
   }
   return(x);
}

/* Transmit a character to fossil with no wait */

void _pascal FossSendCh(byte chr)
{
   int x;
   unsigned y;

   _asm {
      mov   dx,Pport
      mov   al,chr
      mov   ah,0bh
      int   14h
      mov   x,ax
   }
   y = 0;
   while (!x) {
      check_carrier();
      if (++y > COUNTDOWN) 
         aborterror(DEADMODEM,NULL);
      _asm {
         mov   dx,Pport
         mov   al,chr
         mov   ah,0bh
         int   14h
         mov   x,ax
      }
   }
}

/* Transmit a string to fossil */
void _pascal FossSendStr(char *strng)
{
   char *p;

   if (IsLocal)
      return;

   p = strng;
   while (*p) {
      FossSendCh(*p);
      p++;
   }
}

void _pascal FossBreak(int tsecs)
{
   if (prm.flags & FLAG_break_clr) {

      _asm {
         mov   dx,Pport
         mov   al,1		/* Send break */
         mov   ah,1ah
         int   14h
      }

      delay_ms(100 * tsecs);

      _asm {
         mov   dx,Pport
         mov   al,0		/* Stop break */
         mov   ah,1ah
         int   14h
      }
   }
}

