xenocara/app/xlockmore/xlock/vms_amd.c
2006-11-26 11:07:42 +00:00

728 lines
16 KiB
C

/*-
* Sound file for vms
* Jouk Jansen <joukj@alpha.chem.uva.nl> contributed this
* which he found at http://axp616.gsi.de:8080/www/vms/mzsw.html
*/
/** amd.c **/
#include <iodef.h> /* needed for IO$_ functions */
#include <ssdef.h> /* system condition codes */
#include <descrip.h> /* VMS Descriptor functions */
#include <string.h>
#include <starlet.h>
#include "vms_amd.h" /* AMD access functions */
struct dsc$descriptor_s devname; /* device we are using */
static short int so_chan; /* Channel to SODRIVER */
char ReadBuffer[512]; /* Asynchronous read buffer */
unsigned short ReadIOsb[4] =
{0, 0, 0, 0};
int ReadPending = 0;
int ReadCompleted = 0;
/*-
* Initialize access to the AMD chip
*/
unsigned long int
AmdInitialize(char *device, int volume)
{
unsigned long int status;
unsigned long int iosb[2] =
{0, 0};
int p1;
#ifdef DEBUG
(void) printf("Address of AMD Read buffer is 0x%x\n", &ReadBuffer);
#endif
/*
* Create the descriptor
*/
devname.dsc$w_length = strlen(device);
devname.dsc$a_pointer = device;
devname.dsc$b_dtype = DSC$K_DTYPE_T;
devname.dsc$b_class = DSC$K_CLASS_S;
/*
* Assign a channel to the device
*/
status = sys$assign(&devname, &so_chan, 0, 0, 0);
if (!(status & 1))
return (status);
/*
* Clear MMR1
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Clear MMR2
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_MMR2, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Set Volume to initial 30%
*/
p1 = 0x2ABD;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_GER, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Get MMR1
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_GETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Set MMR1 to 8
*/
p1 = 8;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Set GR
*/
p1 = 0x92FB;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_GR, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Get MMR1
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_GETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Set MMR1 to 12 (0x0C)
*/
p1 = 12;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Get MMR2
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_GETREG, /* IOCTL code (P3) */
MAP_MMR2, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Put it back MMR2
*/
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_MMR2, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Set GX to 0x0112
*/
p1 = 0x0112;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_GX, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Get MMR1
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_GETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Set MMR1 to 14 (0x0E)
*/
p1 = 14;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Set GER (Volume to what the user wants)
*/
p1 = VolumeTable[volume - 1].ger_value;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_GER, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Get MMR1
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_GETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Set GR (Volume to what the user wants)
*/
p1 = VolumeTable[volume - 1].gr_value;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_GR, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Get MMR1
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_GETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Return Success
*/
return (SS$_NORMAL);
}
/*-
* Return the channel number associated with the device
*/
unsigned short
AmdGetChannel(void)
{
return (so_chan);
}
/*-
* Increase or Decrease the Volume
*/
AmdSetVolume(int volume)
{
unsigned long int status;
unsigned short iosb[4] =
{0, 0, 0, 0};
int p1;
/*
* Set GER (Volume to what the user wants)
*/
p1 = VolumeTable[volume - 1].ger_value;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_GER, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Get MMR1
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_GETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Set GR (Volume to what the user wants)
*/
p1 = VolumeTable[volume - 1].gr_value;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_GR, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Get MMR1
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_GETREG, /* IOCTL code (P3) */
MAP_MMR1, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Return Success
*/
return (SS$_NORMAL);
}
/*-
* Start recording sound
*/
unsigned long int
AmdInitRecord()
{
unsigned long int status;
unsigned long int iosb[2] =
{0, 0};
int p1, p2, p3, p4, p5, p6;
/*
* Set recording level to 100%
*/
p1 = 0x0E;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* I/O status */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer Length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_GX, /* AMD Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Start recording
*/
p3 = 2;
p4 = 0x07D0;
p5 = 0x14;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACCESS, /* function code */
iosb, /* I/O Status */
0, /* ast routine */
0, /* ast param */
0, /* P1 */
0, /* P2 */
p3, /* Single freq tone */
p4, /* frequency */
p5, /* amplitude */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Retrieve the value of MMR2
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_GETREG, /* IOCTL code (P3) */
MAP_MMR2, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Set MMR2 to 0
*/
p1 = 0;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_MMR2, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Issue a stop
*/
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* I/O status */
0, /* ast routine */
0, /* ast param */
0, /* P1 */
0, /* P2 */
AMD_STOP, /* IOCTL function code */
0, /* P4 */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Issue a read start to begin reading data
*/
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* I/O status */
0, /* ast routine */
0, /* ast param */
0, /* P1 */
0, /* P2 */
AMD_READSTART, /* IOCTL function code */
0, /* P4 */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
/*
* Return success
*/
return (SS$_NORMAL);
}
/*-
* Select the Internal or External Speaker
*/
unsigned long int
AmdSelect(int s)
{
unsigned long int status;
unsigned long int iosb[2];
int p1;
/*
* Set the MMR2 register to indicate speaker
*/
p1 = s;
status = sys$qiow(0, /* efn */
so_chan, /* channel */
IO$_ACPCONTROL, /* function */
iosb, /* iosb */
0, /* ast routine */
0, /* ast param */
&p1, /* Buffer (P1) */
sizeof (p1), /* Buffer length (P2) */
AMD_SETREG, /* IOCTL code (P3) */
MAP_MMR2, /* AMD INDIRECT Register (P4) */
0, /* P5 */
0); /* P6 */
if (!(status & 1))
return (status);
if (!(iosb[0] & 1))
return (iosb[0]);
}
/*-
* Write a buffer of sound data to the device
*/
unsigned long int
AmdWrite(char *buffer, int len)
{
unsigned long int status;
unsigned long iosb[2] =
{0, 0};
/*
* Write the data to the device
*/
status = sys$qiow(0,
so_chan,
IO$_WRITEVBLK,
iosb,
0,
0,
buffer, len, 0, 0, 0, 0);
if (!(status & 1))
return (status);
/*
* Return success
*/
return (SS$_NORMAL);
}