[comp.sources.misc] v06i108: glib part 7 of 15

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (05/15/89)

Posting-number: Volume 6, Issue 108
Submitted-by: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
Archive-name: glib/part07

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 7 (of 15)."
# Contents:  amigmach.c d10urp.mnu menutoc.l
# Wrapped by lee@uhccux on Sun May  7 00:40:14 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'amigmach.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amigmach.c'\"
else
echo shar: Extracting \"'amigmach.c'\" \(13113 characters\)
sed "s/^X//" >'amigmach.c' <<'END_OF_FILE'
X/* $Id: amigmach.c,v 1.6 89/05/06 17:13:10 lee Exp $
X *
X * GLIB - a Generic LIBrarian and editor for synths
X *
X * Machine dependent stuff.
X *
X * Amiga version.
X * Alan Bland
X *
X * modifications by Mark Rinfret and Dave Weiler
X * $Log:	amigmach.c,v $
X * Revision 1.6  89/05/06  17:13:10  lee
X * rel. to comp.sources.misc
X * 
X */
X
X#include "glib.h"
X#include <stdio.h>
X#include <ctype.h>
X
X#ifndef AZTEC_C
X#include <dos.h>
X#endif
X#include <intuition/intuition.h>
X#include <exec/types.h>
X#include <exec/ports.h>
X#include <exec/io.h>
X#include <exec/devices.h>
X#include <exec/memory.h>
X#include <devices/serial.h>
X
X#ifdef ARP
X	#include <libraries/arpbase.h>
X	#include <arpfunctions.h>
X#endif
X
X#ifdef AZTEC_C
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <functions.h>
X#else
X#include <proto/exec.h>
X#include <proto/intuition.h>
X#endif
X
X#ifdef ARP
X	char FileName[FCHARS+1];
X	char DirName[DSIZE+1];
X	struct FileRequester MyFileRequest =
X		{
X		"GLIB file name -->",
X		FileName,
X		DirName,
X		0,
X		0,0,
X		0,
X		0
X		};
X	int FileRequestImminent;
X#else
X	struct IntuitionBase *IntuitionBase;
X	struct GfxBase *GfxBase;
X#endif
X
Xstruct Screen *S;
Xstruct Window *W;
Xstruct RastPort *R;
X
Xint Rows, Cols;
X
X#define TOPEDGE 8	/* how much of screen bar to show */
Xint WindowWidth = 640;
Xint WindowHeight = 200 - TOPEDGE;
X
X/* standard WB colors */
X#define BLUE 0
X#define WHITE 1
X#define BLACK 2
X#define ORANGE 3
X
X
Xhello()
X{
X	windinit();
X	openmidi();
X}
X
Xbye()
X{
X	closemidi();
X	windexit(0);
X}
X
Xint MouseX, MouseY, MouseButtons;
Xint Mouseok = 0;
X
X/* getmouse - get current row and column of mouse */
Xgetmouse(amr,amc)
Xint *amr;
Xint *amc;
X{
X	*amr = MouseY / 8;
X	*amc = MouseX / 8;
X}
X
X/* statmouse - return mouse button state (0=nothing pressed,1=left,2=right) */
Xstatmouse()
X{
X	nextevent(MOUSEBUTTONS, 0);
X	return MouseButtons;
X}
X
X/* Return when either a console key or mouse button is pressed. */
Xmouseorkey()
X{
X	return nextevent(MOUSEBUTTONS | VANILLAKEY, 1);
X}
X
Xflushconsole()
X{
X	while (nextevent(VANILLAKEY, 0) >= 0) ;
X}
X
Xgetconsole()
X{
X	return nextevent(VANILLAKEY, 1);
X}
X
Xcursor(state)
Xint state;
X{
X	int x, y;
X	x = R->cp_x;
X	y = R->cp_y - R->Font->tf_Baseline;
X	SetDrMd(R, COMPLEMENT);
X	RectFill(R, x, y, x+8, y+R->Font->tf_YSize-1);
X	SetDrMd(R, JAM2);
X}
X
Xnextevent(flags, wait)
Xlong flags;
Xint wait;
X{
X	register int class, code;
X	register struct IntuiMessage *message;
X	int result;
X
X	cursor(1);
X	ModifyIDCMP(W, CLOSEWINDOW | flags);
X	while (1)
X	{
X		if (wait)
X		{
X		    /* get next event, waiting if none are available */
X		    while ((message = (struct IntuiMessage *)GetMsg(W->UserPort)) == NULL)
X		    {
X			Wait(1<<W->UserPort->mp_SigBit);
X		    }
X		}
X		else
X		{
X		    /* get next event, but return if none are available */
X		    message = (struct IntuiMessage *)GetMsg(W->UserPort);
X		    if (message == NULL)
X		    {
X			result = -1;
X			break;
X		    }
X		}
X		class = message->Class;
X		code = message->Code;
X		MouseX = message->MouseX;
X		MouseY = message->MouseY;
X		ReplyMsg((struct Message *)message);
X
X		switch (class)
X		{
X		case VANILLAKEY:
X			result = code;
X			break;
X		case CLOSEWINDOW:
X			result = 'q';
X			break;
X		case MOUSEBUTTONS:
X			switch (code)
X			{
X			case SELECTDOWN:
X				MouseButtons = 1;
X				break;
X			case MENUDOWN:
X				MouseButtons = 2;
X				break;
X			default:
X				MouseButtons = 0;
X				break;
X			}
X			result = MOUSE;
X			break;
X		default:
X			continue;
X		}
X		break;
X	}
X	cursor(0);
X	return result;
X}
X
X/*------------------------------------------------------------------------
X * MIDI I/O Routines for Amiga.
X *
X * Uses low-level serial I/O for simultaneous reads and writes.
X */
X
Xstruct MsgPort	*MidiInPort, *MidiOutPort;
Xstruct IOExtSer	*MidiIn, *MidiOut;
Xint	SerOpen = 0;
X
Xunsigned char   MidiInBuf;
Xint	MidiDataAvail = 0;
X
X/*
X * start an asynchronous read request from MIDI IN
X */
X
Xstartmidiread()
X{
X	MidiIn->IOSer.io_Data = (APTR) &MidiInBuf;
X	MidiIn->IOSer.io_Length = 1;
X	MidiIn->IOSer.io_Command = CMD_READ;
X	MidiIn->IOSer.io_Flags = IOF_QUICK;	/* use quick I/O */
X	BeginIO((struct IORequest *) MidiIn);
X	/* did I/O complete quickly? */
X	if ((MidiIn->IOSer.io_Flags & IOF_QUICK)) {
X		/* wow, data's coming in fast! */
X		MidiDataAvail = 1;
X	} else {
X		/* no data this time, it'll arrive later */
X		MidiDataAvail = 0;
X	}
X}
X
X/*
X * get a byte from MIDI IN.
X * assumes startmidiread has been previously done.  if statmidi has been
X * checked, this function will not wait.  otherwise, it will wait for
X * a single byte to arrive if none is available.
X */
Xunsigned
Xgetmidi()
X{
X	register struct Message	*io;
X        unsigned result;
X
X	/* return previously-received data, if available */
X	if (MidiDataAvail) {
X                result = MidiInBuf & 0xff;
X		/* start a new I/O */
X		startmidiread();
X		return result;
X	}
X
X	/* read next available byte */
X	io = (struct Message *) CheckIO((struct IORequest *) MidiIn);
X	if (io == FALSE) {
X		/* wait for next byte */
X		WaitIO((struct IORequest *) MidiIn);
X		io = &MidiIn->IOSer.io_Message;
X	}
X
X	Remove(&io->mn_Node);
X	result = MidiInBuf;
X	startmidiread();	/* start I/O for next byte */
X	return result;
X}
X
X/*
X * write one byte to MIDI OUT
X */
X
Xsendmidi(c)
Xint c;
X{
X	char	buf = c;
X#ifdef STATISTICS
X        long    bytesOut;
X        long    start, totalTime, average;
X
X
X        ++bytesOut;
X        start = milliclock();
X#endif
X	MidiOut->IOSer.io_Data = (APTR) &buf;
X	MidiOut->IOSer.io_Length = 1;
X	MidiOut->IOSer.io_Command = CMD_WRITE;
X	DoIO((struct IORequest *) MidiOut);	/* synchronous request */
X#ifdef STATISTICS
X        totalTime += milliclock() - start;
X        average = totalTime / bytesOut;
X#endif
X}
X
X/*  FUNCTION
X        sendmulti - send multiple bytes to midi device
X
X    SYNOPSIS
X        void sendmulti(buffer, count)
X                char    *buffer;
X                int     count;
X
X    DESCRIPTION
X        sendmulti transfers <count> bytes from <buffer> to the currently
X        open midi device.
X
X*/
X
Xvoid
Xsendmulti(buffer, count)
X    char *buffer; int count;
X{
X#ifdef STATISTICS
X        long    bytesOut;
X        long    start, totalTime, average;
X
X
X        bytesOut += count;
X        start = milliclock();
X#endif
X        MidiOut->IOSer.io_Data = (APTR) buffer;
X        MidiOut->IOSer.io_Length = count;
X        MidiOut->IOSer.io_Command = CMD_WRITE;
X        DoIO((struct IORequest *) MidiOut);     /* synchronous request */
X#ifdef STATISTICS
X        totalTime += milliclock() - start;
X        average = totalTime / bytesOut;
X#endif
X
X
X}
X
X/*
X * check if any midi data is waiting to be received
X */
Xstatmidi()
X{
X	/* check if data has previously been received */
X	if (MidiDataAvail) return 1;
X
X	/* check if i/o has completed */
X	return (CheckIO((struct IORequest *) MidiIn) == FALSE) ? 0 : 1;
X}
X
Xopenmidi()
X{
X	/* create message port for serial device */
X        MidiInPort = (struct MsgPort *) CreatePort(SERIALNAME,0L);
X	if (MidiInPort == NULL) fatal("Can't create MidiInPort");
X
X	/* create i/o request block for serial device */
X	MidiIn = (struct IOExtSer *)
X                CreateExtIO(MidiInPort, (long) sizeof(struct IOExtSer));
X	if (MidiIn == NULL) fatal("Can't create MidiIn");
X
X	/* open the serial device */
X	MidiIn->io_SerFlags = SERF_SHARED;
X	SerOpen = OpenDevice(SERIALNAME,0,(struct IORequest *) MidiIn,0) == 0 ? 1 : 0;
X	if (SerOpen == 0) fatal("Can't open serial.device");
X
X	/* set serial device parameters */
X	MidiIn->io_Baud = 31250;
X        MidiIn->io_RBufLen = 512;       /* large input buffer - if your synth
X					 * sends dumps larger than this you
X					 * will have to increase it. */
X	MidiIn->io_SerFlags = SERF_RAD_BOOGIE;
X	MidiIn->IOSer.io_Command = SDCMD_SETPARAMS;
X	DoIO((struct IORequest *) MidiIn);
X
X	/* clone MidiIn into MidiOut to allow simultaneous i/o */
X        MidiOutPort = (struct MsgPort *) CreatePort("MidiOut",0L);
X	if (MidiOutPort == NULL) fatal("Can't create MidiOutPort");
X
X	MidiOut = (struct IOExtSer *)
X			CreateExtIO(MidiOutPort, sizeof(struct IOExtSer));
X	*MidiOut = *MidiIn;
X	MidiOut->IOSer.io_Message.mn_ReplyPort = MidiOutPort;
X
X	/* get the MIDI IN port started */
X	startmidiread();
X}
X
Xclosemidi()
X{
X	if (SerOpen) CloseDevice((struct IORequest *)MidiIn);
X	if (MidiIn) DeleteExtIO((struct IORequest *)MidiIn);
X	if (MidiOut) DeleteExtIO((struct IORequest *)MidiOut);
X	if (MidiInPort) DeletePort(MidiInPort);
X	if (MidiOutPort) DeletePort(MidiOutPort);
X}
X
Xflushmidi()
X{
X	while ( STATMIDI )
X		getmidi();
X}
X
X#ifdef AZTEC_C
Xlong milliclock()
X{
X    static long secs, startSecs, micros, startMicros;
X    long product;
X
X    CurrentTime(&secs, &micros);
X    if (startSecs == 0) {
X        startSecs = secs;
X        startMicros = micros;
X    }
X    product =  ((secs - startSecs) * 1000L +
X                (micros - startMicros)/1000L);
X    return product;
X}
X#else
Xlong milliclock()
X{
X	unsigned int clock[2];
X	long milli;
X	timer(clock);
X	milli = clock[0] * 1000 + clock[1] / 1000;
X	return milli;
X}
X#endif
X
Xmillisleep(n)
X{
X    long ticks = n/20;
X
X    if (ticks) Delay(ticks);        /* Avoid the Delay(0) bug! */
X}
X
Xchar *
Xalloc(n)
X{
X	char *p;
X
X	if ( (p=malloc((unsigned)n)) == (char *)NULL ) {
X		fatal("GLIB is out of memory!");
X	}
X	return(p);
X}
X
Xstruct TextAttr font =
X{
X	"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT
X};
X
Xstruct NewScreen ns =
X{
X	0,0,640,200,2,BLACK,WHITE,HIRES,CUSTOMSCREEN,&font,"",NULL,NULL
X};
X
Xwindinit()
X{
X	struct NewWindow nw;
X
X	if (S != NULL) return;
X
X#ifdef ARP
X	FileRequestImminent = FALSE;
X	/* libraries opened by arpc.o */
X#else
X	IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
X	GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0);
X	if (IntuitionBase == NULL || GfxBase == NULL) exit(1);
X#endif
X
X	if ((S = (struct Screen *) OpenScreen(&ns)) == NULL) exit(1);
X
X	nw.LeftEdge = 0;
X	nw.TopEdge = TOPEDGE;
X	nw.Width = WindowWidth;
X	nw.Height = WindowHeight;
X	nw.DetailPen = BLACK;
X	nw.BlockPen = WHITE;
X	nw.Title = NULL;
X	nw.Flags = SMART_REFRESH | ACTIVATE | BACKDROP |
X		   BORDERLESS | NOCAREREFRESH | RMBTRAP;
X	nw.IDCMPFlags = CLOSEWINDOW | VANILLAKEY;
X	nw.Type = CUSTOMSCREEN;
X	nw.FirstGadget = NULL;
X	nw.CheckMark = NULL;
X	nw.Screen = S;
X	nw.BitMap = NULL;
X	if ((W = (struct Window *) OpenWindow(&nw)) == NULL) exit(1);
X	R = W->RPort;
X	SetAPen(R, ORANGE);
X	SetBPen(R, BLACK);
X	ShowTitle(S, FALSE);
X	Cols=80;
X	Rows=24;
X#ifdef ARP
X	MyFileRequest.fr_Window = W;
X#endif
X}
X
Xwindgoto(r,c)
Xint r,c;
X{
X	Move(R, c*8, r*8 + R->Font->tf_Baseline);
X}
X
Xwindeeol()
X{
X	int x, y;
X	x = R->cp_x;
X	y = R->cp_y  - R->Font->tf_Baseline;
X	SetAPen(R, BLACK);
X	RectFill(R, x, y, WindowWidth, y+R->Font->tf_YSize-1);
X	SetAPen(R, ORANGE);
X}
X
Xwinderaserow(r)
X{
X	windgoto(r,0);
X	windeeol();
X}
X
Xwindexit(r)
Xint r;
X{
X#ifdef ARP
X	if (W) CloseWindowSafely(W,NULL);
X#else
X	if (W) CloseWindow(W);
X#endif
X	if (S) CloseScreen(S);
X	exit(r);
X}
X
Xwindclear()
X{
X	SetAPen(R, BLACK);
X	RectFill(R, 0, 0, WindowWidth, WindowHeight);
X	SetAPen(R, ORANGE);
X}
X
X/* windgets - get a line of input from the console, handling backspaces */
Xwindgets(s)
Xchar *s;
X{
X	char *origs = s;
X	int c;
X
X#ifdef ARP
X	if (FileRequestImminent) {
X		FileRequestImminent = FALSE;
X		if (FileRequest(&MyFileRequest)==NULL) {
X      			message("No file name entered");
X			strcpy(s,"");
X      		}   
X		else {
X			strcpy(s,DirName);
X			if(s[0]!=0 && (s[strlen(s)-1]!=':'))
X				strcat(s,"/");
X			strcat(s,FileName);
X		}
X	}
X	else {
X#endif
X	SetAPen(R, WHITE);
X
X	while ( (c=getconsole()) != '\n' && c!='\r' && c!= EOF ) {
X		if ( c == '\b' ) {
X			if ( s > origs ) {
X				wbackspace();
X				s--;
X			}
X		}
X		else if (c == 24) {
X			while (s > origs) {
X				wbackspace();
X				s--;
X			}
X		} else if (isprint(c)) {
X			windputc(c);
X			*s++ = c;
X		}
X		windrefresh();
X	}
X	*s = '\0';
X	SetAPen(R, ORANGE);
X#ifdef ARP
X	}
X#endif
X}
X
Xwindstr(s)
Xchar *s;
X{
X#ifdef ARP
X	if (!strnicmp(s,"File name",9))
X		FileRequestImminent = TRUE;
X	else
X#endif
X
X		Text(R, s, strlen(s));
X}
X
Xwindputc(c)
Xint c;
X{
X	char s = c;
X	Text(R, &s, 1);
X}
X
Xwbackspace()
X{
X	int x, y;
X	x = R->cp_x;
X	y = R->cp_y;
X	Move(R, x-8, y);
X	windputc(' ');
X	Move(R, x-8, y);
X}
X
Xwindrefresh()
X{
X}
X
Xbeep()
X{
X	DisplayBeep(S);
X}
X
Xwindhigh()
X{
X}
X
Xwindnorm()
X{
X}
X
Xstruct IntuiText fataltext = { 1,0,COMPLEMENT,16,32,NULL,NULL,NULL };
Xstruct IntuiText canceltext = { 1,0,COMPLEMENT,2,2,NULL,"cancel",NULL };
X
Xfatal(text)
Xchar *text;
X{
X	fataltext.IText = text;
X	AutoRequest(W, &fataltext, NULL, &canceltext, 0, 0, 320, 90);
X	bye();
X}
X
X/****************
X * openls(), nextls(), and closels() are used to scan the current directory.
X ***************/
X
X#ifdef AZTEC_C
X#include "amigadir.h"
Xstatic DIR *dir;
Xopenls()
X{
X    dir = opendir("");
X}
Xchar *
Xnextls()
X{
X    struct direct *result;
X
X    if (dir) {
X        if (result = readdir(dir)) {
X            return result->d_name;
X        }
X        closels();
X    }
X    return NULL;
X}
X
Xclosels()
X{
X    if (dir) {
X        closedir(dir);
X        dir = NULL;
X    }
X}
X#else
Xstruct FileInfoBlock *lsinfo = NULL;
X
Xopenls()
X{
X}
X
Xchar *
Xnextls()
X{
X	int error;
X	if (lsinfo == NULL) {
X		lsinfo = (struct FileInfoBlock *) alloc(sizeof(struct FileInfoBlock));
X		error = dfind(lsinfo, "#?", 0);
X	} else {
X		error = dnext(lsinfo);
X	}
X	if (error == 0) {
X		return lsinfo->fib_FileName;
X	} else {
X		return NULL;
X	}
X}
X
Xclosels()
X{
X	free(lsinfo);
X	lsinfo = NULL;
X}
X#endif
X
END_OF_FILE
if test 13113 -ne `wc -c <'amigmach.c'`; then
    echo shar: \"'amigmach.c'\" unpacked with wrong size!
