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