/*************************************************************************** * 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 #include #include #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); } }