fi
# end of 'amigmach.c'
fi
if test -f 'd10urp.mnu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'d10urp.mnu'\"
else
echo shar: Extracting \"'d10urp.mnu'\" \(13527 characters\)
sed "s/^X//" >'d10urp.mnu' <<'END_OF_FILE'
X/* $Id: d10urp.mnu,v 1.6 89/05/06 17:13:19 lee Exp $
X * GLIB - a Generic LIBrarian and editor for synths
X *
X * D10 User Rhythm Pattern Librarian
X *
X * Code started 31 JAN 89 --  Michael R. Kesti mrk@gvgspd.GVG.TEK.COM
X * modified by Greg Lee
X * 
X */
X
X#include "glib.h"
X#include "vis.h"
X
X#define D10URPSIZE 588
X#define URPBASEADDR 0x0a0000
X#define RESERVESIZE 20
X
Xchar *visnum(), *visonoff();
X
X
X/* This array contains arbitrary screen labels */
Xstruct labelinfo Ldurp[] = {
X#MENU
X
X
X
X
X
X
X
X
X
X
X
X
X               No User Rhythm Pattern editing is supported.
X
X
X
X
X
X
X
X
X
X
X Press SPACE BAR to sound note %   at volume %   for duration %  on channel % .
X#END
X-1,-1,NULL
X};
X
Xstruct paraminfo  Pdurp[] =  {
X/*
XNAME		TYPE		POS	MAX	OFFSET	MASK	SHIFT	ADHOC
X */
X#O autopitch	num		%%	127	-60
X#O autovol	num		%%	127	-63
X#O autodur	num		%%	20	-5	*5
X#O autochan	num		%%	16	-1	*5
XNULL,NULL,-1,-1,-1,-1,visnum,0,0,0,0
X};
X
X
X/*
X * durpnum
X *
X * Convert a voice number (0 to 31) to the string displayed in the
X * librarian (ie. 51 to 88).
X */
X
Xchar *
Xdurpnum(n)
X{
X	static char v[3];
X
X	if ( n < 0 || n > 31 )
X		return("??");
X
X	v[0] = n/8 + '5';
X	v[1] = n%8 + '1';
X	v[2] = '\0';
X	return(v);
X}
X
X/*
X * dnumurp
X *
X * Convert a display-style voice number (55 to 88) to internal
X * format (0 to 31).
X */
X
Xdnumurp(n)
Xint n;
X{
X	int ld, rd;
X	
X	/* crack out the digits as octal codes */
X	ld = (n / 10) - 1; /* middle digit */
X	rd = (n % 10) - 1; /* right digit */
X
X	if(ld < 4 || ld > 7 || rd < 0 || rd > 7) {
X		return(-1);
X	} else {
X		return(((ld - 4) * 8) + rd); /* combine as octal */
X	}
X}
X
X/*
X * durpdin
X *
X * Take library bank 'data' and stuff values in the P array, by using
X * the setval function.
X */
X
Xdurpdin(data)
Xchar *data;
X{
X	/* The first RESERVESIZE bytes are reserved (arbitrarily) for the voice name */
X}
X
X/*
X * durpdout
X *
X * Take (possibly changed) parameters values out of the P array and
X * put them back into the library bank 'data'.
X */
X
Xdurpdout(data)
Xchar *data;
X{
X}
X
X/*
X * durpsedit
X *
X * Send a single voice to the edit buffer of the D10.  This will be whatever
X * voice is currently selected.
X */
X
Xdurpsedit(data)
Xchar *data;
X{
X}
X
X/*
X * durpnof
X *
X * Return a pointer to the voice name buried in library bank data.
X */
Xchar *
Xdurpnof(data)
Xchar *data;
X{
X	static char buf[10];
X	int n, v;
X
X	for(n = 0; n < D10URPSIZE; n++)
X		if ( data[n + RESERVESIZE] != 0 ) break;
X	if ( n != D10URPSIZE ) {
X		v = data[RESERVESIZE + 2] + (16 * data[RESERVESIZE + 3]);
X		sprintf(buf, "%2d events", v);
X	}
X	else
X		strcpy(buf, "         ");
X	return(buf);
X}
X
X/*
X * durpsnof
X *
X * Set the voice name buried in data to name.
X */
Xdurpsnof(data,name)
Xchar *data;
Xchar *name;
X{
X}
X
X/* durpsone - send a single voice to the D10 */
Xdurpsone(iv, data)
Xint iv;
Xchar *data;
X{
X	int n;
X	int cksum;
X	long curadd;
X	int addbyte;
X
X	curadd = URPBASEADDR;
X
X	for(n = 0; n < iv; n++) {
X		curadd += 0x44c;	/* D10URPSIZE */
X
X		if((curadd & 0x80) != 0) {
X			curadd &= 0x7fff7f;
X			curadd += 0x100;
X		}
X		if((curadd & 0x8000) != 0) {
X			curadd &= 0x7f7f7f;
X			curadd += 0x10000;
X		}
X	}
X
X	sendmidi(0xf0);
X	sendmidi(0x41);
X	sendmidi(0x10);
X	sendmidi(0x16);
X	sendmidi(0x12);		/* DT1 - Data set 1 command */
X
X	addbyte = ((curadd >> 16) & 0x7f);	/* address msb */
X	sendmidi(addbyte);
X	cksum = addbyte;
X	addbyte = ((curadd >> 8) & 0x7f);
X	sendmidi(addbyte);
X	cksum += addbyte;
X	addbyte = (curadd & 0x7f);		/* address lsb */
X	sendmidi(addbyte);
X	cksum += addbyte;
X
X	for(n = 0; n < 256; n++) {
X		sendmidi(data[n + RESERVESIZE] & 0x7f);
X		cksum += data[n + RESERVESIZE] & 0x7f;
X	}
X	sendmidi((-cksum) & 0x7f);	/* checksum */
X	sendmidi(EOX);
X
X	curadd += 256;
X
X	if((curadd & 0x8000) != 0) {
X		curadd &= 0x7f7f7f;
X		curadd += 0x10000;
X	}
X	sendmidi(0xf0);
X	sendmidi(0x41);
X	sendmidi(0x10);
X	sendmidi(0x16);
X	sendmidi(0x12);		/* DT1 - Data set 1 command */
X
X	addbyte = ((curadd >> 16) & 0x7f);	/* address msb */
X	sendmidi(addbyte);
X	cksum = addbyte;
X	addbyte = ((curadd >> 8) & 0x7f);
X	sendmidi(addbyte);
X	cksum += addbyte;
X	addbyte = (curadd & 0x7f);		/* address lsb */
X	sendmidi(addbyte);
X	cksum += addbyte;
X
X	for(n = 256; n < 512; n++) {
X		sendmidi(data[n + RESERVESIZE] & 0x7f);
X		cksum += data[n + RESERVESIZE] & 0x7f;
X	}
X	sendmidi((-cksum) & 0x7f);	/* checksum */
X	sendmidi(EOX);
X
X
X	curadd += 256;
X
X	if((curadd & 0x8000) != 0) {
X		curadd &= 0x7f7f7f;
X		curadd += 0x10000;
X	}
X
X	sendmidi(0xf0);
X	sendmidi(0x41);
X	sendmidi(0x10);
X	sendmidi(0x16);
X	sendmidi(0x12);		/* DT1 - Data set 1 command */
X
X	addbyte = ((curadd >> 16) & 0x7f);	/* address msb */
X	sendmidi(addbyte);
X	cksum = addbyte;
X	addbyte = ((curadd >> 8) & 0x7f);
X	sendmidi(addbyte);
X	cksum += addbyte;
X	addbyte = (curadd & 0x7f);		/* address lsb */
X	sendmidi(addbyte);
X	cksum += addbyte;
X
X	for(n = 512; n < (D10URPSIZE - 512); n++) {
X		sendmidi(data[n + RESERVESIZE] & 0x7f);
X		cksum += data[n + RESERVESIZE] & 0x7f;
X	}
X	sendmidi((-cksum) & 0x7f);	/* checksum */
X	sendmidi(EOX);
X
X	return(0);
X}
X
X/* durpgbulk - Request and read a bulk dump from the D10 */
Xdurpgbulk(data)
Xchar *data;
X{
X	static	char Buff[BUFSIZ];
X	int n, v, b2, ret = 1;
X	long begin, toolong;
X	long curadd;
X	int addbyte;
X	int cksum;
X	
X	sprintf(Buff,"\n");
X	windstr(Buff);
X	
X	curadd = URPBASEADDR;
X
X	for(v = 0; v < Nvoices; v++) {
X
X		flushmidi();
X
X		if(v % 10 != 0) {
X			sprintf(Buff, ".");
X		} else {
X			sprintf(Buff,"%d", (v / 10));
X		}
X		windstr(Buff);
X
X	/* request the voice */
X		sendmidi(0xf0);
X		sendmidi(0x41);
X		sendmidi(0x10);
X		sendmidi(0x16);
X		sendmidi(0x11);		/* RQ1 - Data request 1 command */
X
X		addbyte = ((curadd >> 16) & 0x7f);	/* address msb */
X		sendmidi(addbyte);
X		cksum = addbyte;
X		addbyte = ((curadd >> 8) & 0x7f);
X		sendmidi(addbyte);
X		cksum += addbyte;
X		addbyte = (curadd & 0x7f);		/* address lsb */
X		sendmidi(addbyte);
X		cksum += addbyte;
X
X		sendmidi(0x00);		/* length msb */
X		cksum += 0x00;
X		sendmidi(0x04);		/* should be D10URPSIZE */
X		cksum += 0x04;
X		sendmidi(0x4c);		/* length lsb */
X		cksum += 0x4c;
X
X		sendmidi((-cksum) & 0x7f);	/* checksum */
X		sendmidi(EOX);
X	
X	/* set up timeout */
X		begin = milliclock();
X		toolong = begin + (1000 * TIMEOUT);
X
X	/* read header */
X		for(n = 0; n < 8; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8))
X					n++;
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout waiting for header";
X					goto getout;
X				}
X			}
X		}
X
X	/* read data */
X		for(n = 0; n < 256; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8)) {
X					VOICEBYTE(data,v,n + RESERVESIZE) = b2;
X					n++;
X				}
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout reading data";
X					goto timeout0;
X				}
X			}
X		}
X
X	timeout0:
X		if ( n != 256 ) {
X			Reason = "Timeout reading data!";
X			goto getout;
X		}
X
X	/* read checksum */
X		for(n = 0; n < 1; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8))
X					n++;
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout reading checksum";
X					goto getout;
X				}
X			}
X		}
X
X	/* read EOX */
X		for(n = 0; n < 1; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8))
X					if ( b2 != EOX ) {
X						sprintf(Buff,"EOX not received (%X)\n", b2);
X						Reason = Buff;
X						goto getout;
X					}
X					n++;
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout reading EOX";
X					goto getout;
X				}
X			}
X		}
X
X	/* read header */
X		for(n = 0; n < 8; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8))
X					n++;
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout waiting for header";
X					goto getout;
X				}
X			}
X		}
X
X	/* read data */
X		for(n = 0; n < 256; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8)) {
X					VOICEBYTE(data,v,n + RESERVESIZE + 256) = b2;
X					n++;
X				}
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout reading data";
X					goto timeout1;
X				}
X			}
X		}
X
X	timeout1:
X		if ( n != 256 ) {
X			Reason = "Timeout reading data!";
X			goto getout;
X		}
X
X	/* read checksum */
X		for(n = 0; n < 1; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8))
X					n++;
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout reading checksum";
X					goto getout;
X				}
X			}
X		}
X
X	/* read EOX */
X		for(n = 0; n < 1; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8))
X					if ( b2 != EOX ) {
X						sprintf(Buff,"EOX not received (%X)\n", b2);
X						Reason = Buff;
X						goto getout;
X					}
X					n++;
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout reading EOX";
X					goto getout;
X				}
X			}
X		}
X
X	/* read header */
X		for(n = 0; n < 8; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8))
X					n++;
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout waiting for header";
X					goto getout;
X				}
X			}
X		}
X
X	/* read data */
X		for(n = 0; n < 76; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8)) {
X					VOICEBYTE(data,v,n + RESERVESIZE + 512) = b2;
X					n++;
X				}
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout reading data";
X					goto timeout2;
X				}
X			}
X		}
X
X	timeout2:
X		if ( n != 76 ) {
X			Reason = "Timeout reading data!";
X			goto getout;
X		}
X
X	/* read checksum */
X		for(n = 0; n < 1; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8))
X					n++;
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout reading checksum";
X					goto getout;
X				}
X			}
X		}
X
X	/* read EOX */
X		for(n = 0; n < 1; ) {
X			if ( STATMIDI ) {
X				b2 = (getmidi() & 0xff);
X				/* burn active sensing and timing clock */
X				if((b2 != 0xfe) && (b2 != 0xf8))
X					if ( b2 != EOX ) {
X						sprintf(Buff,"EOX not received (%X)\n", b2);
X						Reason = Buff;
X						goto getout;
X					}
X					n++;
X			} else {
X				if ( milliclock() > toolong ) {
X					Reason = "Timeout reading EOX";
X					goto getout;
X				}
X			}
X		}
X
X		curadd += 0x44c;		/* D10URPSIZE */
X
X		if((curadd & 0x80) != 0) {
X			curadd &= 0x7fff7f;
X			curadd += 0x100;
X		}
X		if((curadd & 0x8000) != 0) {
X			curadd &= 0x7f7f7f;
X			curadd += 0x10000;
X		}
X
X	} /* go back for another voice */
X
X	Reason = "";
X	ret = 0;	/* all's well */
X
Xgetout:
X	return(ret);
X}
X
X/* durpsbulk - send a bulk dump to the D10 */
Xdurpsbulk(data)
Xchar *data;
X{
X	static char Buff[BUFSIZ];
X	int v, n;
X	int cksum;
X	long curadd, intadd;
X	int addbyte, databyte;
X	int curoff;
X
X	curadd = URPBASEADDR;
X	curoff = 0;	
X	sprintf(Buff,"\n");
X	windstr(Buff);
X
X	for(v = 0; v <Nvoices ; v++) {
X		if((((v > 63) ? (v - 64) : v) % 10) != 0) {
X			sprintf(Buff, ".");
X		} else {
X			sprintf(Buff,"%d", (((v > 63) ? (v - 64) : v) / 10));
X		}
X
X		windstr(Buff);
X
X		sendmidi(0xf0);
X		sendmidi(0x41);
X		sendmidi(0x10);
X		sendmidi(0x16);
X		sendmidi(0x12);		/* DT1 - Data set 1 command */
X		addbyte = ((curadd >> 16) & 0x7f);	/* address msb */
X		sendmidi(addbyte);
X		cksum = addbyte;
X		addbyte = ((curadd >> 8) & 0x7f);
X		sendmidi(addbyte);
X		cksum += addbyte;
X		addbyte = (curadd & 0x7f);		/* address lsb */
X		sendmidi(addbyte);
X		cksum += addbyte;
X
X		for(n = 0; n < 256; n++) {
X			databyte = data[curoff + n + RESERVESIZE] & 0x7f;
X			sendmidi(databyte);
X			cksum += databyte;
X		}
X		sendmidi((-cksum) & 0x7f);	/* checksum */
X		sendmidi(EOX);
X
X		intadd = curadd + 256;
X
X		if((intadd & 0x8000) != 0) {
X			intadd &= 0x7f7f7f;
X			intadd += 0x10000;
X		}
X
X		sendmidi(0xf0);
X		sendmidi(0x41);
X		sendmidi(0x10);
X		sendmidi(0x16);
X		sendmidi(0x12);		/* DT1 - Data set 1 command */
X		addbyte = ((intadd >> 16) & 0x7f);	/* address msb */
X		sendmidi(addbyte);
X		cksum = addbyte;
X		addbyte = ((intadd >> 8) & 0x7f);
X		sendmidi(addbyte);
X		cksum += addbyte;
X		addbyte = (intadd & 0x7f);		/* address lsb */
X		sendmidi(addbyte);
X		cksum += addbyte;
X
X		for(n = 256; n < 512; n++) {
X			databyte = data[curoff + n + RESERVESIZE] & 0x7f;
X			sendmidi(databyte);
X			cksum += databyte;
X		}
X		sendmidi((-cksum) & 0x7f);	/* checksum */
X		sendmidi(EOX);
X
X		intadd += 256;
X
X		if((intadd & 0x8000) != 0) {
X			intadd &= 0x7f7f7f;
X			intadd += 0x10000;
X		}
X
X		sendmidi(0xf0);
X		sendmidi(0x41);
X		sendmidi(0x10);
X		sendmidi(0x16);
X		sendmidi(0x12);		/* DT1 - Data set 1 command */
X		addbyte = ((curadd >> 16) & 0x7f);	/* address msb */
X		sendmidi(addbyte);
X		cksum = addbyte;
X		addbyte = ((curadd >> 8) & 0x7f);
X		sendmidi(addbyte);
X		cksum += addbyte;
X		addbyte = (curadd & 0x7f);		/* address lsb */
X		sendmidi(addbyte);
X		cksum += addbyte;
X
X		for(n = 512; n < (D10URPSIZE - 512); n++) {
X			databyte = data[curoff + n + RESERVESIZE] & 0x7f;
X			sendmidi(databyte);
X			cksum += databyte;
X		}
X		sendmidi((-cksum) & 0x7f);	/* checksum */
X		sendmidi(EOX);
X
X		curadd += 0x44c;		/* D10URPSIZE */
X
X		if((curadd & 0x80) != 0) {
X			curadd &= 0x7fff7f;
X			curadd += 0x100;
X		}
X		if((curadd & 0x8000) != 0) {
X			curadd &= 0x7f7f7f;
X			curadd += 0x10000;
X		}
X		curoff += (D10URPSIZE + RESERVESIZE);
X	}
X	return(0);
X}
X
X/* end */
END_OF_FILE
if test 13527 -ne `wc -c <'d10urp.mnu'`; then
    echo shar: \"'d10urp.mnu'\" unpacked with wrong size!
