Metropoli BBS
VIEWER: play16.c MODE: TEXT (ASCII)
/***************************************************************************
*	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;

}

[ RETURN TO DIRECTORY ]