home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 15 / 15.iso / s / s038 / 1.ddi / SUPP.LIF / RTERM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-06  |  25.0 KB  |  1,021 lines

  1.  
  2. /*
  3.  *   RTERM.C
  4.  *
  5.  *   Terminal emulator for iRMX                                    Version  1.0
  6.  *
  7.  * HISTORY:
  8.  *
  9.  *     - Version X.01 to X.10:
  10.  *
  11.  *        Prototype software, many features added
  12.  *        and many bug fixes.                Nam Ly 02/29/90
  13.  *
  14.  *     - Version 1.0:
  15.  *        First version checked into the source data base, many features
  16.  *        added and many bug fixes.            Nam Ly 09/15/90
  17.  *
  18.  */
  19.  
  20. #include <stdio.h>
  21. #include <dos.h>
  22. #include <fcntl.h>
  23. #include <sys\types.h>
  24. #include <sys\stat.h>
  25. #include "rterm.h"
  26. /*
  27.  * -- External declaration
  28.  */
  29. extern int kb_char(void);
  30. extern void set_dos_flag(void);
  31.  
  32. extern unsigned pascal RQLookupObject(unsigned, unsigned char far *, unsigned, unsigned far *);
  33. extern void pascal RQSendMessage(unsigned, unsigned, unsigned, unsigned far *);
  34. extern unsigned pascal RQGetTaskTokens(unsigned char, unsigned far *);
  35.  
  36. #define VERSION "V1.0"
  37. char version[] = "program_version_number=V1.0program_name=RTERM";
  38.  
  39. static char cpyrt[] = {0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,};
  40. static char name[] = " 1989 Intel Corporation";
  41.  
  42. #define EOK                0
  43. #define rootjob            3
  44. #define callingtask        0
  45.  
  46. static unsigned    roottoken;
  47. static unsigned    vm86j;
  48. static unsigned    Kb_Mux;
  49. static unsigned    except;
  50. static unsigned    response;
  51. static unsigned    segment;
  52. static unsigned    rootjobtoken;
  53.  
  54. unsigned char vm86[12] ={10,'R','?','V','M','8','6','_','J','O','B',0};
  55.  
  56. unsigned char kb_mb[14] ={12,'R','?','K','B','_'
  57.                             ,'M','A','I','L','B','O','X',0};
  58.  
  59.    union REGS ireg;
  60. /*
  61.  * Standard way of doing things
  62.  */
  63. static void set_cursor(unsigned char, unsigned char);
  64. static unsigned int get_key(void);
  65. static void set_page(unsigned int);
  66. static void get_mode(void);
  67. static void set_mode(unsigned char);
  68. static unsigned char get_cols(void);
  69. static void str_copy(int *, int *, unsigned int);
  70. static void update_screen(void);
  71. static void restore(void);
  72. static void set_screen_attrib(void);
  73. static void set_forg_col(void);
  74. static void set_back_col(void);
  75. static void send_data(unsigned int);
  76. static unsigned int restore_r_screen(void);
  77. static unsigned int save_r_screen(void);
  78.  
  79. OUT_BUFFER far *out_buf= MK_FP (0x0040, 0xE0);
  80. IN_BUFFER  far *in_buf = MK_FP (0x0040, 0xE2);
  81.  
  82. /*
  83.  * -----------------------   Main Program  ------------------------------------
  84.  */
  85. main()
  86. {
  87.    printf("\niRMX Terminal emulator, ");
  88.    printf(VERSION);
  89.    printf("\n%s%s\n",cpyrt,name);
  90.  
  91.   /*
  92.    * The following copyright message is printed ONLY because of the
  93.    * licensing agreement associated with the Microsoft C compiler.
  94.    * It must be removed if this utility is ever generated with a 
  95.    * different compiler.
  96.    */
  97.    printf("%s (c) Microsoft Corp 1984, 1985, 1986, 1987.",cpyrt);
  98.    printf(" All rights reserved.\n\n");
  99.  
  100.   /*
  101.    * initialize save buffer ptr
  102.    */
  103.    save_buff = (int far *)save_buffer;
  104.   /*
  105.    * Set up the screen attribute
  106.    */
  107.    forground  = (WHITE | HI_INTENS);
  108.    background = BLUE;
  109.  
  110.    r_term.row    = CRTROWS;         /* Set number of rows    */
  111.  
  112.    get_mode();
  113.    r_term.column = get_cols();      /* Get columns           */
  114.    r_term.crtlen = r_term.row * r_term.column;
  115.  
  116.    r_term.console_state = 0;        /*     ????              */
  117.    r_term.output_state  = 0;        /*     ????              */
  118.    r_term.routine_index = 0;        /*     default           */
  119.  
  120.    r_term.displayw = ((background << 4) + forground) << 8;  /* Set colors */
  121.    /*
  122.     * Find base address of display memory
  123.     */
  124.    FP_SEG(video_p) = (r_term.mode == 7) ?  0xb000 :  0xb800;
  125.    FP_OFF(video_p) = 0;
  126.    /*
  127.     * save stuff on the DOS screen
  128.     */
  129.    movedata (FP_SEG(video_p), FP_OFF(video_p),       /* source seg. off. */
  130.              FP_SEG(save_buff), FP_OFF(save_buff),   /* destin seg. off. */
  131.              4000);                                  /* count            */
  132.  
  133.    if ( !restore_r_screen() )
  134.    {
  135.       /*
  136.        * blank the screen
  137.        */
  138.        temp_ptr =(int far *) video_p;
  139.        for(tmp=0; tmp < r_term.crtlen; tmp++)
  140.        {
  141.          (*temp_ptr++) = r_term.displayw;
  142.        }
  143.        /*
  144.         * put the cursor to top of screen
  145.         */
  146.        r_term.row = 0;
  147.        r_term.column = 0;
  148.        set_cursor(r_term.row, r_term.column);
  149.     }
  150.     Stop_output = FALSE;
  151.  
  152.    /*
  153.     * initialize input/output buffer @ iRMX comm. area
  154.     */
  155.    if( in_buf->count > 29 )
  156.       in_buf->count   = 0;
  157.  
  158.    Num_chars          = 0;
  159.    out_buf->flag_byte = 0;
  160.    out_buf->data_byte = 0;
  161.  
  162.     roottoken = RQGetTaskTokens(rootjob,&except);
  163.     if (except != EOK)
  164.     {
  165.         printf("RQGetTaskTokens fail, error: %X\n", except);
  166.         exit(0);
  167.     }
  168.     vm86j = RQLookupObject(roottoken,&vm86[0],0,&except);
  169.     if (except != EOK)
  170.     {
  171.         printf("RQLookupObject fail, error: %X\n", except);
  172.         exit(0);
  173.     }
  174.  
  175.     Kb_Mux = RQLookupObject(vm86j,&kb_mb[0],0,&except);
  176.     if (except != EOK)
  177.     {
  178.         printf("RQLookupObject fail, error: %X\n", except);
  179.         exit(0);
  180.     }
  181.  
  182.     response    = 0;
  183.     segment        = Kb_Mux;
  184.  
  185.  
  186.    for (;;)   /*  forever loop */
  187.    {
  188.       if( kb_char() )                 /* keyboard data is available */
  189.       {
  190.         if(Stop_output)               /* output is stopped          */
  191.         {
  192.           Stop_output = FALSE;        /* then enable screen output  */
  193.           temp = get_key();           /* and flush the kb buffer    */
  194.         }
  195.         else
  196.         {
  197.           switch (temp = get_key())
  198.           {
  199.             case 0x0E08:              /* Backspace key       */
  200.                  temp = 0x7f;
  201.                  send_data(temp);
  202.                  break;
  203.             case 0x1011:              /* Control-Q           */
  204.                  Stop_output = FALSE;
  205.                  break;
  206.             case 0x1117:              /* Control-W           */
  207.                  temp = 0x17;
  208.                  send_data(temp);
  209.                  break;
  210.             case 0x1312:              /* Control-R           */
  211.                  temp = 0x12;
  212.                  send_data(temp);
  213.                  break;
  214.             case 0x1910:              /* Control-P           */
  215.                  temp = 0x10;
  216.                  send_data(temp);
  217.                  break;
  218.             case 0x1F13:              /* Control-S           */
  219.                  Stop_output = TRUE;
  220.                  break;
  221.             case 0x2C1A:              /* Control-Z           */
  222.                  temp = 0x1A;
  223.                  send_data(temp);
  224.                  break;
  225.             case 0x2D18:              /* Control-X           */
  226.                  temp = 0x18;
  227.                  send_data(temp);
  228.                  break;
  229.             case 0x8200:              /* ALT (minus)         */
  230.                  set_back_col();
  231.                  break;
  232.             case 0x8300:              /* ALT (plus)          */
  233.                  set_forg_col();
  234.                  break;
  235.  
  236.             case 0x2d00:              /* ALT-X  exit program */
  237.                  save_r_screen();
  238.                  restore();           /* restore the screen  */
  239.                  exit(0);
  240.             case 0x2300:              /* ALT-H key           */
  241.                  break;
  242.             case 0x2E03:              /* Control-C key       */
  243.                  break;
  244.  
  245.             case 0x4700:              /* Home key            */
  246.                  temp = 0x1d;
  247.                  send_data(temp);
  248.                  break;
  249.  
  250.             case 0x4900:              /* Page-up key         */
  251.                  break;
  252.             case 0x4F00:              /* End key             */
  253.                  break;
  254.             case 0x5100:              /* Page down           */
  255.                  break;
  256.  
  257.             case 0x4800:              /* Up arrow            */
  258.                  temp = 0x1e;
  259.                  send_data(temp);
  260.                  break;
  261.             case 0x4B00:              /* Left arrow          */
  262.                  temp = 0x1f;
  263.                  send_data(temp);
  264.                  break;
  265.             case 0x4D00:              /* Right arrow         */
  266.                  temp = 0x19;
  267.                  send_data(temp);
  268.                  break;
  269.             case 0x5000:              /* Down arrow          */
  270.                  temp = 0x1c;
  271.                  send_data(temp);
  272.                  break;
  273.  
  274.             case 0x7500:              /* Ctrl-End            */
  275.                  *bflag_ptr = 0x1234; /* skip the mem. test  */
  276.                  outp(0x64, 0xFC);    /* do warm reset       */
  277.                  break;
  278.  
  279.             case 0x7700:              /* Ctrl-Home           */
  280.                  temp = 0xEE;         /* Break to SDM mon    */
  281.                  send_data(temp);
  282.                  break;
  283.  
  284.             case 0x7200:              /* Ctrl-SysRq          */
  285.             case 0x7600:              /* Ctrl-Pgdn           */
  286.                  temp = 0xEF;         /* reload DOS frm. RMX */
  287.                  send_data(temp);
  288.                  break;
  289.  
  290.             default:
  291.                        /* send characters to the comm area for iRMX */
  292.                  send_data(temp);
  293.                  break;
  294.           }
  295.         }
  296.       }
  297.  
  298.      /*
  299.       * check the comm. area and process characters from iRMX driver
  300.       * and display them.
  301.       */
  302.       if (((in_buf->count) > 0) && (Num_chars == 0))
  303.       {
  304.         /*
  305.          * copy data from iRMX to local buffer
  306.          */
  307.         for(tmp=0; tmp < in_buf->count; tmp++)
  308.            Temp_str[tmp] = in_buf->data_byte[tmp];
  309.  
  310.         Num_chars = in_buf->count;   /* save count for update_screen */
  311.         in_buf->count = 0;           /* tell RMX we read the data    */
  312.        }
  313.  
  314.        update_screen();             /*    write data to screen       */
  315.  
  316.    }        /* end forever!!!??? */
  317.  
  318.    restore();                       /*    restore the DOS screen     */
  319.    exit(0);
  320.  
  321. } /* --------------------- end of main code section ------------------------ */
  322.  
  323. /*
  324.  *  -----------------------  Local procedures -------------------------------
  325.  *
  326.  * Title : update_screen
  327.  *         Process characters from the input data segment and update screen
  328.  */
  329.  
  330. void update_screen()
  331. {
  332.  
  333. if ( ( Stop_output ) || ( Num_chars == 0) )
  334.   return;
  335.  
  336. for (index = 0; index <= Num_chars - 1; index++)
  337. {
  338.     /*
  339.      *  Get one character from buffer
  340.      */
  341.     X_char =  Temp_str[index];
  342.  
  343.     switch (r_term.routine_index)
  344.     {
  345.     case 0 :
  346.         /* routine$index = 0 - ordinary character */ 
  347.         {
  348.         if (X_char < DISPLAYABLECHAR &&
  349.                      (r_term.console_state & LITERALMODE) == 0)
  350.             switch (X_char)
  351.             {
  352.             case 0 :
  353.                 {
  354.                 /* CASE 0 -     */
  355.                 }
  356.                 break;
  357.             case 1 :            /* CASE 1 - erase rest of screen */
  358.                 {
  359.                     temp_w = r_term.displayw + BLANKCHARACTER;
  360.                     t_count = (CRTCOLS * (CRTROWS - r_term.row - 1) + CRTCOLS - r_term.column);
  361.                     des_ptr =(int far *) video_p+(r_term.row * CRTCOLS + r_term.column);
  362.                     for(tmp=0; tmp < t_count; ++tmp)
  363.                     {
  364.                         (*des_ptr++) = temp_w;
  365.                     }
  366.                 }
  367.                 break;
  368.             case 2 :            /* CASE 2 - erase line */
  369.                 {
  370.                     temp_w = r_term.displayw + BLANKCHARACTER;
  371.                     t_count = CRTCOLS;
  372.                     des_ptr =(int far *) video_p+(r_term.row * CRTCOLS);
  373.                     for(tmp=0; tmp < t_count; ++tmp)
  374.                     {
  375.                         (*des_ptr++) = temp_w;
  376.                     }
  377.                 }
  378.                 break;
  379.             case 3 :            /* CASE 3 - erase rest of line */
  380.                 {
  381.                     temp_w = r_term.displayw + BLANKCHARACTER;
  382.                     t_count = CRTCOLS - r_term.column;
  383.                     des_ptr =(int far *) video_p+(r_term.row * CRTCOLS + r_term.column);
  384.                     for(tmp=0; tmp < t_count; ++tmp)
  385.                     {
  386.                         (*des_ptr++) = temp_w;
  387.                     }
  388.                 }
  389.                 break;
  390.             case 4 :            /* CASE 4 - cursor absolute */
  391.                 {
  392.                 r_term.routine_index = 1;
  393.                 }
  394.                 break;
  395.             case 5 :            /* CASE 5 - line delete */
  396.                 {
  397.                     t_count = (LASTROW - r_term.row) * CRTCOLS * 2;
  398.                     src_ptr =(int far *) video_p+((r_term.row + 1) * CRTCOLS);
  399.                     des_ptr =(int far *) video_p+(r_term.row * CRTCOLS);
  400.  
  401.                     movedata (FP_SEG(src_ptr), FP_OFF(src_ptr), /* source seg. off. */
  402.                             FP_SEG(des_ptr), FP_OFF(des_ptr),   /* destin seg. off. */
  403.                             t_count);                           /* count            */
  404.  
  405.                     temp_w = r_term.displayw + BLANKCHARACTER;
  406.                     t_count = CRTCOLS;
  407.                     des_ptr =(int far *) video_p+(LASTROW * CRTCOLS);
  408.                     for(tmp=0; tmp < t_count; ++tmp)
  409.                     {
  410.                         (*des_ptr++) = temp_w;
  411.                     }
  412.                 }
  413.                 break;
  414.             case 6 :            /* CASE 6 - line insert */
  415.                 {
  416.                     t_count = (LASTROW - r_term.row) * CRTCOLS;
  417.                     src_ptr =(int far *) video_p+(r_term.row * CRTCOLS) + t_count;
  418.                     des_ptr =(int far *) video_p+((r_term.row + 1) * CRTCOLS) + t_count;
  419.                     for(tmp=0; tmp < t_count; ++tmp)
  420.                     {
  421.                         (*des_ptr--) = (*src_ptr--);
  422.                     }
  423.  
  424.                     temp_w = r_term.displayw + BLANKCHARACTER;
  425.                     t_count = CRTCOLS;
  426.                     des_ptr =(int far *) video_p+(r_term.row * CRTCOLS);
  427.                     for(tmp=0; tmp < t_count; ++tmp)
  428.                     {
  429.                         (*des_ptr++) = temp_w;
  430.                     }
  431.                 }
  432.                 break;
  433.             case 7 :            /* CASE 7 - bell */
  434.                 {
  435.                 }
  436.                 break;
  437.             case 8 :            /* CASE 8 - backspace */
  438.                 {
  439.                     if (r_term.column == 0)
  440.                     {
  441.                         if (r_term.row > 0)
  442.                         {
  443.                             --r_term.row;
  444.                             r_term.column = LASTCOL;
  445.                         }
  446.                     }
  447.                     else
  448.                         --r_term.column;
  449.                 }
  450.                 break;
  451.             case 9 :            /* CASE 9 - tab */
  452.                 {
  453.                 /* CASE 9 - tab */
  454.                 }
  455.                 break;
  456.             case 10 :            /* CASE 0A - linefeed */
  457.                 {
  458.                     if (r_term.row >= LASTROW)
  459.                     {
  460.                         t_count = CRTCOLS * LASTROW * 2;
  461.                         src_ptr =(int far *) video_p + CRTCOLS;
  462.                         des_ptr =(int far *) video_p;
  463.  
  464.                         movedata (FP_SEG(src_ptr), FP_OFF(src_ptr), /* source seg. off. */
  465.                                 FP_SEG(des_ptr), FP_OFF(des_ptr),   /* destin seg. off. */
  466.                                 t_count);                           /* count            */
  467.  
  468.                         temp_w = r_term.displayw + BLANKCHARACTER;
  469.                         t_count = CRTCOLS;
  470.                         des_ptr =(int far *) video_p+(CRTCOLS * LASTROW);
  471.                         for(tmp=0; tmp < t_count; ++tmp)
  472.                         {
  473.                             (*des_ptr++) = temp_w;
  474.                         }
  475.                     }
  476.                     else
  477.                         ++r_term.row;
  478.                 }
  479.                 break;
  480.             case 11 :            /* CASE 0B - set color */
  481.                 {
  482.                     r_term.routine_index = 3;
  483.                 }
  484.                 break;
  485.             case 12 :            /* CASE 0C - erase screen */
  486.                 {
  487.                     temp_w = r_term.displayw + BLANKCHARACTER;
  488.                     des_ptr =(int far *) video_p;
  489.                     for(tmp=0; tmp < r_term.crtlen; ++tmp)
  490.                     {
  491.                         (*des_ptr++) = temp_w;
  492.                     }
  493.  
  494.                     r_term.row = 0;
  495.                     r_term.column = 0;
  496.                 }
  497.                 break;
  498.             case 13 :            /* CASE 0D - CR */
  499.                 {
  500.                 r_term.column = 0;
  501.                 }
  502.                 break;
  503.             case 14 :            /* CASE 0E - literal */
  504.                 {
  505.                 r_term.console_state = r_term.console_state | LITERALMODE;
  506.                 }
  507.                 break;
  508.             case 15 :            /* CASE 0F - set raw mode */
  509.                 {
  510.                 r_term.console_state = r_term.console_state | RAWMODE;
  511.                 }
  512.                 break;
  513.             case 16 :            /* CASE 10 - set cooked mode */
  514.                 {
  515.                 r_term.console_state = r_term.console_state & ~RAWMODE;
  516.                 }
  517.                 break;
  518.             case 17 :            /* CASE 11 - X-ON    */
  519.                 {
  520.                 /* CASE 11 - X-ON    */
  521.                 }
  522.                 break;
  523.             case 18 :            /* CASE 12         */
  524.                 {
  525.                 /* CASE 12         */
  526.                 }
  527.                 break;
  528.             case 19 :            /* CASE 13 - X-OFF */
  529.                 {
  530.                 /* CASE 13 - X-OFF */
  531.                 }
  532.                 break;
  533.             case 20 :            /* CASE 14         */
  534.                 {
  535.                 /* CASE 14 */
  536.                 }
  537.                 break;
  538.             case 21 :            /* CASE 15         */
  539.                 {
  540.                 /* CASE 15 */
  541.                 }
  542.                 break;
  543.             case 22 :            /* CASE 16         */
  544.                 {
  545.                 /* CASE 16 */
  546.                 }
  547.                 break;
  548.             case 23 :            /* CASE 17         */
  549.                 {
  550.                 /* CASE 17 */
  551.                 }
  552.                 break;
  553.             case 24 :            /* CASE 18         */
  554.                 {
  555.                 /* CASE 18 */
  556.                 }
  557.                 break;
  558.             case 25 :            /* CASE 19 - cursor right */
  559.                 {
  560.                     if (r_term.column >= LASTCOL)
  561.                     {
  562.                         if (r_term.row < LASTROW)
  563.                         {
  564.                             ++r_term.row;
  565.                             r_term.column = 0;
  566.                         }
  567.                     }
  568.                     else
  569.                     {
  570.                         ++r_term.column;
  571.                     }
  572.                 }
  573.                 break;
  574.             case 26 :            /* CASE 1A  */
  575.                 {
  576.                 /* CASE 1A */
  577.                 }
  578.                 break;
  579.             case 27 :            /* CASE 1B */
  580.                 {
  581.                 /* CASE 1B */
  582.                 }
  583.                 break;
  584.             case 28 :            /* CASE 1C - cursor down */
  585.                 {
  586.                 if (r_term.row != LASTROW) ++r_term.row;
  587.                 }
  588.                 break;
  589.             case 29 :            /* CASE 1D - cursor home */
  590.                 {
  591.                     r_term.row    = 0;
  592.                     r_term.column = 0;
  593.                 }
  594.                 break;
  595.             case 30 :            /* CASE 1E - cursor up */
  596.                 {
  597.                     if (r_term.row != 0) --r_term.row;
  598.                 }
  599.                 break;
  600.             case 31 :            /* CASE 1F - cursor left */
  601.                 {
  602.                     if (r_term.column == 0)
  603.                     {
  604.                         if (r_term.row > 0)
  605.                         {
  606.                             --r_term.row;
  607.                             r_term.column = LASTCOL;
  608.                         }
  609.                     }
  610.                     else
  611.                         --r_term.column;
  612.                 }
  613.                 break;
  614.             }    /* CASE char */
  615.  
  616.         else    /* process normal character */
  617.         {
  618.             r_term.console_state = r_term.console_state & ~LITERALMODE;
  619.  
  620.             /* write the characrer to display ram at current cursor pos. */
  621.  
  622.             (*video_p)[r_term.row * CRTCOLS + r_term.column] = r_term.displayw + X_char;
  623.  
  624.             /* update cursor position */
  625.  
  626.             ++r_term.column;
  627.  
  628.             if (r_term.column > LASTCOL)
  629.             {
  630.                 r_term.column = 0;
  631.                 if (r_term.row >= LASTROW)
  632.                 {
  633.                     /* scroll the display up one line */
  634.                     t_count = CRTCOLS * LASTROW * 2;
  635.                     src_ptr =(int far *) video_p + CRTCOLS;
  636.                     des_ptr =(int far *) video_p;
  637.  
  638.                     movedata (FP_SEG(src_ptr), FP_OFF(src_ptr), /* source seg. off. */
  639.                             FP_SEG(des_ptr), FP_OFF(des_ptr),   /* destin seg. off. */
  640.                             t_count);                           /* count            */
  641.  
  642.                     /* erase the last line on the screen */
  643.                     temp_w = r_term.displayw + BLANKCHARACTER;
  644.                     t_count = CRTCOLS;
  645.                     des_ptr =(int far *) video_p+(CRTCOLS * LASTROW);
  646.                     for(tmp=0; tmp < t_count; ++tmp)
  647.                     {
  648.                         (*des_ptr++) = temp_w;
  649.                     }
  650.                 }
  651.                 else
  652.                     ++r_term.row;
  653.             }
  654.         }
  655.     }    /* of case 0    => routine$index = 0 */
  656.     break;
  657.  
  658.     case 1 :
  659.         /* routine$index = 1 - second byte of absolute cursor position */
  660.         {
  661.             r_term.routine_index = 2;
  662.             temp = X_char - 0x20;
  663.             if (temp < CRTROWS)
  664.                 r_term.row = temp;
  665.             else
  666.                 r_term.row = 0;
  667.         }
  668.         break;
  669.  
  670.     case 2 :
  671.         /* routine$index = 2 - third byte of absolute cursor position */
  672.         {
  673.             r_term.routine_index = 0;
  674.             temp = X_char - 0x20;
  675.             if (temp <= CRTCOLS)
  676.                 r_term.column = temp;
  677.             else
  678.                 r_term.column = 0;
  679.         }
  680.         /* routine$index = 3 - second byte of set foreground color */
  681.         break;
  682.     case 3 :
  683.         {
  684.             r_term.routine_index = 0;
  685.             r_term.displayw = X_char * 256;
  686.         }
  687.         break;
  688.     }    /* CASE routine$index */
  689. }    /* of DO index */
  690.  
  691. End_of_output:
  692.  
  693. Num_chars = 0;
  694.  
  695. set_cursor(r_term.row, r_term.column);
  696.  
  697. }    /* End update_screen */
  698.  
  699.  
  700. /*
  701.  *  Title:    get_mode
  702.  *            Determine the display mode.
  703.  *
  704.  *   Return: r_term.mode
  705.  *           r_term.page
  706.  *           r_term.column
  707.  */
  708.  
  709. void get_mode(void)
  710. {
  711.    ireg.h.ah = 0x0f;
  712.    int86(0x10, &ireg, &ireg);
  713.  
  714.    r_term.mode = (ireg.h.al);
  715.    r_term.page = (ireg.h.bh);
  716.    r_term.column = (ireg.h.ah);
  717. }
  718.  
  719. /*
  720.  *  Title:   set_mode
  721.  *           Set the display mode for the video device.
  722.  */
  723.  
  724. void set_mode(unsigned char mode)
  725. {
  726.    ireg.h.ah = 0x00;                      /* Function 0 */
  727.    ireg.h.al = mode;
  728.  
  729.    int86(0x10, &ireg, &ireg);
  730. }
  731.  
  732. /*
  733.  *  Title:    get_cols()
  734.  *            Determine the number of columns being used by the video display
  735.  *            via interrupt 0x10, function 0x0f.
  736.  *  Return:   number of columns (40 or 80).
  737.  */
  738.  
  739. unsigned char get_cols(void)
  740. {
  741.    ireg.h.ah = 0x0f;
  742.  
  743.    int86(0x10, &ireg, &ireg);            /* mode is returned in ireg.h.al  */
  744.  
  745.    if (ireg.h.al < 2)
  746.       return 40;                         /* 40-column mode                 */
  747.    if (ireg.h.al > 3 && ireg.h.al != 7)
  748.       return 0;                          /* Return 0 for any graphics mode */
  749.    else
  750.       return 80;                         /* 80-column mode                 */
  751. }
  752.  
  753.  
  754. /*
  755.  *  Title:  set_page
  756.  *          Set the currently-active video page.
  757.  */
  758.  
  759. #define MAXPAGE   8
  760.  
  761. void set_page(unsigned int page)
  762. {
  763.    ireg.h.ah = 0x05;                      /* Function */
  764.    ireg.h.al = (page % MAXPAGE);
  765.  
  766.    int86(0x10, &ireg, &ireg);
  767. }
  768.  
  769.  
  770. /*
  771.  *  Title:  read_cursor()
  772.  *          Read the current row and column position of the cursor.
  773.  *  Input:  int *row and int *col
  774.  */
  775.  
  776. void read_cursor(int *row, int *col)
  777. {
  778.    ireg.h.ah = 0x03;                   /* Function     */
  779.    ireg.h.bh = r_term.page;             /* Current page */
  780.    int86(0x10, &ireg, &ireg);
  781.  
  782.    *row = (int) ireg.h.dh;
  783.    *col = (int) ireg.h.dl;
  784. }
  785.  
  786. /*
  787.  * Title:    set_cursor
  788.  */
  789.  
  790. void set_cursor(unsigned char row, unsigned char col)
  791. {
  792.    ireg.h.ah = 0x02;                   /* Function */
  793.    ireg.h.bh = r_term.page;            /* Current page */
  794.    ireg.h.dh = row;
  795.    ireg.h.dl = col;
  796.  
  797.    int86(0x10, &ireg, &ireg);
  798.  
  799. }
  800.  
  801. /*
  802.  *  Title:  send_data
  803.  *          Copy a byte of data to iRMX buffer
  804.  */
  805. void send_data(unsigned int data_byte)
  806. {
  807.     if (!(out_buf->flag_byte))
  808.     {
  809.         out_buf->data_byte = (unsigned char) (data_byte & 0x00ff);
  810.         out_buf->flag_byte = TRUE;
  811.         RQSendMessage(Kb_Mux, segment, response, &except);
  812.         if (except != EOK)
  813.         {
  814.             printf("RQSendMessage fail, error: %X\n", except);
  815.             exit(0);
  816.         }
  817.  
  818.     }
  819. }
  820.  
  821.  
  822. /*
  823.  * Title:  get_key
  824.  */
  825.  
  826. unsigned int get_key()
  827. {
  828.     ireg.h.ah = 0;                  /* Get next key from keyboard   */
  829.  
  830.     int86(0x16, &ireg, &ireg);
  831.     return(ireg.x.ax);
  832. }
  833.  
  834. /*
  835.  * Title restore
  836.  *        Restore the screen
  837.  */
  838.  
  839. void restore()
  840. {
  841.  movedata (FP_SEG(save_buff), FP_OFF(save_buff),   /* source seg. off. */
  842.            FP_SEG(video_p), FP_OFF(video_p),       /* destin seg. off. */
  843.           4000);                                   /* count            */
  844.  
  845. r_term.row = 25;
  846. r_term.column = 0;
  847. set_cursor(r_term.row, r_term.column);
  848.  
  849. }
  850.  
  851. /*
  852.  * Title:    str_copy()
  853.  */
  854.  
  855. void str_copy(int *source, int *target, unsigned int count)
  856. {
  857.  
  858.    while (count !=0)
  859.    {
  860.       *target++ = *source++;
  861.       --count;
  862.    }
  863. }
  864.  
  865. /*
  866.  *  Change forground color
  867.  */
  868. void set_forg_col()
  869. {
  870.     if( ((++forground) && 0x1f) > 0x0f )
  871.         forground = 0;
  872.     if (forground == background)
  873.     {
  874.         if( ((++forground) && 0x1f) > 0x0f )
  875.             forground = 0;
  876.     }
  877.     r_term.displayw = ((((background << 4) + forground) << 8) & 0x7f00 );
  878.     set_screen_attrib();
  879. }
  880.  
  881. /*
  882.  *  Change background color
  883.  */
  884. void set_back_col()
  885. {
  886.     if( ((++background) && 0x0f) > 0x07 )
  887.         background = 0;
  888.     if (forground == background)
  889.     {
  890.         if( ((++background) && 0x0f) > 0x07 )
  891.             background = 0;
  892.     }
  893.     r_term.displayw = ((((background << 4) + forground) << 8) & 0x7f00 );
  894.     set_screen_attrib();
  895. }
  896.  
  897. /*
  898.  * Title:  set_screen_attrib
  899.  *         Set attribute for the whole screen
  900.  */
  901.  
  902. void set_screen_attrib()
  903. {
  904.     unsigned char far *tmp_ptr;
  905.     unsigned int temp_b;
  906.     unsigned char x;
  907.     unsigned int y;
  908.  
  909.     temp_b = (r_term.displayw >> 8);
  910.     x = (char) temp_b;
  911.     x &= NO_BLINK;
  912.     tmp_ptr =(char far *) video_p +1;
  913.  
  914.     for(y=1; y <= 2000; ++y)
  915.     {
  916.         (*tmp_ptr) = (char) x;
  917.         tmp_ptr += 2;
  918.     }
  919. }
  920. /*
  921.  *  Title:  save_r_screen
  922.  *          Save iRMX screen in file RMX$$$.SCR
  923.  */
  924. unsigned int save_r_screen()
  925. {
  926.     int *buff_ptr, *last_b_ptr;
  927.     int far *screen_ptr;
  928.     int fd_out, bytes;
  929.  
  930.     if ((fd_out = open("\\RMX$$$.SCR",
  931.                        O_WRONLY|O_CREAT|O_BINARY,
  932.                                S_IREAD|S_IWRITE)) < 0)
  933.     {
  934.       return(FALSE);  /* error open file */
  935.     }
  936.     /* Copy the screen into a near buffer. */
  937.  
  938.     last_b_ptr = &Temp_Buff[SCREENLENGTH];
  939.     buff_ptr = Temp_Buff;
  940.  
  941.     screen_ptr = (int far *) video_p;
  942.     for (; buff_ptr < last_b_ptr; ++buff_ptr, ++screen_ptr)
  943.         *buff_ptr = *screen_ptr;
  944.  
  945.     /* Write it to file. */
  946.  
  947.     bytes = write(fd_out, Temp_Buff, SCREENLENGTH * 2);
  948.     if (bytes != SCREENLENGTH * 2)
  949.     {
  950.      close(fd_out) ;
  951.      return(FALSE);  /* error writing file */
  952.     }
  953.     /*
  954.      * Save screen cursor location to file
  955.      */
  956.     Temp_Buff[0] = ( (r_term.row << 8) + r_term.column );
  957.     bytes = write(fd_out, Temp_Buff, 2);
  958.     /*
  959.      * Save screen attribute
  960.      */
  961.     Temp_Buff[0] = r_term.displayw;
  962.     bytes = write(fd_out, Temp_Buff, 2);
  963.  
  964.     close(fd_out) ;
  965.     return(TRUE);
  966. }
  967.  
  968. /*
  969.  *  Title:  restore_r_screen
  970.  *          Restore iRMX screen from file RMX$$$.SCR
  971.  */
  972. unsigned int restore_r_screen()
  973. {
  974.     int *buff_ptr, *last_b_ptr;
  975.     int far *screen_ptr;
  976.     int fd_in, bytes, Temp_W;
  977.  
  978.     if ((fd_in = open("\\RMX$$$.SCR", O_RDONLY | O_BINARY)) < 0)
  979.     {
  980.       return(FALSE);  /* error open file */
  981.     }
  982.  
  983.     /* Read the file into buffer. */
  984.  
  985.     bytes = read(fd_in, Temp_Buff, SCREENLENGTH * 2);
  986.  
  987.     if (bytes <= 0)
  988.     {
  989.       close(fd_in) ;
  990.       return(FALSE);  /* error reading file */
  991.     }
  992.  
  993.     /* Copy the buffer to screen memory. */
  994.  
  995.     last_b_ptr = &Temp_Buff[bytes / 2];
  996.     buff_ptr = Temp_Buff;
  997.  
  998.     screen_ptr = (int far *) video_p;
  999.     for (; buff_ptr < last_b_ptr; ++buff_ptr, ++screen_ptr)
  1000.         *screen_ptr = *buff_ptr;
  1001.  
  1002.     /*
  1003.      * read the screen cursor location from file
  1004.      */
  1005.     bytes = read(fd_in, Temp_Buff, 2);
  1006.  
  1007.     Temp_W = Temp_Buff[0];
  1008.     r_term.row = (unsigned char) (Temp_W >> 8);
  1009.     Temp_W = Temp_Buff[0];
  1010.     r_term.column = (unsigned char) (Temp_W);
  1011.     /*
  1012.      * read screen attribute
  1013.      */
  1014.     bytes = read(fd_in, Temp_Buff, 2);
  1015.     r_term.displayw = Temp_Buff[0];
  1016.  
  1017.     close(fd_in) ;
  1018.     set_cursor(r_term.row, r_term.column);
  1019.     return(TRUE);
  1020. }
  1021.