home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archimedes / aracom.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  13KB  |  595 lines

  1. /* -> c.ckacon
  2.  */
  3.  
  4. char *connv = "Arthur Connect Command (based on C-Kermit V4C(010)) 19 Dec 85";
  5.  
  6. /*  C K A C O N  --  Smart terminal emulation to remote system, for Arthur */
  7.  
  8. /*
  9.  Author: Frank da Cruz (SY.FDC@CU20B),
  10.  Columbia University Center for Computing Activities, January 1985.
  11.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  12.  Permission is granted to any individual or institution to use, copy, or
  13.  redistribute this software so long as it is not sold for profit,
  14.  provided this copyright notice is retained. 
  15.  Arthur version: Richard Cownie/Acorn VLSI Tools Group
  16.  (c) Acorn Computers Plc 1985
  17. */
  18.  
  19. #include "ckcdeb.h"
  20. #include <stdio.h>
  21. #include "ckcker.h"
  22.  
  23. #ifdef ANSI
  24. #include "ckatio.h"
  25. #include "ckafio.h"
  26. #include "ckamis.h"
  27. #endif
  28.  
  29. #ifdef ARTHUR
  30. #include "arthur.h"
  31. #include "plib.h"
  32. #include "tty.h"
  33. #endif
  34.  
  35. /* parameters to be tuned for performance (NB may blow up if you go wrong) */
  36. #define BUFSZ 2048   /* buffer up to BUFSZ chars */
  37. #define BUFHI 1280   /* send ^S when we have this many chars pending */
  38. #define BSIZE 32     /* grab <= BSIZE chars at a time from rs423 input */
  39. #define LOTS 128     /* send ^S when rs423 buf contains > LOTS */
  40. #define FEW 64       /* send ^Q when rs423 buf contains < FEW */
  41. #define VSIZE 4      /* give <= VSIZE chars at a time to protocol handler */
  42.  
  43. #define keybf      0
  44. #define rs423inbf  1
  45. #define rs423outbf 2
  46. #define CTRL_S 19
  47. #define CTRL_Q 17
  48.  
  49. /* No buffering on output */
  50. #define send(c) putinbf(rs423outbf, c)
  51.  
  52.  
  53. /* Current speed setting */
  54. extern int speed;
  55.  
  56. /* Current session log file descriptor and name */
  57. extern int seslog;
  58. extern char sesfil[];
  59.  
  60. /****************************************************/
  61. /*  Procedures to do Unix termcap functions on ACW  */
  62. /****************************************************/
  63.  
  64. int rawvdu = -1;
  65. int lrawkb = -1;
  66.  
  67. #ifdef ANSI
  68. void
  69. #endif
  70. vdus(s) char *s; { while(*s) XSWriteByte(rawvdu, *s++); }
  71. #undef vdu
  72. #define vdu(c) XSWriteByte(rawvdu, c)
  73.  
  74. #ifdef ANSI
  75. void
  76. #endif
  77. bbc_wipe(lx,ly,ux,uy) int lx,ly,ux,uy; {
  78.   if (lx > ux) return; if (ly < uy) return;
  79.   vdu(28); vdu(lx); vdu(ly); vdu(ux); vdu(uy); vdu(12); vdu(26);
  80. }
  81.  
  82. #ifdef ANSI
  83. void
  84. #endif
  85. term_cl() { vdu(12); }
  86.  
  87. #ifdef ANSI
  88. void
  89. #endif
  90. term_bs() { vdu(8); }
  91.  
  92. #ifdef ANSI
  93. void
  94. #endif
  95. term_cm(row,col) int row,col; { vdu(31); vdu(col); vdu(row); }
  96.  
  97. #ifdef ANSI
  98. void
  99. #endif
  100. term_nd() { vdu(9); }
  101.  
  102. #ifdef ANSI
  103. void
  104. #endif
  105. term_up() { vdu(11); }
  106.  
  107. #ifdef ANSI
  108. void
  109. #endif
  110. term_ce() { /* clear to end of line: non-trivial */ 
  111.   int x, y;
  112.   get_posn(&x, &y); bbc_wipe(x,y,79,y); term_cm(y,x);
  113. }
  114.  
  115. #ifdef ANSI
  116. void
  117. #endif
  118. term_cd() {
  119.   int x, y;
  120.   get_posn(&x, &y); bbc_wipe(x,y,79,y);
  121.   if (y < 31) bbc_wipe(0,31,79,y+1);
  122.   term_cm(y,x);
  123. }
  124.  
  125. #ifdef ANSI
  126. void
  127. #endif
  128. term_ta() {
  129.   int x, y;
  130.   get_posn(&x, &y); vdu(' '); while ((++x) % 8) vdu(' ');
  131. }
  132.  
  133. #ifdef ANSI
  134. void
  135. #endif
  136. term_ho() { vdu(30); }
  137.  
  138. #ifdef ANSI
  139. void
  140. #endif
  141. term_so() { vdu(17); vdu(0); vdu(17); vdu(129); }
  142.  
  143. #ifdef ANSI
  144. void
  145. #endif
  146. term_se() { vdu(17); vdu(1); vdu(17); vdu(128); }
  147.  
  148. /****************************************************/
  149. /*  State machine to filter VDU stream & tweak vdu  */
  150. /****************************************************/
  151.  
  152. #ifdef ANSI
  153. #undef NULL
  154. #endif
  155. #define NULL 0 /* initial state for the state machine */
  156. static int emul_state, emul_x, emul_y, emul_len;
  157. static char emul_seq[32];
  158.  
  159. #ifdef ANSI
  160. void
  161. #endif
  162. emul_start()
  163. /* initialise terminal emulator */
  164. { int j;
  165. reg_set rs;
  166. error *ret;
  167.  
  168.   /*
  169.    * Open the kb as a stream, but bypass the stream library
  170.    * and access it directly!
  171.    */
  172.   lrawkb = XFindInput("RAWKB:",6);
  173.   rawvdu = XFindOutput("RAWVDU:", 7);
  174.  
  175. #ifdef VT52
  176.     mode(3);
  177. #endif
  178.  
  179.     /* set register 10 of 6845 video chip to 0 for big non-flashing cursor */
  180.     vdu(23); vdu(0); vdu(10); vdu(0x0); for (j = 0; j < 6; ++j) vdu(0);
  181.     vdu(23); vdu(0); vdu(11); vdu(0x7); for (j = 0; j < 6; ++j) vdu(0);
  182.  
  183.     emul_state = NULL; emul_len = 0;
  184.   
  185.     /* Disable rs423 as output stream */
  186.     rs.r[0] = 3;
  187.     rs.r[1] = 0;
  188.     ret = osbyte( &rs );
  189.  
  190.     /* Enable kb and rs423 as input */
  191.     rs.r[0] = 2;
  192.     rs.r[1] = 2;
  193.     ret = osbyte( &rs );
  194.  
  195.     /* Set line speed */
  196.     setbaud( speed );
  197.  
  198.     /* disable cursor editing and fn key nums to cursor and copy keys */
  199.     rs.r[0] = 4;
  200.     rs.r[1] = 2;
  201.     ret = osbyte( &rs );
  202.  
  203.     /* Disable escape */
  204.     rs.r[0] = 229;
  205.     rs.r[1] = 1;
  206.     ret = osbyte( &rs );
  207.  
  208.     rsintercept();
  209.  
  210. }
  211.  
  212. #ifdef ANSI
  213. #undef CR
  214. #undef LF
  215. #undef ESC
  216. #endif
  217.  
  218. #define CR 13
  219. #define LF 10
  220. #define ESC 27
  221.  
  222.  
  223. #ifdef ANSI
  224. void
  225. #endif
  226. putseq() /* put an aborted sequence to vdu in readable form */
  227. { int j,x; char c;
  228.   for (j = 0; j < emul_len; j++) {
  229.     c = emul_seq[j]; x = c;
  230.     if (c < ' ') printf("[%x]", x); else vdu(c);
  231.   }
  232. }
  233.  
  234. #define next(s) { emul_state = s; return; }
  235. #define abort { putseq(); emul_len = 0; emul_state = NULL; return; }
  236. #define done { emul_len = 0; emul_state = NULL; return; }
  237. #define isdigit(c) (('0' <= c) && (c <= '9'))
  238.  
  239. /*************************************/
  240. /*  A simple dumb terminal emulator  */
  241. /*************************************/
  242.  
  243. #ifdef DUMB
  244. #ifdef ANSI
  245. void
  246. #endif
  247. emul_inch(c) char c;
  248. /* deal with character received from line: dumb terminal */
  249. {
  250.   if (c >= 128) c -= 128;
  251.   switch(c) {
  252.     case 8:  term_bs(); break;
  253.     case 9:  term_ta(); break;
  254.     case CR: break;
  255.     case LF: vdu(CR); vdu(LF); break;
  256.     default: if (c >= ' ') vdu(c);
  257.   }
  258. }
  259.  
  260.  
  261. #ifdef ANSI
  262. void
  263. #endif
  264. emul_outch(c) int c;
  265. /* send sequence corresponding to key press c on ACW keyboard */
  266. /* sends ESC-0,..,ESC-9 for the function keys, ESC-A,...,ESC-D for the */
  267. /* cursor keys, with control & shift adding an extra ESC- prefix each. */
  268. {
  269. char *code = "0123456789 ]DCBA"; 
  270.  
  271.   if (c < 128) { send(c); return; }
  272.   while ( c >= 0x144 ) { send(ESC); c -= 16; }
  273.   send(ESC);
  274.   send(code[c-128]);
  275.  
  276.   inter();
  277.  
  278. }
  279. #endif
  280.  
  281. /*************************************/
  282. /*   End of dumb terminal emulator   */
  283. /*************************************/
  284.  
  285. #ifdef VT52
  286.  
  287. #define emul_inch VT52_inch
  288. #define emul_outch VT52_outch
  289.  
  290. /********************************************************************/
  291. /*  An example of a smart terminal emulator, for those who want to  */
  292. /*  hack emulators for the terminal of their choice. This one does  */
  293. /*  a subset of VT52 as defined by the BSD 4.2 Unix termcap file,   */
  294. /*  together with inverse video highlighting.                       */
  295. /********************************************************************/
  296.  
  297. /* First define states of the machine to be used to interpret codes */
  298.  
  299. #define SESC 1
  300. #define SBRA 2
  301. #define SO1  3
  302. #define GETY 4
  303. #define GETX 5
  304. #define CL1  6
  305. #define CL2  7
  306.  
  307.  
  308. /* Respond to UNIX ttytype */
  309. void answer(void)
  310. {       sendchar(ESC); sendchar('/'); sendchar('Z'); inter(); 
  311. }
  312.  
  313. /* Now the interpreter itself */
  314. #ifdef ANSI
  315. void
  316. #endif
  317. VT52_inch(c) char c;
  318. /* deal with char c received from line: VT52 emulation */
  319. {
  320.   if (c >= 128) c -= 128;
  321.   emul_seq[emul_len++] = c;
  322.   switch(emul_state) {
  323.     case NULL:
  324.       switch(c) {
  325.         case ESC: next(SESC);
  326.         case 9:   term_ta(); done;
  327.         default: 
  328.                 vdu(c); 
  329.                 if(seslog) zchout(ZSFILE,c); /* session logging */
  330.                 done;
  331.       }
  332.     case SESC:
  333.       switch(c) {
  334.     case 'A':  term_up(); done;
  335.         case 'C':  term_nd(); done;
  336.     case 'J':  term_cd(); done;
  337.         case 'K':  term_ce(); done;
  338.         case 'H':  next(CL1);   
  339.     case 'Y':  next(GETY); 
  340.     case '[':  next(SBRA); 
  341.     case '>':  term_ce(); done;
  342.     default: abort;
  343.       }
  344.     case SBRA:  
  345.       switch(c) {
  346.         case '4':
  347.         case '7':  next(SO1);
  348.         case 'c':  answer();
  349.         case 'm':  term_se(); done;
  350.         default :  abort;
  351.       }
  352.     case SO1:   if (c == 'm') { term_so(); done; } else abort;
  353.     case GETY:  emul_y = (c - ' '); next(GETX);
  354.     case GETX:  emul_x = (c - ' '); term_cm(emul_y, emul_x); done;
  355.     case CL1:   if (c == ESC) { next(CL2); } else abort;
  356.     case CL2:   if (c == 'J') { term_cl(); done; } else abort;
  357.     default:    abort;
  358.   }
  359. }
  360.  
  361. void linebreak(void)
  362. {
  363. reg_set rs;
  364. error *ret;
  365.  
  366.         rs.r[0] = 156;
  367.         rs.r[1] = 0x60;
  368.         rs.r[2] = 0x9f;
  369.         ret = osbyte( &rs );
  370.  
  371.         rs.r[0] = 19;
  372.         ret = osbyte( &rs );
  373.         ret = osbyte( &rs );    
  374.         ret = osbyte( &rs );
  375.  
  376.         rs.r[0] = 156;
  377.         rs.r[1] = 0x20;
  378.         rs.r[2] = 0x9f;
  379.         ret = osbyte( &rs );
  380. }
  381.  
  382. #ifdef ANSI
  383. void
  384. #endif
  385. VT52_outch(c)
  386. int c;
  387. /* send sequence corresponding to key press c */
  388. /* this generates some bizarre non-standard escape sequences copied */
  389. /* from a terminal ROM developed for in-house use at ACORN. */
  390. { char *code = "<>,.45O78J ]DCBA";
  391.  
  392.   if( c == 169 )
  393.   {
  394.       /* CTL-F9 Sends a line break */
  395.       linebreak();
  396.       return;
  397.   }
  398.  
  399.   if (c < 128) { send(c); return; }
  400.   while (c >= 144) { send(ESC); c -= 16; }
  401.   send(ESC);
  402.   if( c != 128 )
  403.           send(code[c-128]);
  404.   inter();
  405.  
  406. }
  407.  
  408. /**************************/
  409. /*  End of VT52 emulator  */
  410. /**************************/
  411.  
  412. #endif
  413.  
  414. #ifdef ANSI
  415. void
  416. #endif
  417. emul_finish()
  418. /* finish terminal emulation & tidy up */
  419. {
  420. #ifdef ARTHUR
  421. int j;
  422. reg_set rs;
  423. error *ret;
  424.  
  425.   /* set register 10 of 6845 video chip to 0 for big non-flashing cursor */
  426.   vdu(23); vdu(0); vdu(10); vdu(0x67); for (j = 0; j < 6; ++j) vdu(0);
  427.  
  428.     rs.r[0] = 2;
  429.     rs.r[1] = 0;
  430.     ret = osbyte( &rs );
  431.  
  432.     rs.r[0] = 4;
  433.     rs.r[1] = 0;
  434.     ret = osbyte( &rs );
  435.  
  436.  
  437.  
  438.     /* enable cursor editing and fn key nums to cursor and copy keys */
  439.     rs.r[0] = 4;
  440.     rs.r[1] = 0;
  441.     ret = osbyte( &rs );
  442.  
  443.  
  444.     /* Disable escape */
  445.     rs.r[0] = 229;
  446.     rs.r[1] = 0;
  447.     ret = osbyte( &rs );
  448.  
  449.     rsrelease();
  450.  
  451.     mode(0);
  452.  
  453.     XCloseStream( rawvdu );
  454.     XCloseStream( lrawkb );
  455.  
  456.  
  457.  
  458. #endif
  459. }
  460.  
  461. /**************************************************/
  462. /*  C O N E C T  --  Perform terminal connection  */
  463. /**************************************************/
  464.  
  465. #define END_KEY 161 /* Key value to end terminal session */
  466.  
  467. #ifdef ANSI
  468. int
  469. #endif
  470. conect() {
  471.   int key,max,min,block,doneCtrlS,ok,userok;
  472.   int head = 0, tail = 0, size = 0; char buf[BUFSZ];
  473.  
  474.   printf("\nYou are now connected to your host computer\n");
  475.   printf("Press F1 to return to local kermit\n\n");
  476.   if(seslog) printf("(Session logged to %s)\n",sesfil);
  477.  
  478.   initrs(); emul_start(); send(CR); inter();
  479.   doneCtrlS = 1; ok = userok = 1; max = min = 0;
  480.  
  481.   for (;;)
  482.   {
  483.       if (doneCtrlS)
  484.       {
  485.           if (min+size < FEW)
  486.               ok = 1;
  487.           if (ok && userok)
  488.           {
  489.               send(CTRL_Q); inter();
  490.               doneCtrlS = 0;
  491.           }
  492.       }
  493.       else if ((min+size == 0) || (max > FEW))
  494.       {
  495.           min = nrsbuf(); 
  496.           if ((min > LOTS) || (size > BUFHI))
  497.               ok = 0;
  498.           if (! (ok && userok))
  499.           {
  500.               send(CTRL_S); inter();
  501.               doneCtrlS = 1;
  502.           }
  503.       }
  504.  
  505.       block = min;
  506.       if (block > BSIZE) block = BSIZE;
  507.  
  508.       while (block--)
  509.       { /* get chars from rs423 buffer */
  510.           testbf(rs423inbf, &key);
  511.           min--;
  512.           buf[tail] = key;
  513.           ++size;
  514.           if (++tail >= BUFSZ)
  515.               tail = 0;
  516.       }
  517.       
  518.       block = size;
  519.       if (block > VSIZE) block = VSIZE;
  520.       max = min + LOTS; /* chars may be coming */
  521.       while (block--)
  522.       { /* hand chars to protocol interpreter */
  523.           emul_inch(buf[head]);
  524.           --size;
  525.           if (++head >= BUFSZ)
  526.               head = 0;
  527.       }
  528.       if (testbf(keybf, &key))
  529.       { /* have a key press */
  530.           if (key == END_KEY)
  531.           {
  532.               termrs(); emul_finish(); 
  533.               printf("\nReturn to Arthur-Kermit.\n"); return(1);
  534.           } 
  535.           else if (key == CTRL_S) userok = 0;
  536.           else if (key == CTRL_Q) userok = 1;
  537.           else if (key >= 127) emul_outch(key); 
  538.           else send(key);
  539.           
  540.           inter();
  541.       } 
  542.   }
  543. }
  544.  
  545. /*****************************************************/
  546. /*  H C O N N E  --  Give help message for connect.  */
  547. /*****************************************************/
  548.  
  549. #ifdef ANSI
  550. int
  551. #endif
  552. hconne() {
  553.     int c;
  554.     static char *hlpmsg[] = {
  555. "\r\n  C to close the connection, or:",
  556. "\r\n  S for status",
  557. "\r\n  ? for help",
  558. "\r\n  B to send a BREAK",
  559. "\r\n  0 to send a null",
  560. "\r\n escape character twice to send the escape character.\r\n\r\n",
  561. "" };
  562.  
  563.     conola(hlpmsg);         /* Print the help message. */
  564.     conol("Command> ");         /* Prompt for command. */
  565.     c = coninc(0);
  566.     conoc(c);               /* Echo it. */
  567.     conoll("");
  568.     c &= 0177;              /* Strip any parity. */
  569.     return(c);              /* Return it. */
  570. }
  571.  
  572. /***************************************************************/
  573. /*  C H S T R  --  Make a printable string out of a character  */
  574. /***************************************************************/
  575.  
  576. char * chstr(c) int c; {
  577.     static char s[8];
  578.     char *cp = s;
  579.  
  580.     if (c < SP) {
  581.     sprintf(cp,"CTRL-%c",ctl(c));
  582.     } else sprintf(cp,"'%c'\n",c);
  583.     cp = s;
  584.     return(cp);
  585. }
  586.  
  587. /*********************************************************/
  588. /*  D O E S C  --  Process an escape character argument  */
  589. /*********************************************************/
  590.  
  591. #ifdef ANSI
  592. void
  593. #endif
  594. doesc(c) char c; {}
  595.