/***************************************************************
 * vt100 - terminal emulator - initialization
 *
 *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
 *	v2.3 861101 DBW - minor bug fixes
 *	v2.2 861012 DBW - more of the same
 *	v2.1 860915 DBW - new features (see README)
 *	     860901 ACS	- Added Parity and Word Length and support code
 *	     860823 DBW - Integrated and rewrote lots of code
 *	v2.0 860809 DBW - Major rewrite
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 ***************************************************************/

#define MODULE_INIT 1
#include "vt100.h"

char line[256];
static char cmds[] = "V^GRSBLHXEOIT.D";

char *InitDefaults(argc,argv)
int	argc;
char	**argv;
    {
    FILE    *fd;
    char    scr[32],delim,macro[256],c0,*ptr,*ptr2;
    int	    i,j,k;
    long    li;

    if (((argc > 1) && (fd=fopen(argv[1],"r")) != 0) ||
	(fd=fopen("vt100.init","r")) != 0 ||
	(fd=fopen("s:vt100.init","r")) != 0) {
	while (fgets(line,256,fd) != 0) {
	    if ((c0 = line[0]) == '#') continue;
	    if ((c0|' ') == 'e') break;
	    switch (c0|' ') {
		case 'b':
		if ((line[1]|' ') == 'o') {
		    /* bold color */
		    if (sscanf(line,"%s %x",scr,&i) == 2) p_bold = i;
		    break;
		    }
		if ((line[1]|' ') == 'u') {
		    /* buffer size */
		    if (sscanf(line,"%s %d",scr,&i) == 2) p_buffer = i;
		    if (p_buffer < 512) p_buffer = 512;
		    break;
		    }
		if ((line[1]|' ') == 'r') {
		    /* break time */
		    if (sscanf(line,"%s %ld",scr,&li) == 2) p_break = li;
		    break;
		    }
		if ((line[1]|' ') != 'a') break;
		switch(line[2]|' ') {
		    /* baud rate */
		    case 'u':
		    if (sscanf(line,"%s %d",scr,&i) == 2)
			switch (i) {
			    case  300:
			    case 1200:
			    case 2400:
			    case 4800:
			    case 9600:	p_baud = i; break;
			    }
		    break;

		    /* background */
		    case 'c':
		    if (sscanf(line,"%s %x",scr,&i) == 2) p_background = i;
		    break;
		    }
		break;

		/* screen type */
		case 's':
		if (sscanf(line,"%s %s",scr,scr) == 2) {
		    if ((scr[0]|' ') == 'w') p_screen = 0;
		    else		     p_screen = 1;
		    }
		break;

		/* number of lines */
		case 'l':
		if (sscanf(line,"%s %d",scr,&i) == 2) p_lines = i;
		break;

		/* screen depth */
		case 'd':
		if (sscanf(line,"%s %d",scr,&i) == 2) p_depth = i;
		break;

		/* cursor color */
		case 'c':
		if (sscanf(line,"%s %x",scr,&i) == 2) p_cursor = i;
		break;

		/* interlace type */
		case 'i':
		if (sscanf(line,"%s %s",scr,scr) == 2) {
		    if ((scr[1]|' ') == 'n') p_interlace = 1;
		    else		     p_interlace = 0;
		    }
		break;

		case 'f':
		switch (line[1]|' ') {

		    /* foreground color */
		    case 'o':
    		    if (sscanf(line,"%s %x",scr,&i) == 2) p_foreground = i;
		    break;

		    /* function key */
		    default:
		    if (sscanf(&line[1],"%d",&i) != 1) break;
		    if (i < 1 || i > 10) break;
		    delim = 0;
		    for (j=(i==10?3:2); line[j] != 0 &&
			      (line[j] == ' ' || line[j] == '\t'); j++) ;
		    if (line[j] == 0) {
			if (c0 == 'f') p_f[i-1] = NULL;
			else	       p_F[i-1] = NULL;
			break;
			}
		    delim = line[j];
		    k = 0;
		    macro[0] = 0;
		    while (line[++j] != delim) {
			if (line[j] == 0) {
			    if (fgets(line,256,fd) == 0) {
				line[0] = delim;
				line[1] = 0;
				}
			    j = -1;
			    continue;
			    }
			if (line[j] == '^' && line[++j] != '^')
			    macro[k++] = (line[j]|' ') - 0x60;
			else if (line[j] != '\n') macro[k++] = line[j];
			macro[k]   = 0;
			}
		    ptr = malloc(k+1);
		    if (c0 == 'f') p_f[i-1] = ptr;
		    else	   p_F[i-1] = ptr;
		    strcpy(ptr,macro);
		    break;
		    }
		break;

		case 'k':
		/*keyscript*/
		if (sscanf(line,"%s %x",scr,&i) == 2)
		    p_keyscript = i & 0x7F;
		break;

		case 'm':
		if (sscanf(line,"%s %s",scr,scr) == 2) {
		    if ((scr[0]|' ') == 'i')	p_mode = 0;
		    else			p_mode = 1;
		    }
		break;

		case 'p': /*parity*/
		if (sscanf(line,"%s %s",scr,scr) == 2)
		    switch(*scr|' ') {
			case 'n':   p_parity =  0; break;
			case 'm':   p_parity =	1; break;
			case 's':   p_parity =  2; break;
			case 'e':   p_parity =  3; break;
			case 'o':   p_parity =  4; break;
			}
		break;

		case 'v': /*volume*/
		if (sscanf(line,"%s %d",scr,&i) == 2)
		    if (i >= 0) p_volume = i;
		break;

		case 'w':
		/*wrap*/
		if ((line[1]|' ') == 'r') {
		    if (sscanf(line,"%s %s",scr,scr) == 2) {
			if ((scr[1]|' ') == 'n') p_wrap = 1;
			else			 p_wrap = 0;
			}
		    }

		/* workbench or custom colors */
		else if ((line[1]|' ') == 'b' &&
			 sscanf(line,"%s %s",scr,scr) == 2) {
		    if ((scr[0]|' ') == 'n') p_wbcolors = 0;
		    else		     p_wbcolors = 1;
		    }
		break;
		}
	    }
	fclose(fd);
	}
    /* Now set up all the screen info as necessary */
    if (p_interlace == 0) {
	if (p_lines > 24) p_lines = 24;
	MINY = 14;
	NewWindow.Height    = (long)((p_lines*8)+8);
	}
    else {
	if (p_lines > 48) p_lines = 48;
	MINY = 16;
	NewScreen.ViewModes |= LACE;
	NewWindow.Height    = (long)((p_lines*8)+10);
	}
    NewWindow.MinHeight = NewWindow.Height;
    NewWindow.MaxHeight = NewWindow.Height;
    NewWindow.TopEdge   = 0L;
    MAXY = ((p_lines-1)*8) + MINY;
    top  = MINY;
    bot	 = MAXY;
    savx = MINX;
    savy = MINY;
    if (p_screen == 1) {
	if (p_depth > 2) p_depth = 2;
	if (p_depth < 1) p_depth = 1;
	NewScreen.Depth	    = (long)p_depth;
	NewScreen.Height    = (long)((p_lines*8)+16);
	if (p_interlace == 1)
	    NewScreen.TopEdge   = (long)(400 - NewScreen.Height);
	else
	    NewScreen.TopEdge   = (long)(208 - NewScreen.Height);
	}
    else {
	p_depth			= 2L;
	NewWindow.TopEdge	= 0L;
	NewWindow.Screen	= NULL;
	NewWindow.Type		= WBENCHSCREEN;
	}
    /* see if we exit with a startup script */
    if ((c0|' ') == 'e') {
	ptr = &line[0];
	while (*ptr != '\000' && *ptr != ' ' && *ptr != '\t') ptr++;
	if (*ptr == '\000') return(NULL);
	while (*ptr != '\000' && (*ptr == ' ' || *ptr == '\t')) ptr++;
	if (*ptr == '\000') return(NULL);
	ptr2 = ptr;	
	while (*ptr2 != '\000' && *ptr2 != ' ' &&
	       *ptr2 != '\t'   && *ptr2 != '\n') ptr2++;
	*ptr2 = '\000';
	return(ptr);
	}
    else return(NULL);
    }

