[mod.amiga.sources] vt100 emulator v1.1

doc@pucc-j.UUCP (07/22/86)

    Here is a shell archive of the latest vt100 emulator by Dave Wecker.
He has fixed up alot of stuff and added alot of wanted features.  I will
be first in saying "Thanx Dave" for all you've done so far!

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	README
#	Makefile
#	make.scr
#	colors.c
#	init.c
#	kermit.c
#	remote.c
#	vt100.c
#	window.c
#	xmodem.c
#	vt100.h
# This archive created: Tue Jul 22 15:27:49 1986
# By:	Craig Norborg (Purdue University Computing Center)
cat << \SHAR_EOF > README
This archive contains a vt100 emulator with KERMIT and XMODEM file transfer
protocols by Dave Wecker (Based on AmigaTerm). 

Releases:
---------
	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
	v1.0 860712 DBW	- First version released

Release Notes:
--------------
v1.1 860720 DBW	- Added command line switches (all optional):

		   1> vt100 [-s baud] [-f hex] [-b hex] [-c typ] [-t] [-i]

			-s baud	= Set speed (baud rate).
			-f hex	= Set foreground color (rgb hex number).
			-b hex	= Set background color (rgb hex number).
			-c typ	= Create window according to "typ":
					0 = use WORKBENCH screen
					1 = CUSTOM interlaced (1/2  screen)
					2 = CUSTOM interlaced (full screen)
			-t	= Text mode for KERMIT (LF <--> CRLF)
			-i	= Image mode for KERMIT (no translation)

		  Defaults are:

		   1> vt100 -s 2400 -f a00 -b 200 -c 2 -i

		- Added environment variables for all defaults. This allows
		  you to setup a custom environment by defining any of the
		  following:

			vt100_speed	- default baud rate
			vt100_fg	- default foreground color
			vt100_bg	- default background color
			vt100_cust	- create window of specified type
			vt100_text	- do KERMIT transfers in CRLF mode
			vt100_image	- do KERMIT transfers in image mode

		  A sample set of lines (in startup-sequence) could be:

			set vt100_speed=1200 vt100_cust=0
			set vt100_fg=666 vt100_bg=005 vt100_image=1

		  Which would give you a terminal emulator running at 1200
		  baud in the workbench screen with a white foreground and
		  a blue background (with KERMIT transfers in image mode)
		  any time you ran vt100. NOTE: command line switches
		  override any defaults set by environment variables.

		- Menu item added to allow full control over colors while
		  running the emulator (using a palette editor).

		- Using borderless window to allow full 80 columns (without
		  having to go to a smaller font).

		- Erased part of the title bar so that a full 24 lines will
		  fit on a non interlaced workbench window (this is a
		  temporary kludge for now).

		- Got rid of the un-necessary resize gadget.

		- Made the custom screen half height and moved the window
		  accordingly (when cust = 1).


v1.0 860712 DBW	- Initial (early) release.

Known problems:
---------------
		- Alot of reports that KERMIT is sick. This will be the
		  next thing fixed.

		- Several people said that everything but "larn" works.
		  Since I don't have "larn", what I really need to be sent
		  is the escape sequence(s) that do not work correctly.
		  I will be happy to fix the problem if it is specified
		  with a little more detail.

Installation:
-------------
The files in this archive may be extracted by the bourne shell (/bin/sh) or
the shar program using the "unshar switch (-u)", contact me if you need a
copy of this version of shar.

Files:
------
	README		- this file

	makefile	- a script that can be handed to "execute" to create
			  the emulator (switches are for MANX AZTEC-C).

	vt100.h		- include file used by all other modules

	window.c	- manager for window and keyboard

	vt100.c		- main module, handles menus

	remote.c	- handle remote characters (vt100 emulation)

	kermit.c	- kermit protocol (to transfer text files on VMS
			  select the CRLF option on the transfer mode menu,
			  otherwise use image mode).

	init.c		- startup code

	xmodem.c	- xmodem protocol that understands AMIGA binary and
			  text file formats (automatically).

	colors.c	- palette editor for foreground and background colors

Contact:
--------
Please send bugs/comments/suggestions to:

	Dave Wecker at	ENET:	COOKIE::WECKER
			ARPA:	wecker%cookie.dec.com@decwrl.dec.com
			USENET:	decvax!decwrl!cookie.dec.com!wecker

SHAR_EOF
cat << \SHAR_EOF > Makefile
# *** Note ***  Compilation will go faster if you have the libraries in
# RamDisk.  This makefile lets the user decide if they wish to have it there
# or not
#
SRC = vt100.c init.c window.c xmodem.c remote.c kermit.c colors.c 
OBJ = vt100.o init.o window.o xmodem.o remote.o kermit.o colors.o
HDR = vt100.h

all: vt100

vt100: $(OBJ)
	ln -v -w -o vt100 $(OBJ) -lc

vt100.syms: vt100.h
	echo

vt100.o: vt100.c vt100.h
	cc +Hvt100.syms vt100.c

init.o: init.c vt100.syms vt100.h
	cc +Ivt100.syms init.c

window.o: window.c vt100.syms vt100.h
	cc +Ivt100.syms window.c

xmodem.o: xmodem.c vt100.syms vt100.h
	cc +Ivt100.syms xmodem.c

remote.o: remote.c vt100.syms vt100.h
	cc +Ivt100.syms remote.c

kermit.o: kermit.c vt100.syms vt100.h
	cc +Ivt100.syms kermit.c

colors.o: colors.c vt100.syms vt100.h
	cc +Ivt100.syms colors.c
SHAR_EOF
cat << \SHAR_EOF > make.scr
. Script to build vt100 terminal emulator
. 	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
. 	v1.0 860712 DBW	- First version released
. ----------
. Type "execute makefile" to build the emulator
. ----------
echo "cc +Hvt100.syms vt100.c"
cc +Hvt100.syms vt100.c
. ----------
echo "cc +Ivt100.syms init.c"
cc +Ivt100.syms init.c
. ----------
echo "cc +Ivt100.syms window.c"
cc +Ivt100.syms window.c
. ----------
echo "cc +Ivt100.syms xmodem.c"
cc +Ivt100.syms xmodem.c
. ----------
echo "cc +Ivt100.syms remote.c"
cc +Ivt100.syms remote.c
. ----------
echo "cc +Ivt100.syms kermit.c"
cc +Ivt100.syms kermit.c
. ----------
echo "cc +Ivt100.syms colors.c"
cc +Ivt100.syms colors.c
. ----------
if not exists ram:c.lib
  echo "Copying c.lib to ram"
  copy df0:lib/c.lib ram:
  set CLIB=ram:
  endif
echo "Linking vt100"
ln -v -w -o vt100 vt100.o init.o window.o xmodem.o remote.o kermit.o colors.o -lc 
. ----------
echo "Done!"
SHAR_EOF
cat << \SHAR_EOF > colors.c
/***********************************************************************
 *  vt100 terinal emulator - COLOR map setting program
 *	(code from MicroSmith's PALETTE tool)
 *
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 ***********************************************************************/

#define MODULE_COLORS 1
#include "vt100.h"

#define NL 0

#define PLX 165      /* Palette Window Size  */
#define PLY 84
 
#define PGAD 0             /* You can offset the gadgets here  */
#define PGHI   PGAD+CTSIZ  /* Offset frm color selectors       */
 
struct IntuiText rtxt = {1,0,JAM2,-9,2,NL,(UBYTE *)"R",NL};
struct IntuiText gtxt = {1,0,JAM2,-9,2,NL,(UBYTE *)"G",NL};
struct IntuiText btxt = {1,0,JAM2,-9,2,NL,(UBYTE *)"B",NL};
 
struct Image    r_img, g_img, b_img;
struct PropInfo r_prop,g_prop,b_prop;
 
struct Gadget blue_gad = {
   NL, 17,67, 90,11, GADGHCOMP, GADGIMMEDIATE | RELVERIFY,
   PROPGADGET,(APTR)&b_img, NL,
   &btxt, NL,(APTR)&b_prop, PGHI+3, NL };
 
struct Gadget green_gad = {
   &blue_gad, 17,51, 90,11, GADGHCOMP, GADGIMMEDIATE | RELVERIFY,
   PROPGADGET,(APTR)&g_img, NL,
   &gtxt, NL,(APTR)&g_prop, PGHI+4, NL };
 
struct Gadget red_gad = {
   &green_gad, 17,35, 90,11, GADGHCOMP, GADGIMMEDIATE | RELVERIFY,
   PROPGADGET,(APTR)&r_img, NL,
   &rtxt, NL,(APTR)&r_prop, PGHI+5, NL };
 
struct IntuiText oktxt = {1,0,JAM2,8,2,NL,(UBYTE *)" OK ",NL};
struct IntuiText cntxt = {1,0,JAM2,0,2,NL,(UBYTE *)"Cancel",NL};
struct IntuiText retxt = {1,0,JAM2,4,2,NL,(UBYTE *)"Reset",NL};
 
char frog[] = "hex";
struct IntuiText hxtxt = {1,0,JAM2,136,19,NL,(UBYTE *)frog,NL};
 
struct Gadget re_gad = {
   &red_gad, 110,67, 54,11, GADGHCOMP, RELVERIFY,
   BOOLGADGET, NL, NL,
   &retxt, NL,NL, PGHI+2, NL };
struct Gadget cn_gad = {
   &re_gad, 110,51, 54,11, GADGHCOMP, RELVERIFY,
   BOOLGADGET, NL, NL,
   &cntxt, NL,NL, PGHI+1, NL };
struct Gadget ok_gad = {
   &cn_gad, 110,35, 54,11, GADGHCOMP, RELVERIFY,
   BOOLGADGET, NL, NL,
   &oktxt, NL,NL, PGHI, NL };
 
struct Image m3C[CTSIZ] = {
   {0,0,16,16,1, NL ,0,0,NL },   /* Colors   */
   {0,0,16,16,1, NL ,0,1,NL } };
 
