home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume3 / mg2a / part08 < prev    next >
Encoding:
Text File  |  1989-02-03  |  58.3 KB  |  2,242 lines

  1. Path: xanth!mcnc!gatech!mandrill!hal!ncoast!allbery
  2. From: BLARSON@ECLA.USC.EDU (Bob Larson)
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i032: mg 2a part 8 of 15
  5. Message-ID: <12401300459.47.BLARSON@ECLA.USC.EDU>
  6. Date: 26 May 88 04:58:01 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: BLARSON@ECLA.USC.EDU (Bob Larson)
  9. Lines: 2230
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. comp.sources.misc: Volume 3, Issue 32
  13. Submitted-By: "Bob Larson" <BLARSON@ECLA.USC.EDU>
  14. Archive-Name: mg2a/Part08
  15.  
  16. #    This is a shell archive.
  17. #    Remove everything above and including the cut line.
  18. #    Then run the rest of the file through sh.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar:    Shell Archiver
  22. #    Run the following text with /bin/sh to create:
  23. #    sys/default/README
  24. #    sys/default/alloca.c
  25. #    sys/default/chrdef.h
  26. #    sys/default/cinfo.c
  27. #    sys/default/tty.c
  28. #    sys/default/ttydef.h
  29. #    sys/default/ttykbd.c
  30. #    sys/default/varargs.h
  31. #    sys/prime/cinfo.c
  32. #    sys/prime/fileio.c
  33. #    sys/prime/make.cpl
  34. #    sys/prime/mg.64v.options.c
  35. #    sys/prime/mg.options.c
  36. #    sys/prime/readme
  37. #    sys/prime/spawn.c
  38. #    sys/prime/stackptr$.pma
  39. #    sys/prime/sysdef.h
  40. #    sys/prime/ttyio.c
  41. #    sys/prime/varargs.h.ins.cc
  42. # This archive created: Sun May 22 02:24:06 1988
  43. # By:    blarson
  44. if test -d sys
  45. then true
  46. else mkdir sys
  47. fi
  48. if test -d sys/default
  49. then true
  50. else mkdir sys/default
  51. fi
  52. if test -d sys/prime
  53. then true
  54. else mkdir sys/prime
  55. fi
  56. cat << \SHAR_EOF > sys/default/README
  57.             MG Termcap Terminal Driver
  58.  
  59. The termcap library needs to know where to get the terminal type and
  60. termcap capibilities file from.  UNIX and Os9/68k users should
  61.  
  62.     setenv TERM term-type
  63.  
  64. to their terminal type, and
  65.  
  66.     setenv TERMCAP termcap-file
  67.  
  68. if they are using a non-standard termcap file.  VMS users should see
  69. [.SYS.VMS]AAAREADME.1ST for information on how to define the logical
  70. names TERM and ETC to point to the termcap definition file.  Users of
  71. other operating systems should do the aproprate thing.  For an example
  72. of a termcap file, UNIX users may look in /etc/termcap, Os9/68k users
  73. may look at /dd/sys/termcap (if present), and VMS users should see the
  74. file [.SYS.VMS.TERMCAP]TERMCAP. 
  75.  
  76. MG requires that certain terminal capabilities exist in the specified
  77. termcap entry.  The "cm" (cursor motion) capability *must* be
  78. available to use MG.  (Yes, it is possible to fake cm with some other
  79. capibilities, but MG doesn't try.) If your terminal is one that uses
  80. control characters in the paramater portion of the "cm" string, the
  81. "up" and "bc" capabilites may also be needed.  (See your termlib
  82. documentation for when this is so.)
  83.  
  84. If the following capabilities are available, they are used.  The AL
  85. and DL sequences are not totally standard, but having them improves
  86. the performance of the editor, since it doesn't have to redraw the
  87. screen to delete a line.  They should not be used if they need control
  88. characters as paramaters.
  89.  
  90.     cd    -- clear display
  91.     ce    -- clear to end of line
  92.  
  93.     al    -- insert 1 line
  94.     dl    -- delete 1 line
  95.  
  96.     AL    -- insert multiple lines (note capitalization)
  97.     DL    -- delete multiple lines (note capitalization)
  98.  
  99.     ti    -- cursor movement initialization string
  100.     te    -- cursor movement end string
  101.  
  102. The cs capability is not as standard as some of the other
  103. capibilities, but is used by MG when available.  It is used to define
  104. a "scrolling region", which defines a window within the screen where
  105. all the action takes place.  A newline character at the bottom of this
  106. area scrolls the rest of the text in the area up one line, just like
  107. the normal screen; a reverse linefeed (sr) at the top of the window
  108. moves all the text in the area down a line.  MG does not properly
  109. handle "cs" if your terminal needs control characters as paramaters,
  110. and in this case "cs" should not be defined.
  111.  
  112. If the cs and sr capabilities are available, the termcap driver uses
  113. these to make the insert/delete line functions work more smoothly. If
  114. only the cs capability is present, it is still used for the delete
  115. line function, but not for inserting lines.
  116.  
  117. Use of the cs capability is often desirable, but is not a win on
  118. bit-mapped screens such as Sun workstation console windows.  This is
  119. because it takes longer to scroll the window than to redraw it.  If
  120. you are using a workstation window, you might consider using a termcap
  121. entry that doesn't have the cs capability.
  122.  
  123. The definition of the cs capability is: the first parameter in the
  124. sequence defines the first row (origin 0) that is in the scrolling
  125. region, and the second argument defines the last row to include in the
  126. scrolling region.
  127.  
  128.     cs    -- set scrolling region (arg1 = top, arg2 = bottom)
  129.     sr    -- reverse index
  130.  
  131. The following capabilities provide for an enhanced (reverse-video or
  132. otherwise rendered) mode line.  The sg entry should not be present on
  133. terminals that do this to characters as they are placed on the screen.
  134. Terminals that put a region of the screen in the standout mode should
  135. have sg defined as numeric: :sg#0: for terminals that do this on
  136. regions but don't take any character positions to do this, (this may
  137. be a non-standard interprition of the meaning of sg) and the number of
  138. character positions taken by any other terminal.
  139.  
  140.     so    -- enter standout mode
  141.     se    -- leave standout mode
  142.     sg    -- number of character positions used by standout
  143.  
  144.         Terminal-specific initialization file
  145.  
  146. If the MG termcap terminal driver is compiled with XKEYS defined, and
  147. the startup file option is enabled as well, MG will look for a
  148. terminal-specific initialization file.  The name of the terminal
  149. initialization file varies between operating systems, but will usually
  150. look like .mg-TERM, where TERM represents your terminal type.  For
  151. example, a terminal initialization file under Unix and VMS for the DEC
  152. VT100 terminal (termcap type vt100) would have the name ".mg-vt100". 
  153.  
  154. The terminal-specific startup file has the same format as the mg
  155. startup file, and is executed immediately after the startup file
  156. during mg's startup phase.  An example vt100 initialization file
  157. follows, which globally binds the key sequences sent by the VT100
  158. terminal (in keypad mode) to the appropriate functions.
  159.  
  160. ----------------------------------CUT HERE-----------------------------------
  161. ;
  162. ; Small key definition file for VT100 terminals using the termcap
  163. ; driver. This only works if XKEYS is defined during compilation.
  164. ;
  165. (global-set-key "\eOA" 'previous-line)    ; up arrow
  166. (global-set-key "\eOB" 'next-line)    ; down arrow
  167. (global-set-key "\eOC" 'forward-char)    ; right arrow
  168. (global-set-key "\eOD" 'backward-char)    ; left arrow
  169. SHAR_EOF
  170. cat << \SHAR_EOF > sys/default/alloca.c
  171. /*
  172.     alloca -- (mostly) portable public-domain implementation
  173.  
  174.     last edit:    86/01/26    D A Gwyn
  175.  
  176.     This implementation of the PWB library alloca() function,
  177.     which is used to allocate space off the run-time stack so
  178.     that it is automatically reclaimed upon procedure exit, 
  179.     was inspired by discussions with J. Q. Johnson of Cornell.
  180.  
  181.     It should work under any C implementation that uses an
  182.     actual procedure stack (as opposed to a linked list of
  183.     frames).  There are some preprocessor constants that can
  184.     be defined when compiling for your specific system, for
  185.     improved efficiency; however, the defaults should be okay.
  186.  
  187.     The general concept of this implementation is to keep
  188.     track of all alloca()-allocated blocks, and reclaim any
  189.     that are found to be deeper in the stack than the current
  190.     invocation.  This heuristic does not reclaim storage as
  191.     soon as it becomes invalid, but it will do so eventually.
  192.  
  193.     As a special case, alloca(0) reclaims storage without
  194.     allocating any.  It is a good idea to use alloca(0) in
  195.     your main control loop, etc. to force garbage collection.
  196. */
  197. #ifndef lint
  198. static char    SCCSid[] = "@(#)alloca.c    1.1";    /* for the "what" utility */
  199. #endif
  200.  
  201. #ifdef X3J11
  202. typedef void    *pointer;        /* generic pointer type */
  203. #else
  204. typedef char    *pointer;        /* generic pointer type */
  205. #endif
  206.  
  207. #define    NULL    0            /* null pointer constant */
  208.  
  209. extern void    free();
  210. extern pointer    malloc();
  211.  
  212. /*
  213.     Define STACK_DIRECTION if you know the direction of stack
  214.     growth for your system; otherwise it will be automatically
  215.     deduced at run-time.
  216.  
  217.     STACK_DIRECTION > 0 => grows toward higher addresses
  218.     STACK_DIRECTION < 0 => grows toward lower addresses
  219.     STACK_DIRECTION = 0 => direction of growth unknown
  220. */
  221.  
  222. #ifndef STACK_DIRECTION
  223. #define    STACK_DIRECTION    0        /* direction unknown */
  224. #endif
  225.  
  226. #if STACK_DIRECTION != 0
  227.  
  228. #define    STACK_DIR    STACK_DIRECTION    /* known at compile-time */
  229.  
  230. #else    /* STACK_DIRECTION == 0; need run-time code */
  231.  
  232. static int    stack_dir = 0;        /* 1 or -1 once known */
  233. #define    STACK_DIR    stack_dir
  234.  
  235. static void
  236. find_stack_direction( /* void */ )
  237.     {
  238.     static char    *addr = NULL;    /* address of first
  239.                        `dummy', once known */
  240.     auto char    dummy;        /* to get stack address */
  241.  
  242.     if ( addr == NULL )
  243.         {            /* initial entry */
  244.         addr = &dummy;
  245.  
  246.         find_stack_direction();    /* recurse once */
  247.         }
  248.     else                /* second entry */
  249.         if ( &dummy > addr )
  250.             stack_dir = 1;    /* stack grew upward */
  251.         else
  252.             stack_dir = -1;    /* stack grew downward */
  253.     }
  254.  
  255. #endif    /* STACK_DIRECTION == 0 */
  256.  
  257. /*
  258.     An "alloca header" is used to:
  259.     (a) chain together all alloca()ed blocks;
  260.     (b) keep track of stack depth.
  261.  
  262.     It is very important that sizeof(header) agree with malloc()
  263.     alignment chunk size.  The following default should work okay.
  264. */
  265.  
  266. #ifndef    ALIGN_SIZE
  267. #define    ALIGN_SIZE    sizeof(double)
  268. #endif
  269.  
  270. typedef union hdr
  271.     {
  272.     char    align[ALIGN_SIZE];    /* to force sizeof(header) */
  273.     struct    {
  274.         union hdr    *next;    /* for chaining headers */
  275.         char        *deep;    /* for stack depth measure */
  276.         }    h;
  277.     }    header;
  278.  
  279. /*
  280.     alloca( size ) returns a pointer to at least `size' bytes of
  281.     storage which will be automatically reclaimed upon exit from
  282.     the procedure that called alloca().  Originally, this space
  283.     was supposed to be taken from the current stack frame of the
  284.     caller, but that method cannot be made to work for some
  285.     implementations of C, for example under Gould's UTX/32.
  286. */
  287.  
  288. pointer
  289. alloca( size )                /* returns pointer to storage */
  290.     unsigned    size;        /* # bytes to allocate */
  291.     {
  292.     static header    *last = NULL;    /* -> last alloca header */
  293.     auto char    probe;        /* probes stack depth: */
  294.     register char    *depth = &probe;
  295.  
  296. #if STACK_DIRECTION == 0
  297.     if ( STACK_DIR == 0 )        /* unknown growth direction */
  298.         find_stack_direction();
  299. #endif
  300.  
  301.     /* Reclaim garbage, defined as all alloca()ed storage that
  302.        was allocated from deeper in the stack than currently. */
  303.  
  304.     {
  305.     register header    *hp;        /* traverses linked list */
  306.  
  307.     for ( hp = last; hp != NULL; )
  308.         if ( STACK_DIR > 0 && hp->h.deep > depth
  309.           || STACK_DIR < 0 && hp->h.deep < depth
  310.            )    {
  311.             register header    *np = hp->h.next;
  312.  
  313.             free( (pointer)hp );    /* collect garbage */
  314.  
  315.             hp = np;    /* -> next header */
  316.             }
  317.         else
  318.             break;        /* rest are not deeper */
  319.  
  320.     last = hp;            /* -> last valid storage */
  321.     }
  322.  
  323.     if ( size == 0 )
  324.         return NULL;        /* no allocation required */
  325.  
  326.     /* Allocate combined header + user data storage. */
  327.  
  328.     {
  329.     register pointer    new = malloc( sizeof(header) + size );
  330.                     /* address of header */
  331.  
  332.     if ( new == NULL )
  333.         return NULL;        /* abort() is traditional */
  334.  
  335.     ((header *)new)->h.next = last;
  336.     ((header *)new)->h.deep = depth;
  337.  
  338.     last = (header *)new;
  339.  
  340.     /* User storage begins just after header. */
  341.  
  342.     return (pointer)((char *)new + sizeof(header));
  343.     }
  344.     }
  345. SHAR_EOF
  346. cat << \SHAR_EOF > sys/default/chrdef.h
  347. /*
  348.  * sys/default/chardef.h: character set specific #defines for mg 2a
  349.  * Warning: System specific ones exist
  350.  */
  351.  
  352. #ifndef    CHARMASK
  353. /*
  354.  * casting should be at least as efficent as anding with 0xff,
  355.  * and won't have the size problems.  Override in sysdef.h if no
  356.  * unsigned char type.
  357.  */
  358. #define    CHARMASK(c)    ((unsigned char) (c))
  359. #endif
  360.  
  361. /*
  362.  * These flags, and the macros below them,
  363.  * make up a do-it-yourself set of "ctype" macros that
  364.  * understand the DEC multinational set, and let me ask
  365.  * a slightly different set of questions.
  366.  */
  367. #define _W    0x01            /* Word.            */
  368. #define _U    0x02            /* Upper case letter.        */
  369. #define _L    0x04            /* Lower case letter.        */
  370. #define _C    0x08            /* Control.            */
  371. #define _P    0x10            /* end of sentence punctuation    */
  372. #define    _D    0x20            /* is decimal digit        */
  373.  
  374. #define ISWORD(c)    ((cinfo[CHARMASK(c)]&_W)!=0)
  375. #define ISCTRL(c)    ((cinfo[CHARMASK(c)]&_C)!=0)
  376. #define ISUPPER(c)    ((cinfo[CHARMASK(c)]&_U)!=0)
  377. #define ISLOWER(c)    ((cinfo[CHARMASK(c)]&_L)!=0)
  378. #define ISEOSP(c)    ((cinfo[CHARMASK(c)]&_P)!=0)
  379. #define    ISDIGIT(c)    ((cinfo[CHARMASK(c)]&_D)!=0)
  380. #define TOUPPER(c)    ((c)-0x20)
  381. #define TOLOWER(c)    ((c)+0x20)
  382.  
  383. /*
  384.  * generally useful thing for chars
  385.  */
  386. #define CCHR(x)        ((x) ^ 0x40)    /* CCHR('?') == DEL */
  387.  
  388. #ifndef    METACH
  389. #define    METACH    CCHR('[')
  390. #endif
  391.  
  392. #ifdef    XKEYS
  393. #define    K00    256
  394. #define    K01    257
  395. #define    K02    258
  396. #define    K03    259
  397. #define    K04    260
  398. #define    K05    261
  399. #define    K06    262
  400. #define    K07    263
  401. #define    K08    264
  402. #define    K09    265
  403. #define    K0A    266
  404. #define    K0B    267
  405. #define    K0C    268
  406. #define    K0D    269
  407. #define    K0E    270
  408. #define    K0F    271
  409. #define    K10    272
  410. #define    K11    273
  411. #define    K12    274
  412. #define    K13    275
  413. #define    K14    276
  414. #define    K15    277
  415. #define    K16    278
  416. #define    K17    279
  417. #define    K18    280
  418. #define    K19    281
  419. #define    K1A    282
  420. #define    K1B    283
  421. #define    K1C    284
  422. #define    K1D    285
  423. #define    K1E    286
  424. #define    K1F    287
  425. #endif
  426. SHAR_EOF
  427. cat << \SHAR_EOF > sys/default/cinfo.c
  428. /*
  429.  *        Character class tables.
  430.  * Do it yourself character classification
  431.  * macros, that understand the multinational character set,
  432.  * and let me ask some questions the standard macros (in
  433.  * ctype.h) don't let you ask.
  434.  */
  435. #include    "def.h"
  436.  
  437. /*
  438.  * This table, indexed by a character drawn
  439.  * from the 256 member character set, is used by my
  440.  * own character type macros to answer questions about the
  441.  * type of a character. It handles the full multinational
  442.  * character set, and lets me ask some questions that the
  443.  * standard "ctype" macros cannot ask.
  444.  */
  445. char    cinfo[256] = {
  446.     _C,        _C,        _C,        _C,    /* 0x0X */
  447.     _C,        _C,        _C,        _C,
  448.     _C,        _C,        _C,        _C,
  449.     _C,        _C,        _C,        _C,
  450.     _C,        _C,        _C,        _C,    /* 0x1X */
  451.     _C,        _C,        _C,        _C,
  452.     _C,        _C,        _C,        _C,
  453.     _C,        _C,        _C,        _C,
  454.     0,        _P,        0,        0,    /* 0x2X */
  455.     _W,        _W,        0,        _W,
  456.     0,        0,        0,        0,
  457.     0,        0,        _P,        0,
  458.     _D|_W,        _D|_W,        _D|_W,        _D|_W,    /* 0x3X */
  459.     _D|_W,        _D|_W,        _D|_W,        _D|_W,
  460.     _D|_W,        _D|_W,        0,        0,
  461.     0,        0,        0,        _P,
  462.     0,        _U|_W,        _U|_W,        _U|_W,    /* 0x4X */
  463.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  464.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  465.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  466.     _U|_W,        _U|_W,        _U|_W,        _U|_W,    /* 0x5X */
  467.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  468.     _U|_W,        _U|_W,        _U|_W,        0,
  469.     0,        0,        0,        0,
  470.     0,        _L|_W,        _L|_W,        _L|_W,    /* 0x6X */
  471.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  472.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  473.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  474.     _L|_W,        _L|_W,        _L|_W,        _L|_W,    /* 0x7X */
  475.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  476.     _L|_W,        _L|_W,        _L|_W,        0,
  477.     0,        0,        0,        _C,
  478.     0,        0,        0,        0,    /* 0x8X */
  479.     0,        0,        0,        0,
  480.     0,        0,        0,        0,
  481.     0,        0,        0,        0,
  482.     0,        0,        0,        0,    /* 0x9X */
  483.     0,        0,        0,        0,
  484.     0,        0,        0,        0,
  485.     0,        0,        0,        0,
  486.     0,        0,        0,        0,    /* 0xAX */
  487.     0,        0,        0,        0,
  488.     0,        0,        0,        0,
  489.     0,        0,        0,        0,
  490.     0,        0,        0,        0,    /* 0xBX */
  491.     0,        0,        0,        0,
  492.     0,        0,        0,        0,
  493.     0,        0,        0,        0,
  494.     _U|_W,        _U|_W,        _U|_W,        _U|_W,    /* 0xCX */
  495.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  496.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  497.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  498.     0,        _U|_W,        _U|_W,        _U|_W,    /* 0xDX */
  499.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  500.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  501.     _U|_W,        _U|_W,        0,        _W,
  502.     _L|_W,        _L|_W,        _L|_W,        _L|_W,    /* 0xEX */
  503.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  504.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  505.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  506.     0,        _L|_W,        _L|_W,        _L|_W,    /* 0xFX */
  507.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  508.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  509.     _L|_W,        _L|_W,        0,        0
  510. };
  511.  
  512. /*
  513.  * Find the name of a keystroke.  Needs to be changed to handle 8-bit printing
  514.  * characters and function keys better.     Returns a pointer to the terminating
  515.  * '\0'.
  516.  */
  517.  
  518. char *keyname(cp, k)
  519. register char *cp;
  520. register int k;
  521. {
  522.     register char *np;
  523. #ifdef    FKEYS
  524.     extern char *keystrings[];
  525. #endif
  526.  
  527.     if(k < 0) k = CHARMASK(k);            /* sign extended char */
  528.     switch(k) {
  529.     case CCHR('@'): np = "NUL"; break;
  530.     case CCHR('I'): np = "TAB"; break;
  531.     case CCHR('J'): np = "LFD"; break; /* yuck, but that's what GNU calls it */
  532.     case CCHR('M'): np = "RET"; break;
  533.     case CCHR('['): np = "ESC"; break;
  534.     case ' ':    np = "SPC"; break; /* yuck again */
  535.     case CCHR('?'): np = "DEL"; break;
  536.     default:
  537. #ifdef    FKEYS
  538.         if(k >= KFIRST && k <= KLAST &&
  539.             (np = keystrings[k - KFIRST]) != NULL)
  540.         break;
  541. #endif
  542.         if(k > CCHR('?')) {
  543.         *cp++ = '0';
  544.         *cp++ = ((k>>6)&7) + '0';
  545.         *cp++ = ((k>>3)&7) + '0';
  546.         *cp++ = (k&7) + '0';
  547.         *cp = '\0';
  548.         return cp;
  549.         }
  550.         if(k < ' ') {
  551.         *cp++ = 'C';
  552.         *cp++ = '-';
  553.         k = CCHR(k);
  554.         if(ISUPPER(k)) k = TOLOWER(k);
  555.         }
  556.         *cp++ = k;
  557.         *cp = '\0';
  558.         return cp;
  559.     }
  560.     (VOID) strcpy(cp, np);
  561.     return cp + strlen(cp);
  562. }
  563. SHAR_EOF
  564. cat << \SHAR_EOF > sys/default/tty.c
  565. /*
  566.  * Termcap/terminfo display driver
  567.  *
  568.  * Termcap is a terminal information database and routines to describe
  569.  * terminals on most UNIX systems.  Many other systems have adopted
  570.  * this as a reasonable way to allow for widly varying and ever changing
  571.  * varieties of terminal types.     This should be used where practical.
  572.  */
  573. /* Known problems:
  574.  *    If you have a terminal with no clear to end of screen and
  575.  *    memory of lines below the ones visible on the screen, display
  576.  *    will be wrong in some cases.  I doubt that any such terminal
  577.  *    was ever made, but I thought everyone with delete line would
  578.  *    have clear to end of screen too...
  579.  *
  580.  *    Code for terminals without clear to end of screen and/or clear
  581.  *    to end of line has not been extensivly tested.
  582.  *
  583.  *    Cost calculations are very rough.  Costs of insert/delete line
  584.  *    may be far from the truth.  This is accentuated by display.c
  585.  *    not knowing about multi-line insert/delete.
  586.  *
  587.  *    Using scrolling region vs insert/delete line should probably
  588.  *    be based on cost rather than the assuption that scrolling
  589.  *    region operations look better.
  590.  */
  591. #include    "def.h"
  592.  
  593. #define BEL    0x07            /* BEL character.        */
  594.  
  595. extern    int    ttrow;
  596. extern    int    ttcol;
  597. extern    int    tttop;
  598. extern    int    ttbot;
  599. extern    int    tthue;
  600.  
  601. int    tceeol;            /* Costs are set later */
  602. int    tcinsl;
  603. int    tcdell;
  604.  
  605. static    int    insdel;        /* Do we have both insert & delete line? */
  606.  
  607. #ifdef NO_RESIZE
  608. static    setttysize();
  609. #endif
  610.  
  611. char    *tgetstr();
  612. char    *tgoto();
  613. int    ttputc();
  614.  
  615. #define TCAPSLEN 1024
  616.  
  617. char tcapbuf[TCAPSLEN];
  618.  
  619. /* PC, UP, and BC are used by termlib, so must be extern and have these
  620.  * names unless you have a non-standard termlib.
  621.  */
  622.  
  623. int    LI;            /* standard # lines */
  624. char    PC,
  625.     *CM,
  626.     *CE,
  627.     *UP,
  628.     *BC,
  629.     *IM,            /* insert mode */
  630.     *IC,            /* insert a single space */
  631.     *EI,            /* end insert mode */
  632.     *DC,
  633.     *AL,            /* add line */
  634.     *DL,            /* del line */
  635.     *pAL,            /* parameterized add line */
  636.     *pDL,            /* parameterized delete line */
  637.     *TI,            /* term init -- start using cursor motion */
  638.     *TE,            /* term end --- end using cursor motion */
  639.     *SO,
  640.     *SE,
  641.     *CD,
  642.     *CS,            /* set scroll region            */
  643.     *SF,            /* forw index (used with scroll region)    */
  644.     *SR;            /* back index (used with scroll region)    */
  645. #ifdef    XKEYS
  646. char    *KS, *KE;        /* enter keypad mode, exit keypad mode    */
  647. #endif
  648. int    SG;    /* number of glitches, 0 for invisible, -1 for none    */
  649.     /* (yes virginia, there are terminals with invisible glitches)    */
  650.  
  651. /*
  652.  * Initialize the terminal when the editor
  653.  * gets started up.
  654.  */
  655. static char tcbuf[1024];
  656.  
  657. ttinit() {
  658.     char *tv_stype;
  659.     char *t, *p, *tgetstr();
  660. #ifndef gettermtype        /* (avoid declaration if #define) */
  661.     char *gettermtype();    /* system dependent function to determin terminal type */
  662. #endif
  663.  
  664.     if((tv_stype = gettermtype()) == NULL)
  665.         panic("Could not determine terminal type");
  666.     if((tgetent(tcbuf, tv_stype)) != 1) {
  667.         (VOID) strcpy(tcbuf, "Unknown terminal type ");
  668.         (VOID) strcat(tcbuf, tv_stype);
  669.         panic(tcbuf);
  670.     }
  671.  
  672.     p = tcapbuf;
  673.     t = tgetstr("pc", &p);
  674.     if(t) PC = *t;
  675.  
  676.     LI = tgetnum("li");
  677.     CD = tgetstr("cd", &p);
  678.     CM = tgetstr("cm", &p);
  679.     CE = tgetstr("ce", &p);
  680.     UP = tgetstr("up", &p);
  681.     BC = tgetstr("bc", &p);
  682.     IM = tgetstr("im", &p);
  683.     IC = tgetstr("ic", &p);
  684.     EI = tgetstr("ei", &p);
  685.     DC = tgetstr("dc", &p);
  686.     AL = tgetstr("al", &p);
  687.     DL = tgetstr("dl", &p);
  688.     pAL= tgetstr("AL", &p);    /* parameterized insert and del. line */
  689.     pDL= tgetstr("DL", &p);
  690.     TI = tgetstr("ti", &p);
  691.     TE = tgetstr("te", &p);
  692.     SO = tgetstr("so", &p);
  693.     SE = tgetstr("se", &p);
  694.     CS = tgetstr("cs", &p); /* set scrolling region */
  695.     SF = tgetstr("sf", &p);
  696.     if(!SF || !*SF) {    /* this is what GNU Emacs does */
  697.         SF = tgetstr("do", &p);
  698.         if(!SF || !*SF) {
  699.         SF = tgetstr("nl", &p);
  700.         if(!SF || !*SF) SF = "\n";
  701.         }
  702.     }
  703.     SR = tgetstr("sr", &p);
  704.     SG = tgetnum("sg");    /* standout glitch    */
  705. #ifdef    XKEYS
  706.     KS = tgetstr("ks", &p);    /* keypad start, keypad end    */
  707.     KE = tgetstr("ke", &p);
  708. #endif
  709.  
  710.     if(CM == NULL || UP == NULL)
  711.         panic("This terminal is to stupid to run MicroGnuEmacs\n");
  712.     ttresize();            /* set nrow & ncol    */
  713.  
  714.     /* watch out for empty capabilities (sure to be wrong)    */
  715.     if (CE && !*CE) CE = NULL;
  716.     if (CS && !*CS) CS = NULL;
  717.     if (SR && !*SR) SR = NULL;
  718.     if (AL && !*AL) AL = NULL;
  719.     if (DL && !*DL) DL = NULL;
  720.     if (pAL && !*pAL) pAL = NULL;
  721.     if (pDL && !*pDL) pDL = NULL;
  722.     if (CD && !*CD) CD = NULL;
  723.  
  724.     if(!CE) tceeol = ncol;
  725.     else    tceeol = charcost(CE);
  726.  
  727.     /* Estimate cost of inserting a line */
  728.     if (CS && SR)    tcinsl = charcost(CS)*2 + charcost(SR);
  729.     else if (pAL)    tcinsl = charcost(pAL);
  730.     else if (AL)    tcinsl = charcost(AL);
  731.     else        tcinsl = NROW * NCOL;    /* make this cost high enough */
  732.  
  733.     /* Estimate cost of deleting a line */
  734.     if (CS)        tcdell = charcost(CS)*2 + charcost(SF);
  735.     else if (pDL)    tcdell = charcost(pDL);
  736.     else if (DL)    tcdell = charcost(DL);
  737.     else        tcdell = NROW * NCOL;    /* make this cost high enough */
  738.  
  739.     /* Flag to indicate that we can both insert and delete lines */
  740.     insdel = (AL || pAL) && (DL || pDL);
  741.  
  742.     if (p >= &tcapbuf[TCAPSLEN])
  743.         panic("Terminal description too big!\n");
  744.     if (TI && *TI) putpad(TI, 1);    /* init the term */
  745. }
  746.  
  747. /*
  748.  * Clean up the terminal, in anticipation of
  749.  * a return to the command interpreter. This is a no-op
  750.  * on the ANSI display. On the SCALD display, it sets the
  751.  * window back to half screen scrolling. Perhaps it should
  752.  * query the display for the increment, and put it
  753.  * back to what it was.
  754.  */
  755. tttidy() {
  756.     if (TE && *TE) putpad(TE, 1);    /* set the term back to normal mode */
  757. #ifdef    XKEYS
  758.     ttykeymaptidy();
  759. #endif
  760. }
  761.  
  762. /*
  763.  * Move the cursor to the specified
  764.  * origin 0 row and column position. Try to
  765.  * optimize out extra moves; redisplay may
  766.  * have left the cursor in the right
  767.  * location last time!
  768.  */
  769. ttmove(row, col) {
  770.     char    *tgoto();
  771.  
  772.     if (ttrow!=row || ttcol!=col) {
  773.     putpad(tgoto(CM, col, row), 1);
  774.     ttrow = row;
  775.     ttcol = col;
  776.     }
  777. }
  778.  
  779. /*
  780.  * Erase to end of line.
  781.  */
  782. tteeol() {
  783.     if(CE) putpad(CE, 1);
  784.     else {
  785.     register int i=ncol-ttcol;
  786.     while(i--) ttputc(' ');
  787.     ttrow = ttcol = HUGE;
  788.     }
  789. }
  790.  
  791. /*
  792.  * Erase to end of page.
  793.  */
  794. tteeop() {
  795.     if(CD) putpad(CD, nrow - ttrow);
  796.     else {
  797.     putpad(CE, 1);
  798.     if (insdel) ttdell(ttrow + 1, LI, LI - ttrow - 1);
  799.     else {        /* do it by hand */
  800.         register int line;
  801.         for (line = ttrow + 1; line <= LI; ++line) {
  802.         ttmove(line, 0);
  803.         tteeol();
  804.         }
  805.     }
  806.     ttrow = ttcol = HUGE;
  807.     }
  808. }
  809.  
  810. /*
  811.  * Make a noise.
  812.  */
  813. ttbeep() {
  814.     ttputc(BEL);
  815.     ttflush();
  816. }
  817.  
  818. /*
  819.  * Insert nchunk blank line(s) onto the
  820.  * screen, scrolling the last line on the
  821.  * screen off the bottom.  Use the scrolling
  822.  * region if possible for a smoother display.
  823.  * If no scrolling region, use a set
  824.  * of insert and delete line sequences
  825.  */
  826. ttinsl(row, bot, nchunk) {
  827.     register int    i, nl;
  828.  
  829.     if (row == bot) {        /* Case of one line insert is    */
  830.     ttmove(row, 0);        /*    special            */
  831.     tteeol();
  832.     return;
  833.     }
  834.     if (CS && SR) {        /* Use scroll region and back index    */
  835.     nl = bot - row;
  836.     ttwindow(row,bot);
  837.     ttmove(row, 0);
  838.     while (nchunk--) putpad(SR, nl);
  839.     ttnowindow();
  840.     return;
  841.     } else if (insdel) {
  842.     ttmove(1+bot-nchunk, 0);
  843.     nl = nrow - ttrow;
  844.     if (pDL) putpad(tgoto(pDL, 0, nchunk), nl);
  845.     else for (i=0; i<nchunk; i++)    /* For all lines in the chunk    */
  846.         putpad(DL, nl);
  847.     ttmove(row, 0);
  848.     nl = nrow - ttrow;    /* ttmove() changes ttrow */
  849.     if (pAL) putpad(tgoto(pAL, 0, nchunk), nl);
  850.     else for (i=0; i<nchunk; i++)    /* For all lines in the chunk    */
  851.         putpad(AL, nl);
  852.     ttrow = HUGE;
  853.     ttcol = HUGE;
  854.     } else panic("ttinsl: Can't insert/delete line");
  855. }
  856.  
  857. /*
  858.  * Delete nchunk line(s) from "row", replacing the
  859.  * bottom line on the screen with a blank line.
  860.  * Unless we're using the scrolling region, this is
  861.  * done with a crafty sequences of insert and delete
  862.  * lines.  The presence of the echo area makes a
  863.  * boundry condition go away.
  864.  */
  865. ttdell(row, bot, nchunk)
  866. {
  867.     register int    i, nl;
  868.  
  869.     if (row == bot) {        /* One line special case    */
  870.     ttmove(row, 0);
  871.     tteeol();
  872.     return;
  873.     }
  874.     if (CS) {            /* scrolling region    */
  875.     nl = bot - row;
  876.     ttwindow(row, bot);
  877.     ttmove(bot, 0);
  878.     while (nchunk--) putpad(SF, nl);
  879.     ttnowindow();
  880.     }
  881.     else if(insdel) {
  882.     ttmove(row, 0);            /* Else use insert/delete line    */
  883.     nl = nrow - ttrow;
  884.     if (pDL) putpad(tgoto(pDL, 0, nchunk), nl);
  885.     else for (i=0; i<nchunk; i++)    /* For all lines in the chunk    */
  886.         putpad(DL, nl);
  887.     ttmove(1+bot-nchunk,0);
  888.     nl = nrow - ttrow;    /* ttmove() changes ttrow */
  889.     if (pAL) putpad(tgoto(pAL, 0, nchunk), nl);
  890.     else for (i=0; i<nchunk; i++)    /* For all lines in the chunk    */
  891.         putpad(AL, nl);
  892.     ttrow = HUGE;
  893.     ttcol = HUGE;
  894.     } else panic("ttdell: Can't insert/delete line");
  895. }
  896.  
  897. /*
  898.  * This routine sets the scrolling window
  899.  * on the display to go from line "top" to line
  900.  * "bot" (origin 0, inclusive). The caller checks
  901.  * for the pathalogical 1 line scroll window that
  902.  * doesn't work right, and avoids it. The "ttrow"
  903.  * and "ttcol" variables are set to a crazy value
  904.  * to ensure that the next call to "ttmove" does
  905.  * not turn into a no-op (the window adjustment
  906.  * moves the cursor).
  907.  *
  908.  */
  909. ttwindow(top, bot)
  910. {
  911.     if (CS && (tttop!=top || ttbot!=bot)) {
  912.         putpad(tgoto(CS, bot, top), nrow - ttrow);
  913.         ttrow = HUGE;            /* Unknown.        */
  914.         ttcol = HUGE;
  915.         tttop = top;            /* Remember region.    */
  916.         ttbot = bot;
  917.     }
  918. }
  919.  
  920. /*
  921.  * Switch to full screen scroll. This is
  922.  * used by "spawn.c" just before is suspends the
  923.  * editor, and by "display.c" when it is getting ready
  924.  * to exit.  This function gets to full screen scroll
  925.  * by telling the terminal to set a scrolling regin
  926.  * that is LI or nrow rows high, whichever is larger.
  927.  * This behavior seems to work right on systems
  928.  * where you can set your terminal size.
  929.  */
  930. ttnowindow()
  931. {
  932.     if (CS) {
  933.     putpad(tgoto(CS, (nrow > LI ? nrow : LI) - 1, 0), nrow - ttrow);
  934.     ttrow = HUGE;            /* Unknown.        */
  935.     ttcol = HUGE;
  936.     tttop = HUGE;            /* No scroll region.    */
  937.     ttbot = HUGE;
  938.     }
  939. }
  940.  
  941. /*
  942.  * Set the current writing color to the
  943.  * specified color. Watch for color changes that are
  944.  * not going to do anything (the color is already right)
  945.  * and don't send anything to the display.
  946.  * The rainbow version does this in putline.s on a
  947.  * line by line basis, so don't bother sending
  948.  * out the color shift.
  949.  */
  950. ttcolor(color) register int color; {
  951.     if (color != tthue) {
  952.     if (color == CTEXT) {        /* Normal video.    */
  953.         putpad(SE, 1);
  954.     } else if (color == CMODE) {    /* Reverse video.    */
  955.         putpad(SO, 1);
  956.     }
  957.     tthue = color;            /* Save the color.    */
  958.     }
  959. }
  960.  
  961. /*
  962.  * This routine is called by the
  963.  * "refresh the screen" command to try and resize
  964.  * the display. The new size, which must be deadstopped
  965.  * to not exceed the NROW and NCOL limits, it stored
  966.  * back into "nrow" and "ncol". Display can always deal
  967.  * with a screen NROW by NCOL. Look in "window.c" to
  968.  * see how the caller deals with a change.
  969.  */
  970. ttresize() {
  971.     setttysize();            /* found in "ttyio.c",    */
  972.                     /* ask OS for tty size    */
  973.     if (nrow < 1)            /* Check limits.    */
  974.         nrow = 1;
  975.     else if (nrow > NROW)
  976.         nrow = NROW;
  977.     if (ncol < 1)
  978.         ncol = 1;
  979.     else if (ncol > NCOL)
  980.         ncol = NCOL;
  981. }
  982.  
  983. #ifdef NO_RESIZE
  984. static setttysize() {
  985.     nrow = tgetnum("li");
  986.     ncol = tgetnum("co");
  987. }
  988. #endif
  989.  
  990. static int cci;
  991.  
  992. /*ARGSUSED*/
  993. static int        /* fake char output for charcost() */
  994. fakec(c)
  995. char c;
  996. {
  997.     cci++;
  998. }
  999.  
  1000. /* calculate the cost of doing string s */
  1001. charcost (s) char *s; {
  1002.     cci = 0;
  1003.  
  1004.     tputs(s, nrow, fakec);
  1005.     return cci;
  1006. }
  1007. SHAR_EOF
  1008. cat << \SHAR_EOF > sys/default/ttydef.h
  1009. /*
  1010.  *    Termcap terminal file, nothing special, just make it big
  1011.  *    enough for windowing systems.
  1012.  */
  1013.  
  1014. #define GOSLING            /* Compile in fancy display.    */
  1015. /* #define    MEMMAP        */    /* Not memory mapped video.    */
  1016.  
  1017. #define NROW    66            /* (maximum) Rows.        */
  1018. #define NCOL    132            /* (maximum) Columns.        */
  1019. /* #define    MOVE_STANDOUT        /* don't move in standout mode    */
  1020. #define STANDOUT_GLITCH            /* possible standout glitch    */
  1021. #define TERMCAP                /* for possible use in ttyio.c    */
  1022.  
  1023. #define getkbd()    (ttgetc())
  1024.  
  1025. #ifndef XKEYS
  1026. #define ttykeymapinit() {}
  1027. #endif
  1028.  
  1029. extern    int tputs();
  1030. #define    putpad(str, num)    tputs(str, num, ttputc)
  1031.  
  1032. #define    KFIRST    K00
  1033. #define    KLAST    K00
  1034. SHAR_EOF
  1035. cat << \SHAR_EOF > sys/default/ttykbd.c
  1036. /*
  1037.  * Name:    MG 2a
  1038.  *        Termcap keyboard driver using key files
  1039.  * Created:    22-Nov-1987 Mic Kaczmarczik (mic@emx.cc.utexas.edu)
  1040.  */
  1041.  
  1042. #include    "def.h"
  1043. #ifdef    XKEYS
  1044.  
  1045. /*
  1046.  * Get keyboard character.  Very simple if you use keymaps and keys files.
  1047.  * Bob was right -- the old XKEYS code is not the right solution.
  1048.  * FKEYS code is not usefull other than to help debug FKEYS code in
  1049.  * extend.c.
  1050.  */
  1051.  
  1052. #ifdef FKEYS
  1053. char    *keystrings[] = { NULL } ;
  1054. #endif
  1055.  
  1056. /*
  1057.  * Turn on function keys using KS, then load a keys file, if available.
  1058.  * The keys file is located in the same manner as the startup file is,
  1059.  * depending on what startupfile() does on your system.
  1060.  */
  1061. extern    int    ttputc();
  1062.  
  1063. ttykeymapinit()
  1064. {
  1065.     extern    char *KS;
  1066. #ifndef    NO_STARTUP
  1067.     char *cp, *startupfile();
  1068.  
  1069.     if (cp = gettermtype()) {
  1070.         if (((cp = startupfile(cp)) != NULL)
  1071.             && (load(cp) != TRUE))
  1072.             ewprintf("Error reading key initialization file");
  1073.     }
  1074. #endif
  1075.     if (KS && *KS)            /* turn on keypad    */
  1076.         putpad(KS, 1);
  1077. }
  1078.  
  1079. /*
  1080.  * Clean up the keyboard -- called by tttidy()
  1081.  */
  1082. ttykeymaptidy()
  1083. {
  1084.     extern    char *KE;
  1085.  
  1086.     if (KE && *KE)
  1087.         putpad(KE, 1);    /* turn off keypad        */
  1088. }
  1089.  
  1090. #endif
  1091. SHAR_EOF
  1092. cat << \SHAR_EOF > sys/default/varargs.h
  1093. /* varargs.h for MicroGnuEmacs 2a.  This one will work on systems that    */
  1094. /* the non-varargs version of mg 1 did.                    */
  1095. /* based on the one I wrote for os9/68k .  I did not look at the bsd code. */
  1096.  
  1097. /* by Robert A. Larson */
  1098.  
  1099. /* assumptions made about how arguments are passed:            */
  1100. /*    arguments are stored in a block of memory with no padding between. */
  1101. /*    The first argument will have the lowest address            */
  1102.  
  1103. /* varargs is a "portable" way to write a routine that takes a variable */
  1104. /* number of arguements.  This implemination agrees with both the 4.2bsd*/
  1105. /* and Sys V documentation of varargs.  Note that just because varargs.h*/
  1106. /* is used does not mean that it is used properly.            */
  1107.  
  1108. #define va_dcl        unsigned va_alist;
  1109.  
  1110. typedef    char *va_list;
  1111.  
  1112. #define    va_start(pvar)        ((pvar) = (char *)&va_alist)
  1113.  
  1114. #define va_arg(pvar,type)    (((pvar)+=sizeof(type)),*(((type *)(pvar)) - 1))
  1115.  
  1116. #define va_end(pvar)        /* va_end is simple */
  1117. SHAR_EOF
  1118. cat << \SHAR_EOF > sys/prime/cinfo.c
  1119. /*
  1120.  *        Character class tables.
  1121.  * Do it yourself character classification
  1122.  * macros, that understand the multinational character set,
  1123.  * and let me ask some questions the standard macros (in
  1124.  * ctype.h) don't let you ask.
  1125.  *
  1126.  * primos specific version
  1127.  */
  1128. #include    "def.h"
  1129.  
  1130. /*
  1131.  * This table, indexed by a character drawn
  1132.  * from the 256 member character set, is used by my
  1133.  * own character type macros to answer questions about the
  1134.  * type of a character. It handles the full multinational
  1135.  * character set, and lets me ask some questions that the
  1136.  * standard "ctype" macros cannot ask.
  1137.  */
  1138. char    cinfo[256] = {
  1139.     _C,        _C,        _C,        _C,    /* 0x0X */
  1140.     _C,        _C,        _C,        _C,
  1141.     _C,        _C,        _C,        _C,
  1142.     _C,        _C,        _C,        _C,
  1143.     _C,        _C,        _C,        _C,    /* 0x1X */
  1144.     _C,        _C,        _C,        _C,
  1145.     _C,        _C,        _C,        _C,
  1146.     _C,        _C,        _C,        _C,
  1147.     0,        _P,        0,        0,    /* 0x2X */
  1148.     _W,        _W,        0,        _W,
  1149.     0,        0,        0,        0,
  1150.     0,        0,        _P,        0,
  1151.     _D|_W,        _D|_W,        _D|_W,        _D|_W,    /* 0x3X */
  1152.     _D|_W,        _D|_W,        _D|_W,        _D|_W,
  1153.     _D|_W,        _D|_W,        0,        0,
  1154.     0,        0,        0,        _P,
  1155.     0,        _U|_W,        _U|_W,        _U|_W,    /* 0x4X */
  1156.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  1157.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  1158.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  1159.     _U|_W,        _U|_W,        _U|_W,        _U|_W,    /* 0x5X */
  1160.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  1161.     _U|_W,        _U|_W,        _U|_W,        0,
  1162.     0,        0,        0,        0,
  1163.     0,        _L|_W,        _L|_W,        _L|_W,    /* 0x6X */
  1164.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  1165.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  1166.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  1167.     _L|_W,        _L|_W,        _L|_W,        _L|_W,    /* 0x7X */
  1168.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  1169.     _L|_W,        _L|_W,        _L|_W,        0,
  1170.     0,        0,        0,        _C,
  1171.     _C,        _C,        _C,        _C,    /* 0x8X */
  1172.     _C,        _C,        _C,        _C,
  1173.     _C,        _C,        _C,        _C,
  1174.     _C,        _C,        _C,        _C,
  1175.     _C,        _C,        _C,        _C,    /* 0x9X */
  1176.     _C,        _C,        _C,        _C,
  1177.     _C,        _C,        _C,        _C,
  1178.     _C,        _C,        _C,        _C,
  1179.     0,        _P,        0,        0,    /* 0xAX */
  1180.     _W,        _W,        0,        _W,
  1181.     0,        0,        0,        0,
  1182.     0,        0,        _P,        0,
  1183.     _D|_W,        _D|_W,        _D|_W,        _D|_W,    /* 0xbX */
  1184.     _D|_W,        _D|_W,        _D|_W,        _D|_W,
  1185.     _D|_W,        _D|_W,        0,        0,
  1186.     0,        0,        0,        _P,
  1187.     0,        _U|_W,        _U|_W,        _U|_W,    /* 0xCX */
  1188.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  1189.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  1190.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  1191.     _U|_W,        _U|_W,        _U|_W,        _U|_W,    /* 0xDX */
  1192.     _U|_W,        _U|_W,        _U|_W,        _U|_W,
  1193.     _U|_W,        _U|_W,        _U|_W,        0,
  1194.     0,        0,        0,        0,
  1195.     0,        _L|_W,        _L|_W,        _L|_W,    /* 0xEX */
  1196.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  1197.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  1198.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  1199.     _L|_W,        _L|_W,        _L|_W,        _L|_W,    /* 0xFX */
  1200.     _L|_W,        _L|_W,        _L|_W,        _L|_W,
  1201.     _L|_W,        _L|_W,        _L|_W,        0,
  1202.     0,        0,        0,        _C,
  1203. };
  1204.  
  1205. /*
  1206.  * Find the name of a keystroke.  Needs to be changed to handle 8-bit printing
  1207.  * characters and function keys better.     Returns a pointer to the terminating
  1208.  * '\0'.
  1209.  */
  1210.  
  1211. char *keyname(cp, k)
  1212. register char *cp;
  1213. register int k;
  1214. {
  1215.     register char *np;
  1216. #ifdef    FKEYS
  1217.     extern char *keystrings[];
  1218. #endif
  1219.  
  1220.     if(k < 0) k = CHARMASK(k);            /* sign extended char */
  1221.     switch(k) {
  1222.     case CCHR('@'): np = "NUL"; break;
  1223.     case CCHR('I'): np = "TAB"; break;
  1224.     case CCHR('J'): np = "LFD"; break; /* yuck, but that's what GNU calls it */
  1225.     case CCHR('M'): np = "RET"; break;
  1226.     case CCHR('['): np = "ESC"; break;
  1227.     case ' ':    np = "SPC"; break; /* yuck again */
  1228.     case CCHR('?'): np = "DEL"; break;
  1229.     default:
  1230. #ifdef    FKEYS
  1231.         if(k >= KFIRST && k <= KLAST &&
  1232.             (np = keystrings[k - KFIRST]) != NULL)
  1233.         break;
  1234. #endif
  1235.         if(k < CCHR('@')) {
  1236.         *cp++ = '0';
  1237.         *cp++ = ((k>>6)&7) + '0';
  1238.         *cp++ = ((k>>3)&7) + '0';
  1239.         *cp++ = (k&7) + '0';
  1240.         *cp = '\0';
  1241.         return cp;
  1242.         }
  1243.         if(k < ' ') {
  1244.         *cp++ = 'C';
  1245.         *cp++ = '-';
  1246.         k = CCHR(k);
  1247.         if(ISUPPER(k)) k = TOLOWER(k);
  1248.         }
  1249.         *cp++ = k;
  1250.         *cp = '\0';
  1251.         return cp;
  1252.     }
  1253.     (VOID) strcpy(cp, np);
  1254.     return cp + strlen(cp);
  1255. }
  1256. SHAR_EOF
  1257. cat << \SHAR_EOF > sys/prime/fileio.c
  1258. /*
  1259.  * Prime fileio.c for MicroGnuEmacs by Robert A. Larson
  1260.  *    system dependent file io routines
  1261.  *
  1262.  * Prime keeps the parity bit of every character set, as does mg 2a for primos.
  1263.  */
  1264. #include <errd.ins.cc>
  1265. #include <keys.ins.cc>
  1266. #include "def.h"
  1267.  
  1268. static FILE    *ffp;
  1269. char *index(), *rindex();
  1270. fortran void cnam$$(), at$(), at$abs(), at$any(), at$hom(), clo$fu();
  1271. fortran void gpath$(), dir$se(), cv$fdv();
  1272. fortran long srsfx$();
  1273.  
  1274. /*
  1275.  * Open a file for reading.
  1276.  */
  1277. ffropen(fn)
  1278. char   *fn;
  1279. {
  1280.     if ((ffp=fopen(fn, "r")) == NULL)
  1281.         return (FIOFNF);
  1282.     return (FIOSUC);
  1283. }
  1284.  
  1285. /*
  1286.  * Open a file for writing.
  1287.  * Return TRUE if all is well, and
  1288.  * FALSE on error (cannot create).
  1289.  */
  1290. ffwopen(fn)
  1291. char    *fn;
  1292. {
  1293.     short unit, type, sfu, code;
  1294.     struct {short len; char data[128];} fnb;
  1295.     register char *cp = &fnb.data[0];
  1296.     struct {short len; char data[32];} basename;
  1297.  
  1298.     /* most of this is to get a SAM rather than DAM file ... */
  1299.     (void) strcpy(fnb.data, fn);
  1300.     fnb.len = strlen(fnb.data);
  1301.     (void) srsfx$((short)(k$writ+k$getu+k$nsam), fnb, unit, type,
  1302.         (short)0, (short)0, basename, sfu, code);
  1303. #ifdef OPEN_BUG
  1304.     if(code==0) {
  1305.         clo$fu(unit, code);
  1306.         fnb.data[fnb.len] = '\0';
  1307.         if((ffp=fopen(fnb.data, "w"))!=NULL) return FIOSUC;
  1308.     }
  1309.     ewprintf("Cannot open file for writing");
  1310.     return FIOERR;
  1311. #else
  1312.     if (code != 0 || (ffp=fdopen(open("", -2, unit), "w")) == NULL) {
  1313.         ewprintf("Cannot open file for writing");
  1314.         if(code==0) clo$fu(unit, code);
  1315.         return (FIOERR);
  1316.     }
  1317.     return (FIOSUC);
  1318. #endif
  1319. }
  1320.  
  1321. /*
  1322.  * Close a file.
  1323.  * Should look at the status.
  1324.  */
  1325. ffclose()
  1326. {
  1327.     fclose(ffp);
  1328.     return (FIOSUC);
  1329. }
  1330.  
  1331. /*
  1332.  * Write a buffer to the already
  1333.  * opened file. bp points to the
  1334.  * buffer. Return the status.
  1335.  * Check only at the newline and
  1336.  * end of buffer.
  1337.  */
  1338. ffputbuf(bp)
  1339. BUFFER *bp;
  1340. {
  1341.     register char *cp;
  1342.     register char *cpend;
  1343.     register LINE *lp;
  1344.     register LINE *lpend;
  1345.  
  1346.     lpend = bp->b_linep;
  1347.     lp = lforw(lpend);
  1348.     do {
  1349.     cp = <ext(lp)[0];        /* begining of line    */
  1350.     cpend = &cp[llength(lp)];    /* end of line        */
  1351.     while(cp != cpend) {
  1352.         putc(*cp, ffp);
  1353.         cp++;    /* putc may evalualte arguments more than once */
  1354.     }
  1355.     lp = lforw(lp);
  1356.     if(lp == lpend) break;        /* no implied newline on last line */
  1357.     putc('\n', ffp);
  1358.     } while(!ferror(ffp));
  1359.     if(ferror(ffp)) {
  1360.     ewprintf("Write I/O error");
  1361.     return FIOERR;
  1362.     }
  1363.     return FIOSUC;
  1364. }
  1365.  
  1366. /*
  1367.  * Read a line from a file, and store the bytes
  1368.  * in the supplied buffer. Stop on end of file or end of
  1369.  * line.  When FIOEOF is returned, there is a valid line
  1370.  * of data without the normally implied \n.
  1371.  */
  1372. ffgetline(buf, nbuf, nbytes)
  1373. register char    *buf;
  1374. register int    nbuf;
  1375. register int    *nbytes;
  1376. {
  1377.     register int    c;
  1378.     register int    i;
  1379.  
  1380.     i = 0;
  1381.     while((c = getc(ffp))!=EOF && c!='\n') {
  1382.         buf[i++] = c;
  1383.         if (i >= nbuf) return FIOLONG;
  1384.     }
  1385.     if (c == EOF  && ferror(ffp) != FALSE) {
  1386.         ewprintf("File read error");
  1387.         return FIOERR;
  1388.     }
  1389.     *nbytes = i;
  1390.     return c==EOF ? FIOEOF : FIOSUC;
  1391. }
  1392.  
  1393. #ifndef NO_BACKUP
  1394. /*
  1395.  * Rename the file "fname" into a backup copy.
  1396.  */
  1397. fbackupfile(fname)
  1398. char   *fname;
  1399. {
  1400.     struct {short len; char data[128];} back;
  1401.     struct {short len; char data[32];} ent;
  1402.     register char *cp;
  1403.     short code = 0, i;
  1404.  
  1405.     strcpy(back.data, fname);
  1406.     strcat(back.data, ".BAK");
  1407.     (void) delete(back.data);
  1408.     if((cp = rindex(back.data, '>'))!=NULL) {
  1409.     if(back.data[0]==('<') && index(back.data, '>')==cp) {
  1410.         strncpy(ent.data, back.data+1, ent.len = (cp - back.data) - 1);
  1411.         at$abs((short)k$setc, ent, (short)0, code);
  1412.     } else {
  1413.         back.len = (cp - back.data);
  1414.         if(index(back.data, '>') == cp)
  1415.          at$any((short)k$setc, back, code);
  1416.         else at$((short)k$setc, back, code);
  1417.     }
  1418.     if(code) return FALSE;
  1419.     cp++;
  1420.     /* cnam$$ needs word aligned strings */
  1421.     strncpy(ent.data, cp, back.len = strlen(cp));
  1422.     cp = ent.data;
  1423.     } else back.len = strlen(cp = back.data);
  1424.     cnam$$((char [])cp, (short)(back.len - 4), (char [])cp, back.len, code);
  1425.     at$hom(i);
  1426.     return code == 0;
  1427. }
  1428. #endif
  1429.  
  1430. /*
  1431.  * The string "fn" is a file name.  Prepend the directory name if
  1432.  * it's relative to the current directory.
  1433.  */
  1434. #ifndef NO_DIR
  1435. extern char *wdir;
  1436. #endif
  1437.  
  1438. char *adjustname(fn)
  1439. register char  *fn;
  1440. {
  1441.     static char fnb[NFILEN];
  1442.     register char *cp = fnb;
  1443.     register char *cp2;
  1444.  
  1445. #ifndef NO_DIR
  1446.     if((fn[0] == '*' && fn[1] == '>') || index(fn, '>')==NULL) {
  1447.     cp2 = wdir;
  1448.     while(*cp2) {
  1449.         *cp = *cp2;
  1450.         cp++;
  1451.         cp2++;
  1452.     }
  1453.     *cp++ = '>';
  1454.     if(fn[1]=='>') fn+=2;
  1455.     }
  1456. #endif
  1457.     while(*fn) {
  1458.     *cp = ISUPPER(*fn) ? TOLOWER(*fn) : *fn;
  1459.     cp++;
  1460.     fn++;
  1461.     }
  1462.     *cp = '\0';
  1463.     return fnb;
  1464. }
  1465.  
  1466. #ifndef NO_STARTUP
  1467. char *startupfile(suffix)
  1468. char *suffix;
  1469. {
  1470.     short code, len;
  1471.     static char startname[128];
  1472.     register char *cp;
  1473.  
  1474.     gpath$((short)k$inia, (short)-3, (char [])startname,
  1475.           (short)(128 - 5), len, code);
  1476.     if (code==0) {
  1477.         strcpy(startname + len, ">.MG");
  1478.         if(suffix) {
  1479.         startname[len+4] = '.';
  1480.         strcpy(startname + len + 5, suffix);
  1481.         }
  1482.         if(access(startname, 4)==0)
  1483.         return startname;
  1484.     }
  1485.     strcpy(startname, "MG*>.MG");
  1486.     if(suffix) {
  1487.         startname[7] = '.';
  1488.         strcpy(startname+8, suffix);
  1489.     }
  1490.     if(access(startname, 4)==0)
  1491.         return startname;
  1492.     return (char *)NULL;
  1493. }
  1494. #endif
  1495.  
  1496. /* compare file names */
  1497. fncmp(fn1, fn2)
  1498. register char *fn1, *fn2;
  1499. {
  1500.     /* ignore disk name if on one but not the other */
  1501.     if(*fn1 != *fn2) {
  1502.     if(*fn1 == '<') {
  1503.         fn1 = index(fn1, '>');
  1504.         if(fn1 == NULL) return -1;
  1505.         fn1++;
  1506.     } else if(*fn2 == '<') {
  1507.         fn2 = index(fn2, '>');
  1508.         if(fn2 == NULL) return -1;
  1509.         fn2++;
  1510.     } else return -1;
  1511.     } else fn1++, fn2++;
  1512.     /* compare ignoring case */
  1513.     while(*fn1) {
  1514.     if((*fn1 != *fn2) && (!ISUPPER(*fn1) || (TOLOWER(*fn1) == *fn2))
  1515.               && (!ISUPPER(*fn2) || (TOLOWER(*fn2) == *fn1)))
  1516.         return -1;
  1517.     fn1++;
  1518.     fn2++;
  1519.     }
  1520.     return *fn2;
  1521. }
  1522.  
  1523. #ifndef NO_DIRED
  1524. #include "kbd.h"
  1525.  
  1526. BUFFER *dired_(dirname)
  1527. char *dirname;
  1528. {
  1529.     register BUFFER *bp;
  1530.     LINE *lp, *blp;
  1531.     BUFFER *findbuffer();
  1532.     short dirunit, j, code, type, init, counts[4], i, nent;
  1533.     struct {short len; char dat[128];} dir;
  1534.     struct ent {short len; char dat[32];} base;
  1535.     static struct ent wild[1] = {{2, {'@','@'}}};
  1536.     static struct {
  1537.     short vers;
  1538.     struct ent *wp;
  1539.     short count;
  1540.     struct {unsigned dirs:1, seg_dirs:1, files:1, acats:1, rbf:1, spare:11;} desired;
  1541.     long mb, ma, bb, ba, cb, ca, ab, aa;
  1542.     } sel = {
  1543.     1,
  1544.     &wild[0],
  1545.     1,
  1546.     {1, 1, 1, 0, 0, 0},
  1547.     0, 0, 0, 0, 0, 0, 0, 0,
  1548.     }, *s = &sel;
  1549. #define MAXSE 16
  1550.     struct {
  1551.     struct {unsigned type:8, length:8;} ecw;
  1552.     struct ent name;
  1553.     struct {unsigned spare:5, odel:1, owrite:1, oread:1, delp:1,
  1554.         spare2:4, nodel:1, nowrite:1, noread:1;} prot;
  1555.     struct {unsigned lrat:1, dumped:1, dos:1, spec:1, rwl: 2,
  1556.         spare:2, type:8;} info;
  1557.     long dtm;
  1558.     short nondefault, logical_type, trunc;
  1559.     long dtb, dtc, dta;
  1560.     } ret[MAXSE], *r = &ret[0];
  1561.     static char *types[] = {"SAM", "DAM", "SEGSAM", "SEGDAM", "UFD",
  1562.     "ACAT", "CAM"};
  1563.     static char *rwlock[] = {"sys", "excl", "updt", "none"};
  1564.  
  1565.     if((dirname = adjustname(dirname)) == NULL) {
  1566.     ewprintf("Bad directory name");
  1567.     return NULL;
  1568.     }
  1569.     (void) strncpy(dir.dat, dirname, dir.len = strlen(dirname));
  1570.     if(dir.dat[dir.len-1]=='>') dir.len--;
  1571.     else strcat(dirname, ">");
  1572.     if((bp = findbuffer(dirname)) == NULL) {
  1573.     ewprintf("Could not create directory buffer");
  1574.     return NULL;
  1575.     }
  1576.     if(bclear(bp) != TRUE) return NULL;
  1577.     (void) srsfx$((short)(k$read+k$getu), dir, dirunit, type,
  1578.     (short)0, (short)0, base, j, code);
  1579.     if(code!=0) {
  1580.     ewprintf("Could not open directory '%s'", dirname);
  1581.     return NULL;
  1582.     }
  1583.     if(type<2 || type > 4) {
  1584.     clo$fu(dirunit, code);
  1585.     ewprintf("Not a directory '%s'", dirname);
  1586.     return NULL;
  1587.     }
  1588.     for(init = 0x8000; ; init = 0) {
  1589.     dir$se(dirunit, type, init, s, r, (short)MAXSE,
  1590.         (short)((sizeof ret[0])/2), nent, (short [])counts, (short)4, code);
  1591.     if(code!=0 && (code!=e$eof || nent==0)) break;
  1592.     for(i=0; i < nent; i++) {
  1593.         cv$fdv(ret[i].dtm, j, base);
  1594.         for(j=0; j<ret[i].name.len; j++)
  1595.         if(ISUPPER(ret[i].name.dat[j]))
  1596.             ret[i].name.dat[j] = TOLOWER(ret[i].name.dat[j]);
  1597. #define D_FILEPOS 36
  1598.         if((lp = lalloc(D_FILEPOS + 1 + ret[i].name.len)) != NULL) {
  1599.         sprintf(lp->l_text, "  %-6s  %-4s  %.18s  %.*s",
  1600.             types[ret[i].info.type], rwlock[ret[i].info.rwl],
  1601.             base.dat, ret[i].name.len, ret[i].name.dat);
  1602.         llength(lp)--;
  1603.         for(blp=bp->b_linep->l_fp; blp!=bp->b_linep; blp=blp->l_fp) {
  1604.             j = strncmp(ret[i].name.dat, &blp->l_text[D_FILEPOS],
  1605.             ret[i].name.len);
  1606.             if(j < 0 || (j==0 && ret[i].name.len <=
  1607.             llength(blp)-D_FILEPOS)) break;
  1608.         }
  1609.         lp->l_fp = blp;
  1610.         lp->l_bp = blp->l_bp;
  1611.         blp->l_bp = lp;
  1612.         lp->l_bp->l_fp = lp;
  1613.         } else {
  1614.         clo$fu(dirunit, code);
  1615.         return NULL;
  1616.         }
  1617.     }
  1618.     }
  1619.     if(code!=e$eof) ewprintf("Directory read error %d", code);
  1620.     clo$fu(dirunit, code);
  1621.     bp->b_dotp = lforw(bp->b_linep);
  1622.     bp->b_doto = 0;
  1623.     bp->b_markp = NULL;
  1624.     strncpy(bp->b_fname, dirname, NFILEN);
  1625.     if((bp->b_modes[0] = name_mode("dired")) == NULL) {
  1626.     bp->b_modes[0] = &map_table[0];
  1627.     ewprintf("Could not find mode dired");
  1628.     return NULL;
  1629.     }
  1630.     bp->b_nmodes = 0;
  1631.     return bp;
  1632. }
  1633.  
  1634. d_makename(lp, fn)
  1635. register LINE *lp;
  1636. register char *fn;
  1637. {
  1638.     register char *cp;
  1639.  
  1640.     if(llength(lp) <= D_FILEPOS) return ABORT;
  1641.     (VOID) strcpy(fn, curbp->b_fname);
  1642.     cp = fn + strlen(fn);
  1643.     bcopy(&lp->l_text[D_FILEPOS], cp, llength(lp) - D_FILEPOS);
  1644.     cp[llength(lp) - D_FILEPOS] = '\0';
  1645.     return strncmp(&lp->l_text[2], "UFD", 3)==0 ||
  1646.     strncmp(&lp->l_text[2], "SEG", 3)==0;
  1647. }
  1648.  
  1649. rename(old, new)
  1650. char *old, *new;
  1651. {
  1652.     struct {short len; char dat[128];} f;
  1653.     struct {short len; char dat[32];} oldent;
  1654.     char *cp;
  1655.     short code;
  1656.  
  1657.     old = adjustname(old);
  1658.     cp = rindex(old, '>');
  1659.     strncpy(f.dat, old, f.len = cp - old);
  1660.     at$((short)k$setc, f, code);
  1661.     if(code!=0) return -1;
  1662.     cp++;
  1663.     strncpy(oldent.dat, cp, oldent.len = strlen(cp));
  1664.     strncpy(f.dat, new, f.len = strlen(new));
  1665.     cnam$$((char [])oldent.dat, oldent.len, (char [])f.dat, f.len, code);
  1666.     if(code!=0) {
  1667.     at$hom(code);
  1668.     return -1;
  1669.     }
  1670.     at$hom(code);
  1671.     return 0;
  1672. }
  1673. #endif
  1674.  
  1675. #ifndef NO_DIR
  1676. char *getwd(cwd)
  1677. char *cwd;
  1678. {
  1679.     char homedir[128];         /* cwd may not be word alligned */
  1680.     short len, code;
  1681.     register char *cp1, *cp2;
  1682.  
  1683.     gpath$((short)k$homa, (short)-2, (char [])homedir, (short)128, len, code);
  1684.     if(code!=0) return NULL;
  1685.     cp1 = cwd;
  1686.     cp2 = homedir;
  1687.     while(len--) {
  1688.     *cp1 = ISUPPER(*cp2) ? TOLOWER(*cp2) : *cp2;
  1689.     cp1++;
  1690.     cp2++;
  1691.     }
  1692.     *cp1 = '\0';
  1693.     return cwd;
  1694. }
  1695. #endif
  1696. SHAR_EOF
  1697. cat << \SHAR_EOF > sys/prime/make.cpl
  1698. /* make for micrognuemacs on primos
  1699. /* by Robert A. Larson
  1700. &args como:-como; ph:-ph; v64v: -64v;
  1701. &if ^ [null %como%] &then como make.como
  1702. &if ^ [null %ph%] &then &do
  1703.   chap idle
  1704. &end
  1705. &do f &list *>sys>prime>sysdef.h *>sys>default>ttydef.h *>sys>default>chrdef.h
  1706.   &if ^ [exists [entryname %f%]] &then copy %f% -rpt
  1707.   &else &if [attrib [entryname %f%] -dtm] < [attrib %f% -dtm] ~
  1708.     &then copy %f% -nq -rpt
  1709. &end
  1710. &set_var w := [attrib def.h -dtm]
  1711. &if %w% < [attrib sysdef.h -dtm] &then &set_var w := [attrib sysdef.h -dtm]
  1712. &if %w% < [attrib ttydef.h -dtm] &then &set_var w := [attrib ttydef.h -dtm]
  1713. &if %w% < [attrib chrdef.h -dtm] &then &set_var w := [attrib chrdef.h -dtm]
  1714. &if [null %v64v%] &then &do
  1715.   &if %w% < [attrib *>sys>prime>mg.options.c -dtm] ~
  1716.     &then &set_var w := [attrib *>sys>prime>mg.options.c -dtm]
  1717.   &set_var binext := .bin
  1718. &end
  1719. &else &do
  1720.   &if %w% < [attrib *>sys>prime>mg.64v.options.c -dtm] ~
  1721.     &then &set_var w := [attrib *>sys>prime>mg.64v.options.c -dtm]
  1722.   &set_var binext := .64v.bin
  1723.   &set_var m := ^ [exists stackptr$.64v.bin]
  1724.   &if ^ %m% &then &do
  1725.     &set_var bw := [attrib stackptr$.64v.bin -dtm]
  1726.     &set_var m := [attrib *>sys>prime>stackptr$.pma -dtm] > %bw% | %w% > %bw%
  1727.   &end
  1728.   &if %m% &then pma *>sys>prime>stackptr$.pma -list no -bin stackptr$.64v.bin
  1729. &end
  1730. &s dir := *
  1731. &do f &list basic.c buffer.c dir.c dired.c display.c echo.c extend.c file.c ~
  1732.     help.c kbd.c keymap.c line.c macro.c main.c match.c modes.c paragraph.c ~
  1733.     random.c region.c search.c version.c window.c word.c
  1734.   &call compile
  1735. &end
  1736. &s dir := *>sys>prime
  1737. &do f &list cinfo.c fileio.c spawn.c ttyio.c
  1738.   &call compile
  1739. &end
  1740. &s dir := *>sys>default
  1741. &do f &list tty.c
  1742.   &call compile
  1743. &end
  1744. &s dir := *>termlib
  1745. &do f &list fgetlr.c tgetent.c tgetflag.c tgetnum.c tgetstr.c tgoto.c tputs.c
  1746.   &call compile
  1747. &end
  1748. date
  1749. time
  1750. &set_var u := 0
  1751. &data bind
  1752.   version mg 2a
  1753.   no_wildcard
  1754.   no_iteration
  1755.   li ccmain
  1756.   &do f &items [wild @%binext% -single u]
  1757.     lo %f%
  1758.   &end
  1759.   li c_lib
  1760.   li
  1761.   dynt -all
  1762.   rdc
  1763.   &if [null %v64v%] &then &do
  1764.     map mg.map
  1765.     file mg.run
  1766.   &end
  1767.   &else &do
  1768.     map mg.64v.map
  1769.     file mg.64v.run
  1770.   &end
  1771. &end
  1772. date
  1773. time
  1774. &if ^ [null %como%] &then como -end
  1775. &return
  1776.  
  1777. &routine compile
  1778.       &set_var b := [before %f% '.']%binext%
  1779.       &set_var f := %dir%>%f%
  1780.       &set_var m := ^ [exists %b%]
  1781.       &if ^ %m% &then &do             /* avoid attrib on non-existant file
  1782.         &set_var bw := [attrib %b% -dtm]
  1783.         &set_var m := [attrib %f% -dtm] > %bw% | %w% > %bw%
  1784.       &end
  1785.       &if %m% &then &do
  1786.         type %f%
  1787.         date
  1788.         &if [null %v64v%] &then &do
  1789.           ci %f% -optionsfile *>sys>prime>mg.options.c -bin %b%
  1790.         &end
  1791.         &else &do
  1792.           cc %f% -optionsfile *>sys>prime>mg.64v.options.c -bin %b%
  1793.         &end
  1794.       &end
  1795. &return
  1796.  
  1797.  
  1798. SHAR_EOF
  1799. cat << \SHAR_EOF > sys/prime/mg.64v.options.c
  1800. /* options for Primos Mg by Robert A. Larson
  1801.  
  1802. /* 64v mode version
  1803. -64v
  1804. -newfortran
  1805. /* define to indicate primos
  1806. -define __50SERIES
  1807. /* get routine names in stack dump
  1808. -store_owner_field
  1809. /* tell it to run fast
  1810. -standardintrinsics
  1811. -optimize
  1812. /* find varargs.h in *>sys>prime
  1813. -include *>sys>prime
  1814.  
  1815. /* real options
  1816. -define NO_DIRED                /* no 64v mode support in dired code
  1817. -define PREFIXREGION
  1818. -define NOTAB
  1819. SHAR_EOF
  1820. cat << \SHAR_EOF > sys/prime/mg.options.c
  1821. /* options for Prime MicroGnuEmacs by Robert A. Larson
  1822.  
  1823. -32ix
  1824. /* get routine names in stack dump
  1825. -store_owner_field
  1826. /* tell it to run fast
  1827. -standardintrinsics
  1828. -optimize 1
  1829. /* -pbstring was broken, and either got fixed or the other changes...
  1830. -pbstring
  1831. /* find varargs.h in *>sys>prime
  1832. -include *>sys>prime
  1833.  
  1834. /* real options
  1835. -define PREFIXREGION
  1836. -define NOTAB
  1837.  
  1838. SHAR_EOF
  1839. cat << \SHAR_EOF > sys/prime/readme
  1840.  
  1841. MicroGnuEmacs 2a for primos
  1842.  
  1843. This version has only been tested under primos 21.0 (.0, .1, .2s) in
  1844. 32ix mode.  The dired code does not run in 64v mode.  (pl1 type ptr
  1845. options(short) is a pain to simulate in 64v mode C.)  The pre-rev 21
  1846. code should work, but ^p, ^j, and a true meta key will be unusable.
  1847.  
  1848. One major problem has been descovered: mg will always fail if it is
  1849. already in memory.  (access violations, illegal segno, etc.) This is a
  1850. bug that has been reported to prime.  I recomend aliasing mg to remepf
  1851. mg;mg .  (Further oddity: sometime remepf gets access violations!) To
  1852. get your line back to a normal mode after this has happended, set your
  1853. terminal's parity to mark and type "set_async -pro tty -echo -xoff"
  1854. followed by a linefeed.
  1855.  
  1856. Some pre-21 verisons of the C library had a bug in open(), there is
  1857. code that can be included with a #define in fileio.c to avoid this
  1858. problem.  The -pbstring option is broken in some Prime C compiler
  1859. versions, if you notice strange problems try recompiling with
  1860. -lbstring.
  1861.  
  1862. The rev 21 version will not run over primenet since the terminal line
  1863. cannot be conditioned properly.
  1864.  
  1865. Support for Prime's extended character set rather than a meta key
  1866. should not be hard to add.  (chrdef.h, cinfo.c, and ttyio.c are what
  1867. would need changes.)
  1868.  
  1869. Installation:
  1870.   copy *>sys>prime>make.cpl
  1871.   ph make -ph -como             [add -64v if 64v mode is needed.]
  1872. When phantom is finished:
  1873.   copy mg.run cmdnc0>==         [32ix mode]
  1874. or
  1875.   copy mg.64v.run cmdnc0>=.run  [64v mode]
  1876.  
  1877. Global variable .termcap (or .termcap$) should be set to the pathname
  1878. of the termcap file if the default of mg*>termcap is inappropraite,
  1879. and .terminal_type$ (or .term) should be set to your terminal type.
  1880. (Global variables are manipulated with the primos commands
  1881. define_gvar, set_var, and list_var.) The C library must be in your
  1882. search rules.  Your .mg initalization file should be located in your
  1883. inital attach point, if you don't have one the one in mg* will be used
  1884. if available.  (Terminal specific files may also be used.) Prime
  1885. emacs's termcap file does not work well with mg.
  1886.  
  1887. On pre-rev 21 systems, due to primos limitations, neither ^P or ^J are
  1888. usable input, and true meta keys are not supported.  If ^P is
  1889. accidentaly typed and you have break enabled, mg may be resumed with
  1890. the start command (and the screen should be refreshed with the
  1891. recenter command ^L).
  1892.  
  1893. Primos programs other than mg and the C compiler do not understand tab
  1894. characters, so use of notab mode is recomended.
  1895.  
  1896. The options to make.cpl are:
  1897.  
  1898.     -ph         chap -idle
  1899.     -como       create como file make.como
  1900.     -64v        create 64v rather than 32ix mode version
  1901.  
  1902. Compilation options are in the files mg.options.c and
  1903. mg.64v.options.c.
  1904.  
  1905. Warnings to potential modifiers:
  1906.  
  1907.         The source to mg contains tab characters.  These should be
  1908. converted to spaces before printing or editing with an editor that
  1909. does not cope with tabs.
  1910.  
  1911.     Make.cpl does not have all dependencies, if one of the new .h
  1912. files is changed, delete all applicable .bin files.
  1913. SHAR_EOF
  1914. cat << \SHAR_EOF > sys/prime/spawn.c
  1915. /*
  1916.  * prime spawn.c for micrognuemacs
  1917.  */
  1918. #include       "def.h"
  1919.  
  1920. spawncli(f, n)
  1921. {
  1922.        fortran void comlv$();
  1923.        ttcolor(CTEXT);
  1924.        ttnowindow();
  1925.        ttmove(nrow-1, 0);
  1926.        if (epresf != FALSE) {
  1927.            tteeol();
  1928.            epresf = FALSE;
  1929.        }
  1930.        ttclose();
  1931.        comlv$();
  1932.        sgarbf = TRUE;        /* Force repaint.    */
  1933.        ttopen();
  1934. #ifndef NO_DIR
  1935.        (void) dirinit();    /* current directory may have changed */
  1936. #endif
  1937.        return (TRUE);
  1938. }
  1939. SHAR_EOF
  1940. cat << \SHAR_EOF > sys/prime/stackptr$.pma
  1941. *        stackptr$.pma  -- used by 64v varargs.h.ins.cc
  1942. * 02/22/87 Robert Larson  Name chagned to avoid potention conflict
  1943.  
  1944.          SEG
  1945.          SYML
  1946.          RLIT
  1947.          ENT       STACKPTR$
  1948.  
  1949. START    EAXB      SB%+4,*
  1950.          PRTN
  1951.  
  1952.          LINK
  1953. STACKPTR$ ECB      START
  1954.          END
  1955. SHAR_EOF
  1956. cat << \SHAR_EOF > sys/prime/sysdef.h
  1957. /*
  1958.  * Prime specific definitions for MicroGnuEmacs 2a
  1959.  */
  1960. #include <stdio.h>
  1961.  
  1962. #define           PCC               /* "[]" gets an error.              */
  1963. #define           KBLOCK  1024           /* Kill grow.                  */
  1964. #define           GOOD    0           /* Good exit status.              */
  1965. #define           NO_RESIZE           /* screen size is constant          */
  1966. #define           MAXPATH 256
  1967.  
  1968. /* typedefs for gnu version */
  1969. typedef int    RSIZE;           /* Type for file/region sizes   */
  1970. typedef short  KCHAR;           /* Type for internal keystrokes */
  1971.  
  1972. /*
  1973.  * Macros used by the buffer name making code.
  1974.  * Start at the end of the file name, scan to the left
  1975.  * until BDC1 (or BDC2, if defined) is reached. The buffer
  1976.  * name starts just to the right of that location, and
  1977.  * stops at end of string (or at the next BDC3 character,
  1978.  * if defined). BDC2 and BDC3 are mainly for VMS.
  1979.  */
  1980. #define           BDC1    '>'
  1981.  
  1982. #define bcopy(from,to,len)      if(1) {\
  1983.     register char *from_=from, *to_=to; register int len_=len;\
  1984.     while(len_--) *to_++ = *from_++;} else
  1985.  
  1986. #define MALLOCROUND(m) (m+=7, m&=~7)   /* round to 8 byte boundary */
  1987.  
  1988. char *gettermtype();    /* #define fails because of static storage */
  1989.  
  1990. #define unlink(f)    delete(f)
  1991. #define unlinkdir(f) delete(f)
  1992.  
  1993. #ifdef DO_METAKEY
  1994. #define METABIT 0400
  1995. #endif
  1996. SHAR_EOF
  1997. cat << \SHAR_EOF > sys/prime/ttyio.c
  1998. /*
  1999.  *     sys>prime>ttyio.c by Robert A. Larson
  2000.  *
  2001.  * The functions in this file
  2002.  * negotiate with the operating system for
  2003.  * keyboard characters, and write characters to
  2004.  * the display in a barely buffered fashion.
  2005.  */
  2006. #include       "def.h"
  2007.  
  2008. #define           NOBUF   512           /* Output buffer size.           */
  2009.  
  2010. char   obuf[NOBUF];               /* Output buffer.           */
  2011. short  nobuf;                   /* characters in obuf           */
  2012. int    nrow;                   /* Terminal size, rows.           */
  2013. int    ncol;                   /* Terminal size, columns.      */
  2014. short  ospeed;                   /* Terminal speed, for termlib.l */
  2015.  
  2016. #ifndef PRE21
  2017. /* use undocumented calls to set terminal modes */
  2018. #define NSETTINGS 6
  2019. fortran void as$lin(), as$get(), as$set();
  2020. static short myline = 0;
  2021. static short reset[NSETTINGS][2];
  2022. #else
  2023. /* do the best we can without undocumented calls */
  2024. fortran short duplx$();
  2025. fortran void break$();
  2026. short duplx;
  2027. #endif
  2028.  
  2029. /*
  2030.  * This function gets called once, to set up
  2031.  * the terminal channel.
  2032.  */
  2033.  
  2034. ttopen()
  2035. {
  2036. #ifndef PRE21
  2037.     short code, vers, len, bad;
  2038.     static short settings[NSETTINGS][2] = {
  2039.     {1, 0},                   /* no echo */
  2040.     {2, 0},                   /* don't echo line feed for cr */
  2041.     {3, 0},                   /* disable ^S/^Q processing */
  2042.     {11, 0},               /* parity: none */
  2043.     {12, 3},               /* character length: 8 */
  2044.     {15, 1},               /* tran protocol */
  2045.     };
  2046.     short plist[38][2];
  2047.     short *p;
  2048.     register int i;
  2049.  
  2050.     if(myline==0) {
  2051.     as$lin(myline, code);
  2052.     if(code!=0) panic("Can't get terminal line");
  2053.     /* do io to get terminal type before setting modes */
  2054.     (void) gettermtype();
  2055.     }
  2056.     p = &plist[0][0];
  2057.     as$get(myline, vers, p, len, code);
  2058.     if(code!=0) panic("Can't determine current settings");
  2059.     ospeed = plist[9-1][1];
  2060.     for(i=0; i < NSETTINGS; i++) {
  2061.     reset[i][0] = settings[i][0];
  2062.     reset[i][1] = plist[settings[i][0]-1][1];
  2063.     }
  2064.     p = &settings[0][0];
  2065.     as$set(myline, (short)0, p, (short)NSETTINGS, code, bad);
  2066.     if(code!=0) panic("Can't set terminal modes");
  2067. #else
  2068.     (void) gettermtype();
  2069.     duplx = duplx$((short)-1);
  2070.     (void) duplx$((unsigned short)0140000);
  2071.     ospeed = 4; /* assume 9600 for debugging */
  2072. #endif
  2073.     nobuf = 0;
  2074. }
  2075.  
  2076. /*
  2077.  * This function gets called just
  2078.  * before we go back home to the shell. Put all of
  2079.  * the terminal parameters back.
  2080.  */
  2081. ttclose()
  2082. {
  2083. #ifndef PRE21
  2084.     short code, bad;
  2085.     short *p;
  2086. #endif
  2087.  
  2088.     ttflush();
  2089. #ifndef PRE21
  2090.     p = &reset[0][0];
  2091.     as$set(myline, (short)0, p, (short)NSETTINGS, code, bad);
  2092.     if(code!=0) {
  2093.     printf("Can't reset terminal modes: code: %d bad: %d\n",
  2094.         code, bad);
  2095.     exit(1);
  2096.     }
  2097. #else
  2098.     (void) duplx$(duplx);
  2099. #endif
  2100. }
  2101.  
  2102. /*
  2103.  * Write character to the display.
  2104.  * Characters are buffered up, to make things
  2105.  * a little bit more efficient.
  2106.  */
  2107. ttputc(c)
  2108. {
  2109.        if (nobuf >= NOBUF)
  2110.            ttflush();
  2111.        obuf[nobuf++] = c;
  2112. }
  2113.  
  2114. /*
  2115.  * Flush output.
  2116.  */
  2117. ttflush()
  2118. {
  2119.        fortran void tnoua();
  2120.  
  2121.        if (nobuf != 0) {
  2122.            tnoua((char [])obuf, nobuf);
  2123.            nobuf = 0;
  2124.        }
  2125. }
  2126.  
  2127. /*
  2128.  * Read character from terminal.
  2129.  * Parity bit is stripped, to be normal
  2130.  */
  2131. ttgetc()
  2132. {
  2133.     fortran void t1in();
  2134.     short c;
  2135.  
  2136.     t1in(c);
  2137. #ifdef DO_METAKEY
  2138.     if(c&0200) c |= METABIT;
  2139. #endif
  2140.     c |= 0200;
  2141. #ifdef PRE21
  2142.     if(c=='\n') return '\r';       /* fix repping done by primos */
  2143. #ifdef DO_METAKEY
  2144.     if(c==('\n'|METABIT)) return '\r'|METABIT;
  2145. #endif
  2146. #endif
  2147.     return c;
  2148. }
  2149.  
  2150. int typeahead()
  2151. {
  2152.     fortran short tty$in();
  2153.  
  2154.     return tty$in() < 0;
  2155. }
  2156.  
  2157. panic(s) char *s; {
  2158.   fortran void tnoua(), tnou();
  2159.  
  2160.   ttclose();
  2161.   tnoua((char [])"Panic: ", (short)7);
  2162.   tnou((char [])s, (short)strlen(s));
  2163.   exit(1);
  2164. }
  2165.  
  2166. #ifndef NO_DPROMPT
  2167. ttwait() {
  2168.   register short i = 20;
  2169.   fortran short tty$in();
  2170.   fortran void sleep$();
  2171.  
  2172.   while(i--) {
  2173.     if(tty$in()<0) return FALSE;
  2174.     sleep$((long)100);
  2175.   }
  2176.   return tty$in() >= 0;
  2177. }
  2178. #endif
  2179.  
  2180. char *gettermtype()
  2181. {
  2182.     register char *cp;
  2183.     char *gvget();
  2184.     static char termtype[64] = "";
  2185.  
  2186.     if(termtype[0]!='\0') return termtype;
  2187.     cp = gvget(".TERMINAL_TYPE$");     /* get terminal type */
  2188.     if(cp==NULL) cp = gvget(".TERM");
  2189.     if(cp != NULL) {
  2190.     strncpy(termtype, cp, 64);
  2191.     return termtype;
  2192.     }
  2193.     fputs("Terminal type? ", stdout);
  2194.     fgets(termtype, 64, stdin);
  2195.     putchar('\n');
  2196.     termtype[strlen(termtype)-1] = '\0';    /* chop off \n */
  2197.     return termtype;
  2198. }
  2199. SHAR_EOF
  2200. cat << \SHAR_EOF > sys/prime/varargs.h.ins.cc
  2201. /* varargs.h.ins.cc  -- varargs for both 32ix and 64v mode C unser primos */
  2202. /* 02/22/87 Robert Larson  Cleanup  (Variable name changes to avoid conflicts) */
  2203.  
  2204. #ifdef __CI
  2205. /* varargs.h for 32ix mode on a Prime 9955 */
  2206. /* Modified from the Primix varargs.h by James M Synge. */
  2207. typedef char *va_list;
  2208.  
  2209. #define va_alist       _va_arg1
  2210. #define va_dcl           char va_alist;
  2211. #define va_start(list) list = ((va_list)(&_va_arg1))
  2212. #define va_end(list)
  2213.  
  2214. #define va_arg(list,mode)    ((mode *)((list) += sizeof(mode)))[-1]
  2215.  
  2216. #else
  2217.  
  2218. typedef int **va_list;
  2219. extern short *stackptr$();
  2220.  
  2221. #define va_alist \
  2222.     /* first argument at SB%+45 */ \
  2223.     _v0,_v1,_v2,_v3,_v4,_v5,_v6,_v7,_v8,_v9,_v10, \
  2224.     _v11,_v12,_v13,_v14,_v15,_v16,_v17,_v18,_v19,_v20, \
  2225.     _v21,_v22,_v23,_v24,_v25,_v26,_v27,_v28,_v29,_v30, \
  2226.     _v31,_v32,_v33,_v34,_v35,_v36,_v37,_v38,_v39,_v40, \
  2227.     _v41,_v42,_v43,_v44,_v45,_v46,_v47,_v48,_v49,_v50, \
  2228.     _v51,_v52,_v53,_v54,_v55,_v56,_v57,_v58,_v59,_v60, \
  2229.     _v61,_v62,_v63,_v64,_v65,_v66,_v67,_v68,_v69
  2230.  
  2231. #define va_dcl int *_v0;
  2232. #define va_start(list) list = ((va_list)(stackptr$() + 042))
  2233. #define va_end(list)
  2234. #define va_arg(list, mode) ( (sizeof(mode) == sizeof(char *)) ? \
  2235.                  ((**(mode **)((list)++)))    : \
  2236.                  ((mode) (**((list)++))) )
  2237. #endif
  2238. SHAR_EOF
  2239. #    End of shell archive
  2240. exit 0
  2241. -------
  2242.