1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
/* Misc FM chip soundcard routines for sccw */
/* Must compile with -O2 -lm and optionally -DDEBUG_FREQ */
/* Steven J. Merrifield VK3ESM sjm@ee.latrobe.edu.au */
#include <unistd.h>
#include <asm/io.h>
#include <math.h>
#include <stdlib.h>
#include "sccw.h"
void wr_register(int index, int data) /* See the PC Game Programmers Encyclopedia */
{
int i,temp;
outb(index,reg_port);
for (i=1;i<7;i++)
temp = inb(reg_port);
outb(data,data_port);
for (i=1;i<36;i++)
temp = inb(reg_port);
}
int AdLib_found(void) /* See the PC Game Programmers Encyclopedia */
{
long temp1,temp2;
wr_register(4,0x60);
wr_register(4,0x80);
temp1 = inb(reg_port);
wr_register(2,0xFF);
wr_register(4,0x21);
sleep(1);
temp2 = inb(reg_port);
wr_register(4,0x60);
wr_register(4,0x80);
if (((temp1 && 0xE0) == 0) && ((temp2 && 0xE0) == 0xC0))
{
return(TRUE);
}
else return(FALSE);
}
void Reset_AdLib(void) /* Set all registers to 0 */
{
int i;
for (i=1;i<245;i++)
wr_register(i,0);
}
void Play_sound(int f, double delay, int vol)
{
int blk = -1;
int f_num;
int A0_reg,B0_reg,B0_reg10,B0_reg432;
wr_register(0x20,1); /* Play sound at fundamental freq. */
wr_register(0x23,1); /* Carrier at specified freq. */
wr_register(0x43,64-vol); /* Volume */
wr_register(0x63,0xF0); /* Carrier attack = fast, decay = slow */
wr_register(0x83,0xFF); /* Carrier sustain = soft, release = fast */
/* Would you belive it took three days to work out how to do this ? */
do
{
blk++;
f_num = (int)(((float)f / 50000.0) / (1/(pow(2,abs(blk-20)))));
} while (f_num > 1023);
A0_reg = f_num & 0x00FF;
B0_reg10 = (f_num & 0x0300) >> 8;
B0_reg432 = (blk << 2) & 0x00FF; /* Do I really need to & 0x00ff ?? */
B0_reg = (32 | B0_reg432 | B0_reg10) & 0x00FF;
wr_register(0xA0,A0_reg);
wr_register(0xB0,B0_reg);
#ifdef DEBUG_FREQ
printf("blk = %d f_num = %d\n",blk,f_num);
printf("B0_reg432 = %2x\n",B0_reg432); /* bits 4 3 2 */
printf("B0_reg10 = %2x\n",B0_reg10); /* bits 1 0 */
printf("B0_reg = %2x A0_reg = %2x\n\n\n",B0_reg,A0_reg);
#endif
usleep(delay);
wr_register(0xB0,0x00); /* Turn off sound, was 0x11 */
}
|