struct Gadget palg[CTSIZ] = {
   { &palg[1], 3, 3,  16,16, GADGHBOX | GADGIMAGE, RELVERIFY,
      BOOLGADGET,  (APTR)&m3C[0], NL,NL,NL,NL, PGAD+0, NL},
   { &ok_gad, 19,3, 16,16, GADGHBOX | GADGIMAGE, RELVERIFY,
      BOOLGADGET,  (APTR)&m3C[1], NL,NL,NL,NL, PGAD+1, NL} };
 
/* Used to open a Window   */
struct NewWindow NewCmod = {
   40,30, PLX,PLY, 0,1,
   MOUSEBUTTONS | MOUSEMOVE | MENUVERIFY | MENUPICK | GADGETUP |
    GADGETDOWN | CLOSEWINDOW | ACTIVEWINDOW,
   ACTIVATE | SMART_REFRESH,
   &palg[0],NL, NL,    /* FirstGadget, CheckMark, Title  */
   NL,NL,              /* MUST SET SCREEN AFTER OPENSCREEN!!! */
   PLX,PLY,PLX,PLY, CUSTOMSCREEN }; /* MinW, MinH, MaxW, MaxH */
 
/********************************************************************
* palette(window)
*	This is the meat. This routine opens the palette window and
*	retains control until the user selects the OK or CANCEL gadget.
*	The calling argment is a window pointer.  That window
*	is expected to have opened an IDCMP port, which palette uses.
********************************************************************/
palette(calling_window)
struct Window *calling_window;
    {
    struct Window *cW;      /* Palette window handle   */
 
    register struct IntuiMessage *imsg;
    register struct Gadget *igad;
 
    register int class,cursel;
    BOOL keepon,munge;
 
    USHORT backup[CTSIZ];         /* This table restores calling colors... */
 
    static char hxtab[16] = { '0','1','2','3','4','5','6','7','8',
	'9','a','b','c','d','e','f' };

    for ( cursel=CTSIZ-1; cursel >= 0; cursel--)
	backup[cursel] = mycolortable[cursel];
    cursel = 0;

    r_prop.Flags = g_prop.Flags = b_prop.Flags = FREEHORIZ | AUTOKNOB;
    r_prop.HorizBody = g_prop.HorizBody = b_prop.HorizBody = 0x1000;
 
    /* Get screen from calling window   */
    NewCmod.Screen = calling_window->WScreen;  /* NEED TO SET SCREEN!!! */
    if ( ! (cW = (struct Window *)OpenWindow(&NewCmod)) ) {
	return(FALSE); /* Oops...  */
	}
 
    for ( munge = keepon = TRUE; keepon; ) {
 
	if ( munge ) {

	    /* RJ will proably cringe if he see's this, but it is proably */
	    /* safe to modify the HorizPot values this way, UNLESS the    */
	    /* gadgets were being fiddled with when you do it. Here that  */
	    /* is quite unlikely, since another gadget was juthat  */
	    /* is quite unlikely, since another gadget was just activated */
	    /* to cause the munge flag to be set...                       */
 
	    r_prop.HorizPot = (mycolortable[cursel] & 0xf00) << 4;
	    g_prop.HorizPot = (mycolortable[cursel] & 0x0f0) << 8;
	    b_prop.HorizPot = mycolortable[cursel] << 12;
	    RefreshGadgets(&red_gad,cW,NL);
	    munge = FALSE;
	    hxtxt.FrontPen = cursel ^ 15;
	    hxtxt.BackPen  = cursel;
	    }
 
	while ( ! (imsg=(struct IntuiMessage *)GetMsg(cW->UserPort)) ) {
	    class = mycolortable[cursel] = ((r_prop.HorizPot >> 4) & 0xf00) +
		((g_prop.HorizPot >> 8) & 0xf0) + (b_prop.HorizPot >>12);
	    LoadRGB4(myviewport,mycolortable,CTSIZ);
 
	    frog[0] = hxtab[class >> 8];
	    frog[1] = hxtab[ (class >> 4) & 0x0f];
	    frog[2] = hxtab[class & 0x0f];
	    PrintIText(cW->RPort,&hxtxt,0,0);
 
	    /* Proably, should do a WaitPort(cW->UserPort); */
	    /* I didn't, so the color updates faster.       */
	    /* In a multitasking environment, the system is */
	    /* being gronked...                             */
	    }
 
	igad =(struct Gadget *) imsg->IAddress;
	if ( (class = imsg->Class) == MENUVERIFY ) {
	    imsg->Code = MENUCANCEL;      /* Don't Let Em Out! */
	    DisplayBeep(NL);
	    }
	ReplyMsg(imsg);
 
	switch ( class ) {
	    case GADGETUP:
	    case GADGETDOWN:
            if ((igad->GadgetID >= PGAD)&&(igad->GadgetID < PGAD+CTSIZ)) {
		cursel = igad->GadgetID - PGAD;
		munge = TRUE;
		}
            else switch ( igad->GadgetID ) {
		case PGHI+1:      /* Cancel   */
                for ( class =0 ; class<CTSIZ; class++)
		    mycolortable[class] = backup[class];
		LoadRGB4(myviewport,mycolortable,CTSIZ);

		case PGHI:        /* OK */
		keepon = FALSE;
		break;

                case PGHI+2:      /* Reset */
		for (class = 0; class < CTSIZ; class++)
		    mycolortable[class] = default_color[class];
                LoadRGB4(myviewport,mycolortable,CTSIZ);
                munge = TRUE;
                break;
		}
	    }
	}
 
    cW->UserPort = NL;
    CloseWindow(cW);
    return(TRUE);
    }

SHAR_EOF
cat << \SHAR_EOF > init.c
/***************************************************************
 * vt100 - terminal emulator - initialization
 *
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 ***************************************************************/

#define MODULE_INIT 1
#include "vt100.h"

#define BADCH	((int)'?')
#define EMSG	""
#define tell(s)	{fputs(*nargv,stderr);fputs((s),stderr); \
		fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);}
#define	USAGE "Usage: vt100 [-s baudrate] [-f hexcolor] [-b hexcolor] [-c type] [-t] [-i]\n"
#define	OPTSTRING "s:f:b:c:ti"

extern char *index(),*getenv();

int	optind = 1,		/* index into parent argv vector */
	optopt;			/* character checked for validity */
char	*optarg;		/* argument associated with option */

/*
 * get option letter from argument vector
 */
int getopt(nargc, nargv, ostr)
int nargc;
char **nargv, *ostr;
    {
    register char *oli;		/* option letter list index */
    static char	*place = EMSG;	/* option letter processing */

    if (!*place) {			/* update scanning pointer */
	if (optind >= nargc || 
	    *(place = nargv[optind]) != '-' || !*++place) return(EOF);
	if (*place == '-') {	/* found "--" */
		++optind;
		return EOF;
	    }
	}				/* option letter okay? */
    if ((optopt=(int)*place++)==(int)':' || !(oli=index(ostr,optopt))) {
	if (!*place) ++optind;
	tell(": illegal option -- ");
	}
    if (*++oli != ':') {		/* don't need argument */
	optarg = NULL;
	if (!*place) ++optind;
	}
    else {				/* need an argument */
	if (*place) optarg = place;	/* no white space */
	else if (nargc <= ++optind) {	/* no arg */
	    place = EMSG;
	    tell(": option requires an argument -- ");
	    } 
	else {
	    optarg = nargv[optind];	/* white space */
	    }
	place = EMSG;
	++optind;
	}
    return optopt;			/* dump back option letter */
    }

InitDefaults(argc,argv)
int	argc;
char	**argv;
    {
    short   errflg = 0;	
    char *s,C;

    /* first get any environment variables */
    if ((s = getenv("vt100_speed")) != NULL) 
	if (sscanf(s,"%d",&speed) != 1)
	    speed = 2400;
    if ((s = getenv("vt100_fg")) != NULL)
	if (sscanf(s,"%x",&default_color[1]) != 1)
	    default_color[1] = 0xA00;
    if ((s = getenv("vt100_bg")) != NULL)
	if (sscanf(s,"%x",&default_color[0]) != 1)
	    default_color[0] = 0x200;
    if ((s = getenv("vt100_cust")) != NULL)
	if (sscanf(s,"%d",&cust) != 1)
	    cust = 2;
    if (getenv("vt100_text")	!= NULL) imagemode = 0;
    if (getenv("vt100_image")	!= NULL) imagemode = 1;
   
    /* now check any command line switches */
    while(EOF != (C = getopt(argc, argv, OPTSTRING)) &&
	  errflg == 0) {
	switch(C) {
	    case 's':
	    if (sscanf(optarg,"%d",&speed) != 1) ++errflg;
	    break;

	    case 'f':
	    if (sscanf(optarg,"%x",&default_color[1]) != 1) ++errflg;
	    break;

	    case 'b':
	    if (sscanf(optarg,"%x",&default_color[0]) != 1) ++errflg;
	    break;

	    case 'c':
	    if (sscanf(optarg,"%d",&cust) != 1) ++errflg;
	    break;

	    case 't':
	    imagemode = 0;
	    break;

	    case 'i':
	    imagemode = 1;
	    break;

	    default:
	    ++errflg;
	    break;
	    }
	}
    if (errflg != 0) {
	puts(USAGE);
	exit(TRUE);
	}
    }

InitDevs()
{
int i;

IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", INTUITION_REV);
if( IntuitionBase == NULL )
   {
   puts("can't open intuition\n");
   exit(TRUE);
   }

GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",GRAPHICS_REV);
if( GfxBase == NULL )
   {
   puts("can't open graphics library\n");
   exit(TRUE);
   }

if (cust == 0) {
    NewWindow.TopEdge	= 0L;
    NewWindow.Screen	= NULL;
    NewWindow.Type	= WBENCHSCREEN;
    }
else {
    if (cust == 2) {
	NewScreen.TopEdge   = 0L;
	NewScreen.Height    = 400L;
	}
    if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL) {
	puts("can't open screen!!\n");
	exit(TRUE);
	}
    NewWindow.Screen = myscreen;
    }

if(( mywindow = (struct Window *)OpenWindow(&NewWindow) ) == NULL)
   {
   puts("cant open window\n");
   if (cust != 0) CloseScreen( myscreen );
   exit(TRUE);
   }