void InitDevs()
{
USHORT	colors[4];
int	i;
BYTE	*b,*c;

IntuitionBase = (struct IntuitionBase *)
    OpenLibrary("intuition.library", INTUITION_REV);
if( IntuitionBase == NULL )
    cleanup("can't open intuition",1);

GfxBase = (struct GfxBase *)
    OpenLibrary("graphics.library",GRAPHICS_REV);
if( GfxBase == NULL )
    cleanup("can't open graphics library",2);

if (p_screen == 1) {
    if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL)
	cleanup("can't open screen",3);
    NewWindow.Screen = myscreen;
    }

if(( mywindow = (struct Window *)OpenWindow(&NewWindow) ) == NULL)
    cleanup("can't open window",4);

myviewport   = (struct ViewPort *)ViewPortAddress(mywindow);

if (p_screen != 0 && p_wbcolors == 0) {
    colors[0] = p_background;
    colors[1] = p_foreground;
    colors[2] = p_bold;
    colors[3] = p_cursor;
    if (p_depth == 1)
	LoadRGB4(myviewport,(struct ColorMap *)colors,2L);
    else
	LoadRGB4(myviewport,(struct ColorMap *)colors,4L);
    }

Read_Request = (struct IOExtSer *)
    AllocMem((long)sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR);
