[comp.emacs] microEMACS 3.7i for VMS Question!

earleh@dartvax.UUCP (Earle R. Horton) (11/10/86)

> Hello!
> 
> I got the sources for microEMACS 3.7i, and I am trying to compile
> it for VMS 4.4 on a VAX 750. I am having trouble getting it to
> run, as it always dies on the "vtinit( )" routine, module DISPLAY.C
> 
> PS: Also on the same subject, does anyone have the VT100/VT200 arrow
>     keys working?
(See my earlier message)
Also, by the way, you might want to change the variable "eoppad" to 
something greater than zero for 
       "case TT$_UNKNOWN:       /* assume adm3a */"
                                in vmsvt.c.  I use 10, and this greatly
improves the display on my adm3a at 19,200 baud.  

earleh@dartvax.UUCP (Earle R. Horton) (11/12/86)

> Hello!
> 
> I got the sources for microEMACS 3.7i, and I am trying to compile
> it for VMS 4.4 on a VAX 750. I am having trouble getting it to
> run, as it always dies on the "vtinit( )" routine, module DISPLAY.C
> ...
> 
> Spiros Triantafyllopoulos, GM Research Labs
>                            Warren, MI. 48090
>                            Spiros@GMR.COM
> 
> PS: Also on the same subject, does anyone have the VT100/VT200 arrow
>     keys working?

     I have had microEMACS 3.7 running for three or four months now under
VMS, and think I have located all the possible trouble spots one might
encounter getting it up and running under VMS.  Since I do not have version
3.7i, kindly verify the accuracy of what I say here by looking at your
copy of the code if you have 3.7i.  Since the modifications I made to run
microEMACS under VMS are pretty well spread out over the program modules,
I give here a cookbook on how to get things going.  Also, I basically gave
up making changes to things when I became satisfied that the program worked
well enough for me, so you may want to fine tune things a bit and maybe
put in some things I left out, particularly in the VT100 keypad department.

     I have four reasons for not wanting to post the entire set of modules
that I have modified.  (1) It's not my code, after all.  (2) I don't have
the latest version.  (3) Size.  (4) People who use emacs are C programmers
and like to tinker with things (correct me if I am wrong).

--------------------fatal error section--------------------

pipe() and getname() are functions in the VAX C RTL, so they cannot be used
for names in a user program.  Change all occurences of pipe() and getname()
in your copy of the source to something else.  A crude way to do this might
be to do a global replace with a line editor.  Since I do not remember
where all the occurences were, I recommend using "search" to find them.

Also, unlink() is not implemented in the VAX C RTL, so you might want to
comment out the references to it in spawn.c in order to avoid linker
error messages.  It's not used, anyway, under VMS.

     The following set of declarations appears in termio.c in ttopen().  The
compiler didn't like it:
        int     iosb[2];
        int     status;
        struct  dsc$descriptor  idsc;
        struct  dsc$descriptor  odsc;
        char    oname[40];
     It didn't mind this, however:
        struct  dsc$descriptor  idsc;
        struct  dsc$descriptor  odsc;
        char    oname[40];
        int     iosb[2];
        int     status;
     This might be a compiler bug or whatever, but certainly is a strange
one.

--------------------submit file section--------------------

$!command file to compile and link microEMACS 3.7 under VMS 4.3
$!
$!you might want to change the next line to reflect your pathname...
$set default disk$user:[user.earleh.eph]
$!
$cc basic.c, bind.c, buffer.c, display.c, file.c, fileio.c, -
line.c, lock.c, main.c, random.c, region.c , search.c, spawn.c,-
vmsvt.c, termio.c, window.c, word.c, exec.c, input.c, isearch.c
$!
$!
$link basic.obj, bind.obj, buffer.obj, display.obj, file.obj, -
 fileio.obj, line.obj, lock.obj, main.obj, random.obj, -
 region.obj, -
 search.obj, spawn.obj, vmsvt.obj, termio.obj, window.obj, -
 word.obj, -
 exec.obj, input.obj, isearch.obj, options_file/opt /executable=emacs.exe

--------------------options_file.opt--------------------

sys$share:vaxcrtl.exe/share

(This is a one-line file which you pass to the linker as in the submit
file.  It instructs the linker that you will use the VAX C RTL as a 
shared image at run time.  See your system manager to find out whether 
this is implemented on your system.)

--------------------how to invoke it once compiled--------------------

Put this in your "login.com" with the appropriate disk and directory names
for your system:

$emacs :== $__dua1:[user.earleh]emacs

--------------------precompiler options (estruct.h)--------------------

#define ANSI 0
#define VT52 0
#define VMSVT 1
#define VT100PAD 1    /* if you want to use the VT100 keypad */

/* set the rest of the options according to personal taste */

--------------------VT100 keypad section--------------------

Rather than post the entire affected modules, I am going to post the 
routines that I changed in order to get the VT100 keypad going.  I had
to draw the line somewhere between posting nothing and posting all the 
source code I have...  Also, I have not seen 3.7i, so I don't know how
much of what has been changed.  This stuff should be enough to get things
going, however.

The next routine goes in VMSVT.C, and now has the effect of "turning on"
the VT100 keypad (simple, really).


/*******
 *  vmsopen - Get terminal type and open terminal
 *******/