myviewport   = (struct ViewPort *)ViewPortAddress(mywindow);
mycolormap   = (struct ColorMap *)GetColorMap(CTSIZ);
mycolortable = (USHORT *)mycolormap->ColorTable;
Prefs	     = (struct Preferences *)
    AllocMem((long)sizeof(*Prefs),MEMF_PUBLIC|MEMF_CLEAR);
if (!GetPrefs(Prefs,(long)sizeof(*Prefs))) {
    orig_color[0] = Prefs->color0;
    orig_color[1] = Prefs->color1;
    }
FreeMem(Prefs,(long)sizeof(*Prefs));
for (i = 0; i < CTSIZ; i++) mycolortable[i] = default_color[i];
LoadRGB4(myviewport,mycolortable,CTSIZ);

Read_Request = (struct IOExtSer *)
    AllocMem((long)sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR);
Read_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
Read_Request->IOSer.io_Message.mn_ReplyPort = CreatePort("Read_RS",0);
if(OpenDevice(SERIALNAME,NULL,Read_Request,NULL))
   {
   puts("Cant open Read device\n");
   FreeColorMap( mycolormap );
   CloseWindow( mywindow );
   if (cust != 0) CloseScreen( myscreen );
   DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
   FreeMem(Read_Request,(long)sizeof(*Read_Request));
   exit(TRUE);
   }
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);
Write_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
Write_Request->IOSer.io_Message.mn_ReplyPort = CreatePort("Write_RS",0);
if(OpenDevice(SERIALNAME,NULL,Write_Request,NULL))
   {
   puts("Cant open Write device\n");
   FreeColorMap( mycolormap );
   CloseWindow( mywindow );
   if (cust != 0) CloseScreen( myscreen );
   DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
   FreeMem(Write_Request,(long)sizeof(*Write_Request));
   DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
   FreeMem(Read_Request,(long)sizeof(*Read_Request));
   exit(TRUE);
   }
Write_Request->IOSer.io_Command = CMD_WRITE;
Write_Request->IOSer.io_Length = 1;
Write_Request->IOSer.io_Data = (APTR) &rs_out[0];

Read_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
Read_Request->io_Baud = speed;
Read_Request->io_ReadLen = 8;
Read_Request->io_WriteLen = 8;
Read_Request->io_CtlChar = 1L;
Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO(Read_Request);
Read_Request->IOSer.io_Command = CMD_READ;
}

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

/* initialize each menu item and IntuiText with loop */
for( n=0; n<FILEMAX; n++ )
   {
   FileItem[n].NextItem = &FileItem[n+1];
   FileItem[n].LeftEdge = 0;
   FileItem[n].TopEdge = 11 * n;
   FileItem[n].Width = 135;
   FileItem[n].Height = 11;
   FileItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX;
   FileItem[n].MutualExclude = 0;
   FileItem[n].ItemFill = (APTR)&FileText[n];
   FileItem[n].SelectFill = NULL;
   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 Receive";
FileText[5].IText = (UBYTE *)"Kermit Send";
return( 0 );
}

