/***************************************************************************
* NAME: SAMPLE16.C
** COPYRIGHT:
** "Copyright (c) 1994, by FORTE
**
** "This software is furnished under a license and may be used,
** copied, or disclosed only in accordance with the terms of such
** license and with the inclusion of the above copyright notice.
** This software or any other copies thereof may not be provided or
** otherwise made available to any other person. No title to and
** ownership of the software is hereby transfered."
****************************************************************************
* CREATION DATE: 01/01/94
*--------------------------------------------------------------------------*
* VERSION DATE NAME DESCRIPTION
*> 1.0 01/01/94 Original
***************************************************************************/
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include "forte.h"
#include "gf1proto.h"
#include "osproto.h"
#include "proto16.h"
#include "gf1hware.h"
#include "codec.h"
#include "gf1os.h"
#include "codecos.h"
#include "ultraerr.h"
#include "dma.h" /* Hardware defs for PC's dma controllers */
extern DMA_ENTRY _gf1_dma[]; /* Structure that holds data on PC's dma chan */
extern ULTRA_DATA _gf1_data;
extern ULTRA16_DATA _codec_data;
extern IMAGE16 _image_codec;
int
Ultra16RecordDmaBusy()
{
return(_gf1_dma[_codec_data.rec_chan-1].flags & DMA_PENDING);
}
void
Ultra16WaitRecordDma()
{
_codec_data.flags &= ~ADC_DMA_NOWAIT;
ENTER_CRITICAL ;
while (_codec_data.flags & ADC_DMA_BUSY) /* wait for irq to clear this */
{
}
LEAVE_CRITICAL ;
}
int
Ultra16PrimeRecord(pc_ptr,size,repeat)
void far *pc_ptr;
unsigned int size;
int repeat;
{
int mode;
if (repeat)
mode = INDEF_READ;
else
mode = READ_DMA;
/* Make sure the channel is not busy (recording or playback ... )*/
return(PrimeDma(pc_ptr,mode,size,_codec_data.rec_chan));
}
void
Ultra16StartRecordDma(control)
unsigned char control;
{
ENTER_CRITICAL;
/* kick off codec here ... */
outp(_codec_data.addr,CODEC_MCE|IFACE_CTRL);
_image_codec.ic |= CAPTURE_ENABLE;
outp(_codec_data.data,_image_codec.ic);
outp(_codec_data.addr,IFACE_CTRL);
LEAVE_CRITICAL;
}
void
Ultra16StopRecordDma()
{
DMA_ENTRY *tdma;
ENTER_CRITICAL;
outp(_codec_data.addr,CODEC_MCE|IFACE_CTRL);
_image_codec.ic &= ~CAPTURE_ENABLE;
outp(_codec_data.data,_image_codec.ic);
outp(_codec_data.addr,IFACE_CTRL);
tdma = &_gf1_dma[_codec_data.rec_chan-1]; /* point to this dma data */
outp(tdma->single,tdma->dma_disable); /* disable chan */
tdma->flags &= ~DMA_PENDING;
/* Clear flag that irq handler clears when the xfer is complete */
_codec_data.flags &= ~ADC_DMA_BUSY;
LEAVE_CRITICAL;
}
int
Ultra16GoRecord(control)
unsigned char control;
{
DMA_ENTRY *tdma;
tdma = &_gf1_dma[_codec_data.rec_chan-1]; /* point to this dma data */
/* Set flag that irq handler clears when the xfer is complete */
_codec_data.flags |= ADC_DMA_BUSY;
/* Now tell CODEC to start xfer ... */
tdma->cur_control = control;
Ultra16StartRecordDma(control);
return(ULTRA_OK);
}
int
Ultra16RecordData(pc_ptr,control,size,wait,repeat)
void far *pc_ptr;
unsigned char control;
unsigned int size;
int wait;
int repeat;
{
int ret;
if (_codec_data.type == 1)
{
if (_codec_data.rec_chan >=4)
{
ENTER_CRITICAL;
outp(_gf1_data.base_port+0x106,_codec_data.setup & ~0x10);
outp(_gf1_data.base_port+0x106,_codec_data.setup);
LEAVE_CRITICAL;
}
}
if ((ret=Ultra16PrimeRecord(pc_ptr,size,repeat)) != ULTRA_OK)
return(ret);
/* set up the counts ... */
Ultra16ProgRecCnt(size);
Ultra16GoRecord(control);
/* if required, wait till dma is done ... */
if (wait)
Ultra16WaitRecordDma();
else
_codec_data.flags |= ADC_DMA_NOWAIT;
return(ULTRA_OK);
}
unsigned int
Ultra16ReadRecordPosition()
{
DMA_ENTRY *tdma;
unsigned int actual_dma;
unsigned int this_size;
unsigned int total_size;
tdma = &_gf1_dma[_codec_data.rec_chan-1]; /* point to this dma data */
actual_dma = GetRecordDmaPos(_codec_data.rec_chan);
/* Since it counts backwards, subtract this from size of transfer */
this_size = tdma->cur_size - actual_dma;
/* Now add in the amount sent (in case it crosses page) */
total_size = tdma->amnt_sent + this_size;
if ( _codec_data.rec_chan >= 4)
total_size <<= 1;
return(total_size);
}
int
Start_Recording(pc_ptr,size)
void far *pc_ptr;
unsigned int size;
{
unsigned char control=0;
return(Ultra16RecordData(pc_ptr,control,size,FALSE,TRUE));
}
void
Ultra16ProgRecCnt(size)
unsigned int size;
{
unsigned char temp;
unsigned int psize;
psize = size;
/* if in MODE 2 && DUAL DMA */
// if ((_image_codec.mi & CODEC_MODE2) && !(_image_codec.ic & SINGLE_DMA))
if (_image_codec.mi & CODEC_MODE2)
{
temp = _image_codec.cdfr & 0xE0; /* isolate the format bits */
switch (temp)
{
case 0x40: /* 16 bit litle endian */
case 0xC0: /* 16 bit big endian */
size >>= 1;
break;
case 0xA0: /* 16 bit ADPCM */
size >>= 2;
break;
}
if (_image_codec.cdfr & TYPE_STEREO && temp != 0xA0) // not if ADPCM
size >>= 1;
size--;
ENTER_CRITICAL;
outp(_codec_data.addr,REC_LWR_CNT);
outp(_codec_data.data,(char)size);
outp(_codec_data.addr,REC_UPR_CNT);
outp(_codec_data.data,(char)(size>>8));
LEAVE_CRITICAL;
}
else
{
Ultra16ProgPlayCnt(psize);
}
}