Fixed minor bug in M[LSN] interpretation, added octave-tracking.

Added the slur-mark feature.
Name of ioctl's include sys/spkr.h changed to machine/speaker.h
This commit is contained in:
Andrey A. Chernov 1993-11-09 02:32:30 +00:00
parent 4649951014
commit e614aa8a3b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=738
2 changed files with 136 additions and 80 deletions

View File

@ -1,12 +1,10 @@
/*
* spkr.c -- device driver for console speaker on 80386
* spkr.c -- device driver for console speaker
*
* v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990
* modified for 386bsd by Andrew A. Chernov <ache@astral.msk.su>
* 386bsd only clean version, all SYSV stuff removed
* use hz value from param.c
* v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993
* modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su>
*
* $Id$
* $Id: spkr.c,v 1.3 1993/10/16 13:46:21 rgrimes Exp $
*/
#include "speaker.h"
@ -14,12 +12,16 @@
#if NSPEAKER > 0
#include "param.h"
#include "systm.h"
#include "kernel.h"
#include "errno.h"
#include "buf.h"
#include "uio.h"
#include "spkr.h"
#include "machine/speaker.h"
#ifdef HZ
#undef HZ
#endif
#define HZ hz
/**************** MACHINE DEPENDENT PART STARTS HERE *************************
*
@ -75,13 +77,13 @@ unsigned int hz, ticks;
int sps;
#ifdef DEBUG
printf("tone: hz=%d ticks=%d\n", hz, ticks);
(void) printf("tone: hz=%d ticks=%d\n", hz, ticks);
#endif /* DEBUG */
/* set timer to generate clicks at given frequency in Hertz */
sps = spltty();
outb(PIT_CTRL, PIT_MODE); /* prepare timer */
outb(PIT_COUNT, (unsigned char) divisor); /* send lo byte */
outb(PIT_COUNT, (divisor & 0xff)); /* send lo byte */
outb(PIT_COUNT, (divisor >> 8)); /* send hi byte */
splx(sps);
@ -94,7 +96,7 @@ unsigned int hz, ticks;
* emitted.
*/
timeout((caddr_t)endtone, (caddr_t)NULL, ticks);
sleep((caddr_t)endtone, PZERO - 1);
(void) sleep((caddr_t)endtone, PZERO - 1);
}
static int endrest()
@ -113,16 +115,17 @@ int ticks;
* waited out.
*/
#ifdef DEBUG
printf("rest: %d\n", ticks);
(void) printf("rest: %d\n", ticks);
#endif /* DEBUG */
timeout((caddr_t)endrest, (caddr_t)NULL, ticks);
sleep((caddr_t)endrest, PZERO - 1);
(void) sleep((caddr_t)endrest, PZERO - 1);
}
/**************** PLAY STRING INTERPRETER BEGINS HERE **********************
*
* Play string interpretation is modelled on IBM BASIC 2.0's PLAY statement;
* M[LNS] are missing and the ~ synonym and octave-tracking facility is added.
* M[LNS] are missing; the ~ synonym and the _ slur mark and the octave-
* tracking facility are added.
* Requires tone(), rest(), and endtone(). String play is not interruptible
* except possibly at physical block boundaries.
*/
@ -184,7 +187,7 @@ static int pitchtab[] =
static void playinit()
{
octave = DFLT_OCTAVE;
whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
whole = (HZ * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
fill = NORMAL;
value = DFLT_VALUE;
octtrack = FALSE;
@ -200,6 +203,7 @@ int pitch, value, sustain;
/* this weirdness avoids floating-point arithmetic */
for (; sustain; sustain--)
{
/* See the BUGS section in the man page for discussion */
snum *= NUM_MULT;
sdenom *= DENOM_MULT;
}
@ -213,7 +217,7 @@ int pitch, value, sustain;
silence = whole * (FILLTIME-fill) * snum / (FILLTIME * value * sdenom);
#ifdef DEBUG
printf("playtone: pitch %d for %d ticks, rest for %d ticks\n",
(void) printf("playtone: pitch %d for %d ticks, rest for %d ticks\n",
pitch, sound, silence);
#endif /* DEBUG */
@ -237,7 +241,7 @@ static void playstring(cp, slen)
char *cp;
size_t slen;
{
int pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
int pitch, oldfill, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
#define GETNUM(cp, v) for(v=0; isdigit(cp[1]) && slen > 0; ) \
{v = v * 10 + (*++cp - '0'); slen--;}
@ -247,7 +251,7 @@ size_t slen;
register char c = toupper(*cp);
#ifdef DEBUG
printf("playstring: %c (%x)\n", c, c);
(void) printf("playstring: %c (%x)\n", c, c);
#endif /* DEBUG */
switch (c)
@ -305,8 +309,19 @@ size_t slen;
sustain++;
}
/* ...and/or a slur mark */
oldfill = fill;
if (cp[1] == '_')
{
fill = LEGATO;
++cp;
slen--;
}
/* time to emit the actual tone */
playtone(pitch, timeval, sustain);
fill = oldfill;
break;
case 'O':
@ -350,7 +365,15 @@ size_t slen;
slen--;
sustain++;
}
oldfill = fill;
if (cp[1] == '_')
{
fill = LEGATO;
++cp;
slen--;
}
playtone(pitch - 1, value, sustain);
fill = oldfill;
break;
case 'L':
@ -377,7 +400,7 @@ size_t slen;
GETNUM(cp, tempo);
if (tempo < MIN_TEMPO || tempo > MAX_TEMPO)
tempo = DFLT_TEMPO;
whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / tempo;
whole = (HZ * SECS_PER_MIN * WHOLE_NOTE) / tempo;
break;
case 'M':
@ -410,14 +433,14 @@ size_t slen;
* endtone(), and rest() functions defined above.
*/
static int spkr_active; /* exclusion flag */
static struct buf *spkr_inbuf; /* incoming buf */
static int spkr_active = FALSE; /* exclusion flag */
static struct buf *spkr_inbuf; /* incoming buf */
int spkropen(dev)
dev_t dev;
{
#ifdef DEBUG
printf("spkropen: entering with dev = %x\n", dev);
(void) printf("spkropen: entering with dev = %x\n", dev);
#endif /* DEBUG */
if (minor(dev) != 0)
@ -426,20 +449,20 @@ dev_t dev;
return(EBUSY);
else
{
#ifdef DEBUG
(void) printf("spkropen: about to perform play initialization\n");
#endif /* DEBUG */
playinit();
spkr_inbuf = geteblk(DEV_BSIZE);
spkr_active = 1;
spkr_active = TRUE;
return(0);
}
return(0);
}
int spkrwrite(dev, uio)
dev_t dev;
struct uio *uio;
dev_t dev;
struct uio *uio;
{
register unsigned n;
char *cp;
int error;
#ifdef DEBUG
printf("spkrwrite: entering with dev = %x, count = %d\n",
dev, uio->uio_resid);
@ -447,12 +470,17 @@ struct uio *uio;
if (minor(dev) != 0)
return(ENXIO);
else if (uio->uio_resid > DEV_BSIZE) /* prevent system crashes */
return(E2BIG);
else
{
n = MIN(DEV_BSIZE, uio->uio_resid);
unsigned n;
char *cp;
int error;
n = uio->uio_resid;
cp = spkr_inbuf->b_un.b_addr;
error = uiomove(cp, n, uio);
if (!error)
if (!(error = uiomove(cp, n, uio)))
playstring(cp, n);
return(error);
}
@ -462,7 +490,7 @@ int spkrclose(dev)
dev_t dev;
{
#ifdef DEBUG
printf("spkrclose: entering with dev = %x\n", dev);
(void) printf("spkrclose: entering with dev = %x\n", dev);
#endif /* DEBUG */
if (minor(dev) != 0)
@ -471,18 +499,18 @@ dev_t dev;
{
endtone();
brelse(spkr_inbuf);
spkr_active = 0;
spkr_active = FALSE;
return(0);
}
return(0);
}
int spkrioctl(dev, cmd, cmdarg)
dev_t dev;
int cmd;
caddr_t cmdarg;
caddr_t cmdarg;
{
#ifdef DEBUG
printf("spkrioctl: entering with dev = %x, cmd = %x\n", dev, cmd);
(void) printf("spkrioctl: entering with dev = %x, cmd = %x\n");
#endif /* DEBUG */
if (minor(dev) != 0)
@ -495,6 +523,7 @@ caddr_t cmdarg;
rest(tp->duration);
else
tone(tp->frequency, tp->duration);
return(0);
}
else if (cmd == SPKRTUNE)
{
@ -513,10 +542,9 @@ caddr_t cmdarg;
else
tone(ttp.frequency, ttp.duration);
}
return(0);
}
else
return(EINVAL);
return(0);
return(EINVAL);
}
#endif /* NSPEAKER > 0 */

View File

@ -1,12 +1,10 @@
/*
* spkr.c -- device driver for console speaker on 80386
* spkr.c -- device driver for console speaker
*
* v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990
* modified for 386bsd by Andrew A. Chernov <ache@astral.msk.su>
* 386bsd only clean version, all SYSV stuff removed
* use hz value from param.c
* v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993
* modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su>
*
* $Id$
* $Id: spkr.c,v 1.3 1993/10/16 13:46:21 rgrimes Exp $
*/
#include "speaker.h"
@ -14,12 +12,16 @@
#if NSPEAKER > 0
#include "param.h"
#include "systm.h"
#include "kernel.h"
#include "errno.h"
#include "buf.h"
#include "uio.h"
#include "spkr.h"
#include "machine/speaker.h"
#ifdef HZ
#undef HZ
#endif
#define HZ hz
/**************** MACHINE DEPENDENT PART STARTS HERE *************************
*
@ -75,13 +77,13 @@ unsigned int hz, ticks;
int sps;
#ifdef DEBUG
printf("tone: hz=%d ticks=%d\n", hz, ticks);
(void) printf("tone: hz=%d ticks=%d\n", hz, ticks);
#endif /* DEBUG */
/* set timer to generate clicks at given frequency in Hertz */
sps = spltty();
outb(PIT_CTRL, PIT_MODE); /* prepare timer */
outb(PIT_COUNT, (unsigned char) divisor); /* send lo byte */
outb(PIT_COUNT, (divisor & 0xff)); /* send lo byte */
outb(PIT_COUNT, (divisor >> 8)); /* send hi byte */
splx(sps);
@ -94,7 +96,7 @@ unsigned int hz, ticks;
* emitted.
*/
timeout((caddr_t)endtone, (caddr_t)NULL, ticks);
sleep((caddr_t)endtone, PZERO - 1);
(void) sleep((caddr_t)endtone, PZERO - 1);
}
static int endrest()
@ -113,16 +115,17 @@ int ticks;
* waited out.
*/
#ifdef DEBUG
printf("rest: %d\n", ticks);
(void) printf("rest: %d\n", ticks);
#endif /* DEBUG */
timeout((caddr_t)endrest, (caddr_t)NULL, ticks);
sleep((caddr_t)endrest, PZERO - 1);
(void) sleep((caddr_t)endrest, PZERO - 1);
}
/**************** PLAY STRING INTERPRETER BEGINS HERE **********************
*
* Play string interpretation is modelled on IBM BASIC 2.0's PLAY statement;
* M[LNS] are missing and the ~ synonym and octave-tracking facility is added.
* M[LNS] are missing; the ~ synonym and the _ slur mark and the octave-
* tracking facility are added.
* Requires tone(), rest(), and endtone(). String play is not interruptible
* except possibly at physical block boundaries.
*/
@ -184,7 +187,7 @@ static int pitchtab[] =
static void playinit()
{
octave = DFLT_OCTAVE;
whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
whole = (HZ * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
fill = NORMAL;
value = DFLT_VALUE;
octtrack = FALSE;
@ -200,6 +203,7 @@ int pitch, value, sustain;
/* this weirdness avoids floating-point arithmetic */
for (; sustain; sustain--)
{
/* See the BUGS section in the man page for discussion */
snum *= NUM_MULT;
sdenom *= DENOM_MULT;
}
@ -213,7 +217,7 @@ int pitch, value, sustain;
silence = whole * (FILLTIME-fill) * snum / (FILLTIME * value * sdenom);
#ifdef DEBUG
printf("playtone: pitch %d for %d ticks, rest for %d ticks\n",
(void) printf("playtone: pitch %d for %d ticks, rest for %d ticks\n",
pitch, sound, silence);
#endif /* DEBUG */
@ -237,7 +241,7 @@ static void playstring(cp, slen)
char *cp;
size_t slen;
{
int pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
int pitch, oldfill, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
#define GETNUM(cp, v) for(v=0; isdigit(cp[1]) && slen > 0; ) \
{v = v * 10 + (*++cp - '0'); slen--;}
@ -247,7 +251,7 @@ size_t slen;
register char c = toupper(*cp);
#ifdef DEBUG
printf("playstring: %c (%x)\n", c, c);
(void) printf("playstring: %c (%x)\n", c, c);
#endif /* DEBUG */
switch (c)
@ -305,8 +309,19 @@ size_t slen;
sustain++;
}
/* ...and/or a slur mark */
oldfill = fill;
if (cp[1] == '_')
{
fill = LEGATO;
++cp;
slen--;
}
/* time to emit the actual tone */
playtone(pitch, timeval, sustain);
fill = oldfill;
break;
case 'O':
@ -350,7 +365,15 @@ size_t slen;
slen--;
sustain++;
}
oldfill = fill;
if (cp[1] == '_')
{
fill = LEGATO;
++cp;
slen--;
}
playtone(pitch - 1, value, sustain);
fill = oldfill;
break;
case 'L':
@ -377,7 +400,7 @@ size_t slen;
GETNUM(cp, tempo);
if (tempo < MIN_TEMPO || tempo > MAX_TEMPO)
tempo = DFLT_TEMPO;
whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / tempo;
whole = (HZ * SECS_PER_MIN * WHOLE_NOTE) / tempo;
break;
case 'M':
@ -410,14 +433,14 @@ size_t slen;
* endtone(), and rest() functions defined above.
*/
static int spkr_active; /* exclusion flag */
static struct buf *spkr_inbuf; /* incoming buf */
static int spkr_active = FALSE; /* exclusion flag */
static struct buf *spkr_inbuf; /* incoming buf */
int spkropen(dev)
dev_t dev;
{
#ifdef DEBUG
printf("spkropen: entering with dev = %x\n", dev);
(void) printf("spkropen: entering with dev = %x\n", dev);
#endif /* DEBUG */
if (minor(dev) != 0)
@ -426,20 +449,20 @@ dev_t dev;
return(EBUSY);
else
{
#ifdef DEBUG
(void) printf("spkropen: about to perform play initialization\n");
#endif /* DEBUG */
playinit();
spkr_inbuf = geteblk(DEV_BSIZE);
spkr_active = 1;
spkr_active = TRUE;
return(0);
}
return(0);
}
int spkrwrite(dev, uio)
dev_t dev;
struct uio *uio;
dev_t dev;
struct uio *uio;
{
register unsigned n;
char *cp;
int error;
#ifdef DEBUG
printf("spkrwrite: entering with dev = %x, count = %d\n",
dev, uio->uio_resid);
@ -447,12 +470,17 @@ struct uio *uio;
if (minor(dev) != 0)
return(ENXIO);
else if (uio->uio_resid > DEV_BSIZE) /* prevent system crashes */
return(E2BIG);
else
{
n = MIN(DEV_BSIZE, uio->uio_resid);
unsigned n;
char *cp;
int error;
n = uio->uio_resid;
cp = spkr_inbuf->b_un.b_addr;
error = uiomove(cp, n, uio);
if (!error)
if (!(error = uiomove(cp, n, uio)))
playstring(cp, n);
return(error);
}
@ -462,7 +490,7 @@ int spkrclose(dev)
dev_t dev;
{
#ifdef DEBUG
printf("spkrclose: entering with dev = %x\n", dev);
(void) printf("spkrclose: entering with dev = %x\n", dev);
#endif /* DEBUG */
if (minor(dev) != 0)
@ -471,18 +499,18 @@ dev_t dev;
{
endtone();
brelse(spkr_inbuf);
spkr_active = 0;
spkr_active = FALSE;
return(0);
}
return(0);
}
int spkrioctl(dev, cmd, cmdarg)
dev_t dev;
int cmd;
caddr_t cmdarg;
caddr_t cmdarg;
{
#ifdef DEBUG
printf("spkrioctl: entering with dev = %x, cmd = %x\n", dev, cmd);
(void) printf("spkrioctl: entering with dev = %x, cmd = %x\n");
#endif /* DEBUG */
if (minor(dev) != 0)
@ -495,6 +523,7 @@ caddr_t cmdarg;
rest(tp->duration);
else
tone(tp->frequency, tp->duration);
return(0);
}
else if (cmd == SPKRTUNE)
{
@ -513,10 +542,9 @@ caddr_t cmdarg;
else
tone(ttp.frequency, ttp.duration);
}
return(0);
}
else
return(EINVAL);
return(0);
return(EINVAL);
}
#endif /* NSPEAKER > 0 */