[net.emacs] More info on porting MicroEmacs 3.5 to MSC -- details

sharp@yale.ARPA (Oliver Sharp) (05/14/86)

[I hope the net.emacs people who use machines big enough for REAL emacs
(i.e. GNU) won't be too upset if we use net.emacs for info on the small
versions. :-)]


  There was enough interest in my first posting to merit a more detailed
follow up.  It is difficult for me to get diffs, so I will describe
each needed change in detail.  I would imagine that the same changes
applied to version 3.6 will work equally well.  I haven't tested the
program very extensively, but it seems to work enough to be useful.  

  I'm including my makefile at the end for those who are interested.  I 
compiled using large model, because medium model only gave me about 6k free 
data space.  There is a LOT of static data, but other postings I saw seemed 
to imply that other people got a more reasonable amount of space using medium
model.  According to my MSDOS version of the size command, there is 
around 50k of static - putting 6k in the realm of possibility.  Anyone like 
to comment on that?  

Some warnings:
  With large model, I edited a couple of moderately large files; since buffer 
size is an int, the byte count loses over 32k.  I saved the file and it 
seemed to save correctly, though, so it seems as though emacs does not use
that value to save files.  I'm sure there are some other gotchas floating 
around as well; most of them are probably due to the messy Intel architecture 
MS C has to contend with (hey, I worked at uSoft last summer - I can't blame 
the compiler, can I?)  So, as usual, caveat emptor.  Before using this for 
serious work, play around with it to make sure nothing bites you.

  For each file that I edited, I will describe the changes and include
an actual code fragment if it seems useful (they will have some context
around them so you can figure out where they come from).  I know, I know,
you want diffs.  Sorry - they are hard for me to get right now; my machine
is getting packed away for the summer tonight and my last final was this
afternoon.


------------------------------------------------------------------------
estruct.h
------------------------------------------------------------------------

  Add the line "#define MSC 1"; I suggest you put it underneath the LATTICE
symbol.  #define MSDOS to be 1, the terminal driver of your choice to 1,
and the other OS, compiler, and terminal symbols to 0.


------------------------------------------------------------------------
edef.h
------------------------------------------------------------------------

  Every file includes this one, so it is a good place to stick:
char *malloc();

  This is important if you are planning to compile in large model.  Some
people put this line in stdio.h; they don't have to worry about it.  The
problem is that if malloc isn't declared as returning a pointer, the thing
that gets returned is assumed to be a (16 bit) integer.  In large model, 
this assumption is wrong and the pointer value gets completely hashed.  
This bug is a real nuisance to find.

------------------------------------------------------------------------
bind.c
------------------------------------------------------------------------

  There is a line that says:
#if	(MSDOS & LATTICE) | V7 | AMIGA

  Make the obvious modification:
#if	(MSDOS & (LATTICE | MSC)) | V7 | AMIGA


------------------------------------------------------------------------
fileio.c
------------------------------------------------------------------------

  Basically the same deal as bind.c -
From:  #if     V7 | (MSDOS & LATTICE)
To:    #if     V7 | (MSDOS & (LATTICE | MSC))

  In the same file, emacs writes out a ^Z if it is in Lattice.  Since I
am morally opposed to the whole concept of ^Z, I don't do this for MSC.
If you like the EOF mark, you can stick it in.


-------------------------------------------------------------------------
spawn.c
-------------------------------------------------------------------------

  Now we start getting to the more interesting stuff.  According to the
Version 7 manual, the MS C manual, and my memory of Lattice, the invokation
of system() that has two arguments doesn't make much sense.  I suppose it
probably works by ignoring the second one, but I don't understand it.  In
the true tradition of all porting, if you don't understand it #if it and
do it right for your version.

  If you have your switchar set differently than the default, you don't want
to use system because it automatically executes "command /c whatever".  My
solution was to use execlp, which needs another include file.  If you
want to use my solution, put the following code at the top to get the 
include file:

>#if     MSDOS
>#if	MSC
>#include	<process.h>
>#endif
>#include        <dos.h>
>#undef	CPM
>#endif


  Now go to the actual execution of the cli.  Make it look like this:

