/*************************************************************************** * NAME: PLAY16.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 Ultra16PlayDmaBusy() { return(_gf1_dma[_codec_data.play_chan-1].flags & DMA_PENDING); } void Ultra16WaitPlayDma() { _codec_data.flags &= ~DRAM_DMA_NOWAIT; /* NOT MAXX */ ENTER_CRITICAL_ON ; while (_codec_data.flags & DRAM_DMA_BUSY) /* wait for irq to clear this */ { } LEAVE_CRITICAL_ON ; } int Ultra16PrimePlay(pc_ptr,size,repeat) void far *pc_ptr; unsigned int size; int repeat; { int mode; if (repeat) mode = INDEF_WRITE; else mode = WRITE_DMA; /* Make sure the channel is not busy (recording or playback ... )*/ return(PrimeDma(pc_ptr,mode,size,_codec_data.play_chan)); } void Ultra16StartPlayDma(control) unsigned char control; { ENTER_CRITICAL; /* kick off codec here ... */ outp(_codec_data.addr,IFACE_CTRL); _image_codec.ic |= PLAYBACK_ENABLE; outp(_codec_data.data,_image_codec.ic); LEAVE_CRITICAL; } void Ultra16StopPlayDma() { DMA_ENTRY *tdma; ENTER_CRITICAL; outp(_codec_data.addr,IFACE_CTRL); _image_codec.ic &= ~PLAYBACK_ENABLE; outp(_codec_data.data,_image_codec.ic); tdma = &_gf1_dma[_codec_data.play_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 &= ~DRAM_DMA_BUSY; LEAVE_CRITICAL; } int Ultra16GoPlay(control) unsigned char control; { DMA_ENTRY *tdma; tdma = &_gf1_dma[_codec_data.play_chan-1]; /* point to this dma data */ /* Set flag that irq handler clears when the xfer is complete */ _codec_data.flags |= DRAM_DMA_BUSY; /* Now tell CODEC to start xfer ... */ tdma->cur_control = control; Ultra16StartPlayDma(control); return(ULTRA_OK); } int Ultra16PlayData(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.play_chan >=4) { ENTER_CRITICAL; outp(_gf1_data.base_port+0x106,_codec_data.setup & ~0x20); outp(_gf1_data.base_port+0x106,_codec_data.setup); LEAVE_CRITICAL; } } if ((ret=Ultra16PrimePlay(pc_ptr,size,repeat)) != ULTRA_OK) return(ret); /* set up the counts ... */ Ultra16ProgPlayCnt(size); if (!repeat) { /* stop at end .... */ } Ultra16GoPlay(control); /* if required, wait till dma is done ... */ if (wait) Ultra16WaitPlayDma(); else _codec_data.flags |= DRAM_DMA_NOWAIT; return(ULTRA_OK); } unsigned int Ultra16ReadPlayPosition() { DMA_ENTRY *tdma; unsigned int actual_dma; unsigned int this_size; unsigned int total_size; tdma = &_gf1_dma[_codec_data.play_chan-1]; /* point to this dma data */ actual_dma = GetRecordDmaPos(_codec_data.play_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.play_chan >= 4) total_size <<= 1; return(total_size); } void Start_Play(pc_ptr,size) void far *pc_ptr; unsigned int size; { unsigned char control=0; Ultra16PlayData(pc_ptr,control,size,FALSE,TRUE); } void Ultra16ProgPlayCnt(size) unsigned int size; { unsigned char temp; temp = _image_codec.pdfr & 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.pdfr & TYPE_STEREO && temp != 0xA0) // not if ADPCM size >>= 1; size--; ENTER_CRITICAL; outp(_codec_data.addr,PLY_LWR_CNT); outp(_codec_data.data,(char)size); outp(_codec_data.addr,PLY_UPR_CNT); outp(_codec_data.data,(char)(size>>8)); LEAVE_CRITICAL; }