toma@tekgvs.UUCP (Thomas Almy) (06/17/86)
I recently got Microemacs 3.6 running using Microsoft C, following the guidelines recently given by Oliver Sharp at Yale. The following are the modifications I made to Microemacs V3.6. The major concern was increasing the display speed by writing directly to display memory. The modifications are designed for CGA or CGA equivalent display controllers. (See note at end for EGA 80x43 mode!). The result is spectacular! Several other modifications apply even if the change to direct display output are not performed, so read in any case! *****STEP 1 -- Modification to display.c for direct video. This modification is in the spirit of "RAINBOW". I am not showing the modifications as conditional compilations -- I leave that to you (YES I did it on my copy!). First -- delete all references to and definitions of pscreen. These are not needed by the new routines since they never take the time to compare the physical and virtual screens. RAINBOW didn't need this either. Second -- updateline should be called with the reference to pscreen (vp2) deleted. Then use this definition of updateline: updateline(row, vline, flags) int row; char vline[]; /* what we want it to end up as */ short *flags; /* and how we want it that way */ { char *cp1; int req,gmode; req = *flags & VFREQ; gmode = (req ? 2 : 0x17 ); /* white on blue, inverse is green on black */ if (req) *flags |= VFREV; else *flags &= ~VFREV; cp1 = &vline[0]; /* Use fast video. */ putline(row+1,1,cp1,gmode); *flags &= ~VFCHG; } Then add the following definition for putline: putline(row, col, buf, mode) int row,col,mode; char *buf; { register int n; char *display; n = strlen(buf); if (col + n - 1 > term.t_ncol) n = term.t_ncol - col + 1; display = (char *)(0xb8000000L + 2*((col-1)+(row-1)*term.t_ncol)); while (n--) { *display++ = *buf++; *display++ = mode; } } The above is only for Microsoft C compiler, medium or large memory model. It probably would have to be changed for other compilers, and definately needed to be changed for the small model. *******STEP 2 -- Improvement of inline editing in display.c and line.c The speedup for within line editing does not work if the same file is in two or more windows. In this case the performance is excruciatingly slow without a PC AT. This fix makes things work alot faster, even without the direct display writing of step 1. The following change is made to update() in display.c so that only the line containing the cursor will be updated: if ((wp->w_flag & ~WFMODE) == WFEDIT) { j = wp->w_ntrows + i; /* added line */ while ((lp != curwp->w_dotp) && /* wp becomes curwp */ (j > i)) /* added line */ { ++i; lp = lforw(lp); } if (j>i) /* added line */ { vscreen[i]->v_flag |= VFCHG; vtmove(i, 0); for (j = 0; j < llength(lp); ++j) vtputc(lgetc(lp, j)); vteeol(); } } The following change is made to the first statement of lchange(flag) in line.c so that we don't signal hard updates if more than one window and just single line edit. if ((!(flag&WFEDIT)) && /* added term */ (curbp->b_nwnd != 1)) /* Ensure hard. */ flag = WFHARD; ******STEP 3: Fix for erroneous buffer sizes in buffer.c Problem in that the buffer list shows buffer sizes only if they fit in an int. Fix is in makelist() -- change declaration of nbytes to "long", change itoa() so declaration of num is "long". ******STEP 4: Fix keyboard lookahead (add file kbhit.asm) The Microsoft C compiled version has a brain damaged set of bios/bdos calls which cannot return the zero flag, just the sign flag. The use of "kbhit" causes emacs to be exited with the printer on if ^P has been used an odd number of times in an editing session. I linked in this version of kbhit. (Note that failure of these routines in termio.c are the primary cause of the dreaded stack overflow message!). KBHIT_TEXT segment 'CODE' assume cs:KBHIT_TEXT public _kbhit _kbhit PROC FAR mov ah,1 int 22 ; bios call for keyboard status jz nokey mov ax,1 ret nokey: mov ax,0 ret _kbhit endP KBHIT_TEXT ends end ******STEP 5: Fix for WRAP mode not wrapping on white space in word.c Problem is that words ending in periods or other punctuation which are wrapped will cause the punctuation to vanish! Fix is to have wordwrap() call nonblank() instead of inword(), where the definition of nonblank() is: nonblank() { register char c; if (curwp->w_doto == llength(curwp->w_dotp)) return (FALSE); c = lgetc(curwp->w_dotp, curwp->w_doto); if (c == ' ') return (FALSE); if (c == '\t') return (FALSE); /* a tab is white space too */ return (TRUE); } ******STEP 6: Fix for terminal initialization on spawning in spawn.c Problem is that terminal de-initialization code should be executed just before spawning a task (^X-C command), and initialization code just after. I discovered this problem after I modified the system to use 80x43 mode on an EGA display (using NANSI.SYS to change modes). (*term.t_close)(); /* added line */ spawnlp(P_WAIT,"command",NULL); /* Run CLI. */ (*term.t_open)(); /* added line */ This change should be made for at all spawning calls. ******STEP 7: Fix for "delete-blank-lines" in random.c Problem is that this command puts text into kill buffer (yet does not clear the buffer first). An examination of the code shows that this command should not use the kill buffer; its call of ldelete is missing an argument! In deblank, change "ldelete(nld)" to "ldelete(nld,FALSE)". ******STEP 8: Fix for "delete-word" in word.c Problem is that this command puts text into the kill buffer yet does not clear the buffer first. An examination of the code shows that this command intends to use the kill buffer, but is improperly coded. Since other versions of EMACS do not use the kill buffer for this command, the fix is to change delfword and delbword so that they call ldelete with a second argument "FALSE" instead of "TRUE", and change the source file documentation accordingly. If it is desired to have the command put the text into the kill buffer (much more useful, in my opinion) then the following code must be added before the call of ldelete: if ((lastflag&CFKILL) == 0) /* Clear kill buffer if */ kdelete(); /* last wasn't a kill. */ thisflag |= CFKILL; ******Personal preference modifications The problem is that if more than one file is specified, my preference is for the first two files to appear in windows. To do this I add a variable sfile which gets set TRUE if two or more files, and then just before the outermost execution loop I added: if (sfile) { splitwind(); /* split window into two */ nextwind(); /* go to bottom window */ nextbuffer(); /* put next buffer in window */ nextwind(); /* goes back to top window */ } I modified the handling of tabs so that the tab character is always inserted but on display tabs are expanded to the set tab size. This follows the operation of other emaxen (?) that I use. This change required many minor changes to display.c (look for places where the constant 7 and the character '\t' appear. I also modified display.c so that characters with the parity bit set will display with a leading tilde. I added EGA support by having ANSI.C send the command "ESC[=43h" to NANSI.SYS in the open routine, and "ESC[=3h" in the close routine. I also changed the number of lines to 43. Works like a charm with the direct video mods! By the way, if the editor is compiled with the small model, and 2k of stack space (which I found to be adequate), then it works much faster, and still has a capacity of about 30k in buffers. Tom Almy
lawrence@duncan.UUCP (06/22/86)
Thanks for the fix notice. I sneaked them in just before I sent 3.7 off to mod.sources. step1: 3.7 has an IBM-PC specific screen driver similar to the mods made here step2: update changed so much, I will look into making an equivilant change with the new code step3: 3.7 fixes this problem...I also changed the name of itoa() to ltoa() to reflect the fact a long was being changed to an ascii (the same problem also existed in the showcpos() command and has been fixed as well). step4: agreed. 3.7 also has this problem fixed, but in a different way using C code. (check typahead() in termio.c) step5: 3.7 also has this fixed. I used some very similar code to this. step6: also done already step7: I hadn't caught this one. It is fixed now. step8: this one has already been fixed Daniel Lawrence ihnp4!pur-ee!pur-phy!duncan!lawrence or ihnp4!itivax!duncan!lawrence