vmsopen()
{
	termtype = vmsgtty();
	switch (termtype) {
		case TT$_UNKNOWN:	/* Assume ADM3a	*/
			eolexist = FALSE;
			termeop = "\032";
/* My adm3a works better if I pad after clearing the screen.  ERH */
			eoppad = 10;
			break;
		case TT$_VT52:
			termeol = "\033K";
			eolpad = 0;
			termeop = "\033H\033J";
			eoppad = 0;
			break;
                case TT$_VT100:         /* I'm assuming that all these */
                case TT$_VT101:         /* are a super set of the VT100*/
                case TT$_VT102:         /* If I'm wrong, just remove   */
                case TT$_VT105:         /* those entries that aren't.  */
                case TT$_VT125:
                case TT$_VT131:
                case TT$_VT132:
                case TT$_VT200_SERIES:
			revexist = TRUE;
			termeol = "\033[K";
			eolpad = 3;
			termeop = "\033[;H\033[2J";
			eoppad = 50;  
			termtype = TT$_VT100;
			break;
		default:
			puts("Terminal type not supported");
			exit (SS$_NORMAL);
	}
        ttopen();
/* the next line turns on the keypad edit mode. ERH */
        if (termtype == TT$_VT100) ttputs("\033=");
}

As you can see, the only thing different here is that you have to send the
string "\033=" to the terminal sometime in order to put the terminal in 
"edit" mode.  I don't know if this is the same for VT52 or not, but it
should be easy enough to find out...  You might also want to allow for 
VT102, VT200, etc.  I admit, I was lazy.


The next chunk of code is part of termio.c.   The only significant
change is that we send the string "\033>" to the terminal somehow just
before we reset things and exit.

/*
 * This function gets called just before we go back home to the command
 * interpreter. On VMS it puts the terminal back in a reasonable state.
 * Another no-operation on CPM.
 */
ttclose()
{
#if     AMIGA
        amg_flush();
        Close(terminal);
#endif
#if     VMS
        int     status;
        int     iosb[1];
	char 	termtype;

        ttflush();
/* put in some code to get keypad out of edit mode */
        termtype = vmsgtty();
        switch (termtype){
        	case TT$_VT100:
        	case TT$_VT101:
        	case TT$_VT102:
        	case TT$_VT105:
        	case TT$_VT125:
        	case TT$_VT131:
        	case TT$_VT132:
        	case TT$_VT200_SERIES:
        		ttputs("\033>");
			ttflush();
        		break;
        	default:
        		break;
        }

............rest of termio.c............

The next routine can be found at the end of input.c.  When you press
one of the keypad or function keys on a VT100 series, you get a three-
character voodoo sequence which always starts with "\033O" or "\033[".
I tinkered with the key input routines so that these two sequences 
get flagged as "SPEC", and then I put in some appropriate bindings for
them in ebind.h.  Note that when you refer to these keys in your "emacs.rc"
startup file, you can call them for example "FN6" for the keypad "6".
Also note that you cannot use ESC-O or ESC-[ anymore, and that I did
not put in any provision for "gold-key" prefixing.


/*	GETCMD:	Get a command from the keyboard. Process all applicable
		prefix keys
							*/
getcmd()

{

	int c;		/* fetched keystroke */

	/* get initial character */
	c = get1key();

	/* process META prefix */
	if (c == metac) {
		c = get1key();

#if VT100PAD

        /* Process VT100 <Esc>'O' and <Esc>'[' */
                if (c == '[' | c == 'O')
                      {c = get1key();
	      	       return (SPEC | c);
		       }
#endif

	        if (c>='a' && c<='z')		/* Force to upper */
        	        c -= 0x20;
	        if (c>=0x00 && c<=0x1F)		/* control key */
	        	c = CTRL | (c+'@');
		return(META | c);
	}

	/* process CTLX prefix */
	if (c == ctlxc) {
		c = get1key();
	        if (c>='a' && c<='z')		/* Force to upper */
        	        c -= 0x20;
	        if (c>=0x00 && c<=0x1F)		/* control key */
	        	c = CTRL | (c+'@');
		return(CTLX | c);
	}

	/* otherwise, just return it */
	return(c);
}

These are the bindings I elected to put in for the VT100 keypad.  Since
I use an adm3a most of the time, I didn't spend too much time working
out the optimal combination of commands, but merely picked some more or
less at random.  This chunk of code goes in ebind.h, in the middle of 
"KEYTAB  keytab[NBINDS] = {".  I recommend compiling the program and
trying it out for a while before making a choice of what bindings are
best.  Note also that these can be changed "on the fly" using the
"bind-to-key" command or in your startup file.  I also did not 
investigate shift-keypad combinations, since I didn't think of it...


#if     VT100PAD
        {SPEC|'A',              backline},	/* up cursor*/
        {SPEC|'B',              forwline},	/* down cursor*/
        {SPEC|'C',              forwchar},	/* forwards */
        {SPEC|'D',              backchar},	/* backwards */
        {SPEC|'M',              filesave},	/* enter */
        {SPEC|'P',              gotobol},	/* clear */
        {SPEC|'Q',              gotoeol},	/* = */
        {SPEC|'R',              listbuffers},	/* / */
        {SPEC|'S',              namedcmd},	/* * */
        {SPEC|'l',              forwpage},	/* + */
        {SPEC|'m',              backpage},	/* - */
	{SPEC|'n',              setmark},	/* . */
        {SPEC|'p',              forwsearch},	/* 0 */
        {SPEC|'q',              onlywind},	/* 1 */
        {SPEC|'r',          	splitwind},	/* 2 */
        {SPEC|'s',              showcpos},	/* 3 */
        {SPEC|'t',              gotobob},	/* 4 */
        {SPEC|'u',              gotoeob},	/* 5 */
        {SPEC|'v',              deskey},	/* 6 */
        {SPEC|'w',              backword},	/* 7 */
        {SPEC|'x',              forwword},	/* 8 */
        {SPEC|'y',              bindtokey},	/* 9 */
#endif

--------------------that should be enough--------------------

That's all the changes I had to make to get microEMACS 3.7 going under VMS
4.3.  If you are using VMS 4.4 and microEMACS 3.7i, look out for side effects
of any changes that may have occured.

Good luck!