/*
  Rutinas para el manejo del DAC casero, con soporte de doble buffer virtual.
  Por Luis Crespo, FidoNet 2:343/108.21, Internet d8089110@est.fib.upc.es
*/

#include <dos.h>
#include "hardware.h"


static void interrupt (*OldTimerISR)();  /* Puntero a la antigua ISR del timer */
char *pBufDAC;              /* Puntero al buffer de DMA falso */
static unsigned BufSize,    /* Tama¤o del buffer */
                BufPos;     /* Offset de la muestra en el buffer */
static void (*NextBuf)();   /* Rutina de usuario */

void (*DACOut)(unsigned char b);

unsigned LPT1Addr = 0x378,
         LPT2Addr = 0x278;



void DACInit()
{
  unsigned *Addr;

  Addr = (unsigned *)MK_FP(0x40,0x8);
  if (*Addr!=0) LPT1Addr = *Addr;
  Addr = (unsigned *)MK_FP(0x40,0xA);
  if (*Addr!=0) LPT2Addr = *Addr;
}

void LPT1DAC(unsigned char b)
{
  outportb(LPT1Addr,b);
}

void LPT2DAC(unsigned char b)
{
  outportb(LPT2Addr,b);
}


static void interrupt TimerISR()
{
  EOI();
  asm STI
  DACOut(pBufDAC[BufPos]);
  BufPos++;
  if (BufPos==BufSize) NextBuf();
  if (BufPos==BufSize*2)
  {
    BufPos = 0;
    NextBuf();
  }
}

void DACPlayBuf(void *pBuffer, unsigned BufferSize, unsigned *Frec, void (*BufProc)(), char LPTNum)
{
  pBufDAC = pBuffer;
  BufSize = BufferSize;
  NextBuf = BufProc;
  BufPos = 0;
  if (LPTNum==1) DACOut=LPT1DAC; else DACOut=LPT2DAC;
  OldTimerISR = getvect(8);
  setvect(8,TimerISR);
  SetTimerFrec(Frec);
}

void DACStopBuf()
{
  ProgTimer0(0);
  setvect(8,OldTimerISR);
}


