home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 02 / remote.asc < prev    next >
Text File  |  1990-12-26  |  11KB  |  424 lines

  1. _REMOTE CONNECTIVITY FOR PORTABLE TERMINALS: PART I_
  2. by Dan Troy
  3.  
  4.  
  5. [LISTING ONE]
  6.  
  7. void process_VT100_input(char *z)
  8. {
  9. char data;
  10. TERMINALP t = (TERMINALP)z;   /* default VT100 parameters */
  11.  
  12.   if(!eof())                  /* if character exists in   */
  13.   {                           /*      serial buffer       */
  14.      read(&data);             /* then read it             */
  15.      active = TRUE;           /* set global activity flag */
  16.      write_screen(t, data);   /* process VT100 character  */
  17.   }
  18. }
  19.  
  20.  
  21. [LISTING TWO]
  22.  
  23. typedef struct
  24. {
  25.      char addlf;            /* line feed/new line   */
  26.      char keymode;          /* cursor/application   */
  27.      char insert;           /* replace/insert       */
  28.      char autowrap;         /* off/on               */
  29.      char keypad;           /* numeric/alternate    */
  30.      char origin;           /* absolute/relative    */
  31.      char kblock;           /* keyboard unlock/lock */
  32. }TERMINAL, *TERMINALP;
  33.  
  34.  
  35.  
  36. [LISTING THREE]
  37.  
  38. init_emulation_mode:
  39.  
  40. clr ea                             ;shut off interrupts
  41. mov dptr,#emul_processor_address   ;get c function address
  42. mov a,r3                           ;get low byte of function
  43.                                    ;from C call
  44. movx @dptr,a                       ;save at storage address
  45. inc dptr                           ;inc processor address ptr
  46. mov a,r2                           ;get high byte of function
  47. movx @dptr,a                       ;save at storage address
  48. setb ea                            ;turn back on interrupts
  49.  
  50. lcall get_and_decr_stack_pointer   ;get data stack ptr
  51.                                    ;parameter data struct
  52. movx a,@dptr                       ;get low byte of setup
  53.                                    ;parameter data struct
  54. xch a,b                            ;save in b reg
  55. lcall get_and_decr_stack_pointer   ;adjust data stack ptr
  56. movx a,@dptr                       ;get high byte of setup
  57.                                    ;parameter data struct
  58. push acc                           ;save on program stack
  59. mov dptr,#data_struct              ;get storage address
  60. xch a,b
  61. movx @dptr,a                       ;save low byte of setup
  62. inc dptr
  63. pop acc
  64. movx @dptr,a                       ;save high byte of setup
  65.  
  66. ret
  67.  
  68.  
  69.  
  70. [LISTING FOUR]
  71.  
  72. init_emulation_mode(process_VT100_input, (char *) t);
  73.  
  74.  
  75. [LISTING FIVE]
  76.  
  77. typedef void(*PTF) ();         /* a pointer to a function */
  78. extern void init_emulation_mode(PTF, char *);
  79.  
  80. And the VT100 driver can be installed as follows:
  81.  
  82. /* initialize VT100 default parameters */
  83.  
  84. cursor.row = cursor.col = 1;
  85. t->origin = t->addlf = t->keymode = RESET;
  86. t->kblock = t->insert = t->autowrap = RESET;
  87. t->keypad = NUMERIC;
  88.  
  89. clr_display();              /* clear LINKS display */
  90.  
  91. init_emulation_mode(process_VT100_input, (char *) t);
  92.  
  93.  
  94.  
  95.  
  96. [LISTING SIX]
  97.  
  98. BEFORE
  99.  
  100. timer0:
  101.  .
  102.  .
  103.  .
  104. reti
  105.  
  106.  
  107. AFTER
  108.  
  109. timer0:
  110.  .
  111.  .
  112.  .
  113. jnb in_emul_processor,process_emul ;if the emulation driver
  114. reti                               ;is already running, then
  115.                                    ;return from interrupt
  116. process_emul:                      ;else call the driver
  117.  
  118. clr ea                       ;shut off interrupts while the
  119. setb in_emul_processor       ;recursion prevention semaphore
  120. setb ea                      ;is set
  121.  
  122. push dph     ;protect all registers that the C code driver
  123. push dpl     ;could possibly use (includes all of bank 3
  124. push psw     ;registers)
  125. push acc
  126. push b
  127. push 18h
  128. push 19h
  129. push 1ah
  130. push 1bh
  131. push 1ch
  132. push 1dh
  133. push 1eh
  134. push 1fh
  135.  
  136. mov dptr,#return_from_emul_processor   ;put return from
  137. push dpl                               ;emulation driver
  138. push dph                               ;on stack
  139.  
  140. mov dptr,#emul_processor_address   ;put emulation processor
  141. movx a,@dptr                       ;driver address on stack
  142. push acc
  143. inc dptr
  144. movx a,@dptr
  145. push acc
  146.  
  147. mov dptr,#data_struct              ;get the pointer to any
  148. movx a,@dptr                       ;data to be passed to
  149. mov r2,a                           ;the C language driver.
  150. inc dptr                           ;pointer address is
  151. movx a,@dptr                       ;stored in r2 and r3
  152. mov r3,a
  153.  
  154. reti               ;calls generic emulation driver
  155.                    ;(last address on program stack)
  156.  
  157.  
  158.  
  159. [LISTING SEVEN]
  160.  
  161. return_from_emul_processor:
  162.  
  163. pop 1fh     ; restore stack prior to call to VT100 driver
  164. pop 1eh
  165. pop 1dh
  166. pop 1ch
  167. pop 1bh
  168. pop 1ah
  169. pop 19h
  170. pop 18h
  171. pop b
  172. pop acc
  173. pop psw
  174. pop dpl
  175. pop dph
  176.  
  177. clr ea                 ;reset recursion prevention semaphore
  178. clr in_emul_processor  ;while interrupts are off
  179. setb ea
  180.  .
  181.  .
  182. ret      ; gets address of next instruction to execute
  183.          ; in the routine that had been interrupted by
  184.          ; timer 0.
  185.          ; address taken off the 8051 stack and the stack
  186.          ; pointer is updated
  187.  
  188.  
  189.  
  190. [LISTING EIGHT]
  191.  
  192. char *read_VT100_image(char row, char col, char *string,
  193.      char number_to_read)
  194. {
  195.      short i;
  196.      char *ptr;
  197.  
  198.      if(row <= VT100_MAX_ROWS && col <= VT100_MAX_COLS)
  199.      {
  200.        /* calculate number of characters to read on row */
  201.          if((number_to_read + col) > (VT100_MAX_COLS+1))
  202.              number_to_read = (VT100_MAX_COLS+1) - col;
  203.  
  204.       /* get string start address from global screen array */
  205.          ptr = &screen[row - 1][col - 1];
  206.  
  207.       /* transfer string to return string array */
  208.          for(i = 0; i < number_to_read; i++;)
  209.              string[i] = *ptr++;
  210.          str[i] = 0;             /* terminate string */
  211.      }
  212.      return(string);
  213. }
  214.  
  215.  
  216.  
  217. [LISTING NINE]
  218.  
  219.  
  220. void get_cursor_position(TERMINALP t, char *row, char *col)
  221. {
  222. /* if cursor origin is relative, then calc row position
  223.    based on scrolling start position, else use global row
  224.    position */
  225.     if(t->origin == SET)*row = cursor.row - begin.scroll + 1;
  226.     else *row = cursor.row;
  227.  
  228.     *col = cursor.col;
  229. }
  230.  
  231.  
  232.  
  233.  
  234. [LISTING TEN]
  235.  
  236.  
  237. static char screen[24][80];  /* VT100 virtual screen image */
  238.  
  239. /* put a space character in each virtual image position */
  240.  
  241. static void clr_display()
  242. {
  243.       short i,j;
  244.  
  245.       for(j = 0;j < VT100_MAX_ROWS; j++)
  246.          for(i = 0;i < VT100_MAX_COLS; i++)
  247.             screen[j][i]=' ';
  248. }
  249.  
  250.  
  251. [LISTING ELEVEN]
  252.  
  253. static char screen[24][80];  /* VT100 virtual screen image */
  254. char *current, *next, *last;
  255.  
  256. /* put a space character in each virtual image position */
  257.  
  258. static void clr_display()
  259. {
  260. current = &screen[0][0];
  261. last = &screen[24 - 1][80 - 1];
  262.  
  263. do{
  264.   *current++ = ' ';
  265.   *current++ = ' ';
  266.   *current++ = ' ';
  267.   *current++ = ' ';
  268.   *current++ = ' ';
  269.   *current++ = ' ';
  270.   *current++ = ' ';
  271.   *current++ = ' ';
  272.   *current++ = ' ';
  273.   *current++ = ' ';
  274.   }while(current < last);
  275. }
  276.  
  277.  
  278. [LISTING TWELVE]
  279.  
  280. static char screen[24][80];  /* VT100 virtual screen image */
  281. static short begin_scroll_row, end_scroll_row;
  282.  
  283. /*  Scroll screen up one row. Last row is blank. */
  284.  
  285. static void scroll_up()
  286. {
  287.     short i,j;
  288.  
  289.     for(j = (begin_scroll_row-1; j<(end_scroll_row-1); i++)
  290.          for(i = 0;i < VT100_MAX_COLS; i++)
  291.             screen[j][i]=screen[j+1][i];
  292.  
  293.     for(i = 0;i < VT100_MAX_COLS; screen[j][i] = ' ', i++);
  294. }
  295.  
  296.  
  297.  
  298.  
  299. [LISTING THIRTEEN]
  300.  
  301. static char screen[24][80];  /* VT100 virtual screen image */
  302. static char *current, *next, *last;
  303. static short begin_scroll_row, end_scroll_row;
  304.  
  305. /* Scroll screen up one row. Last row is blank.  */
  306.  
  307. static void scroll_up()
  308. {
  309.     current = &screen[begin_scroll_row - 1][0];
  310.     next    = current + 80;
  311.     last    = &screen[end_scroll_row - 1][0];
  312.  
  313. do{
  314.   *current++ = *next++;
  315.   *current++ = *next++;
  316.   *current++ = *next++;
  317.   *current++ = *next++;
  318.   *current++ = *next++;
  319.   *current++ = *next++;
  320.   *current++ = *next++;
  321.   *current++ = *next++;
  322.   *current++ = *next++;
  323.   *current++ = *next++;
  324.   }while(current < last);
  325.  
  326. last += 80;
  327.  
  328. do{
  329.   *current++ = ' ';
  330.   *current++ = ' ';
  331.   *current++ = ' ';
  332.   *current++ = ' ';
  333.   *current++ = ' ';
  334.   *current++ = ' ';
  335.   *current++ = ' ';
  336.   *current++ = ' ';
  337.   *current++ = ' ';
  338.   *current++ = ' ';
  339.   }while(current < last);
  340. }
  341.  
  342.  
  343.  
  344.  
  345. [LISTING FOURTEEN]
  346.  
  347.   #include "speedc.h"
  348.   #include "vt100.h"
  349.   #include "string.h"
  350.  
  351.   void exception_handler(char code);
  352.  
  353.   void main()
  354.   {
  355.    TERMINAL t;          /* define VT100 setup parameters */
  356.    char string[21];
  357.    char display_string[23];
  358.  
  359.    cursor.row = cursor.col = 1;               /* globals defined in vt100.h */
  360.    t->origin = t->addlf = t->keymode = 0;
  361.    t->kblock = t->insert = t-> autowrap = 0;
  362.    t->keypad = NUMERIC;
  363.  
  364. init_emulation_mode(process_VT100_input, (char *)t); /* prototype in vt100.h */
  365.  
  366.   /* initialize the first 3 lines on the LINKS terminal display by
  367.    using the special LINKS x function.  This function allows the
  368.    user to define distinct display regions on the terminal.  The
  369.    nomenclature is as follows:
  370.    D         means define a display region which is touch sensitive.
  371.    1,2, or 3 means that the touch sensitive area defined will
  372.              generate transmit that particular ASCII character in the
  373.              key buffer when that touch sensitive area is pressed on
  374.              the LINKS screen.  This is also referred to as its name.
  375.    A18;      means the touch sensitive display area in row A (first row
  376.              on the LINKS), columns 1-8 (touch display areas have 8
  377.              distinct areas per row).  The semicolon means the end of
  378.              the touch display definition, and what follows is the
  379.              message to be displayed in that display area.
  380.    B18;      means row B (second row), columns 1-8.
  381.    C18;      means row C (third row), columns 1-8.
  382.   */
  383.  
  384.    x("D1 A18;  ");
  385.    x("D2 B18;  ");
  386.    x("D3 C18;  ");
  387.  
  388.    open("98N1",1);      /* open LINKS RS232 port with special LINKS
  389.                               operating system function */
  390.  
  391.    /* continuously update LINKS terminal display with the current VT100
  392.       virtual image found in rows 1-3, columns 1-20) using read_VT100_scr
  393.       whose prototype is in vt100.h.
  394.    */
  395.    do{
  396.       read_VT100_scr(1, 1, string, 20);     /* read row 1, cols 1-20       */
  397.       strcpy(display_string, "P1");         /* prefix string with special  */
  398.       strcat(display_string, string);       /* links P cmd (print to touch */
  399.       x(display_string);                    /* display area named '1')     */
  400.  
  401.       read_VT100_scr(2, 1, string, 20);     /* read row 2, cols 1-20       */
  402.       strcpy(display_string, "P2");         /* prefix string with special  */
  403.       strcat(display_string, string);       /* links P cmd (print to touch */
  404.       x(display_string);                    /* display area named '2')     */
  405.  
  406.       read_VT100_scr(3, 1, string, 20);     /* read row 3, cols 1-20       */
  407.       strcpy(display_string, "P3");         /* prefix string with special  */
  408.       strcat(display_string, string);       /* links P cmd (print to touch */
  409.       x(display_string);                    /* display area named '3')     */
  410.  
  411.       }while(-1);
  412. }
  413.  
  414. /* The exception handler is needed for all LINKS applications to handle
  415.    special LINKS control functions.
  416. */
  417.  
  418. void exception_handler(char code)
  419. {
  420.    if (code == 4)turn_off();    /* detects ON/OFF button pressed,
  421.                                    and turns LINKS off via LINKS turn_off */
  422. }
  423.  
  424.