/*****************************************************************/
/*    The following function initializes the structure arrays    */
/*   needed to provide the BaudRate menu topic.                  */
/*****************************************************************/
InitRSItems()
{
short n;

/* initialize each menu item and IntuiText with loop */
for( n=0; n<RSMAX; n++ )
   {
   RSItem[n].NextItem = &RSItem[n+1];
   RSItem[n].LeftEdge = 0;
   RSItem[n].TopEdge = 11 * n;
   RSItem[n].Width = 85;
   RSItem[n].Height = 11;
   RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT;
   RSItem[n].MutualExclude = (~(1 << n));
   RSItem[n].ItemFill = (APTR)&RSText[n];
   RSItem[n].SelectFill = NULL;
   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 (speed) {
    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;
    }
RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT | 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";

return( 0 );
}

/*****************************************************************/
/*    The following function initializes the structure arrays    */
/*    needed to provide the Transfer Mode menu topic.            */
/*****************************************************************/
InitXFItems()
{
short n;

/* initialize each menu item and IntuiText with loop */
for( n=0; n<XFMAX; n++ )
   {
   XFItem[n].NextItem = &XFItem[n+1];
   XFItem[n].LeftEdge = 0;
   XFItem[n].TopEdge = 11 * n;
   XFItem[n].Width = 85;
   XFItem[n].Height = 11;
   XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT;
   XFItem[n].MutualExclude = (~(1 << n));
   XFItem[n].ItemFill = (APTR)&XFText[n];
   XFItem[n].SelectFill = NULL;
   XFItem[n].Command = 0;
   XFItem[n].SubItem = NULL;
   XFItem[n].NextSelect = 0;

   XFText[n].FrontPen = 0;
   XFText[n].BackPen = 1;
   XFText[n].DrawMode = JAM2;     /* render in fore and background */
   XFText[n].LeftEdge = 0;
   XFText[n].TopEdge = 1;
   XFText[n].ITextFont = NULL;
   XFText[n].NextText = NULL;
   }
XFItem[XFMAX-1].NextItem = NULL;
/* IMAGE mode checked */
XFItem[1].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT | CHECKED;
imagemode = 1;

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

return( 0 );
}

/*****************************************************************/
/*    The following function initializes the structure arrays    */
/*    needed to provide the Color menu topic.			 */
/*****************************************************************/
InitCMItems()
{
short n;

/* initialize each menu item and IntuiText with loop */
for( n=0; n<CMMAX; n++ )
   {
   CMItem[n].NextItem = &CMItem[n+1];
   CMItem[n].LeftEdge = 0;
   CMItem[n].TopEdge = 11 * n;
   CMItem[n].Width = 85;
   CMItem[n].Height = 11;
   CMItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX;
   CMItem[n].MutualExclude = 0;
   CMItem[n].ItemFill = (APTR)&CMText[n];
   CMItem[n].SelectFill = NULL;
   CMItem[n].Command = 0;
   CMItem[n].SubItem = NULL;
   CMItem[n].NextSelect = 0;

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

/* initialize text for specific menu items */
CMText[0].IText = (UBYTE *)"Colors";
CMText[1].IText = (UBYTE *)"Reset";

return( 0 );
}

/**********************************************************************/
/*   The following function initializes the Menu structure array with */
/*  appropriate values for our simple menu strip.  Review the manual  */
/*  if you need to know what each value means.                        */
/**********************************************************************/
InitMenu()
{
menu[0].NextMenu = &menu[1];
menu[0].LeftEdge = 5;
menu[0].TopEdge = 0;
menu[0].Width = 50;
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 = 65;
menu[1].TopEdge = 0;
menu[1].Width = 85;
menu[1].Height = 10;
menu[1].Flags = MENUENABLED;
menu[1].MenuName = "BaudRate";        /* text for menu-bar display */
menu[1].FirstItem = &RSItem[0];    /* pointer to first item in list */

menu[2].NextMenu = &menu[3];
menu[2].LeftEdge = 160;
menu[2].TopEdge = 0;
menu[2].Width = 85;
menu[2].Height = 10;
menu[2].Flags = MENUENABLED;
menu[2].MenuName = "Xfer Mode";        /* text for menu-bar display */
menu[2].FirstItem = &XFItem[0];    /* pointer to first item in list */

menu[3].NextMenu = NULL;
menu[3].LeftEdge = 260;
menu[3].TopEdge = 0;
menu[3].Width = 110;
menu[3].Height = 10;
menu[3].Flags = MENUENABLED;
menu[3].MenuName = "Change Colors";    /* text for menu-bar display */
menu[3].FirstItem = &CMItem[0];    /* pointer to first item in list */

return( 0 );
}

SHAR_EOF
cat << \SHAR_EOF > kermit.c
/*************************************************************
 * vt100 terminal emulator - KERMIT protocol support
 *
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 *************************************************************/

#define MODULE_KERMIT 1
#include "vt100.h"

#define MAXPACKSIZ 94       /* Maximum msgpkt size */
#define SOH         1       /* Start of header */
#define CR         13       /* ASCII Carriage Return */
#define LF         10       /* ASCII line feed */
#define SP         32       /* ASCII space */
#define DEL       127       /* Delete (rubout) */

#define MAXTRY    10       /* Times to retry a msgpkt */
#define MYQUOTE  '#'       /* Quote character I will use */
#define MYRPTQ   '~'       /* Repeat quote character */
#define MYPAD      0       /* Number of padding characters I will need */
#define MYPCHAR    0       /* Padding character I need (NULL) */
#define MYEOL    '\n'      /* End-Of-Line character I need */
#define MYTIME    10       /* Seconds after which I should be timed out */
#define MAXTIM    60       /* Maximum timeout interval */
#define MINTIM     2       /* Minumum timeout interval */


#define tochar(ch)  ((ch) + ' ')
#define unchar(ch)  ((ch) - ' ')
#define ctl(ch)     ((ch) ^ 64 )

/* Global Variables */

short
   size,      /* Size of present data */
   osize,     /* Size of last data entry */
   rpsiz,     /* Maximum receive msgpkt size */
   spsiz,     /* Maximum send msgpkt size */
   timint,    /* Time interval to wait */
   pad,       /* How much padding to send */
   n,         /* Packet number */
   numtry,    /* Times this msgpkt retried */
   oldtry,    /* Times previous msgpkt retried */
   rptflg,    /* are we doing repeat quoting */
   first,     /* is this the first time in a file */
   rpt;       /* current repeat count */

char
   next,      /* what is the next character */
   t,         /* current character */
   state,     /* Present state of the automaton */
   padchar,   /* Padding character to send */
   eol,       /* End-Of-Line character to send */
   quote,     /* Quote character in incoming data */
   rptq,      /* Quote character for repeats */
   ackpkt[MAXPACKSIZ+10], /* ACK/NAK packet buffer */
   msgpkt[MAXPACKSIZ+10], /* Message Packet buffer */
   filnam[40];            /* remote file name */

FILE *fp;     /* file for send/receive */

doksend(file)
char *file;
   {
   short retval;

   if ((fp = fopen(file,"r")) == NULL) {
      emits("Cannot open send file\n");
      return FALSE;
      }
   emits("Remote file name [local name]: ");
   filename(filnam);
   if (filnam[0] == 0) strcpy(filnam,file);
   timeout = FALSE;
   emits("\nType <ESC> to abort transfer\n");
   retval  = sendsw();
   emits("\n");
   fclose(fp);
   return(retval);
   }

dokreceive(file)
char *file;
   {
   short retval;

   if ((fp = fopen(file,"w")) == NULL) {
      emits("Cannot open file\n");
      return FALSE;
      }
   emits("Remote file name [local name]: ");
   filename(filnam);
   if (filnam[0] == 0) strcpy(filnam,file);
   timeout = FALSE;
   emits("\nType <esc> to abort transfer\n");
   retval  = recsw();
   emits("\n");
   fclose(fp);
   return(retval);
   }

sendsw()
   {
   char sinit(), sfile(), sdata(), seof(), sbreak();

   state = 'S';
   n = 0;
   numtry = 0;
   while(TRUE) {
      switch(state) {
         case 'S':   state = sinit();  break;
         case 'F':   state = sfile();  break;
         case 'D':   state = sdata();  break;
         case 'Z':   state = seof();   break;
         case 'B':   state = sbreak(); break;
         case 'C':   return(TRUE);
         case 'A':   return(FALSE);
         default:    return(FALSE);
         }
      }
   }

char sinit()
   {
   int num, len;

   if (numtry++ > MAXTRY) return('A');
   spar(msgpkt);

   spack('S',n,9,msgpkt);
   switch(rpack(&len,&num,ackpkt)) {
      case 'N':  return(state);
      case 'Y':  if (n != num) return(state);
                 rpar(ackpkt);
                 if (eol == 0) eol = '\n';
                 if (quote == 0) quote = '#';
                 numtry = 0;
                 n = (n+1)%64;
                 return('F');
      case 'E':  return('A');
      case FALSE:return(state);
      default:   return('A');
      }
    }

char sfile()
   {
   int num, len;

   if (numtry++ > MAXTRY) return('A');

   spack('F',n,strlen(filnam),filnam);
   switch(rpack(&len,&num,ackpkt)) {
      case 'N':
         num = (--num<0 ? 63:num);
         if (n != num) return(state);
      case 'Y':
         if (n != num) return(state);
         numtry = 0;
         n = (n+1)%64;
         first = 1;
         size = getpkt();
         return('D');
      case 'E':
         return('A');
      case FALSE: return(state);
      default:    return('A');
      }
   }

char sdata()
   {
   int num, len;

   if (numtry++ > MAXTRY) return('A');

   spack('D',n,size,msgpkt);
   switch(rpack(&len,&num,ackpkt)) {
      case 'N':
         num = (--num<0 ? 63:num);
         if (n != num) return(state);
      case 'Y':
         if (n != num) return(state);
         numtry = 0;
         n = (n+1)%64;
         if ((size = getpkt()) == 0) return('Z');
         return('D');
      case 'E':
         return('A');
      case FALSE: return(state);
      default:    return('A');
      }
   }

char seof()
   {
   int num, len;

   if (numtry++ > MAXTRY) return('A');

   spack('Z',n,0,msgpkt);
   switch(rpack(&len,&num,ackpkt)) {
      case 'N':
         num = (--num<0 ? 63:num);
         if (n != num) return(state);
      case 'Y':
         if (n != num) return(state);
         numtry = 0;
         n = (n+1)%64;
         return('B');
      case 'E':
         return('A');
      case FALSE: return(state);
      default:    return('A');
      }
   }

char sbreak()
   {
   int num, len;
   if (numtry++ > MAXTRY) return('A');

   spack('B',n,0,msgpkt);
   switch (rpack(&len,&num,ackpkt)) {
      case 'N':
         num = (--num<0 ? 63:num);
         if (n != num) return(state);
      case 'Y':
         if (n != num) return(state);
         numtry = 0;
         n = (n+1)%64;
         return('C');
      case 'E':
         return('A');
      case FALSE: return(state);
      default:    return ('A');
      }
   }

recsw()
   {
   char rinit(), rfile(), rdata();

   state = 'R';
   n = 0;
   numtry = 0;

   while(TRUE) {
      switch(state) {
         case 'R':   state = rinit(); break;
         case 'F':   state = rfile(); break;
         case 'D':   state = rdata(); break;
         case 'C':   return(TRUE);
         case 'A':   return(FALSE);
         }
      }
   }

char rinit()
   {
   int len, num;
   if (numtry++ > MAXTRY) return('A');

   spack('R',n,strlen(filnam),filnam);
   switch(rpack(&len,&num,msgpkt)) {
      case 'S':
         rpar(msgpkt);
         spar(msgpkt);
         spack('Y',n,9,msgpkt);
         oldtry = numtry;
         numtry = 0;
         n = (n+1)%64;
         return('F');
      case 'E':
         return('A');
      case FALSE:
         spack('N',n,0,0);
         return(state);
      default:
         return('A');
      }
   }

char rfile()
   {
   int num, len;
   if (numtry++ > MAXTRY) return('A');

   switch(rpack(&len,&num,msgpkt)) {
      case 'S':
         if (oldtry++ > MAXTRY) return('A');
         if (num == ((n==0) ? 63:n-1)) {
            spar(msgpkt);
            spack('Y',num,9,msgpkt);
            numtry = 0;
            return(state);
            }
         else return('A');
      case 'Z':
         if (oldtry++ > MAXTRY) return('A');
         if (num == ((n==0) ? 63:n-1)) {
            spack('Y',num,0,0);
            numtry = 0;
            return(state);
            }
         else return('A');
      case 'F':
         if (num != n) return('A');
         spack('Y',n,0,0);
         oldtry = numtry;
         numtry = 0;
         n = (n+1)%64;
         return('D');
      case 'B':
         if (num != n) return ('A');
         spack('Y',n,0,0);
         return('C');
      case 'E':
         return('A');
      case FALSE:
         spack('N',n,0,0);
         return(state);
      default:
         return ('A');
      }
   }

char rdata()
   {
   int num, len;
   if (numtry++ > MAXTRY) return('A');

   switch(rpack(&len,&num,msgpkt)) {
      case 'D':
         if (num != n) {
            if (oldtry++ > MAXTRY) return('A');
            if (num == ((n==0) ? 63:n-1)) {
               spack('Y',num,6,msgpkt);
               numtry = 0;
               return(state);
               }
            else return('A');
            }
         decode();
         spack('Y',n,0,0);
         oldtry = numtry;
         numtry = 0;
         n = (n+1)%64;
         return('D');
      case 'F':
         if (oldtry++ > MAXTRY) return('A');
         if (num == ((n==0) ? 63:n-1)) {
            spack('Y',num,0,0);
            numtry = 0;
            return(state);
            }
         else return('A');
      case 'Z':
         if (num != n) return('A');
         spack('Y',n,0,0);
         n = (n+1)%64;
         return('C');
      case 'E':
         return('A');
      case FALSE:
         spack('N',n,0,0);
         return(state);
      default:
        return('A');
      }
   }

spack(type,num,len,data)
char type, *data;
short num, len;
   {
   short i;
   char chksum, buffer[100];
   register char *bufp;

   if (type != 'Y' && type != 'N') {
      if (num == 0) emits("\n");
      emit(type);
      }
   bufp = buffer;
   for (i=1; i<=pad; i++) sendchar(padchar);

   *bufp++ = SOH;
   *bufp++ = tochar(len+3);
   chksum  = tochar(len+3);
   *bufp++ = tochar(num);
   chksum += tochar(num);
   *bufp++ = type;
   chksum += type;

   for (i=0; i<len; i++) {
      *bufp++ = data[i];
      chksum += data[i];
      }
   chksum = (((chksum&0300) >> 6)+chksum)&077;
   *bufp++ = tochar(chksum);
   *bufp++ = '\r';
   *bufp++ = '\n';
   *bufp   = 0;
   sendstring(buffer);
   }

rpack(len,num,data)
short *len, *num;
char *data;
   {
   short i, done;
   char t, type, cchksum, rchksum;

    while (t != SOH) {
       t = readchar();
       if (timeout) return(FALSE);
       }

    done = FALSE;
    while (!done) {
       t = readchar();
       if (timeout) return(FALSE);
       if (t == SOH) continue;
       cchksum = t;
       *len = unchar(t)-3;
       t = readchar();
       if (timeout) return(FALSE);
       if (t == SOH) continue;
       cchksum = cchksum + t;
       *num = unchar(t);
       t = readchar();
       if (timeout) return(FALSE);
       if (t == SOH) continue;
       cchksum = cchksum + t;
       type = t;
       for (i=0; i<*len; i++) {
          t = readchar();
          if (timeout) return(FALSE);
          if (t == SOH) continue;
          cchksum = cchksum + t;
          data[i] = t;
          }
       data[*len] = 0;
       t = readchar();
       if (timeout) return(FALSE);
       rchksum = unchar(t);
       t = readchar();
       if (timeout) return(FALSE);
       if (t == SOH) continue;
       done = TRUE;
       }
   if (type != 'Y' && type != 'N') {
      if (*num == 0) emits("\n");
      emit(type);
      }
   cchksum = (((cchksum&0300) >> 6)+cchksum)&077;
   if (cchksum != rchksum) return(FALSE);
   return(type);
   }

getpkt() {
   short i,eof;

   static char leftover[6] = { '\0', '\0', '\0', '\0', '\0', '\0' };

   if (first == 1) {
      first = 0;
      *leftover = '\0';
      t = getc(fp);
      if (t == EOF) {
         first = 1;
         return(size = 0);
         }
      }
   else if (first == -1) {
      first = 1;
      return(size = 0);
      }
   for (size = 0; (msgpkt[size] = leftover[size]) != '\0'; size++) ;
   *leftover = '\0';
   rpt = 0;
   eof = 0;
   while (!eof) {
      next = getc(fp);
      if (next == EOF) {
         first = -1;
         eof   =  1;
         }
      osize = size;
      encode(t);
      t = next;
      if (size == spsiz-3) return(size);
      if (size > spsiz-3) {
         for (i = 0; (leftover[i] = msgpkt[osize+i]) != '\0'; i++) ;
         size = osize;
         msgpkt[size] = '\0';
         return(size);
         }
      }
   return(size);
   }

encode(a)
char a;
   {
   short a7,b8;

   if ((!imagemode) && a == '\n') {
      rpt = 0;
      msgpkt[size++] = quote;
      msgpkt[size++] = ctl('\r');
      if (size <= spsiz-3) osize = size;
      msgpkt[size++] = quote;
      msgpkt[size++] = ctl('\n');
      return;
      }
   if (rptflg) {
      if (a == next && (first == 0)) {
         if (++rpt < 94) return;
         else if (rpt == 94) {
            msgpkt[size++] = rptq;
            msgpkt[size++] = tochar(rpt);
            rpt = 0;
            }
         }
      else if (rpt == 1) {
         rpt = 0;
         encode(a);
         if (size <= spsiz-3) osize = size;
         rpt = 0;
         encode(a);
         return;
         }
      else if (rpt > 1) {
         msgpkt[size++] = rptq;
         msgpkt[size++] = tochar(++rpt);
         rpt = 0;
         }
      }
   a7 = a & 0177;
   b8 = a & 0200;
   if ((a7 < SP) || (a7==DEL)) {
      msgpkt[size++] = quote;
      a = ctl(a);
      }
   if (a7 == quote) msgpkt[size++] = quote;
   if ((rptflg) && (a7 == rptq)) msgpkt[size++] = quote;
   msgpkt[size++] = a;
   msgpkt[size] = '\0';
   }

decode()
   {
   USHORT a, a7, b8;
   char *buf;

   buf = msgpkt;
   rpt = 0;
   while ((a = *buf++) != '\0') {
      if (rptflg) {
         if (a == rptq) {
            rpt = unchar(*buf++);
            a = *buf++;
            }
         }
      if (a == quote) {
         a  = *buf++;
         a7 = a & 0177;
         if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') a = ctl(a);
         }
      if (rpt == 0) rpt = 1;
      if ((!imagemode) && a == '\r') continue;
      for (; rpt > 0; rpt--) putc(a, fp);
      }
   return(0);
   }

spar(data)
char data[];
   {
   data[0] = tochar(MAXPACKSIZ);
   data[1] = tochar(MYTIME);
   data[2] = tochar(MYPAD);
   data[3] = ctl(MYPCHAR);
   data[4] = tochar(MYEOL);
   data[5] = MYQUOTE;
   data[6] = 'N';
   data[7] = '1';
   data[8] = MYRPTQ;
   data[9] = '\0';
   }

rpar(data)
char data[];
   {
   spsiz   = unchar(data[0]);
   timint  = unchar(data[1]);
   pad     = unchar(data[2]);
   padchar = ctl(data[3]);
   eol     = unchar(data[4]);
   quote   = data[5];
   rptflg  = 0;
   if (data[6] == 0) return;
   if (data[7] == 0) return;
   if (data[8] == 0) return;
   rptq    = data[8];
   rptflg  = ((rptq > 040 && rptq < 0100) || (rptq > 0140 && rptq < 0177));
   }

SHAR_EOF
cat << \SHAR_EOF > remote.c
/****************************************************
 * vt100 emulator - remote character interpretation
 *
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 ****************************************************/

#define MODULE_REMOTE 1
#include "vt100.h"

static USHORT top       = MINY;
static USHORT bot       = MAXY;
static USHORT savx      = MINX;
static USHORT savy      = MINY;
static USHORT savmode   = 0;
static USHORT nlmode    = 0;
static USHORT alt       = 0;
static USHORT savalt    = 0;
static USHORT a[2]      = { 0, 0 };
static USHORT sa[2]     = { 0, 0 };
static short  inesc     = -1;

static short  p1,p2,numpar;
static char   escseq[40];

/************************************************
*  function to handle remote characters
*************************************************/
doremote(c)
char c;
    {
    if (c == 27 || inesc >= 0) { doesc(c); return; }
    if (c == 10 || c == 11 || c == 12) {
	if (nlmode) doindex('E'); else doindex('D');
	return;
	}
    if (c == 13) {
	if (!nlmode) emit(c);
	return;
	}
    if (c == 15) { alt = 0; return; }
    if (c == 14) { alt = 1; return; }
    if (a[alt] && c > 94 && c < 127) { doalt(c); return; }
    emit(c);
    }

doesc(c)
char c;
    {
    if (inesc < 0) { inesc = 0; return; }
    if (c == 27 || c == 24) { inesc = -1; return; }
    if (inesc == 0) {
	if (c == '[' || c == '#' || c == '(' || c == ')') {
	    numpar = 0;
	    escseq[inesc++] = c;
	    return;
	    }
	if (c == 'D' || c == 'E' || c == 'M') {
	    inesc = -1;
	    doindex(c);
	    return;
	    }
	if (c == '7') {
	    inesc = -1;
	    savx = x; savy = y; savmode = curmode; savalt = alt;
	    sa[0] = a[0]; sa[1] = a[1];
	    return;
	    }
	if (c == '8') {
	    inesc = -1;
	    x = savx; y = savy; alt = savalt; curmode = savmode;
	    a[0] = sa[0]; a[1] = sa[1];
	    return;
	    }
	if (c == 'c') {
	    inesc = -1;
	    top = MINY; bot = MAXY; savx = MINX; savy = MINY;
	    a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
	    emit(12); return;
	    }
	inesc = -1;
	return;
	}
    if (inesc == 1 && escseq[0] == '#') { inesc = -1; return; }
    if (inesc == 1 && escseq[0] == '(') {
	inesc = -1;
	if (c == '0' || c == '2') a[0] = 1; else a[0] = 0;
	return;
	}
    if (inesc == 1 && escseq[0] == ')') {
	inesc = -1;
	if (c == '0' || c == '2') a[1] = 1; else a[1] = 0;
	return;
	}
    if ((c >= '0' && c <= '9') || c == ';' || c == '?') {
	if (inesc == 1) numpar = 1;
	if (c == ';') numpar++;
	escseq[inesc++] = c;
	return;
	}
    escseq[inesc] = '\000';
    inesc = -1; p1 = -1; p2 = -1;
    if (escseq[1] == '?') return;
    switch (numpar) {
	case 1: sscanf(escseq,"[%d",         &p1);             break;
	case 2: sscanf(escseq,"[%d;%d",      &p1,&p2);         break;
	case 3: sscanf(escseq,"[%d;%d;%d",   &p1,&p2,&p2);     break;
	case 4: sscanf(escseq,"[%d;%d;%d;%d",&p1,&p2,&p2,&p2); break;
	}
    if (c >= 'A' && c <= 'D') {
	if (p1 <= 0) p1 = 1;
	switch (c) {
	    case 'A':   y -= 8*p1; if (y<top)  y = top;  break;
	    case 'B':   y += 8*p1; if (y>bot)  y = bot;  break;
	    case 'C':   x += 8*p1; if (x>MAXX) x = MAXX; break;
	    case 'D':   x -= 8*p1; if (x<MINX) x = MINX; break;
	    }
	return;
	}
    if (c == 'H' || c == 'f') {
	if (p1 <= 0) p1 = 1;
	if (p2 <= 0) p2 = 1;
	y = (--p1*8)+MINY; x = (--p2*8)+MINX;
	if (y > MAXY) y = MAXY;
	if (x > MAXX) x = MAXX;
	if (y < MINY) y = MINY;
	if (x < MINX) x = MINX;
	return;
	}
    if (c == 'r') {
	if (p1 <= 0) p1 = 1;
	if (p2 <= 0) p2 = 24;
	top = (--p1*8)+MINY; bot = (--p2*8)+MINY;
	if (top < MINY) top = MINY;
	if (bot > MAXY) bot = MAXY;
	if (top > bot) { top = MINY; bot = MAXY; }
	return;
	}
    if (c == 'm') {
	if (p2 >= 0) p1 = p2;
	if (p1 <= 0) curmode = 0; else curmode = 1;
	return;
	}
    if (c == 'K') {
	doerase();
	return;
	}
    if (c == 'J') {
	if (p1 < 0) p1 = 0;
	SetAPen(mywindow->RPort,0L);
	if (p1 == 0) RectFill(mywindow->RPort,
	    (long)MINX,(long)(y+2),(long)(MAXX+7),(long)(bot+2));
	else if (p1 == 1) RectFill(mywindow->RPort,
	    (long)MINX,(long)(top-7),(long)(MAXX+7),(long)(y-7));
	else RectFill(mywindow->RPort,
	    (long)MINX,(long)(top-7),(long)(MAXX+7),(long)(bot+2));
	SetAPen(mywindow->RPort,1L);
	doerase(); return;
	}
    if (c == 'h') {
	if (p1 == 20) nlmode = 1;
	return;
	}
    if (c == 'l') {
	if (p1 == 20) nlmode = 0;
	return;
	}
    if (c == 'x') {
	sendchar(27); sendstring("[3;1;8;64;64;1;0x"); return;
	}
    if (c == 'n') {
	if (p1 == 6) {
	    sendchar(27);
	    sprintf(escseq,"[%d;%dR",((y-MINY)/8)+1,((x-MINX)/8)+1);
	    sendstring(escseq); return;
	    }
	sendchar(27); sendstring("[0n"); return;
	}
    if (c == 'c') {
	sendchar(27); sendstring("[?1;0c"); return;
	}
    }

doindex(c)
char c;
    {
    inesc = -1;
    if (c != 'M') {
	if (y > bot) { top = MINY; bot = MAXY; y = bot; }
	if (y == bot) {
	    ScrollRaster(mywindow->RPort,0L,8L,MINX,(long)(top-6),
		(long)(MAXX+7),(long)(bot+1));
	    y -= 8;
	    }
	if (c == 'E') x = MINX;
	y += 8;
	}
    else {
	if (y < top) { top = MINY; bot = MAXY; y = top; }
	if (y == top) {
	    ScrollRaster(mywindow->RPort,0L,-8L,(long)MINX,(long)(top-7),
		(long)(MAXX+7),(long)(bot+1));
	    y += 8;
	    }
	y -= 8;
	}
    return;
    }

doalt(c)
char c;
    {
    short oldx,newx;
    inesc = -1;
    oldx = x; emit(' '); newx = x;
    x = oldx;
    SetAPen(mywindow->RPort,1L);
    switch (c) {
	case 'j':
	case 'm':
	case 'v':   doline(4,-8,4,-4);
	if      (c=='j')  doline(0,-4,4,-4);
	else if (c=='m')  doline(4,-4,8,-4);
	else              doline(0,-4,8,-4);
	break;

	case 'k':
	case 'l':
	case 'w': doline(4,-4,4,0);
	if      (c=='k')  doline(0,-4,4,-4);
	else if (c=='l')  doline(4,-4,8,-4);
	else              doline(0,-4,8,-4);
	break;

	case 'n':
	case 'q': doline(0,-4,8,-4);
	if      (c=='n')  doline(4,-8,4,0);
	break;

	case 't':
	case 'u':
	case 'x':   doline(4,-8,4,0);
	if      (c=='t')  doline(4,-4,8,-4);
	else if (c=='u')  doline(0,-4,4,-4);
	break;
	}
    x = newx;
    }

doline(x1,y1,x2,y2) {
    RectFill(mywindow->RPort,(long)(x+x1),(long)(y+y1),
	(long)(x+x2),(long)(y+y2));
    }

doerase()
    {
    inesc = -1;
    if (p1 < 0) p1 = 0;
    SetAPen(mywindow->RPort,0L);
    if (p1 == 0) RectFill(mywindow->RPort,(long)x,(long)(y-6),
	(long)(MAXX+7),(long)(y+1));
    else if (p1 == 1) RectFill(mywindow->RPort,
	(long)MINX,(long)(y-6),(long)(x+7),(long)(y+1));
    else RectFill(mywindow->RPort,
	(long)MINX,(long)(y-6),(long)(MAXX+7),(long)(y+1));
    SetAPen(mywindow->RPort,1L);
    return;
    }
SHAR_EOF
cat << \SHAR_EOF > vt100.c
/************************************************************************
*  vt100 terminal emulator with xmodem transfer capability
*
*	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
*	v1.0 860712 DBW	- First version released
*
*  use <esc> to abort xmodem or kermit transfers
*
*  written by Michael Mounier
*  new version by Dave Wecker
************************************************************************/

/*  all includes defines and globals */
#define MODULE_MAIN 1
#include "vt100.h"

/******************************************************/
/*                   Main Program                     */
/*                                                    */
/*      This is the main body of the program.         */
/******************************************************/

main(argc,argv)
int	argc;
char	**argv;
    {
    ULONG class;
    USHORT code,menunum,itemnum;
    int KeepGoing,capture,send,maxwait,i;
    char c,name[32];
    FILE *tranr,*trans;

    InitDefaults(argc,argv);
    InitDevs();
    InitFileItems();
    InitRSItems();
    InitXFItems();
    InitCMItems();
    InitMenu();
    SetMenuStrip(mywindow,&menu[0]);

    KeepGoing = TRUE;
    capture=FALSE;
    send=FALSE;
    x = MINX ; y = MINY; curmode = 0;
    SetAPen(mywindow->RPort,1L);
    cursoron();
    cursoroff();
    emit(12);
    BeginIO(Read_Request);

    while( KeepGoing )
	    {
	    /* wait for window message or serial port message */
	    cursoron();
	    Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
		(1L << mywindow->UserPort->mp_SigBit));
	    cursoroff();

	    if (send)
		{
		if ((c=getc(trans)) != EOF)
		    {
		    if (c == '\n') c = '\r';
		    sendchar(c);
		    }
		else
		    {
		    fclose(trans);
		    emits("\nFile Sent\n");
		    send=FALSE;
		    }
		}
	    maxwait = 0;
	    while (CheckIO(Read_Request) && maxwait++ < 20)
		{
		WaitIO(Read_Request);
		c=rs_in[0] & 0x7f;
		BeginIO(Read_Request);
		doremote(c);
		if (capture && c != 10) {
		    if (c == 13) c = 10;
		    putc(c , tranr);
		    }
		}

	    while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) )
		{
		class = NewMessage->Class;
		code = NewMessage->Code;
		ReplyMsg( NewMessage );
		switch( class )
		    {
		    case CLOSEWINDOW:
		    KeepGoing = FALSE;
		    break;

		    case RAWKEY:
		    c = toasc(code);
		    break;

		    case NEWSIZE:
		    emit(12);
		    break;

		    case MENUPICK:
		    if ( code != MENUNULL )
			{
			menunum = MENUNUM( code );
			itemnum = ITEMNUM( code );
			switch( menunum )
			    {
			    case 0:
			    switch( itemnum )
				{
				case 0:
				if (capture == TRUE)
				    {
				    capture=FALSE;
				    fclose(tranr);
				    emits("\nEnd File Capture\n");
				    }
				else
				    {
				    emits("\nAscii Capture:");
				    filename(name);
				    if ((tranr=fopen(name,"w")) == 0)
					{
					capture=FALSE;
					emits("\nError Opening File\n");
					break;
					}
				    capture=TRUE;
				    }
				break;

				case 1:
				if (send == TRUE)
				{ 
				    send=FALSE;
				    fclose(trans);
				    emits("\nFile Send Cancelled\n");
				    }
				else
				    {
				    emits("\nAscii Send:");
				    filename(name);
				    if ((trans=fopen(name,"r")) == 0)
					{
					send=FALSE;
					emits("\nError Opening File\n");
					break;
					}
				    send=TRUE;
				    }
				break;

				case 2:
				emits("\nXmodem Receive:");
				filename(name);
				if (XMODEM_Read_File(name))
				    {
				    emits("\nRecieved File\n");
				    emit(8);
				    }
				else
				    {
				    close(fd);
				    emits("Xmodem Receive Failed\n");
				    emit(8);
				    }
				break;

				case 3:
				emits("\nXmodem Send:");
				filename(name);
				if (XMODEM_Send_File(name))
				    {
				    emits("\nSent File\n");
				    emit(8);
				    }
				else
				    {
				    close(fd);
				    emits("\nXmodem Send Failed\n");
				    emit(8);
				    }
				break;

				case 4:
				emits("\nKermit Receive local name:");
				filename(name);
				if (dokreceive(name))
				    {
				    emits("\nRecieved File\n");
				    emit(8);
				    }
				else
				    {
				    close(fd);
				    emits("Kermit Receive Failed\n");
				    emit(8);
				    }
				break;

				case 5:
				emits("\nKermit Send local name:");
				filename(name);
				if (doksend(name))
				    {
				    emits("\nSent File\n");
				    emit(8);
				    }
				else
				    {
				    close(fd);
				    emits("\nKermit Send Failed\n");
				    emit(8);
				    }
				break;
				}
			    break;

			    case 1:
			    AbortIO(Read_Request);
			    switch( itemnum )
				{
				case 0:
				Read_Request->io_Baud = 300;
				break;
				case 1:
				Read_Request->io_Baud = 1200;
				break;
				case 2:
				Read_Request->io_Baud = 2400;
				break;
				case 3:
				Read_Request->io_Baud = 4800;
				break;
				case 4:
				Read_Request->io_Baud = 9600;
				break;
				}
			    Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
			    DoIO(Read_Request);
			    Read_Request->IOSer.io_Command = CMD_READ;
			    BeginIO(Read_Request);
			    break;

			    case 2:
			    switch( itemnum )
				{
				case 0:
				imagemode = 0;
				break;

				case 1:
				imagemode = 1;
				break;
				}
			    break;

			    case 3:
			    switch (itemnum) {
				case 0:
				palette(mywindow);
				break;

				case 1:
				for (i = 0; i< CTSIZ; i++) 
				    mycolortable[i] = default_color[i];
				LoadRGB4(myviewport,mycolortable,CTSIZ);
				break;
				}
			    } /* end of switch ( menunum ) */
			}    /*  end of if ( not null ) */
		    }   /* end of switch (class) */
		}   /* end of while ( newmessage )*/
	    }  /* end while ( keepgoing ) */

    /*   It must be time to quit, so we have to clean
    *   up and exit.
    */

    for (i = 0; i< CTSIZ; i++) mycolortable[i] = orig_color[i];
    LoadRGB4(myviewport,mycolortable,CTSIZ);
    CloseDevice(Read_Request);
    DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
    FreeMem(Read_Request,(long)sizeof(*Read_Request));
    CloseDevice(Write_Request);
    DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
    FreeMem(Write_Request,(long)sizeof(*Write_Request));
    ClearMenuStrip( mywindow );
    FreeColorMap( mycolormap );
    CloseWindow( mywindow );
    if (cust != 0) CloseScreen( myscreen );
    exit(FALSE);
    } /* end of main */