Read_Request->io_SerFlags = 0L;
Read_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
if(OpenDevice(SERIALNAME,NULL,Read_Request,NULL))
    cleanup("Cant open Read device",5);
rs_in = malloc(p_buffer+1);
Read_Request->io_SerFlags = 0L;
Read_Request->io_Baud	  = p_baud;
Read_Request->io_ReadLen  = 8L;
Read_Request->io_WriteLen = 8L;
Read_Request->io_CtlChar  = 0x11130000L;
Read_Request->io_RBufLen  = p_buffer;
Read_Request->io_BrkTime  = p_break;
Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO(Read_Request);
Read_Request->IOSer.io_Command = CMD_READ;
Read_Request->IOSer.io_Length  = 1;
Read_Request->IOSer.io_Data    = (APTR) &rs_in[0];

Write_Request = (struct IOExtSer *)
    AllocMem((long)sizeof(*Write_Request),MEMF_PUBLIC|MEMF_CLEAR);
b = (BYTE *)Read_Request;
c = (BYTE *)Write_Request;
for (i=0;i<sizeof(struct IOExtSer);i++) *c++ = *b++;
Write_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
Write_Request->IOSer.io_Command = CMD_WRITE;
Write_Request->IOSer.io_Length  = 1;
Write_Request->IOSer.io_Data    = (APTR) &rs_out[0];

Timer_Port = CreatePort("Timer Port",0L);
Script_Timer_Port = CreatePort("Timer Port",0L);

if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0) ||
    OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Script_Timer, 0)) 
	cleanup("can't open timer device",7);

Timer.tr_node.io_Message.mn_ReplyPort = Timer_Port;
Timer.tr_node.io_Command = TR_ADDREQUEST;
Timer.tr_node.io_Flags = 0;
Timer.tr_node.io_Error = 0;

Script_Timer.tr_node.io_Message.mn_ReplyPort = Script_Timer_Port;
Script_Timer.tr_node.io_Command = TR_ADDREQUEST;
Script_Timer.tr_node.io_Flags = 0;
Script_Timer.tr_node.io_Error = 0;

BeepWave   = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR));
if (BeepWave != 0) BeepWave[0] = 100;

Audio_Port = CreatePort("Audio Port",0L);

Audio_Request.ioa_Request.io_Message.mn_ReplyPort   = Audio_Port;
Audio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85;
Audio_Request.ioa_Data		    = Audio_AllocMap;
Audio_Request.ioa_Length	    = (ULONG) sizeof(Audio_AllocMap);

if (OpenDevice(AUDIONAME, NULL, (char *) &Audio_Request, NULL))
	cleanup("can't open audio device",8);

Audio_Request.ioa_Request.io_Command	= CMD_WRITE;
Audio_Request.ioa_Request.io_Flags	= ADIOF_PERVOL;
Audio_Request.ioa_Data		= BeepWave;
Audio_Request.ioa_Length	= BEEPSIZE;
Audio_Request.ioa_Period	= COLORCLOCK / (BEEPSIZE * BEEPFREQ);
Audio_Request.ioa_Volume	= p_volume;
Audio_Request.ioa_Cycles	= 100;
}

