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