SHAR_EOF
cat << \SHAR_EOF > window.c
/****************************************************
 * vt100 emulator - window/keyboard support
 *
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 ****************************************************/

#define MODULE_WINDOW 1
#include "vt100.h"

/*************************************************
*  function to get file name
*************************************************/
filename(name)
char name[];
    {
    char c;
    ULONG class;
    USHORT code;
    int keepgoing,i;
    keepgoing = TRUE;
    i=0;
    while (keepgoing) {
	while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) )
	    {
	    class = NewMessage->Class;
	    code = NewMessage->Code;
	    ReplyMsg( NewMessage );
	    if (class=RAWKEY)
		{
		c = toasc(code);
		name[i]=c;
		if (name[i] != 0)
		    {
		    if (name[i] == 13)
			{
			name[i]=0;
			keepgoing = FALSE;
			}
		    else
			{
			if (name[i] == 8)
			    {
			    i -=2;
			    if (i < -1)
			    i = -1;
			    else
				{
				emit(8);
				emit(32);
				emit(8);
				}
			    }
			else
			emit(c);
			}
		    i += 1;
		    }
		}
	    } /* end of new message loop */
	}   /* end of god knows what */
    emit(13);
    emit(10);
    } /* end of function */


/*************************************************
*  function to print a string
*************************************************/
emits(string)
char string[];
    {
    int i;
    char c;

    i=0;
    while (string[i] != 0)
	{
	c=string[i];
	if (c == 10) emit(13);
	emit(c);
	i += 1;
	}
    }