/*****************************************************************/
/*    The following function initializes the structure arrays    */
/*   needed to provide the File menu topic.                      */
/*****************************************************************/
void InitFileItems()
    {
    int	    n,nplus1;

/* initialize each menu item and IntuiText with loop */
for( n=0; n<FILEMAX; n++ )
    {
    nplus1 = n + 1;
    FileItem[n].NextItem = &FileItem[nplus1];
    FileItem[n].LeftEdge = 0;
    FileItem[n].TopEdge = 10 * n;
    FileItem[n].Width = 120+40;
    FileItem[n].Height = 10;
    FileItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
    FileItem[n].MutualExclude = 0;
    FileItem[n].ItemFill = (APTR)&FileText[n];
    FileItem[n].SelectFill = NULL;
    if (n >= 2 && n <= 7) {
	FileItem[n].Command  = cmds[n-2];
	FileItem[n].Flags   |= COMMSEQ;
	}
    else FileItem[n].Command = 0;
    FileItem[n].SubItem = NULL;
    FileItem[n].NextSelect = 0;

    FileText[n].FrontPen = 0;
    FileText[n].BackPen = 1;
    FileText[n].DrawMode = JAM2;/* render in fore and background */
    FileText[n].LeftEdge = 0;
    FileText[n].TopEdge = 1;
    FileText[n].ITextFont = NULL;
    FileText[n].NextText = NULL;
    }
FileItem[FILEMAX-1].NextItem = NULL;

/* initialize text for specific menu items */

FileText[0].IText = (UBYTE *)"Ascii  Capture";
FileText[1].IText = (UBYTE *)"Ascii  Send";
FileText[2].IText = (UBYTE *)"Xmodem Receive";
FileText[3].IText = (UBYTE *)"Xmodem Send";
FileText[4].IText = (UBYTE *)"Kermit Get";
FileText[5].IText = (UBYTE *)"Kermit Receive";
FileText[6].IText = (UBYTE *)"Kermit Send";
FileText[7].IText = (UBYTE *)"Kermit BYE";
}