fi
# end of 'd10urp.mnu'
fi
if test -f 'menutoc.l' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'menutoc.l'\"
else
echo shar: Extracting \"'menutoc.l'\" \(12722 characters\)
sed "s/^X//" >'menutoc.l' <<'END_OF_FILE'
X%{
X/* $Id: menutoc.l,v 1.6 89/05/06 17:13:37 lee Exp $
X *	menutoc.l	-- Greg Lee, lee@uhccux.uhcc.hawaii.edu
X *			   February 1989
X * Scott Snyder added cmd line args and fixed a bug (see comment below)
X * Mark Rinfret made a couple changes for Aztec C
X * $Log:	menutoc.l,v $
X * Revision 1.6  89/05/06  17:13:37  lee
X * rel. to comp.sources.misc
X * 
X
X	Generate C language menu module for Glib from menu specification.
X
XCompile:
X	flex menutoc.l
X	cc -o menutoc lex.yy.c
Xor
X	lex menutoc.l
X	cc -o menutoc lex.yy.c -ll
X
XUsage:
X	menutoc <file.menu >file.c
X
XDescription:
X
XMenutoc simplifies constructing and modifying synthesizer-specific
Xmodules for Tim Thompson's Glib.  It allows the form of the on-screen
Xmenu to be specified as a picture in the menu source file, and generates
X'setval' and 'getval' calls automatically.  This version works with
Xthe version of Glib modified by Michael Kesti.
X
X[The original version of flex distributed on Usenet has a bug which
X prevents setting the start state.  If this is a problem, you can
X fix it by making two changes to flex's skeleton files:
X	CHANGE
X	static int yy_start;
X	TO
X	static int yy_start = 0;
X
X	CHANGE
X		yy_start = 1;
X	TO
X		if (!yy_start) yy_start = 1;
X]
X
XThe following characterization of how menutoc works is probably
Xnot entirely clear.  Look at the example k1single.menu and the
Xsource code to get a more exact idea.  The source k1single.menu
Xgives the C file k1single.c after processing by menutoc.
X
XThe menu source file should contain five special preprocessor
Xdirectives: '#MENU' (once), '#END' (once), '#O' (one for each
Xlabel name), '#GETVAL' (once), and '#SETVAL' (once).  The source
Xfile has four sections:
X	(1) the portion before the '#MENU' directive is passed
X	    through unchanged to the output,
X	(2) a picture of the screen menu is given between the
X	    '#MENU' and '#END' directives,
X	(3) after the '#END' directive is C code with '#O' directives
X	    which specify the data offsets of variables and with
X	    '%%' or '@@' references to the screen locations for
X	    variable values, and
X	(4) more C code containing somewhere the '#SETVAL' and
X	    '#GETVAL' directives which cause a series of calls
X	    to the 'setval' and 'getval' functions to be generated,
X	    making use of the offset information given by the '#O'
X	    directives in the preceding section.
X
XThe picture of the screen menu has constant strings in the position
Xthey will be output to the screen and '%' or '@' in each position
Xwhere the current value of some variable is to be displayed by
XGlib.  The locations of the '%'s and '@'s are remembered in the
Xorder in which they are encountered (scanning left-to-right and
Xtop-to-bottom in the picture), then the corresponding row/column
Xcoordinates are substituted for '%%'s and '@@'s encountered in
Xsection 3 of the source file.  The '%'s and '@'s are stored
Xindependently so as to make it more convenient to specify menus
Xthat have two columns of values.
X
XThe '#O' specifications are given in the form:
X
X#O <NAME> <TYPE> <POS> <MAX> <OFFSET> <MASK> <SHIFT> <ADHOC>
X
XSuch a line generates one "paraminfo" entry for an array, and some of
Xthe information is saved and made use of in generating 'setval' and
X'getval' calls.  NAME is the name of a variable label (no caps); TYPE is
Xthe name of a vis-function used to display the current value on the
Xscreen; POS should be either '%%' or '@@', which will be replaced by row
Xand column coordinates of the position to display the value; MAX is the
Xmaximum value the glib editor is to accept (the minimum is assumed to be
X0); OFFSET is the offset of the byte containing the value in the data
Xarray.  (If OFFSET is negative, the (positive) value is taken to be the
Xinitial value rather than the offset.)
X
XThe NAME argument may begin with a digit specifying a repetition
Xcount.  It's a shortcut which is like giving several consecutive
X#O-lines for <NAME>1, <NAME>2, ...
X
XThe last three #O arguments are optional.  MASK is a number with 1-bits
Xin positions holding the value for those cases where part of a byte is
Xused for some other purpose.  SHIFT is the number of bits the bitfield
Xis shifted left in the byte.  So, for instance, if the synth keeps a
Xvalue in the 4th, 5th, and 6th bits, one would give '0x1C' for the MASK
Xand '3' for SHIFT.  (Use caps for hex digits A-F.)
X
XThere is no systematic provision for values some of whose bits are found
Xin one byte, some in another.  The ADHOC argument has the form
X'*<digit>' and is used in the example to provide for such a case.  The
Xcode below in this file was just made up ad hoc for two such cases I
Xencountered with the Kawai K1.
X
X*/
X
X/*
X * Modified 4-13-89 by Scott Snyder:
X *  1. Increased MAXVAL from 100 to 200 (for DX7).
X *  2. Changed type of temps from 'unsigned char' to 'unsigned' (for DX7).
X *  3. Added command line processing (since TMAKE doesn't support redirection).
X *
X * 4-19-18
X *  Fixed bug with zero offsets.
X */
X
X#ifdef AZTEC_C
Xlong atol();
X# define strtol(a, b, c) atol(a)
X#endif
X#define MAXLINE 133
X#define MAXVAL 200
X#define MAXVSTRINGS 200
X#define MAXBUF 2000
X
X	char *infname = "file.mnu";
X	int lcnt = 1;
X	int i, j, k, wcol=0, col=0, row=0;
X	char word[MAXLINE];
X	int wordp = 0;
X	int valpos[MAXVAL][2];
X	int valpos2[MAXVAL][2];
X	int valcnt = 0;
X	int valcnt2= 0;
X	int offset;
X	int nlist[MAXVSTRINGS][6];
X	int np = 0;
X	char buf[MAXBUF];
X	int bufp=0;
X	int multiple, special;
X        int vmin, vmax, vval, mask, vshift, vrow, vcol, iflag;
X	char visfunc[20];
X	int state;
X%}
X
X%s M IG VAL O P Q
X
X%%
X
X<IG>^#[ \t]*MENU.*\n	{ BEGIN(M); lcnt++; }
X<IG>\n			{ ECHO; lcnt++; }
X<IG>.			ECHO;
X
X<M>"@"	{	writeword();
X		if (valcnt2+1 >= MAXVAL) {
X		    fprintf(stderr,"menutoc: too many @s in menu\n");
X		    exit(1);
X		}
X		valpos2[valcnt2][0] = row;
X		valpos2[valcnt2++][1] = col;
X		col += 1;
X};
X
X<M>"%"	{	writeword();
X		if (valcnt+1 >= MAXVAL) {
X		    fprintf(stderr,"menutoc: too many %%s in menu\n");
X		    exit(1);
X		}
X		valpos[valcnt][0] = row;
X		valpos[valcnt++][1] = col;
X		col += 1;
X};
X
X<M>[ ]*	{	if (yyleng > 4) writeword();
X		else if (wordp) for (i=0; i<yyleng; i++) append(' ');
X		col += yyleng;
X};
X
X<M>\t  {	writeword(); col = ((col + 8)/8)*8;
X};
X
X<M>\n  {	writeword(); col = 0; row += 1; lcnt++;
X};
X
X<M>.  {		append(yytext[0]); col += 1;
X};
X
X<M>^#[ \t]*END.*\n  {
X		BEGIN(VAL); i = 0; j = 0; lcnt++;
X		printf("# line %d \"%s\"\n", lcnt, infname);
X};
X
X<VAL>^"#O"[ \t]+  {
X		if (np+1 >= MAXVSTRINGS) {
X		    fprintf(stderr,"menutoc: too many VSTRINGs\n");
X		    exit(1);
X		}
X		BEGIN(O);
X		multiple = special = 0;
X		vmax = offset = mask = vshift = vmin = vrow = vcol = iflag = 0;
X		state = 0;
X};
X
X<O>[0-9]	multiple = atoi(yytext);
X
X<O>[a-z][a-z_0-9]*  {
X		if (bufp+yyleng >= MAXBUF) {
X		    fprintf(stderr,"menutoc: out of storage room\n");
X		    exit(1);
X		}
X		nlist[np][0] = bufp;
X		strcpy(buf+bufp, yytext);
X		bufp += yyleng+1;
X		BEGIN(P);
X};
X
X<P>[ \t]*	;
X<P>[a-z0-9_]+  {
X		strcpy(visfunc, yytext);
X		if (yyleng >= 20) {
X		    fprintf(stderr,"menutoc: vis name too long\n");
X		    exit(1);
X		}
X		BEGIN(Q);
X};
X
X<Q>[ \t]*	;
X<Q>\n  {	lcnt++;
X		if (special == 5) vmin = 1;
X		else vmin = 0;
X		if (offset < 0) vval = -offset;
X		else vval = 0;
X
X		if (multiple) for (k=0; k<multiple; k++) {
X			printf("\"%s%d\",NULL,-1,-1,%d,%d,vis%s,%d,%d,%d,0,\n",
X				buf+nlist[np][0], k+1, vrow, vcol, visfunc,
X				vmin, vmax, vval);
X			if (k+1 < multiple) {
X			if (iflag) {
X			    if (i < valcnt) {
X				vrow = valpos[i][0]; vcol = valpos[i++][1];
X			    } else
X			    fprintf(stderr,"menutoc: too many %%%%s\n");
X			} else
X			    if (j < valcnt2) {
X				vrow = valpos2[j][0]; vcol = valpos2[j++][1];
X			    } else
X			    fprintf(stderr,"menutoc: too many @@s\n");
X			}
X		}
X		else
X			printf("\"%s\",NULL,-1,-1,%d,%d,vis%s,%d,%d,%d,0,\n",
X			    buf+nlist[np][0], vrow, vcol, visfunc,
X			    vmin, vmax, vval);
X		if (multiple)
X			printf("# line %d \"%s\"\n", lcnt, infname);
X		nlist[np][1] = offset;
X		nlist[np][2] = mask;
X		nlist[np][3] = vshift;
X		nlist[np][4] = multiple;
X		nlist[np][5] = special;
X		np++;
X		BEGIN(VAL);
X};
X
X<Q>"-"*[0-9A-Fx]+  {
X		k = (int)strtol(yytext, (char **)NULL, 0);
X		switch (state) {
X		  case 0: vmax = k;   break;
X		  case 1: offset = k; break;
X		  case 2: mask = k;   break;
X		  case 3: vshift = k; break;
X		  case 4: vmin = k;   break;
X                }
X                ++state;
X};
X
X<Q>"%%"  {	if (i < valcnt) {
X			vrow = valpos[i][0];
X			vcol = valpos[i][1];
X			i++;
X			iflag++;
X		}
X		else fprintf(stderr,"\nmenutoc: too many %%%%s\n");
X};
X<Q>"@@"  {	if (j < valcnt2) {
X			vrow = valpos2[j][0];
X			vcol = valpos2[j][1];
X			j++;
X		}
X		else fprintf(stderr,"\nmenutoc: too many @@s\n");
X};
X<Q>"--"  {	vrow = -1;
X		vcol = -1;
X};
X<Q>"*"[1-9]  {
X		special = yytext[1] - '0';
X};
X<VAL>.		ECHO;
X<VAL>\n		{ ECHO; lcnt++; }
X
X<VAL>^#[ \t]*SETVAL.*\n  {
X		lcnt++;
X		/* make sure i,k will be used before declaring them */
X		for (k=0; k<np; k++)
X			if (nlist[k][1]>=0 && (nlist[k][5] || nlist[k][2])) {
X				printf("\tINT16 i, k;\n\n");
X				break;
X			}
X		for (k=0; k<np; k++) dosetval(k);
X		printf("# line %d \"%s\"\n", lcnt, infname);
X};
X
X<VAL>^#[ \t]*GETVAL.*\n  {
X		lcnt++;
X		/* make sure i,j,k will be used before declaring them */
X		for (k=0; k<np; k++)
X			if (nlist[k][1]>=0 && (nlist[k][5] || nlist[k][2])) {
X				printf("\tINT16 i, j, k;\n\n");
X				break;
X			}
X		for (k=0; k<np; k++) dogetval(k);
X		printf("# line %d \"%s\"\n", lcnt, infname);
X};
X
X<VAL>\\%%+	printf("%s", yytext+1);
X<VAL>\\@@+	printf("%s", yytext+1);
X
X<VAL>"@@"  {	if (j < valcnt2) {
X			printf("%d, %d", valpos2[j][0], valpos2[j][1]);
X			j++;
X		}
X		else fprintf(stderr,"\nmenutoc: too many @@s\n");
X};
X
X<VAL>"%%"  {	if (i < valcnt) {
X			printf("%d, %d", valpos[i][0], valpos[i][1]);
X			i++;
X		}
X		else fprintf(stderr,"\nmenutoc: too many %%%%s\n");
X};
X
X<VAL>.		ECHO;
X<VAL>\n		{ ECHO; lcnt++; }
X
X%%
Xdosetval(k)
Xint k;
X{	int m;
X
X	special  = nlist[k][5];
X
X	if (special == 1 || special == 3) k++;
X	else if (special == 2 || special == 4) k--;
X
X	bufp     = nlist[k][0];
X	offset   = nlist[k][1];
X	mask     = nlist[k][2];
X	vshift   = nlist[k][3];
X	multiple = nlist[k][4];
X
X	if (offset < 0) return;
X
X	if (multiple) for (m = 1; m <= multiple; m++)
X	{	outsetval(m); offset++;		}
X	else	outsetval(0);
X}
X
Xoutsetval(m)
Xint m;
X{
X	if (!mask && !special) {
X		printf("setval(\"%s", buf+bufp);
X		if (m) printf("%d", m);
X		printf("\",(INT16)data[RESERVESIZE+%d]);\n",offset);
X		return;
X	}
X
X	printf("i = (INT16)data[RESERVESIZE+%d]; ", offset);
X	if (mask) {
X		printf("i &= %d; ", mask);
X		if (vshift) printf("i >>= %d; ", vshift);
X	}
X
X	if (special == 2) printf("i += k << 1;\n");
X	else if (special == 4) printf("i += k << 7;\n");
X
X	if (special == 1 || special == 3) printf("k = i;\n");
X	else {
X		printf("setval(\"%s", buf+bufp);
X		if (m) printf("%d", m);
X		printf("\",i);\n");
X	}
X}
X
Xdogetval(k)
Xint k;
X{	int m;
X
X	bufp     = nlist[k][0];
X	offset   = nlist[k][1];
X	mask     = nlist[k][2];
X	vshift   = nlist[k][3];
X	multiple = nlist[k][4];
X	special  = nlist[k][5];
X
X	if (offset < 0) return;
X
X	if (multiple) for (m = 1; m <= multiple; m++)
X	{	outgetval(m); offset++;		}
X	else	outgetval(0);
X}
X
Xoutgetval(m)
Xint m;
X{
X	if (!mask && !special) {
X		printf("data[RESERVESIZE+%d] = ", offset);
X		printf("getval(\"%s", buf+bufp);
X		if (m) printf("%d", m);
X		printf("\");\n");
X		return;
X	}
X
X	if (special == 2 || special == 4)
X		printf("i = k; ");
X	else {
X		printf("i = getval(\"%s", buf+bufp);
X		if (m) printf("%d", m);
X		printf("\"); ");
X	}
X
X	if (special == 1) printf("k = i >> 1; i &= 1;\n");
X	else if (special == 3) printf("k = i >> 7; i &= 0x7f;\n");
X
X	if (mask) {
X		printf("j = data[RESERVESIZE+%d]; ", offset);
X		if (vshift) printf("i <<= %d; ", vshift);
X		printf("j &= ~%d; ", mask);
X		printf("i = j|i; ");
X	}
X	printf("data[RESERVESIZE+%d] = i;\n", offset);
X}
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{	char *basename();
X
X  if (argc > 1) {
X    infname = basename(argv[1]);
X    if (freopen(argv[1], "r", stdin) == NULL) {
X      perror("Can't open input file");
X      exit(1);
X    }
X  }
X  if (argc > 2) {
X    if (freopen(argv[2], "w", stdout) == NULL) {
X      perror("Can't open output file");
X      exit(1);
X    }
X  }
X
X	word[0] = 0;
X	BEGIN(IG);
X	yylex();
X	if (i < valcnt) fprintf(stderr,"\nmenutoc: not enough %%%%s\n");
X	if (j < valcnt2) fprintf(stderr,"\nmenutoc: not enough @@s\n");
X	exit(0);
X}
X
Xchar   *basename(s)
Xchar   *s;
X{
X	char   *p;
X	char   *strrchr();
X
X	if (p = strrchr (s, '/'))
X		return (++p);
X	else
X		return (s);
X}
X
Xappend(c)
Xchar c;
X{
X	if (wordp+1 >= MAXLINE) {
X	    fprintf(stderr,"menutoc: string in menu too long\n");
X	    exit(1);
X	}
X	if (!wordp) wcol = col;
X	word[wordp++] = c;
X	word[wordp] = 0;
X}
X
Xwriteword()
X{
X	if (wordp) {
X		while (word[--wordp] == ' ') ;
X		word[++wordp] = 0;
X		printf("%d,%d,\"%s\",\n", row, wcol, word);
X		wordp = 0;
X		word[wordp] = 0;
X	}
X}
END_OF_FILE
if test 12722 -ne `wc -c <'menutoc.l'`; then
    echo shar: \"'menutoc.l'\" unpacked with wrong size!
fi
# end of 'menutoc.l'
fi
echo shar: End of archive 7 \(of 15\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 15 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0