home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d478
/
mp
/
source
/
serial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-18
|
7KB
|
292 lines
/**************************************************************************
* serial.c: Serial port access functions.
* Part of MP, the MIDI Playground.
*
* Author: Daniel Barrett
* Version: See the file "version.h".
* Copyright: None! This program is in the Public Domain.
* Please share it with others.
***************************************************************************/
#include "mp.h"
#include "midi.h"
static struct MsgPort *MidiPort = NULL;
static struct IOExtSer *Midi = NULL;
long serialFlags = 0L;
#define F_MIDIPORT 1
#define F_MIDI 2
#define F_DEVICE 4
#define F_SERPARAMS 8
BOOL AllDigits(char *str);
char *GetEnv(char *str);
BOOL MakeSerialDeviceName(char *str, char *device, int *unit);
/****************************************************************************
* SerialSetup: Open the serial port and its message port.
* Allow for an alternate MIDI device in an environment variable.
***************************************************************************/
BOOL SerialSetup(FLAGS sysex)
{
char deviceName[BUFSIZ], *envVar;
int unit;
/* Set the defaults. */
strcpy(deviceName, DEFAULT_MIDI_DEVICE);
unit = DEFAULT_MIDI_UNIT;
/* If environment variable is set, find the real MIDI device info. */
if ((envVar = GetEnv(MIDI_ENV_VAR))
&& (!MakeSerialDeviceName(envVar, deviceName, &unit)))
return(FALSE);
/* Create a port. */
if (! (MidiPort = CreatePort(0, 0)) )
{
fprintf(stderr, "Cannot create port\n");
SerialShutdown();
return(FALSE);
}
else
serialFlags |= F_MIDIPORT;
/* Create an extended I/O structure. */
if (! (Midi = (struct IOExtSer *)
CreateExtIO(MidiPort, sizeof(struct IOExtSer))))
{
fprintf(stderr, "Cannot create extended I/O structure\n");
SerialShutdown();
return(FALSE);
}
else
serialFlags |= F_MIDI;
/* Open the serial device. */
Midi->io_SerFlags = SERF_SHARED;
if (OpenDevice(deviceName, unit, (struct IORequest *)Midi, 0))
{
fprintf(stderr,
"Cannot open serial device \"%s\", unit %d.\n",
deviceName, unit);
SerialShutdown();
return(FALSE);
}
else
serialFlags |= F_DEVICE;
/* Set the serial device parameters. */
Midi->io_SerFlags = SERF_RAD_BOOGIE;
if (sysex)
{
Midi->io_TermArray.TermArray0 = 0xF7F7F7F7;
Midi->io_TermArray.TermArray1 = 0xF7F7F7F7;
Midi->io_SerFlags |= SERF_EOFMODE;
}
Midi->io_Baud = MIDI_BAUD_RATE;
Midi->io_ExtFlags = 0; /* For future compatibility */
Midi->IOSer.io_Command = SDCMD_SETPARAMS;
if (DoIO((struct IORequest *)Midi) != 0)
{
fprintf(stderr, "Cannot set serial parameters.\n");
SerialShutdown();
return(FALSE);
}
else
serialFlags |= F_SERPARAMS;
return(TRUE);
}
/****************************************************************************
* SerialShutdown: Close the serial port and its message port.
***************************************************************************/
void SerialShutdown(void)
{
if (serialFlags & F_DEVICE)
{
ResetSerialPort();
AbortIO((struct IORequest *)Midi);
WaitIO((struct IORequest *)Midi);
CloseDevice((struct IORequest *)Midi);
}
if (serialFlags & F_MIDI)
DeleteExtIO((struct IORequest *)Midi);
if (serialFlags & F_MIDIPORT)
DeletePort(MidiPort);
}
/****************************************************************************
* ResetSerialPort: Clear all data from the serial port.
***************************************************************************/
void ResetSerialPort(void)
{
Midi->IOSer.io_Command = CMD_CLEAR;
DoIO((struct IORequest *)Midi);
}
/****************************************************************************
* Is any data there?
***************************************************************************/
long AnyMidiData(void)
{
Midi->IOSer.io_Command = SDCMD_QUERY;
DoIO((struct IORequest *)Midi);
return(Midi->IOSer.io_Actual);
}
/****************************************************************************
* PrepareToReadMidi: Prepare a READ request for the MIDI port.
* PrepareToWriteMidi: Prepare a WRITE request for the MIDI port.
***************************************************************************/
void PrepareToReadMidi(UBYTE buf[], int len)
{
Midi->IOSer.io_Command = CMD_READ;
Midi->IOSer.io_Data = (APTR)buf;
Midi->IOSer.io_Length = len;
}
void PrepareToWriteMidi(UBYTE buf[], int len)
{
Midi->IOSer.io_Command = CMD_WRITE;
Midi->IOSer.io_Data = (APTR)buf;
Midi->IOSer.io_Length = len;
}
/****************************************************************************
* DoTheIO: General-purpose MIDI I/O routine. Quits on ^C.
****************************************************************************/
long DoTheIO(void)
{
int mask, temp;
long bytesDone = 0L;
mask = SIGBREAKF_CTRL_C | (1L << MidiPort->mp_SigBit);
SendIO((struct IORequest *)Midi);
while (1)
{
temp = Wait(mask);
if (temp & SIGBREAKF_CTRL_C)
{
bytesDone = CTRL_C_NO_BYTES;
break;
}
if (CheckIO((struct IORequest *)Midi))
{
WaitIO((struct IORequest *)Midi);
bytesDone = Midi->IOSer.io_Actual;
break;
}
}
AbortIO((struct IORequest *)Midi);
WaitIO((struct IORequest *)Midi);
return(bytesDone);
}
/****************************************************************************
* Fast serial reading routine, from idea on 1.3 RKM's page 863.
* If any data is waiting, get all of it with DoIO(). Otherwise, post an
* asynchronous request for 1 byte. Repeat this in the calling program.
****************************************************************************/
long FastSerialRead(UBYTE buf[])
{
long bytesWaiting, bytesRead;
if ((bytesWaiting = AnyMidiData()) > 0)
{
PrepareToReadMidi(buf, MIN(bytesWaiting, BUFSIZ));
DoIO((struct IORequest *)Midi);
return(Midi->IOSer.io_Actual);
}
else
{
PrepareToReadMidi(buf, 1);
return(DoTheIO());
}
}
/****************************************************************************
* Allow the use of another MIDI device than serial.device.
* Environment variable syntax is "DEVICENAME:UNITNUMBER".
* For example: "midi.device:2".
*
* "device" MUST be preallocated.
****************************************************************************/
BOOL MakeSerialDeviceName(char *str, char *device, int *unit)
{
while (str && *str && (*str != ':'))
*(device++) = *(str++);
*device = '\0';
if ((*str != ':') || *(str+1) == '\0')
{
fprintf(stderr,
"Your MIDI device name (variable "
MIDI_ENV_VAR
") is missing a colon\nand/or a unit number.\n");
return(FALSE);
}
str++;
if (!AllDigits(str))
{
fprintf(stderr,
"Your MIDI device unit number (variable "
MIDI_ENV_VAR
") must be\na positive integer.\n");
return(FALSE);
}
else
*unit = atoi(str);
return(TRUE);
}
/* AllDigits: Return TRUE iff the string "str" consists only of digits. */
BOOL AllDigits(char *str)
{
if ((!str) || (*str == '\0')) /* NULL or empty string. */
return(FALSE);
else
while (*str) /* For each character... */
if (!isdigit(*str)) /* if not a digit... */
return(FALSE); /* goodbye! */
else
str++;
return(TRUE); /* All were digits. */
}