/******************************************************************
/*			Main Comm menu
/*		set up for Baud & Parity submenus
/******************************************************************/
void InitCommItems()
    {
    int	    n,nplus1;

/* initialize each menu item and IntuiText with loop */
for( n=0; n<COMMAX; n++ )
    {
    nplus1 = n + 1;
    CommItem[n].NextItem = &CommItem[nplus1];
    CommItem[n].LeftEdge = 0;
    CommItem[n].TopEdge = 10 * n;
    CommItem[n].Width = 88;
    CommItem[n].Height = 10;
    CommItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP ;
    CommItem[n].MutualExclude = 0;
    CommItem[n].ItemFill = (APTR)&CommText[n];
    CommItem[n].SelectFill = NULL;
    CommItem[n].Command = 0;
    CommItem[n].NextSelect = 0;

    CommText[n].FrontPen = 0;
    CommText[n].BackPen = 1;
    CommText[n].DrawMode = JAM2;    
    CommText[n].LeftEdge = 0;
    CommText[n].TopEdge = 1;
    CommText[n].ITextFont = NULL;
    CommText[n].NextText = NULL;
    }
CommItem[COMMAX-1].NextItem = NULL;

CommText[0].IText = (UBYTE *)"Baud Rate";
CommText[1].IText = (UBYTE *)"Parity   ";
CommText[2].IText = (UBYTE *)"Xfer Mode";
CommItem[0].SubItem = RSItem;
CommItem[1].SubItem = ParItem;
CommItem[2].SubItem = XFItem;

/*****************************************************************/
/*    The following initializes the structure arrays		 */
/*   needed to provide the BaudRate Submenu topic.               */
/*****************************************************************/

for( n=0; n<RSMAX; n++ )
    {
    nplus1 = n + 1;
    RSItem[n].NextItem = &RSItem[nplus1];
    RSItem[n].LeftEdge = 75;
    RSItem[n].TopEdge = 10 * n;
    RSItem[n].Width = 56+40;
    RSItem[n].Height = 10;
    RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
    RSItem[n].MutualExclude = (~(1 << n));
    RSItem[n].ItemFill = (APTR)&RSText[n];
    RSItem[n].SelectFill = NULL;
    if (n >= 1 && n <= 2) {
	RSItem[n].Command    = cmds[n+5];
	RSItem[n].Flags	    |= COMMSEQ;
	}
    else RSItem[n].Command = 0;
    RSItem[n].SubItem = NULL;
    RSItem[n].NextSelect = 0;

    RSText[n].FrontPen = 0;
    RSText[n].BackPen = 1;
    RSText[n].DrawMode = JAM2;     /* render in fore and background */
    RSText[n].LeftEdge = 0;
    RSText[n].TopEdge = 1;
    RSText[n].ITextFont = NULL;
    RSText[n].NextText = NULL;
    }
RSItem[RSMAX-1].NextItem = NULL;

/* select baud item chekced */
switch (p_baud) {
    case 300:	n = 0; break;
    case 1200:	n = 1; break;
    case 2400:	n = 2; break;
    case 4800:	n = 3; break;
    case 9600:	n = 4; break;
    default:	n = 2; p_baud = 2400;
    }
RSItem[n].Flags |= CHECKED;

/* initialize text for specific menu items */
RSText[0].IText = (UBYTE *)"   300";
RSText[1].IText = (UBYTE *)"  1200";
RSText[2].IText = (UBYTE *)"  2400";
RSText[3].IText = (UBYTE *)"  4800";
RSText[4].IText = (UBYTE *)"  9600";

/*****************************************************************/
/*    The following initializes the structure arrays		 */
/*   needed to provide the Parity   Submenu topic.               */
/*****************************************************************/

for( n=0; n<PARMAX; n++ )
    {
    nplus1 = n + 1;
    ParItem[n].NextItem = &ParItem[nplus1];
    ParItem[n].LeftEdge = 75;
    ParItem[n].TopEdge = 10 * n;
    ParItem[n].Width = 56+40;
    ParItem[n].Height = 10;
    ParItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
    ParItem[n].MutualExclude = (~(1 << n));
    ParItem[n].ItemFill = (APTR)&ParText[n];
    ParItem[n].SelectFill = NULL;
    if (n == 0 || n == 3 || n == 4) {
	ParItem[n].Command   = cmds[(n==0)?8:n+6];
	ParItem[n].Flags    |= COMMSEQ;
	}
    else ParItem[n].Command = 0;
    ParItem[n].SubItem = NULL;
    ParItem[n].NextSelect = 0;

    ParText[n].FrontPen = 0;
    ParText[n].BackPen = 1;
    ParText[n].DrawMode = JAM2;/* render in fore and background */
    ParText[n].LeftEdge = 0;
    ParText[n].TopEdge = 1;
    ParText[n].ITextFont = NULL;
    ParText[n].NextText = NULL;
    }
ParItem[PARMAX-1].NextItem = NULL;

/* select parity item chekced */
ParItem[p_parity].Flags |= CHECKED;

/* initialize text for specific menu items */
ParText[0].IText = (UBYTE *)"  None ";
ParText[1].IText = (UBYTE *)"  Mark ";
ParText[2].IText = (UBYTE *)"  Space";
ParText[3].IText = (UBYTE *)"  Even ";
ParText[4].IText = (UBYTE *)"  Odd  ";

/*****************************************************************/
/*    The following initializes the structure arrays		 */
/*    needed to provide the Transfer Mode menu topic.            */
/*****************************************************************/

/* initialize each menu item and IntuiText with loop */
for( n=0; n<XFMAX; n++ )
    {
    nplus1 = n + 1;
    XFItem[n].NextItem = &XFItem[nplus1];
    XFItem[n].LeftEdge = 75;
    XFItem[n].TopEdge = 10 * n;
    XFItem[n].Width = 80+40;
    XFItem[n].Height = 10;
    XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
    XFItem[n].MutualExclude = (~(1 << n));
    XFItem[n].ItemFill = (APTR)&XFText[n];
    XFItem[n].SelectFill = NULL;
    if (n < 2) {
	XFItem[n].Command    = cmds[n+11];
	XFItem[n].Flags	    |= COMMSEQ;
	}
    else XFItem[n].Command = 0;
    XFItem[n].SubItem = NULL;
    XFItem[n].NextSelect = 0;

    XFText[n].FrontPen = 0;
    XFText[n].BackPen = 1;
    XFText[n].DrawMode = JAM2;
    XFText[n].LeftEdge = 0;
    XFText[n].TopEdge = 1;
    XFText[n].ITextFont = NULL;
    XFText[n].NextText = NULL;
    }
XFItem[XFMAX-1].NextItem = NULL;
/* mode checked */
XFItem[p_mode].Flags |= CHECKED;

/* initialize text for specific menu items */
XFText[0].IText = (UBYTE *)"  Image";
XFText[1].IText = (UBYTE *)"  Text ";

} /* end of InitCommItems() */