/*************************************************
*  function to output ascii chars to window
*************************************************/
emit(c)
char c;
    {
    Move(mywindow->RPort,(long)x,(long)y);

    c &= 0x7F;
    switch( c )
	{
	case '\t':
	x += 64 - ((x-MINX) % 64);
	break;

	case 10:  /* lf */
	y += 8;
	break;

	case 13:  /* cr */
	x = MINX;
	break;

	case 8:   /* backspace */
	x -= 8;
	if (x < MINX) x = MINX;
	break;

	case 12:     /* page */
	x = MINX;
	y = MINY;
	SetAPen(mywindow->RPort,0L);
	RectFill(mywindow->RPort,(long)MINX,
	    (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1));
	SetAPen(mywindow->RPort,1L);
	break;

	case 7:     /* bell */
	ClipBlit(mywindow->RPort,0L,0L,mywindow->RPort,0L,0L,
	    MAXX,MAXY,0x50L);
	ClipBlit(mywindow->RPort,0L,0L,mywindow->RPort,0L,0L,
	    MAXX,MAXY,0x50L);
	break;

	default:
	if (c < ' ' || c > '~') break;
	if (curmode) {
	    Text(mywindow->RPort," ",1L);
	    Move(mywindow->RPort,(long)x,(long)y);
	    SetDrMd(mywindow->RPort,(long)INVERSVID);
	    Text(mywindow->RPort,&c,1L);
	    SetDrMd(mywindow->RPort,(long)JAM2);
	    }
	else Text(mywindow->RPort,&c,1L);
	x += 8;
	} /* end of switch */

    while (x > MAXX) x -= 8;
    while (y > MAXY) {
	y -= 8;
	x  = MINX;
	ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
	    (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1));
	}
    }