>#if     MSDOS
>        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
>        (*term.t_flush)();
>#if	MSC
>	spawnlp(P_WAIT,"command",NULL);
>#else
>       sys("\\command.com", "");               /* Run CLI.             */
>#endif
>        sgarbf = TRUE;
>        return(TRUE);
>#endif

  Do the same thing at the spawn() routine:

>#if     MSDOS
>        if ((s=mlreply("MS-DOS command: ", line, NLINE)) != TRUE)
>                return (s);
>#if	MSC
>	spawnlp(P_WAIT,line,NULL);
>#else
>        system(line);
>#endif
>        while ((*term.t_getchar)() != '\r')     /* Pause.               */
>                ;
>        sgarbf = TRUE;
>        return (TRUE);
>#endif

  Almost there.  The only other change is to get rid of the invokation of
forklp(), which doesn't exist in MSC.  Just use spawnlp instead:

>#if LATTICE
>        return forklp(cmd, tail, NULL);
>#endif
>#if MSC
>        return spawnlp(P_WAIT, cmd, tail, NULL);
>#endif

  Actually, this is in the sys() routine which isn't used at all any
more, but it doesn't hurt to fix it anyway.


-------------------------------------------------------------------------
termio.c
-------------------------------------------------------------------------

  This is the really crucial file; I explained what the problem was in my
first posting (I didn't explain that typahead() also has the same problem ... 
sorry).  Here is the way the code should look - I just picked out the 
interesting fragment:

inside ttgetc():

>#if	MSDOS & (LATTICE | MSC)
>	int c;		/* character read */
>	int flags;	/* cpu flags after dos call */
>
>	/* if a char already is ready, return it */
>	if (nxtchar >= 0) {
>		c = nxtchar;
>		nxtchar = -1;
>		return(c);
>	}
>
>	/* call the dos to get a char */
>	rg.h.ah = 7;		/* dos Direct Console Input call */
>	intdos(&rg, &rg);
>	c = rg.h.al;		/* grab the char */
>
>	return(c);
>#endif


in typahead():

> #if	MSDOS
>	int c;		/* character read */
>	int flags;	/* cpu flags from dos call */
>
>#if	MSC
>	if (kbhit() != 0)
>		return(TRUE);
>	else
>		return(FALSE);
>#endif
>
>	if (nxtchar >= 0)
>		return(TRUE);

etc.


----------------------------------------------------------------------
makefile
----------------------------------------------------------------------

  I have a lookalike to the UNIX make, so this uses feature that aren't in
some of the stripped down versions that have been floating around.  You 
might have to change it to work with your system.


#  Makefile for emacs

.c.obj:
	cl -c -Ml $*.c

CFLAGS=		-O

OFILES=		ansi.obj basic.obj bind.obj buffer.obj display.obj file.obj \
                fileio.obj hp150.obj line.obj lock.obj main.obj random.obj \
                region.obj search.obj spawn.obj tcap.obj termio.obj vt52.obj \
                window.obj word.obj 

CFILES=		ansi.c basic.c bind.c buffer.c display.c file.c \
		fileio.c hp150.c line.c lock.c main.c random.c region.c \
		search.c spawn.c tcap.c termio.c vt52.c window.c word.c

HFILES=		estruct.h edef.h efunc.h epath.h ebind.h

emacs:		$(OFILES)
		link @emacs.lnk

$(OFILES):	$(HFILES)


----------------------------------------------------------------------
emacs.lnk
----------------------------------------------------------------------

ansi basic bind buffer display file fileio hp150 line lock main random +
region search spawn tcap termio vt52 window word 
emacs /STACK:50000;


=======================================================================

Well, that's it.  I hope you can all figure out what to do from that.  I
won't be available for a while, since it is the end of the semester, so
I'm afraid I am going to leave you all to fend for yourselves.  I will
probably be reading the group net.micro.pc over the summer, so if you post 
there I ought to see it eventually.

Good Luck! 

BTW, if you find any bugs in the original code (or even mine, I guess :-),
go ahead and post.

Oliver Sharp
.....!yale!sharp