/*****************************************************************/
/*    The following function initializes the structure arrays    */
/*   needed to provide the Script menu topic.                    */
/*****************************************************************/
void InitScriptItems()
{
int n,nplus1;

/* initialize each menu item and IntuiText with loop */
for( n=0; n<SCRIPTMAX; n++ )
    {
    nplus1 = n + 1;
    ScriptItem[n].NextItem = &ScriptItem[nplus1];
    ScriptItem[n].LeftEdge = 0;
    ScriptItem[n].TopEdge = 10 * n;
    ScriptItem[n].Width = 128;
    ScriptItem[n].Height = 10;
    ScriptItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
    ScriptItem[n].MutualExclude = 0;
    ScriptItem[n].ItemFill = (APTR)&ScriptText[n];
    ScriptItem[n].SelectFill = NULL;
    ScriptItem[n].Command = 0;
    ScriptItem[n].SubItem = NULL;
    ScriptItem[n].NextSelect = 0;

    ScriptText[n].FrontPen = 0;
    ScriptText[n].BackPen = 1;
    ScriptText[n].DrawMode = JAM2;/* render in fore and background */
    ScriptText[n].LeftEdge = 0;
    ScriptText[n].TopEdge = 1;
    ScriptText[n].ITextFont = NULL;
    ScriptText[n].NextText = NULL;
    }
ScriptItem[SCRIPTMAX-1].NextItem = NULL;

/* initialize text for specific menu items */
ScriptText[0].IText = (UBYTE *)"Execute file";
ScriptText[1].IText = (UBYTE *)"Abort Execution";
}

/*****************************************************************/
/*    The following function initializes the structure arrays    */
/*   needed to provide the Util menu topic.                    */
/*****************************************************************/
void InitUtilItems()
    {
    int	    n,nplus1;

/* initialize each menu item and IntuiText with loop */
for( n=0; n<UTILMAX; n++ )
    {
    nplus1 = n + 1;
    UtilItem[n].NextItem = &UtilItem[nplus1];
    UtilItem[n].LeftEdge = 0;
    UtilItem[n].TopEdge = 10 * n;
    UtilItem[n].Width = 88+40;
    UtilItem[n].Height = 10;
    UtilItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
    UtilItem[n].MutualExclude = 0;
    UtilItem[n].ItemFill = (APTR)&UtilText[n];
    UtilItem[n].SelectFill = NULL;
    if (n == 0 || n == 2) {
	UtilItem[n].Command   = cmds[(n==0)?13:14];
	UtilItem[n].Flags    |= COMMSEQ;
	}
    else UtilItem[n].Command = 0;
    UtilItem[n].SubItem = NULL;
    UtilItem[n].NextSelect = 0;

    UtilText[n].FrontPen = 0;
    UtilText[n].BackPen = 1;
    UtilText[n].DrawMode = JAM2;/* render in fore and background */
    UtilText[n].LeftEdge = 0;
    UtilText[n].TopEdge = 1;
    UtilText[n].ITextFont = NULL;
    UtilText[n].NextText = NULL;
    }

/*  until we know how to toggle DTR */
/* UtilItem[1].Flags ^= ITEMENABLED; */

UtilItem[UTILMAX-1].NextItem = NULL;

/* initialize text for specific menu items */
UtilText[0].IText = (UBYTE *)"Send Break";
UtilText[1].IText = (UBYTE *)"Hang Up";
UtilText[2].IText = (UBYTE *)"Change Dir";
}

/****************************************************************/
/*   The following function inits the Menu structure array with */
/*  appropriate values for our simple menu.  Review the manual  */
/*  if you need to know what each value means.                  */
/****************************************************************/
void InitMenu()
{
menu[0].NextMenu = &menu[1];
menu[0].LeftEdge = 5;
menu[0].TopEdge = 0;
menu[0].Width = 40;
menu[0].Height = 10;
menu[0].Flags = MENUENABLED;
menu[0].MenuName = "File";        /* text for menu-bar display */
menu[0].FirstItem = &FileItem[0]; /* pointer to first item in list */

menu[1].NextMenu = &menu[2];
menu[1].LeftEdge = 55;
menu[1].TopEdge = 0;
menu[1].Width = 88;
menu[1].Height = 10;
menu[1].Flags = MENUENABLED;
menu[1].MenuName = "Comm Setup";   /* text for menu-bar display */
menu[1].FirstItem = &CommItem[0];  /* pointer to first item in list */

menu[2].NextMenu = &menu[3];
menu[2].LeftEdge = 153;
menu[2].TopEdge = 0;
menu[2].Width = 56;
menu[2].Height = 10;
menu[2].Flags = MENUENABLED;
menu[2].MenuName = "Script";        /* text for menu-bar display */
menu[2].FirstItem = &ScriptItem[0]; /* pointer to first item in list*/

menu[3].NextMenu = NULL;
menu[3].LeftEdge = 225;
menu[3].TopEdge = 0;
menu[3].Width = 64;
menu[3].Height = 10;
menu[3].Flags = MENUENABLED;
menu[3].MenuName = "Utility";      /* text for menu-bar display */
menu[3].FirstItem = &UtilItem[0];  /* pointer to first item in list*/
}

