home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / atarist / asttty.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  12KB  |  517 lines

  1. /*********************************/
  2. /* IBM Block Terminal Emulation  */
  3. /* written by B. Nebel, March 86 */
  4. /* Version 1.2 of 5/10/86        */
  5. /*********************************/
  6.  
  7. /* include files */
  8. /*****************/
  9.  
  10. #include "define.h"      /* common C defintions */
  11. #include "osbind.h"      /* binding of TOS */
  12. #include "gemdefs.h"     /* GEM defintions */
  13.  
  14.  
  15. /* some ASCII codes */
  16. /********************/
  17.  
  18. #define NUL 0x00 /* ^@ */
  19. #define SOH 0x01 /* ^A */
  20. #define ETX 0x03 /* ^C */
  21. #define BEL 0x07 /* ^G */
  22. #define BS  0x08 /* ^H */
  23. #define HT  0x08 /* ^I */
  24. #define LF  0x0A /* ^J */
  25. #define VT  0x0B /* ^K */
  26. #define FF  0x0C /* ^L */
  27. #define CR  0x0D /* ^M */
  28. #define DC1 0x11 /* ^S */
  29. #define DC3 0x13 /* ^Q */
  30. #define SUB 0x1A /* ^Z */
  31. #define ESC 0x1B /* ^[ */
  32. #define DEL 0x7F
  33.  
  34.  
  35.  
  36. /* Some Scan Codes */
  37. /*******************/
  38.  
  39. #define CLR_HOME_KEY     0x47
  40. #define UP_KEY           0x48
  41. #define LEFT_KEY         0x4B
  42. #define RIGHT_KEY        0x4D
  43. #define DOWN_KEY         0x50
  44. #define INSERT_KEY       0x52
  45. #define UNDO_KEY         0x61
  46. #define HELP_KEY         0x62
  47.  
  48.  
  49. /* global constant parameters */
  50. /******************************/
  51.  
  52. #define ACCESSORY YES
  53. #define MENU_NAME "  IBM Terminal" /* name of menu entry */
  54. #define MAX_LL 80  /* line length */
  55. #define MAX_BUF 20 /* ring buffers */
  56.  
  57. /* external functions */
  58. /**********************/
  59.  
  60. /* GEMDOS (osbind.h) */
  61. /* Crawio, Cauxin, Cauxout, Cauxis, Malloc, Mfree */
  62.  
  63. /* XBIOS (osbind.h) */
  64. /* Rsconf */
  65.  
  66. /* VDI */
  67. extern int v_opnvwk();
  68. extern int v_clsvwk();
  69. extern int v_enter_cur();
  70. extern int v_exit_cur();
  71. extern int v_curright();
  72. extern int v_curleft();
  73. extern int v_curhome();
  74. extern int v_eeos();
  75. extern int v_eeol();
  76. extern int vs_curaddress();
  77. extern int vq_curaddress();
  78. extern int v_curtext();
  79. extern int vq_chcells();
  80. extern int vro_copyfm();
  81.  
  82. /* AES */
  83. extern int appl_init();
  84. extern int appl_exit();
  85. extern int graf_handle();
  86. extern int graf_mouse();
  87. extern int graf_growbox();
  88. extern int menu_register();
  89. extern int evnt_mesag();
  90. extern int evnt_timer();
  91. extern int wind_create();
  92. extern int wind_open();
  93. extern int wind_close();
  94. extern int wind_delete();
  95. extern int wind_get();
  96. extern int wind_update();
  97.  
  98. extern int form_alert();
  99.  
  100. extern int gl_apid;
  101.  
  102. /* Global Variables */
  103. /********************/
  104.  
  105.  
  106. int menu_id, vdi_handle, wi_handle;          /* some handles */
  107. int gl_hchar, gl_wchar, gl_wbox, gl_hbox;    /* sizes given back by VDI */
  108. int xdesk, ydesk, hdesk, wdesk;              /* desktop size and loc. */
  109. int last_entry, next_entry;                  /* ptr to ring buffer */
  110. char ring_buffer [MAX_BUF] [MAX_LL];         /* the ring buffer */
  111. int ring_filled[MAX_BUF];                    /* fill counter for ring buf */
  112. int aux_received;                            /* if <> 0 someth. rec. by aux */
  113. FDB scrn_mfdb;                               /* mfdbs for saving menu bar */
  114. FDB save_mfdb;
  115. int work_in[11];                             /* params for vdi_opnvwk */
  116. int work_out[57];
  117. int pxy[8];                                  /* param for raster copy */
  118. long int buff_loc = NIL;                     /* save buffer for menu bar */
  119. long buff_size;                              /* buffer size */
  120. int menbbuf[1000];                           /* buffer for menu bar */
  121.                                              /* static allocation because
  122.                                                 Malloc allocates too much */
  123.  
  124. int contrl[12];                              /* VDI/AES glob. params */
  125. int intin[128];
  126. int ptsin[128];
  127. int intout[128];
  128. int ptsout[128];
  129.  
  130. /**********************************/
  131. /* Initializations & Terminations */
  132. /**********************************/
  133.  
  134. open_vdi()
  135. /* open virtual work station */
  136. {
  137.  int i;
  138.  
  139.    vdi_handle = graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  140.    for (i = 1; i < 10; i++)
  141.      { work_in[i] = 1; }
  142.    work_in[10] = 2;
  143.    v_opnvwk(work_in, &vdi_handle, work_out);
  144.    wind_get(0,WF_WORKXYWH,&xdesk,&ydesk,&wdesk,&hdesk);
  145. }
  146.  
  147. int init_terminal()
  148. /* init virtual workstation as a terminal */
  149. {
  150.  graf_mouse(M_OFF,NIL);
  151.  if (!(save_menu_bar())) return FALSE;
  152.  wi_handle = wind_create(0,xdesk,ydesk,wdesk,hdesk);
  153.  graf_growbox(xdesk,ydesk,gl_wbox,gl_hbox,xdesk,ydesk,wdesk,hdesk);
  154.  wind_open(wi_handle,xdesk,ydesk,wdesk,hdesk);
  155.  v_enter_cur(vdi_handle);
  156.  v_curhome(vdi_handle);
  157.  v_eeos(vdi_handle);
  158.  return TRUE;
  159. }
  160.  
  161. int save_menu_bar()
  162. /* save menu bar in a area to be allocated */
  163. {
  164.  vq_extnd(vdi_handle, 0, work_out);
  165.  save_mfdb.fd_w       = work_out[0] + 1;
  166.  save_mfdb.fd_h       = ydesk;
  167.  save_mfdb.fd_wdwidth = save_mfdb.fd_w >> 4;
  168.  save_mfdb.fd_stand   = 0;
  169.  vq_extnd(vdi_handle, 1, work_out);
  170.  save_mfdb.fd_nplanes = work_out[4];
  171.  buff_size = (save_mfdb.fd_w >> 3) * save_mfdb.fd_h * save_mfdb.fd_nplanes;
  172.  buff_loc  = save_mfdb.fd_addr =
  173.  /*   ((buff_loc == NIL) ? (Malloc(buff_size)) : buff_loc);
  174.   * I use static allocation because Malloc stole me 50 K!
  175.   */
  176.  &menbbuf[0];
  177.  scrn_mfdb.fd_addr   = 0;
  178.  if (buff_loc == NIL)
  179.   {form_alert(1,"[1][Nicht genug Speicherplatz vorhanden][Abort]");
  180.    return FALSE;};
  181.  pxy[0] = pxy[4] = 0;
  182.  pxy[1] = pxy[5] = 0;
  183.  pxy[2] = pxy[6] = save_mfdb.fd_w - 1;
  184.  pxy[3] = pxy[7] = ydesk - 1;
  185.  vro_cpyfm(vdi_handle,3,pxy,&scrn_mfdb,&save_mfdb);
  186.  return TRUE;
  187. }
  188.  
  189.  
  190. close_vdi()
  191. /* close virtual workstation */
  192.  v_clsvwk(vdi_handle);
  193.  
  194. exit_terminal()
  195. /* exit terminal mode */
  196. {
  197.  v_exit_cur(vdi_handle);
  198.  restore_menu_bar();
  199.  wind_close(wi_handle);
  200.  wind_delete(wi_handle);
  201.  graf_shrinkbox(xdesk,ydesk,gl_wbox,gl_hbox,xdesk,ydesk,wdesk,hdesk);
  202. #if !ACCESSORY
  203.  graf_mouse(M_ON,NIL);
  204. #endif
  205. }
  206.  
  207. restore_menu_bar()
  208. {
  209.  vro_cpyfm(vdi_handle,3,pxy,&save_mfdb,&scrn_mfdb);
  210.  /* Mfree(buff_loc); Do not free because it doesn't work right! */
  211.  graf_mouse(M_ON,NIL);
  212. }
  213.  
  214. /*****************/
  215. /* VDI Functions */
  216. /*****************/
  217.  
  218. vdi_ch(ch)
  219. int ch;
  220. Crawio(ch);
  221.  
  222. vdi_line(string)
  223. char string[];
  224. {
  225.  v_curtext(vdi_handle,string);
  226.  vdi_ch(CR);
  227.  vdi_ch(LF);
  228. }
  229.  
  230. /**********************/
  231. /* Terminal Functions */
  232. /**********************/
  233.  
  234. help()
  235. {
  236.  v_curhome(vdi_handle);
  237.  v_eeos(vdi_handle);
  238.  vdi_line("**********************");
  239.  vdi_line("* IBM Block Terminal *");
  240.  vdi_line("**********************");
  241.  vdi_line("");
  242.  vdi_line("BACKSPACE           - letztes Zeichen lschen");
  243.  vdi_line("DELETE              - aktuelles Zeichen lschen");
  244.  vdi_line("INSERT              - lsche Zeile");
  245.  vdi_line("RETURN und ENTER    - sende Zeile");
  246.  vdi_line("CLR HOME            - sende BREAK Sequenz");
  247.  vdi_line("Pfeile links/rechts - Cursor in der Zeile bewegen");
  248.  vdi_line("Pfeile oben/unten   - letzte/nchste Zeile editieren");
  249.  vdi_line("HELP                - Ausgabe dieser Meldung");
  250.  vdi_line("UNDO                - zurck zum Desktop");
  251.  vdi_line("");
  252. }
  253.  
  254. flush_rs232_buffer()
  255. while (Cauxis() != 0) Cauxin();
  256.  
  257. flush_terminal_buffer()
  258. while (Crawio(0xFF) != 0);
  259.  
  260. wait_for_char(scan_code,ch)
  261. char *scan_code,*ch;
  262. {
  263. long result;
  264.  do {*scan_code = NUL;
  265.          if ((result = Crawio(0xFF)) != 0)
  266.             {
  267.              *ch = result & 0xFF;
  268.              *scan_code = result >> 16 ;
  269.             }
  270.          else
  271.             {if (Cauxis() != 0)
  272.                 {result = Cauxin();
  273.                  *ch = result & 0x7F;
  274.                  if (*ch <= '~')
  275.                      {
  276.                       vdi_ch(*ch);
  277.                       aux_received = YES;
  278.                      };
  279.                 };
  280.             };
  281.     }
  282.  while (*scan_code == NUL);
  283. }
  284.  
  285. send_break()
  286. {char tsr;
  287.  tsr = (Rsconf(-1,-1,-1,-1,-1,-1) >> 16) & 0xFF;
  288.  Rsconf(-1,-1,-1,-1,(tsr | 0x08),-1);
  289.  evnt_timer(750,0);
  290.  Rsconf(-1,-1,-1,-1,tsr,-1);
  291. }
  292.  
  293. ring_bell()
  294. vdi_ch(BEL);
  295.  
  296. redisplay(from,to,line)
  297. int from, to;
  298. char line[];
  299. {
  300. int i,r,c;
  301.  vq_curaddress(vdi_handle,&r,&c);
  302.  for (i = from; i <= to; i++) vdi_ch(line[i]);
  303.  v_eeol(vdi_handle);
  304.  vs_curaddress(vdi_handle,r,c);
  305. }
  306.  
  307. move_right(dummy)
  308. int dummy;
  309. v_curright(vdi_handle);
  310.  
  311. move_left(vcol)
  312. int vcol;
  313. {
  314.  int r,c;
  315.  vq_chcells(vdi_handle,&r,&c);
  316.  if (c >= vcol) v_curleft(vdi_handle);
  317. }
  318.  
  319. shift_right(from, to, line)
  320. int from, to;
  321. char line[];
  322. {
  323.  int i;
  324.  for (i = to ; i >= from ; i--) line[i+1] = line[i];
  325. }
  326.  
  327. shift_left(from, to, line)
  328. int from, to;
  329. char line[];
  330. {
  331.  int i;
  332.  for (i = from; i <= to; i++) line[i] = line[i+1];
  333. }
  334.  
  335. copy_buf_entry(src,dst)
  336. char src[];
  337. char dst[];
  338. {
  339.  int i;
  340.  for (i = 0; i < MAX_LL; i++) dst[i] = src[i];
  341. }
  342.  
  343. int dec_entry(e)
  344. int *e;
  345. return ((--(*e) < 0) ? (*e = MAX_BUF - 1) : (*e));
  346.  
  347. int inc_entry(e)
  348. int *e;
  349. return ((++(*e) >= MAX_BUF) ? (*e = 0) : (*e));
  350.  
  351. int get_line(filled, line)
  352. int *filled;
  353. char line[];
  354. {
  355. int pos, scol, srow;
  356. char ch, scan_code;
  357.  aux_received = NO;
  358.  pos = 0;
  359.  *filled = 0;
  360.  vq_curaddress(vdi_handle,&srow,&scol);
  361.  while (TRUE)
  362.  {
  363.   wait_for_char(&scan_code,&ch);
  364.   if (aux_received)
  365.    {vq_curaddress(vdi_handle,&srow,&scol);
  366.     redisplay(0,*filled-1,line);
  367.     vs_curaddress(vdi_handle,srow,scol+pos);
  368.     aux_received = NO;
  369.    };
  370.   if (ch != NUL)
  371.    {if ((ch >= ' ') && (ch <= '~'))
  372.      {if (*filled >= MAX_LL)
  373.        ring_bell();
  374.       else
  375.        {shift_right(pos, (*filled)-1, line);
  376.         line[pos] = ch;
  377.         redisplay(pos,*filled,line);
  378.         (*filled)++;
  379.         pos++;
  380.         move_right(scol+pos);
  381.        };
  382.      }
  383.      else
  384.       switch (ch)
  385.        {case CR: vdi_ch(CR); return TRUE;
  386.         case BS: if (pos == 0)
  387.                   ring_bell();
  388.                   else
  389.                    {move_left(scol+pos);
  390.                     shift_left(--pos,--(*filled),line);
  391.                     redisplay(pos,(*filled)-1,line);
  392.                    };
  393.                   break;
  394.         case DEL: if (pos == *filled)
  395.                    ring_bell();
  396.                    else
  397.                     {shift_left(pos,--(*filled),line);
  398.                      redisplay(pos,(*filled)-1,line);
  399.                     };
  400.                    break;
  401.         default: ring_bell(); break;
  402.        };
  403.    }
  404.   else
  405.    switch (scan_code)
  406.     {case UNDO_KEY:
  407.           return FALSE;
  408.      case LEFT_KEY:
  409.           if (pos == 0) ring_bell(); else move_left(scol+pos--);
  410.           break;
  411.      case RIGHT_KEY:
  412.           if (pos == *filled) ring_bell(); else move_right(scol+pos++);
  413.           break;
  414.      case UP_KEY:
  415.           pos = *filled = ring_filled[dec_entry(&last_entry)];
  416.           copy_buf_entry(ring_buffer[last_entry],line);
  417.           vs_curaddress(vdi_handle,srow,scol);
  418.           redisplay(0,(*filled)-1,line);
  419.           vs_curaddress(vdi_handle,srow,scol+pos);
  420.           break;
  421.      case DOWN_KEY:
  422.           pos = *filled = ring_filled[inc_entry(&last_entry)];
  423.           copy_buf_entry(ring_buffer[last_entry],line);
  424.           vs_curaddress(vdi_handle,srow,scol);
  425.           redisplay(0,(*filled)-1,line);
  426.           vs_curaddress(vdi_handle,srow,scol+pos);
  427.           break;
  428.      case HELP_KEY:
  429.           help();
  430.           vq_curaddress(vdi_handle,&srow,&scol);
  431.           redisplay(0,*filled-1,line);
  432.           vs_curaddress(vdi_handle,srow,scol+pos);
  433.           break;
  434.      case CLR_HOME_KEY:
  435.           vs_curaddress(vdi_handle,srow,scol);
  436.           v_eeol(vdi_handle);
  437.           pos = *filled = 0;
  438.           send_break();
  439.           aux_received = TRUE;
  440.           break;
  441.      case INSERT_KEY:
  442.           vs_curaddress(vdi_handle,srow,scol);
  443.           v_eeol(vdi_handle);
  444.           pos = *filled = 0;
  445.           break;
  446.      default: ring_bell(); break;
  447.     };
  448.  };
  449. }
  450.  
  451. send_line(filled,line)
  452. int filled;
  453. char line[];
  454. {
  455. int i;
  456.  for (i = 0; i < filled; i++) Cauxout(line[i]);
  457.  Cauxout(CR);
  458. }
  459.  
  460. terminal()
  461. {
  462. char this_line[MAX_LL];
  463. int this_fill;
  464.  vdi_ch(ESC);
  465.  vdi_ch('w');
  466.  help();
  467.  flush_rs232_buffer();
  468.  flush_terminal_buffer();
  469.  while (TRUE)
  470.   {if (!get_line(&this_fill,this_line)) break;
  471.    send_line(this_fill,this_line);
  472.    if (this_fill != 0)
  473.     {ring_filled[next_entry] = this_fill;
  474.      copy_buf_entry(this_line,ring_buffer[next_entry]);
  475.      inc_entry(&next_entry);
  476.     };
  477.    last_entry = next_entry;
  478.   };
  479. }
  480.  
  481. init_accessory()
  482. menu_id = menu_register(gl_apid,MENU_NAME);
  483.  
  484. handle_events()
  485. {
  486. int mbuf[10];
  487.  while (TRUE)
  488.   {evnt_mesag(mbuf);
  489.    {if ((mbuf[0] == AC_OPEN) && (mbuf[4] == menu_id))
  490.      {wind_update(BEG_UPDATE);
  491.       open_vdi();
  492.       if (init_terminal())
  493.           {terminal ();
  494.            exit_terminal();
  495.           };
  496.       close_vdi();
  497.       wind_update(END_UPDATE);
  498.      };
  499.    };
  500.   };
  501. }
  502.  
  503. main()
  504. {appl_init();
  505. #if ACCESSORY
  506.  init_accessory();
  507.  handle_events();
  508. #else
  509.  open_vdi();
  510.  if (init_terminal())
  511.       {terminal();
  512.        exit_terminal();};
  513.  close_vdi();
  514.  appl_exit();
  515. #endif
  516. }
  517.