#include "SDswi.h"

#include <string.h>

int SoundDriver_GetDriversCount(void)
{
	_kernel_swi_regs regs;
	int i;

	for (i = 1; ; i++)
	{
		regs.r[0] = 0;
		regs.r[1] = i;
		regs.r[2] = 0;
		regs.r[3] = 0;
		// SoundDriver_Info
		if (_kernel_swi(0x06dbc2, &regs, &regs)
		||  (regs.r[0] == -1))
			break;
	}

	return i - 1;
}

const char* SoundDriver_GetDriver(int driver)
{
	_kernel_swi_regs regs;

	regs.r[0] = 0;
	regs.r[1] = driver;
	regs.r[2] = 0;
	regs.r[3] = 0;
	// SoundDriver_Info
	if (_kernel_swi(0x06dbc2, &regs, &regs)) return NULL;

	return (char*) regs.r[3];
}

int SoundDriver_FindDriver(const char* pname)
{
	_kernel_swi_regs regs;
	int i;

	if (!(*pname)) return -1;
	if (!strcmp(pname, "None")) return -1;
	if (!strcmp(pname, "SoundDMA")) return 0;

	for (i = 1; ; i++)
	{
		regs.r[0] = 0;
		regs.r[1] = i;
		regs.r[2] = 0;
		regs.r[3] = 0;
		// SoundDriver_Info
		if (_kernel_swi(0x06dbc2, &regs, &regs)) return -1;

		if (regs.r[0] == -1) return -1;
		if (!strcmp(pname, (char*) regs.r[3]))
			return i;
	}

	return -1;
}

const char* SoundDriver_GetLeftSource(int driver, int s)
{
	_kernel_swi_regs regs;

	regs.r[0] = 2;
	regs.r[1] = driver;
	regs.r[2] = s;
	regs.r[3] = -1;
	// SoundDriver_Source
	if (_kernel_swi(0x06dbc5, &regs, &regs)) return NULL;

	return (char*) regs.r[2];
}

int SoundDriver_FindLeftSource(int driver, const char* pname)
{
	_kernel_swi_regs regs;
	int i;

	for (i = 0; ; i++)
	{
		regs.r[0] = 2;
		regs.r[1] = driver;
		regs.r[2] = i;
		regs.r[3] = -1;
		// SoundDriver_Source
		if (_kernel_swi(0x06dbc5, &regs, &regs)) return 0;

		if (!regs.r[2]) return 0;
		if (!strcmp(pname, (char*) regs.r[2]))
			return i;
	}
	return 0;
}

const char* SoundDriver_GetRightSource(int driver, int s)
{
	_kernel_swi_regs regs;

	regs.r[0] = 2;
	regs.r[1] = driver;
	regs.r[2] = -1;
	regs.r[3] = s;
	// SoundDriver_Source
	if (_kernel_swi(0x06dbc5, &regs, &regs)) return NULL;

	return (char*) regs.r[3];
}

int SoundDriver_FindRightSource(int driver, const char* pname)
{
	_kernel_swi_regs regs;
	int i;

	for (i = 0; ; i++)
	{
		regs.r[0] = 2;
		regs.r[1] = driver;
		regs.r[2] = -1;
		regs.r[3] = i;
		// SoundDriver_Source
		if (_kernel_swi(0x06dbc5, &regs, &regs)) return 0;

		if (!regs.r[3]) return 0;
		if (!strcmp(pname, (char*) regs.r[3]))
			return i;
	}
	return 0;
}

const char* SoundDriver_GetSampleType(int driver, int s)
{
	_kernel_swi_regs regs;

	regs.r[0] = 2;
	regs.r[1] = driver;
	regs.r[2] = s;
	regs.r[3] = 0;
	// SoundDriver_SampleType
	if (_kernel_swi(0x06dbc7, &regs, &regs)) return NULL;

	return (char*) regs.r[3];
}

int SoundDriver_FindSampleType(int driver, const char* pname)
{
	_kernel_swi_regs regs;
	int i;

	for (i = 0; ; i++)
	{
		regs.r[0] = 2;
		regs.r[1] = driver;
		regs.r[2] = i;
		regs.r[3] = 0;
		// SoundDriver_SampleType
		if (_kernel_swi(0x06dbc7, &regs, &regs)) return 0;

		if (!regs.r[2] || !regs.r[3]) return 0;
		if (!strcmp(pname, (char*) regs.r[3]))
			return i;
	}
	return 0;
}

void SoundDriver_Config(int driver
			, const char* sourceleft
			, const char* sourceright
			, const char* sampletype
			, int	freq)
{
	_kernel_swi_regs	regs;
	int			left;
	int			right;
	int			type;

	if (driver <= 0) return;

	left = SoundDriver_FindLeftSource(driver, sourceleft);
	right = SoundDriver_FindRightSource(driver, sourceright);
	type = SoundDriver_FindSampleType(driver, sampletype);

	regs.r[0] = 1;
	regs.r[1] = driver;
	regs.r[2] = left;
	regs.r[3] = right;
	// SoundDriver_Source
	if (_kernel_swi(0x06dbc5, &regs, &regs)) return;

	regs.r[0] = 1;
	regs.r[1] = driver;
	regs.r[2] = freq<<10;
	// SoundDriver_SampleRate
	if (_kernel_swi(0x06dbc6, &regs, &regs)) return;

	regs.r[0] = 1;
	regs.r[1] = driver;
	regs.r[2] = 2;
	regs.r[3] = type;
	// SoundDriver_SampleType
	if (_kernel_swi(0x06dbc7, &regs, &regs)) return;
}
