728 lines
16 KiB
C
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);
|
|
}
|