19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* This file is part of the Dreamcast function library.
29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Please see libdream.c for further details.
39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *
49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * (c)2000 Dan Potter
59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * modify BERO
69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */
79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "aica.h"
89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <arch/irq.h>
109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <dc/spu.h>
119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* #define dc_snd_base ((volatile unsigned char *)0x00800000) */ /* arm side */
139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define dc_snd_base ((volatile unsigned char *)0xa0700000) /* dc side */
149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Some convienence macros */
169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define	SNDREGADDR(x)	(0xa0700000 + (x))
179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define	CHNREGADDR(ch,x)	SNDREGADDR(0x80*(ch)+(x))
189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SNDREG32(x)	(*(volatile unsigned long *)SNDREGADDR(x))
219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define SNDREG8(x)	(*(volatile unsigned char *)SNDREGADDR(x))
229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CHNREG32(ch, x) (*(volatile unsigned long *)CHNREGADDR(ch,x))
239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define CHNREG8(ch, x)	(*(volatile unsigned long *)CHNREGADDR(ch,x))
249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define G2_LOCK(OLD) \
269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	do { \
279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		if (!irq_inside_int()) \
289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			OLD = irq_disable(); \
299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		/* suspend any G2 DMA here... */ \
309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		while((*(volatile unsigned int *)0xa05f688c) & 0x20) \
319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			; \
329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	} while(0)
339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define G2_UNLOCK(OLD) \
359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	do { \
369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		/* resume any G2 DMA here... */ \
379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		if (!irq_inside_int()) \
389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			irq_restore(OLD); \
399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	} while(0)
409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid aica_init() {
439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	int i, j, old = 0;
449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Initialize AICA channels */
469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	G2_LOCK(old);
479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SNDREG32(0x2800) = 0x0000;
489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	for (i=0; i<64; i++) {
509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		for (j=0; j<0x80; j+=4) {
519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			if ((j&31)==0) g2_fifo_wait();
529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			CHNREG32(i, j) = 0;
539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		}
549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		g2_fifo_wait();
559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		CHNREG32(i,0) = 0x8000;
569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		CHNREG32(i,20) = 0x1f;
579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SNDREG32(0x2800) = 0x000f;
609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_fifo_wait();
619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	G2_UNLOCK(old);
629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Translates a volume from linear form to logarithmic form (required by
659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   the AICA chip */
669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* int logs[] = {
679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall0, 40, 50, 58, 63, 68, 73, 77, 80, 83, 86, 89, 92, 94, 97, 99, 101, 103,
699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall105, 107, 109, 111, 112, 114, 116, 117, 119, 120, 122, 123, 125, 126, 127,
709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall129, 130, 131, 133, 134, 135, 136, 137, 139, 140, 141, 142, 143, 144, 145,
719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159,
729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall160, 161, 162, 162, 163, 164, 165, 166, 166, 167, 168, 169, 170, 170, 171,
739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall172, 172, 173, 174, 175, 175, 176, 177, 177, 178, 179, 180, 180, 181, 182,
749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 188, 189, 190, 190, 191,
759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall191, 192, 193, 193, 194, 194, 195, 196, 196, 197, 197, 198, 198, 199, 199,
769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall200, 201, 201, 202, 202, 203, 203, 204, 204, 205, 205, 206, 206, 207, 207,
779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall208, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215,
789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall215, 216, 216, 217, 217, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222,
799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall222, 222, 223, 223, 224, 224, 225, 225, 225, 226, 226, 227, 227, 228, 228,
809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall228, 229, 229, 230, 230, 230, 231, 231, 232, 232, 232, 233, 233, 234, 234,
819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall234, 235, 235, 236, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240,
829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall240, 241, 241, 241, 242, 242, 243, 243, 243, 244, 244, 244, 245, 245, 245,
839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall246, 246, 247, 247, 247, 248, 248, 248, 249, 249, 249, 250, 250, 250, 251,
849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall251, 251, 252, 252, 252, 253, 253, 253, 254, 254, 254, 255
859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}; */
879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallconst static unsigned char logs[] = {
899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	0, 15, 22, 27, 31, 35, 39, 42, 45, 47, 50, 52, 55, 57, 59, 61,
909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	63, 65, 67, 69, 71, 73, 74, 76, 78, 79, 81, 82, 84, 85, 87, 88,
919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	90, 91, 92, 94, 95, 96, 98, 99, 100, 102, 103, 104, 105, 106,
929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	108, 109, 110, 111, 112, 113, 114, 116, 117, 118, 119, 120, 121,
939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	135, 136, 137, 138, 138, 139, 140, 141, 142, 143, 144, 145, 146,
959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 156,
969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	157, 158, 159, 160, 160, 161, 162, 163, 164, 164, 165, 166, 167,
979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176,
989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	177, 178, 178, 179, 180, 181, 181, 182, 183, 183, 184, 185, 185,
999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193, 193, 194,
1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	195, 195, 196, 197, 197, 198, 199, 199, 200, 200, 201, 202, 202,
1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	203, 204, 204, 205, 205, 206, 207, 207, 208, 209, 209, 210, 210,
1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	211, 212, 212, 213, 213, 214, 215, 215, 216, 216, 217, 217, 218,
1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	219, 219, 220, 220, 221, 221, 222, 223, 223, 224, 224, 225, 225,
1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 232, 232, 233,
1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 239, 239, 240,
1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246,
1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 254, 255
1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall};
1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* For the moment this is going to have to suffice, until we really
1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   figure out what these mean. */
1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define AICA_PAN(x) ((x)==0x80?(0):((x)<0x80?(0x1f):(0x0f)))
1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define AICA_VOL(x) (0xff - logs[128 + (((x) & 0xff) / 2)])
1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall//#define AICA_VOL(x) (0xff - logs[x&255])
1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic inline unsigned  AICA_FREQ(unsigned freq)	{
1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	unsigned long freq_lo, freq_base = 5644800;
1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	int freq_hi = 7;
1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Need to convert frequency to floating point format
1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   (freq_hi is exponent, freq_lo is mantissa)
1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   Formula is ferq = 44100*2^freq_hi*(1+freq_lo/1024) */
1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	while (freq < freq_base && freq_hi > -8) {
1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		freq_base >>= 1;
1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		--freq_hi;
1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	while (freq < freq_base && freq_hi > -8) {
1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		freq_base >>= 1;
1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		freq_hi--;
1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	freq_lo = (freq<<10) / freq_base;
1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	return (freq_hi << 11) | (freq_lo & 1023);
1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Sets up a sound channel completely. This is generally good if you want
1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   a quick and dirty way to play notes. If you want a more comprehensive
1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   set of routines (more like PC wavetable cards) see below.
1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   ch is the channel to play on (0 - 63)
1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   smpptr is the pointer to the sound data; if you're running off the
1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     SH4, then this ought to be (ptr - 0xa0800000); otherwise it's just
1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     ptr. Basically, it's an offset into sound ram.
1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   mode is one of the mode constants (16 bit, 8 bit, ADPCM)
1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   nsamp is the number of samples to play (not number of bytes!)
1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   freq is the sampling rate of the sound
1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   vol is the volume, 0 to 0xff (0xff is louder)
1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   pan is a panning constant -- 0 is left, 128 is center, 255 is right.
1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   This routine (and the similar ones) owe a lot to Marcus' sound example --
1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   I hadn't gotten quite this far into dissecting the individual regs yet. */
1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid aica_play(int ch,int mode,unsigned long smpptr,int loopst,int loopend,int freq,int vol,int pan,int loopflag) {
1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/*	int i;
1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/
1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	int val;
1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	int old = 0;
1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Stop the channel (if it's already playing) */
1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	aica_stop(ch);
1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* doesn't seem to be needed, but it's here just in case */
1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/*
1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	for (i=0; i<256; i++) {
1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		asm("nop");
1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		asm("nop");
1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		asm("nop");
1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		asm("nop");
1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/
1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	G2_LOCK(old);
1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Envelope setup. The first of these is the loop point,
1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   e.g., where the sample starts over when it loops. The second
1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   is the loop end. This is the full length of the sample when
1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   you are not looping, or the loop end point when you are (though
1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   storing more than that is a waste of memory if you're not doing
1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   volume enveloping). */
1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	CHNREG32(ch, 8) = loopst & 0xffff;
1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	CHNREG32(ch, 12) = loopend & 0xffff;
1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Write resulting values */
1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	CHNREG32(ch, 24) = AICA_FREQ(freq);
1809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Set volume, pan, and some other things that we don't know what
1829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   they do =) */
1839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	CHNREG32(ch, 36) = AICA_PAN(pan) | (0xf<<8);
1849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Convert the incoming volume and pan into hardware values */
1859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Vol starts at zero so we can ramp */
1869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	vol = AICA_VOL(vol);
1879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	CHNREG32(ch, 40) = 0x24 | (vol<<8);
1889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Convert the incoming volume and pan into hardware values */
1899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Vol starts at zero so we can ramp */
1909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* If we supported volume envelopes (which we don't yet) then
1929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   this value would set that up. The top 4 bits determine the
1939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   envelope speed. f is the fastest, 1 is the slowest, and 0
1949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   seems to be an invalid value and does weird things). The
1959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   default (below) sets it into normal mode (play and terminate/loop).
1969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	CHNREG32(ch, 16) = 0xf010;
1979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	*/
1989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	CHNREG32(ch, 16) = 0x1f;	/* No volume envelope */
1999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Set sample format, buffer address, and looping control. If
2029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   0x0200 mask is set on reg 0, the sample loops infinitely. If
2039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   it's not set, the sample plays once and terminates. We'll
2049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	   also set the bits to start playback here. */
2059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	CHNREG32(ch, 4) = smpptr & 0xffff;
2069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	val = 0xc000 | 0x0000 | (mode<<7) | (smpptr >> 16);
2079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	if (loopflag) val|=0x200;
2089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	CHNREG32(ch, 0) = val;
2109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	G2_UNLOCK(old);
2129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Enable playback */
2149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* CHNREG32(ch, 0) |= 0xc000; */
2159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_fifo_wait();
2169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if 0
2189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	for (i=0xff; i>=vol; i--) {
2199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		if ((i&7)==0) g2_fifo_wait();
2209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		CHNREG32(ch, 40) =  0x24 | (i<<8);;
2219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
2229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_fifo_wait();
2249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
2259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
2269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Stop the sound on a given channel */
2289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid aica_stop(int ch) {
2299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_write_32(CHNREGADDR(ch, 0),(g2_read_32(CHNREGADDR(ch, 0)) & ~0x4000) | 0x8000);
2309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_fifo_wait();
2319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
2329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The rest of these routines can change the channel in mid-stride so you
2359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall   can do things like vibrato and panning effects. */
2369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set channel volume */
2389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid aica_vol(int ch,int vol) {
2399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall//	g2_write_8(CHNREGADDR(ch, 41),AICA_VOL(vol));
2409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_write_32(CHNREGADDR(ch, 40),(g2_read_32(CHNREGADDR(ch, 40))&0xffff00ff)|(AICA_VOL(vol)<<8) );
2419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_fifo_wait();
2429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
2439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set channel pan */
2459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid aica_pan(int ch,int pan) {
2469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall//	g2_write_8(CHNREGADDR(ch, 36),AICA_PAN(pan));
2479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_write_32(CHNREGADDR(ch, 36),(g2_read_32(CHNREGADDR(ch, 36))&0xffffff00)|(AICA_PAN(pan)) );
2489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_fifo_wait();
2499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
2509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Set channel frequency */
2529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid aica_freq(int ch,int freq) {
2539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_write_32(CHNREGADDR(ch, 24),AICA_FREQ(freq));
2549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_fifo_wait();
2559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
2569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Get channel position */
2589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint aica_get_pos(int ch) {
2599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if 1
2609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Observe channel ch */
2619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_write_32(SNDREGADDR(0x280c),(g2_read_32(SNDREGADDR(0x280c))&0xffff00ff) | (ch<<8));
2629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_fifo_wait();
2639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Update position counters */
2649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	return g2_read_32(SNDREGADDR(0x2814)) & 0xffff;
2659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else
2669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Observe channel ch */
2679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	g2_write_8(SNDREGADDR(0x280d),ch);
2689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Update position counters */
2699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	return g2_read_32(SNDREGADDR(0x2814)) & 0xffff;
2709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
2719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
272