[net.info-terms] Z29 Termcap Entry

nessus@mit-eddie.UUCP (Doug Alan) (08/15/83)

     (Free: One Z29 Termcap entry enclosed!!!)

     The problem declaring an H19 to be synonomous with a Z29 is that
it needs more padding.  It especially loses if a program attempts to
put the Z29 into insert mode and insert text at 9600 baud.  It even
loses worse if the program attempts to insert tabs at 9600 baud.
     Adding padding to text that is inserted loses because in order to
make the Z29 not die, one must add so much padding that whenever the
program tries to use insert mode, the effective rate is about 110
baud.
     What program would be silly enough to put the terminal into
insert mode and shove stuff at it at 9600 baud you ask?  Gosling's
Emacs.  Emacs seems to want to do the mathematically optimal thing in
doing a redisplay rather than the practical thing.  When it is about
to output a line on top of a line that is already on the screen,
instead of just killing to the end of the line and outputing the new
line, it compares the old line and the new line and if there are any
similarities, it constructs the new line by deleting the text on the
old line on the terminal that is already there and then inserting new
text into the line to transform it into the new line that is to be
displayed.  The Z29 does not act kindly to this.
     But don't cry for too long.... There is a solution.  You can make
a termcap entry for the Z29 that says the Z29 has no insert mode.
Then Emacs cannot use it's horrible hack.  "Oh, no, but now inserting
into a line will be really slow", you say.  Well there is a sort of a
solution to that too.  There is an insert character option on the Z29
that will insert one character.  Unfortunately, it involves putting
the terminal into ansi mode, inserting the character, and changing it
back to H19 mode.  All this takes 12 characters.  Pretty expensive to
insert one character, but it works.  Either Emacs doesn't try to use
it's inserting hack when it's only given an insert character ability or
the Z29 doesn't require padding with this (the former is probably more
likely, but I haven't checked it out).
     "Shut up and give us the termcap entry!", you shout out of boredom
of this unnecessarily long verbiage.  Okay, here it is: (I make no
claim that it provides enough padding in all cases -- but it (almost)
always seems to work for me.  I make no claim that it never provides
way too much padding -- perhaps it doesn't, but I never tried to
whittle the padding down to the absolute minimum necessary.)


zb|z29|zenith 29|z29b:is=\E<\E[?2h\Ev:\
	:al=1\EL:am:bs:cd=14\EJ:ce=1\EK:cl=14\EE:cm=\EY%+ %+ :co#80:\
	:dc=0.1*\EN:dl=1\EM:do=\EB:ei=:ho=\EH:im=:ic=1\E<\E[1@\E[?2h:\
	:li#24:mi:nd=\EC:as=\EF:ae=\EG:sf=2\n:\
	:ms:pt:sr=2\EI:se=\Eq:so=\Ep:up=1\EA:vs=\Ex4:ve=\Ey4:\
	:kb=^h:ku=\EA:kd=\EB:kl=\ED:kr=\EC:kh=\EH:kn#10:\
	:k1=\ES:k2=\ET:k3=\EU:k4=\EV:k5=\EW:\
	:k6=\EP:k7=\EQ:k8=\ER:k9=\E0I:k0=\E~:l0=home:

				-Doug Alan
				 decvax!genrad!mit-eddie!nessus
				 Nessus@MIT-MC

thomas@utah-gr.UUCP (Spencer W. Thomas) (08/16/83)

     What program would be silly enough to put the terminal into
  insert mode and shove stuff at it at 9600 baud you ask?  Gosling's
  Emacs.  Emacs seems to want to do the mathematically optimal thing in
  doing a redisplay rather than the practical thing.  When it is about
  to output a line on top of a line that is already on the screen,
  instead of just killing to the end of the line and outputing the new
  line, it compares the old line and the new line and if there are any
  similarities, it constructs the new line by deleting the text on the
  old line on the terminal that is already there and then inserting new
  text into the line to transform it into the new line that is to be
  displayed.  The Z29 does not act kindly to this.

There is a fix to this problem.  The termcap driver in Gosling's emacs
does not do a good job of computing the costs of inserting and deleting
characters.  Here is a diff listing (the numbers will be off, that's why
I did it with context) which fixes the problem.  It also fixes a long
standing problem (which is in ALL the terminal drivers) of computing the
"baud factor".  The formula used in the stock emacs is
	1) Special case to the Concept-100 and is "based on an analysis
		of the interrupt routine" in it, therefore not necessarily
		applicable to other terminals, and
	2) negative at 19.2k baud.
I have replaced it with a simple, straightforward calculation which seems
to do a pretty good job.

The diff listing follows.

=Spencer

*** old
--- new
***************
*** 14,15
  #include <stdio.h>
  #include "config.h"

--- 14,16 -----
  #include <stdio.h>
+ #include <ctype.h>
  #include "config.h"
***************
*** 230,233
      PC = 0;
!     BaudFactor = 1 / (1 - (.45 +.3 * BaudRate / 9600.))
! 	* (BaudRate / 10000.);
      if (CursStr == 0 || UP == 0 || ELstr == 0 || ESstr == 0) {

--- 235,237 -----
      PC = 0;
!     BaudFactor = BaudRate / 10000.;
      if (CursStr == 0 || UP == 0 || ELstr == 0 || ESstr == 0) {
***************
*** 240,243
      }
!     tt.t_ILmf = BaudFactor * 0.75;
!     tt.t_ILov = ILstr ? 2 : MissingFeature;
      if (!ILstr)

--- 244,251 -----
      }
!     if (ILstr)
! 	costof(ILstr, &ov, &mf);
!     else
! 	ov = mf = MissingFeature;
!     tt.t_ILmf = mf;
!     tt.t_ILov = ov;
      if (!ILstr)
***************
*** 247,252
      if (ICstr && DCstr) {
! 	tt.t_ICov = 1;
! 	tt.t_ICov = 4;
! 	tt.t_DCmf = 2;
! 	tt.t_DCov = 0;
      }

--- 255,267 -----
      if (ICstr && DCstr) {
! 	costof(ICstr, &ov, &mf);
! 	tt.t_ICov = ov + (ICPstr ? mf : 0);
! 	if (ICPstr)
! 	    costof(ICPstr, &ov, &mf);
! 	else
! 	    ov = mf + 1;
! 	tt.t_ICmf = ov;
! 
! 	tt.t_DCov = tt.t_ICov;
! 	costof(DCstr, &ov, &mf);
! 	tt.t_DCmf = ov + mf;
      }
***************
*** 253,254
      else {
!  	tt.t_ICov = MissingFeature;
  	tt.t_ICov = MissingFeature;

--- 268,270 -----
      else {
! 	tt.t_ICmf = MissingFeature;
  	tt.t_ICov = MissingFeature;
***************
*** 263,264
  
  

--- 278,286 -----
  
+ static
+ costof (str, ov, mf)
+ char *str;
+ int *ov, *mf;
+ {
+     register char *cp;
+     int pad;
+     *ov = *mf = pad = 0;
+     for (cp = str; isdigit(*cp); cp++)
+ 	pad = pad * 10 + (*cp - '0');
+     if (*cp == '*')
+     {
+ 	*mf = pad * BaudFactor;
+ 	cp++;
+     }
+     else
+ 	*ov = pad;
+     *ov += strlen(cp);
+     return *ov;
+ }
+ 
  static