/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1987,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
#ifndef lint
static char    *rcsid = "$Header:speaker.c 12.0$";
#endif

#include <dos.h>
#include <stdio.h>
#include <sys/types.h>
#include "pcparam.h"
#include "rb.h"
#include "bios.h"
#include "vars.h"

static          spkoff;
static          spktime = 0;
struct spkdata  spkdata[NCPU] = {0};

#define SPK_TIMER_CTRL	0x43
#define SPK_TIMER_DATA	0x42
#define SPK_TIMER_INIT	0xb6
#define SPK_CONTROL	0x61
#define SPK_ON		0x03


speaker(pcplqe)
	pcplqaddr_t     pcplqe;
{
	struct pcspk_cmd blk;
	u_long          unixaddr;
	char far       *pcaddr;

	if (cur_cbcb != screen_cbcb)
	{
		/* not current screen - pretend we did it */
		spkdata[cur_cbcb->cpu].status = 1;
		rompint3(3,FAKEPOLL(SPIRQ), 0, 0, cur_cbcb);
		return;
	}

	pcaddr = (char far *) &blk;
	unixaddr = (u_long) pcplqe->unix_cb;

	movein(unixaddr, pcaddr, sizeof(struct pcspk_cmd));

	/*
	 * don't let the speaker hang if (rc < 0) { spkoff =
	 * IOIN(SPK_CONTROL); spktime = 1; return; } 
	 *
	/* Change byte order: All the other conversions (RT data-> ATR data)
	 * has been handled by the unix code. 
	 */
	blk.duration = exchw(blk.duration);
	if (blk.vol)
	{
		IOOUT(SPK_TIMER_CTRL, SPK_TIMER_INIT);
		IOOUT(SPK_TIMER_DATA, blk.freqlow);
		IOOUT(SPK_TIMER_DATA, blk.freqhigh);
		spkoff = IOIN(SPK_CONTROL);
		IOOUT(SPK_CONTROL, SPK_ON);
	} else
	{
		spkoff = IOIN(SPK_CONTROL);
	}
	spktime = blk.duration;
}

/*
 * If we're waiting on a tone, control the decrement and intrupt when complete
 */
speaker_int()
{
	if (spktime)
	{
		if ((--spktime) == 0)
		{
			IOOUT(SPK_CONTROL, spkoff);
			spkdata[screen_cbcb->cpu].status = 1;
			rompint3(3,FAKEPOLL(SPIRQ), 0, 0, screen_cbcb);
		}
	}
}