/******************************
* Manipulate cursor
******************************/
cursoroff()
    {
    SetDrMd(mywindow->RPort,COMPLEMENT);
    SetAPen(mywindow->RPort,3L);
    RectFill(mywindow->RPort,
	(long)(x-1),(long)(y-8),(long)(x+8),(long)(y+2));
    SetAPen(mywindow->RPort,1L);
    SetDrMd(mywindow->RPort,(long)JAM2);
    }

cursoron()
    {
    SetDrMd(mywindow->RPort,COMPLEMENT);
    SetAPen(mywindow->RPort,3L);
    RectFill(mywindow->RPort,
	(long)(x-1),(long)(y-8),(long)(x+8),(long)(y+2));
    SetAPen(mywindow->RPort,1L);
    SetDrMd(mywindow->RPort,(long)JAM2);
    }

/************************************************
*  function to take raw key data and convert it 
*  into ascii chars
**************************************************/
toasc(code)
USHORT code;
    {
    static int ctrl = FALSE;
    static int shift = FALSE;
    static int capsl = FALSE;
    char c;
    static char keys[75] = {
	'`' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '0' , '-' ,
	'=' , '\\' , 0 , '0' , 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , 'o' ,
	'p' , '[' , ']' , 0 , '1' , '2' , '3' , 'a' , 's' , 'd' , 'f' , 'g' , 'h' ,
	'j' , 'k' , 'l' , ';' , '\'' , 0 , 0 , '4' , '5' , '6' , 0 , 'z' , 'x' , 'c' , 'v' ,
	'b' , 'n' , 'm' , 44 , '.' , '/' , 0 , '.' , '7' , '8' , '9' , ' ' , 8 ,
	'\t' , 13 , 13 , 27 , 127 , 0 , 0 , 0 , '-' } ;

    switch ( code )
	{
	case 98:   capsl = TRUE; c = 0;break;
	case 226:  capsl = FALSE;c = 0;break;
	case 99:   ctrl = TRUE;  c = 0;break;
	case 227:  ctrl = FALSE; c = 0;break;
	case 96:
	case 97:   shift = TRUE; c = 0;break;
	case 224:
	case 225:  shift = FALSE;c = 0;break;
	case 0x50: c=0; sendchar(27); sendstring("OP"); break;
	case 0x51: c=0; sendchar(27); sendstring("OQ"); break;
	case 0x52: c=0; sendchar(27); sendstring("OR"); break;
	case 0x53: c=0; sendchar(27); sendstring("OS"); break;
	case 0x0f: c=0; sendchar(27); sendstring("Op"); break;
	case 0x1d: c=0; sendchar(27); sendstring("Oq"); break;
	case 0x1e: c=0; sendchar(27); sendstring("Or"); break;
	case 0x1f: c=0; sendchar(27); sendstring("Os"); break;
	case 0x2d: c=0; sendchar(27); sendstring("Ot"); break;
	case 0x2e: c=0; sendchar(27); sendstring("Ou"); break;
	case 0x2f: c=0; sendchar(27); sendstring("Ov"); break;
	case 0x3d: c=0; sendchar(27); sendstring("Ow"); break;
	case 0x3e: c=0; sendchar(27); sendstring("Ox"); break;
	case 0x3f: c=0; sendchar(27); sendstring("Oy"); break;
	case 0x43: c=0; sendchar(27); sendstring("OM"); break;
	case 0x4a: c=0; sendchar(27); sendstring("Ol"); break;
	case 0x5f: c=0; sendchar(27); sendstring("Om"); break;
	case 0x3c: c=0; sendchar(27); sendstring("On"); break;
	case 0x4c: c = 0; sendchar(27); sendstring("[A"); break;
	case 0x4d: c = 0; sendchar(27); sendstring("[B"); break;
	case 0x4e: c = 0; sendchar(27); sendstring("[C"); break;
	case 0x4f: c = 0; sendchar(27); sendstring("[D"); break;
	default:
	if (code < 75) c = keys[code];
	else c = 0;
	}

    /* add modifiers to the keys */

    if (c != 0) {
	if (shift) {
	    if ((c <= 'z') && (c >= 'a')) c -= 32;
	    else
	    switch( c ) {
		case '[':  c = '{'; break;
		case ']':  c = '}'; break;
		case '\\': c = '|'; break;
		case '\'': c = '"'; break;
		case ';':  c = ':'; break;
		case '/':  c = '?'; break;
		case '.':  c = '>'; break;
		case ',':  c = '<'; break;
		case '`':  c = '~'; break;
		case '=':  c = '+'; break;
		case '-':  c = '_'; break;
		case '1':  c = '!'; break;
		case '2':  c = '@'; break;
		case '3':  c = '#'; break;
		case '4':  c = '$'; break;
		case '5':  c = '%'; break;
		case '6':  c = '^'; break;
		case '7':  c = '&'; break;
		case '8':  c = '*'; break;
		case '9':  c = '('; break;
		case '0':  c = ')'; break;
		default:            break;
		}
	    }
	else if (capsl && (c <= 'z') && (c >= 'a')) c -= 32;
	}
    if (ctrl) {
	if (c >= '`' && c <= 127) c -= 96;
	else if (c >= '@' && c <= '_') c -= 64;
	}
    if (c != 0) sendchar(c);
    return(c);
    }

SHAR_EOF
cat << \SHAR_EOF > xmodem.c
/*************************************************************
 * vt100 terminal emulator - XMODEM protocol support
 *
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 *************************************************************/

#define MODULE_XMODEM 1
#include "vt100.h"

/************************************************************
* Send a string (using sendchar below)
************************************************************/

sendstring(s)
char *s;
    {
    char c;

    while ((c = *s++) != '\000') sendchar(c);
    }

/**************************************************************/
/* send char and read char functions for the xmodem function */
/************************************************************/
sendchar(ch)
int ch;
    {
    rs_out[0] = ch;
    DoIO(Write_Request);
    }

readchar()
    {
    unsigned char c;
    int rd,ch;

    rd = FALSE;

    while (rd == FALSE)
	{
	Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) | ( 1L << mywindow->UserPort->mp_SigBit));
	if(CheckIO(Read_Request))
	    {
	    WaitIO(Read_Request);
	    ch=rs_in[0];
	    rd = TRUE;
	    BeginIO(Read_Request);
	    }
	if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort))
	if ((NewMessage->Class) == RAWKEY)
	if ((NewMessage->Code) == 69)
	    {
	    emits("\nUser Cancelled Transfer");
	    break;
	    }
	}
    if (rd == FALSE)
	{
	timeout = TRUE;
	emits("\nTimeout Waiting For Character\n");
	}
    c = ch;
    return(c);
    }

/**************************************/
/* xmodem send and recieve functions */
/************************************/

XMODEM_Read_File(file)
char *file;
    {
    int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag;
    unsigned int checksum, j, bufptr,i;
    char numb[10];
    bytes_xferred = 0L;

    if ((fd = creat(file, 0)) < 0)
	{
	emits("Cannot Open File\n");
	return FALSE;
	}
    else
    emits("Receiving File\n\nType <ESC> to abort transfer\n");

    timeout=FALSE;
    sectnum = errors = bufptr = 0;
    sendchar(NAK);
    firstchar = 0;
    while (firstchar != EOT && errors != ERRORMAX)
	{
	errorflag = FALSE;

	do                                    /* get sync char */
	    {
	    firstchar = readchar();
	    if (timeout == TRUE)
	    return FALSE;
	    }
	while (firstchar != SOH && firstchar != EOT);

	if  (firstchar == SOH)
	    {
	    emits("Getting Block ");
	    sprintf(numb, "%d", sectnum);
	    emits(numb);
	    emits("...");
	    sectcurr = readchar();
	    if (timeout == TRUE)
	    return FALSE;
	    sectcomp = readchar();
	    if (timeout == TRUE)
	    return FALSE;
	    if ((sectcurr + sectcomp) == 255)
		{
		if (sectcurr == (sectnum + 1 & 0xff))
		    {
		    checksum = 0;
		    for (j = bufptr; j < (bufptr + SECSIZ); j++)
			{
			bufr[j] = readchar();
			if (timeout == TRUE)
			return FALSE;
			checksum = (checksum + bufr[j]) & 0xff;
			}
		    if (checksum == readchar())
			{
			errors = 0;
			sectnum++;
			bufptr += SECSIZ;
			bytes_xferred += SECSIZ;
			emits("verified\n");
			if (bufptr == BufSize)
			    {
			    if (write(fd, bufr, BufSize-128) == EOF)
				{
				emits("\nError Writing File\n");
				return FALSE;
				}
			    bufptr = 128;
			    for (j = 0; j < 128; j++)
				bufr[j] = bufr[(BufSize-128)+j];
			    }
			sendchar(ACK);
			}
		    else
			{
			errorflag = TRUE;
			if (timeout == TRUE)
			return FALSE;
			}
		    }
		else
		    {
		    if (sectcurr == (sectnum & 0xff))
			{
			emits("\nReceived Duplicate Sector\n");
			sendchar(ACK);
			}
		    else
		    errorflag = TRUE;
		    }
		}
	    else
	    errorflag = TRUE;
	    }
	if (errorflag == TRUE)
	    {
	    errors++;
	    emits("\nError\n");
	    sendchar(NAK);
	    }
	}        /* end while */
    if ((firstchar == EOT) && (errors < ERRORMAX))
	{
	sendchar(ACK);
	while (bufptr > 0 && (bufr[--bufptr] == 0x00 ||
			      bufr[bufptr]   == 0x1A)) ;
	write(fd, bufr, ++bufptr);
	close(fd);
	return TRUE;
	}
    return FALSE;
    }

