home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / MODEM / UWPC201.ZIP / UW-SRC.ZIP / TERMINAL.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-31  |  10.3 KB  |  301 lines

  1. //-------------------------------------------------------------------------
  2. //
  3. // TERMINAL.CPP - Declarations for terminal clients based on neutral
  4. //          terminal descriptions.
  5. // 
  6. //  This file is part of UW/PC - a multi-window comms package for the PC.
  7. //  Copyright (C) 1990-1991  Rhys Weatherley
  8. //
  9. //  This program is free software; you can redistribute it and/or modify
  10. //  it under the terms of the GNU General Public License as published by
  11. //  the Free Software Foundation; either version 1, or (at your option)
  12. //  any later version.
  13. //
  14. //  This program is distributed in the hope that it will be useful,
  15. //  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. //  GNU General Public License for more details.
  18. //
  19. //  You should have received a copy of the GNU General Public License
  20. //  along with this program; if not, write to the Free Software
  21. //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. //
  23. // Revision History:
  24. // ================
  25. //
  26. //  Version  DD/MM/YY  By  Description
  27. //  -------  --------  --  --------------------------------------
  28. //    1.0    04/04/91  RW  Original Version of TERMINAL.CPP
  29. //    1.1    25/07/91  RW  Add handling of UW/PC clients.
  30. //
  31. // You may contact the author by:
  32. // =============================
  33. //
  34. //  e-mail: rhys@cs.uq.oz.au
  35. //    mail: Rhys Weatherley
  36. //          5 Horizon Drive
  37. //          Jamboree Heights
  38. //          Queensland 4074
  39. //        Australia
  40. //
  41. //-------------------------------------------------------------------------
  42.  
  43. #include "client.h"        // Declarations for this module
  44. #include "display.h"        // Window display declarations
  45. #include "opcodes.h"        // Opcodes for the terminal description
  46. #include "screen.h"        // Screen accessing classes
  47. #include "config.h"        // Configuration handling routines
  48. #include "uw.h"            // UW protocol declarations
  49. #include <ctype.h>        // Character typing macros
  50.  
  51. // Jump to the currently stored location.
  52. void    UWTermDesc::jump (void)
  53. {
  54.   PC = (description[PC] & 255) | ((description[PC + 1] & 255) << 8);
  55. } // UWTermDesc::jump //
  56.  
  57. // Interpret a terminal description until the next
  58. // character request, starting with the given character.
  59. void    UWTermDesc::interpret (int ch)
  60. {
  61.   unsigned char opcode;
  62.   int value;
  63.   acc = ch;            // Set accumulator from received character.
  64.  
  65.   // Loop around fetching opcodes until next character get //
  66.   while ((opcode = description[PC++]) != OP_GETCH)
  67.     switch (opcode)
  68.       {
  69.     case OP_SEND:        window -> send (acc,0); break;
  70.     case OP_SEND52:        window -> send (acc,1); break;
  71.     case OP_CR:        window -> cr (); break;
  72.     case OP_LF:        window -> lf (); break;
  73.     case OP_BS:        window -> bs (0); break;
  74.     case OP_BSWRAP:        window -> bs (1); break;
  75.     case OP_MOVE:        window -> move (regx,regy); break;
  76.     case OP_CLEAR:        window -> clear (); break;
  77.     case OP_CLREOL:        window -> clear (CLR_END_LINE); break;
  78.     case OP_CLREOS:        window -> clear (CLR_END_SCREEN); break;
  79.     case OP_CLRSOL:        window -> clear (CLR_ST_LINE); break;
  80.     case OP_CLRSOS:        window -> clear (CLR_ST_SCREEN); break;
  81.     case OP_INSLINE:    window -> insline (); break;
  82.     case OP_DELLINE:    window -> delline (); break;
  83.     case OP_INSCHAR:    window -> inschar (acc); break;
  84.     case OP_DELCHAR:    window -> delchar (); break;
  85. #ifdef    UWPC_DOS
  86.     case OP_SETATTR:    window -> setattr
  87.           (HardwareScreen.attributes[description[PC++]]); break;
  88.     case OP_SETATTR_ACC:    window -> setattr
  89.           (HardwareScreen.attributes[acc]); break;
  90.     case OP_SETSCRL:    window -> setscroll
  91.           (HardwareScreen.attributes[description[PC++]]); break;
  92.     case OP_SETSCRL_ACC:    window -> setscroll
  93.           (HardwareScreen.attributes[acc]); break;
  94. #else    /* UWPC_DOS */
  95.     case OP_SETATTR:    window -> setattr
  96.               (UWConfig.NewAttrs[description[PC++]]); break;
  97.     case OP_SETATTR_ACC:    window -> setattr
  98.               (UWConfig.NewAttrs[acc]); break;
  99.     case OP_SETSCRL:    window -> setscroll
  100.               (UWConfig.NewAttrs[description[PC++]]); break;
  101.     case OP_SETSCRL_ACC:    window -> setscroll
  102.               (UWConfig.NewAttrs[acc]); break;
  103. #endif    /* UWPC_DOS */
  104.     case OP_SETX:        regx = acc; break;
  105.     case OP_SETY:        regy = acc; break;
  106.     case OP_LOAD:        acc = description[PC++] & 255; break;
  107.     case OP_LOAD_WORD:    acc = description[PC++] & 255;
  108.                 acc |= (description[PC++] & 255) << 8;
  109.                 break;
  110.     case OP_LOAD_WIDTH:    acc = window -> width; break;
  111.     case OP_LOAD_HEIGHT:    acc = window -> height; break;
  112.     case OP_ADD:        acc += description[PC++] & 255; break;
  113.     case OP_ADD_WORD:    acc += description[PC++] & 255;
  114.                 acc += (description[PC++] & 255) << 8;
  115.                 break;
  116.     case OP_ADD_WIDTH:    acc += window -> width; break;
  117.     case OP_ADD_HEIGHT:    acc += window -> height; break;
  118.     case OP_SUB:        acc -= description[PC++] & 255; break;
  119.     case OP_SUB_WORD:    value = description[PC++] & 255;
  120.                 value |= (description[PC++] & 255) << 8;
  121.                 acc -= value;
  122.                 break;
  123.     case OP_SUB_WIDTH:    acc -= window -> width; break;
  124.     case OP_SUB_HEIGHT:    acc -= window -> height; break;
  125.     case OP_CMP:        compare = acc - (description[PC++] & 255);
  126.                 break;
  127.     case OP_CMP_WORD:    value = description[PC++] & 255;
  128.                 value |= (description[PC++] & 255) << 8;
  129.                 compare = acc - value;
  130.                 break;
  131.     case OP_CMP_WIDTH:    compare = acc - (window -> width); break;
  132.     case OP_CMP_HEIGHT:    compare = acc - (window -> height); break;
  133.     case OP_SWITCH:        if (acc == (description[PC++] & 255))
  134.                   jump ();
  135.                  else
  136.                   PC += 2;    // Skip jump address.
  137.                 break;
  138.     case OP_SWITCH_WORD:    value = description[PC++] & 255;
  139.                 value |= (description[PC++] & 255) << 8;
  140.                 if (acc == value)
  141.                   jump ();
  142.                  else
  143.                   PC += 2;    // Skip jump address.
  144.                 break;
  145.     case OP_JE:        if (compare == 0)
  146.                   jump ();
  147.                  else
  148.                   PC += 2;
  149.                 break;
  150.     case OP_JNE:        if (compare != 0)
  151.                   jump ();
  152.                  else
  153.                   PC += 2;
  154.                 break;
  155.     case OP_JA:        if (compare > 0)
  156.                   jump ();
  157.                  else
  158.                   PC += 2;
  159.                 break;
  160.     case OP_JAE:        if (compare >= 0)
  161.                   jump ();
  162.                  else
  163.                   PC += 2;
  164.                 break;
  165.     case OP_JB:        if (compare < 0)
  166.                   jump ();
  167.                  else
  168.                   PC += 2;
  169.                 break;
  170.     case OP_JBE:        if (compare <= 0)
  171.                   jump ();
  172.                  else
  173.                   PC += 2;
  174.                 break;
  175.     case OP_JSR:        stack[SP++] = PC + 2;
  176.     case OP_JMP:        jump (); break;
  177.     case OP_RET:        PC = stack[--SP]; break;
  178.     case OP_REMOTE:        send (acc); break;
  179.     case OP_ESCAPE:        ++PC; break;    /* Ignore for now */
  180.     case OP_ESCAPE_WORD:    PC += 2; break;    /* Ignore for now */
  181.     case OP_TAB:        window -> tab (); break;
  182.     case OP_BELL:        window -> bell (); break;
  183.     case OP_SAVEXY:        savex = window -> x;
  184.                 savey = window -> y;
  185.                 break;
  186.     case OP_RESTXY:        window -> move (savex,savey); break;
  187.     case OP_GETXY:        regx = window -> x;
  188.                 regy = window -> y;
  189.                 break;
  190.     case OP_GETX:        acc = regx; break;
  191.     case OP_GETY:        acc = regy; break;
  192.     case OP_SET:        flags |= 1 << (description[PC++]); break;
  193.     case OP_RESET:        flags &= ~(1 << (description[PC++])); break;
  194.     case OP_TEST:        compare = flags & (1 << (description[PC++]));
  195.                 break;
  196.     case OP_SCRLUP:        window -> scrollscreen (1); break;
  197.     case OP_SCRLDN:        window -> scrollscreen (0); break;
  198.     case OP_RESARR:        for (value = 0;value < TERM_ARGS;++value)
  199.                   argarray[value] = -1;    // Set defaults.
  200.                 index = 0;
  201.                 base = -1;
  202.                 break;
  203.     case OP_GETARG:        if (isdigit (acc))
  204.                   {
  205.                     if (argarray[index] == -1)
  206.                       argarray[index] = 0;
  207.                     argarray[index] = (argarray[index] * 10)
  208.                         + (acc - '0');
  209.                     PC -= 2;    // Backup and do instr again
  210.                   }
  211.                  else
  212.                   ++index;    // Arg recognised - move on
  213.                 break;
  214.     case OP_GETA:        acc = argarray[(description[PC] & 255) + base];
  215.                 if (acc == -1)
  216.                   acc = description[PC + 1] & 255;
  217.                 PC += 2;
  218.                 break;
  219.     case OP_DEC:        --index; compare = index; break;
  220.     case OP_SHIFT:        ++base; break;
  221.     case OP_SETC:        index = acc; break;
  222.     case OP_SAVEATTR:    saveattr = window -> getattr (); break;
  223.     case OP_RESTATTR:    window -> setattr (saveattr); break;
  224.     case OP_INSBLANK:    window -> inschar (-1); break;
  225.     case OP_CLIENT:        UWMaster.startclient (acc);
  226.                 break;
  227.     default:        break;
  228.       } // switch //
  229. } // UWTermDesc::interpret //
  230.  
  231. // Process any key mappings for this terminal type.
  232. void    UWTermDesc::key (int keypress)
  233. {
  234.   int posn,match;
  235.   if (keypress < 0x3B00)        // ASCII and normal ALT keys.
  236.     {
  237.       UWTerminal::key (keypress);    // Process keypress normally.
  238.       return;
  239.     }
  240.   posn = keys;                // Want to scan key mapping table.
  241.   while (1)
  242.     {
  243.       match = (description[posn] & 255) | ((description[posn + 1] & 255) << 8);
  244.       posn += 2;
  245.       if (!match || keypress == match)
  246.         break;                // Found the key or no match at all.
  247.       posn += description[posn] & 255;    // Skip past the string to the next one
  248.     }
  249.   if (match)
  250.     {
  251.       // Output the characters associated with the key mapping //
  252.       int ch;
  253.       posn++;                // Skip string length value.
  254.       while ((ch = (description[posn++] & 255)) != 0)
  255.     send (ch);            // Send mapping to remote machine.
  256.     }
  257.    else
  258.     UWTerminal::key (keypress);        // Process the key normally.
  259. } // UWTermDesc //
  260.  
  261. // Process a character from the remote server.  This may
  262. // be called at any time while the client is active.
  263. void    UWTermDesc::remote (int ch)
  264. {
  265.   if (description == 0)
  266.     {
  267.       UWTerminal::remote (ch);        // Emulate a "really dumb" terminal.
  268.       return;
  269.     }
  270.    else
  271.     interpret (ch);            // Interpret the emulation.
  272. } // UWTermDesc::remote //
  273.  
  274. // Set the description to be used for the terminal
  275. // emulation of this terminal object, and start it up.
  276. void    UWTermDesc::setemul (unsigned char far *desc)
  277. {
  278.   int version;
  279.   if (desc == 0)
  280.     {
  281.       description = desc;        // Just disable the emulation.
  282.       return;
  283.     }
  284.   // Get the starting address from the description and initialise.
  285.   PC = ((*desc) & 255) | (((*(desc + 1)) & 255) << 8);
  286.   keys = ((*(desc + 2)) & 255) | (((*(desc + 3)) & 255) << 8);
  287.   version = ((*(desc + 4)) & 255) | (((*(desc + 5)) & 255) << 8);
  288.   if (version < 0x100 || version > UW_TERM_VERSION)
  289.     return;                // Illegal terminal description.
  290.   description = desc + TERM_HEADER_SIZE; // Skip past starting index value.
  291.   regx = 0;                // Start all registers at 0.
  292.   regy = 0;
  293.   flags = 0;
  294.   compare = 0;
  295.   SP = 0;
  296.   savex = 0;
  297.   savey = 0;
  298.   saveattr = window -> getattr ();
  299.   interpret (0);            // Execute till first character get.
  300. } // UWTermDesc::setemul //
  301.