XMODEM_Send_File(file)
char *file;
    {
    int sectnum, bytes_to_send, size, attempts, c, i;
    unsigned checksum, j, bufptr;
    char numb[10];
    timeout=FALSE;
    bytes_xferred = 0;
    if ((fd = open(file, 0)) < 0) {
	emits("Cannot Open Send File\n");
	return FALSE;
	}
    else
    emits("Sending File\n\nType <ESC> to abort transfer\n");
    attempts = 0;
    sectnum = 1;
    /* wait for sync char */
    j=1;
    while (((c = readchar()) != NAK) && (j++ < ERRORMAX));
    if (j >= (ERRORMAX))
	{
	emits("\nReceiver not sending NAKs\n");
	return FALSE;
	}

    while ((bytes_to_send = read(fd, bufr, BufSize)) && attempts != RETRYMAX)
	{
	if (bytes_to_send == EOF)
	    {
	    emits("\nError Reading File\n");
	    return FALSE;
	    }

	bufptr = 0;
	while (bytes_to_send > 0 && attempts != RETRYMAX)
	    {
	    attempts = 0;
	    do
		{
		sendchar(SOH);
		sendchar(sectnum);
		sendchar(~sectnum);
		checksum = 0;
		size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send;
		bytes_to_send -= size;
		for (j = bufptr; j < (bufptr + SECSIZ); j++)
		if (j < (bufptr + size))
		    {
		    sendchar(bufr[j]);
		    checksum += bufr[j];
		    }
		else
		    {
		    sendchar(0);
		    }
		sendchar(checksum & 0xff);
		attempts++;
		c = readchar();
		if (timeout == TRUE)
		return FALSE;
		}
	    while ((c != ACK) && (attempts != RETRYMAX));
	    bufptr += size;
	    bytes_xferred += size;
	    emits("Block ");
	    sprintf(numb, "%d", sectnum);
	    emits(numb);
	    emits(" sent\n");
	    sectnum++;
	    }
	}
    close(fd);
    if (attempts == RETRYMAX)
	{
	emits("\nNo Acknowledgment Of Sector, Aborting\n");
	return FALSE;
	}
    else
	{
	attempts = 0;
	do
	    {
	    sendchar(EOT);
	    attempts++;
	    }
	while ((readchar() != ACK) && (attempts != RETRYMAX) && (timeout == FALSE));
	if (attempts == RETRYMAX)
	emits("\nNo Acknowledgment Of End Of File\n");
	}
    return TRUE;
    }

SHAR_EOF
cat << \SHAR_EOF > vt100.h
/*********************************************************************
 *  a terminal program that has ascii and xmodem transfer capability
 *
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 *  use esc to abort xmodem transfer
 *
 *  written by Michael Mounier
 *  new version by Dave Wecker 860621
 ************************************************************************/

/*  compiler directives to fetch the necessary header files */
#include <exec/types.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/text.h>
#include <graphics/regions.h>
#include <graphics/copper.h>
#include <graphics/gels.h>
#include <devices/serial.h>
#include <devices/keymap.h>
#include <hardware/blit.h>
#include <stdio.h>
#include <ctype.h>
#include <libraries/dos.h>
#include <functions.h>

#undef NULL
#define   NULL   ((void *)0)

#define INTUITION_REV 1L
#define GRAPHICS_REV  1L

/* things for xmodem send and recieve */
#define SECSIZ   0x80
#define TTIME    10          /* number of seconds for timeout */
#define BufSize  0x1000      /* Text buffer */
#define ERRORMAX 10          /* Max errors before abort */
#define RETRYMAX 10          /* Maximum retrys before abort */
#define SOH      1           /* Start of sector char */
#define EOT      4           /* end of transmission char */
#define ACK      6           /* acknowledge sector transmission */
#define NAK      21          /* error in transmission detected */

#define FILEMAX 6    /* number of file menu items */
#define RSMAX 5      /* speed menu items */
#define XFMAX 2      /* transfer mode items */
#define CMMAX 2	     /* number of color menu items */
#define MAXMENU 4    /* total number of menu entries */

#define DPTH	1L
#define SCRNT	197L
#define SCRNH	205L
#define WDTH	640L
#define	WINDT	3L
#define HGHT	200L
#define BCOL	0L
#define	CTSIZ	2L
#define MINX    0L
#define MAXX    632L
#define MINY    14L
#define MAXY    198L

extern struct MsgPort *CreatePort();

#ifdef MODULE_MAIN
char    bufr[BufSize];
int     fd, timeout = FALSE;
long    bytes_xferred;
int     imagemode = TRUE;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

struct NewScreen NewScreen = {
   0,SCRNT,WDTH,SCRNH,DPTH,       /* left, top, width, height, depth */
   0,1,(HIRES|LACE),    /* DetailPen, BlockPen, ViewModes */
   CUSTOMSCREEN,NULL,   /* Type, Font */
   (UBYTE *)"VT100 Terminal Screen", /* Title */
   NULL,NULL };         /* Gadgets, Bitmap */

struct NewWindow NewWindow = {
   0,WINDT,WDTH,HGHT,     /* left, top, width, height */
   0,1,              /* detailpen, blockpen */
   MENUPICK | CLOSEWINDOW | RAWKEY | NEWSIZE,
   SMART_REFRESH | REPORTMOUSE | ACTIVATE | BORDERLESS |
   WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG, /* Flags */
   NULL,NULL,        /* FirstGadget, CheckMark */
   (UBYTE *)
   "VT100 Terminal Window                                                  ",
   NULL,             /* set screen after open screen */
   NULL,             /* bitmap */
   WDTH, HGHT, WDTH, HGHT,/* minw, minh, maxw, maxh */
   CUSTOMSCREEN      /* Type */
};

struct Screen *myscreen;            /* ptr to applications screen */
struct Window *mywindow;            /* ptr to applications window */
struct ViewPort *myviewport;
struct ColorMap *mycolormap;
USHORT *mycolortable;
struct IntuiMessage *NewMessage;    /* msg structure for GetMsg() */
struct Preferences  *Prefs;	    /* preferences from GetPrefs() */

struct MenuItem FileItem[FILEMAX];
struct IntuiText FileText[FILEMAX];
struct MenuItem RSItem[RSMAX];
struct IntuiText RSText[RSMAX];
struct MenuItem XFItem[XFMAX];
struct IntuiText XFText[XFMAX];
struct MenuItem CMItem[CMMAX];
struct IntuiText CMText[CMMAX];
struct Menu menu[MAXMENU];
struct IOExtSer *Read_Request;
char rs_in[2];
struct IOExtSer *Write_Request;
char rs_out[2];
short x,y,curmode;

/*************************** defaults ***********************************/
USHORT	orig_color[CTSIZ]    = {0x004,0x666};
USHORT	default_color[CTSIZ] = {0x200,0xA00};
short	speed = 2400;
short	cust  = 2;

#else /* not MODULE_MAIN */
extern char    bufr[BufSize];
extern int     fd, timeout;
extern long    bytes_xferred;
extern int     imagemode;

extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;

extern struct NewScreen NewScreen;
extern struct NewWindow NewWindow;
extern struct Screen *myscreen;
extern struct Window *mywindow;
extern struct ViewPort *myviewport;
extern struct ColorMap *mycolormap;
extern USHORT *mycolortable;
extern struct IntuiMessage *NewMessage;
extern struct Preferences  *Prefs;
extern struct MenuItem FileItem[FILEMAX];
extern struct IntuiText FileText[FILEMAX];
extern struct MenuItem RSItem[RSMAX];
extern struct IntuiText RSText[RSMAX];
extern struct MenuItem XFItem[XFMAX];
extern struct IntuiText XFText[XFMAX];
extern struct MenuItem CMItem[CMMAX];
extern struct IntuiText CMText[CMMAX];
extern struct Menu menu[MAXMENU];
extern struct IOExtSer *Read_Request;
extern char rs_in[2];
extern struct IOExtSer *Write_Request;
extern char rs_out[2];
extern short x,y,curmode;
extern USHORT	orig_color[CTSIZ];
extern USHORT	default_color[CTSIZ];
extern short	speed;
extern short	cust;
#endif /* not MODULE_MAIN */

#ifndef MODULE_INIT
extern InitDefaults(),InitDevs(),InitFileItems(),InitRSItems(),
	InitXFItems(),InitCMItems(),InitMenu();
#endif

#ifndef MODULE_WINDOW
extern filename(),emits(),emit(),cursoroff(),cursoron(),toasc();
#endif

#ifndef MODULE_XMODEM
extern sendchar(), sendstring(), readchar(),
       XMODEM_Read_File(), XMODEM_Send_File();
#endif

#ifndef MODULE_REMOTE
extern doremote();
#endif

#ifndef MODULE_KERMIT
extern doksend(),dokreceive();
#endif

#ifndef MODULE_COLORS
extern palette();
#endif

SHAR_EOF
#	End of shell archive
exit 0